Skip to content

Commit

Permalink
[jnigen] JniX to JX rename (#126)
Browse files Browse the repository at this point in the history
Closed #124.
Closed #125.

* Added `JPrimitive` and its subclasses instead of using the typedefs from `ffi` directly.
* Renamed `JniObject`, `JniString`, and ... to the shorter `JObject`, JString`, and ...
* Made tests more robust by deleting the objects in an arena.
  • Loading branch information
HosseinYousefi authored Nov 9, 2022
1 parent 3c4eb25 commit 1c95d14
Show file tree
Hide file tree
Showing 38 changed files with 2,754 additions and 2,503 deletions.
6 changes: 3 additions & 3 deletions pkgs/jni/example/integration_test/on_device_jni_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ void main() {
}
}

testWidgets("Long.intValue() using JniObject", (t) async {
testWidgets("Long.intValue() using JObject", (t) async {
final longClass = Jni.findJniClass("java/lang/Long");

final longCtor = longClass.getCtorID("(J)V");
Expand All @@ -38,7 +38,7 @@ void main() {

testWidgets("call a static method using JniClass APIs", (t) async {
final integerClass = JniClass.fromRef(Jni.findClass("java/lang/Integer"));
final result = integerClass.callStaticMethodByName<JniString>(
final result = integerClass.callStaticMethodByName<JString>(
"toHexString", "(I)Ljava/lang/String;", [31]);

final resultString = result.toDartString();
Expand Down Expand Up @@ -116,7 +116,7 @@ void main() {
});

testWidgets("enums", (t) async {
final ordinal = Jni.retrieveStaticField<JniObject>(
final ordinal = Jni.retrieveStaticField<JObject>(
"java/net/Proxy\$Type", "HTTP", "Ljava/net/Proxy\$Type;")
.use((f) => f.callMethodByName<int>("ordinal", "()I", []));
expect(ordinal, equals(1));
Expand Down
8 changes: 4 additions & 4 deletions pkgs/jni/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import 'package:jni/jni.dart';
// GlobalJniEnv is a thin abstraction over JNIEnv in JNI C API.
//
// For a more ergonomic API for common use cases of calling methods and
// accessing fields, see next examples using JniObject and JniClass.
// accessing fields, see next examples using JObject and JniClass.
String toJavaStringUsingEnv(int n) => using((arena) {
final env = Jni.env;
final cls = env.FindClass("java/lang/String".toNativeChars(arena));
Expand Down Expand Up @@ -56,7 +56,7 @@ int uptime() {
}

void quit() {
JniObject.fromRef(Jni.getCurrentActivity())
JObject.fromRef(Jni.getCurrentActivity())
.use((ac) => ac.callMethodByName<void>("finish", "()V", []));
}

Expand All @@ -68,7 +68,7 @@ void showToast(String text) {
// In this example, Toaster class wraps android.widget.Toast so that it
// can be called from any thread. See
// android/app/src/main/java/com/github/dart_lang/jni_example/Toaster.java
Jni.invokeStaticMethod<JniObject>(
Jni.invokeStaticMethod<JObject>(
"com/github/dart_lang/jni_example/Toaster",
"makeText",
"(Landroid/app/Activity;Landroid/content/Context;"
Expand Down Expand Up @@ -100,7 +100,7 @@ void main() {
"android/os/Build", "DEVICE", "Ljava/lang/String;")),
Example(
"Package name",
() => JniObject.fromRef(Jni.getCurrentActivity()).use((activity) =>
() => JObject.fromRef(Jni.getCurrentActivity()).use((activity) =>
activity.callMethodByName<String>(
"getPackageName", "()Ljava/lang/String;", [])),
),
Expand Down
54 changes: 28 additions & 26 deletions pkgs/jni/ffigen.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,32 +55,34 @@ typedefs:
- '__builtin_va_list'
rename:
'JNI(.*)': 'Jni$1'
'jint': 'JInt'
'jclass': 'JClass'
'jobject': 'JObject'
'jbyte': 'JByte'
'jsize': 'JSize'
'jmethodID': 'JMethodID'
'jfieldID': 'JFieldID'
'jboolean': 'JBoolean'
'jthrowable': 'JThrowable'
'jchar': 'JChar'
'jshort': 'JShort'
'jlong': 'JLong'
'jfloat': 'JFloat'
'jdouble': 'JDouble'
'jstring': 'JString'
'jarray': 'JArray'
'jobjectArray': 'JObjectArray'
'jbooleanArray': 'JBooleanArray'
'jbyteArray': 'JByteArray'
'jcharArray': 'JCharArray'
'jshortArray': 'JShortArray'
'jintArray': 'JIntArray'
'jlongArray': 'JLongArray'
'jfloatArray': 'JFloatArray'
'jdoubleArray': 'JDoubleArray'
'jweak': 'JWeak'
# Primitives
'jbyte': 'JByteMarker'
'jboolean': 'JBooleanMarker'
'jchar': 'JCharMarker'
'jshort': 'JShortMarker'
'jint': 'JIntMarker'
'jlong': 'JLongMarker'
'jfloat': 'JFloatMarker'
'jdouble': 'JDoubleMarker'
'jsize': 'JSizeMarker'

'jclass': 'JClassPtr'
'jobject': 'JObjectPtr'
'jmethodID': 'JMethodIDPtr'
'jfieldID': 'JFieldIDPtr'
'jthrowable': 'JThrowablePtr'
'jstring': 'JStringPtr'
'jarray': 'JArrayPtr'
'jobjectArray': 'JObjectArrayPtr'
'jbooleanArray': 'JBooleanArrayPtr'
'jbyteArray': 'JByteArrayPtr'
'jcharArray': 'JCharArrayPtr'
'jshortArray': 'JShortArrayPtr'
'jintArray': 'JIntArrayPtr'
'jlongArray': 'JLongArrayPtr'
'jfloatArray': 'JFloatArrayPtr'
'jdoubleArray': 'JDoubleArrayPtr'
'jweak': 'JWeakPtr'
'jvalue': 'JValue'
preamble: |
// Autogenerated file. Do not edit.
Expand Down
2 changes: 1 addition & 1 deletion pkgs/jni/lib/internal_helpers_for_jnigen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
library internal_helpers_for_jnigen;

export 'src/jni.dart' show ProtectedJniExtensions;
export 'src/jni_object.dart' show JniReference;
export 'src/types.dart' show JReference;
export 'src/accessors.dart';
3 changes: 1 addition & 2 deletions pkgs/jni/lib/jni.dart
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,7 @@ export 'src/third_party/jni_bindings_generated.dart'
hide JniBindings, JniEnv, JniEnv1, JniExceptionDetails;
export 'src/jni.dart' hide ProtectedJniExtensions;
export 'src/jvalues.dart' hide JValueArgs, toJValues;
export 'src/jni_exceptions.dart';
export 'src/jni_object.dart' hide JniReference;
export 'src/types.dart' hide JReference;

export 'package:ffi/ffi.dart' show using, Arena;
export 'dart:ffi' show nullptr;
33 changes: 18 additions & 15 deletions pkgs/jni/lib/src/accessors.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import 'package:jni/src/jvalues.dart';

import 'third_party/jni_bindings_generated.dart';
import 'jni.dart';
import 'jni_exceptions.dart';
import 'types.dart';

void _check(JThrowable exception) {
void _check(JThrowablePtr exception) {
if (exception != nullptr) {
Jni.accessors.throwException(exception);
}
Expand Down Expand Up @@ -55,7 +55,7 @@ extension JniResultMethods on JniResult {
return result.d;
}

JObject get object {
JObjectPtr get object {
check();
return result.l;
}
Expand All @@ -67,12 +67,12 @@ extension JniResultMethods on JniResult {
}

extension JniIdLookupResultMethods on JniPointerResult {
JMethodID get methodID {
JMethodIDPtr get methodID {
_check(exception);
return id.cast<jmethodID_>();
}

JFieldID get fieldID {
JFieldIDPtr get fieldID {
_check(exception);
return id.cast<jfieldID_>();
}
Expand All @@ -84,7 +84,7 @@ extension JniIdLookupResultMethods on JniPointerResult {
}

extension JniClassLookupResultMethods on JniClassLookupResult {
JClass get checkedClassRef {
JClassPtr get checkedClassRef {
_check(exception);
return classRef;
}
Expand All @@ -95,7 +95,7 @@ extension JniAccessorWrappers on Pointer<JniAccessors> {
///
/// The original exception object is deleted by this method. The message
/// and Java stack trace are included in the exception.
void throwException(JThrowable exception) {
void throwException(JThrowablePtr exception) {
final details = getExceptionDetails(exception);
final env = Jni.env;
final message = env.asDartString(details.message);
Expand All @@ -108,42 +108,45 @@ extension JniAccessorWrappers on Pointer<JniAccessors> {

// TODO(PR): How to name these methods? These only wrap toNativeChars()
// so that generated bindings are less verbose.
JClass getClassOf(String internalName) =>
JClassPtr getClassOf(String internalName) =>
using((arena) => getClass(internalName.toNativeChars(arena)))
.checkedClassRef;

JMethodID getMethodIDOf(JClass cls, String name, String signature) =>
JMethodIDPtr getMethodIDOf(JClassPtr cls, String name, String signature) =>
using((arena) => getMethodID(
cls, name.toNativeChars(arena), signature.toNativeChars(arena)))
.methodID;

JMethodID getStaticMethodIDOf(JClass cls, String name, String signature) =>
JMethodIDPtr getStaticMethodIDOf(
JClassPtr cls, String name, String signature) =>
using((arena) => getStaticMethodID(
cls, name.toNativeChars(arena), signature.toNativeChars(arena)))
.methodID;

JFieldID getFieldIDOf(JClass cls, String name, String signature) =>
JFieldIDPtr getFieldIDOf(JClassPtr cls, String name, String signature) =>
using((arena) => getFieldID(
cls, name.toNativeChars(arena), signature.toNativeChars(arena)))
.fieldID;

JFieldID getStaticFieldIDOf(JClass cls, String name, String signature) =>
JFieldIDPtr getStaticFieldIDOf(
JClassPtr cls, String name, String signature) =>
using((arena) => getStaticFieldID(
cls, name.toNativeChars(arena), signature.toNativeChars(arena)))
.fieldID;

JniResult newObjectWithArgs(JClass cls, JMethodID ctor, List<dynamic> args) =>
JniResult newObjectWithArgs(
JClassPtr cls, JMethodIDPtr ctor, List<dynamic> args) =>
using((arena) {
return newObject(cls, ctor, toJValues(args, allocator: arena));
});

JniResult callMethodWithArgs(
JObject obj, JMethodID id, int callType, List<dynamic> args) =>
JObjectPtr obj, JMethodIDPtr id, int callType, List<dynamic> args) =>
using((arena) =>
callMethod(obj, id, callType, toJValues(args, allocator: arena)));

JniResult callStaticMethodWithArgs(
JClass cls, JMethodID id, int callType, List<dynamic> args) =>
JClassPtr cls, JMethodIDPtr id, int callType, List<dynamic> args) =>
using((arena) => callStaticMethod(
cls, id, callType, toJValues(args, allocator: arena)));
}
Loading

0 comments on commit 1c95d14

Please sign in to comment.