jvm_android.h 6.4 KB

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