New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MediaLibraryService throws ForegroundServiceDidNotStartInTimeException #167
Comments
I've also seen this in Crashlytics, although I'm myself have been unable to reproduce this. |
Thanks for reporting! Do you have some more context what command has been sent to the service when this happens? I'm asking because I probably have found an execution path that could cause this problem, but I can not repro this and hence I can not verify a fix. I think the reason for this could be that the pending intent of 'pause' is starting a foreground service and then does not call I will provide a fix for the case described above. However, I can't be really sure whether this is the root case of the exception above because I can't repro now. I think it may be a corner case that sends the You have already reported that this happens on Android 12. Can you let me know the |
So in my case, I have both target & compile SDK set to 33. Full stacktrace:
|
@marcbaechinger This crash is reported a lot |
***** EDIT ***** Hi, I reproduce the crash with media session demo app
|
Thanks for digging some further. That give me some further data points.
Yes, indeed, these cases are always about closing the app and having only the service playing in the background. As soon as your app is in the foreground with a controller connected you are bound to the service, and you will never see such an exception.
With the default behaviour of the I still think it's the |
Hi @marcbaechinger, |
This should be fixed with this commit. Please re-open if you think you still see this issue with this commit. |
I'm still a little bit concerned it's not a complete fix.
Seems racy, the pending intent in the notification can be clicked on after something else has just toggled this. Also do you have a test for playback stopped by suppression? I assume this will work because it's temporary and the session is still active? |
This comment was marked as off-topic.
This comment was marked as off-topic.
@yschimke This issue is about a By design, the service is started by creating a controller/browser and binding to the service. The service shouldn't be started by a pending intent (not For this reason, I agree that this is about a race condition or an invalid state but elsewhere (stale notification?). I couldn't repro, because I do not understand from where a pending intent for I agree that I'm not sure that this fixes the problem, but I think it removes the If you have any way to repro this |
Thanks for clarifying. |
A follow up to stopping speaker playback with a Player decorator from #15. It looks like we will need to change to using playback suppression to avoid errors like #167, when we don't start a foreground service. We may not have this implemented by 1.0, but would like it in the API and it seems to be appropriate. PiperOrigin-RevId: 478835686
A follow up to stopping speaker playback with a Player decorator from androidx/media#15. It looks like we will need to change to using playback suppression to avoid errors like androidx/media#167, when we don't start a foreground service. We may not have this implemented by 1.0, but would like it in the API and it seems to be appropriate. PiperOrigin-RevId: 478835686
When can we expect a new release of the media3 library? |
We have many reports in Crashlytics of users facing this issue, however I believe it's not causing crashes (although they get reported as one), as I can see in our database that the users who face the crash can listen to the app audios and complete the full playback. We have not been able to reproduce it ourselves so far. Another annoying thing is that we get different reports in Crashlytics that are not getting grouped as the same issue, and it's spamming us with many different issues that are essentially the same. Android 12 examples:
Different report, same issue:
Another:
And many more. Android 11 example:
We have around 15 different reports of this same issue with slightly different line numbers throwing the error in the last 7 days. Do you have any insights or recommendations on what to do? |
@marcbaechinger thanks for replay. Prev onPlaybackResumption() implementation was for testing ( just to see my log). Now i'm trying to implementend like you said. without "Thread.sleep(2000)" (which is not ok to put) betweend loadup (my data from data store preff) and return in onPlaybackResumption() i can not ensure that the media item i need to return will have valid data Do you have any other solution? LE : Also now i notice if i open app, play, wait for sound, pause and then dismiss app i can start only form headphones. If i tap "play" on notification nothing happens : no service restart, no onPlaybackResumption(), no sound |
I'm not sure I understand what the problem is I'm afraid. In case you mean that you need to load the data asynchronously to return it in
If you can repro this with the session demo app, please file another issue with reproduction steps and a bug report attached. It would be unrelated to this issue. |
Thanks for your report! The Media3 Automotive Demo app works well for me with the new emulator running Android 33. I can start playback after installing. I see an issue when I install the app again from Android Studio. In such a case the UI of the emulator doesn't seems to be happy. The service can be started though and I can't see the exception you are reporting. If you can repro this with the Automotive Demo app, please provide us with some repro steps so we can look into this. |
Hello, thank you for your quick answer.
Can you please explain why you override this exception and why you create a notification inside? FYI: Thank you! |
Thanks for confirming. Looks like an app issue rather than a problem in the library.
You don't have to call From what you report I think that playback fails somehow when it should start playing. I would start investigating what calls you get from Automotive and then how these calls are execueyd by your service. I would expect Automotive calls Callback methods like You need what your app does differently than the demo app. I suggest to add an
I don't think this is relevant in the case you are looking into. This is overridden for a bug in Android 12, where a media controller that calls play when being in the background misses the exemption to start the service. The notification allows the user to continue manually in such a case. Please note that this issue is about |
Hi! Please help to solve this problem! ......
|
For background on the issue, and why this change may help, see androidx/media#890. I had hoped that upgrading the Media3 library version back in #92 would completely solve the problems we had been seeing in production. While it did help in some ways, by eliminating `ForegroundServiceDidNotStartInTimeException`s (see androidx/media#167), it also seems to have morphed a lot of problems into a new form, namely App Not Responding (ANR) problems that arise in `MiniPlayerFragment`. The basic idea here is to reduce the rate at which we create and release `MediaController`s in `MiniPlayerFragment`, by moving the creation and releasing to fragment lifecycle callbacks that are invoked less frequently than `onResume()` and `onPause()`. My hypothesis is that rapid creation and releasing of `MediaController`s results in some kind of race condition that is very hard to reproduce locally but will occur in production with enough use of the app. It's not completely clear that this PR will definitely solve the problems we're seeing in production, but it seems like a worthwhile experiment to try. Other than potentially decreasing the rate of ANRs, it should not have any other noticeable effects on the behavior of the app.
Hello guys! Any updates on how to resolve this issue? |
As a summary from the comments above you would need to figure out what or who is trying to attempt to start the service based on which signal that Media3 or your app is giving. There are many reasons why this can go wrong, including Media3 bugs that have been removed as tracked in this issue. Assuming you are using the most recent release version of the library, it's difficult to tell without further information. Most advice I can give can possibly and alternatively be found in comments above. Seeing that one crash in your stats above is happening for different vendors, makes me think something may be wrong on the app side for some edge cases. General, library things on would generate more reports I think. A questionary would probably start somewhere in asking whether your app does declare the If yes: do you have If no: Do you see crashes of your service that somehow leak a media button receiver configuration when the session isn't properly released? As in |
@marcbaechinger what is the proper thing to do if implementing Callback.onPlaybackResumption if we don't have the data to populate the playlist? (Note, that's a rare case, but it can happen, an example would be most recently played item was deleted). |
I was seeing crashes, now they are very rare. My issue was that I was implementing Callback.onPlaybackResumption, but had a bug that caused it to not reliably save the most recently played time. After I fix that, I still see a ForegroundServiceDidNotStartInTimeException occasionally, but it's really quite rare now. |
If your app is not using the receiver, then Media3 is not registering a MBR when the app is closed. So it is unclear why someone or something (System/app) attempts to restart your app this way. Similar to other cases from above, it would be important to know how and why a user on the affected devices tries to restart the app despite the app not registering itself for this. The fix you are mentioning has removed a problem on Samsung devices as described in this comment. If we find, how users attempt to start the app on these devices we are a step closer to remove this entirely. We haven't found this yet I'm afraid and it seems that our users don't see that either. My attempts to contact Samsung were unsuccessful I'm afraid. Happy to fix this if we get to the ground of this device-specific problem.
This probably can help to remove the symptom of crashes. The source of the problem on these devices is still unclear. |
I am facing a similar new crash
All the mentioned suggestions from Marc's comment 1705708010: #167 (comment) are already implemented. I think it might be related with the fact that I don't always have something valid to playback (for example, the user has logged out in the meantime), consulted with Marc here: #770. So currently, when I have nothing valid to return, I return: override fun onPlaybackResumption(
mediaSession: MediaSession,
controller: MediaSession.ControllerInfo,
): ListenableFuture<MediaSession.MediaItemsWithStartPosition> {
try {
val playbackResumptionData = getPlaybackResumptionData()
if (playbackResumptionData == null) {
return Futures.immediateFuture(MediaSession.MediaItemsWithStartPosition(emptyList(), 0, 0))
}
...
} catch (e: Exception) {
Timber.d(e)
return Futures.immediateFuture(MediaSession.MediaItemsWithStartPosition(emptyList(), 0, 0))
}
} @marcbaechinger Can |
Yesterday I update to gradle 8.4 and the matching Android Gradle Plugin. I pushed an otherwise small change. Something with the new gradle/plugin and Futures.immediateFuture went completely south and app was completely unusable. Reverting the gradle changes fixed the issue. But Android Studio is nagging to update them. Not sure if its media3 issue with gradle issue, but the crash was decidedly in the media3, but definitely due the gradle update. @TomasValenta are you Gradle 8.4? |
@johngray1965 Please can you file a separate issue about your Gradle 8.4 upgrade issue with repro steps? e.g. are you depending on media3 via maven dependencies or using local source code? |
It appears that when the MediaLibraryService is started, it retains the application context, preventing the application from being killed (when removed from resents). So, the next time the app is started, the application is not recreated. |
Hi, our app is also producing this error on Samsung devices Android 11. We can reproduce the issue by following #167 (comment) on the device setting and do the following steps:
We only use
Is it normal for |
@GilangJS Thanks for reporting. The intent you are seeing on Android 11 with your repro steps above is coming from the notification that Media3 posts. It's the In case you haven't customized the |
I think the official docs on Playback Resumption are somewhat lacking. I found it hard to understand what was required to have playback resumption on my app, and only fully grasped that The bit where pressing play on my BT headset triggers a Foreground Notification, but media3 will only call Additionally the sentence in the docs that says:
Is a bit of an understatement, as failing to provide a workable playlist within 5 seconds will result in the dreaded I would suggest to make this a bit clearer in the docs, which probably would have prevented a good bunch of the comments in this thread :) |
@marcbaechinger I do have an additional question (not sure its been asked). Our media content needs authentication to be played, how are clients expected to handle the scenario in which the user exits the app (i.e. swipes) after a logout operation, and media resumption happens? If we cant return an empty playlist or UnsupportedOperation in the |
@kelmer44 Look at my question here 2 weeks ago with no answer yet and #770. |
I do think this functionality should be built in because this is a legitimate use case, but in the meantime I've done it like so:
Then of course you need to declare this receiver instead of MediaButtonReceiver. Hope that helps. |
@kelmer44 Thanks for you input.
I'm sorry for the inconvenience caused. Given that the two steps of adding the MBR and overriding the callback is documented on the page you linked, the uncertainties come from the fact that the app needs to return a non-empty list. I will amend our documentation to make this clear on DAC as well.
This is a known weak point of the implementation. To solve this Media3 needs two changes I think: 1 - separate BT resumption and System UI notification resumption. This is required because in the case of the System UI notification, there is no API that we can use to opt-out of the notification once we have opted-in. Media3 can't do something here as the system doesn't offer such an API. Given the inability of opting-out once opted-in, you use case of a user that logs out can't really be implemented yet. The separation would give you the option to only use BT resumption without the notification resumption. 2 - Media3 needs to add a API that allows an app to opt-in and out of playback resumption at runtime. Currently this decision is based on the static inclusion of the With 1) and 2) in place, the answer to your question would be you can opt-out from SysUI notification and then use the runtime API to opt-out from BT resumption when the user logs out. See #770 also. |
@marcbaechinger looks like we posted at the same time :) can you check my solution in the comment above |
Yeah, this looks like a legitimate work around an app can try when it knows that there are no items that are returned from I think though this doesn't help for the System UI notification which would still show and try to start service and playback? So from a library perspective we would need a runtime approach as described in #770. |
Media3 Version
1.0.0-beta02
Devices that reproduce the issue
Firebase crashlytics report these devices:
Devices that do not reproduce the issue
No response
Reproducible in the demo app?
Not tested
Reproduction steps
It's happened on some devices. I think It has related to MediaController not properly handling the service.
Expected result
not crash?
Actual result
Media
Bug Report
adb bugreport
to dev.exoplayer@gmail.com after filing this issue.The text was updated successfully, but these errors were encountered: