tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

jvm_android.h (6497B)


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