Version
Media3 main branch
More version details
Bug exists at least since version 1.4.1.
Devices that reproduce the issue
Any Android 12+
Devices that do not reproduce the issue
No response
Reproducible in the demo app?
Not tested
Reproduction steps
When a Player is configured with a non-default ApplicationLooper, the ForegroundServiceStartNotAllowedException handling in MediaSessionService fails because the exception is thrown on a different thread than where the try-catch block executes.
- Create a
Player with non-default Player.getApplicplicationLooper().
- (optional) Override MediaSesssionService.onUpdateNotification with
startInForegroundRequired == true (which seems legal according to the documentation provided and library API).
- MediaSesssionService.onUpdateNotificationInternal is the only place in stack that catches the ForegroundServiceStartNotAllowedException exception. Documentation says "
Triggers notification update and handles {@code ForegroundServiceStartNotAllowedException}".
onUpdateNotificationInternal directly calls onUpdateNotification, onUpdateNotification directly calls getMediaNotificationManager().updateNotification. Calls happen on main thread according to documentation.
- In MediaNotificationManager.updateNotification there is a call to Util.postOrRun with
session.getPlayer().getApplicationLooper().
- Lambda that creates (
createNotification) and shows (updateNotificationInternal) the notification is posted to Player's Looper (which is not main thread's Looper), therefore the catch expression is no more in the needed stack and catches nothing.
Expected result
The ForegroundServiceStartNotAllowedException should be caught and passed to MediaSessionService.Listener.onForegroundServiceStartNotAllowedException() regardless of which looper the Player uses.
If main thread's Looper is used the exception is caught because both Util.postOrRun and mainExecutor (which is just a proxy to Util.postOrRun) are going through immediate OrRun branch and therefore are in the same call stack with catch.
Actual result
Fatal exception:
Exception android.app.ForegroundServiceStartNotAllowedException:
at android.app.ForegroundServiceStartNotAllowedException$1.createFromParcel (ForegroundServiceStartNotAllowedException.java:54)
at android.app.ForegroundServiceStartNotAllowedException$1.createFromParcel (ForegroundServiceStartNotAllowedException.java:50)
at android.os.Parcel.readParcelableInternal (Parcel.java:4828)
at android.os.Parcel.readParcelable (Parcel.java:4790)
at android.os.Parcel.createExceptionOrNull (Parcel.java:3018)
at android.os.Parcel.createException (Parcel.java:3007)
at android.os.Parcel.readException (Parcel.java:2990)
at android.os.Parcel.readException (Parcel.java:2932)
at android.app.IActivityManager$Stub$Proxy.startService (IActivityManager.java:5426)
at android.app.ContextImpl.startServiceCommon (ContextImpl.java:1899)
at android.app.ContextImpl.startForegroundService (ContextImpl.java:1875)
at android.content.ContextWrapper.startForegroundService (ContextWrapper.java:827)
at androidx.core.content.ContextCompat$Api26Impl.startForegroundService (ContextCompat.java:1128)
at androidx.core.content.ContextCompat.startForegroundService (ContextCompat.java:700)
at androidx.media3.session.MediaNotificationManager.startForeground (MediaNotificationManager.java:366)
at androidx.media3.session.MediaNotificationManager.updateNotificationInternal (MediaNotificationManager.java:223)
at androidx.media3.session.MediaNotificationManager.lambda$updateNotification$6 (MediaNotificationManager.java:179)
at android.os.Handler.handleCallback (Handler.java:942)
at android.os.Handler.dispatchMessage (Handler.java:99)
at android.os.Looper.loopOnce (Looper.java:201)
at android.os.Looper.loop (Looper.java:288)
at android.app.ActivityThread.main (ActivityThread.java:7962)
at java.lang.reflect.Method.invoke
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:550)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:952)
Media
Any media with media notification.
Bug Report
Version
Media3 main branch
More version details
Bug exists at least since version 1.4.1.
Devices that reproduce the issue
Any Android 12+
Devices that do not reproduce the issue
No response
Reproducible in the demo app?
Not tested
Reproduction steps
When a Player is configured with a non-default ApplicationLooper, the
ForegroundServiceStartNotAllowedExceptionhandling inMediaSessionServicefails because the exception is thrown on a different thread than where the try-catch block executes.Playerwith non-default Player.getApplicplicationLooper().startInForegroundRequired == true(which seems legal according to the documentation provided and library API).Triggers notification update and handles {@code ForegroundServiceStartNotAllowedException}".onUpdateNotificationInternaldirectly callsonUpdateNotification,onUpdateNotificationdirectly callsgetMediaNotificationManager().updateNotification. Calls happen on main thread according to documentation.session.getPlayer().getApplicationLooper().createNotification) and shows (updateNotificationInternal) the notification is posted toPlayer'sLooper(which is not main thread'sLooper), therefore thecatchexpression is no more in the needed stack and catches nothing.Expected result
The
ForegroundServiceStartNotAllowedExceptionshould be caught and passed to MediaSessionService.Listener.onForegroundServiceStartNotAllowedException() regardless of which looper the Player uses.If main thread's
Looperis used the exception is caught because bothUtil.postOrRunandmainExecutor(which is just a proxy toUtil.postOrRun) are going through immediateOrRunbranch and therefore are in the same call stack withcatch.Actual result
Fatal exception:
Media
Any media with media notification.
Bug Report
adb bugreportto android-media-github@google.com after filing this issue.