Skip to content

Commit

Permalink
refactor: make native library bridge aware
Browse files Browse the repository at this point in the history
  • Loading branch information
cinit committed Aug 11, 2024
1 parent 5c72c50 commit a78be84
Show file tree
Hide file tree
Showing 15 changed files with 980 additions and 46 deletions.
484 changes: 484 additions & 0 deletions app/src/main/cpp/nativebridge/native_bridge.h

Large diffs are not rendered by default.

15 changes: 14 additions & 1 deletion app/src/main/cpp/qauxv_core/HostInfo.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ static std::optional<std::string> sDataDir;
static std::optional<uint64_t> sLongVersionCode = 0;
static std::optional<JavaVM*> sJavaVM = nullptr;

// can be overridden by HostInfo::InitHostInfo
#ifdef NDEBUG
static bool sIsDebugBuild = false;
#else
static bool sIsDebugBuild = true;
#endif

int HostInfo::GetSdkInt() noexcept {
static int sdkInt = android_get_device_api_level();
return sdkInt;
Expand Down Expand Up @@ -59,6 +66,10 @@ std::string HostInfo::GetDataDir() {
return sDataDir.value();
}

bool HostInfo::IsDebugBuild() noexcept {
return sIsDebugBuild;
}

void HostInfo::PreInitHostInfo(JavaVM* jvm, std::string dataDir) {
CHECK(jvm != nullptr);
CHECK(!dataDir.empty());
Expand All @@ -71,7 +82,8 @@ void HostInfo::InitHostInfo(
std::string dataDir,
std::string_view packageName,
std::string_view versionName,
uint64_t longVersionCode
uint64_t longVersionCode,
bool isDebugBuild
) {
CHECK(!packageName.empty());
CHECK(jvm != nullptr);
Expand All @@ -81,6 +93,7 @@ void HostInfo::InitHostInfo(
sPackageName = packageName;
sVersionName = versionName;
sLongVersionCode = longVersionCode;
sIsDebugBuild = isDebugBuild;
}

} // qauxv
4 changes: 3 additions & 1 deletion app/src/main/cpp/qauxv_core/HostInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class HostInfo {
static std::string GetDataDir();
static uint32_t GetVersionCode32() noexcept;
static uint64_t GetLongVersionCode() noexcept;
static bool IsDebugBuild() noexcept;
static JavaVM* GetJavaVM() noexcept;

static void PreInitHostInfo(JavaVM* jvm, std::string dataDir);
Expand All @@ -34,7 +35,8 @@ class HostInfo {
std::string dataDir,
std::string_view packageName,
std::string_view versionName,
uint64_t longVersionCode
uint64_t longVersionCode,
bool isDebugBuild
);

};
Expand Down
37 changes: 31 additions & 6 deletions app/src/main/cpp/qauxv_core/jni_method_registry.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ std::string NormalizeClassName(std::string_view name) {
* @param class_loader the class loader object.
*/
void RegisterJniLateInitMethodsToClassLoader(JNIEnv* env, JniMethodInitType type, jobject class_loader) {
using qauxv::ThrowExceptionIfNoPendingException;
using qauxv::ThrowIfNoPendingException;
std::vector<JniMethodInitMethodList>* methods = nullptr;
switch (type) {
case JniMethodInitType::kPrimaryPreInit:
Expand Down Expand Up @@ -96,20 +96,45 @@ void RegisterJniLateInitMethodsToClassLoader(JNIEnv* env, JniMethodInitType type
jstring class_name = env->NewStringUTF(NormalizeClassName(method_list.declare_class).c_str());
auto klass = static_cast<jclass>(env->CallObjectMethod(class_loader, kLoadClass, class_name));
if (env->ExceptionCheck() || klass == nullptr) {
ThrowExceptionIfNoPendingException(env, "java/lang/NullPointerException",
fmt::format("class {} not found", method_list.declare_class));
ThrowIfNoPendingException(env, "java/lang/NullPointerException", fmt::format("class {} not found", method_list.declare_class));
return; // with exception
}
const JNINativeMethod* method_array = method_list.methods.data();
if (env->RegisterNatives(klass, method_array, (jint) method_list.methods.size()) != JNI_OK) {
ThrowExceptionIfNoPendingException(env, "java/lang/RuntimeException",
fmt::format("RegisterNatives failed for class {}",
method_list.declare_class));
ThrowIfNoPendingException(env, "java/lang/RuntimeException",
fmt::format("RegisterNatives failed for class {}", method_list.declare_class));
return; // with exception
}
env->DeleteLocalRef(class_name);
env->DeleteLocalRef(klass);
}
}

void RegisterJniMethodsCommon(JNIEnv* env, jobject class_loader, std::string_view klass, const std::vector<JNINativeMethod>& methods) {
jclass kClassLoader = env->FindClass("java/lang/ClassLoader");
// check if the class loader is an instance of ClassLoader
if (!env->IsInstanceOf(class_loader, kClassLoader)) {
env->ThrowNew(env->FindClass("java/lang/IllegalArgumentException"), "class_loader is not an instance of ClassLoader");
return;
}
jmethodID kLoadClass = env->GetMethodID(kClassLoader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
if (kLoadClass == nullptr) {
env->ThrowNew(env->FindClass("java/lang/NoSuchMethodError"), "loadClass method not found");
return;
}
jstring class_name = env->NewStringUTF(NormalizeClassName(klass).c_str());
auto klass_obj = static_cast<jclass>(env->CallObjectMethod(class_loader, kLoadClass, class_name));
if (env->ExceptionCheck() || klass_obj == nullptr) {
ThrowIfNoPendingException(env, "java/lang/NullPointerException", fmt::format("class {} not found", klass));
return; // with exception
}
const JNINativeMethod* method_array = methods.data();
if (env->RegisterNatives(klass_obj, method_array, (jint) methods.size()) != JNI_OK) {
ThrowIfNoPendingException(env, "java/lang/RuntimeException", fmt::format("RegisterNatives failed for class {}", klass));
return; // with exception
}
env->DeleteLocalRef(class_name);
env->DeleteLocalRef(klass_obj);
}

}
2 changes: 2 additions & 0 deletions app/src/main/cpp/qauxv_core/jni_method_registry.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ void RegisterJniLateInitMethod(JniMethodInitType type, const char* declare_class
*/
void RegisterJniLateInitMethodsToClassLoader(JNIEnv* env, JniMethodInitType type, jobject class_loader);

void RegisterJniMethodsCommon(JNIEnv* env, jobject class_loader, std::string_view klass, const std::vector<JNINativeMethod>& methods);

} // qauxv::jniutil

#define REGISTER_PRIMARY_PRE_INIT_NATIVE_METHODS(DECLARE_CLASS, METHOD_ARRAY) \
Expand Down
Loading

0 comments on commit a78be84

Please sign in to comment.