42 Commits

Author SHA1 Message Date
bachinger
84c0b6bcb1 Add MediaSession.sendError to send non-fatal error data to controllers
This allows to set custom error message for instance on Android
Auto/Automotive OS.

Issue: androidx/media#543
PiperOrigin-RevId: 633610089
2024-05-14 09:30:18 -07:00
Gaëtan Muller
973b717914 Remove unnecessary SDK_INT checks 2024-02-13 10:26:19 +00:00
bachinger
a063d137b4 Add session extras to the state of the controller
This change adds `MediaController.getSessionExtras()` through
which a controller can access the session extras.

The session extras can be set for the entire session when
building the session. This can be overridden for specific
controllers in `MediaSession.Callback.onConnect`.

PiperOrigin-RevId: 584430419
2023-11-21 14:32:33 -08:00
bachinger
f53e1bc6f6 Only set the queue when COMMAND_GET_TIMELINE is available
Android Auto shows a queue button when the queue is not empty.
Apps were able to remove this queue button with the legacy API
by not setting the queue of the session.

After this change, removing `COMMAND_GET_TIMELINE` from the commands
of the media notification controller or the session player sets the
queue in the platform session to null.

#minor-release
Issue: androidx/media#339
PiperOrigin-RevId: 573813558
2023-10-16 08:14:38 -07:00
bachinger
99086b4007 Add default implementation of Callback.onSubscribe
The library already maintains the subscribed controllers internally. This
change adds `MediaLibrarySession.getSubscribedControllers(mediaId)` to
access subscribed controllers for a given media ID.

To accept a subscription, `MediaLibraryService.Callback.onSubscribe` is
required to return `RESULT_SUCCESS`. So far, this isn't the case for the
default implementation of the library.

This change implements `Callback.onSubscribe` to conditionally
provide `RESULT_SUCCESS`. The default calls `Callback.onGetItem(mediaId)` to
assess the availability of the media item. If the app retruns `RESULT_SUCCESS`
with a browsable item, the subscription is accepted. If receiving a valid item
fails, the subscription is rejected.

Issue: androidx/media#561
PiperOrigin-RevId: 568925079
2023-09-27 12:19:34 -07:00
bachinger
742410d517 Use proxy controller to maintain platform session and notification
With this change, the notification controller that is connected by
`MediaNotificationManager`, is used as a proxy controller of the
System UI controller. An app can use the proxy at connection time
and during the lifetime of the session for configuration of the
platform session and the media notification on all API levels.

This includes using custom layout and available player and session
commands of the proxy to maintain the platform session (actions,
custom actions, session extras) and the `MediaNotification.Provider`.

The legacy System UI controller is hidden from the public API,
instead the app interacts with the Media3 proxy:

- System UI is hidden from `MediaSession.getConnectedControllers()`.
- Calls from System UI to methods of `MediaSession.Callback`/
  `MediaLibrarySession.Callback` are mapped to the `ControllerInfo`
  of the proxy controller.
- When `getControllerForCurrentRequest()` is called during an operation of
  System UI the proxy `ControllerInfo` is returned.

PiperOrigin-RevId: 567606117
2023-09-22 06:36:22 -07:00
jbibik
39c1ac7f3a Move setAudioAttributes from ExoPlayer to Player
PiperOrigin-RevId: 566607528
2023-09-19 06:08:37 -07:00
tonihei
597de8706d Show play button during playback suppression by default
This changes the default logic of shouldShowPlayButton to show a play
button while the playback is temporarily suppressed. This helps to
provide better UI feedback to the fact that playback stopped and
provides a quick way for users to override the suppression and attempt
to restart playback.

Some apps may want to keep the legacy behavior depending on their app's
needs. Hence, we also add a config parameter to set this behavior both
in MediaSession and our default UI components.

Issue: google/ExoPlayer#11213
PiperOrigin-RevId: 557129171
2023-08-15 17:15:38 +01:00
bachinger
a90ec96425 Use MediaUtils.intersect in MediaControllerImplBase
PiperOrigin-RevId: 550566322
2023-08-01 13:54:11 +01:00
bachinger
ea21d27a69 Add custom layout to the state of the MediaController
This change also marks the buttons of the custom layout as
enabled/disabled according to available commands in the controller.
Accordingly, `CommandButton.Builder.setEnabled(boolean)` is deprecated
because the value is overridden by the library.

Issue: androidx/media#38

#minor-release

PiperOrigin-RevId: 547272588
2023-07-13 15:47:50 +01:00
bachinger
bd97dd8519 Rollback of 7956c80f73
*** Original commit ***

Rollback of 2a6f893fba

*** Original commit ***

Set video size to 0/0 when video render is disabled

In terms of MCVR wi...

***

PiperOrigin-RevId: 540525069
2023-06-19 16:09:13 +01:00
Googler
7956c80f73 Rollback of 2a6f893fba
*** Original commit ***

BEGIN_PUBLIC
Set video size to 0/0 when video render is disabled

In terms of MCVR with a `VideoRendererEventListener`, the video size is set to
0/0 right after `onVideoDisabled()` is called and is set to the actual size as
soon as the video size is known after 'onVideoEnabled()`.

For ExoPlayer and in terms of the `Player` interface, `Player.getVideoSize()`
returns a video size of 0/0 when `Player.getCurrentTracks()` does not support
`C.TRACK_TYPE_VIDEO`. This is ensured by the masking behavior

***

PiperOrigin-RevId: 537938947
2023-06-06 18:06:46 +00:00
tonihei
2c07468908 Implement Player.replaceMediaItem(s)
This change moves the default logic into the actual Player
implementations, but does not introduce any behavior changes compared
to addMediaItems+removeMediaItems except to make the updates "atomic"
in ExoPlayerImpl, SimpleBasePlayer and MediaController. It also
provides backwards compatbility for cases where Players don't support
the operation.

Issue: google/ExoPlayer#8046

#minor-release

PiperOrigin-RevId: 534945089
2023-05-25 10:00:02 +01:00
bachinger
2a6f893fba Set video size to 0/0 when video render is disabled
In terms of MCVR with a `VideoRendererEventListener`, the video size is set to
0/0 right after `onVideoDisabled()` is called and is set to the actual size as
soon as the video size is known after 'onVideoEnabled()`.

For ExoPlayer and in terms of the `Player` interface, `Player.getVideoSize()`
returns a video size of 0/0 when `Player.getCurrentTracks()` does not support
`C.TRACK_TYPE_VIDEO`. This is ensured by the masking behavior of
`ExoPlayerImpl` that sets an empty track selection result when the playing
period changes due to a seek or timeline removal.

When transitioning playback from a video media item to the next, or when
seeking within the same video media item, the renderer is not disabled.

#minor-release

PiperOrigin-RevId: 533479600
2023-05-24 15:28:20 +01:00
ibaker
485517f34d Upgrade to Gradle 8.0 and Android Gradle Plugin 8.0.1
This change was auto-generated by the Android Studio Upgrade Assistant.

Issue: androidx/media#409
PiperOrigin-RevId: 533467455
2023-05-19 17:24:28 +01:00
ibaker
b3db85133a Add android.namespace to all build.gradle files
This is a pre-requisite for the Android Studio upgrade assistant to
upgrade from AGP 7.2.2 to 8.0.1, otherwise it fails and complains
this is missing.

Issue: androidx/media#409
PiperOrigin-RevId: 533463246
2023-05-19 17:19:15 +01:00
bachinger
5e4421c2ba Add MediaSession.setSessionActivity(PendingIntent)
The session activity is already sent to the controller with the
`ConnectionState` when it connects. This change adds the ability to update the
activity.

This allows an app to change the intent that is used to open an activity
for the notification. An app is likely to want to change the session activity
just before the session is released. This allows to use a different activity or
more importantly the back stack of the activity for while the app is running
and when used for the playback resumption notification.

PiperOrigin-RevId: 530627102
2023-05-11 09:52:04 +00:00
tonihei
0bac4e24e4 Add routing controller id to DeviceInfo
And forward the id to the VolumeProviderCompat and read it from the platform
MediaController for compatibility.

PiperOrigin-RevId: 526046892
2023-04-24 11:35:08 +01:00
jbibik
c71e4bf1ff Extend Player interface, overloading 4 device-volume methods with flags
Previously, ExoPlayerImpl had volume flags hardcoded to SHOW_UI, but now the developer can choose what happens on volume change. The old methods have been deprecated.

PiperOrigin-RevId: 523974358
2023-04-13 16:30:30 +01:00
tonihei
ae875648a7 Update available commands when setting a new player in MediaSession
#minor-release

PiperOrigin-RevId: 523633865
2023-04-12 16:55:47 +01:00
ibaker
c0459e6ae1 Exclude test_session_{common,current} from API and Javadoc tests
We don't publish documentation for these, nor maven artifacts for them -
they only exist as source code on GitHub.

PiperOrigin-RevId: 513863141
2023-03-07 11:48:38 +00:00
bachinger
4a9cf7d069 Do not assume a valid queue in 3rd party sessions
This change fixes an issue that can be reproduced when
a controller `onConnect` creates a `QueueTimeline` out
of the state of a legacy session and then `prepare` is called.

`activeQueueItemId`, `metadata` and the `queue` of the legacy
session are used when a `QueueTimeline` is created. The change
adds unit tests to cover the different combinatoric cases these
properties being set or unset.

PiperOrigin-RevId: 505731288
2023-02-01 10:34:25 +00:00
tonihei
067340cb0a Filter available commands based on PlaybackStateCompat actions
This allows a MediaController to understand which methods calls
are available on a legacy session.

PiperOrigin-RevId: 504306806
2023-01-25 18:42:51 +00:00
bachinger
375299bf36 Use onMediaMetadataChanged for updating the legacy session
Issue: androidx/media#219
PiperOrigin-RevId: 501080612
2023-01-17 01:46:39 +00:00
bachinger
1803d1cdb8 Migrate BROWSER_ROOT_HINTS_KEY_ROOT_CHILDREN_SUPPORTED_FLAGS to Media3
PiperOrigin-RevId: 490376734
2022-11-24 14:38:41 +00:00
tonihei
c5e071e556 Align PlaybackStateCompat states with logic in MediaSessionConnector
Creating the PlaybackStateCompat from a media3 Player state is done
already by the MediaSessionConnector (and used widely). The media3
session module should set the same states under the same circumstances
to ensure compatiblity and consistency.

PlaybackStateCompat changes made in media3 session:
 - Use STATE_STOPPED when player is ended instead of STATE_PAUSED
 - Use STATE_PLAYING when playback is suppressed temporarily.
 - Set the playback speed to 0 if the player is not playing.
 - Add extras for mediaId and user-set playback speed.

Part of the problem was that Player.isPlaying() was used to check
the state. Unfortunately, MockPlayer.isPlaying() is implemented in
a way that makes it hard to test these changes, because the value
is set independently of playbackState, playWhenReady and suppression
reason. To be able to write consistent, logical tests, this change
also removes the independent setting of isPlaying in MockPlayer to
align it better with a real player. This requires to update some
other tests to use alternative methods.

PiperOrigin-RevId: 487500859
2022-11-10 14:58:06 +00:00
tianyifeng
77fedd8d7d Load bitmaps for MediaMetadataCompat and handle the metadata updates.
* Add `Listener` in `MediaSession` with method `onNotificationRefreshRequired(MediaSession)`.
* Add `MediaSessionService` as the listener of the `MediaSession` when `MediaSession` is added to `MediaSessionService`
* Load bitmap when update metadata in `MediaSessionLegacyStub` and call `onNotificationRefreshRequired` when bitmap asynchronously arrives.

PiperOrigin-RevId: 485376145
2022-11-08 11:19:04 +00:00
christosts
46d5a0e33b MediaController: Add missing event flags (1/2)
This is the first commit out of two. This change adds the missing event
flags for the onEvents() callback when MediaController is connected to a
media3 session (see MediaControllerImplBase). I updated the
MediaControllerListenerTest and MediaControllerStateMaskingTest with
assertions that on onEvents() is called alongside individual
Player.Listener callbacks.

There will be a follow-up change for the case where a MediaController is
connected to a legacy MediaSession (MediaControllerImplLegacy). I've
split this in two separate changes to make the size of the commit
manageable for reviewing.

#minor-release

PiperOrigin-RevId: 481933437
2022-10-24 10:34:30 +00:00
bachinger
006a519a0e Migrate media constants from androidx.media.util.MediaConstants
Adds root extras and metadata extras to MockMediaLibraryService and MockMediaBrowserCompatService and completed test cases for asserting
interoperability with a media1 or Media3 browser.

PiperOrigin-RevId: 480854842
2022-10-17 15:56:30 +00:00
tonihei
d2887d5237 Remove test that just times out
One of the tests in MediaBrowserListenerTest caused the remote
browser service to crash and then just timed out. As this asserts
nothing useful besides checking that the timeout method is working,
we can remove the test.

Crashing the remote browser service had the side effect of letting
subsequent tests in the same class fail because the previous session
was never released and was still present in the static MediaSession
SESSION_ID_TO_SESSION_MAP instance, which prevented the creation
of new sessions with the same id. This is only an issue in test
runs because a real process would also lose its static variables
when it crashes.

PiperOrigin-RevId: 476905337
2022-09-30 18:22:32 +00:00
tonihei
7cb7636ed9 Run MediaSessionStub commands in order
Some commands are run asynchronously and subsequent commands need
to wait until the previous one finished. This can be supported
by returning a Future for each command and using the existing
command execution logic to wait for each Future to complete.

As some MediaSessionStub code is now executed delayed to when it
was originally created, we also need to check if the session is
not released before triggering any actions or sending result codes.

Issue: androidx/media#85
PiperOrigin-RevId: 462101136
2022-07-21 12:54:06 +00:00
bachinger
5bf9e2fb31 Exclude tracks if COMMAND_GET_TRACKS is not available
Issue: androidx/media#102
#minor-release
PiperOrigin-RevId: 461891031
2022-07-21 12:50:29 +00:00
bachinger
9a895cd18f Implement getCurrentTracks in MediaController
After this change the current tracks are sent to the controller as part of
`PlayerInfo` and call `Listener.onTracksChanged()` in case of a change in tracks.

PiperOrigin-RevId: 461578695
2022-07-21 12:40:39 +00:00
tonihei
21d4e85817 Remove setMediaUri/onSetMediaUri
This code path is now completely redundant as the same effect can be
achieved by using player.setMediaItem.

#minor-release

PiperOrigin-RevId: 455115567
2022-06-15 15:32:14 +00:00
bachinger
85a936ecb1 Implement session extras for Media3 and legacy controllers
This provides an (unstable) API for apps to broadcast session extras
Bundle to all connected controllers and set the extras in the legacy
session.

Similar to the custom layout, the extras Bundle is not part of the
Media3 session state. This means that when a Media3 controller
connects to the session after the broadcast, the extras needs to be
sent to that controller in  `MediaSession.Callback.onPostConnect(MediaSession session, ControllerInfo controller)`.

PiperOrigin-RevId: 451871731
2022-05-30 16:52:43 +00:00
bachinger
bf3d81c262 Add missing tests for custom layout notification
PiperOrigin-RevId: 451859199
2022-05-30 16:51:08 +00:00
rohks
c728647290 Create new class to store cues and timestamp.
We need to pass timestamp for the list of cues so we are defining a new class CueGroup which will store both cues and timestamp.

PiperOrigin-RevId: 449212054
2022-05-24 10:49:48 +01:00
bachinger
3ac7e0e84e Update error state of legacy playback state if authentication fails
This change adds the ability to update the error code of the PlaybackStateCompat in
cases we need this for backwards compatibility. It is applied in the least
intrusive way because normally, return values of a service method should not change
the state of the `PlaybackStateCompat`, just because it has nothing to do with the
playback state but rather with the state of the `MediaLibrarySession`.

For this reason only the error code `RESULT_ERROR_SESSION_AUTHENTICATION_EXPIRED`
is taken into account while all other error codes are not mapped to the
`PlaybackStateCompat'.

PiperOrigin-RevId: 438038852
2022-04-06 11:25:27 +01:00
Ian Baker
38717ce969 Reformat some javadoc 2022-02-18 14:54:02 +00:00
jaewan
cd56084b3e Fix flaky MediaBrowserListenerTest
MediaNotificationHandler tries to connect session in the same
process, so tests should be aware MediaControllers from the
MediaNotificationHandler.

PiperOrigin-RevId: 422330424
2022-01-25 18:34:25 +00:00
ibaker
f37e980018 Migrate media3.session references from Window to MediaItem
#minor-release

PiperOrigin-RevId: 405927299
2021-11-08 15:13:41 +00:00
Andrew Lewis
933e207b3e Update to androidx.media3
PiperOrigin-RevId: 405656499
2021-10-27 09:12:46 +01:00