| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| #include "android_jni.h" |
| #include "base/android/log_utils.h" |
| |
| namespace { |
| JavaVM *g_jvm = nullptr; |
| } |
| |
| namespace base { |
| namespace android { |
| |
| void InitVM(JavaVM *vm) { |
| g_jvm = vm; |
| } |
| |
| JNIEnv *AttachCurrentThread() { |
| JNIEnv *env = nullptr; |
| |
| JavaVMAttachArgs args; |
| args.version = JNI_VERSION_1_4; |
| args.name = "weex_sdk_runtime"; |
| args.group = nullptr; |
| |
| jint ret = g_jvm->AttachCurrentThread(&env, &args); |
| if (ret != JNI_OK) { |
| LOGE("weex AttachCurrentThread failed"); |
| env = nullptr; |
| } |
| return env; |
| } |
| |
| void DetachFromVM() { |
| if (g_jvm) { |
| g_jvm->DetachCurrentThread(); |
| } |
| } |
| |
| ScopedLocalJavaRef<jclass> GetClass(JNIEnv *env, const char *class_name) { |
| jclass clazz; |
| clazz = env->FindClass(class_name); |
| return ScopedLocalJavaRef<jclass>(env, clazz); |
| } |
| |
| jclass GetClass(JNIEnv *env, const char *class_name, intptr_t *class_id) { |
| if (*class_id) { |
| return reinterpret_cast<jclass>(*class_id); |
| } |
| ScopedGlobalJavaRef<jclass> clazz; |
| clazz.Reset(env, GetClass(env, class_name)); |
| *class_id = reinterpret_cast<intptr_t>(clazz.Release()); |
| return reinterpret_cast<jclass>(*class_id); |
| } |
| |
| jmethodID GetMethod(JNIEnv *env, jclass clazz, MethodType type, |
| const char *method_name, const char *jni_signature) { |
| if (type == STATIC_METHOD) { |
| return env->GetStaticMethodID(clazz, method_name, jni_signature); |
| } else if (type == INSTANCE_METHOD) { |
| return env->GetMethodID(clazz, method_name, jni_signature); |
| } |
| return 0; |
| } |
| |
| jmethodID GetMethod(JNIEnv *env, jclass clazz, MethodType type, |
| const char *method_name, const char *jni_signature, intptr_t *method_id) { |
| if (*method_id) { |
| return reinterpret_cast<jmethodID>(*method_id); |
| } |
| *method_id = reinterpret_cast<intptr_t>(GetMethod(env, |
| clazz, type, method_name, jni_signature)); |
| return reinterpret_cast<jmethodID>(*method_id); |
| } |
| |
| bool HasException(JNIEnv *env) { |
| return env->ExceptionCheck() != JNI_FALSE; |
| } |
| |
| bool ClearException(JNIEnv *env) { |
| if (!HasException(env)) |
| return false; |
| env->ExceptionDescribe(); |
| env->ExceptionClear(); |
| return true; |
| } |
| |
| void CheckException(JNIEnv *env) { |
| if (!HasException(env)) |
| return; |
| |
| // Exception has been found, might as well tell breakpad about it. |
| jthrowable java_throwable = env->ExceptionOccurred(); |
| if (java_throwable) { |
| // Clear the pending exception, since a local reference is now held. |
| env->ExceptionDescribe(); |
| env->ExceptionClear(); |
| } |
| |
| // Now, feel good about it and die. |
| // CHECK(false) << "Please include Java exception stack in crash report"; |
| } |
| } // namespace android |
| } // namespace base |