|
Name |
|
Date |
Size |
#Lines |
LOC |
| .. | | - | - |
| java/src/org/chromium/example/jni_generator/ | | 03-May-2024 | - | 285 | 131 |
| AndroidManifest.xml | D | 03-May-2024 | 430 | 14 | 5 |
| README.md | D | 03-May-2024 | 5 KiB | 119 | 90 |
| SampleForTests_jni.golden | D | 03-May-2024 | 21.5 KiB | 495 | 430 |
| android_jar.classes | D | 03-May-2024 | 3.1 KiB | 99 | 98 |
| jni_exception_list.gni | D | 03-May-2024 | 500 | 14 | 10 |
| jni_generator.py | D | 03-May-2024 | 49.4 KiB | 1,410 | 1,169 |
| jni_generator_helper.h | D | 03-May-2024 | 1.8 KiB | 57 | 34 |
| jni_generator_tests.py | D | 03-May-2024 | 43.1 KiB | 1,189 | 1,079 |
| jni_registration_generator.py | D | 03-May-2024 | 11 KiB | 341 | 271 |
| sample_entry_point.cc | D | 03-May-2024 | 955 | 28 | 16 |
| sample_for_tests.cc | D | 03-May-2024 | 5 KiB | 155 | 109 |
| sample_for_tests.h | D | 03-May-2024 | 3.6 KiB | 115 | 35 |
| testCalledByNatives.golden | D | 03-May-2024 | 16.7 KiB | 420 | 367 |
| testConstantsFromJavaP.golden | D | 03-May-2024 | 78.1 KiB | 2,060 | 1,870 |
| testFromJavaP.golden | D | 03-May-2024 | 8.6 KiB | 247 | 211 |
| testFromJavaPGenerics.golden | D | 03-May-2024 | 2.6 KiB | 82 | 62 |
| testInnerClassNatives.golden | D | 03-May-2024 | 2.1 KiB | 61 | 44 |
| testInnerClassNativesBothInnerAndOuter.golden | D | 03-May-2024 | 2.5 KiB | 71 | 52 |
| testInnerClassNativesBothInnerAndOuterRegistrations.golden | D | 03-May-2024 | 3.3 KiB | 110 | 80 |
| testInnerClassNativesMultiple.golden | D | 03-May-2024 | 3.2 KiB | 84 | 64 |
| testInputStream.javap | D | 03-May-2024 | 6.5 KiB | 229 | 205 |
| testMotionEvent.javap | D | 03-May-2024 | 63.8 KiB | 2,296 | 1,941 |
| testMotionEvent.javap7 | D | 03-May-2024 | 85 KiB | 2,371 | 2,121 |
| testMultipleJNIAdditionalImport.golden | D | 03-May-2024 | 2.5 KiB | 71 | 53 |
| testNativeExportsOnlyOption.golden | D | 03-May-2024 | 9.4 KiB | 215 | 183 |
| testNatives.golden | D | 03-May-2024 | 8.4 KiB | 223 | 186 |
| testNativesLong.golden | D | 03-May-2024 | 1.5 KiB | 50 | 35 |
| testNativesRegistrations.golden | D | 03-May-2024 | 6.2 KiB | 176 | 151 |
| testSingleJNIAdditionalImport.golden | D | 03-May-2024 | 2.2 KiB | 67 | 49 |
| testTracing.golden | D | 03-May-2024 | 3.4 KiB | 100 | 77 |
README.md
1# Overview
2JNI (Java Native Interface) is the mechanism that enables Java code to call
3native functions, and native code to call Java functions.
4
5 * Native code calls into Java using apis from `<jni.h>`, which basically mirror
6 Java's reflection APIs.
7 * Java code calls native functions by declaring body-less functions with the
8 `native` keyword, and then calling them as normal Java functions.
9
10`jni_generator` generates boiler-plate code with the goal of making our code:
11 1. easier to write, and
12 2. typesafe.
13
14`jni_generator` uses regular expressions to parse .Java files, so don't do
15anything too fancy. E.g.:
16 * Classes must be either explicitly imported, or are assumed to be in
17the same package. To use `java.lang` classes, add an explicit import.
18 * Inner classes need to be referenced through the outer class. E.g.:
19 `void call(Outer.Inner inner)`
20
21The presense of any JNI within a class will result in ProGuard obfuscation for
22the class to be disabled.
23
24### Exposing Native Methods
25
26**Without Crazy Linker:**
27 * Java->Native calls are exported from the shared library and lazily resolved
28 by the runtime (via `dlsym()`).
29
30**With Crazy Linker:**
31 * Java->Native calls are explicitly registered with JNI on the native side.
32 Explicit registration is necessary because crazy linker provides its own
33 `dlsym()`, but JNI is hardcoded to use the system's `dlsym()`.
34 * The logic to explicitly register stubs is generated by
35 `jni_registration_generator.py`.
36 * This script finds all native methods by scanning all source `.java` files
37 of an APK. Inefficient, but very convenient.
38 * Since `dlsym()` is not used in this case, we use a linker script to avoid
39 the cost of exporting symbols from the shared library (refer to
40 `//build/config/android:hide_all_but_jni_onload`).
41 * `jni_registration_generator.py` exposes two registrations methods:
42 * `RegisterNonMainDexNatives` - Registers native functions needed by multiple
43 process types (e.g. Rendereres, GPU process).
44 * `RegisterMainDexNatives` - Registers native functions needed only by the
45 browser process.
46
47### Exposing Java Methods
48
49Java methods just need to be annotated with `@CalledByNative`. The generated
50functions can be put into a namespace using `@JNINamespace("your_namespace")`.
51
52## Usage
53
54Because the generator does not generate any source files, generated headers must
55not be `#included` by multiple sources. If there are Java functions that need to
56be called by multiple sources, one source should be chosen to expose the
57functions to the others via additional wrapper functions.
58
59### Calling Java -> Native
60
61 * Methods marked as `native` will have stubs generated for them that forward
62 calls to C++ function (that you must write).
63 * If the first parameter is a C++ object (e.g. `long mNativePointer`), then the
64 bindings will automatically generate the appropriate cast and call into C++
65 code (JNI itself is only C).
66
67### Calling Native -> Java
68
69 * Methods annotated with `@CalledByNative` will have stubs generated for them.
70 * Just call the generated stubs defined in generated `.h` files.
71
72### Java Objects and Garbage Collection
73
74All pointers to Java objects must be registered with JNI in order to prevent
75garbage collection from invalidating them.
76
77For Strings & Arrays - it's common practice to use the `//base/android/jni_*`
78helpers to convert them to `std::vectors` and `std::strings` as soon as
79possible.
80
81For other objects - use smart pointers to store them:
82 * `ScopedJavaLocalRef<>` - When lifetime is the current function's scope.
83 * `ScopedJavaGlobalRef<>` - When lifetime is longer than the current function's
84 scope.
85 * `JavaObjectWeakGlobalRef<>` - Weak reference (do not prevent garbage
86 collection).
87 * `JavaParamRef<>` - Use to accept any of the above as a parameter to a
88 function without creating a redundant registration.
89
90### Additional Guidelines / Advice
91
92Minimize the surface API between the two sides. Rather than calling multiple
93functions across boundaries, call only one (and then on the other side, call as
94many little functions as required).
95
96If a Java object "owns" a native one, store the pointer via
97`"long mNativeClassName"`. Ensure to eventually call a native method to delete
98the object. For example, have a `close()` that deletes the native object.
99
100The best way to pass "compound" types across in either direction is to
101create an inner class with PODs and a factory function. If possible, make mark
102all the fields as "final".
103
104## Build Rules
105
106 * `generate_jni` - Generates a header file with stubs for given `.java` files
107 * `generate_jar_jni` - Generates a header file with stubs for a given `.jar`
108 file
109 * `generate_jni_registration` - Generates a header file with functions to
110 register native-side JNI methods (required only when using crazy linker).
111
112Refer to [//build/config/android/rules.gni](https://cs.chromium.org/chromium/src/build/config/android/rules.gni)
113for more about the GN templates.
114
115## Changing `jni_generator`
116
117 * Python unit tests live in `jni_generator_tests.py`
118 * A working demo app exists as `//base/android/jni_generator:sample_jni_apk`
119