Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 735aa554 authored by Jerome Gaillard's avatar Jerome Gaillard Committed by Android (Google) Code Review
Browse files

Merge changes from topic "cherrypicker-L33600030007059837:N51300030113435133" into main

* changes:
  Reintroduce support for setting the ICU default locale.
  Fix ICU-related failures in Robolectric.
  Register NativeAllocationRegistry JNI methods via jni wrappers.
  Fix layoutlib build
  Add back support for 'method_binding_format' in HostRuntime.cpp
parents 0c488346 26667c51
Loading
Loading
Loading
Loading
+61 −22
Original line number Diff line number Diff line
@@ -20,7 +20,9 @@
#include <android_runtime/AndroidRuntime.h>
#include <jni_wrappers.h>
#include <nativehelper/JNIHelp.h>
#include <nativehelper/ScopedUtfChars.h>
#include <nativehelper/jni_macros.h>
#include <unicode/locid.h>
#include <unicode/putil.h>
#include <unicode/udata.h>

@@ -64,7 +66,7 @@ static JNINativeMethod gMethods[] = {
};

int register_libcore_util_NativeAllocationRegistry(JNIEnv* env) {
    return jniRegisterNativeMethods(env, "libcore/util/NativeAllocationRegistry", gMethods,
    return android::RegisterMethodsOrDie(env, "libcore/util/NativeAllocationRegistry", gMethods,
                                         NELEM(gMethods));
}

@@ -259,11 +261,21 @@ static void* mmapFile(const char* dataFilePath) {
#endif
}

// Loads the ICU data file from the location specified in the system property ro.icu.data.path
static void loadIcuData() {
    string icuPath = base::GetProperty("ro.icu.data.path", "");
    if (!icuPath.empty()) {
        // Set the location of ICU data
// returns result from java.lang.System.getProperty
static string getJavaProperty(JNIEnv* env, const char* property_name) {
    jclass system = FindClassOrDie(env, "java/lang/System");
    jmethodID getPropertyMethod =
            GetStaticMethodIDOrDie(env, system, "getProperty",
                                   "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");

    auto jString = (jstring)env->CallStaticObjectMethod(system, getPropertyMethod,
                                                        env->NewStringUTF(property_name),
                                                        env->NewStringUTF(""));
    ScopedUtfChars chars(env, jString);
    return string(chars.c_str());
}

static void loadIcuData(string icuPath) {
    void* addr = mmapFile(icuPath.c_str());
    UErrorCode err = U_ZERO_ERROR;
    udata_setCommonData(addr, &err);
@@ -271,23 +283,45 @@ static void loadIcuData() {
        ALOGE("Unable to load ICU data\n");
    }
}

// Loads the ICU data file from the location specified in properties.
// First try specified in the system property ro.icu.data.path,
// then fallback to java property icu.data.path
static void loadIcuData() {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    string icuPath = base::GetProperty("ro.icu.data.path", "");
    if (!icuPath.empty()) {
        loadIcuData(icuPath);
    } else {
        // fallback to read from java.lang.System.getProperty
        string icuPathFromJava = getJavaProperty(env, "icu.data.path");
        if (!icuPathFromJava.empty()) {
            loadIcuData(icuPathFromJava);
        }
    }

static int register_android_core_classes(JNIEnv* env) {
    jclass system = FindClassOrDie(env, "java/lang/System");
    jmethodID getPropertyMethod =
            GetStaticMethodIDOrDie(env, system, "getProperty",
                                   "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
    // Check for the ICU default locale property. In Libcore, the default ICU
    // locale is set when ICU.setDefaultLocale is called, which is called by
    // Libcore's implemenentation of Java's Locale.setDefault. The default
    // locale is used in cases such as when ucol_open(NULL, ...) is called, for
    // example in SQLite's 'COLLATE UNICODE'.
    string icuLocaleDefault = getJavaProperty(env, "icu.locale.default");
    if (!icuLocaleDefault.empty()) {
        UErrorCode status = U_ZERO_ERROR;
        icu::Locale locale = icu::Locale::forLanguageTag(icuLocaleDefault.c_str(), status);
        if (U_SUCCESS(status)) {
            icu::Locale::setDefault(locale, status);
        }
        if (U_FAILURE(status)) {
            fprintf(stderr, "Failed to set the ICU default locale to '%s' (error code %d)\n",
                    icuLocaleDefault.c_str(), status);
        }
    }
}

    // Get the names of classes that need to register their native methods
    auto nativesClassesJString =
            (jstring)env->CallStaticObjectMethod(system, getPropertyMethod,
                                                 env->NewStringUTF("core_native_classes"),
                                                 env->NewStringUTF(""));
    const char* nativesClassesArray = env->GetStringUTFChars(nativesClassesJString, nullptr);
    string nativesClassesString(nativesClassesArray);
static int register_android_core_classes(JNIEnv* env) {
    string nativesClassesString = getJavaProperty(env, "core_native_classes");
    vector<string> classesToRegister = parseCsv(nativesClassesString);
    env->ReleaseStringUTFChars(nativesClassesJString, nativesClassesArray);

    if (register_jni_procs(gRegJNIMap, classesToRegister, env) < 0) {
        return JNI_ERR;
@@ -359,6 +393,11 @@ void AndroidRuntime::onStarted() {

void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();

    auto method_binding_format = getJavaProperty(env, "method_binding_format");

    setJniMethodFormat(method_binding_format);

    // Register native functions.
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android native methods\n");