1*0e209d39SAndroid Build Coastguard Worker /* 2*0e209d39SAndroid Build Coastguard Worker * Copyright (C) 2019 The Android Open Source Project 3*0e209d39SAndroid Build Coastguard Worker * 4*0e209d39SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*0e209d39SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*0e209d39SAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*0e209d39SAndroid Build Coastguard Worker * 8*0e209d39SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*0e209d39SAndroid Build Coastguard Worker * 10*0e209d39SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*0e209d39SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*0e209d39SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*0e209d39SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*0e209d39SAndroid Build Coastguard Worker * limitations under the License. 15*0e209d39SAndroid Build Coastguard Worker */ 16*0e209d39SAndroid Build Coastguard Worker 17*0e209d39SAndroid Build Coastguard Worker #ifndef ICU_REGISTRATION_H_included 18*0e209d39SAndroid Build Coastguard Worker #define ICU_REGISTRATION_H_included 19*0e209d39SAndroid Build Coastguard Worker 20*0e209d39SAndroid Build Coastguard Worker #include <memory> 21*0e209d39SAndroid Build Coastguard Worker #include <string> 22*0e209d39SAndroid Build Coastguard Worker #include <cstdio> 23*0e209d39SAndroid Build Coastguard Worker 24*0e209d39SAndroid Build Coastguard Worker 25*0e209d39SAndroid Build Coastguard Worker /** 26*0e209d39SAndroid Build Coastguard Worker * def NO_ANDROID_LOGGING 27*0e209d39SAndroid Build Coastguard Worker * This flag turns off the usage of liblog, and logs into stderr instead. 28*0e209d39SAndroid Build Coastguard Worker * This is not expected to be used in Android platform build, but is useful 29*0e209d39SAndroid Build Coastguard Worker * when building this ICU4C for unbundled library or app. 30*0e209d39SAndroid Build Coastguard Worker */ 31*0e209d39SAndroid Build Coastguard Worker #if defined(__ANDROID__) && !defined(NO_ANDROID_LIBLOG) 32*0e209d39SAndroid Build Coastguard Worker #include <android-base/logging.h> 33*0e209d39SAndroid Build Coastguard Worker #include <android-base/unique_fd.h> 34*0e209d39SAndroid Build Coastguard Worker #include <log/log.h> 35*0e209d39SAndroid Build Coastguard Worker #define AICU_LOGE(...) ALOGE(__VA_ARGS__) 36*0e209d39SAndroid Build Coastguard Worker #define AICU_LOGW(...) ALOGW(__VA_ARGS__) 37*0e209d39SAndroid Build Coastguard Worker #define AICU_LOGD(...) ALOGD(__VA_ARGS__) 38*0e209d39SAndroid Build Coastguard Worker #define AICU_LOGV(...) ALOGV(__VA_ARGS__) 39*0e209d39SAndroid Build Coastguard Worker #else 40*0e209d39SAndroid Build Coastguard Worker // http://b/171371690 Avoid dependency on liblog and libbase on host for 41*0e209d39SAndroid Build Coastguard Worker // downstream unbundled branches. In this case, liblog and libbase are not 42*0e209d39SAndroid Build Coastguard Worker // very useful on host and we just try to avoid it here in our best effort. 43*0e209d39SAndroid Build Coastguard Worker 44*0e209d39SAndroid Build Coastguard Worker // Check if a host should log a message. 45*0e209d39SAndroid Build Coastguard Worker // 46*0e209d39SAndroid Build Coastguard Worker // This method checks the priority argument against the wildcard level set 47*0e209d39SAndroid Build Coastguard Worker // in the ANDROID_LOG_TAGS environment variable. The priority specified 48*0e209d39SAndroid Build Coastguard Worker // corresponds to the standard Android set: 49*0e209d39SAndroid Build Coastguard Worker // 50*0e209d39SAndroid Build Coastguard Worker // V - verbose D - debug 51*0e209d39SAndroid Build Coastguard Worker // I - info W - warn 52*0e209d39SAndroid Build Coastguard Worker // E - error F - fatal 53*0e209d39SAndroid Build Coastguard Worker // 54*0e209d39SAndroid Build Coastguard Worker // If the ANDROID_LOG_TAGS variable is not set then this method returns true. 55*0e209d39SAndroid Build Coastguard Worker // Otherwise, the priority is compared to the level in ANDROID_LOG_TAGS. 56*0e209d39SAndroid Build Coastguard Worker // 57*0e209d39SAndroid Build Coastguard Worker // Example: if ANDROID_LOG_TAGS has the value "*:W" then this method will 58*0e209d39SAndroid Build Coastguard Worker // return true if the priority is warn or above. 59*0e209d39SAndroid Build Coastguard Worker bool AIcuHostShouldLog(char priority); 60*0e209d39SAndroid Build Coastguard Worker 61*0e209d39SAndroid Build Coastguard Worker #define AICU_LOG_PRINTLN(priority, ...) \ 62*0e209d39SAndroid Build Coastguard Worker do { \ 63*0e209d39SAndroid Build Coastguard Worker if (AIcuHostShouldLog(priority)) { \ 64*0e209d39SAndroid Build Coastguard Worker fprintf(stderr, __VA_ARGS__); \ 65*0e209d39SAndroid Build Coastguard Worker fputc('\n', stderr); \ 66*0e209d39SAndroid Build Coastguard Worker } \ 67*0e209d39SAndroid Build Coastguard Worker } while (0) 68*0e209d39SAndroid Build Coastguard Worker #define AICU_LOGE(...) AICU_LOG_PRINTLN('E', __VA_ARGS__) 69*0e209d39SAndroid Build Coastguard Worker #define AICU_LOGW(...) AICU_LOG_PRINTLN('W', __VA_ARGS__) 70*0e209d39SAndroid Build Coastguard Worker #define AICU_LOGD(...) AICU_LOG_PRINTLN('D', __VA_ARGS__) 71*0e209d39SAndroid Build Coastguard Worker #define AICU_LOGV(...) AICU_LOG_PRINTLN('V', __VA_ARGS__) 72*0e209d39SAndroid Build Coastguard Worker #ifndef CHECK 73*0e209d39SAndroid Build Coastguard Worker #define CHECK(cond) \ 74*0e209d39SAndroid Build Coastguard Worker if (!(cond)) { \ 75*0e209d39SAndroid Build Coastguard Worker AICU_LOGE(#cond "\n"); \ 76*0e209d39SAndroid Build Coastguard Worker abort(); \ 77*0e209d39SAndroid Build Coastguard Worker } 78*0e209d39SAndroid Build Coastguard Worker #endif 79*0e209d39SAndroid Build Coastguard Worker #endif 80*0e209d39SAndroid Build Coastguard Worker 81*0e209d39SAndroid Build Coastguard Worker namespace androidicuinit { 82*0e209d39SAndroid Build Coastguard Worker namespace impl { 83*0e209d39SAndroid Build Coastguard Worker 84*0e209d39SAndroid Build Coastguard Worker /* 85*0e209d39SAndroid Build Coastguard Worker * Handles ICU data mapping for a single ICU .dat file. 86*0e209d39SAndroid Build Coastguard Worker * The Create method handles mapping the file into memory and calling 87*0e209d39SAndroid Build Coastguard Worker * udata_setCommonData(). The file is unmapped on object destruction. 88*0e209d39SAndroid Build Coastguard Worker */ 89*0e209d39SAndroid Build Coastguard Worker class IcuDataMap final { 90*0e209d39SAndroid Build Coastguard Worker public: 91*0e209d39SAndroid Build Coastguard Worker // Maps in ICU data at the path and call udata_setCommonData(), returning 92*0e209d39SAndroid Build Coastguard Worker // null if it failed (prints error to ALOGE). 93*0e209d39SAndroid Build Coastguard Worker static std::unique_ptr<IcuDataMap> Create(const std::string& path); 94*0e209d39SAndroid Build Coastguard Worker // Unmaps the ICU data. 95*0e209d39SAndroid Build Coastguard Worker ~IcuDataMap(); 96*0e209d39SAndroid Build Coastguard Worker 97*0e209d39SAndroid Build Coastguard Worker private: IcuDataMap(const std::string & path)98*0e209d39SAndroid Build Coastguard Worker IcuDataMap(const std::string& path) 99*0e209d39SAndroid Build Coastguard Worker : path_(path), data_(nullptr), data_length_(0) {} 100*0e209d39SAndroid Build Coastguard Worker bool TryMap(); 101*0e209d39SAndroid Build Coastguard Worker bool TryUnmap(); 102*0e209d39SAndroid Build Coastguard Worker 103*0e209d39SAndroid Build Coastguard Worker std::string path_; // Save for error messages. 104*0e209d39SAndroid Build Coastguard Worker void* data_; // Save for munmap. 105*0e209d39SAndroid Build Coastguard Worker size_t data_length_; // Save for munmap. 106*0e209d39SAndroid Build Coastguard Worker 107*0e209d39SAndroid Build Coastguard Worker // Disable copy constructor and assignment operator 108*0e209d39SAndroid Build Coastguard Worker IcuDataMap(const IcuDataMap&) = delete; 109*0e209d39SAndroid Build Coastguard Worker void operator=(const IcuDataMap&) = delete; 110*0e209d39SAndroid Build Coastguard Worker }; 111*0e209d39SAndroid Build Coastguard Worker 112*0e209d39SAndroid Build Coastguard Worker } // namespace impl 113*0e209d39SAndroid Build Coastguard Worker 114*0e209d39SAndroid Build Coastguard Worker /* 115*0e209d39SAndroid Build Coastguard Worker * Handles the mapping of all ICU data files into memory for the various files 116*0e209d39SAndroid Build Coastguard Worker * used on Android. All data files are unmapped on object destruction. 117*0e209d39SAndroid Build Coastguard Worker */ 118*0e209d39SAndroid Build Coastguard Worker class IcuRegistration final { 119*0e209d39SAndroid Build Coastguard Worker public: 120*0e209d39SAndroid Build Coastguard Worker static void Register(); 121*0e209d39SAndroid Build Coastguard Worker static void Deregister(); 122*0e209d39SAndroid Build Coastguard Worker 123*0e209d39SAndroid Build Coastguard Worker // Required to be public so it can be destructed by unique_ptr. 124*0e209d39SAndroid Build Coastguard Worker ~IcuRegistration(); 125*0e209d39SAndroid Build Coastguard Worker 126*0e209d39SAndroid Build Coastguard Worker private: 127*0e209d39SAndroid Build Coastguard Worker IcuRegistration(); 128*0e209d39SAndroid Build Coastguard Worker 129*0e209d39SAndroid Build Coastguard Worker static bool pathExists(const std::string& path); 130*0e209d39SAndroid Build Coastguard Worker static std::string getTimeZoneModulePath(); 131*0e209d39SAndroid Build Coastguard Worker static std::string getI18nModulePath(); 132*0e209d39SAndroid Build Coastguard Worker 133*0e209d39SAndroid Build Coastguard Worker std::unique_ptr<impl::IcuDataMap> icu_datamap_from_tz_module_; 134*0e209d39SAndroid Build Coastguard Worker std::unique_ptr<impl::IcuDataMap> icu_datamap_from_i18n_module_; 135*0e209d39SAndroid Build Coastguard Worker 136*0e209d39SAndroid Build Coastguard Worker // Disable copy constructor and assignment operator 137*0e209d39SAndroid Build Coastguard Worker IcuRegistration(const IcuRegistration&) = delete; 138*0e209d39SAndroid Build Coastguard Worker void operator=(const IcuRegistration&) = delete; 139*0e209d39SAndroid Build Coastguard Worker }; 140*0e209d39SAndroid Build Coastguard Worker 141*0e209d39SAndroid Build Coastguard Worker } // namespace androidicuinit 142*0e209d39SAndroid Build Coastguard Worker 143*0e209d39SAndroid Build Coastguard Worker /** 144*0e209d39SAndroid Build Coastguard Worker * Initialize the ICU and load the data from .dat files from system image and 145*0e209d39SAndroid Build Coastguard Worker * various mainline modules. 146*0e209d39SAndroid Build Coastguard Worker * If ICU has already been registered, the function calls abort() and the process terminates. 147*0e209d39SAndroid Build Coastguard Worker * This function is NOT thread-safe. 148*0e209d39SAndroid Build Coastguard Worker */ 149*0e209d39SAndroid Build Coastguard Worker void android_icu_register(); 150*0e209d39SAndroid Build Coastguard Worker 151*0e209d39SAndroid Build Coastguard Worker /** 152*0e209d39SAndroid Build Coastguard Worker * Unregister and unload the data. After this call, user can re-register. 153*0e209d39SAndroid Build Coastguard Worker */ 154*0e209d39SAndroid Build Coastguard Worker void android_icu_deregister(); 155*0e209d39SAndroid Build Coastguard Worker 156*0e209d39SAndroid Build Coastguard Worker /** 157*0e209d39SAndroid Build Coastguard Worker * @return true if ICU has been registered. 158*0e209d39SAndroid Build Coastguard Worker */ 159*0e209d39SAndroid Build Coastguard Worker bool android_icu_is_registered(); 160*0e209d39SAndroid Build Coastguard Worker 161*0e209d39SAndroid Build Coastguard Worker 162*0e209d39SAndroid Build Coastguard Worker #endif // ICU_REGISTRATION_H_included 163