learntoflutter / flutter_embed_unity

19 stars 5 forks source link

[Flutter 3.22 & 3.24] ARFoundation crashes on Android < 13 - NoClassDefFoundError: Landroid/window/OnBackInvokedCallback #21

Open timbotimbo opened 5 months ago

timbotimbo commented 5 months ago

[UPDATE]

This is now in the Unity issue tracker. Anyone affect by this should probably upvote this in the issuetracker.

Description

Since Flutter 3.22, Unity will crash on certain Android versions when ARFoundation is activated.
This only happens on Android <13. This might also affect other unity plugins using native code, I just noticed it using ARFoundation.

In my own project Unity works fine for 3D scenes but crashes when I switch to a scene that includes ARFoundation. In the example project here, Unity shows up with the Flutter logo but crashes once the AR support check runs.

Error in the console:

E/Unity   ( 7029): AndroidJavaException: java.lang.NoClassDefFoundError: Failed resolution of: Landroid/window/OnBackInvokedCallback;
E/Unity   ( 7029): java.lang.NoClassDefFoundError: Failed resolution of: Landroid/window/OnBackInvokedCallback;
E/Unity   ( 7029):  at java.lang.reflect.Executable.getMethodReturnTypeInternal(Native Method)
E/Unity   ( 7029):  at java.lang.reflect.Method.getReturnType(Method.java:148)
E/Unity   ( 7029):  at java.lang.Class.getDeclaredMethods(Class.java:1880)
E/Unity   ( 7029):  at com.unity3d.player.ReflectionHelper.getMethodID(Unknown Source:26)
E/Unity   ( 7029):  at com.unity3d.player.UnityPlayer.nativeRender(Native Method)
E/Unity   ( 7029):  at com.unity3d.player.UnityPlayer.-$$Nest$mnativeRender(Unknown Source:0)
E/Unity   ( 7029):  at com.unity3d.player.UnityPlayer$F$a.handleMessage(Unknown Source:122)
E/Unity   ( 7029):  at android.os.Handler.dispatchMessage(Handler.java:102)
E/Unity   ( 7029):  at android.os.Looper.loop(Looper.java:214)
E/Unity   ( 7029):  at com.unity3d.player.UnityPlayer$F.run(Unknown Source:24)
E/Unity   ( 7029): Caused by: java.lang.ClassNotFoundException: Didn't find class "android.window.OnBackInvokedCallback" on path: DexPathList[[zip file "/data/app/com.learntoflutter.flutter_embed_uni

Looking up OnBackInvokedCallback, it is added in API 33 (android 13) and is related to the predictive back gesture in Android 14.

I'm not sure if this is a flutter bug where it sends some kind of message which it shouldn't on API <33, or if it is caused by Unity missing an implementation.

Error log

Full console log up to the crash ``` √ Built build\app\outputs\flutter-apk\app-debug.apk D/FlutterEmbedLog( 7029): onAttachedToEngine D/FlutterEmbedLog( 7029): onAttachedToActivity D/FlutterEmbedLog( 7029): Activity resumed, resuming Unity Connecting to VM Service at ws://127.0.0.1:1851/hE4igOjN93Y=/ws D/com.learntoflutter.flutter_embed_unity_android.platformView.UnityViewFactory@4db3836( 7029): UnityViewFactory creating view 0 I/IL2CPP ( 7029): JNI_OnLoad I/FlutterEmbedLog( 7029): Attached Unity to view I/FlutterEmbedLog( 7029): Attached Unity to new view D/FlutterEmbedLog( 7029): UnityPlatformView onFlutterViewAttached I/PlatformViewsController( 7029): Hosting view in a virtual display for platform view: 0 I/PlatformViewsController( 7029): PlatformView is using SurfaceTexture backend D/Dialog ( 7029): mIsSamsungBasicInteraction = false D/Dialog ( 7029): mIsSamsungBasicInteraction = false, isMetaDataInActivity = false D/vndksupport( 7029): Loading /vendor/lib64/hw/android.hardware.graphics.mapper@2.0-impl.so from current namespace instead of sphal namespace. I/DecorView( 7029): createDecorCaptionView >> DecorView@bdb2310[], isFloating: false, isApplication: false, hasWindowDecorCaption: false, hasWindowControllerCallback: false D/InputTransport( 7029): Input channel constructed: fd=96 D/ViewRootImpl@4eea71a[MainActivity]( 7029): setView = DecorView@bdb2310[MainActivity] TM=true MM=false D/ViewRootImpl@da5e15f[MainActivity]( 7029): Relayout returned: old=[0,0][720,1480] new=[0,0][720,1480] result=0x3 surface={valid=true 503242113024} changed=false V/InputMethodManager( 7029): Not IME target window, ignoring D/FlutterEmbedLog( 7029): UnityPlayerSingleton onWindowVisibilityChanged 0 D/FlutterEmbedLog( 7029): UnityPlayerSingleton became visible, so pausing and resuming Unity D/SurfaceView( 7029): onWindowVisibilityChanged(0) true com.unity3d.player.a{e296541 VFE...... ......I. 0,0-0,0 #7f05004f app:id/unitySurfaceView} of ViewRootImpl@4eea71a[MainActivity] D/ViewRootImpl@4eea71a[MainActivity]( 7029): dispatchAttachedToWindow D/ViewRootImpl@4eea71a[MainActivity]( 7029): Relayout returned: old=[0,0][720,788] new=[0,0][720,788] result=0x7 surface={valid=true 502678339584} changed=true D/mali_winsys( 7029): EGLint new_window_surface(egl_winsys_display *, void *, EGLSurface, EGLConfig, egl_winsys_surface **, EGLBoolean) returns 0x3000 D/OpenGLRenderer( 7029): eglCreateWindowSurface = 0x7509fc9b80, 0x7509f6c010 D/SurfaceView( 7029): show() Surface(name=SurfaceView - Sys2030:com.learntoflutter.flutter_embed_unity_example/com.learntoflutter.flutter_embed_unity_example.MainActivity@e296541@0[7029])/@0x5c01ae6 com.unity3d.player.a{e296541 VFE...... ......ID 0,0-720,788 #7f05004f app:id/unitySurfaceView} D/SurfaceView( 7029): surfaceCreated 1 #8 com.unity3d.player.a{e296541 VFE...... ......ID 0,0-720,788 #7f05004f app:id/unitySurfaceView} D/SurfaceView( 7029): surfaceChanged (720,788) 1 #8 com.unity3d.player.a{e296541 VFE...... ......ID 0,0-720,788 #7f05004f app:id/unitySurfaceView} I/Unity ( 7029): MemoryManager: Using 'Dynamic Heap' Allocator. W/d_unity_exampl( 7029): Accessing hidden method Ljava/lang/invoke/MethodHandles$Lookup;->(Ljava/lang/Class;I)V (light greylist, reflection) D/ViewRootImpl@4eea71a[MainActivity]( 7029): Relayout returned: old=[0,0][720,788] new=[0,0][720,788] result=0x3 surface={valid=true 502678339584} changed=false D/ViewRootImpl@4eea71a[MainActivity]( 7029): MSG_RESIZED: frame=Rect(0, 0 - 720, 788) ci=Rect(0, 0 - 0, 0) vi=Rect(0, 0 - 0, 0) or=1 I/Unity ( 7029): SystemInfo CPU = ARM64 FP ASIMD AES, Cores = 8, Memory = 3679mb I/Unity ( 7029): SystemInfo ARM big.LITTLE configuration: 4 big (mask: 0xf0), 4 little (mask: 0xf) I/Unity ( 7029): ApplicationInfo com.learntoflutter.flutter_embed_unity_example version 1.0 I/Unity ( 7029): Built from '2022.3/staging' branch, Version '2022.3.33f1 (b2c853adf198)', Build type 'Release', Scripting Backend 'il2cpp', CPU 'arm64-v8a', Stripping 'Enabled' D/ViewRootImpl@da5e15f[MainActivity]( 7029): Relayout returned: old=[0,0][720,1480] new=[0,0][720,1480] result=0x3 surface={valid=true 503242113024} changed=false D/ViewRootImpl@da5e15f[MainActivity]( 7029): Relayout returned: old=[0,0][720,1480] new=[0,0][720,1480] result=0x3 surface={valid=true 503242113024} changed=false D/InputMethodManager( 7029): prepareNavigationBarInfo() DecorView@9b0e2bd[MainActivity] D/InputMethodManager( 7029): getNavigationBarColor() -855310 V/InputMethodManager( 7029): Starting input: tba=com.learntoflutter.flutter_embed_unity_example ic=null mNaviBarColor -855310 mIsGetNaviBarColorSuccess true , NavVisible : true , NavTrans : false D/InputMethodManager( 7029): startInputInner - Id : 0 I/InputMethodManager( 7029): startInputInner - mService.startInputOrWindowGainedFocus D/InputTransport( 7029): Input channel constructed: fd=109 D/InputTransport( 7029): Input channel destroyed: fd=89 D/ViewRootImpl@da5e15f[MainActivity]( 7029): Relayout returned: old=[0,0][720,1480] new=[0,0][720,1480] result=0x1 surface={valid=true 503242113024} changed=false I/d_unity_exampl( 7029): Compiler allocated 4MB to compile void android.view.ViewRootImpl.performTraversals() I/flutter ( 7029): FlutterEmbed: onPlatformViewCreated(0) D/ViewRootImpl@da5e15f[MainActivity]( 7029): setWindowStopped(true) old=false D/SurfaceView( 7029): windowStopped(true) false io.flutter.embedding.android.FlutterSurfaceView{c93b274 V.E...... ........ 0,0-720,1384} of ViewRootImpl@da5e15f[MainActivity] D/SurfaceView( 7029): show() Surface(name=SurfaceView - com.learntoflutter.flutter_embed_unity_example/com.learntoflutter.flutter_embed_unity_example.MainActivity@c93b274@0[7029])/@0xb321012 io.flutter.embedding.android.FlutterSurfaceView{c93b274 V.E...... ........ 0,0-720,1384} D/SurfaceView( 7029): surfaceDestroyed callback.size 1 #1 io.flutter.embedding.android.FlutterSurfaceView{c93b274 V.E...... ........ 0,0-720,1384} W/libEGL ( 7029): EGLNativeWindowType 0x752b916010 disconnect failed D/SurfaceView( 7029): destroy() Surface(name=SurfaceView - com.learntoflutter.flutter_embed_unity_example/com.learntoflutter.flutter_embed_unity_example.MainActivity@c93b274@0[7029])/@0xb321012 io.flutter.embedding.android.FlutterSurfaceView{c93b274 V.E...... ........ 0,0-720,1384} E/SchedPolicy( 7029): set_timerslack_ns write failed: Operation not permitted I/Unity ( 7029): Company Name: DefaultCompany I/Unity ( 7029): Product Name: FlutterEmbedUnityExample D/mali_winsys( 7029): EGLint new_window_surface(egl_winsys_display *, void *, EGLSurface, EGLConfig, egl_winsys_surface **, EGLBoolean) returns 0x3000 D/Unity ( 7029): GL_EXT_debug_marker GL_ARM_rgba8 GL_ARM_mali_shader_binary GL_OES_depth24 GL_OES_depth_texture GL_OES_depth_texture_cube_map GL_OES_packed_depth_stencil GL_OES_rgb8_rgba8 GL_EXT_read_format_bgra GL_OES_compressed_paletted_texture GL_OES_compressed_ETC1_RGB8_texture GL_OES_standard_derivatives GL_OES_EGL_image GL_OES_EGL_image_external GL_OES_EGL_image_external_essl3 GL_OES_EGL_sync GL_OES_texture_npot GL_OES_vertex_half_float GL_OES_required_internalformat GL_OES_vertex_array_object GL_OES_mapbuffer GL_EXT_texture_format_BGRA8888 GL_EXT_texture_rg GL_EXT_texture_type_2_10_10_10_REV GL_OES_fbo_render_mipmap GL_OES_element_index_uint GL_EXT_shadow_samplers GL_OES_texture_compression_astc GL_KHR_texture_compression_astc_ldr GL_KHR_texture_compression_astc_hdr GL_KHR_texture_compression_astc_sliced_3d GL_KHR_debug GL_EXT_occlusion_query_boolean GL_EXT_disjoint_timer_query GL_EXT_blend_minmax GL_EXT_discard_framebuffer GL_OES_get_program_binary GL_OES_texture_3D GL_EXT_texture_storage GL_EXT_multisampled_render_ D/Unity ( 7029): to_texture GL_EXT_multisampled_render_to_texture2 GL_OES_surfaceless_context GL_OES_texture_stencil8 GL_EXT_shader_pixel_local_storage GL_ARM_shader_framebuffer_fetch GL_ARM_shader_framebuffer_fetch_depth_stencil GL_ARM_mali_program_binary GL_EXT_sRGB GL_EXT_sRGB_write_control GL_EXT_texture_sRGB_decode GL_EXT_texture_sRGB_R8 GL_EXT_texture_sRGB_RG8 GL_KHR_blend_equation_advanced GL_KHR_blend_equation_advanced_coherent GL_OES_texture_storage_multisample_2d_array GL_OES_shader_image_atomic GL_EXT_robustness GL_EXT_draw_buffers_indexed GL_OES_draw_buffers_indexed GL_EXT_texture_border_clamp GL_OES_texture_border_clamp GL_EXT_texture_cube_map_array GL_OES_texture_cube_map_array GL_OES_sample_variables GL_OES_sample_shading GL_OES_shader_multisample_interpolation GL_EXT_shader_io_blocks GL_OES_shader_io_blocks GL_EXT_tessellation_shader GL_OES_tessellation_shader GL_EXT_primitive_bounding_box GL_OES_primitive_bounding_box GL_EXT_geometry_shader GL_OES_geometry_shader GL_ANDROID_extension_pack_es31a GL_EXT_gpu_sh D/Unity ( 7029): ader5 GL_OES_gpu_shader5 GL_EXT_texture_buffer GL_OES_texture_buffer GL_EXT_copy_image GL_OES_copy_image GL_EXT_shader_non_constant_global_initializers GL_EXT_color_buffer_half_float GL_EXT_color_buffer_float GL_EXT_YUV_target GL_OVR_multiview GL_OVR_multiview2 GL_OVR_multiview_multisampled_render_to_texture GL_KHR_robustness GL_KHR_robust_buffer_access_behavior GL_EXT_draw_elements_base_vertex GL_OES_draw_elements_base_vertex GL_EXT_protected_textures GL_EXT_buffer_storage GL_EXT_external_buffer GL_EXT_EGL_image_array I/chatty ( 7029): uid=11295(com.learntoflutter.flutter_embed_unity_example) UnityMain identical 14 lines E/SchedPolicy( 7029): set_timerslack_ns write failed: Operation not permitted D/ ( 7029): PlayerBase::PlayerBase() D/ ( 7029): TrackPlayerBase::TrackPlayerBase() I/libOpenSLES( 7029): Emulating old channel mask behavior (ignoring positional mask 0x3, using default mask 0x3 based on channel count of 2) W/AudioTrack( 7029): notificationFrames=-10 clamped to the range -1 to -8 I/AudioTrack( 7029): AUDIO_OUTPUT_FLAG_FAST successful; frameCount 0 -> 1536 I/AudioTrack( 7029): updateAudioTranstionLength FadeIn[0] FadeOut[0] FadeInRing[0] W/Unity ( 7029): The referenced script (Unknown) on this Behaviour is missing! W/Unity ( 7029): The referenced script on this Behaviour (Game Object '') is missing! D/ViewRootImpl@da5e15f[MainActivity]( 7029): setWindowStopped(false) old=true D/SurfaceView( 7029): windowStopped(false) false io.flutter.embedding.android.FlutterSurfaceView{c93b274 G.E...... ......I. 0,0-720,1384} of ViewRootImpl@da5e15f[MainActivity] D/SurfaceView( 7029): show() Surface(name=SurfaceView - com.learntoflutter.flutter_embed_unity_example/com.learntoflutter.flutter_embed_unity_example.MainActivity@c93b274@1[7029])/@0xb23b62a io.flutter.embedding.android.FlutterSurfaceView{c93b274 V.E...... ......ID 0,0-720,1384} D/SurfaceView( 7029): surfaceCreated 1 #3 io.flutter.embedding.android.FlutterSurfaceView{c93b274 V.E...... ......ID 0,0-720,1384} D/mali_winsys( 7029): EGLint new_window_surface(egl_winsys_display *, void *, EGLSurface, EGLConfig, egl_winsys_surface **, EGLBoolean) returns 0x3000 D/SurfaceView( 7029): surfaceChanged (720,1384) 1 #3 io.flutter.embedding.android.FlutterSurfaceView{c93b274 V.E...... ......ID 0,0-720,1384} D/InputMethodManager( 7029): prepareNavigationBarInfo() DecorView@9b0e2bd[MainActivity] D/InputMethodManager( 7029): getNavigationBarColor() -855310 V/InputMethodManager( 7029): Starting input: tba=com.learntoflutter.flutter_embed_unity_example ic=null mNaviBarColor -855310 mIsGetNaviBarColorSuccess true , NavVisible : true , NavTrans : false D/InputMethodManager( 7029): startInputInner - Id : 0 I/InputMethodManager( 7029): startInputInner - mService.startInputOrWindowGainedFocus D/InputTransport( 7029): Input channel constructed: fd=119 D/InputTransport( 7029): Input channel destroyed: fd=109 D/ViewRootImpl@da5e15f[MainActivity]( 7029): setWindowStopped(false) old=false D/FlutterEmbedLog( 7029): Activity resumed, resuming Unity I/Unity ( 7029): XRGeneral Settings awakening... I/Unity ( 7029): UnityEngine.DebugLogHandler:Internal_Log(LogType, LogOption, String, Object) I/Unity ( 7029): UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[]) I/Unity ( 7029): UnityEngine.Logger:Log(LogType, Object) I/Unity ( 7029): UnityEngine.Debug:Log(Object) I/Unity ( 7029): UnityEngine.XR.Management.XRGeneralSettings:Awake() I/Unity ( 7029): I/IL2CPP ( 7029): Locale en-GB I/native ( 7029): I0000 00:00:1718716607.710883 7097 arpresto_api.cc:36] ArPresto::ArPresto_initialize V/Unity-ARCore( 7029): Initializing ARCore Pause Handler V/Unity-ARCore( 7029): PauseHandler: JNI not attached to thread. Attempting to attach. V/Unity-ARCore( 7029): PauseHandler: Attached JNI to thread. D/SensorManager( 7029): registerListener :: 6, LSM6DSL Acceleration Sensor, 200000, 0, D/ ( 7029): PlayerBase::stop() from IPlayer D/AudioTrack( 7029): stop() called with 112896 frames delivered I/AudioTrack( 7029): Skip ramp W/libEGL ( 7029): EGLNativeWindowType 0x750a02d010 disconnect failed D/mali_winsys( 7029): EGLint new_window_surface(egl_winsys_display *, void *, EGLSurface, EGLConfig, egl_winsys_surface **, EGLBoolean) returns 0x3000 D/SurfaceView( 7029): onWindowVisibilityChanged(8) false com.unity3d.player.a{e296541 VFE...... ........ 0,0-720,788 #7f05004f app:id/unitySurfaceView} of ViewRootImpl@4eea71a[MainActivity] D/SurfaceView( 7029): show() Surface(name=SurfaceView - Sys2030:com.learntoflutter.flutter_embed_unity_example/com.learntoflutter.flutter_embed_unity_example.MainActivity@e296541@0[7029])/@0x5c01ae6 com.unity3d.player.a{e296541 VFE...... ........ 0,0-720,788 #7f05004f app:id/unitySurfaceView} D/SurfaceView( 7029): surfaceDestroyed callback.size 1 #2 com.unity3d.player.a{e296541 VFE...... ........ 0,0-720,788 #7f05004f app:id/unitySurfaceView} W/OpenGLRenderer( 7029): Surface doesn't have any previously queued frames, nothing to readback from V/MediaRouter( 7029): Adding route: RouteInfo{ name=Phone, description=null, status=null, category=RouteCategory{ name=System types=ROUTE_TYPE_LIVE_AUDIO ROUTE_TYPE_LIVE_VIDEO groupable=false }, supportedTypes=ROUTE_TYPE_LIVE_AUDIO ROUTE_TYPE_LIVE_VIDEO , presentationDisplay=null } V/MediaRouter( 7029): Selecting route: RouteInfo{ name=Phone, description=null, status=null, category=RouteCategory{ name=System types=ROUTE_TYPE_LIVE_AUDIO ROUTE_TYPE_LIVE_VIDEO groupable=false }, supportedTypes=ROUTE_TYPE_LIVE_AUDIO ROUTE_TYPE_LIVE_VIDEO , presentationDisplay=null } D/SurfaceView( 7029): destroy() Surface(name=SurfaceView - Sys2030:com.learntoflutter.flutter_embed_unity_example/com.learntoflutter.flutter_embed_unity_example.MainActivity@e296541@0[7029])/@0x5c01ae6 com.unity3d.player.a{e296541 VFE...... ........ 0,0-720,788 #7f05004f app:id/unitySurfaceView} D/FlutterEmbedLog( 7029): UnityPlayerSingleton onWindowVisibilityChanged 8 D/ ( 7029): NULL == surf->write_back_color_buffer D/ ( 7029): NULL == surf->write_back_color_buffer D/Dialog ( 7029): mIsSamsungBasicInteraction = false D/Dialog ( 7029): mIsSamsungBasicInteraction = false, isMetaDataInActivity = false E/BufferQueueProducer( 7029): [SurfaceTexture-0-7029-0] disconnect: not connected (req=1) I/DecorView( 7029): createDecorCaptionView >> DecorView@cadfdda[], isFloating: false, isApplication: false, hasWindowDecorCaption: false, hasWindowControllerCallback: false D/InputTransport( 7029): Input channel constructed: fd=106 D/ViewRootImpl@df81b94[MainActivity]( 7029): setView = DecorView@cadfdda[MainActivity] TM=true MM=false D/OpenGLRenderer( 7029): eglDestroySurface = 0x7509fc9b80, 0x7509f6c000 D/ViewRootImpl@4eea71a[MainActivity]( 7029): dispatchDetachedFromWindow D/ViewRootImpl@4eea71a[MainActivity]( 7029): Surface release. android.view.ViewRootImpl.doDie:7976 android.view.ViewRootImpl.die:7944 android.view.WindowManagerGlobal.removeViewLocked:497 android.view.WindowManagerGlobal.removeView:435 android.view.WindowManagerImpl.removeViewImmediate:124 android.app.Dialog.dismissDialog:518 android.app.Dialog.dismiss:501 android.app.Dialog.cancel:1462 D/InputTransport( 7029): Input channel destroyed: fd=96 D/ViewRootImpl@da5e15f[MainActivity]( 7029): MSG_RESIZED_REPORT: frame=Rect(0, 0 - 720, 1480) ci=Rect(0, 48 - 0, 96) vi=Rect(0, 48 - 0, 96) or=1 D/ViewRootImpl@da5e15f[MainActivity]( 7029): Relayout returned: old=[0,0][720,1480] new=[0,0][720,1480] result=0x1 surface={valid=true 503242113024} changed=false V/InputMethodManager( 7029): Not IME target window, ignoring D/FlutterEmbedLog( 7029): UnityPlayerSingleton onWindowVisibilityChanged 0 D/FlutterEmbedLog( 7029): UnityPlayerSingleton became visible, so pausing and resuming Unity D/SurfaceView( 7029): onWindowVisibilityChanged(0) true com.unity3d.player.a{e296541 VFE...... ........ 0,0-720,788 #7f05004f app:id/unitySurfaceView} of ViewRootImpl@df81b94[MainActivity] D/ViewRootImpl@df81b94[MainActivity]( 7029): dispatchAttachedToWindow D/ViewRootImpl@df81b94[MainActivity]( 7029): Relayout returned: old=[0,0][720,788] new=[0,0][720,788] result=0x7 surface={valid=true 502528794624} changed=true D/mali_winsys( 7029): EGLint new_window_surface(egl_winsys_display *, void *, EGLSurface, EGLConfig, egl_winsys_surface **, EGLBoolean) returns 0x3000 D/OpenGLRenderer( 7029): eglCreateWindowSurface = 0x7509fc9b80, 0x75010ce010 D/SurfaceView( 7029): show() Surface(name=SurfaceView - Sys2030:com.learntoflutter.flutter_embed_unity_example/com.learntoflutter.flutter_embed_unity_example.MainActivity@e296541@1[7029])/@0x383063d com.unity3d.player.a{e296541 VFE...... ........ 0,0-720,788 #7f05004f app:id/unitySurfaceView} D/SurfaceView( 7029): surfaceCreated 1 #8 com.unity3d.player.a{e296541 VFE...... ........ 0,0-720,788 #7f05004f app:id/unitySurfaceView} D/SurfaceView( 7029): surfaceChanged (720,788) 1 #8 com.unity3d.player.a{e296541 VFE...... ........ 0,0-720,788 #7f05004f app:id/unitySurfaceView} D/mali_winsys( 7029): EGLint new_window_surface(egl_winsys_display *, void *, EGLSurface, EGLConfig, egl_winsys_surface **, EGLBoolean) returns 0x3000 D/ViewRootImpl@df81b94[MainActivity]( 7029): Relayout returned: old=[0,0][720,788] new=[0,0][720,788] result=0x3 surface={valid=true 502528794624} changed=false D/ViewRootImpl@df81b94[MainActivity]( 7029): MSG_RESIZED: frame=Rect(0, 0 - 720, 788) ci=Rect(0, 0 - 0, 0) vi=Rect(0, 0 - 0, 0) or=1 I/native ( 7029): I0000 00:00:1718716610.317826 7097 arpresto_api.cc:111] ArPresto::ArPresto_checkApkAvailability I/native ( 7029): I0000 00:00:1718716610.719147 7097 arpresto_api.cc:80] ArPresto::ArPresto_handleActivityPause I/native ( 7029): I0000 00:00:1718716610.736396 7097 arpresto_api.cc:70] ArPresto::ArPresto_handleActivityResume D/ViewRootImpl@da5e15f[MainActivity]( 7029): Relayout returned: old=[0,0][720,1480] new=[0,0][720,1480] result=0x1 surface={valid=true 503242113024} changed=false V/MediaRouter( 7029): onRestoreRoute() : route=RouteInfo{ name=Phone, description=null, status=null, category=RouteCategory{ name=System types=ROUTE_TYPE_LIVE_AUDIO ROUTE_TYPE_LIVE_VIDEO groupable=false }, supportedTypes=ROUTE_TYPE_LIVE_AUDIO ROUTE_TYPE_LIVE_VIDEO , presentationDisplay=null } V/MediaRouter( 7029): Selecting route: RouteInfo{ name=Phone, description=null, status=null, category=RouteCategory{ name=System types=ROUTE_TYPE_LIVE_AUDIO ROUTE_TYPE_LIVE_VIDEO groupable=false }, supportedTypes=ROUTE_TYPE_LIVE_AUDIO ROUTE_TYPE_LIVE_VIDEO , presentationDisplay=null } I/Unity ( 7029): ARCheckAvailability: check I/Unity ( 7029): UnityEngine.DebugLogHandler:Internal_Log(LogType, LogOption, String, Object) I/Unity ( 7029): UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[]) I/Unity ( 7029): UnityEngine.Logger:Log(LogType, Object) I/Unity ( 7029): UnityEngine.Debug:Log(Object) I/Unity ( 7029): Assets.Scripts.d__2:MoveNext() I/Unity ( 7029): UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr) I/Unity ( 7029): UnityEngine.MonoBehaviour:StartCoroutineManaged2(IEnumerator) I/Unity ( 7029): UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator) I/Unity ( 7029): Assets.Scripts.ARCheckAvailability:Start() I/Unity ( 7029): I/Unity ( 7029): ARCheckAvailability: checking... I/Unity ( 7029): UnityEngine.DebugLogHandler:Internal_Log(LogType, LogOption, String, Object) I/Unity ( 7029): UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[]) I/Unity ( 7029): UnityEngine.Logger:Log(LogType, Object) I/Unity ( 7029): UnityEngine.Debug:Log(Object) I/Unity ( 7029): Assets.Scripts.d__2:MoveNext() I/Unity ( 7029): UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr) I/Unity ( 7029): UnityEngine.MonoBehaviour:StartCoroutineManaged2(IEnumerator) I/Unity ( 7029): UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator) I/Unity ( 7029): Assets.Scripts.ARCheckAvailability:Start() I/Unity ( 7029): E/Unity ( 7029): OPENGL NATIVE PLUG-IN ERROR: GL_OUT_OF_MEMORY: Not enough memory left to execute command I/native ( 7029): I0000 00:00:1718716610.819003 7097 arpresto_api.cc:193] ArPresto::ArPresto_setCameraTextureNames I/native ( 7029): I0000 00:00:1718716610.819069 7097 arpresto_api.cc:212] ArPresto::ArPresto_setEnabled W/Unity ( 7029): Additional Lights Cookie Format (GrayscaleHigh) is not supported by the platform. Falling back to 32-bit format (RGBA8 UNorm) W/Unity ( 7029): UnityEngine.DebugLogHandler:Internal_Log(LogType, LogOption, String, Object) W/Unity ( 7029): UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[]) W/Unity ( 7029): UnityEngine.Logger:Log(LogType, Object) W/Unity ( 7029): UnityEngine.Debug:LogWarning(Object) W/Unity ( 7029): UnityEngine.Rendering.Universal.UniversalRenderPipelineAsset:get_additionalLightsCookieFormat() W/Unity ( 7029): UnityEngine.Rendering.Universal.UniversalRenderer:.ctor(UniversalRendererData) W/Unity ( 7029): UnityEngine.Rendering.Universal.UniversalRendererData:Create() W/Unity ( 7029): UnityEngine.Rendering.Universal.ScriptableRendererData:InternalCreateRenderer() W/Unity ( 7029): UnityEngine.Rendering.Universal.UniversalRenderPipelineAsset:CreateRenderers() W/Unity ( 7029): UnityEngine.Rendering.Universal.UniversalRenderPipelineAsset:CreatePipeline() W/Unity ( 7029): UnityEngine.Rendering.RenderPipelineAsset:InternalCreatePipeline() W/Unity ( 7029): UnityEngine.Rendering.RenderPipelineManager:PrepareRenderPipeline(RenderPipelineAsset) W/Unity ( 7029): UnityEngine.Rendering.RenderPipelineManag E/Unity ( 7029): AndroidJavaException: java.lang.NoClassDefFoundError: Failed resolution of: Landroid/window/OnBackInvokedCallback; E/Unity ( 7029): java.lang.NoClassDefFoundError: Failed resolution of: Landroid/window/OnBackInvokedCallback; E/Unity ( 7029): at java.lang.reflect.Executable.getMethodReturnTypeInternal(Native Method) E/Unity ( 7029): at java.lang.reflect.Method.getReturnType(Method.java:148) E/Unity ( 7029): at java.lang.Class.getDeclaredMethods(Class.java:1880) E/Unity ( 7029): at com.unity3d.player.ReflectionHelper.getMethodID(Unknown Source:26) E/Unity ( 7029): at com.unity3d.player.UnityPlayer.nativeRender(Native Method) E/Unity ( 7029): at com.unity3d.player.UnityPlayer.-$$Nest$mnativeRender(Unknown Source:0) E/Unity ( 7029): at com.unity3d.player.UnityPlayer$F$a.handleMessage(Unknown Source:122) E/Unity ( 7029): at android.os.Handler.dispatchMessage(Handler.java:102) E/Unity ( 7029): at android.os.Looper.loop(Looper.java:214) E/Unity ( 7029): at com.unity3d.player.UnityPlayer$F.run(Unknown Source:24) E/Unity ( 7029): Caused by: java.lang.ClassNotFoundException: Didn't find class "android.window.OnBackInvokedCallback" on path: DexPathList[[zip file "/data/app/com.learntoflutter.flutter_embed_uni I/Unity ( 7029): ARCheckAvailability: available I/Unity ( 7029): UnityEngine.DebugLogHandler:Internal_Log(LogType, LogOption, String, Object) I/Unity ( 7029): UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[]) I/Unity ( 7029): UnityEngine.Logger:Log(LogType, Object) I/Unity ( 7029): UnityEngine.Debug:Log(Object) I/Unity ( 7029): Assets.Scripts.d__2:MoveNext() I/Unity ( 7029): UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr) I/Unity ( 7029): D/ViewRootImpl@da5e15f[MainActivity]( 7029): ViewPostIme pointer 0 D/ViewRootImpl@da5e15f[MainActivity]( 7029): ViewPostIme pointer 1 D/InputMethodManager( 7029): prepareNavigationBarInfo() DecorView@9b0e2bd[MainActivity] D/InputMethodManager( 7029): getNavigationBarColor() -855310 V/InputMethodManager( 7029): Starting input: tba=com.learntoflutter.flutter_embed_unity_example ic=null mNaviBarColor -855310 mIsGetNaviBarColorSuccess true , NavVisible : true , NavTrans : false D/InputMethodManager( 7029): startInputInner - Id : 0 I/InputMethodManager( 7029): startInputInner - mService.startInputOrWindowGainedFocus D/InputTransport( 7029): Input channel constructed: fd=135 D/InputTransport( 7029): Input channel destroyed: fd=119 D/ViewRootImpl@da5e15f[MainActivity]( 7029): setWindowStopped(true) old=false D/SurfaceView( 7029): windowStopped(true) false io.flutter.embedding.android.FlutterSurfaceView{c93b274 V.E...... ........ 0,0-720,1384} of ViewRootImpl@da5e15f[MainActivity] D/SurfaceView( 7029): show() Surface(name=SurfaceView - com.learntoflutter.flutter_embed_unity_example/com.learntoflutter.flutter_embed_unity_example.MainActivity@c93b274@1[7029])/@0xb23b62a io.flutter.embedding.android.FlutterSurfaceView{c93b274 V.E...... ........ 0,0-720,1384} D/SurfaceView( 7029): surfaceDestroyed callback.size 1 #1 io.flutter.embedding.android.FlutterSurfaceView{c93b274 V.E...... ........ 0,0-720,1384} W/libEGL ( 7029): EGLNativeWindowType 0x750117f010 disconnect failed D/SurfaceView( 7029): destroy() Surface(name=SurfaceView - com.learntoflutter.flutter_embed_unity_example/com.learntoflutter.flutter_embed_unity_example.MainActivity@c93b274@1[7029])/@0xb23b62a io.flutter.embedding.android.FlutterSurfaceView{c93b274 V.E...... ........ 0,0-720,1384} D/ViewRootImpl@da5e15f[MainActivity]( 7029): Relayout returned: old=[0,0][720,1480] new=[0,0][720,1480] result=0x1 surface={valid=true 503242113024} changed=false ```

Flutter version

Crashed on:

Did not crash on:

Unity version

Only tested with: 2022.3.21f1, 2022.3.33f1 ArFoundation 5.1.2 and 5.1.4

Minimum reproducible example

Any project using AR with android <13 will likely work to trigger this.

Android devices

Devices without crash:

Devices with crash:

Some things I've tried

timbotimbo commented 5 months ago

Narrowed it down to this commit on Flutter master. Which includes the engine PR Platform channel for predictive back in route transitions on android

timbotimbo commented 4 months ago

With some custom plugin modifications I managed to try this on Unity 2023.2.20 and 6000.0.7. 6000.0.7 even has a Predictive Back Support toggle in the player settings.

I'm still getting the same error, so I will probably have to open an issue in the Flutter repo.

2023.2.20

E/Unity   (17280): AndroidJavaException: java.lang.NoClassDefFoundError: Failed resolution of: Landroid/window/OnBackInvokedCallback;
E/Unity   (17280): java.lang.NoClassDefFoundError: Failed resolution of: Landroid/window/OnBackInvokedCallback;
E/Unity   (17280):   at java.lang.reflect.Executable.getMethodReturnTypeInternal(Native Method)
E/Unity   (17280):   at java.lang.reflect.Method.getReturnType(Method.java:148)
E/Unity   (17280):   at java.lang.Class.getDeclaredMethods(Class.java:1880)
E/Unity   (17280):   at com.unity3d.player.ReflectionHelper.getMethodID(Unknown Source:26)
E/Unity   (17280):   at com.unity3d.player.UnityPlayerForActivityOrService.nativeRender(Native Method)
E/Unity   (17280):   at com.unity3d.player.S.handleMessage(Unknown Source:140)
E/Unity   (17280):   at android.os.Handler.dispatchMessage(Handler.java:102)
E/Unity   (17280):   at android.os.Looper.loop(Looper.java:214)
E/Unity   (17280):   at com.unity3d.player.V.run(Unknown Source:24)
E/Unity   (17280): Caused by: java.lang.ClassNotFoundException: Didn't find class "android.window.OnBackInvokedCallback" on path: DexPathList[

6000

E/Unity   ( 8521): AndroidJavaException: java.lang.NoClassDefFoundError: Failed resolution of: Landroid/window/OnBackInvokedCallback;
E/Unity   ( 8521): java.lang.NoClassDefFoundError: Failed resolution of: Landroid/window/OnBackInvokedCallback;
E/Unity   ( 8521):   at java.lang.reflect.Executable.getMethodReturnTypeInternal(Native Method)
E/Unity   ( 8521):   at java.lang.reflect.Method.getReturnType(Method.java:148)
E/Unity   ( 8521):   at java.lang.Class.getDeclaredMethods(Class.java:1880)
E/Unity   ( 8521):   at com.unity3d.player.ReflectionHelper.getMethodID(Unknown Source:26)
E/Unity   ( 8521):   at com.unity3d.player.UnityPlayerForActivityOrService.nativeRender(Native Method)
E/Unity   ( 8521):   at com.unity3d.player.v0.handleMessage(Unknown Source:140)
E/Unity   ( 8521):   at android.os.Handler.dispatchMessage(Handler.java:102)
E/Unity   ( 8521):   at android.os.Looper.loop(Looper.java:214)
E/Unity   ( 8521):   at com.unity3d.player.x0.run(Unknown Source:24)
E/Unity   ( 8521): Caused by: java.lang.ClassNotFoundException: Didn't find class "android.window.OnBackInvokedCallback" on path: DexPathList[[zip file "/data/app/com....
timbotimbo commented 4 months ago

After a report in the Flutter repo this can be labeled as a Unity issue.

The cause

Once AR boots up, Unity uses the getMethodID function in the ReflectionHelper class of unity-classes.jar . This function gets a list of all function in the current Activity using Java reflection getDeclaredMethods(), and then tries to match function signatures. It then repeats this for all super classes of the current Activity.

The getDeclaredMethods call instantly crashes on Android <13 because it can't handle the OnBackInvokedCallback return type that is defined in API 33.

What now

Flutter won't stop using this class for a few people using the niche use-case of embedding Unity with AR. So AR is broken from now on unless this can be fixed on the Unity side.

With some luck a try-catch around getDeclaredMethods might be enough.

However this means either:

  1. Getting Unity to modify their reflection usage.
  2. Decompiling unity-classes.jar to add a try-catch.

I've tried to decompile unity-classes.jar, but none of the decompilers that I could find returned valid code that could compile again without errors.

Unity reproduction

To replicate this issue witthout Flutter:

  1. export a Unity project using AR as an Android project.
  2. edit the UnityPlayerActivity.java file. Either add a parent Activity that includes this function, or add this function to the Activity itself.
    import android.annotation.TargetApi;
    import android.window.OnBackInvokedCallback;
    @TargetApi(33)
    protected OnBackInvokedCallback getOnBackInvokedCallback() {
        return null;
    }
  3. Now run this using Android Studio on on a device with Android API <33.

TLDR (too long didn't read)

AR is broken with Flutter 3.22+. Don't expect this to be fixed for months, if at all.

jamesncl commented 4 months ago

Thanks again for your tireless and meticulous work tracking all of this @timbotimbo it's very much appreciated. I've added a note to the README for this issue.

timbotimbo commented 3 months ago

This is now in the Unity issue tracker.

They seem to have omitted most details from my bug report, but I guess it is a first step.

Anyone affect by this should probably upvote this in the issuetracker.

timbotimbo commented 1 month ago

Unity got back to me on the bug report, calling it "By Design".

Given that Flutter devs point me at Unity, and Unity considers it by design, AR is likely a lost cause on Android < 13.