1*6777b538SAndroid Build Coastguard Worker // Copyright 2019 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #include "base/fuchsia/intl_profile_watcher.h" 6*6777b538SAndroid Build Coastguard Worker 7*6777b538SAndroid Build Coastguard Worker #include <fuchsia/intl/cpp/fidl.h> 8*6777b538SAndroid Build Coastguard Worker #include <lib/sys/cpp/component_context.h> 9*6777b538SAndroid Build Coastguard Worker #include <string> 10*6777b538SAndroid Build Coastguard Worker #include <vector> 11*6777b538SAndroid Build Coastguard Worker 12*6777b538SAndroid Build Coastguard Worker #include "base/fuchsia/fuchsia_logging.h" 13*6777b538SAndroid Build Coastguard Worker #include "base/fuchsia/process_context.h" 14*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_piece.h" 15*6777b538SAndroid Build Coastguard Worker 16*6777b538SAndroid Build Coastguard Worker using ::fuchsia::intl::Profile; 17*6777b538SAndroid Build Coastguard Worker 18*6777b538SAndroid Build Coastguard Worker namespace base { 19*6777b538SAndroid Build Coastguard Worker FuchsiaIntlProfileWatcher(ProfileChangeCallback on_profile_changed)20*6777b538SAndroid Build Coastguard WorkerFuchsiaIntlProfileWatcher::FuchsiaIntlProfileWatcher( 21*6777b538SAndroid Build Coastguard Worker ProfileChangeCallback on_profile_changed) 22*6777b538SAndroid Build Coastguard Worker : FuchsiaIntlProfileWatcher( 23*6777b538SAndroid Build Coastguard Worker ComponentContextForProcess() 24*6777b538SAndroid Build Coastguard Worker ->svc() 25*6777b538SAndroid Build Coastguard Worker ->Connect<::fuchsia::intl::PropertyProvider>(), 26*6777b538SAndroid Build Coastguard Worker on_profile_changed) {} 27*6777b538SAndroid Build Coastguard Worker FuchsiaIntlProfileWatcher(::fuchsia::intl::PropertyProviderPtr property_provider,ProfileChangeCallback on_profile_changed)28*6777b538SAndroid Build Coastguard WorkerFuchsiaIntlProfileWatcher::FuchsiaIntlProfileWatcher( 29*6777b538SAndroid Build Coastguard Worker ::fuchsia::intl::PropertyProviderPtr property_provider, 30*6777b538SAndroid Build Coastguard Worker ProfileChangeCallback on_profile_changed) 31*6777b538SAndroid Build Coastguard Worker : property_provider_(std::move(property_provider)), 32*6777b538SAndroid Build Coastguard Worker on_profile_changed_(std::move(on_profile_changed)) { 33*6777b538SAndroid Build Coastguard Worker DCHECK(property_provider_.is_bound()); 34*6777b538SAndroid Build Coastguard Worker DCHECK(on_profile_changed_); 35*6777b538SAndroid Build Coastguard Worker 36*6777b538SAndroid Build Coastguard Worker property_provider_.set_error_handler([](zx_status_t status) { 37*6777b538SAndroid Build Coastguard Worker ZX_LOG(ERROR, status) << "intl.PropertyProvider disconnected. " 38*6777b538SAndroid Build Coastguard Worker << "Profile changes will not be monitored."; 39*6777b538SAndroid Build Coastguard Worker }); 40*6777b538SAndroid Build Coastguard Worker 41*6777b538SAndroid Build Coastguard Worker property_provider_.events().OnChange = [this]() { 42*6777b538SAndroid Build Coastguard Worker property_provider_->GetProfile( 43*6777b538SAndroid Build Coastguard Worker [this](Profile profile) { on_profile_changed_.Run(profile); }); 44*6777b538SAndroid Build Coastguard Worker }; 45*6777b538SAndroid Build Coastguard Worker } 46*6777b538SAndroid Build Coastguard Worker 47*6777b538SAndroid Build Coastguard Worker FuchsiaIntlProfileWatcher::~FuchsiaIntlProfileWatcher() = default; 48*6777b538SAndroid Build Coastguard Worker 49*6777b538SAndroid Build Coastguard Worker // static GetPrimaryTimeZoneIdFromProfile(const Profile & profile)50*6777b538SAndroid Build Coastguard Workerstd::string FuchsiaIntlProfileWatcher::GetPrimaryTimeZoneIdFromProfile( 51*6777b538SAndroid Build Coastguard Worker const Profile& profile) { 52*6777b538SAndroid Build Coastguard Worker if (!profile.has_time_zones()) { 53*6777b538SAndroid Build Coastguard Worker DLOG(WARNING) << "Profile does not contain time zones."; 54*6777b538SAndroid Build Coastguard Worker return std::string(); 55*6777b538SAndroid Build Coastguard Worker } 56*6777b538SAndroid Build Coastguard Worker 57*6777b538SAndroid Build Coastguard Worker const std::vector<::fuchsia::intl::TimeZoneId>& time_zones = 58*6777b538SAndroid Build Coastguard Worker profile.time_zones(); 59*6777b538SAndroid Build Coastguard Worker if (time_zones.empty()) { 60*6777b538SAndroid Build Coastguard Worker DLOG(ERROR) << "Profile contains an empty time zones list."; 61*6777b538SAndroid Build Coastguard Worker return std::string(); 62*6777b538SAndroid Build Coastguard Worker } 63*6777b538SAndroid Build Coastguard Worker 64*6777b538SAndroid Build Coastguard Worker return time_zones[0].id; 65*6777b538SAndroid Build Coastguard Worker } 66*6777b538SAndroid Build Coastguard Worker 67*6777b538SAndroid Build Coastguard Worker // static 68*6777b538SAndroid Build Coastguard Worker std::string GetPrimaryTimeZoneIdForIcuInitialization()69*6777b538SAndroid Build Coastguard WorkerFuchsiaIntlProfileWatcher::GetPrimaryTimeZoneIdForIcuInitialization() { 70*6777b538SAndroid Build Coastguard Worker return GetPrimaryTimeZoneIdFromProfile(GetCurrentProfileSync()); 71*6777b538SAndroid Build Coastguard Worker } 72*6777b538SAndroid Build Coastguard Worker 73*6777b538SAndroid Build Coastguard Worker // static GetPrimaryLocaleIdFromProfile(const::fuchsia::intl::Profile & profile)74*6777b538SAndroid Build Coastguard Workerstd::string FuchsiaIntlProfileWatcher::GetPrimaryLocaleIdFromProfile( 75*6777b538SAndroid Build Coastguard Worker const ::fuchsia::intl::Profile& profile) { 76*6777b538SAndroid Build Coastguard Worker if (!profile.has_locales()) { 77*6777b538SAndroid Build Coastguard Worker DLOG(ERROR) << "Profile does not contain locale information."; 78*6777b538SAndroid Build Coastguard Worker return std::string(); 79*6777b538SAndroid Build Coastguard Worker } 80*6777b538SAndroid Build Coastguard Worker 81*6777b538SAndroid Build Coastguard Worker const std::vector<::fuchsia::intl::LocaleId>& locale_preferences = 82*6777b538SAndroid Build Coastguard Worker profile.locales(); 83*6777b538SAndroid Build Coastguard Worker if (locale_preferences.empty()) { 84*6777b538SAndroid Build Coastguard Worker DLOG(ERROR) << "Profile contains an empty locale list."; 85*6777b538SAndroid Build Coastguard Worker return std::string(); 86*6777b538SAndroid Build Coastguard Worker } 87*6777b538SAndroid Build Coastguard Worker 88*6777b538SAndroid Build Coastguard Worker return locale_preferences[0].id; 89*6777b538SAndroid Build Coastguard Worker } 90*6777b538SAndroid Build Coastguard Worker 91*6777b538SAndroid Build Coastguard Worker // static GetPrimaryLocaleIdForInitialization()92*6777b538SAndroid Build Coastguard Workerstd::string FuchsiaIntlProfileWatcher::GetPrimaryLocaleIdForInitialization() { 93*6777b538SAndroid Build Coastguard Worker return GetPrimaryLocaleIdFromProfile(GetCurrentProfileSync()); 94*6777b538SAndroid Build Coastguard Worker } 95*6777b538SAndroid Build Coastguard Worker 96*6777b538SAndroid Build Coastguard Worker // static GetProfileFromPropertyProvider(::fuchsia::intl::PropertyProviderSyncPtr property_provider)97*6777b538SAndroid Build Coastguard WorkerProfile FuchsiaIntlProfileWatcher::GetProfileFromPropertyProvider( 98*6777b538SAndroid Build Coastguard Worker ::fuchsia::intl::PropertyProviderSyncPtr property_provider) { 99*6777b538SAndroid Build Coastguard Worker DCHECK(property_provider.is_bound()); 100*6777b538SAndroid Build Coastguard Worker Profile profile; 101*6777b538SAndroid Build Coastguard Worker zx_status_t status = property_provider->GetProfile(&profile); 102*6777b538SAndroid Build Coastguard Worker if (status != ZX_OK) { 103*6777b538SAndroid Build Coastguard Worker ZX_DLOG(ERROR, status) << "Failed to get intl Profile"; 104*6777b538SAndroid Build Coastguard Worker } 105*6777b538SAndroid Build Coastguard Worker return profile; 106*6777b538SAndroid Build Coastguard Worker } 107*6777b538SAndroid Build Coastguard Worker 108*6777b538SAndroid Build Coastguard Worker // static GetCurrentProfileSync()109*6777b538SAndroid Build Coastguard Worker::fuchsia::intl::Profile FuchsiaIntlProfileWatcher::GetCurrentProfileSync() { 110*6777b538SAndroid Build Coastguard Worker ::fuchsia::intl::PropertyProviderSyncPtr provider; 111*6777b538SAndroid Build Coastguard Worker ComponentContextForProcess()->svc()->Connect(provider.NewRequest()); 112*6777b538SAndroid Build Coastguard Worker return GetProfileFromPropertyProvider(std::move(provider)); 113*6777b538SAndroid Build Coastguard Worker } 114*6777b538SAndroid Build Coastguard Worker 115*6777b538SAndroid Build Coastguard Worker } // namespace base 116