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 14namespace base { 15namespace 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// 84class 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