/* * Retrieve string resource with a given name * arguments: * in: resourceName, name of string resource to retrieve * return: string resource value, returns "" when there is no string resource with given name */ std::string JNIHelper::GetStringResource(const std::string& resourceName) { if (activity_ == NULL) { LOGI("JNIHelper has not been initialized. Call init() to initialize the " "helper"); return std::string(""); } // Lock mutex std::lock_guard<std::mutex> lock(mutex_); JNIEnv *env = AttachCurrentThread(); jstring name = env->NewStringUTF(resourceName.c_str()); jstring ret = (jstring) CallObjectMethod("getStringResource", "(Ljava/lang/String;)Ljava/lang/String;", name); const char *resource = env->GetStringUTFChars(ret, NULL); std::string s = std::string(resource); env->ReleaseStringUTFChars(ret, resource); env->DeleteLocalRef(ret); env->DeleteLocalRef(name); return s; }
/* * Dtor */ JNIHelper::~JNIHelper() { // Lock mutex std::lock_guard<std::mutex> lock(mutex_); JNIEnv *env = AttachCurrentThread(); env->DeleteGlobalRef(jni_helper_java_ref_); env->DeleteGlobalRef(jni_helper_java_class_); }
void JNIHelper::DeleteObject(jobject obj) { if (obj == NULL) { LOGI("obj can not be NULL"); return; } JNIEnv *env = AttachCurrentThread(); env->DeleteGlobalRef(obj); }
uint32_t JNIHelper::LoadCubemapTexture(const char *file_name, const int32_t face, const int32_t miplevel, const bool sRGB, int32_t *outWidth, int32_t *outHeight, bool *hasAlpha) { if (activity_ == NULL) { LOGI("JNIHelper has not been initialized. Call init() to initialize the " "helper"); return 0; } // Lock mutex std::lock_guard<std::mutex> lock(mutex_); JNIEnv *env = AttachCurrentThread(); jstring name = env->NewStringUTF(file_name); jmethodID mid = env->GetMethodID(jni_helper_java_class_, "loadCubemapTexture", "(Ljava/lang/String;IIZ)Ljava/lang/Object;"); jobject out = env->CallObjectMethod(jni_helper_java_ref_, mid, name, face, miplevel); jclass javaCls = RetrieveClass(env, "com/sample/helper/NDKHelper$TextureInformation"); jfieldID fidRet = env->GetFieldID(javaCls, "ret", "Z"); jfieldID fidHasAlpha = env->GetFieldID(javaCls, "alphaChannel", "Z"); jfieldID fidWidth = env->GetFieldID(javaCls, "originalWidth", "I"); jfieldID fidHeight = env->GetFieldID(javaCls, "originalHeight", "I"); bool ret = env->GetBooleanField(out, fidRet); bool alpha = env->GetBooleanField(out, fidHasAlpha); int32_t width = env->GetIntField(out, fidWidth); int32_t height = env->GetIntField(out, fidHeight); if (!ret) { LOGI("Texture load failed %s", file_name); } LOGI("Loaded texture original size:%dx%d alpha:%d", width, height, (int32_t) alpha); if (outWidth != NULL) { *outWidth = width; } if (outHeight != NULL) { *outHeight = height; } if (hasAlpha != NULL) { *hasAlpha = alpha; } env->DeleteLocalRef(name); env->DeleteLocalRef(javaCls); return 0; }
jobject JNIHelper::CreateObject(const char *class_name) { JNIEnv *env = AttachCurrentThread(); jclass cls = env->FindClass(class_name); jmethodID constructor = env->GetMethodID(cls, "<init>", "()V"); jobject obj = env->NewObject(cls, constructor); jobject objGlobal = env->NewGlobalRef(obj); env->DeleteLocalRef(obj); env->DeleteLocalRef(cls); return objGlobal; }
void JNIHelper::RunOnUiThread(std::function<void()> callback) { // Lock mutex std::lock_guard<std::mutex> lock(mutex_); JNIEnv *env = AttachCurrentThread(); static jmethodID mid = NULL; if (mid == NULL) mid = env->GetMethodID(jni_helper_java_class_, "runOnUIThread", "(J)V"); // Allocate temporary function object to be passed around std::function<void()> *pCallback = new std::function<void()>(callback); env->CallVoidMethod(jni_helper_java_ref_, mid, (int64_t) pCallback); }
int32_t JNIHelper::GetNativeAudioSampleRate() { if (activity_ == NULL) { LOGI("JNIHelper has not been initialized. Call init() to initialize the " "helper"); return 0; } JNIEnv *env = AttachCurrentThread(); jmethodID mid = env->GetMethodID(jni_helper_java_class_, "getNativeAudioSampleRate", "()I"); int32_t i = env->CallIntMethod(jni_helper_java_ref_, mid); return i; }
uint32_t platformLanIP() { auto env = gApp->activity->env; auto vm = gApp->activity->vm; auto obj = gApp->activity->clazz; vm->AttachCurrentThread( &env, NULL ); auto clazz = env->GetObjectClass(obj); jmethodID methodID = env->GetMethodID(clazz, "getLanIp", "()I"); auto result = env->CallIntMethod(obj, methodID); vm->DetachCurrentThread(); return result; }
int platformVibrate(uint64_t milliseconds) { auto env = gApp->activity->env; auto vm = gApp->activity->vm; auto obj = gApp->activity->clazz; vm->AttachCurrentThread( &env, NULL ); auto clazz = env->GetObjectClass(obj); jmethodID vibrateID = env->GetMethodID(clazz, "vibrate", "(J)I"); auto result = env->CallIntMethod(obj, vibrateID, milliseconds); vm->DetachCurrentThread(); return result; }
void platformSetOrientation(int orientation) { auto env = gApp->activity->env; auto vm = gApp->activity->vm; auto obj = gApp->activity->clazz; vm->AttachCurrentThread( &env, NULL ); auto clazz = env->GetObjectClass(obj); jmethodID orientationID = env->GetMethodID(clazz, "setOrientation", "(I)V"); env->CallVoidMethod(obj, orientationID, orientation); vm->DetachCurrentThread(); }
FlingAnimator::FlingAnimator() { // hold the global reference of the Java objects. JNIEnv* env = AttachCurrentThread(); ASSERT(env); ScopedJavaLocalRef<jclass> cls(GetClass(env, "android/widget/OverScroller")); jmethodID constructor = GetMethodID(env, cls, "<init>", "(Landroid/content/Context;)V"); ScopedJavaLocalRef<jobject> tmp(env, env->NewObject(cls.obj(), constructor, GetApplicationContext())); ASSERT(tmp.obj()); m_javaScroller.Reset(tmp); m_flingMethodId = GetMethodID(env, cls, "fling", "(IIIIIIIIII)V"); m_abortMethodId = GetMethodID(env, cls, "abortAnimation", "()V"); m_computeMethodId = GetMethodID(env, cls, "computeScrollOffset", "()Z"); m_getXMethodId = GetMethodID(env, cls, "getCurrX", "()I"); m_getYMethodId = GetMethodID(env, cls, "getCurrY", "()I"); }
static void callJNIReturnString(const char* str, char* result) { auto env = gApp->activity->env; auto vm = gApp->activity->vm; auto obj = gApp->activity->clazz; vm->AttachCurrentThread( &env, NULL ); auto clazz = env->GetObjectClass(obj); jmethodID methodID = env->GetMethodID(clazz, str, "()[B"); auto array = (jbyteArray)env->CallObjectMethod(obj, methodID); auto ptr = env->GetByteArrayElements(array, 0); int len = env->GetArrayLength(array); memcpy(result, ptr, len); result[len] = '\0'; env->ReleaseByteArrayElements(array, ptr, JNI_ABORT); vm->DetachCurrentThread(); }
std::string JNIHelper::GetExternalFilesDir() { if (activity_ == NULL) { LOGI("JNIHelper has not been initialized. Call init() to initialize the " "helper"); return std::string(""); } // Lock mutex std::lock_guard<std::mutex> lock(mutex_); // First, try reading from externalFileDir; JNIEnv *env = AttachCurrentThread(); jstring strPath = GetExternalFilesDirJString(env); const char *path = env->GetStringUTFChars(strPath, NULL); std::string s(path); env->ReleaseStringUTFChars(strPath, path); env->DeleteLocalRef(strPath); return s; }
void JNIHelper::CallVoidMethod(const char *strMethodName, const char *strSignature, ...) { if (activity_ == NULL) { LOGI("JNIHelper has not been initialized. Call init() to initialize the " "helper"); return; } JNIEnv *env = AttachCurrentThread(); jmethodID mid = env->GetMethodID(jni_helper_java_class_, strMethodName, strSignature); if (mid == NULL) { LOGI("method ID %s, '%s' not found", strMethodName, strSignature); return; } va_list args; va_start(args, strSignature); env->CallVoidMethodV(jni_helper_java_ref_, mid, args); va_end(args); return; }
std::string JNIHelper::ConvertString(const char *str, const char *encode) { if (activity_ == NULL) { LOGI("JNIHelper has not been initialized. Call init() to initialize the " "helper"); return std::string(""); } // Lock mutex std::lock_guard<std::mutex> lock(mutex_); JNIEnv *env = AttachCurrentThread(); env->PushLocalFrame(16); int32_t iLength = strlen((const char *)str); jbyteArray array = env->NewByteArray(iLength); env->SetByteArrayRegion(array, 0, iLength, (const signed char *)str); jstring strEncode = env->NewStringUTF(encode); jclass cls = env->FindClass("java/lang/String"); jmethodID ctor = env->GetMethodID(cls, "<init>", "([BLjava/lang/String;)V"); jstring object = (jstring) env->NewObject(cls, ctor, array, strEncode); const char *cparam = env->GetStringUTFChars(object, NULL); std::string s = std::string(cparam); env->ReleaseStringUTFChars(object, cparam); env->DeleteLocalRef(array); env->DeleteLocalRef(strEncode); env->DeleteLocalRef(object); env->DeleteLocalRef(cls); env->PopLocalFrame(NULL); return s; }
bool JNIHelper::CallBooleanMethod(jobject object, const char *strMethodName, const char *strSignature, ...) { bool b; if (activity_ == NULL) { LOGI("JNIHelper has not been initialized. Call init() to initialize the " "helper"); return false; } JNIEnv *env = AttachCurrentThread(); jclass cls = env->GetObjectClass(object); jmethodID mid = env->GetMethodID(cls, strMethodName, strSignature); if (mid == NULL) { LOGI("method ID %s, '%s' not found", strMethodName, strSignature); return false; } va_list args; va_start(args, strSignature); b = env->CallBooleanMethodV(object, mid, args); va_end(args); env->DeleteLocalRef(cls); return b; }
// static void ThreadStore::AttachCurrentThread() { AttachCurrentThread(true); }
uint32_t JNIHelper::LoadTexture(const char *file_name, int32_t *outWidth, int32_t *outHeight, bool *hasAlpha) { if (activity_ == NULL) { LOGI("JNIHelper has not been initialized. Call init() to initialize the " "helper"); return 0; } // Lock mutex std::lock_guard<std::mutex> lock(mutex_); JNIEnv *env = AttachCurrentThread(); jstring name = env->NewStringUTF(file_name); GLuint tex; glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); jmethodID mid = env->GetMethodID(jni_helper_java_class_, "loadTexture", "(Ljava/lang/String;)Ljava/lang/Object;"); jobject out = env->CallObjectMethod(jni_helper_java_ref_, mid, name); jclass javaCls = RetrieveClass(env, "com/sample/helper/NDKHelper$TextureInformation"); jfieldID fidRet = env->GetFieldID(javaCls, "ret", "Z"); jfieldID fidHasAlpha = env->GetFieldID(javaCls, "alphaChannel", "Z"); jfieldID fidWidth = env->GetFieldID(javaCls, "originalWidth", "I"); jfieldID fidHeight = env->GetFieldID(javaCls, "originalHeight", "I"); bool ret = env->GetBooleanField(out, fidRet); bool alpha = env->GetBooleanField(out, fidHasAlpha); int32_t width = env->GetIntField(out, fidWidth); int32_t height = env->GetIntField(out, fidHeight); if (!ret) { glDeleteTextures(1, &tex); tex = -1; LOGI("Texture load failed %s", file_name); } LOGI("Loaded texture original size:%dx%d alpha:%d", width, height, (int32_t) alpha); if (outWidth != NULL) { *outWidth = width; } if (outHeight != NULL) { *outHeight = height; } if (hasAlpha != NULL) { *hasAlpha = alpha; } //Generate mipmap glGenerateMipmap(GL_TEXTURE_2D); env->DeleteLocalRef(name); env->DeleteLocalRef(javaCls); return tex; }
/* * ReadFile */ bool JNIHelper::ReadFile(const char *fileName, std::vector<uint8_t> *buffer_ref) { if (activity_ == NULL) { LOGI("JNIHelper has not been initialized.Call init() to initialize the " "helper"); return false; } // Lock mutex std::lock_guard<std::mutex> lock(mutex_); // First, try reading from externalFileDir; JNIEnv *env = AttachCurrentThread(); jstring str_path = GetExternalFilesDirJString(env); const char *path = env->GetStringUTFChars(str_path, NULL); std::string s(path); if (fileName[0] != '/') { s.append("/"); } s.append(fileName); std::ifstream f(s.c_str(), std::ios::binary); env->ReleaseStringUTFChars(str_path, path); env->DeleteLocalRef(str_path); activity_->vm->DetachCurrentThread(); if (f) { LOGI("reading:%s", s.c_str()); f.seekg(0, std::ifstream::end); int32_t fileSize = f.tellg(); f.seekg(0, std::ifstream::beg); buffer_ref->reserve(fileSize); buffer_ref->assign(std::istreambuf_iterator<char>(f), std::istreambuf_iterator<char>()); f.close(); return true; } else { //Fallback to assetManager AAssetManager *assetManager = activity_->assetManager; AAsset *assetFile = AAssetManager_open(assetManager, fileName, AASSET_MODE_BUFFER); if (!assetFile) { return false; } uint8_t *data = (uint8_t *)AAsset_getBuffer(assetFile); int32_t size = AAsset_getLength(assetFile); if (data == NULL) { AAsset_close(assetFile); LOGI("Failed to load:%s", fileName); return false; } buffer_ref->reserve(size); buffer_ref->assign(data, data + size); AAsset_close(assetFile); return true; } }