diff options
author | Neil Fuller <nfuller@google.com> | 2015-04-07 12:54:40 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2015-04-07 12:54:41 +0000 |
commit | 345d118df6eef599a1ad0ea18022ad1f74633f10 (patch) | |
tree | 9c43cd67897f7354fc9d416b0d522a5fbf6d47e7 /luni/src/main/native | |
parent | e25881196b4cb5f056619bf2883b10bb861dd704 (diff) | |
parent | 317d6e12782e069e4fde06ed0f9a976a7c49f580 (diff) | |
download | libcore-345d118df6eef599a1ad0ea18022ad1f74633f10.zip libcore-345d118df6eef599a1ad0ea18022ad1f74633f10.tar.gz libcore-345d118df6eef599a1ad0ea18022ad1f74633f10.tar.bz2 |
Merge "Changes to enable timezone data overrides for ICU and libcore"
Diffstat (limited to 'luni/src/main/native')
-rw-r--r-- | luni/src/main/native/libcore_icu_ICU.cpp | 80 |
1 files changed, 62 insertions, 18 deletions
diff --git a/luni/src/main/native/libcore_icu_ICU.cpp b/luni/src/main/native/libcore_icu_ICU.cpp index ff76a16..0e744b7 100644 --- a/luni/src/main/native/libcore_icu_ICU.cpp +++ b/luni/src/main/native/libcore_icu_ICU.cpp @@ -815,22 +815,18 @@ static JNINativeMethod gMethods[] = { NATIVE_METHOD(ICU, toLowerCase, "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"), NATIVE_METHOD(ICU, toUpperCase, "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"), }; -void register_libcore_icu_ICU(JNIEnv* env) { - std::string path; - path = u_getDataDirectory(); - path += "/"; - path += U_ICUDATA_NAME; - path += ".dat"; - - #define FAIL_WITH_STRERROR(s) \ - ALOGE("Couldn't " s " '%s': %s", path.c_str(), strerror(errno)); \ - abort(); - #define MAYBE_FAIL_WITH_ICU_ERROR(s) \ - if (status != U_ZERO_ERROR) {\ - ALOGE("Couldn't initialize ICU (" s "): %s (%s)", u_errorName(status), path.c_str()); \ - abort(); \ - } +#define FAIL_WITH_STRERROR(s) \ + ALOGE("Couldn't " s " '%s': %s", path.c_str(), strerror(errno)); \ + return FALSE; + +#define MAYBE_FAIL_WITH_ICU_ERROR(s) \ + if (status != U_ZERO_ERROR) {\ + ALOGE("Couldn't initialize ICU (" s "): %s (%s)", u_errorName(status), path.c_str()); \ + return FALSE; \ + } + +static bool mapIcuData(const std::string& path) { // Open the file and get its length. ScopedFd fd(open(path.c_str(), O_RDONLY)); if (fd.get() == -1) { @@ -852,18 +848,66 @@ void register_libcore_icu_ICU(JNIEnv* env) { FAIL_WITH_STRERROR("madvise(MADV_RANDOM)"); } - // Tell ICU to use our memory-mapped data. UErrorCode status = U_ZERO_ERROR; + + // Tell ICU to use our memory-mapped data. udata_setCommonData(data, &status); MAYBE_FAIL_WITH_ICU_ERROR("udata_setCommonData"); + + return TRUE; +} + +void register_libcore_icu_ICU(JNIEnv* env) { + // Check the timezone override file exists. If it does, map it first so we use it in preference + // to the one that shipped with the device. + const char* dataPathPrefix = getenv("ANDROID_DATA"); + if (dataPathPrefix == NULL) { + ALOGE("ANDROID_DATA environment variable not set"); \ + abort(); + } + + UErrorCode status = U_ZERO_ERROR; // Tell ICU it can *only* use our memory-mapped data. udata_setFileAccess(UDATA_NO_FILES, &status); - MAYBE_FAIL_WITH_ICU_ERROR("udata_setFileAccess"); + if (status != U_ZERO_ERROR) { + ALOGE("Couldn't initialize ICU (s_setFileAccess): %s", u_errorName(status)); + abort(); + } + + // Map in optional TZ data files. + std::string dataPath; + dataPath = dataPathPrefix; + dataPath += "/misc/zoneinfo/current/icu/icu_tzdata.dat"; + + struct stat sb; + if (stat(dataPath.c_str(), &sb) == 0) { + ALOGD("Timezone override file found: %s", dataPath.c_str()); + if (!mapIcuData(dataPath)) { + ALOGW("TZ override file %s exists but could not be loaded. Skipping.", dataPath.c_str()); + } + } else { + ALOGD("No timezone override file found: %s", dataPath.c_str()); + } + + // Use the ICU data files that shipped with the device for everything else. + std::string systemPath; + systemPath = u_getDataDirectory(); + systemPath += "/"; + systemPath += U_ICUDATA_NAME; + systemPath += ".dat"; + + if (!mapIcuData(systemPath)) { + abort(); + } // Failures to find the ICU data tend to be somewhat obscure because ICU loads its data on first // use, which can be anywhere. Force initialization up front so we can report a nice clear error // and bail. u_init(&status); - MAYBE_FAIL_WITH_ICU_ERROR("u_init"); + if (status != U_ZERO_ERROR) {\ + ALOGE("Couldn't initialize ICU (u_init): %s", u_errorName(status)); + abort(); + } + jniRegisterNativeMethods(env, "libcore/icu/ICU", gMethods, NELEM(gMethods)); } |