diff options
author | Neil Fuller <nfuller@google.com> | 2015-04-07 13:33:41 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2015-04-07 13:33:41 +0000 |
commit | ee5e33710062acfa55dffd3095752315cd696934 (patch) | |
tree | 37d0e19e0e8fb2d1cde1e024bbb4cf5fa1338155 /luni | |
parent | d782da989925f35a2ab86685a797b5bcc55c5bbe (diff) | |
parent | 8426170b2440ce9d9857f8b63e5de5f77d7ee393 (diff) | |
download | libcore-ee5e33710062acfa55dffd3095752315cd696934.zip libcore-ee5e33710062acfa55dffd3095752315cd696934.tar.gz libcore-ee5e33710062acfa55dffd3095752315cd696934.tar.bz2 |
am 8426170b: am 345d118d: Merge "Changes to enable timezone data overrides for ICU and libcore"
* commit '8426170b2440ce9d9857f8b63e5de5f77d7ee393':
Changes to enable timezone data overrides for ICU and libcore
Diffstat (limited to 'luni')
-rw-r--r-- | luni/src/main/java/libcore/util/ZoneInfoDB.java | 3 | ||||
-rw-r--r-- | luni/src/main/native/libcore_icu_ICU.cpp | 80 |
2 files changed, 64 insertions, 19 deletions
diff --git a/luni/src/main/java/libcore/util/ZoneInfoDB.java b/luni/src/main/java/libcore/util/ZoneInfoDB.java index 906ec14..b8e1dad 100644 --- a/luni/src/main/java/libcore/util/ZoneInfoDB.java +++ b/luni/src/main/java/libcore/util/ZoneInfoDB.java @@ -41,7 +41,8 @@ import libcore.io.MemoryMappedFile; */ public final class ZoneInfoDB { private static final TzData DATA = - new TzData(System.getenv("ANDROID_ROOT") + "/usr/share/zoneinfo/tzdata"); + new TzData(System.getenv("ANDROID_DATA") + "/misc/zoneinfo/current/tzdata", + System.getenv("ANDROID_ROOT") + "/usr/share/zoneinfo/tzdata"); public static class TzData { /** 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)); } |