Skip to content

Commit

Permalink
Set position and speed on the Android MediaSession.
Browse files Browse the repository at this point in the history
This allows Assistant to do relative seeks since it's now able to get
the accurate playback position from its MediaController.

The SbPlayer is short-circuited from the Android player implementation
to the Android MediaSessionClient implementation. This allows it to
learn the position and speed with SbPlayerGetInfo2 in lieu of the
missing information not available through the web MediaSession.

Note that duration is NOT included since it's not ever set by the
shared Starboard player internal implementation. Setting it to the wrong
value negatively affects Assistant, so we don't set it at all.

This should not be a permanent fix, as the web MediaSession should be
extended to allow live playback metadata to be communicated from the web
app to the user agent.
w3c/mediasession#70
w3c/mediasession#202

b/111302299

Cherry-Pick: I9e29176b43f06473fdb6a990dfd088908aa2fa9f
Change-Id: I099004d086b2b85420551a0d5c83add2877f310c
  • Loading branch information
Cobalt Team authored and briantting committed Sep 5, 2018
1 parent afd3f68 commit 52c6aba
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -445,11 +445,14 @@ void sendFeedback(
void updateMediaSession(
int playbackState,
long actions,
long positionMs,
float speed,
String title,
String artist,
String album,
MediaImage[] artwork) {
cobaltMediaSession.updateMediaSession(playbackState, actions, title, artist, album, artwork);
cobaltMediaSession.updateMediaSession(
playbackState, actions, positionMs, speed, title, artist, album, artwork);
}

/** Returns string for kSbSystemPropertyUserAgentAuxField */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,8 @@ private static void nativeInvokeAction(long action) {
public void updateMediaSession(
final int playbackState,
final long actions,
final long positionMs,
final float speed,
final String title,
final String artist,
final String album,
Expand All @@ -356,7 +358,9 @@ public void updateMediaSession(
new Runnable() {
@Override
public void run() {
updateMediaSessionInternal(playbackState, actions, title, artist, album, artwork);
updateMediaSessionInternal(
playbackState, actions, positionMs, speed,
title, artist, album, artwork);
}
});
}
Expand All @@ -365,6 +369,8 @@ public void run() {
private void updateMediaSessionInternal(
int playbackState,
long actions,
long positionMs,
float speed,
String title,
String artist,
String album,
Expand All @@ -389,26 +395,30 @@ private void updateMediaSessionInternal(
}

int androidPlaybackState;
String stateName;
switch (playbackState) {
case PLAYBACK_STATE_PLAYING:
androidPlaybackState = PlaybackState.STATE_PLAYING;
stateName = "PLAYING";
break;
case PLAYBACK_STATE_PAUSED:
androidPlaybackState = PlaybackState.STATE_PAUSED;
stateName = "PAUSED";
break;
case PLAYBACK_STATE_NONE:
default:
androidPlaybackState = PlaybackState.STATE_NONE;
stateName = "NONE";
break;
}

Log.i(TAG, String.format(
"MediaSession state: %s, position: %d ms, speed: %f x", stateName, positionMs, speed));

playbackStateBuilder =
new PlaybackState.Builder()
.setActions(actions)
.setState(
androidPlaybackState,
PlaybackState.PLAYBACK_POSITION_UNKNOWN,
playbackState == PLAYBACK_STATE_PLAYING ? 1.0f : 0.0f);
.setState(androidPlaybackState, positionMs, speed);
mediaSession.setPlaybackState(playbackStateBuilder.build());

// Reset the metadata to make sure we don't retain any fields from previous playback.
Expand Down
29 changes: 28 additions & 1 deletion starboard/android/shared/cobalt/android_media_session_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "starboard/log.h"
#include "starboard/mutex.h"
#include "starboard/once.h"
#include "starboard/player.h"

namespace starboard {
namespace android {
Expand Down Expand Up @@ -170,6 +171,10 @@ class AndroidMediaSessionClient : public MediaSessionClient {
// Protected by "mutex"
static AndroidMediaSessionClient* active_client;

// TODO: Pass the necessary info through web MediaSession so we don't need to
// short-circuit to the player implementation to get info about the playback.
static SbPlayer active_player;

static void OnceInit() { SbMutexCreate(&mutex); }

public:
Expand Down Expand Up @@ -200,6 +205,15 @@ class AndroidMediaSessionClient : public MediaSessionClient {
SbMutexRelease(&mutex);
}

static void UpdateActiveSessionPlatformPlayer(SbPlayer player) {
SbOnce(&once_flag, OnceInit);
SbMutexAcquire(&mutex);

active_player = player;

SbMutexRelease(&mutex);
}

AndroidMediaSessionClient() {}

virtual ~AndroidMediaSessionClient() {
Expand All @@ -224,6 +238,12 @@ class AndroidMediaSessionClient : public MediaSessionClient {
} else if (active_client == this) {
active_client = NULL;
}

SbPlayerInfo2 player_info;
SbMemorySet(&player_info, 0, sizeof(player_info));
if (active_player != kSbPlayerInvalid) {
SbPlayerGetInfo2(active_player, &player_info);
}
SbMutexRelease(&mutex);

jlong playback_state_actions =
Expand Down Expand Up @@ -281,16 +301,19 @@ class AndroidMediaSessionClient : public MediaSessionClient {

env->CallStarboardVoidMethodOrAbort(
"updateMediaSession",
"(IJLjava/lang/String;Ljava/lang/String;Ljava/lang/String;"
"(IJJFLjava/lang/String;Ljava/lang/String;Ljava/lang/String;"
"[Ldev/cobalt/media/MediaImage;)V",
playback_state, playback_state_actions,
player_info.current_media_timestamp / kSbTimeMillisecond,
static_cast<jfloat>(player_info.playback_rate),
j_title.Get(), j_artist.Get(), j_album.Get(), j_artwork.Get());
}
};

SbOnceControl AndroidMediaSessionClient::once_flag = SB_ONCE_INITIALIZER;
SbMutex AndroidMediaSessionClient::mutex;
AndroidMediaSessionClient* AndroidMediaSessionClient::active_client = NULL;
SbPlayer AndroidMediaSessionClient::active_player = kSbPlayerInvalid;

void UpdateActiveSessionPlatformPlaybackState(PlaybackState state) {
MediaSessionPlaybackState media_session_state =
Expand All @@ -300,6 +323,10 @@ void UpdateActiveSessionPlatformPlaybackState(PlaybackState state) {
media_session_state);
}

void UpdateActiveSessionPlatformPlayer(SbPlayer player) {
AndroidMediaSessionClient::UpdateActiveSessionPlatformPlayer(player);
}

} // namespace cobalt
} // namespace shared
} // namespace android
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#ifndef STARBOARD_ANDROID_SHARED_COBALT_ANDROID_MEDIA_SESSION_CLIENT_H_
#define STARBOARD_ANDROID_SHARED_COBALT_ANDROID_MEDIA_SESSION_CLIENT_H_

#include "starboard/player.h"

namespace starboard {
namespace android {
namespace shared {
Expand All @@ -25,6 +27,10 @@ enum PlaybackState { kPlaying = 0, kPaused = 1, kNone = 2 };

void UpdateActiveSessionPlatformPlaybackState(PlaybackState state);

// TODO: Pass the necessary info through web MediaSession so we don't need to
// short-circuit to the player implementation to get info about the playback.
void UpdateActiveSessionPlatformPlayer(SbPlayer player);

} // namespace cobalt
} // namespace shared
} // namespace android
Expand Down
3 changes: 3 additions & 0 deletions starboard/android/shared/player_create.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ using starboard::shared::starboard::player::PlayerWorker;
using starboard::android::shared::cobalt::kPlaying;
using starboard::android::shared::cobalt::
UpdateActiveSessionPlatformPlaybackState;
using starboard::android::shared::cobalt::UpdateActiveSessionPlatformPlayer;

SbPlayer SbPlayerCreate(SbWindow window,
SbMediaVideoCodec video_codec,
Expand Down Expand Up @@ -109,5 +110,7 @@ SbPlayer SbPlayerCreate(SbWindow window,
// matter.
SbPlayerSetBounds(player, 0, 0, 0, 0, 0);

UpdateActiveSessionPlatformPlayer(player);

return player;
}
2 changes: 2 additions & 0 deletions starboard/android/shared/player_destroy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@
using starboard::android::shared::cobalt::kNone;
using starboard::android::shared::cobalt::
UpdateActiveSessionPlatformPlaybackState;
using starboard::android::shared::cobalt::UpdateActiveSessionPlatformPlayer;

void SbPlayerDestroy(SbPlayer player) {
if (!SbPlayerIsValid(player)) {
return;
}
UpdateActiveSessionPlatformPlaybackState(kNone);
UpdateActiveSessionPlatformPlayer(kSbPlayerInvalid);
delete player;
}

0 comments on commit 52c6aba

Please sign in to comment.