1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_ANDROID_JNI_ANDROID_H_ 6 #define BASE_ANDROID_JNI_ANDROID_H_ 7 8 #include <jni.h> 9 #include <sys/types.h> 10 11 #include <string> 12 13 #include "base/android/scoped_java_ref.h" 14 #include "base/atomicops.h" 15 #include "base/base_export.h" 16 #include "base/compiler_specific.h" 17 #include "base/debug/debugging_buildflags.h" 18 #include "base/debug/stack_trace.h" 19 #include "base/macros.h" 20 21 #if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) 22 23 // When profiling is enabled (enable_profiling=true) this macro is added to 24 // all generated JNI stubs so that it becomes the last thing that runs before 25 // control goes into Java. 26 // 27 // This macro saves stack frame pointer of the current function. Saved value 28 // used later by JNI_LINK_SAVED_FRAME_POINTER. 29 #define JNI_SAVE_FRAME_POINTER \ 30 base::android::JNIStackFrameSaver jni_frame_saver(__builtin_frame_address(0)) 31 32 // When profiling is enabled (enable_profiling=true) this macro is added to 33 // all generated JNI callbacks so that it becomes the first thing that runs 34 // after control returns from Java. 35 // 36 // This macro links stack frame of the current function to the stack frame 37 // saved by JNI_SAVE_FRAME_POINTER, allowing frame-based unwinding 38 // (used by the heap profiler) to produce complete traces. 39 #define JNI_LINK_SAVED_FRAME_POINTER \ 40 base::debug::ScopedStackFrameLinker jni_frame_linker( \ 41 __builtin_frame_address(0), \ 42 base::android::JNIStackFrameSaver::SavedFrame()) 43 44 #else 45 46 // Frame-based stack unwinding is not supported, do nothing. 47 #define JNI_SAVE_FRAME_POINTER 48 #define JNI_LINK_SAVED_FRAME_POINTER 49 50 #endif // BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) 51 52 namespace base { 53 namespace android { 54 55 // Used to mark symbols to be exported in a shared library's symbol table. 56 #define JNI_EXPORT __attribute__ ((visibility("default"))) 57 58 // Contains the registration method information for initializing JNI bindings. 59 struct RegistrationMethod { 60 const char* name; 61 bool (*func)(JNIEnv* env); 62 }; 63 64 // Attaches the current thread to the VM (if necessary) and return the JNIEnv*. 65 BASE_EXPORT JNIEnv* AttachCurrentThread(); 66 67 // Same to AttachCurrentThread except that thread name will be set to 68 // |thread_name| if it is the first call. Otherwise, thread_name won't be 69 // changed. AttachCurrentThread() doesn't regard underlying platform thread 70 // name, but just resets it to "Thread-???". This function should be called 71 // right after new thread is created if it is important to keep thread name. 72 BASE_EXPORT JNIEnv* AttachCurrentThreadWithName(const std::string& thread_name); 73 74 // Detaches the current thread from VM if it is attached. 75 BASE_EXPORT void DetachFromVM(); 76 77 // Initializes the global JVM. 78 BASE_EXPORT void InitVM(JavaVM* vm); 79 80 // Returns true if the global JVM has been initialized. 81 BASE_EXPORT bool IsVMInitialized(); 82 83 // Initializes the global ClassLoader used by the GetClass and LazyGetClass 84 // methods. This is needed because JNI will use the base ClassLoader when there 85 // is no Java code on the stack. The base ClassLoader doesn't know about any of 86 // the application classes and will fail to lookup anything other than system 87 // classes. 88 BASE_EXPORT void InitReplacementClassLoader( 89 JNIEnv* env, 90 const JavaRef<jobject>& class_loader); 91 92 // Finds the class named |class_name| and returns it. 93 // Use this method instead of invoking directly the JNI FindClass method (to 94 // prevent leaking local references). 95 // This method triggers a fatal assertion if the class could not be found. 96 // Use HasClass if you need to check whether the class exists. 97 BASE_EXPORT ScopedJavaLocalRef<jclass> GetClass(JNIEnv* env, 98 const char* class_name); 99 100 // The method will initialize |atomic_class_id| to contain a global ref to the 101 // class. And will return that ref on subsequent calls. It's the caller's 102 // responsibility to release the ref when it is no longer needed. 103 // The caller is responsible to zero-initialize |atomic_method_id|. 104 // It's fine to simultaneously call this on multiple threads referencing the 105 // same |atomic_method_id|. 106 BASE_EXPORT jclass LazyGetClass( 107 JNIEnv* env, 108 const char* class_name, 109 base::subtle::AtomicWord* atomic_class_id); 110 111 // This class is a wrapper for JNIEnv Get(Static)MethodID. 112 class BASE_EXPORT MethodID { 113 public: 114 enum Type { 115 TYPE_STATIC, 116 TYPE_INSTANCE, 117 }; 118 119 // Returns the method ID for the method with the specified name and signature. 120 // This method triggers a fatal assertion if the method could not be found. 121 template<Type type> 122 static jmethodID Get(JNIEnv* env, 123 jclass clazz, 124 const char* method_name, 125 const char* jni_signature); 126 127 // The caller is responsible to zero-initialize |atomic_method_id|. 128 // It's fine to simultaneously call this on multiple threads referencing the 129 // same |atomic_method_id|. 130 template<Type type> 131 static jmethodID LazyGet(JNIEnv* env, 132 jclass clazz, 133 const char* method_name, 134 const char* jni_signature, 135 base::subtle::AtomicWord* atomic_method_id); 136 }; 137 138 // Returns true if an exception is pending in the provided JNIEnv*. 139 BASE_EXPORT bool HasException(JNIEnv* env); 140 141 // If an exception is pending in the provided JNIEnv*, this function clears it 142 // and returns true. 143 BASE_EXPORT bool ClearException(JNIEnv* env); 144 145 // This function will call CHECK() macro if there's any pending exception. 146 BASE_EXPORT void CheckException(JNIEnv* env); 147 148 // This returns a string representation of the java stack trace. 149 BASE_EXPORT std::string GetJavaExceptionInfo(JNIEnv* env, 150 jthrowable java_throwable); 151 152 #if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) 153 154 // Saves caller's PC and stack frame in a thread-local variable. 155 // Implemented only when profiling is enabled (enable_profiling=true). 156 class BASE_EXPORT JNIStackFrameSaver { 157 public: 158 JNIStackFrameSaver(void* current_fp); 159 ~JNIStackFrameSaver(); 160 static void* SavedFrame(); 161 162 private: 163 void* previous_fp_; 164 165 DISALLOW_COPY_AND_ASSIGN(JNIStackFrameSaver); 166 }; 167 168 #endif // BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) 169 170 } // namespace android 171 } // namespace base 172 173 #endif // BASE_ANDROID_JNI_ANDROID_H_ 174