sweyer icon indicating copy to clipboard operation
sweyer copied to clipboard

Move the native Android code of Sweyer into a plugin

Open Abestanis opened this issue 2 years ago • 2 comments

I'm opening this as a draft so you can see what I'm working on right now. Once the remaining issues are resolved I will mark this as ready for review.

This is a rather big change, sorry about that. This is work towards the homescreen widget.

We move all of the Android specific Java code into a plugin called sweyer_plugin. During the migration, I converted the former ContentChannel.java to Kotlin and merged it into SweyerPlugin.kt, because it was easier that way.

This fixes #73. The problem was that if Sweyer was not started via the main activity, then the content_channel MethodChannel wouldn't be registered, causing the app to throw on startup.

This can be replicated as follows:

  1. Make sure Sweyer is not started and that there is no cached FlutterEngine. This is the case after a long time of not using the app, a phone reboot or after force stopping Sweyer.
  2. Emit a media play/pause key press. This can be done by attaching a physical device with a play/pause button to the phone, like a headset, and pressing the button. Alternatively, we can use the Android Debug Bridge to emit the corresponding keycode (KEYCODE_MEDIA_PLAY_PAUSE, 85):
    adb shell input keyevent 85
    
  3. Observe that no music is played and the following error can be seen in Logcat:
    Stacktrace
    MissingPluginException(No implementation found for method retrieveSongs on channel content_channel)
    #0      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:165:7)
    <asynchronous suspension>
    #1      MethodChannel.invokeListMethod (package:flutter/src/services/platform_channel.dart:353:35)
    <asynchronous suspension>
    #2      ContentChannel.retrieveSongs (package:sweyer/logic/player/content_channel.dart:113:18)
    <asynchronous suspension>
    #3      ContentControl.refetch (package:sweyer/logic/player/content.dart:383:33)
    <asynchronous suspension>
    #4      Future.wait.<anonymous closure> (dart:async/future.dart:521:21)
    <asynchronous suspension>
    #5      Future.any.onValue (dart:async/future.dart:611:5)
    <asynchronous suspension>
    
  4. In addition to this, the app can also no longer be started normally (via the launcher), it get's stuck at the splash screen.

The reason this is happening is that the key press causes the AudioService to be launched, which creates a new FlutterEngine and starts the app in the service in the background (as it should). The MainActivity is never started, so the MethodChannel is never registered.

To work around this problem, we use the automagically generated GeneratedPluginRegistrant which will automatically load all plugins when a FlutterEngine is created. This allows us to register the method channel even if the MainActivity is never started.

With the changes in this PR, pressing the media play/pause button successfully starts the app in the background and the music starts to play (after about 5 seconds, but that is another issue). There is another problem that no notification for the media session is shown, I have to investigate that.

Here are the Logcat logs before and after this PR when pressing the media play/pause button:

Before
2022-07-14 20:57:32.324 535-2110/? D/PendingIntentHolder: Sending KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_MEDIA_PLAY_PAUSE, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=10409813, downTime=10409813, deviceId=-1, source=0x0, displayId=-1 } to the last known PendingIntent PendingIntent{6fc7c87: PendingIntentRecord{46cbf24 com.nt4f04und.sweyer broadcastIntent}}
2022-07-14 20:57:32.324 535-2110/? D/PendingIntentHolder: Sending KeyEvent { action=ACTION_UP, keyCode=KEYCODE_MEDIA_PLAY_PAUSE, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=10409813, downTime=10409813, deviceId=-1, source=0x0, displayId=-1 } to the last known PendingIntent PendingIntent{6fc7c87: PendingIntentRecord{46cbf24 com.nt4f04und.sweyer broadcastIntent}}
2022-07-14 20:57:32.339 535-560/? I/ActivityManager: Start proc 10498:com.nt4f04und.sweyer/u0a181 for broadcast {com.nt4f04und.sweyer/com.ryanheise.audioservice.MediaButtonReceiver}
2022-07-14 20:57:32.406 10498-10498/com.nt4f04und.sweyer I/t4f04und.sweye: The ClassLoaderContext is a special shared library.
2022-07-14 20:57:32.646 10498-10498/com.nt4f04und.sweyer D/NetworkSecurityConfig: No Network Security Config specified, using platform default
2022-07-14 20:57:32.646 10498-10498/com.nt4f04und.sweyer D/NetworkSecurityConfig: No Network Security Config specified, using platform default
2022-07-14 20:57:32.689 10498-10498/com.nt4f04und.sweyer I/FirebaseApp: Device unlocked: initializing all Firebase APIs for app [DEFAULT]
2022-07-14 20:57:32.702 10498-10498/com.nt4f04und.sweyer I/FirebaseCrashlytics: Initializing Firebase Crashlytics 18.2.11 for com.nt4f04und.sweyer
2022-07-14 20:57:32.750 10498-10524/com.nt4f04und.sweyer I/DynamiteModule: Considering local module com.google.android.gms.measurement.dynamite:73 and remote module com.google.android.gms.measurement.dynamite:74
2022-07-14 20:57:32.750 10498-10524/com.nt4f04und.sweyer I/DynamiteModule: Selected remote version of com.google.android.gms.measurement.dynamite, version >= 74
2022-07-14 20:57:32.751 10498-10524/com.nt4f04und.sweyer V/DynamiteModule: Dynamite loader version >= 2, using loadModule2NoCrashUtils
2022-07-14 20:57:32.780 10498-10524/com.nt4f04und.sweyer W/System: ClassLoader referenced unknown path: 
2022-07-14 20:57:32.843 10498-10498/com.nt4f04und.sweyer I/FirebaseInitProvider: FirebaseApp initialization successful
2022-07-14 20:57:32.857 10498-10498/com.nt4f04und.sweyer D/MediaBrowserCompat: Connecting to a MediaBrowserService.
2022-07-14 20:57:32.871 10498-10498/com.nt4f04und.sweyer I/System.out: ### onCreate
2022-07-14 20:57:32.886 535-1496/? D/MediaSessionService: Media button session is changed to com.nt4f04und.sweyer/media-session (userId=0)
2022-07-14 20:57:32.889 670-670/? I/AvrcpMediaPlayerList: Adding wrapped media player: com.nt4f04und.sweyer at key: 1
2022-07-14 20:57:32.889 670-670/? I/AvrcpMediaPlayerList: onMediaKeyEventSessionChanged: token=com.nt4f04und.sweyer
2022-07-14 20:57:32.893 670-670/? D/AvrcpMediaPlayerList: setActivePlayer(): setting player to com.nt4f04und.sweyer
2022-07-14 20:57:32.903 10498-10498/com.nt4f04und.sweyer I/System.out: ### AudioService will resume on click
2022-07-14 20:57:32.908 670-670/? V/AvrcpMediaPlayerWrapper: onPlaybackStateChanged(): com.nt4f04und.sweyer : PlaybackState {state=0, position=0, buffered position=0, speed=0.0, updated=0, actions=4, custom actions=[], active item id=-1, error=null}
2022-07-14 20:57:32.912 670-670/? V/AvrcpMediaPlayerWrapper: onQueueChanged(): com.nt4f04und.sweyer tried to update with no queue
2022-07-14 20:57:32.917 10498-10498/com.nt4f04und.sweyer I/System.out: ### Creating new FlutterEngine
2022-07-14 20:57:32.960 10498-10533/com.nt4f04und.sweyer I/FA: App measurement initialized, version: 65003
2022-07-14 20:57:32.960 10498-10533/com.nt4f04und.sweyer I/FA: To enable debug logging run: adb shell setprop log.tag.FA VERBOSE
2022-07-14 20:57:32.961 10498-10533/com.nt4f04und.sweyer I/FA: To enable faster debug mode event logging run:
      adb shell setprop debug.firebase.analytics.app com.nt4f04und.sweyer
2022-07-14 20:57:32.968 10498-10536/com.nt4f04und.sweyer I/ResourceExtractor: Found extracted resources res_timestamp-9-1657823873553
2022-07-14 20:57:33.065 10498-10498/com.nt4f04und.sweyer W/t4f04und.sweyer: type=1400 audit(0.0:605): avc: denied { read } for name="max_map_count" dev="proc" ino=367727 scontext=u:r:untrusted_app:s0:c181,c256,c512,c768 tcontext=u:object_r:proc_max_map_count:s0 tclass=file permissive=0 app=com.nt4f04und.sweyer
2022-07-14 20:57:33.125 10498-10498/com.nt4f04und.sweyer D/libEGL: loaded /vendor/lib/egl/libEGL_emulation.so
2022-07-14 20:57:33.133 10498-10498/com.nt4f04und.sweyer D/libEGL: loaded /vendor/lib/egl/libGLESv1_CM_emulation.so
2022-07-14 20:57:33.143 10498-10498/com.nt4f04und.sweyer D/libEGL: loaded /vendor/lib/egl/libGLESv2_emulation.so
2022-07-14 20:57:33.197 10498-10498/com.nt4f04und.sweyer D/HostConnection: HostConnection::get() New Host Connection established 0xf4f6c770, tid 10498
2022-07-14 20:57:33.203 10498-10498/com.nt4f04und.sweyer D/HostConnection: HostComposition ext ANDROID_EMU_CHECKSUM_HELPER_v1 ANDROID_EMU_native_sync_v2 ANDROID_EMU_native_sync_v3 ANDROID_EMU_native_sync_v4 ANDROID_EMU_dma_v1 ANDROID_EMU_direct_mem ANDROID_EMU_host_composition_v1 ANDROID_EMU_host_composition_v2 ANDROID_EMU_vulkan ANDROID_EMU_deferred_vulkan_commands ANDROID_EMU_vulkan_null_optional_strings ANDROID_EMU_vulkan_create_resources_with_requirements ANDROID_EMU_YUV_Cache ANDROID_EMU_vulkan_ignored_handles ANDROID_EMU_has_shared_slots_host_memory_allocator ANDROID_EMU_vulkan_free_memory_sync ANDROID_EMU_vulkan_shader_float16_int8 ANDROID_EMU_vulkan_async_queue_submit ANDROID_EMU_sync_buffer_data ANDROID_EMU_read_color_buffer_dma GL_OES_vertex_array_object GL_KHR_texture_compression_astc_ldr ANDROID_EMU_host_side_tracing ANDROID_EMU_gles_max_version_2 
2022-07-14 20:57:33.216 10498-10498/com.nt4f04und.sweyer D/EGL_emulation: eglCreateContext: 0xf4f6df80: maj 2 min 0 rcv 2
2022-07-14 20:57:33.217 10498-10498/com.nt4f04und.sweyer D/EGL_emulation: eglCreateContext: 0xf4f6f020: maj 2 min 0 rcv 2
2022-07-14 20:57:33.250 10498-10542/com.nt4f04und.sweyer D/HostConnection: HostConnection::get() New Host Connection established 0xf4f6dea0, tid 10542
2022-07-14 20:57:33.254 10498-10542/com.nt4f04und.sweyer D/HostConnection: HostComposition ext ANDROID_EMU_CHECKSUM_HELPER_v1 ANDROID_EMU_native_sync_v2 ANDROID_EMU_native_sync_v3 ANDROID_EMU_native_sync_v4 ANDROID_EMU_dma_v1 ANDROID_EMU_direct_mem ANDROID_EMU_host_composition_v1 ANDROID_EMU_host_composition_v2 ANDROID_EMU_vulkan ANDROID_EMU_deferred_vulkan_commands ANDROID_EMU_vulkan_null_optional_strings ANDROID_EMU_vulkan_create_resources_with_requirements ANDROID_EMU_YUV_Cache ANDROID_EMU_vulkan_ignored_handles ANDROID_EMU_has_shared_slots_host_memory_allocator ANDROID_EMU_vulkan_free_memory_sync ANDROID_EMU_vulkan_shader_float16_int8 ANDROID_EMU_vulkan_async_queue_submit ANDROID_EMU_sync_buffer_data ANDROID_EMU_read_color_buffer_dma GL_OES_vertex_array_object GL_KHR_texture_compression_astc_ldr ANDROID_EMU_host_side_tracing ANDROID_EMU_gles_max_version_2 
2022-07-14 20:57:33.287 10498-10542/com.nt4f04und.sweyer D/EGL_emulation: eglMakeCurrent: 0xf4f6f020: ver 2 0 (tinfo 0xf52b9770) (first time)
2022-07-14 20:57:33.311 10498-10498/com.nt4f04und.sweyer I/System.out: ### onAttachedToEngine
2022-07-14 20:57:33.313 10498-10498/com.nt4f04und.sweyer I/System.out: ### 1 client handlers
2022-07-14 20:57:33.316 10498-10498/com.nt4f04und.sweyer I/System.out: ### new AudioHandlerInterface
2022-07-14 20:57:33.316 10498-10498/com.nt4f04und.sweyer I/System.out: ### connect
2022-07-14 20:57:33.316 10498-10498/com.nt4f04und.sweyer D/MediaBrowserCompat: Connecting to a MediaBrowserService.
2022-07-14 20:57:33.317 10498-10498/com.nt4f04und.sweyer I/System.out: ### connect returned
2022-07-14 20:57:33.317 10498-10498/com.nt4f04und.sweyer I/System.out: ### onAttachedToEngine completed
2022-07-14 20:57:33.363 10498-10498/com.nt4f04und.sweyer I/System.out: flutterEngine warmed up
2022-07-14 20:57:33.382 10498-10498/com.nt4f04und.sweyer I/System.out: ### onGetRoot. isRecentRequest=false
2022-07-14 20:57:33.384 10498-10498/com.nt4f04und.sweyer I/System.out: ### onGetRoot. isRecentRequest=false
2022-07-14 20:57:33.386 10498-10498/com.nt4f04und.sweyer I/System.out: ### onConnected
2022-07-14 20:57:33.405 10498-10498/com.nt4f04und.sweyer I/System.out: ### registered mediaController callback
2022-07-14 20:57:33.412 10498-10498/com.nt4f04und.sweyer I/System.out: ### onConnected returned
2022-07-14 20:57:33.417 10498-10498/com.nt4f04und.sweyer I/System.out: ### onMediaButtonEvent: KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_MEDIA_PLAY_PAUSE, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=10409813, downTime=10409813, deviceId=-1, source=0x0, displayId=-1 }
2022-07-14 20:57:33.417 10498-10498/com.nt4f04und.sweyer I/System.out: ### listener = com.ryanheise.audioservice.AudioServicePlugin$AudioHandlerInterface@939e583
2022-07-14 20:57:33.417 10498-10498/com.nt4f04und.sweyer I/System.out: ### calling onClick
2022-07-14 20:57:33.417 10498-10498/com.nt4f04und.sweyer I/System.out: ### sending click map: {button=0}
2022-07-14 20:57:33.418 10498-10498/com.nt4f04und.sweyer I/System.out: ### called onClick
2022-07-14 20:57:33.420 10498-10498/com.nt4f04und.sweyer D/MediaBrowserCompat: Connecting to a MediaBrowserService.
2022-07-14 20:57:33.424 10498-10498/com.nt4f04und.sweyer I/System.out: ### onGetRoot. isRecentRequest=false
2022-07-14 20:57:33.433 10498-10498/com.nt4f04und.sweyer I/System.out: ### onMediaButtonEvent: KeyEvent { action=ACTION_UP, keyCode=KEYCODE_MEDIA_PLAY_PAUSE, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=10409813, downTime=10409813, deviceId=-1, source=0x0, displayId=-1 }
2022-07-14 20:57:33.433 10498-10498/com.nt4f04und.sweyer I/System.out: ### listener = com.ryanheise.audioservice.AudioServicePlugin$AudioHandlerInterface@939e583
2022-07-14 20:57:33.444 10498-10551/com.nt4f04und.sweyer I/flutter: The Dart VM service is listening on http://127.0.0.1:45411/sY46zHUiGW0=/
2022-07-14 20:57:34.442 10498-10540/com.nt4f04und.sweyer I/flutter: ----------------FIREBASE CRASHLYTICS----------------
2022-07-14 20:57:34.443 10498-10540/com.nt4f04und.sweyer I/flutter: MissingPluginException(No implementation found for method retrieveSongs on channel content_channel)
2022-07-14 20:57:34.443 10498-10540/com.nt4f04und.sweyer I/flutter: #0      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:165:7)
    <asynchronous suspension>
    #1      MethodChannel.invokeListMethod (package:flutter/src/services/platform_channel.dart:353:35)
    <asynchronous suspension>
    #2      ContentChannel.retrieveSongs (package:sweyer/logic/player/content_channel.dart:113:18)
    <asynchronous suspension>
    #3      ContentControl.refetch (package:sweyer/logic/player/content.dart:383:33)
    <asynchronous suspension>
    #4      Future.wait.<anonymous closure> (dart:async/future.dart:521:21)
    <asynchronous suspension>
    #5      Future.any.onValue (dart:async/future.dart:611:5)
    <asynchronous suspension>
2022-07-14 20:57:34.443 10498-10540/com.nt4f04und.sweyer I/flutter: ----------------------------------------------------
After
2022-07-14 21:35:18.285 535-549/? D/PendingIntentHolder: Sending KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_MEDIA_PLAY_PAUSE, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=12675709, downTime=12675709, deviceId=-1, source=0x0, displayId=-1 } to the last known PendingIntent PendingIntent{2ac6e81: PendingIntentRecord{46cbf24 com.nt4f04und.sweyer broadcastIntent}}
2022-07-14 21:35:18.285 535-549/? D/PendingIntentHolder: Sending KeyEvent { action=ACTION_UP, keyCode=KEYCODE_MEDIA_PLAY_PAUSE, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=12675709, downTime=12675709, deviceId=-1, source=0x0, displayId=-1 } to the last known PendingIntent PendingIntent{2ac6e81: PendingIntentRecord{46cbf24 com.nt4f04und.sweyer broadcastIntent}}
    
    --------- beginning of system
2022-07-14 21:35:18.296 535-560/? I/ActivityManager: Start proc 11675:com.nt4f04und.sweyer/u0a181 for broadcast {com.nt4f04und.sweyer/com.ryanheise.audioservice.MediaButtonReceiver}
2022-07-14 21:35:18.347 11675-11675/com.nt4f04und.sweyer I/t4f04und.sweye: The ClassLoaderContext is a special shared library.
2022-07-14 21:35:18.542 11675-11675/com.nt4f04und.sweyer D/NetworkSecurityConfig: No Network Security Config specified, using platform default
2022-07-14 21:35:18.542 11675-11675/com.nt4f04und.sweyer D/NetworkSecurityConfig: No Network Security Config specified, using platform default
2022-07-14 21:35:18.577 11675-11675/com.nt4f04und.sweyer I/FirebaseApp: Device unlocked: initializing all Firebase APIs for app [DEFAULT]
2022-07-14 21:35:18.589 11675-11675/com.nt4f04und.sweyer I/FirebaseCrashlytics: Initializing Firebase Crashlytics 18.2.11 for com.nt4f04und.sweyer
2022-07-14 21:35:18.634 11675-11700/com.nt4f04und.sweyer I/DynamiteModule: Considering local module com.google.android.gms.measurement.dynamite:73 and remote module com.google.android.gms.measurement.dynamite:74
2022-07-14 21:35:18.634 11675-11700/com.nt4f04und.sweyer I/DynamiteModule: Selected remote version of com.google.android.gms.measurement.dynamite, version >= 74
2022-07-14 21:35:18.634 11675-11700/com.nt4f04und.sweyer V/DynamiteModule: Dynamite loader version >= 2, using loadModule2NoCrashUtils
2022-07-14 21:35:18.655 11675-11700/com.nt4f04und.sweyer W/System: ClassLoader referenced unknown path: 
2022-07-14 21:35:18.716 11675-11675/com.nt4f04und.sweyer I/FirebaseInitProvider: FirebaseApp initialization successful
2022-07-14 21:35:18.727 11675-11675/com.nt4f04und.sweyer D/MediaBrowserCompat: Connecting to a MediaBrowserService.
2022-07-14 21:35:18.741 11675-11675/com.nt4f04und.sweyer I/System.out: ### onCreate
2022-07-14 21:35:18.753 535-3654/? D/MediaSessionService: Media button session is changed to com.nt4f04und.sweyer/media-session (userId=0)
2022-07-14 21:35:18.760 670-670/? I/AvrcpMediaPlayerList: Adding wrapped media player: com.nt4f04und.sweyer at key: 1
2022-07-14 21:35:18.760 670-670/? I/AvrcpMediaPlayerList: onMediaKeyEventSessionChanged: token=com.nt4f04und.sweyer
2022-07-14 21:35:18.761 670-670/? D/AvrcpMediaPlayerList: setActivePlayer(): setting player to com.nt4f04und.sweyer
2022-07-14 21:35:18.770 11675-11675/com.nt4f04und.sweyer I/System.out: ### AudioService will resume on click
2022-07-14 21:35:18.774 670-670/? V/AvrcpMediaPlayerWrapper: onPlaybackStateChanged(): com.nt4f04und.sweyer : PlaybackState {state=0, position=0, buffered position=0, speed=0.0, updated=0, actions=4, custom actions=[], active item id=-1, error=null}
2022-07-14 21:35:18.776 670-670/? V/AvrcpMediaPlayerWrapper: onQueueChanged(): com.nt4f04und.sweyer tried to update with no queue
2022-07-14 21:35:18.782 11675-11675/com.nt4f04und.sweyer I/System.out: ### Creating new FlutterEngine
2022-07-14 21:35:18.815 11675-11709/com.nt4f04und.sweyer I/FA: App measurement initialized, version: 65003
2022-07-14 21:35:18.816 11675-11709/com.nt4f04und.sweyer I/FA: To enable debug logging run: adb shell setprop log.tag.FA VERBOSE
2022-07-14 21:35:18.816 11675-11709/com.nt4f04und.sweyer I/FA: To enable faster debug mode event logging run:
      adb shell setprop debug.firebase.analytics.app com.nt4f04und.sweyer
2022-07-14 21:35:18.826 11675-11713/com.nt4f04und.sweyer I/ResourceExtractor: Found extracted resources res_timestamp-9-1657827155117
2022-07-14 21:35:18.909 11675-11675/com.nt4f04und.sweyer W/t4f04und.sweyer: type=1400 audit(0.0:744): avc: denied { read } for name="max_map_count" dev="proc" ino=440824 scontext=u:r:untrusted_app:s0:c181,c256,c512,c768 tcontext=u:object_r:proc_max_map_count:s0 tclass=file permissive=0 app=com.nt4f04und.sweyer
2022-07-14 21:35:18.952 11675-11675/com.nt4f04und.sweyer D/libEGL: loaded /vendor/lib/egl/libEGL_emulation.so
2022-07-14 21:35:18.961 11675-11675/com.nt4f04und.sweyer D/libEGL: loaded /vendor/lib/egl/libGLESv1_CM_emulation.so
2022-07-14 21:35:18.973 11675-11675/com.nt4f04und.sweyer D/libEGL: loaded /vendor/lib/egl/libGLESv2_emulation.so
2022-07-14 21:35:19.020 11675-11675/com.nt4f04und.sweyer D/HostConnection: HostConnection::get() New Host Connection established 0xf4f70de0, tid 11675
2022-07-14 21:35:19.032 11675-11675/com.nt4f04und.sweyer D/HostConnection: HostComposition ext ANDROID_EMU_CHECKSUM_HELPER_v1 ANDROID_EMU_native_sync_v2 ANDROID_EMU_native_sync_v3 ANDROID_EMU_native_sync_v4 ANDROID_EMU_dma_v1 ANDROID_EMU_direct_mem ANDROID_EMU_host_composition_v1 ANDROID_EMU_host_composition_v2 ANDROID_EMU_vulkan ANDROID_EMU_deferred_vulkan_commands ANDROID_EMU_vulkan_null_optional_strings ANDROID_EMU_vulkan_create_resources_with_requirements ANDROID_EMU_YUV_Cache ANDROID_EMU_vulkan_ignored_handles ANDROID_EMU_has_shared_slots_host_memory_allocator ANDROID_EMU_vulkan_free_memory_sync ANDROID_EMU_vulkan_shader_float16_int8 ANDROID_EMU_vulkan_async_queue_submit ANDROID_EMU_sync_buffer_data ANDROID_EMU_read_color_buffer_dma GL_OES_vertex_array_object GL_KHR_texture_compression_astc_ldr ANDROID_EMU_host_side_tracing ANDROID_EMU_gles_max_version_2 
2022-07-14 21:35:19.049 11675-11675/com.nt4f04und.sweyer D/EGL_emulation: eglCreateContext: 0xf4f70130: maj 2 min 0 rcv 2
2022-07-14 21:35:19.052 11675-11675/com.nt4f04und.sweyer D/EGL_emulation: eglCreateContext: 0xf4f6ff70: maj 2 min 0 rcv 2
2022-07-14 21:35:19.089 11675-11719/com.nt4f04und.sweyer D/HostConnection: HostConnection::get() New Host Connection established 0xf4f6fdb0, tid 11719
2022-07-14 21:35:19.094 11675-11719/com.nt4f04und.sweyer D/HostConnection: HostComposition ext ANDROID_EMU_CHECKSUM_HELPER_v1 ANDROID_EMU_native_sync_v2 ANDROID_EMU_native_sync_v3 ANDROID_EMU_native_sync_v4 ANDROID_EMU_dma_v1 ANDROID_EMU_direct_mem ANDROID_EMU_host_composition_v1 ANDROID_EMU_host_composition_v2 ANDROID_EMU_vulkan ANDROID_EMU_deferred_vulkan_commands ANDROID_EMU_vulkan_null_optional_strings ANDROID_EMU_vulkan_create_resources_with_requirements ANDROID_EMU_YUV_Cache ANDROID_EMU_vulkan_ignored_handles ANDROID_EMU_has_shared_slots_host_memory_allocator ANDROID_EMU_vulkan_free_memory_sync ANDROID_EMU_vulkan_shader_float16_int8 ANDROID_EMU_vulkan_async_queue_submit ANDROID_EMU_sync_buffer_data ANDROID_EMU_read_color_buffer_dma GL_OES_vertex_array_object GL_KHR_texture_compression_astc_ldr ANDROID_EMU_host_side_tracing ANDROID_EMU_gles_max_version_2 
2022-07-14 21:35:19.129 11675-11719/com.nt4f04und.sweyer D/EGL_emulation: eglMakeCurrent: 0xf4f6ff70: ver 2 0 (tinfo 0xf52bb7f0) (first time)
2022-07-14 21:35:19.152 11675-11675/com.nt4f04und.sweyer I/System.out: ### onAttachedToEngine
2022-07-14 21:35:19.154 11675-11675/com.nt4f04und.sweyer I/System.out: ### 1 client handlers
2022-07-14 21:35:19.157 11675-11675/com.nt4f04und.sweyer I/System.out: ### new AudioHandlerInterface
2022-07-14 21:35:19.157 11675-11675/com.nt4f04und.sweyer I/System.out: ### connect
2022-07-14 21:35:19.157 11675-11675/com.nt4f04und.sweyer D/MediaBrowserCompat: Connecting to a MediaBrowserService.
2022-07-14 21:35:19.157 11675-11675/com.nt4f04und.sweyer I/System.out: ### connect returned
2022-07-14 21:35:19.157 11675-11675/com.nt4f04und.sweyer I/System.out: ### onAttachedToEngine completed
2022-07-14 21:35:19.207 11675-11675/com.nt4f04und.sweyer I/System.out: flutterEngine warmed up
2022-07-14 21:35:19.229 11675-11675/com.nt4f04und.sweyer I/System.out: ### onGetRoot. isRecentRequest=false
2022-07-14 21:35:19.231 11675-11675/com.nt4f04und.sweyer I/System.out: ### onGetRoot. isRecentRequest=false
2022-07-14 21:35:19.234 11675-11675/com.nt4f04und.sweyer I/System.out: ### onConnected
2022-07-14 21:35:19.238 11675-11675/com.nt4f04und.sweyer I/System.out: ### registered mediaController callback
2022-07-14 21:35:19.241 11675-11675/com.nt4f04und.sweyer I/System.out: ### onConnected returned
2022-07-14 21:35:19.244 11675-11675/com.nt4f04und.sweyer I/System.out: ### onMediaButtonEvent: KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_MEDIA_PLAY_PAUSE, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=12675709, downTime=12675709, deviceId=-1, source=0x0, displayId=-1 }
2022-07-14 21:35:19.244 11675-11675/com.nt4f04und.sweyer I/System.out: ### listener = com.ryanheise.audioservice.AudioServicePlugin$AudioHandlerInterface@939e583
2022-07-14 21:35:19.244 11675-11675/com.nt4f04und.sweyer I/System.out: ### calling onClick
2022-07-14 21:35:19.245 11675-11675/com.nt4f04und.sweyer I/System.out: ### sending click map: {button=0}
2022-07-14 21:35:19.245 11675-11675/com.nt4f04und.sweyer I/System.out: ### called onClick
2022-07-14 21:35:19.247 11675-11675/com.nt4f04und.sweyer D/MediaBrowserCompat: Connecting to a MediaBrowserService.
2022-07-14 21:35:19.250 11675-11675/com.nt4f04und.sweyer I/System.out: ### onGetRoot. isRecentRequest=false
2022-07-14 21:35:19.255 11675-11675/com.nt4f04und.sweyer I/System.out: ### onMediaButtonEvent: KeyEvent { action=ACTION_UP, keyCode=KEYCODE_MEDIA_PLAY_PAUSE, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=12675709, downTime=12675709, deviceId=-1, source=0x0, displayId=-1 }
2022-07-14 21:35:19.255 11675-11675/com.nt4f04und.sweyer I/System.out: ### listener = com.ryanheise.audioservice.AudioServicePlugin$AudioHandlerInterface@939e583
2022-07-14 21:35:19.278 11675-11728/com.nt4f04und.sweyer I/flutter: The Dart VM service is listening on http://127.0.0.1:39901/2INEzRwrE7w=/
2022-07-14 21:35:20.747 11675-11675/com.nt4f04und.sweyer I/ExoPlayerImpl: Init 73db5cf [ExoPlayerLib/2.17.1] [generic_x86_arm, sdk_gphone_x86, Google, 30]
2022-07-14 21:35:20.800 11675-11675/com.nt4f04und.sweyer W/t4f04und.sweye: Accessing hidden method Landroid/media/AudioTrack;->getLatency()I (greylist, reflection, allowed)
2022-07-14 21:35:20.903 11675-11675/com.nt4f04und.sweyer I/TetheringManager: registerTetheringEventCallback:com.nt4f04und.sweyer
2022-07-14 21:35:21.255 11675-11744/com.nt4f04und.sweyer W/XingSeeker: XING data size mismatch: 4908360, 4908232
2022-07-14 21:35:21.324 11675-11741/com.nt4f04und.sweyer I/VideoCapabilities: Unsupported profile 4 for video/mp4v-es
2022-07-14 21:35:21.412 11675-11745/com.nt4f04und.sweyer D/CCodec: allocate(c2.android.mp3.decoder)
2022-07-14 21:35:21.415 11675-11745/com.nt4f04und.sweyer I/Codec2Client: Available Codec2 services: "software"
2022-07-14 21:35:21.426 11675-11745/com.nt4f04und.sweyer I/CCodec: Created component [c2.android.mp3.decoder]
2022-07-14 21:35:21.426 11675-11745/com.nt4f04und.sweyer D/CCodecConfig: read media type: audio/mpeg
2022-07-14 21:35:21.428 11675-11745/com.nt4f04und.sweyer D/ReflectedParamUpdater: extent() != 1 for single value type: algo.buffers.max-count.values
2022-07-14 21:35:21.428 11675-11745/com.nt4f04und.sweyer D/ReflectedParamUpdater: extent() != 1 for single value type: output.subscribed-indices.values
2022-07-14 21:35:21.429 11675-11745/com.nt4f04und.sweyer D/ReflectedParamUpdater: extent() != 1 for single value type: input.buffers.allocator-ids.values
2022-07-14 21:35:21.429 11675-11745/com.nt4f04und.sweyer D/ReflectedParamUpdater: extent() != 1 for single value type: output.buffers.allocator-ids.values
2022-07-14 21:35:21.429 11675-11745/com.nt4f04und.sweyer D/ReflectedParamUpdater: extent() != 1 for single value type: algo.buffers.allocator-ids.values
2022-07-14 21:35:21.429 11675-11745/com.nt4f04und.sweyer D/ReflectedParamUpdater: extent() != 1 for single value type: output.buffers.pool-ids.values
2022-07-14 21:35:21.429 11675-11745/com.nt4f04und.sweyer D/ReflectedParamUpdater: extent() != 1 for single value type: algo.buffers.pool-ids.values
2022-07-14 21:35:21.432 11675-11745/com.nt4f04und.sweyer I/CCodecConfig: query failed after returning 7 values (BAD_INDEX)
2022-07-14 21:35:21.433 11675-11745/com.nt4f04und.sweyer D/CCodecConfig: c2 config diff is Dict {
      c2::u32 coded.bitrate.value = 64000
      c2::u32 input.buffers.max-size.value = 8192
      c2::u32 input.delay.value = 0
      string input.media-type.value = "audio/mpeg"
      string output.media-type.value = "audio/raw"
      c2::u32 raw.channel-count.value = 2
      c2::u32 raw.sample-rate.value = 44100
    }
2022-07-14 21:35:21.437 11675-11745/com.nt4f04und.sweyer D/CCodec: [c2.android.mp3.decoder] buffers are bound to CCodec for this session
2022-07-14 21:35:21.437 11675-11745/com.nt4f04und.sweyer D/CCodecConfig: no c2 equivalents for flags
2022-07-14 21:35:21.438 11675-11745/com.nt4f04und.sweyer D/CCodecConfig: config failed => CORRUPTED
2022-07-14 21:35:21.438 11675-11745/com.nt4f04und.sweyer W/Codec2Client: query -- param skipped: index = 1107298332.
2022-07-14 21:35:21.438 11675-11745/com.nt4f04und.sweyer D/CCodec: client requested max input size 4096, which is smaller than what component recommended (8192); overriding with component recommendation.
2022-07-14 21:35:21.438 11675-11745/com.nt4f04und.sweyer W/CCodec: This behavior is subject to change. It is recommended that app developers double check whether the requested max input size is in reasonable range.
2022-07-14 21:35:21.438 11675-11745/com.nt4f04und.sweyer D/CCodec: setup formats input: AMessage(what = 0x00000000) = {
      int32_t channel-count = 2
      int32_t max-input-size = 8192
      string mime = "audio/mpeg"
      int32_t sample-rate = 44100
    } and output: AMessage(what = 0x00000000) = {
      int32_t channel-count = 2
      string mime = "audio/raw"
      int32_t sample-rate = 44100
    }
2022-07-14 21:35:21.440 11675-11745/com.nt4f04und.sweyer W/Codec2Client: query -- param skipped: index = 1342179345.
2022-07-14 21:35:21.440 11675-11745/com.nt4f04und.sweyer W/Codec2Client: query -- param skipped: index = 2415921170.
2022-07-14 21:35:21.447 11675-11745/com.nt4f04und.sweyer E/FMQ: grantorIdx must be less than 3
2022-07-14 21:35:21.448 11675-11745/com.nt4f04und.sweyer E/FMQ: grantorIdx must be less than 3
2022-07-14 21:35:21.448 11675-11745/com.nt4f04und.sweyer D/CCodecBufferChannel: [c2.android.mp3.decoder#82] Created input block pool with allocatorID 16 => poolID 17 - OK (0)
2022-07-14 21:35:21.449 11675-11745/com.nt4f04und.sweyer I/CCodecBufferChannel: [c2.android.mp3.decoder#82] Created output block pool with allocatorID 16 => poolID 37 - OK
2022-07-14 21:35:21.449 11675-11745/com.nt4f04und.sweyer D/CCodecBufferChannel: [c2.android.mp3.decoder#82] Configured output block pool ids 37 => OK
2022-07-14 21:35:21.450 11675-11745/com.nt4f04und.sweyer E/ion: ioctl c0044901 failed with code -1: Inappropriate ioctl for device
2022-07-14 21:35:21.460 11675-11745/com.nt4f04und.sweyer E/FMQ: grantorIdx must be less than 3
2022-07-14 21:35:21.466 11675-11749/com.nt4f04und.sweyer E/FMQ: grantorIdx must be less than 3
2022-07-14 21:35:21.539 11675-11717/com.nt4f04und.sweyer I/flutter: ### AudioService.init
2022-07-14 21:35:21.590 11675-11675/com.nt4f04und.sweyer I/System.out: ### ClientInterface message: configure
2022-07-14 21:35:21.678 11675-11717/com.nt4f04und.sweyer I/flutter: ### received click: {button: 0}
2022-07-14 21:35:21.678 11675-11717/com.nt4f04und.sweyer I/flutter: button value is "0"
2022-07-14 21:35:21.678 11675-11717/com.nt4f04und.sweyer I/flutter: type: int
2022-07-14 21:35:21.680 11675-11717/com.nt4f04und.sweyer I/flutter: ### calling handler.click(MediaButton.media)
2022-07-14 21:35:21.686 11675-11675/com.nt4f04und.sweyer I/System.out: ### AudioHandlerInterface message: setQueue
2022-07-14 21:35:21.689 670-670/? V/AvrcpMediaPlayerWrapper: onQueueChanged(): com.nt4f04und.sweyer tried to update with no queue
2022-07-14 21:35:21.703 11675-11675/com.nt4f04und.sweyer I/System.out: ### AudioHandlerInterface message: setState
2022-07-14 21:35:21.705 670-670/? V/AvrcpMediaPlayerWrapper: onPlaybackStateChanged(): com.nt4f04und.sweyer : PlaybackState {state=0, position=0, buffered position=0, speed=1.0, updated=12679108, actions=512, custom actions=[], active item id=-1, error=null}
2022-07-14 21:35:21.707 11675-11745/com.nt4f04und.sweyer I/CCodecConfig: query failed after returning 7 values (BAD_INDEX)
2022-07-14 21:35:21.708 11675-11745/com.nt4f04und.sweyer W/Codec2Client: query -- param skipped: index = 1342179345.
2022-07-14 21:35:21.708 11675-11745/com.nt4f04und.sweyer W/Codec2Client: query -- param skipped: index = 2415921170.
2022-07-14 21:35:21.709 11675-11745/com.nt4f04und.sweyer D/CCodecBuffers: [c2.android.mp3.decoder#82:Output[N]] popFromStashAndRegister: output format changed to AMessage(what = 0x00000000) = {
      int32_t channel-count = 2
      string mime = "audio/raw"
      int32_t sample-rate = 44100
    }
2022-07-14 21:35:21.717 11675-11675/com.nt4f04und.sweyer I/System.out: ### AudioHandlerInterface message: setState
2022-07-14 21:35:21.727 11675-11717/com.nt4f04und.sweyer I/flutter: ### called callbacks.click
2022-07-14 21:35:21.737 670-670/? V/AvrcpMediaPlayerWrapper: onPlaybackStateChanged(): com.nt4f04und.sweyer : PlaybackState {state=2, position=35000, buffered position=6321, speed=1.0, updated=12679147, actions=15064959, custom actions=[], active item id=0, error=null}
2022-07-14 21:35:21.740 11675-11675/com.nt4f04und.sweyer I/System.out: ### AudioHandlerInterface message: setMediaItem
2022-07-14 21:35:21.745 11675-11675/com.nt4f04und.sweyer I/System.out: ### AudioHandlerInterface message: setState
2022-07-14 21:35:21.755 670-670/? V/AvrcpMediaPlayerWrapper: onPlaybackStateChanged(): com.nt4f04und.sweyer : PlaybackState {state=2, position=35000, buffered position=6321, speed=1.0, updated=12679149, actions=15064959, custom actions=[], active item id=0, error=null}
2022-07-14 21:35:21.756 11675-11675/com.nt4f04und.sweyer I/System.out: ### AudioHandlerInterface message: setState
2022-07-14 21:35:21.762 670-670/? V/AvrcpMediaPlayerWrapper: onPlaybackStateChanged(): com.nt4f04und.sweyer : PlaybackState {state=2, position=35000, buffered position=6321, speed=1.0, updated=12679152, actions=15064959, custom actions=[], active item id=0, error=null}
2022-07-14 21:35:21.764 11675-11675/com.nt4f04und.sweyer I/System.out: ### AudioHandlerInterface message: setState
2022-07-14 21:35:21.772 670-670/? V/AvrcpMediaPlayerWrapper: onPlaybackStateChanged(): com.nt4f04und.sweyer : PlaybackState {state=2, position=35000, buffered position=6321, speed=1.0, updated=12679203, actions=15064959, custom actions=[], active item id=0, error=null}
2022-07-14 21:35:21.776 11675-11752/com.nt4f04und.sweyer E/MediaMetadataRetrieverJNI: getEmbeddedPicture: Call to getEmbeddedPicture failed.
2022-07-14 21:35:23.918 670-670/? E/AvrcpMediaPlayerWrapper: Timeout while waiting for metadata to sync for com.nt4f04und.sweyer
2022-07-14 21:35:23.934 670-670/? V/AvrcpMediaPlayerWrapper: trySendMediaUpdate(): Metadata has been updated for com.nt4f04und.sweyer
2022-07-14 21:35:26.037 11675-11675/com.nt4f04und.sweyer I/System.out: ### AudioHandlerInterface message: setState
2022-07-14 21:35:26.043 670-670/? V/AvrcpMediaPlayerWrapper: onPlaybackStateChanged(): com.nt4f04und.sweyer : PlaybackState {state=3, position=35001, buffered position=74004, speed=1.0, updated=12683518, actions=15064959, custom actions=[], active item id=0, error=null}
2022-07-14 21:35:26.044 535-583/? W/ActivityManager: Background start not allowed: service Intent { cmp=com.nt4f04und.sweyer/com.ryanheise.audioservice.AudioService } to com.nt4f04und.sweyer/com.ryanheise.audioservice.AudioService from pid=11675 uid=10181 pkg=com.nt4f04und.sweyer startFg?=false
2022-07-14 21:35:26.045 11675-11675/com.nt4f04und.sweyer E/MethodChannel#com.ryanheise.audio_service.handler.methods: Failed to handle method call
    java.lang.IllegalStateException: Not allowed to start service Intent { cmp=com.nt4f04und.sweyer/com.ryanheise.audioservice.AudioService }: app is in background uid UidRecord{b350441 u0a181 CEM  idle change:cached procs:1 seq(0,0,0)}
        at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1715)
        at android.app.ContextImpl.startService(ContextImpl.java:1670)
        at android.content.ContextWrapper.startService(ContextWrapper.java:720)
        at com.ryanheise.audioservice.AudioService.enterPlayingState(AudioService.java:646)
        at com.ryanheise.audioservice.AudioService.setState(AudioService.java:516)
        at com.ryanheise.audioservice.AudioServicePlugin$AudioHandlerInterface.onMethodCall(AudioServicePlugin.java:864)
        at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:262)
        at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:295)
        at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$io-flutter-embedding-engine-dart-DartMessenger(DartMessenger.java:319)
        at io.flutter.embedding.engine.dart.DartMessenger$$ExternalSyntheticLambda0.run(Unknown Source:12)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
2022-07-14 21:35:26.085 11675-11717/com.nt4f04und.sweyer I/flutter: ----------------FIREBASE CRASHLYTICS----------------
2022-07-14 21:35:26.086 11675-11717/com.nt4f04und.sweyer I/flutter: PlatformException(error, Not allowed to start service Intent { cmp=com.nt4f04und.sweyer/com.ryanheise.audioservice.AudioService }: app is in background uid UidRecord{b350441 u0a181 CEM  idle change:cached procs:1 seq(0,0,0)}, null, java.lang.IllegalStateException: Not allowed to start service Intent { cmp=com.nt4f04und.sweyer/com.ryanheise.audioservice.AudioService }: app is in background uid UidRecord{b350441 u0a181 CEM  idle change:cached procs:1 seq(0,0,0)}
        at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1715)
        at android.app.ContextImpl.startService(ContextImpl.java:1670)
        at android.content.ContextWrapper.startService(ContextWrapper.java:720)
        at com.ryanheise.audioservice.AudioService.enterPlayingState(AudioService.java:646)
        at com.ryanheise.audioservice.AudioService.setState(AudioService.java:516)
        at com.ryanheise.audioservice.AudioServicePlugin$AudioHandlerInterface.onMethodCall(AudioServicePlugin.java:864)
    	at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessa
2022-07-14 21:35:26.086 11675-11717/com.nt4f04und.sweyer I/flutter: #0      StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:607:7)
    #1      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:167:18)
    <asynchronous suspension>
    #2      MethodChannelAudioService.setState (package:audio_service_platform_interface/method_channel_audio_service.dart:19:5)
    <asynchronous suspension>
    #3      AudioService.init.<anonymous closure> (package:audio_service/audio_service.dart:958:7)
    <asynchronous suspension>
2022-07-14 21:35:26.086 11675-11717/com.nt4f04und.sweyer I/flutter: ----------------------------------------------------
2022-07-14 21:35:26.106 535-583/? I/MediaFocusControl: requestAudioFocus() from uid/pid 10181/11675 [email protected]_session.AndroidAudioManager$Singleton$$ExternalSyntheticLambda0@7be14f9 callingPack=com.nt4f04und.sweyer req=1 flags=0x0 sdk=30
2022-07-14 21:35:26.263 11675-11741/com.nt4f04und.sweyer D/AudioTrack: getTimestamp_l(37): device stall time corrected using current time 12683761201800
2022-07-14 21:35:26.568 11675-11748/com.nt4f04und.sweyer D/BufferPoolAccessor2.0: bufferpool2 0xf4cc7838 : 5(40960 size) total buffers - 4(32768 size) used buffers - 0/5 (recycle/alloc) - 13/112 (fetch/transfer)
2022-07-14 21:35:26.568 11675-11748/com.nt4f04und.sweyer D/BufferPoolAccessor2.0: evictor expired: 1, evicted: 1
2022-07-14 21:35:27.048 11675-11675/com.nt4f04und.sweyer I/System.out: ### AudioHandlerInterface message: setState
2022-07-14 21:35:27.053 670-670/? V/AvrcpMediaPlayerWrapper: onPlaybackStateChanged(): com.nt4f04und.sweyer : PlaybackState {state=3, position=40336, buffered position=110811, speed=1.0, updated=12684541, actions=15064959, custom actions=[], active item id=0, error=null}
2022-07-14 21:35:28.080 11675-11675/com.nt4f04und.sweyer I/System.out: ### AudioHandlerInterface message: setState
2022-07-14 21:35:28.086 670-670/? V/AvrcpMediaPlayerWrapper: onPlaybackStateChanged(): com.nt4f04und.sweyer : PlaybackState {state=3, position=41373, buffered position=110811, speed=1.0, updated=12685578, actions=15064959, custom actions=[], active item id=0, error=null}
2022-07-14 21:35:29.268 11675-11675/com.nt4f04und.sweyer I/System.out: ### AudioHandlerInterface message: setState
2022-07-14 21:35:29.274 670-670/? V/AvrcpMediaPlayerWrapper: onPlaybackStateChanged(): com.nt4f04und.sweyer : PlaybackState {state=3, position=42559, buffered position=110811, speed=1.0, updated=12686765, actions=15064959, custom actions=[], active item id=0, error=null}
2022-07-14 21:35:30.446 11675-11675/com.nt4f04und.sweyer I/System.out: ### AudioHandlerInterface message: setState
2022-07-14 21:35:30.451 670-670/? V/AvrcpMediaPlayerWrapper: onPlaybackStateChanged(): com.nt4f04und.sweyer : PlaybackState {state=3, position=43738, buffered position=110811, speed=1.0, updated=12687943, actions=15064959, custom actions=[], active item id=0, error=null}
2022-07-14 21:35:31.481 11675-11675/com.nt4f04und.sweyer I/System.out: ### AudioHandlerInterface message: setState
2022-07-14 21:35:31.484 670-670/? V/AvrcpMediaPlayerWrapper: onPlaybackStateChanged(): com.nt4f04und.sweyer : PlaybackState {state=3, position=44773, buffered position=110811, speed=1.0, updated=12688978, actions=15064959, custom actions=[], active item id=0, error=null}
2022-07-14 21:35:31.814 11675-11745/com.nt4f04und.sweyer D/BufferPoolAccessor2.0: bufferpool2 0xf4cc7838 : 4(32768 size) total buffers - 4(32768 size) used buffers - 0/5 (recycle/alloc) - 13/809 (fetch/transfer)
2022-07-14 21:35:32.681 11675-11675/com.nt4f04und.sweyer I/System.out: ### AudioHandlerInterface message: setState
2022-07-14 21:35:32.685 670-670/? V/AvrcpMediaPlayerWrapper: onPlaybackStateChanged(): com.nt4f04und.sweyer : PlaybackState {state=3, position=45973, buffered position=110811, speed=1.0, updated=12690178, actions=15064959, custom actions=[], active item id=0, error=null}

Remaining issues

  • [ ] After starting the app from the AudioService and then launching the app from the launcher, the Tracks list is initially empty and only fills when switching to other tabs and back.
  • [ ] When starting from the background, the audio service is not showing a media session notification. This is probably related to this IllegalStateException:
    Stacktrace
     java.lang.IllegalStateException: Not allowed to start service Intent { cmp=com.nt4f04und.sweyer/com.ryanheise.audioservice.AudioService }: app is in background uid UidRecord{b350441 u0a181 CEM  idle change:cached procs:1 seq(0,0,0)}
            at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1715)
            at android.app.ContextImpl.startService(ContextImpl.java:1670)
            at android.content.ContextWrapper.startService(ContextWrapper.java:720)
            at com.ryanheise.audioservice.AudioService.enterPlayingState(AudioService.java:646)
            at com.ryanheise.audioservice.AudioService.setState(AudioService.java:516)
            at com.ryanheise.audioservice.AudioServicePlugin$AudioHandlerInterface.onMethodCall(AudioServicePlugin.java:864)
            at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:262)
            at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:295)
            at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$io-flutter-embedding-engine-dart-DartMessenger(DartMessenger.java:319)
            at io.flutter.embedding.engine.dart.DartMessenger$$ExternalSyntheticLambda0.run(Unknown Source:12)
            at android.os.Handler.handleCallback(Handler.java:938)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:223)
            at android.app.ActivityThread.main(ActivityThread.java:7656)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
    

Some thoughts

  • A positive side effect of this is that it might make it easier when we want to support other platforms. The sweyer_plugin could act as a common interface to the platform specific stuff of each platform.
  • I think it might be good to move all fields of Song which are directly filled from the media store to the MediaStoreSong, and similarly for the other MediaStore classes. I didn't want to do it in this PR though, because it is already so large.

Abestanis avatar Jul 14 '22 20:07 Abestanis

The changes in the goldens are actually fixes to our tests. Previously the Song instances returned by the FakeContentChannel had an origin set, but this was not realistic, because the origin is never set for songs coming from the media store (e.g. origin is never specified in Song.fromMap). See also f63444fc807f424c2ead428372f67baeec92de55.

Abestanis avatar Jul 14 '22 20:07 Abestanis

There are two fundamental problems with this PR:

  1. It unnecessarily converts Java's code to Kotlin's while also moving it to a different location, which makes it very hard to review the actual changes. If you want to convert Java to Kotlin (which is also an arguable investment of my and your time but OK), please make it in a separate pull request.
  2. For some reason it uses a federated plugin structure. I don't see how this is justified, since the only reason it exists is to enable plugin athors to delegate implementation of a certain platforms for plugins to 3d parties, as well as allowing multiple implementations of those platforms. In our case it doesn't bring any benefit, while enables a lot of unncessary boilerplate.

nt4f04uNd avatar Jul 14 '22 23:07 nt4f04uNd