prevent Android notification spamming
Which API doesn't behave as documented, and how does it misbehave? when Android notification is under pressure from update requiest, the system might ignore these,
Minimal reproduction project i can consitently reproduce this with both example and with reproducible from https://github.com/ryanheise/audio_service/issues/654
To Reproduce (i.e. user steps, not code) just press buttons to trigger notification updates and eventually notification will ignore some and might stuck on pause button, while the playback paused, so it will be impossible to press it again
Error messages n/a
Expected behavior plugin should prevent this
- debounce notification updates at least at about 200ms - this seems to fix it
- even if system ignores the update and wrong button remains - it should not block the user and play/pause should happen dependently on playback state, not UI state
Screenshots
https://user-images.githubusercontent.com/39104740/114455688-b23b1f80-9be4-11eb-8aff-d62c5ff27143.mp4
Runtime Environment (please complete the following information if relevant): android
Flutter SDK version
flutter doctor -v
[✓] Flutter (Channel master, 2.1.0-13.0.pre.574, on Microsoft Windows [Version 10.0.19041.867], locale ru-RU)
• Flutter version 2.1.0-13.0.pre.574 at c:\dev\src\flutter
• Framework revision 02efffc134 (33 hours ago), 2021-04-10 03:49:01 -0400
• Engine revision 8863afff16
• Dart version 2.13.0 (build 2.13.0-222.0.dev)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
• Android SDK at C:\Users\danya\AppData\Local\Android\sdk
• Platform android-30, build-tools 30.0.2
• Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
• Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)
• All Android licenses accepted.
[✓] Chrome - develop for the web
• Chrome at C:\Program Files\Google\Chrome\Application\chrome.exe
[✓] Visual Studio - develop for Windows (Visual Studio Community 2019 16.7.7)
• Visual Studio at C:\Program Files (x86)\Microsoft Visual Studio\2019\Community
• Visual Studio Community 2019 version 16.7.30621.155
• Windows 10 SDK version 10.0.19041.0
[✓] Android Studio (version 4.0)
• Android Studio at C:\Program Files\Android\Android Studio
• Flutter plugin version 50.0.1
• Dart plugin version 193.7547
• Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)
[✓] IntelliJ IDEA Community Edition (version 2020.3)
• IntelliJ at C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2020.3.3
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
[✓] VS Code (version 1.55.1)
• VS Code at C:\Users\danya\AppData\Local\Programs\Microsoft VS Code
• Flutter extension version 3.21.0
[✓] Connected device (4 available)
• sdk gphone x86 (mobile) • emulator-5554 • android-x86 • Android 11 (API 30) (emulator)
• Windows (desktop) • windows • windows-x64 • Microsoft Windows [Version 10.0.19041.867]
• Chrome (web) • chrome • web-javascript • Google Chrome 89.0.4389.114
• Edge (web) • edge • web-javascript • Microsoft Edge 89.0.774.63
• No issues found!
Additional context none
I would be more inclined to let the app manage debouncing rather than the plugin. The Android APIs similarly don't stop you from doing bad things, but it is up to the app developer not to spam the notification.
how about adding this to the example app?
Actually, this may not be a bad idea for the iOS side, since I think we are running into issues if updating nowPlayingInfo too quickly in succession.
However, I might prefer throttle to debounce since (hopefully) that will be more responsive. debounce will delay the event for the window duration where as throttle will (hopefully) emit the event immediately and then delay before the next one.
Actually debounce delays the event, so it will be in race, if you pause the notification, and then the debounced event fires. I wasn't aware of throttle, it looks more suitable, hopefully it doesn't have this problem.
Also, can we evaluate the necessity of AudioProcessingState as per https://github.com/ryanheise/audio_service/issues/655 ?
I think most of the uneccessary update pressure happens from item loading state being directly casted into this (as per example), which happens really fast in short period of time
I just tried out throttleTime and it doesn't do exactly what we want either. It will emit leading events at the start of a window immediately, but it may miss trailing events. For example:
A B C D E F // before throttling
A D // after throttling
We should really have both the first and the last events. throttleTime does have an option for including both the leading and trailing event in a window, but that would give you events A C D F which is also not ideal.
What I really want is A D F and F would happen after seeing that the next window was empty. I guess I could just implement this behaviour manually.
There's a priority in events that we want to keep. For example if F is playing change event - we definitely want to have it, if it's position, or processing state event, we care less a lot. I agree throttleTime won't help with this. What we want to is to differentiate important events and the ones we can skip.