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

Commit 8630b289 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Cherry pick customize JNI method binding name." into main

parents 71780b82 c80e7d04
Loading
Loading
Loading
Loading
+39 −1
Original line number Diff line number Diff line
@@ -69,9 +69,47 @@ static inline T MakeGlobalRefOrDie(JNIEnv* env, T in) {
    return static_cast<T>(res);
}

//  Inline variable that specifies the method binding format.
//  The expected format is 'XX${method}XX', where ${method} represents the original method name.
//  This variable is shared across all translation units. This is treated as a global variable as
//  per C++ 17.
inline std::string jniMethodFormat;

inline static void setJniMethodFormat(std::string value) {
    jniMethodFormat = value;
}

// Potentially translates the given JNINativeMethods if setJniMethodFormat has been set.
// Has no effect otherwise
inline const JNINativeMethod* maybeRenameJniMethods(const JNINativeMethod* gMethods,
                                                    int numMethods) {
    if (jniMethodFormat.empty()) {
        return gMethods;
    }
    // Make a copy of gMethods with reformatted method names.
    JNINativeMethod* modifiedMethods = new JNINativeMethod[numMethods];
    LOG_ALWAYS_FATAL_IF(!modifiedMethods, "Failed to allocate a copy of the JNI methods");

    size_t methodNamePos = jniMethodFormat.find("${method}");
    LOG_ALWAYS_FATAL_IF(methodNamePos == std::string::npos,
                        "Invalid jniMethodFormat: could not find '${method}' in pattern");

    for (int i = 0; i < numMethods; i++) {
        modifiedMethods[i] = gMethods[i];
        std::string modifiedName = jniMethodFormat;
        modifiedName.replace(methodNamePos, 9, gMethods[i].name);
        char* modifiedNameChars = new char[modifiedName.length() + 1];
        LOG_ALWAYS_FATAL_IF(!modifiedNameChars, "Failed to allocate the new method name");
        std::strcpy(modifiedNameChars, modifiedName.c_str());
        modifiedMethods[i].name = modifiedNameChars;
    }
    return modifiedMethods;
}

static inline int RegisterMethodsOrDie(JNIEnv* env, const char* className,
                                       const JNINativeMethod* gMethods, int numMethods) {
    int res = jniRegisterNativeMethods(env, className, gMethods, numMethods);
    const JNINativeMethod* modifiedMethods = maybeRenameJniMethods(gMethods, numMethods);
    int res = jniRegisterNativeMethods(env, className, modifiedMethods, numMethods);
    LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");
    return res;
}