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