diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 5f6ca3d991..355582e366 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -67,6 +67,8 @@ service is stopped from the foreground and a notification with a play button is shown to restart playback of the last media item ([#112](https://github.com/androidx/media/issues/112)). + * Don't start a foreground service with a pending intent for pause + ([#167](https://github.com/androidx/media/issues/167)). * RTSP: * Add H263 fragmented packet handling ([#119](https://github.com/androidx/media/pull/119)). diff --git a/libraries/session/src/main/java/androidx/media3/session/DefaultActionFactory.java b/libraries/session/src/main/java/androidx/media3/session/DefaultActionFactory.java index 699f9cb991..ed65296b88 100644 --- a/libraries/session/src/main/java/androidx/media3/session/DefaultActionFactory.java +++ b/libraries/session/src/main/java/androidx/media3/session/DefaultActionFactory.java @@ -105,7 +105,9 @@ import androidx.media3.common.util.Util; intent.setData(mediaSession.getImpl().getUri()); intent.setComponent(new ComponentName(service, service.getClass())); intent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, keyCode)); - if (Util.SDK_INT >= 26 && command == COMMAND_PLAY_PAUSE) { + if (Util.SDK_INT >= 26 + && command == COMMAND_PLAY_PAUSE + && !mediaSession.getPlayer().getPlayWhenReady()) { return Api26.createForegroundServicePendingIntent(service, keyCode, intent); } else { return PendingIntent.getService( diff --git a/libraries/session/src/test/java/androidx/media3/session/DefaultActionFactoryTest.java b/libraries/session/src/test/java/androidx/media3/session/DefaultActionFactoryTest.java index 73c68ce21f..d83ad4d74b 100644 --- a/libraries/session/src/test/java/androidx/media3/session/DefaultActionFactoryTest.java +++ b/libraries/session/src/test/java/androidx/media3/session/DefaultActionFactoryTest.java @@ -42,18 +42,61 @@ public class DefaultActionFactoryTest { public void createMediaPendingIntent_intentIsMediaAction() { DefaultActionFactory actionFactory = new DefaultActionFactory(Robolectric.setupService(TestService.class)); - MediaSession mockMediaSession = mock(MediaSession.class); - MediaSessionImpl mockMediaSessionImpl = mock(MediaSessionImpl.class); - when(mockMediaSession.getImpl()).thenReturn(mockMediaSessionImpl); Uri dataUri = Uri.parse("http://example.com"); + MediaSession mockMediaSession = mock(MediaSession.class); + Player mockPlayer = mock(Player.class); + MediaSessionImpl mockMediaSessionImpl = mock(MediaSessionImpl.class); + when(mockMediaSession.getPlayer()).thenReturn(mockPlayer); + when(mockMediaSession.getImpl()).thenReturn(mockMediaSessionImpl); when(mockMediaSessionImpl.getUri()).thenReturn(dataUri); + PendingIntent pendingIntent = + actionFactory.createMediaActionPendingIntent(mockMediaSession, Player.COMMAND_SEEK_FORWARD); + + ShadowPendingIntent shadowPendingIntent = shadowOf(pendingIntent); + assertThat(actionFactory.isMediaAction(shadowPendingIntent.getSavedIntent())).isTrue(); + assertThat(shadowPendingIntent.getSavedIntent().getData()).isEqualTo(dataUri); + } + + @Test + public void createMediaPendingIntent_commandPlayPauseWhenNotPlayWhenReady_isForegroundService() { + DefaultActionFactory actionFactory = + new DefaultActionFactory(Robolectric.setupService(TestService.class)); + Uri dataUri = Uri.parse("http://example.com"); + MediaSession mockMediaSession = mock(MediaSession.class); + Player mockPlayer = mock(Player.class); + MediaSessionImpl mockMediaSessionImpl = mock(MediaSessionImpl.class); + when(mockMediaSession.getPlayer()).thenReturn(mockPlayer); + when(mockMediaSession.getImpl()).thenReturn(mockMediaSessionImpl); + when(mockMediaSessionImpl.getUri()).thenReturn(dataUri); + when(mockPlayer.getPlayWhenReady()).thenReturn(false); + + PendingIntent pendingIntent = + actionFactory.createMediaActionPendingIntent(mockMediaSession, Player.COMMAND_PLAY_PAUSE); + + ShadowPendingIntent shadowPendingIntent = shadowOf(pendingIntent); + assertThat(shadowPendingIntent.isForegroundService()).isTrue(); + } + + @Test + public void createMediaPendingIntent_commandPlayPauseWhenPlayWhenReady_notAForegroundService() { + DefaultActionFactory actionFactory = + new DefaultActionFactory(Robolectric.setupService(TestService.class)); + Uri dataUri = Uri.parse("http://example.com"); + MediaSession mockMediaSession = mock(MediaSession.class); + Player mockPlayer = mock(Player.class); + MediaSessionImpl mockMediaSessionImpl = mock(MediaSessionImpl.class); + when(mockMediaSession.getPlayer()).thenReturn(mockPlayer); + when(mockMediaSession.getImpl()).thenReturn(mockMediaSessionImpl); + when(mockMediaSessionImpl.getUri()).thenReturn(dataUri); + when(mockPlayer.getPlayWhenReady()).thenReturn(true); + PendingIntent pendingIntent = actionFactory.createMediaActionPendingIntent(mockMediaSession, Player.COMMAND_PLAY_PAUSE); ShadowPendingIntent shadowPendingIntent = shadowOf(pendingIntent); assertThat(actionFactory.isMediaAction(shadowPendingIntent.getSavedIntent())).isTrue(); - assertThat(shadowPendingIntent.getSavedIntent().getData()).isEqualTo(dataUri); + assertThat(shadowPendingIntent.isForegroundService()).isFalse(); } @Test