1*d9f75844SAndroid Build Coastguard Worker /* 2*d9f75844SAndroid Build Coastguard Worker * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 3*d9f75844SAndroid Build Coastguard Worker * 4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license 5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source 6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found 7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may 8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree. 9*d9f75844SAndroid Build Coastguard Worker */ 10*d9f75844SAndroid Build Coastguard Worker 11*d9f75844SAndroid Build Coastguard Worker #ifndef MODULES_UTILITY_INCLUDE_JVM_ANDROID_H_ 12*d9f75844SAndroid Build Coastguard Worker #define MODULES_UTILITY_INCLUDE_JVM_ANDROID_H_ 13*d9f75844SAndroid Build Coastguard Worker 14*d9f75844SAndroid Build Coastguard Worker #include <jni.h> 15*d9f75844SAndroid Build Coastguard Worker 16*d9f75844SAndroid Build Coastguard Worker #include <memory> 17*d9f75844SAndroid Build Coastguard Worker #include <string> 18*d9f75844SAndroid Build Coastguard Worker 19*d9f75844SAndroid Build Coastguard Worker #include "api/sequence_checker.h" 20*d9f75844SAndroid Build Coastguard Worker #include "modules/utility/include/helpers_android.h" 21*d9f75844SAndroid Build Coastguard Worker 22*d9f75844SAndroid Build Coastguard Worker namespace webrtc { 23*d9f75844SAndroid Build Coastguard Worker 24*d9f75844SAndroid Build Coastguard Worker // RAII JavaVM AttachCurrentThread/DetachCurrentThread object. 25*d9f75844SAndroid Build Coastguard Worker // 26*d9f75844SAndroid Build Coastguard Worker // The JNI interface pointer (JNIEnv) is valid only in the current thread. 27*d9f75844SAndroid Build Coastguard Worker // Should another thread need to access the Java VM, it must first call 28*d9f75844SAndroid Build Coastguard Worker // AttachCurrentThread() to attach itself to the VM and obtain a JNI interface 29*d9f75844SAndroid Build Coastguard Worker // pointer. The native thread remains attached to the VM until it calls 30*d9f75844SAndroid Build Coastguard Worker // DetachCurrentThread() to detach. 31*d9f75844SAndroid Build Coastguard Worker class JvmThreadConnector { 32*d9f75844SAndroid Build Coastguard Worker public: 33*d9f75844SAndroid Build Coastguard Worker JvmThreadConnector(); 34*d9f75844SAndroid Build Coastguard Worker ~JvmThreadConnector(); 35*d9f75844SAndroid Build Coastguard Worker 36*d9f75844SAndroid Build Coastguard Worker private: 37*d9f75844SAndroid Build Coastguard Worker SequenceChecker thread_checker_; 38*d9f75844SAndroid Build Coastguard Worker bool attached_; 39*d9f75844SAndroid Build Coastguard Worker }; 40*d9f75844SAndroid Build Coastguard Worker 41*d9f75844SAndroid Build Coastguard Worker // This class is created by the NativeRegistration class and is used to wrap 42*d9f75844SAndroid Build Coastguard Worker // the actual Java object handle (jobject) on which we can call methods from 43*d9f75844SAndroid Build Coastguard Worker // C++ in to Java. See example in JVM for more details. 44*d9f75844SAndroid Build Coastguard Worker // TODO(henrika): extend support for type of function calls. 45*d9f75844SAndroid Build Coastguard Worker class GlobalRef { 46*d9f75844SAndroid Build Coastguard Worker public: 47*d9f75844SAndroid Build Coastguard Worker GlobalRef(JNIEnv* jni, jobject object); 48*d9f75844SAndroid Build Coastguard Worker ~GlobalRef(); 49*d9f75844SAndroid Build Coastguard Worker 50*d9f75844SAndroid Build Coastguard Worker jboolean CallBooleanMethod(jmethodID methodID, ...); 51*d9f75844SAndroid Build Coastguard Worker jint CallIntMethod(jmethodID methodID, ...); 52*d9f75844SAndroid Build Coastguard Worker void CallVoidMethod(jmethodID methodID, ...); 53*d9f75844SAndroid Build Coastguard Worker 54*d9f75844SAndroid Build Coastguard Worker private: 55*d9f75844SAndroid Build Coastguard Worker JNIEnv* const jni_; 56*d9f75844SAndroid Build Coastguard Worker const jobject j_object_; 57*d9f75844SAndroid Build Coastguard Worker }; 58*d9f75844SAndroid Build Coastguard Worker 59*d9f75844SAndroid Build Coastguard Worker // Wraps the jclass object on which we can call GetMethodId() functions to 60*d9f75844SAndroid Build Coastguard Worker // query method IDs. 61*d9f75844SAndroid Build Coastguard Worker class JavaClass { 62*d9f75844SAndroid Build Coastguard Worker public: JavaClass(JNIEnv * jni,jclass clazz)63*d9f75844SAndroid Build Coastguard Worker JavaClass(JNIEnv* jni, jclass clazz) : jni_(jni), j_class_(clazz) {} ~JavaClass()64*d9f75844SAndroid Build Coastguard Worker ~JavaClass() {} 65*d9f75844SAndroid Build Coastguard Worker 66*d9f75844SAndroid Build Coastguard Worker jmethodID GetMethodId(const char* name, const char* signature); 67*d9f75844SAndroid Build Coastguard Worker jmethodID GetStaticMethodId(const char* name, const char* signature); 68*d9f75844SAndroid Build Coastguard Worker jobject CallStaticObjectMethod(jmethodID methodID, ...); 69*d9f75844SAndroid Build Coastguard Worker jint CallStaticIntMethod(jmethodID methodID, ...); 70*d9f75844SAndroid Build Coastguard Worker 71*d9f75844SAndroid Build Coastguard Worker protected: 72*d9f75844SAndroid Build Coastguard Worker JNIEnv* const jni_; 73*d9f75844SAndroid Build Coastguard Worker jclass const j_class_; 74*d9f75844SAndroid Build Coastguard Worker }; 75*d9f75844SAndroid Build Coastguard Worker 76*d9f75844SAndroid Build Coastguard Worker // Adds support of the NewObject factory method to the JavaClass class. 77*d9f75844SAndroid Build Coastguard Worker // See example in JVM for more details on how to use it. 78*d9f75844SAndroid Build Coastguard Worker class NativeRegistration : public JavaClass { 79*d9f75844SAndroid Build Coastguard Worker public: 80*d9f75844SAndroid Build Coastguard Worker NativeRegistration(JNIEnv* jni, jclass clazz); 81*d9f75844SAndroid Build Coastguard Worker ~NativeRegistration(); 82*d9f75844SAndroid Build Coastguard Worker 83*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<GlobalRef> NewObject(const char* name, 84*d9f75844SAndroid Build Coastguard Worker const char* signature, 85*d9f75844SAndroid Build Coastguard Worker ...); 86*d9f75844SAndroid Build Coastguard Worker 87*d9f75844SAndroid Build Coastguard Worker private: 88*d9f75844SAndroid Build Coastguard Worker JNIEnv* const jni_; 89*d9f75844SAndroid Build Coastguard Worker }; 90*d9f75844SAndroid Build Coastguard Worker 91*d9f75844SAndroid Build Coastguard Worker // This class is created by the JVM class and is used to expose methods that 92*d9f75844SAndroid Build Coastguard Worker // needs the JNI interface pointer but its main purpose is to create a 93*d9f75844SAndroid Build Coastguard Worker // NativeRegistration object given name of a Java class and a list of native 94*d9f75844SAndroid Build Coastguard Worker // methods. See example in JVM for more details. 95*d9f75844SAndroid Build Coastguard Worker class JNIEnvironment { 96*d9f75844SAndroid Build Coastguard Worker public: 97*d9f75844SAndroid Build Coastguard Worker explicit JNIEnvironment(JNIEnv* jni); 98*d9f75844SAndroid Build Coastguard Worker ~JNIEnvironment(); 99*d9f75844SAndroid Build Coastguard Worker 100*d9f75844SAndroid Build Coastguard Worker // Registers native methods with the Java class specified by `name`. 101*d9f75844SAndroid Build Coastguard Worker // Note that the class name must be one of the names in the static 102*d9f75844SAndroid Build Coastguard Worker // `loaded_classes` array defined in jvm_android.cc. 103*d9f75844SAndroid Build Coastguard Worker // This method must be called on the construction thread. 104*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<NativeRegistration> RegisterNatives( 105*d9f75844SAndroid Build Coastguard Worker const char* name, 106*d9f75844SAndroid Build Coastguard Worker const JNINativeMethod* methods, 107*d9f75844SAndroid Build Coastguard Worker int num_methods); 108*d9f75844SAndroid Build Coastguard Worker 109*d9f75844SAndroid Build Coastguard Worker // Converts from Java string to std::string. 110*d9f75844SAndroid Build Coastguard Worker // This method must be called on the construction thread. 111*d9f75844SAndroid Build Coastguard Worker std::string JavaToStdString(const jstring& j_string); 112*d9f75844SAndroid Build Coastguard Worker 113*d9f75844SAndroid Build Coastguard Worker private: 114*d9f75844SAndroid Build Coastguard Worker SequenceChecker thread_checker_; 115*d9f75844SAndroid Build Coastguard Worker JNIEnv* const jni_; 116*d9f75844SAndroid Build Coastguard Worker }; 117*d9f75844SAndroid Build Coastguard Worker 118*d9f75844SAndroid Build Coastguard Worker // Main class for working with Java from C++ using JNI in WebRTC. 119*d9f75844SAndroid Build Coastguard Worker // 120*d9f75844SAndroid Build Coastguard Worker // Example usage: 121*d9f75844SAndroid Build Coastguard Worker // 122*d9f75844SAndroid Build Coastguard Worker // // At initialization (e.g. in JNI_OnLoad), call JVM::Initialize. 123*d9f75844SAndroid Build Coastguard Worker // JNIEnv* jni = ::base::android::AttachCurrentThread(); 124*d9f75844SAndroid Build Coastguard Worker // JavaVM* jvm = NULL; 125*d9f75844SAndroid Build Coastguard Worker // jni->GetJavaVM(&jvm); 126*d9f75844SAndroid Build Coastguard Worker // webrtc::JVM::Initialize(jvm); 127*d9f75844SAndroid Build Coastguard Worker // 128*d9f75844SAndroid Build Coastguard Worker // // Header (.h) file of example class called User. 129*d9f75844SAndroid Build Coastguard Worker // std::unique_ptr<JNIEnvironment> env; 130*d9f75844SAndroid Build Coastguard Worker // std::unique_ptr<NativeRegistration> reg; 131*d9f75844SAndroid Build Coastguard Worker // std::unique_ptr<GlobalRef> obj; 132*d9f75844SAndroid Build Coastguard Worker // 133*d9f75844SAndroid Build Coastguard Worker // // Construction (in .cc file) of User class. 134*d9f75844SAndroid Build Coastguard Worker // User::User() { 135*d9f75844SAndroid Build Coastguard Worker // // Calling thread must be attached to the JVM. 136*d9f75844SAndroid Build Coastguard Worker // env = JVM::GetInstance()->environment(); 137*d9f75844SAndroid Build Coastguard Worker // reg = env->RegisterNatives("org/webrtc/WebRtcTest", ,); 138*d9f75844SAndroid Build Coastguard Worker // obj = reg->NewObject("<init>", ,); 139*d9f75844SAndroid Build Coastguard Worker // } 140*d9f75844SAndroid Build Coastguard Worker // 141*d9f75844SAndroid Build Coastguard Worker // // Each User method can now use `reg` and `obj` and call Java functions 142*d9f75844SAndroid Build Coastguard Worker // // in WebRtcTest.java, e.g. boolean init() {}. 143*d9f75844SAndroid Build Coastguard Worker // bool User::Foo() { 144*d9f75844SAndroid Build Coastguard Worker // jmethodID id = reg->GetMethodId("init", "()Z"); 145*d9f75844SAndroid Build Coastguard Worker // return obj->CallBooleanMethod(id); 146*d9f75844SAndroid Build Coastguard Worker // } 147*d9f75844SAndroid Build Coastguard Worker // 148*d9f75844SAndroid Build Coastguard Worker // // And finally, e.g. in JNI_OnUnLoad, call JVM::Uninitialize. 149*d9f75844SAndroid Build Coastguard Worker // JVM::Uninitialize(); 150*d9f75844SAndroid Build Coastguard Worker class JVM { 151*d9f75844SAndroid Build Coastguard Worker public: 152*d9f75844SAndroid Build Coastguard Worker // Stores global handles to the Java VM interface. 153*d9f75844SAndroid Build Coastguard Worker // Should be called once on a thread that is attached to the JVM. 154*d9f75844SAndroid Build Coastguard Worker static void Initialize(JavaVM* jvm); 155*d9f75844SAndroid Build Coastguard Worker // Like the method above but also passes the context to the ContextUtils 156*d9f75844SAndroid Build Coastguard Worker // class. This method should be used by pure-C++ Android users that can't call 157*d9f75844SAndroid Build Coastguard Worker // ContextUtils.initialize directly. 158*d9f75844SAndroid Build Coastguard Worker static void Initialize(JavaVM* jvm, jobject context); 159*d9f75844SAndroid Build Coastguard Worker // Clears handles stored in Initialize(). Must be called on same thread as 160*d9f75844SAndroid Build Coastguard Worker // Initialize(). 161*d9f75844SAndroid Build Coastguard Worker static void Uninitialize(); 162*d9f75844SAndroid Build Coastguard Worker // Gives access to the global Java VM interface pointer, which then can be 163*d9f75844SAndroid Build Coastguard Worker // used to create a valid JNIEnvironment object or to get a JavaClass object. 164*d9f75844SAndroid Build Coastguard Worker static JVM* GetInstance(); 165*d9f75844SAndroid Build Coastguard Worker 166*d9f75844SAndroid Build Coastguard Worker // Creates a JNIEnvironment object. 167*d9f75844SAndroid Build Coastguard Worker // This method returns a NULL pointer if AttachCurrentThread() has not been 168*d9f75844SAndroid Build Coastguard Worker // called successfully. Use the AttachCurrentThreadIfNeeded class if needed. 169*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<JNIEnvironment> environment(); 170*d9f75844SAndroid Build Coastguard Worker 171*d9f75844SAndroid Build Coastguard Worker // Returns a JavaClass object given class `name`. 172*d9f75844SAndroid Build Coastguard Worker // Note that the class name must be one of the names in the static 173*d9f75844SAndroid Build Coastguard Worker // `loaded_classes` array defined in jvm_android.cc. 174*d9f75844SAndroid Build Coastguard Worker // This method must be called on the construction thread. 175*d9f75844SAndroid Build Coastguard Worker JavaClass GetClass(const char* name); 176*d9f75844SAndroid Build Coastguard Worker 177*d9f75844SAndroid Build Coastguard Worker // TODO(henrika): can we make these private? jvm()178*d9f75844SAndroid Build Coastguard Worker JavaVM* jvm() const { return jvm_; } 179*d9f75844SAndroid Build Coastguard Worker 180*d9f75844SAndroid Build Coastguard Worker protected: 181*d9f75844SAndroid Build Coastguard Worker JVM(JavaVM* jvm); 182*d9f75844SAndroid Build Coastguard Worker ~JVM(); 183*d9f75844SAndroid Build Coastguard Worker 184*d9f75844SAndroid Build Coastguard Worker private: jni()185*d9f75844SAndroid Build Coastguard Worker JNIEnv* jni() const { return GetEnv(jvm_); } 186*d9f75844SAndroid Build Coastguard Worker 187*d9f75844SAndroid Build Coastguard Worker SequenceChecker thread_checker_; 188*d9f75844SAndroid Build Coastguard Worker JavaVM* const jvm_; 189*d9f75844SAndroid Build Coastguard Worker }; 190*d9f75844SAndroid Build Coastguard Worker 191*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc 192*d9f75844SAndroid Build Coastguard Worker 193*d9f75844SAndroid Build Coastguard Worker #endif // MODULES_UTILITY_INCLUDE_JVM_ANDROID_H_ 194