1 // Copyright (c) 2013 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_GENERATOR_SAMPLE_FOR_TESTS_H_ 6 #define BASE_ANDROID_JNI_GENERATOR_SAMPLE_FOR_TESTS_H_ 7 8 #include <jni.h> 9 #include <map> 10 #include <string> 11 12 #include "base/android/jni_android.h" 13 14 namespace base { 15 namespace android { 16 17 // This file is used to: 18 // - document the best practices and guidelines on JNI usage. 19 // - ensure sample_for_tests_jni.h compiles and the functions declared in it 20 // as expected. 21 // 22 // Methods are called directly from Java (except RegisterJNI). More 23 // documentation in SampleForTests.java 24 // 25 // For C++ to access Java methods: 26 // - GN Build must be configured to generate bindings: 27 // # Add import at top of file: 28 // if (is_android) { 29 // import("//build/config/android/rules.gni") # For generate_jni(). 30 // } 31 // # ... 32 // # An example target that will rely on JNI: 33 // component("foo") { 34 // # ... normal sources, defines, deps. 35 // # For each jni generated .java -> .h header file in jni_headers 36 // # target there will be a single .cc file here that includes it. 37 // # 38 // # Add a dep for JNI: 39 // if (is_android) { 40 // deps += [ ":foo_jni" ] 41 // } 42 // } 43 // # ... 44 // # Create target for JNI: 45 // if (is_android) { 46 // generate_jni("jni_headers") { 47 // sources = [ 48 // "java/src/org/chromium/example/jni_generator/SampleForTests.java", 49 // ] 50 // jni_package = "foo" 51 // } 52 // android_library("java") { 53 // java_files = [ 54 // "java/src/org/chromium/example/jni_generator/SampleForTests.java", 55 // "java/src/org/chromium/example/jni_generator/NonJniFile.java", 56 // ] 57 // } 58 // } 59 // 60 // For C++ methods to be exposed to Java: 61 // - The generated RegisterNativesImpl method must be called, this is typically 62 // done by having a static RegisterJNI method in the C++ class. 63 // - The RegisterJNI method is added to a module's collection of register 64 // methods, such as: example_jni_registrar.h/cc files which call 65 // base::android::RegisterNativeMethods. 66 // An example_jni_registstrar.cc: 67 // 68 // namespace { 69 // const base::android::RegistrationMethod kRegisteredMethods[] = { 70 // // Initial string is for debugging only. 71 // { "ExampleName", base::ExampleNameAndroid::RegisterJNI }, 72 // { "ExampleName2", base::ExampleName2Android::RegisterJNI }, 73 // }; 74 // } // namespace 75 // 76 // bool RegisterModuleNameJni(JNIEnv* env) { 77 // return RegisterNativeMethods(env, kRegisteredMethods, 78 // arraysize(kRegisteredMethods)); 79 // } 80 // 81 // - Each module's RegisterModuleNameJni must be called by a larger module, 82 // or application during startup. 83 // 84 class CPPClass { 85 public: 86 CPPClass(); 87 ~CPPClass(); 88 89 // Register C++ methods exposed to Java using JNI. 90 static bool RegisterJNI(JNIEnv* env); 91 92 // Java @CalledByNative methods implicitly available to C++ via the _jni.h 93 // file included in the .cc file. 94 95 class InnerClass { 96 public: 97 jdouble MethodOtherP0(JNIEnv* env, 98 const base::android::JavaParamRef<jobject>& caller); 99 }; 100 101 void Destroy(JNIEnv* env, const base::android::JavaParamRef<jobject>& caller); 102 103 jint Method(JNIEnv* env, const base::android::JavaParamRef<jobject>& caller); 104 105 void AddStructB(JNIEnv* env, 106 const base::android::JavaParamRef<jobject>& caller, 107 const base::android::JavaParamRef<jobject>& structb); 108 109 void IterateAndDoSomethingWithStructB( 110 JNIEnv* env, 111 const base::android::JavaParamRef<jobject>& caller); 112 113 base::android::ScopedJavaLocalRef<jstring> ReturnAString( 114 JNIEnv* env, 115 const base::android::JavaParamRef<jobject>& caller); 116 117 private: 118 std::map<long, std::string> map_; 119 120 DISALLOW_COPY_AND_ASSIGN(CPPClass); 121 }; 122 123 } // namespace android 124 } // namespace base 125 126 #endif // BASE_ANDROID_JNI_GENERATOR_SAMPLE_FOR_TESTS_H_ 127