mapbox / mapbox-gl-native-android

Interactive, thoroughly customizable maps in native Android powered by vector tiles and OpenGL
https://mapbox.com/mobile
Other
217 stars 118 forks source link

Flutter useHybridComposition cause crash #732

Open paulVulog opened 2 years ago

paulVulog commented 2 years ago

Environment

Observed behavior and steps to reproduce

When running an app with MapboxMap.useHybridComposition = true; and doing some multitouch on the map, you can easily get some app crashes.

here are the produced logs :

I/ViewRootImpl@e968b84[MainActivity](17240): ViewPostIme pointer 0
W/MultiFingerGesture(17240): Some MotionEvents were not passed to the library or events from different view trees are merged.
W/MultiFingerGesture(17240): Some MotionEvents were not passed to the library or events from different view trees are merged.
I/flutter (17240): UserRepository _notifyUpdate  updateDetected:false with 0 item(s)
F/libc    (17240): Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 17240 (mobile.team.dev), pid 17240 (mobile.team.dev)
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'samsung/starltexx/starlte:10/QP1A.190711.020/G960FXXUHFVB4:user/release-keys'
Revision: '26'
ABI: 'arm64'
Timestamp: 2022-05-31 15:30:39+0200
pid: 17240, tid: 17240, name: mobile.team.dev  >>> com.vulog.carshare.oa.mobile.team.dev <<<
uid: 11028
signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr --------
Abort message: 'ubsan: shift-out-of-bounds'
    x0  0000000000000000  x1  0000000000004358  x2  0000000000000006  x3  0000007fdd49f910
    x4  0000000000000000  x5  0000000000000000  x6  0000000000000000  x7  0000000000000010
    x8  00000000000000f0  x9  000000733df4c5e0  x10 0000000000000000  x11 0000000000000001
    x12 0000000000000008  x13 0000000000000014  x14 0000000000000008  x15 0000000000000019
    x16 000000733e01a8c0  x17 000000733dff7880  x18 0000007342056000  x19 00000000000000ac
    x20 0000000000004358  x21 00000000000000b2  x22 0000000000004358  x23 00000000ffffffff
    x24 0000007341b6e020  x25 00000000154cdae0  x26 0000000013e3ed90  x27 0000000013e33378
    x28 0000000013e3ea98  x29 0000007fdd49f9c0
    sp  0000007fdd49f8f0  lr  000000733dfab330  pc  000000733dfab360
backtrace:
      #00 pc 0000000000083360  /apex/com.android.runtime/lib64/bionic/libc.so (abort+176) (BuildId: 3f350ca06c3b80560f65755286daf320)
      mapbox/mapbox-maps-android#1 pc 000000000002c06c  /system/lib64/libinput.so (abort_with_message(char const*)+20) (BuildId: e48e0a6a2819b165ee68017ba2d6b61f)
      mapbox/mapbox-maps-android#2 pc 000000000002c0f8  /system/lib64/libinput.so (__ubsan_handle_shift_out_of_bounds_minimal_abort+24) (BuildId: e48e0a6a2819b165ee68017ba2d6b61f)
      mapbox/mapbox-maps-android#3 pc 000000000002a48c  /system/lib64/libinput.so (android::VelocityTracker::addMovement(android::MotionEvent const*)+884) (BuildId: e48e0a6a2819b165ee68017ba2d6b61f)
      mapbox/mapbox-maps-android#4 pc 00000000002ed494  /system/framework/arm64/boot-framework.oat (art_jni_trampoline+180) (BuildId: d9f5e98f49949c317e5890da1317a97a9c9c5fbb)
      mapbox/mapbox-maps-android#5 pc 000000000208f79c  /memfd:/jit-cache (deleted) (android.view.VelocityTracker.addMovement+60)
      mapbox/mapbox-maps-android#6 pc 00000000020779e0  /memfd:/jit-cache (deleted) (android.view.GestureDetector.onTouchEvent+304)
      mapbox/mapbox-maps-android#7 pc 0000000002093440  /memfd:/jit-cache (deleted) (androidx.core.view.GestureDetectorCompat$GestureDetectorCompatImplJellybeanMr2.onTouchEvent+64)
      mapbox/mapbox-maps-android#8 pc 000000000209ac78  /memfd:/jit-cache (deleted) (androidx.core.view.GestureDetectorCompat.onTouchEvent+72)
      mapbox/mapbox-maps-android#9 pc 000000000208e6ec  /memfd:/jit-cache (deleted) (com.mapbox.android.gestures.StandardScaleGestureDetector.analyzeEvent+300)
      mapbox/mapbox-maps-android#10 pc 000000000207cc28  /memfd:/jit-cache (deleted) (com.mapbox.android.gestures.BaseGesture.analyze+344)
      mapbox/mapbox-maps-android#11 pc 00000000020856ac  /memfd:/jit-cache (deleted) (com.mapbox.android.gestures.BaseGesture.onTouchEvent+44)
      mapbox/mapbox-maps-android#12 pc 00000000020767e0  /memfd:/jit-cache (deleted) (com.mapbox.android.gestures.AndroidGesturesManager.onTouchEvent+224)
      mapbox/mapbox-maps-android#13 pc 00000000020a757c  /memfd:/jit-cache (deleted) (com.mapbox.mapboxsdk.plugins.annotation.DraggableAnnotationController$1.onTouch+108)
      mapbox/mapbox-maps-android#14 pc 000000000208b1d4  /memfd:/jit-cache (deleted) (android.view.View.dispatchTouchEvent+948)
      mapbox/mapbox-maps-android#15 pc 000000000207e3cc  /memfd:/jit-cache (deleted) (android.view.ViewGroup.dispatchTransformedTouchEvent+252)
      mapbox/mapbox-maps-android#16 pc 000000000208a748  /memfd:/jit-cache (deleted) (android.view.ViewGroup.dispatchTouchEvent+4104)
      mapbox/mapbox-maps-android#17 pc 000000000208cf58  /memfd:/jit-cache (deleted) (io.flutter.plugin.platform.PlatformViewsController$1.onTouch+536)
      mapbox/mapbox-maps-android#18 pc 0000000002076f18  /memfd:/jit-cache (deleted) (io.flutter.embedding.engine.systemchannels.PlatformViewsChannel$1.touch+1480)
      mapbox/mapbox-maps-android#19 pc 000000000208ec00  /memfd:/jit-cache (deleted) (io.flutter.embedding.engine.systemchannels.PlatformViewsChannel$1.onMethodCall+1168)
      mapbox/mapbox-maps-android#20 pc 000000000208dc68  /memfd:/jit-cache (deleted) (io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage+232)
      mapbox/mapbox-maps-android#21 pc 0000000002082624  /memfd:/jit-cache (deleted) (io.flutter.embedding.engine.dart.DartMessenger.invokeHandler+244)
      mapbox/mapbox-maps-android#22 pc 000000000203ef1c  /memfd:/jit-cache (deleted) (io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$io-flutter-embedding-engine-dart-DartMessenger+252)
      mapbox/mapbox-maps-android-internal#205 pc 0000000002068f74  /memfd:/jit-cache (deleted) (io.flutter.embedding.engine.dart.DartMessenger$$ExternalSyntheticLambda0.run+132)
      mapbox/mapbox-maps-android#24 pc 0000000002036a94  /memfd:/jit-cache (deleted) (android.os.Handler.handleCallback+68)
      mapbox/mapbox-maps-android#25 pc 0000000002037fc0  /memfd:/jit-cache (deleted) (android.os.Handler.dispatchMessage+64)
      mapbox/mapbox-maps-android#26 pc 00000000020acf50  /memfd:/jit-cache (deleted) (android.os.Looper.loop+1216)
      mapbox/mapbox-maps-android#27 pc 000000000013863c  /apex/com.android.runtime/lib64/libart.so (art_quick_osr_stub+60) (BuildId: 0680f97b9649cf08862df1e69e76e0f3)
      mapbox/mapbox-maps-android#28 pc 0000000000340a40  /apex/com.android.runtime/lib64/libart.so (art::jit::Jit::MaybeDoOnStackReplacement(art::Thread*, art::ArtMethod*, unsigned int, int, art::JValue*)+1688) (BuildId: 0680f97b9649cf08862df1e69e76e0f3)
      mapbox/mapbox-maps-android#29 pc 00000000005b5d04  /apex/com.android.runtime/lib64/libart.so (MterpMaybeDoOnStackReplacement+212) (BuildId: 0680f97b9649cf08862df1e69e76e0f3)
      mapbox/mapbox-maps-android-internal#210 pc 0000000000137350  /apex/com.android.runtime/lib64/libart.so (MterpHelpers+240) (BuildId: 0680f97b9649cf08862df1e69e76e0f3)
      mapbox/mapbox-maps-android#31 pc 00000000003980c0  /system/framework/framework.jar (android.os.Looper.loop+1076)
      mapbox/mapbox-maps-android#32 pc 00000000005adc18  /apex/com.android.runtime/lib64/libart.so (MterpInvokeStatic+1136) (BuildId: 0680f97b9649cf08862df1e69e76e0f3)
      mapbox/mapbox-maps-android#33 pc 0000000000132994  /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_static+20) (BuildId: 0680f97b9649cf08862df1e69e76e0f3)
      mapbox/mapbox-maps-android#34 pc 00000000001a8998  /system/framework/framework.jar (android.app.ActivityThread.main+208)
      mapbox/mapbox-maps-android#35 pc 00000000002bbe28  /apex/com.android.runtime/lib64/libart.so (_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_6JValueEbb.llvm.5467380822148485331+240) (BuildId: 0680f97b9649cf08862df1e69e76e0f3)
      mapbox/mapbox-maps-android#36 pc 000000000059c210  /apex/com.android.runtime/lib64/libart.so (artQuickToInterpreterBridge+1024) (BuildId: 0680f97b9649cf08862df1e69e76e0f3)
      mapbox/mapbox-maps-android#37 pc 0000000000141468  /apex/com.android.runtime/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: 0680f97b9649cf08862df1e69e76e0f3)
      mapbox/mapbox-maps-android#38 pc 00000000001385b8  /apex/com.android.runtime/lib64/libart.so (art_quick_invoke_static_stub+568) (BuildId: 0680f97b9649cf08862df1e69e76e0f3)
      mapbox/mapbox-maps-android#39 pc 00000000001470cc  /apex/com.android.runtime/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+276) (BuildId: 0680f97b9649cf08862df1e69e76e0f3)
      mapbox/mapbox-maps-android#40 pc 00000000004bad28  /apex/com.android.runtime/lib64/libart.so (art::(anonymous namespace)::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::(anonymous namespace)::ArgArray*, art::JValue*, char const*)+104) (BuildId: 0680f97b9649cf08862df1e69e76e0f3)
      mapbox/mapbox-maps-android#41 pc 00000000004bc770  /apex/com.android.runtime/lib64/libart.so (art::InvokeMethod(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jobject*, _jobject*, unsigned long)+1472) (BuildId: 0680f97b9649cf08862df1e69e76e0f3)
      mapbox/mapbox-maps-android#42 pc 0000000000447e90  /apex/com.android.runtime/lib64/libart.so (art::Method_invoke(_JNIEnv*, _jobject*, _jobject*, _jobjectArray*)+48) (BuildId: 0680f97b9649cf08862df1e69e76e0f3)
      mapbox/mapbox-maps-android#43 pc 00000000000c8d34  /system/framework/arm64/boot.oat (art_jni_trampoline+180) (BuildId: 61ec5d1d9be4570882fca4a5ac76332f673e2f85)
      mapbox/mapbox-maps-android#44 pc 0000000000138334  /apex/com.android.runtime/lib64/libart.so (art_quick_invoke_stub+548) (BuildId: 0680f97b9649cf08862df1e69e76e0f3)
      mapbox/mapbox-maps-android#45 pc 00000000001470ac  /apex/com.android.runtime/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+244) (BuildId: 0680f97b9649cf08862df1e69e76e0f3)
      mapbox/mapbox-maps-android#46 pc 00000000002eb4f8  /apex/com.android.runtime/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+384) (BuildId: 0680f97b9649cf08862df1e69e76e0f3)
      mapbox/mapbox-maps-android#47 pc 00000000002e6584  /apex/com.android.runtime/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+900) (BuildId: 0680f97b9649cf08862df1e69e76e0f3)
      mapbox/mapbox-maps-android#48 pc 00000000005aad78  /apex/com.android.runtime/lib64/libart.so (MterpInvokeVirtual+648) (BuildId: 0680f97b9649cf08862df1e69e76e0f3)
      mapbox/mapbox-maps-android#49 pc 0000000000132814  /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_virtual+20) (BuildId: 0680f97b9649cf08862df1e69e76e0f3)
      mapbox/mapbox-maps-android#50 pc 0000000000501642  /system/framework/framework.jar (com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run+22)
      mapbox/mapbox-maps-android#51 pc 00000000002bbe28  /apex/com.android.runtime/lib64/libart.so (_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_6JValueEbb.llvm.5467380822148485331+240) (BuildId: 0680f97b9649cf08862df1e69e76e0f3)
      mapbox/mapbox-maps-android-internal#222 pc 000000000059c210  /apex/com.android.runtime/lib64/libart.so (artQuickToInterpreterBridge+1024) (BuildId: 0680f97b9649cf08862df1e69e76e0f3)
      mapbox/mapbox-maps-android#53 pc 0000000000141468  /apex/com.android.runtime/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: 0680f97b9649cf08862df1e69e76e0f3)
      mapbox/mapbox-maps-android#54 pc 0000000000abf764  /system/framework/arm64/boot-framework.oat (com.android.internal.os.ZygoteInit.main+3012) (BuildId: d9f5e98f49949c317e5890da1317a97a9c9c5fbb)
      mapbox/mapbox-maps-android#55 pc 00000000001385b8  /apex/com.android.runtime/lib64/libart.so (art_quick_invoke_static_stub+568) (BuildId: 0680f97b9649cf08862df1e69e76e0f3)
      mapbox/mapbox-maps-android#56 pc 00000000001470cc  /apex/com.android.runtime/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+276) (BuildId: 0680f97b9649cf08862df1e69e76e0f3)
      mapbox/mapbox-maps-android#57 pc 00000000004bad28  /apex/com.android.runtime/lib64/libart.so (art::(anonymous namespace)::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::(anonymous namespace)::ArgArray*, art::JValue*, char const*)+104) (BuildId: 0680f97b9649cf08862df1e69e76e0f3)
      mapbox/mapbox-maps-android#58 pc 00000000004ba988  /apex/com.android.runtime/lib64/libart.so (art::InvokeWithVarArgs(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, std::__va_list)+408) (BuildId: 0680f97b9649cf08862df1e69e76e0f3)
      mapbox/mapbox-maps-android#59 pc 00000000003c48a8  /apex/com.android.runtime/lib64/libart.so (art::JNI::CallStaticVoidMethodV(_JNIEnv*, _jclass*, _jmethodID*, std::__va_list)+624) (BuildId: 0680f97b9649cf08862df1e69e76e0f3)
      mapbox/mapbox-maps-android#60 pc 00000000000ee3cc  /system/lib64/libandroid_runtime.so (_JNIEnv::CallStaticVoidMethod(_jclass*, _jmethodID*, ...)+116) (BuildId: fc35ebb304e552924cf0583921fca054)
      mapbox/mapbox-maps-android#61 pc 00000000000f14ec  /system/lib64/libandroid_runtime.so (android::AndroidRuntime::start(char const*, android::Vector<android::String8> const&, bool)+804) (BuildId: fc35ebb304e552924cf0583921fca054)
      mapbox/mapbox-maps-android#62 pc 00000000000034f0  /system/bin/app_process64 (main+1184) (BuildId: d345cc25886f3d75c6e2e9c16568090a)
      mapbox/mapbox-maps-android#63 pc 000000000007e854  /apex/com.android.runtime/lib64/bionic/libc.so (__libc_init+108) (BuildId: 3f350ca06c3b80560f65755286daf320)
Lost connection to device.

Way to reproduce using the Mapbox Gl sample app:

  @override
  void initState() {
    initHybridComposition();
    super.initState();
  }

  /// Determine the android version of the phone and turn off HybridComposition
  /// on older sdk versions to improve performance for these
  ///
  /// !!! Hybrid composition is currently broken do no use !!!
  Future<void> initHybridComposition() async {
    MapboxMap.useHybridComposition = true;
  }
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        floatingActionButton: Padding(
          padding: const EdgeInsets.all(32.0),
          child: FloatingActionButton(
            child: Icon(Icons.swap_horiz),
            onPressed: () => setState(
              () => isLight = !isLight,
            ),
          ),
        ),
        body: Stack(
            children: [MapboxMap(
              styleString: isLight ? MapboxStyles.LIGHT : MapboxStyles.DARK,
              accessToken: MapsDemo.ACCESS_TOKEN,
              onMapCreated: _onMapCreated,
              initialCameraPosition: const CameraPosition(target: LatLng(0.0, 0.0)),
              onStyleLoadedCallback: _onStyleLoadedCallback,
            ),
          Center(
            child: Container(
              width: 50,
              height: 50,
              color: Colors.green,
            ),
          ),
        ]
        ));
  }

This will simply add a widget on top of the map to reproduce the crash.

One digit on the map The Other One on the green widget Tap both at the same time.

You will get a crash.

It only crash if you tap a widget (flutter) stacked on top of the map (nativ view because of .useHybridComposition = true)

Expected behavior

We should not get any crash. Minimum requirement is to silently catch the exception. (this is what google maps seems to do - see below)

Notes / preliminary analysis

I have tested the same behavior on the GoogleMap sample app : https://github.com/flutter/plugins/tree/main/packages/google_maps_flutter/google_maps_flutter

I am able to reproduce the same kind of issue, Except that the google map do not Crash. There is only some flutter Error log :

I/ViewRootImpl@4ffe3aa[FlutterActivity](18949): ViewPostIme pointer 0
E/MethodChannel#flutter/platform_views(18949): Failed to handle method call
E/MethodChannel#flutter/platform_views(18949): java.lang.IllegalArgumentException: pointerIndex out of range
E/MethodChannel#flutter/platform_views(18949):  at android.view.MotionEvent.nativeGetPointerId(Native Method)
E/MethodChannel#flutter/platform_views(18949):  at android.view.MotionEvent.getPointerId(MotionEvent.java:2717)
E/MethodChannel#flutter/platform_views(18949):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:3585)
E/MethodChannel#flutter/platform_views(18949):  at io.flutter.plugin.platform.PlatformViewsController$1.onTouch(PlatformViewsController.java:313)
E/MethodChannel#flutter/platform_views(18949):  at io.flutter.embedding.engine.systemchannels.PlatformViewsChannel$1.touch(PlatformViewsChannel.java:176)
E/MethodChannel#flutter/platform_views(18949):  at io.flutter.embedding.engine.systemchannels.PlatformViewsChannel$1.onMethodCall(PlatformViewsChannel.java:68)
E/MethodChannel#flutter/platform_views(18949):  at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:262)
E/MethodChannel#flutter/platform_views(18949):  at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:296)
E/MethodChannel#flutter/platform_views(18949):  at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$DartMessenger(DartMessenger.java:320)
E/MethodChannel#flutter/platform_views(18949):  at io.flutter.embedding.engine.dart.-$$Lambda$DartMessenger$AIEPqY6mWzaNK15HekX9bftoAXs.run(Unknown Source:12)
E/MethodChannel#flutter/platform_views(18949):  at android.os.Handler.handleCallback(Handler.java:883)
E/MethodChannel#flutter/platform_views(18949):  at android.os.Handler.dispatchMessage(Handler.java:100)
E/MethodChannel#flutter/platform_views(18949):  at android.os.Looper.loop(Looper.java:237)
E/MethodChannel#flutter/platform_views(18949):  at android.app.ActivityThread.main(ActivityThread.java:8167)
E/MethodChannel#flutter/platform_views(18949):  at java.lang.reflect.Method.invoke(Native Method)
E/MethodChannel#flutter/platform_views(18949):  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
E/MethodChannel#flutter/platform_views(18949):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
I/ViewRootImpl@4ffe3aa[FlutterActivity](18949): ViewPostIme pointer 1
E/flutter (18949): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: PlatformException(error, pointerIndex out of range, null, java.lang.IllegalArgumentException: pointerIndex out of range
E/flutter (18949):  at android.view.MotionEvent.nativeGetPointerId(Native Method)
E/flutter (18949):  at android.view.MotionEvent.getPointerId(MotionEvent.java:2717)
E/flutter (18949):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:3585)
E/flutter (18949):  at io.flutter.plugin.platform.PlatformViewsController$1.onTouch(PlatformViewsController.java:313)
E/flutter (18949):  at io.flutter.embedding.engine.systemchannels.PlatformViewsChannel$1.touch(PlatformViewsChannel.java:176)
E/flutter (18949):  at io.flutter.embedding.engine.systemchannels.PlatformViewsChannel$1.onMethodCall(PlatformViewsChannel.java:68)
E/flutter (18949):  at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:262)
E/flutter (18949):  at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:296)
E/flutter (18949):  at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$DartMessenger(DartMessenger.java:320)
E/flutter (18949):  at io.flutter.embedding.engine.dart.-$$Lambda$DartMessenger$AIEPqY6mWzaNK15HekX9bftoAXs.run(Unknown Source:12)
E/flutter (18949):  at android.os.Handler.handleCallback(Handler.java:883)
E/flutter (18949):  at android.os.Handler.dispatchMessage(Handler.java:100)
E/flutter (18949):  at android.os.Looper.loop(Looper.java:237)
E/flutter (18949):  at android.app.ActivityThread.main(ActivityThread.java:8167)
E/flutter (18949):  at java.lang.reflect.Method.invoke(Native Method)
E/flutter (18949):  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
E/flutter (18949):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
E/flutter (18949): )
E/flutter (18949): #0      StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:607:7)
E/flutter (18949): mapbox/mapbox-maps-android#1      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:177:18)
E/flutter (18949): <asynchronous suspension>
E/flutter (18949): mapbox/mapbox-maps-android#2      AndroidViewController.sendMotionEvent (package:flutter/src/services/platform_views.dart:803:5)
E/flutter (18949): <asynchronous suspension>
E/flutter (18949): mapbox/mapbox-maps-android#3      AndroidViewController.dispatchPointerEvent (package:flutter/src/services/platform_views.dart:895:7)
E/flutter (18949): <asynchronous suspension>
E/flutter (18949): 

Additional links and references

The issue is tracked in this repository - forwarded to the main Android Mapbox repository here: https://github.com/flutter-mapbox-gl/maps/issues/1077

ZiZasaurus commented 2 years ago

@paulVulog thank you for reporting, I will transfer this ticket to the appropriate repo.

devmobile-vulog commented 2 years ago

@ZiZasaurus any status on this ? It is really impacting. Where did you transfer this issue to ?

KnIfER commented 2 years ago

Hi, similiar backtrace here https://github.com/appxmod/diodict-decompiled/commit/719900901b1a2acabace2e068a1ddb63778b5aa7

If I filter out ACTION_POINTER_DOWN,the native crash will become the “pointerIndex out of range” Exception:

if (actionMasked!=MotionEvent.ACTION_POINTER_DOWN) {
    try {
        boolean flingEvent = this.flingDetector.onTouchEvent(event);
        if (flingEvent) {
            // this.flingDetector = new GestureDetector(getContext(), this);
            return flingEvent;
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
ankiimation commented 2 years ago

I resolved this issue by create new Flutter Engine with custom MyPlatformViewController extend PlatformViewController https://github.com/flutter/engine/pull/34182/commits/991471b66d1dced23b0962b6440314ae7c4a787d

MyPlatformViewController:

class MyPlatformViewsController : PlatformViewsController() {
    override fun toMotionEvent(
        density: Float,
        touch: PlatformViewsChannel.PlatformViewTouch?,
        usingVirtualDiplays: Boolean
    ): MotionEvent {
        val motionEventId = MotionEventId.from(touch!!.motionEventId)
        val trackedEvent = MotionEventTracker.getInstance().pop(motionEventId)

        // Pointer coordinates in the tracked events are global to FlutterView
        // framework converts them to be local to a widget, given that
        // motion events operate on local coords, we need to replace these in the tracked
        // event with their local counterparts.

        // Pointer coordinates in the tracked events are global to FlutterView
        // framework converts them to be local to a widget, given that
        // motion events operate on local coords, we need to replace these in the tracked
        // event with their local counterparts.
        val pointerProperties = parsePointerPropertiesList(
            touch!!.rawPointerPropertiesList
        ).toTypedArray()
        val pointerCoords = parsePointerCoordsList(
            touch!!.rawPointerCoords, density
        )
            .toTypedArray()

        return if (!usingVirtualDiplays && trackedEvent != null) {
            MotionEvent.obtain(
                trackedEvent.downTime,
                trackedEvent.eventTime,
                touch!!.action,
                touch!!.pointerCount,
                pointerProperties,
                pointerCoords,
                trackedEvent.metaState,
                trackedEvent.buttonState,
                trackedEvent.xPrecision,
                trackedEvent.yPrecision,
                trackedEvent.deviceId,
                trackedEvent.edgeFlags,
                trackedEvent.source,
                trackedEvent.flags
            )
        } else MotionEvent.obtain(
            touch!!.downTime.toLong(),
            touch!!.eventTime.toLong(),
            touch!!.action,
            touch!!.pointerCount,
            pointerProperties,
            pointerCoords,
            touch!!.metaState,
            touch!!.buttonState,
            touch!!.xPrecision,
            touch!!.yPrecision,
            touch!!.deviceId,
            touch!!.edgeFlags,
            touch!!.source,
            touch!!.flags
        )

    }

    private fun parsePointerPropertiesList(rawPropertiesList: Any): List<PointerProperties> {
        val rawProperties = rawPropertiesList as List<Any>
        val pointerProperties: MutableList<PointerProperties> = java.util.ArrayList()
        for (o in rawProperties) {
            pointerProperties.add(parsePointerProperties(o))
        }
        return pointerProperties
    }

    private fun parsePointerProperties(rawProperties: Any): PointerProperties {
        val propertiesList = rawProperties as List<Any>
        val properties = PointerProperties()
        properties.id = propertiesList[0] as Int
        properties.toolType = propertiesList[1] as Int
        return properties
    }

    private fun parsePointerCoordsList(rawCoordsList: Any, density: Float): List<PointerCoords> {
        val rawCoords = rawCoordsList as List<Any>
        val pointerCoords: MutableList<PointerCoords> = ArrayList()
        for (o in rawCoords) {
            pointerCoords.add(parsePointerCoords(o, density))
        }
        return pointerCoords
    }

    private fun parsePointerCoords(rawCoords: Any, density: Float): PointerCoords {
        val coordsList = rawCoords as List<Any>
        val coords = PointerCoords()
        coords.orientation = (coordsList[0] as Double).toFloat()
        coords.pressure = (coordsList[1] as Double).toFloat()
        coords.size = (coordsList[2] as Double).toFloat()
        coords.toolMajor = (coordsList[3] as Double * density).toFloat()
        coords.toolMinor = (coordsList[4] as Double * density).toFloat()
        coords.touchMajor = (coordsList[5] as Double * density).toFloat()
        coords.touchMinor = (coordsList[6] as Double * density).toFloat()
        coords.x = (coordsList[7] as Double * density).toFloat()
        coords.y = (coordsList[8] as Double * density).toFloat()
        return coords
    }
}

In MainActivity (your main flutter activity):

    override fun provideFlutterEngine(context: Context): FlutterEngine? {
        return FlutterEngine(
            context,
            null,
            FlutterJNI(),
            MyCustomFlutterEngine(),
            Companion.flutterShellArgs.toArray(),
            false
        )
    }