dart-lang / native

Dart packages related to FFI and native assets bundling.
BSD 3-Clause "New" or "Revised" License
155 stars 43 forks source link

Paramater with `Float` type seems lost. #1226

Closed yanshouwang closed 4 months ago

yanshouwang commented 4 months ago

I bind the CameraX successfully with JNIGEN, but I found an issue that the Float argument is lost when execute CameraController.setZoomRatio.

The generated method is like this:

  static final _id_setZoomRatio = _class.instanceMethodId(
    r"setZoomRatio",
    r"(F)Lcom/google/common/util/concurrent/ListenableFuture;",
  );

  static final _setZoomRatio = ProtectedJniExtensions.lookup<
          ffi.NativeFunction<
              jni.JniResult Function(ffi.Pointer<ffi.Void>, jni.JMethodIDPtr,
                  ffi.VarArgs<(ffi.Float,)>)>>("globalEnv_CallObjectMethod")
      .asFunction<
          jni.JniResult Function(
              ffi.Pointer<ffi.Void>, jni.JMethodIDPtr, double)>();

  /// from: public com.google.common.util.concurrent.ListenableFuture setZoomRatio(float f)
  /// The returned object must be released after use, by calling the [release] method.
  ListenableFuture<jni.JObject> setZoomRatio(
    double f,
  ) {
    return _setZoomRatio(
            reference.pointer, _id_setZoomRatio as jni.JMethodIDPtr, f)
        .object(const $ListenableFutureType(jni.JObjectType()));
  }

Here is how I used it:

  @override
  Future<void> setZoomRatio(double zoomRatio) async {
    final lisentalbeFuture = await runOnPlatformThread(() {
      return jniValue.setZoomRatio(zoomRatio);
    });
    final completer = Completer<void>();
    final executor = jni.ContextCompat.getMainExecutor(JNI.activity);
    lisentalbeFuture.addListener(
      jni.Runnable.implement(jni.$RunnableImpl(
        run: () {
          try {
            final futureType = jni.Future.type(JObject.type);
            final future = lisentalbeFuture.castTo(futureType);
            future.get0();
            completer.complete();
          } catch (e) {
            completer.completeError(e);
          }
        },
      )),
      executor,
    );
    await completer.future;
  }

When I run the app and call the setZoomRatio method with non-zero argument, the method will throw this

[HomeViewModel] Exception in Java code called through JNI: java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Requested zoomRatio 0.0 is not within valid range [1.0 , 10.0]

                java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Requested zoomRatio 0.0 is not within valid range [1.0 , 10.0]
                    at androidx.camera.core.impl.utils.futures.ImmediateFuture$ImmediateFailedFuture.get(ImmediateFuture.java:136)
                Caused by: java.lang.IllegalArgumentException: Requested zoomRatio 0.0 is not within valid range [1.0 , 10.0]
                    at androidx.camera.camera2.internal.ZoomStateImpl.setZoomRatio(ZoomStateImpl.java:42)
                    at androidx.camera.camera2.internal.ZoomControl.setZoomRatio(ZoomControl.java:213)
                    at androidx.camera.camera2.internal.Camera2CameraControlImpl.setZoomRatio(Camera2CameraControlImpl.java:352)
                    at androidx.camera.core.impl.RestrictedCameraControl.setZoomRatio(RestrictedCameraControl.java:136)
                    at androidx.camera.view.CameraController.setZoomRatio(CameraController.java:1794)
                    at android.os.MessageQueue.nativePollOnce(Native Method)
                    at android.os.MessageQueue.next(MessageQueue.java:341)
                    at android.os.Looper.loopOnce(Looper.java:169)
                    at android.os.Looper.loop(Looper.java:300)
                    at android.app.ActivityThread.main(ActivityThread.java:8343)
                    at java.lang.reflect.Method.invoke(Native Method)
                    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:559)
                    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:954)

You can run the example here: https://github.com/yanshouwang/camerax/tree/dev/camerax_android/example

HosseinYousefi commented 4 months ago

This is fixed now. Update your jni/jnigen to 0.9.3 and regenerate your bindings.