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