wang-bin / fvp

Flutter video player plugin for all desktop+mobile platforms. download prebuilt examples from github actions. https://pub.dev/packages/fvp
BSD 3-Clause "New" or "Revised" License
197 stars 31 forks source link

Black screen when closing mobile screen and reopening #101

Closed abdelaziz-mahdy closed 2 months ago

abdelaziz-mahdy commented 5 months ago

Describe the bug when playing a video and then closing the mobile screen and reopening the video is black.

Expected behavior it should be working

Log info and logs can be found here https://github.com/wang-bin/fvp/issues/98#issuecomment-2183982659

abdelaziz-mahdy commented 5 months ago

trying the https://github.com/wang-bin/fvp/issues/98#issuecomment-2184045413 i always get crashes using local version i did run flutter pub cache clean and flutter clean so will open a pr reverting the impller support and lets try to test it https://github.com/wang-bin/fvp/pull/102

I/flutter (28128): FVP mdk.FINE: 00:32:29.062: AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED
I/flutter (28128): FVP mdk.FINE: 00:32:29.062: MediaFormat: android._color-format: int32(2130708361), android._video-scaling: int32(1), rotation-degrees: int32(0), color-standard: int32(1), color-range: int32(2), color-transfer: int32(3), cta861.max-cll: float(0.000000), cta861.max-fall: float(0.000000), sar-height: int32(1), sar-width: int32(1), crop: Rect(0, 0, 1919, 1079), width: int32(1920), height: int32(1088), max-height: int32(1088), max-width: int32(1920), mime: string(video/raw), priority: int32(0), android._dataspace: int32(260), color-format: int32(2130708361)}
I/flutter (28128): FVP mdk.FINE: 00:32:29.062: unknown, bpc:0, bpp:0(), channels:(), map: 0 0 0 0
I/flutter (28128): FVP mdk.FINE: 00:32:29.062: size: 1920x1080, bytes: 1920x1088
I/flutter (28128): FVP mdk.FINE: 00:32:29.062: video stream#0 sending 1 invalid AOT frame @0.023000s. seeking: 0
I/flutter (28128): FVP mdk.FINE: 00:32:29.062: 0xb4000072803ed0c0 1st video frame to render @0.023000s, sync time: 0.080000
I/flutter (28128): FVP mdk.FINE: 00:32:29.063: VideoRenderer clear buffered frames
I/flutter (28128): FVP mdk.FINE: 00:32:29.063: 0-track seek end video frame @0.023000 seek_pos_: -1
I/flutter (28128): FVP mdk.FINE: 00:32:29.063: 0xb4000072803ed0c0 1st video frame to render @0.023000s, sync time: 0.080000
I/flutter (28128): FVP mdk.FINE: 00:32:29.063: VideoRenderer WxH=1920.000000x1080.000000 1920.000000x1080.000000, frame: 1920x1080
I/flutter (28128): FVP mdk.FINE: 00:32:29.063: update transform 2d. scale: (1.000000, 1.000000), orientation: 0
I/flutter (28128): FVP mdk.FINE: 00:32:29.063: m: mat<4, 4>(
I/flutter (28128): FVP mdk.FINE: 00:32:29.063: 1  0  0  0
I/flutter (28128): FVP mdk.FINE: 00:32:29.063: 0  1  0  0
I/flutter (28128): FVP mdk.FINE: 00:32:29.063: 0  0  1  0
I/flutter (28128): FVP mdk.FINE: 00:32:29.063: 0  0  0  1
I/flutter (28128): FVP mdk.FINE: 00:32:29.063: )
I/flutter (28128): FVP mdk.FINE: 00:32:29.063: ThreadLocal<std::unordered_map<const void *, std::unique_ptr<UGL::opengl::Context>>>::Data::Data() thread: 486411360112
I/flutter (28128): FVP mdk.FINE: 00:32:29.063: T *ThreadLocal<std::unordered_map<const void *, std::unique_ptr<UGL::opengl::Context>>>::get() const allocate and initialize ThreadLocal data
I/flutter (28128): FVP mdk.FINE: 00:32:29.064: new Context object 0xb4000073a0360890(0) for native context handle 0xb40000735034a330
I/flutter (28128): FVP mdk.FINE: 00:32:29.064: ctx->api_: 0xb4000073b05b2ac0
I/flutter (28128): FVP mdk.FINE: 00:32:29.064: probing gl context... native: 0x0
I/flutter (28128): FVP mdk.FINE: 00:32:29.064: EGL_VERSION: 1.5 Android META-EGL
I/flutter (28128): FVP mdk.FINE: 00:32:29.064: EGL_VENDOR: Android
I/flutter (28128): FVP mdk.FINE: 00:32:29.064: EGL_CLIENT_APIS: OpenGL_ES
I/flutter (28128): FVP mdk.FINE: 00:32:29.064: resolving gl common functions...
I/flutter (28128): FVP mdk.FINE: 00:32:29.064: select gl api resolver for EGL|OpenGL|OpenGLES
I/flutter (28128): FVP mdk.FINE: 00:32:29.064: using opengl api resolver: EGL
I/flutter (28128): FVP mdk.FINE: 00:32:29.064: probing gl client context... major_: 0
I/flutter (28128): FVP mdk.FINE: 00:32:29.064: GL_VENDOR: ARM
I/flutter (28128): FVP mdk.FINE: 00:32:29.064: GL_RENDERER: Mali-G78
I/flutter (28128): FVP mdk.FINE: 00:32:29.065: GL_VERSION: OpenGL ES 3.2 v1.r47p0-01eac0.32ea38cfcac3afe9a9b43f4ca33f49a9
I/flutter (28128): FVP mdk.FINE: 00:32:29.065: GL_SHADING_LANGUAGE_VERSION: OpenGL ES GLSL ES 3.20
I/flutter (28128): FVP mdk.FINE: 00:32:29.065: EGL_ANDROID_GLES_layers EGL_ANDROID_front_buffer_auto_refresh EGL_ANDROID_get_frame_timestamps EGL_ANDROID_get_native_client_buffer EGL_ANDROID_image_native_buffer EGL_ANDROID_native_fence_sync EGL_ANDROID_presentation_time EGL_ANDROID_recordable EGL_ANGLE_platform_angle EGL_EXT_client_extensions EGL_EXT_create_context_robustness EGL_EXT_gl_colorspace_bt2020_hlg EGL_EXT_gl_colorspace_bt2020_linear EGL_EXT_gl_colorspace_bt2020_pq EGL_EXT_gl_colorspace_display_p3 EGL_EXT_gl_colorspace_display_p3_linear EGL_EXT_gl_colorspace_display_p3_passthrough EGL_EXT_gl_colorspace_scrgb EGL_EXT_gl_colorspace_scrgb_linear EGL_EXT_image_gl_colorspace EGL_EXT_pixel_format_float EGL_EXT_protected_content EGL_EXT_surface_CTA861_3_metadata EGL_EXT_surface_SMPTE2086_metadata EGL_EXT_yuv_surface EGL_IMG_context_priority EGL_KHR_config_attribs EGL_KHR_create_context EGL_KHR_fence_sync EGL_KHR_get_all_proc_addresses EGL_KHR_gl_colorspace EGL_KHR_gl_renderbuffer_image EGL_KHR_gl_texture_2D_image EGL_KHR_gl
I/flutter (28128): FVP mdk.FINE: 00:32:29.065: OpenGL Context thread: 486411360112
I/flutter (28128): FVP mdk.FINE: 00:32:29.065: OpenGL ES3.2 No profile, EGL150, GLSL320
I/flutter (28128): Features PBO: 1, RG texture: 1, 16bit texture: 0
I/flutter (28128): FVP mdk.FINE: 00:32:29.065: resolving gl extensions...
I/flutter (28128): FVP mdk.FINE: 00:32:29.065: select gl api resolver for EGL|OpenGL|OpenGLES
I/flutter (28128): FVP mdk.FINE: 00:32:29.065: using opengl api resolver: EGL
I/flutter (28128): FVP mdk.FINE: 00:32:29.065: context version: 320
I/flutter (28128): FVP mdk.FINE: 00:32:29.065: extension resolved: glMapBufferOES
I/flutter (28128): FVP mdk.FINE: 00:32:29.065:
I/flutter (28128): FVP mdk.FINE: 00:32:29.065: gl api resolved. thread@ 486411360112
I/flutter (28128): FVP mdk.FINE: 00:32:29.066:
I/flutter (28128): FVP mdk.FINE: 00:32:29.066: 0xb4000073a0360890/0xb40000735034a330 Context::setLocalData local data 0xb4000073503606d0 for key: 0x2. size: 1
I/flutter (28128): FVP mdk.FINE: 00:32:29.066: 0xb4000073a0360890/0xb40000735034a330 Context::setLocalData local data 0xb4000073503609a0 for key: 0x3. size: 2
I/flutter (28128): FVP mdk.FINE: 00:32:29.066: 0xb4000072d0334110mdk::GLVideoRenderer::Private::Renderers::Renderers()
I/flutter (28128): FVP mdk.FINE: 00:32:29.066: 0xb4000073a0360890/0xb40000735034a330 Context::setLocalData local data 0xb40000735035f200 for key: 0x0. size: 3
I/flutter (28128): FVP mdk.FINE: 00:32:29.066: 1Bad mdk license!
I/flutter (28128): FVP mdk.FINE: 00:32:29.066: 1mdk SDK is outdated. Get a new free sdk from https://sourceforge.net/projects/mdk-sdk/files, or purchase a license.
I/flutter (28128): paypal: https://www.paypal.me/ibingow/500 or https://www.qtav.org/donate.html
I/flutter (28128): FVP mdk.FINE: 00:32:29.066:
I/flutter (28128): FVP mdk.FINE: 00:32:29.066: 0xb4000073a0360890/0xb40000735034a330 Context::setLocalData local data 0xb40000735035f830 for key: 0x1. size: 4
I/flutter (28128): FVP mdk.FINE: 00:32:29.066: AHardwareBuffer from AImageReader Surface to EGLImage
I/flutter (28128): FVP mdk.FINE: 00:32:29.066: unknown, bpc:0, bpp:0(), channels:(), map: 0 0 0 0 => mapped rgba, bpc:8, bpp:32(32), channels:(4), map: 0 1 2 3
I/flutter (28128): FVP mdk.FINE: 00:32:29.066:  RGBA8 |  RGBA | UNSIGNED_BYTE
I/flutter (28128): FVP mdk.FINE: 00:32:29.066: frame color: bt709 bt709 bt709 narrow. gamma: 2.200000, signal peak: 1.000000
I/flutter (28128): FVP mdk.FINE: 00:32:29.066:  -
I/flutter (28128): FVP mdk.FINE: 00:32:29.067: output color: bt709 unknown unknown full. gamma: 2.200000, signal peak: 1.000000
I/flutter (28128): FVP mdk.FINE: 00:32:29.067: rgb primaries matrix: mat<3, 3>(
I/flutter (28128): FVP mdk.FINE: 00:32:29.067: 1  0  0
I/flutter (28128): FVP mdk.FINE: 00:32:29.067: 0  1  0
I/flutter (28128): FVP mdk.FINE: 00:32:29.067: 0  0  1
I/flutter (28128): FVP mdk.FINE: 00:32:29.067: )
I/flutter (28128): FVP mdk.FINE: 00:32:29.067: color transform: mat<4, 4>(
I/flutter (28128): FVP mdk.FINE: 00:32:29.067: 1  0  0  0
I/flutter (28128): FVP mdk.FINE: 00:32:29.067: 0  1  0  0
I/flutter (28128): FVP mdk.FINE: 00:32:29.067: 0  0  1  0
I/flutter (28128): FVP mdk.FINE: 00:32:29.067: 0  0  0  1
I/flutter (28128): FVP mdk.FINE: 00:32:29.067: )
I/flutter (28128): FVP mdk.FINE: 00:32:29.068: EQ: mat<4, 4>(
I/flutter (28128): FVP mdk.FINE: 00:32:29.068: 1  0  0  0
I/flutter (28128): FVP mdk.FINE: 00:32:29.068: 0  1  0  0
I/flutter (28128): FVP mdk.FINE: 00:32:29.068: 0  0  1  0
I/flutter (28128): FVP mdk.FINE: 00:32:29.068: 0  0  0  1
I/flutter (28128): FVP mdk.FINE: 00:32:29.068: )
I/flutter (28128): FVP mdk.FINE: 00:32:29.068: material changed: 0x0=>0x90a
I/flutter (28128): FVP mdk.FINE: 00:32:29.068: planar: 0, alpha: 1, texture 2d: 0, external: 1, rg semi-planar: 0, 16=>8: 0, xyz: 0, generic packed yuv: 0, cocgsy: 0, primaries diff: 0, trc: 1=>1, tone map: 0
I/flutter (28128): FVP mdk.FINE: 00:32:29.068: bind attribute: a_Position => 0
I/flutter (28128): FVP mdk.FINE: 00:32:29.068: bind attribute: a_TexCoords0 => 1
I/flutter (28128): FVP mdk.FINE: 00:32:29.068: uniform locations:
I/flutter (28128): FVP mdk.FINE: 00:32:29.068: u_Texture0: 0
I/flutter (28128): FVP mdk.FINE: 00:32:29.068: u_Matrix: 2, u_TexMatrix: 1
I/flutter (28128): FVP mdk.FINE: 00:32:29.069: update built-in uniforms
I/flutter (28128): FVP mdk.FINE: 00:32:29.069: EQ: mat<4, 4>(
I/flutter (28128): FVP mdk.FINE: 00:32:29.069: 1  0  0  0
I/flutter (28128): FVP mdk.FINE: 00:32:29.069: 0  1  0  0
I/flutter (28128): FVP mdk.FINE: 00:32:29.069: 0  0  1  0
I/flutter (28128): FVP mdk.FINE: 00:32:29.069: 0  0  0  1
I/flutter (28128): FVP mdk.FINE: 00:32:29.069: )
I/flutter (28128): FVP mdk.FINE: 00:32:29.069: uniform cb.u_colorMatrix: 3
I/flutter (28128): FVP mdk.FINE: 00:32:29.069: uniform cb.u_ScaleA: 4
I/flutter (28128): FVP mdk.FINE: 00:32:29.069: creating vbo...
I/flutter (28128): FVP mdk.FINE: 00:32:29.069: creating vao...
I/flutter (28128): FVP fvp.FINE: 00:32:29.069: 288013959 player-5476376655373174304 onEvent: render.video - 1st_frame - 23
I/flutter (28128): FVP mdk.INFO: 00:32:29.071: setLoop(0), now 0/0
I/flutter (28128): FVP mdk.FINE: 00:32:29.071: 0xb4000072803ed0c0 virtual void mdk::MediaControlPush::setState(mdk::PlaybackState)@969 requested state 2=>2, current state 2. status: 0X124
I/flutter (28128): FVP mdk.FINE: 00:32:29.071: default FrameReader0xb4000072e031a8b0 request to pause 1, loaded: 4.
I/flutter (28128): FVP mdk.FINE: 00:32:29.071: default FrameReader0xb4000072e031a8b0 state: 2=>2=>2, 0
I/flutter (28128): FVP mdk.INFO: 00:32:29.071: 0xb4000072803ed0c0-MediaControl::seek(pos: 0, flag:0X402 +FromStart). now: 80
I/flutter (28128): FVP mdk.FINE: 00:32:29.072: default 0xb4000072e031a8b0-FrameReader::seek(0, 0X402)
I/flutter (28128): FVP mdk.FINE: 00:32:29.072: default 0xb4000072e031a8b0 FrameReader::update MediaStatus 0X124=>0X1A4
I/flutter (28128): FVP fvp.FINE: 00:32:29.072: 288013959 player-5476376655373174304 onMediaStatus: MediaStatus(+loaded+prepared+buffered) => MediaStatus(+loaded+prepared+buffered)
I/flutter (28128): FVP mdk.FINE: 00:32:29.072: 0xb4000072e031a8b0 default FrameReaderImpl::seekTo(0, 0X402 #1)
I/flutter (28128): FVP mdk.FINE: 00:32:29.072: 0xb4000072803ed0c0 virtual void mdk::MediaControlPush::setState(mdk::PlaybackState)@969 requested state 2=>1, current state 2. status: 0X1A4
I/flutter (28128): FVP mdk.FINE: 00:32:29.072: default FrameReader0xb4000072e031a8b0 request to pause 0, loaded: 4.
I/flutter (28128): FVP mdk.FINE: 00:32:29.072: default FrameReader0xb4000072e031a8b0 state: 2=>2=>1, 0
I/flutter (28128): FVP mdk.FINE: 00:32:29.072: default FrameReader0xb4000072e031a8b0 state requested: 1, current: 2
I/flutter (28128): FVP mdk.FINE: 00:32:29.072: audio stream#1 AOT frame is sent
I/flutter (28128): FVP mdk.FINE: 00:32:29.072: video stream#0 AOT frame is sent
I/flutter (28128): FVP mdk.INFO: 00:32:29.073: virtual int64_t mdk::PacketIOWrapper::seek(int64_t, mdk::SeekFlag)@539 seek target(from 0): 0ms, flags: +FromStart. now: 12.748000
I/flutter (28128): FVP mdk.FINE: 00:32:29.073: default 0xb4000072e031a8b0 FrameReader::update MediaStatus 0X1A4=>0X1A4
I/flutter (28128): FVP mdk.FINE: 00:32:29.073: Seek start. target time: 0 avseek flags: 1
I/flutter (28128): FVP mdk.FINE: 00:32:29.075: Seek end
I/flutter (28128): FVP mdk.FINE: 00:32:29.075: 1 packets is read after seek. read more to get target pts
I/flutter (28128): FVP mdk.FINE: 00:32:29.075: 1 packets is read after seek. seek result pts: 0.023s, requested: 0
I/flutter (28128): FVP mdk.FINE: 00:32:29.075: default 0xb4000072e031a8b0 FrameReader::update MediaStatus 0X1A4=>0X124
I/flutter (28128): FVP fvp.FINE: 00:32:29.075: 288013959 player-5476376655373174304 onMediaStatus: MediaStatus(+loaded+prepared+buffered) => MediaStatus(+loaded+prepared+buffered)
I/flutter (28128): FVP mdk.FINE: 00:32:29.075: seek_drop_non_video_: -4 ms, seek_wait_frame_: 0...
I/flutter (28128): FVP mdk.FINE: 00:32:29.076: default FrameReader0xb4000072e031a8b0 state: 2=>1=>1, 1
I/flutter (28128): FVP mdk.FINE: 00:32:29.076: default FrameReader0xb4000072e031a8b0 update state: 2=>1
I/flutter (28128): FVP fvp.FINE: 00:32:29.076: 288013959 player-5476376655373174304 onPlaybackStateChanged: PlaybackState.paused => PlaybackState.playing
I/flutter (28128): FVP mdk.FINE: 00:32:29.076: audio stream#1 is seeking... got flush pkt. flush decoder and  drop frames until seek target -0.0040s...
I/flutter (28128): FVP mdk.FINE: 00:32:29.077: invalid audio frame @-1.000000
I/flutter (28128): FVP mdk.FINE: 00:32:29.077: #1/1 audio seek_done: 1, seek_wait_frame_: 0/1
I/flutter (28128): FVP mdk.FINE: 00:32:29.077: audio stream#1 sending 1 invalid AOT frame @0.000000s. seeking: 0
I/flutter (28128): FVP mdk.INFO: 00:32:29.077: 0xb4000072803ed0c0 seek end audio frame @0.000000 seek_pos_: -1, sync_ao_ 1
I/flutter (28128): FVP mdk.FINE: 00:32:29.077: >>>>>>>>1st audio frame (after seek) rendered: 1, ao: 0, a: 0, delta: 0 +0.023220
I/flutter (28128): FVP mdk.FINE: 00:32:29.077: audio stream#1 AOT frame is sent
E/MediaCodec(28128): releaseOutputBuffer() is valid only at Executing states; currently during flush()
E/NdkMediaCodec(28128): untranslated sf error code: -38
I/CCodecConfig(28128): query failed after returning 15 values (BAD_INDEX)
W/Codec2Client(28128): query -- param skipped: index = 1073743886.
W/Codec2Client(28128): query -- param skipped: index = 1610614798.
D/CCodecBufferChannel(28128): [c2.exynos.h264.decoder#698] Ignoring stale input buffer done callback: last flush index = 11, frameIndex = 11
F/libc    (28128): Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0 in tid 28208 (1.ui), pid 28128 (ions.anime_here)
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'google/oriole/oriole:14/AP2A.240605.024/11860263:user/release-keys'
Revision: 'MP1.0'
ABI: 'arm64'
Timestamp: 2024-06-23 00:32:29.843187339+0300
Process uptime: 125s
Cmdline: com.zcreations.anime_here
pid: 28128, tid: 28208, name: 1.ui  >>> com.zcreations.anime_here <<<
uid: 10289
tagged_addr_ctrl: 0000000000000001 (PR_TAGGED_ADDR_ENABLE)
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0000000000000000
Cause: null pointer dereference
    x0  b400007270452c20  x1  b4000072a02f2ff0  x2  0000000000000010  x3  0000006f072a77d9
    x4  0000000000000000  x5  b400007270452c20  x6  b4000072a02f2ff0  x7  0000000000000010
    x8  b400007330c32c10  x9  0000000000000000  x10 0000000000000005  x11 0000000000003590
    x12 000000007fffffff  x13 000000000241fe04  x14 000000000241fe04  x15 0000007157115300
    x16 0000000000000000  x17 b400007330c33388  x18 0000007156140000  x19 00000071c8c32a94
    x20 0000007157115df8  x21 b400007330c32c10  x22 0000006f00008081  x23 000e26e9399d0e9b
    x24 0000006f00008081  x25 0000007156f34000  x26 b400007330c32c10  x27 0000006f09a2e160
    x28 000000080000006f  x29 0000007157115318
    lr  000000714f187fd8  sp  0000007157115300  pc  0000000000000000  pst 0000000060001000
2 total frames
backtrace:
      #00 pc 0000000000000000  <unknown>
      #01 pc 0000000000007fd4  [anon:dart-code]
Lost connection to device.

Exited.
wang-bin commented 5 months ago

trying the https://github.com/wang-bin/fvp/issues/98#issuecomment-2184045413 i always get crashes using local version

it's weird, i can't reproduce the crash. can I test your apk?

abdelaziz-mahdy commented 5 months ago

testing with example doesnt crash i am confused, i think i will need to try again, but cant do it right now

abdelaziz-mahdy commented 4 months ago

i think will leave this open until the lifecycle stuff released in flutter and then migrate to it and use surface producer only instead of the current workaround correct? so its blocked by: https://github.com/flutter/flutter/issues/148417

wang-bin commented 4 months ago

current code is ok

abdelaziz-mahdy commented 4 months ago

current code is ok

current code will result of a black screen on impeller when screen goes off, so the life cycle stuff needs to be handled,

so the black screen issue is still happens on impeller

wang-bin commented 4 months ago

wait for official solution. current code is the best we can do.

abdelaziz-mahdy commented 4 months ago

yes i dont mind that but keeping issue open will be a reminder to know that, the issue is blocked by flutter and when they fix it we will too? dont you think

just so it doesnt get forgotten or people misunderstand that its is fixed fully

wang-bin commented 4 months ago

I was wrong. If a surface destroyed then a new one is recreated(and rotated), they are different surfaces, but their texture id can be the same, so it's easy to fix the issue if the callback api is ready.

wang-bin commented 4 months ago

I see flutter is going to recreate player object and restart playback, it's unnecessary and can be slow, maybe it's exoplayer's limitation. Mdk supports recreating renderer with a different surface, the result is frame accurate and fast

abdelaziz-mahdy commented 4 months ago

I see flutter is going to recreate player object and restart playback, it's unnecessary and can be slow, maybe it's exoplayer's limitation. Mdk supports recreating renderer with a different surface, the result is frame accurate and fast

I agree that restarting playback is not efficient, glad that mdk got it handled better

abdelaziz-mahdy commented 2 months ago

the pr has been merged i think now this can be fixed

wang-bin commented 2 months ago

try impeller branch. I'm wondering how can the code support 3.24 and old versions

abdelaziz-mahdy commented 2 months ago

I saw this problem on flutter repo for video_player and when I am migrating media_kit

I guess if java has a conditional compilation that will work correctly?

Something like the API version stuff?

wang-bin commented 2 months ago

java does not support conditional compilation

abdelaziz-mahdy commented 2 months ago

i guess we cant do anything, flutter released it and updated minsdk to 3.24.

wang-bin commented 2 months ago

impeller branch now supports 3.24+ and lower. gradle rewrites java code when necessary

abdelaziz-mahdy commented 2 months ago

Wow I never thought it can be handled like that, nice