use of androidx.annotation.Nullable in project ExoPlayer by google.
the class PlayerCommandQueue method processPendingCommandOnHandler.
private void processPendingCommandOnHandler() {
while (pendingAsyncPlayerCommandResult == null) {
@Nullable PlayerCommand playerCommand;
synchronized (lock) {
playerCommand = pendingPlayerCommandQueue.poll();
}
if (playerCommand == null) {
return;
}
int commandCode = playerCommand.commandCode;
// Check if it's @AsyncCommandCode
boolean asyncCommand = isAsyncCommand(playerCommand.commandCode);
// Continuous COMMAND_CODE_PLAYER_SEEK_TO can be skipped.
if (commandCode == COMMAND_CODE_PLAYER_SEEK_TO) {
@Nullable List<PlayerCommand> skippingCommands = null;
while (true) {
synchronized (lock) {
@Nullable PlayerCommand pendingCommand = pendingPlayerCommandQueue.peek();
if (pendingCommand == null || pendingCommand.commandCode != commandCode) {
break;
}
pendingPlayerCommandQueue.poll();
if (skippingCommands == null) {
skippingCommands = new ArrayList<>();
}
skippingCommands.add(playerCommand);
playerCommand = pendingCommand;
}
}
if (skippingCommands != null) {
for (PlayerCommand skippingCommand : skippingCommands) {
skippingCommand.result.set(new PlayerResult(PlayerResult.RESULT_INFO_SKIPPED, player.getCurrentMediaItem()));
if (DEBUG) {
Log.d(TAG, "skipping pending command, " + skippingCommand);
}
}
}
}
if (asyncCommand) {
// Result would come later, via #notifyCommandCompleted().
// Set pending player result first because it may be notified while the command is running.
pendingAsyncPlayerCommandResult = new AsyncPlayerCommandResult(commandCode, playerCommand.result);
}
if (DEBUG) {
Log.d(TAG, "start processing command, " + playerCommand);
}
int resultCode;
if (player.hasError()) {
resultCode = PlayerResult.RESULT_ERROR_INVALID_STATE;
} else {
try {
boolean handled = playerCommand.command.call();
resultCode = handled ? PlayerResult.RESULT_SUCCESS : PlayerResult.RESULT_INFO_SKIPPED;
} catch (IllegalStateException e) {
resultCode = PlayerResult.RESULT_ERROR_INVALID_STATE;
} catch (IllegalArgumentException | IndexOutOfBoundsException e) {
resultCode = PlayerResult.RESULT_ERROR_BAD_VALUE;
} catch (SecurityException e) {
resultCode = PlayerResult.RESULT_ERROR_PERMISSION_DENIED;
} catch (Exception e) {
resultCode = PlayerResult.RESULT_ERROR_UNKNOWN;
}
}
if (DEBUG) {
Log.d(TAG, "command processed, " + playerCommand);
}
if (asyncCommand) {
if (resultCode != PlayerResult.RESULT_SUCCESS && pendingAsyncPlayerCommandResult != null && playerCommand.result == pendingAsyncPlayerCommandResult.result) {
pendingAsyncPlayerCommandResult = null;
playerCommand.result.set(new PlayerResult(resultCode, player.getCurrentMediaItem()));
}
} else {
playerCommand.result.set(new PlayerResult(resultCode, player.getCurrentMediaItem()));
}
}
}
use of androidx.annotation.Nullable in project ExoPlayer by google.
the class SessionCallback method onConnect.
@Override
@Nullable
public SessionCommandGroup onConnect(MediaSession session, MediaSession.ControllerInfo controllerInfo) {
sessions.add(session);
if (!allowedCommandProvider.acceptConnection(session, controllerInfo)) {
return null;
}
SessionCommandGroup baseAllowedCommands = buildAllowedCommands(session, controllerInfo);
return allowedCommandProvider.getAllowedCommands(session, controllerInfo, baseAllowedCommands);
}
use of androidx.annotation.Nullable in project ExoPlayer by google.
the class SessionCallback method buildAllowedCommands.
private SessionCommandGroup buildAllowedCommands(MediaSession session, MediaSession.ControllerInfo controllerInfo) {
SessionCommandGroup.Builder build;
@Nullable SessionCommandGroup commands = (customCommandProvider != null) ? customCommandProvider.getCustomCommands(session, controllerInfo) : null;
if (commands != null) {
build = new SessionCommandGroup.Builder(commands);
} else {
build = new SessionCommandGroup.Builder();
}
build.addAllPredefinedCommands(SessionCommand.COMMAND_VERSION_1);
build.addCommand(new SessionCommand(SessionCommand.COMMAND_CODE_PLAYER_MOVE_PLAYLIST_ITEM));
// TODO(internal b/142848015): Use removeCommand(int) when it's added.
if (mediaItemProvider == null) {
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_PLAYER_SET_MEDIA_ITEM));
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_PLAYER_SET_PLAYLIST));
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_PLAYER_ADD_PLAYLIST_ITEM));
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_PLAYER_REPLACE_PLAYLIST_ITEM));
}
if (ratingCallback == null) {
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_SESSION_SET_RATING));
}
if (skipCallback == null) {
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_SESSION_SKIP_BACKWARD));
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_SESSION_SKIP_FORWARD));
}
// Check whether the session has unexpectedly changed the player.
if (session.getPlayer() instanceof SessionPlayerConnector) {
SessionPlayerConnector sessionPlayerConnector = (SessionPlayerConnector) session.getPlayer();
// Check whether skipTo* works.
if (!sessionPlayerConnector.canSkipToPlaylistItem()) {
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_PLAYER_SKIP_TO_PLAYLIST_ITEM));
}
if (!sessionPlayerConnector.canSkipToPreviousPlaylistItem()) {
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_PLAYER_SKIP_TO_PREVIOUS_PLAYLIST_ITEM));
}
if (!sessionPlayerConnector.canSkipToNextPlaylistItem()) {
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_PLAYER_SKIP_TO_NEXT_PLAYLIST_ITEM));
}
// Check whether seekTo/rewind/fastForward works.
if (!sessionPlayerConnector.isCurrentMediaItemSeekable()) {
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_PLAYER_SEEK_TO));
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_SESSION_FAST_FORWARD));
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_SESSION_REWIND));
} else {
if (fastForwardMs <= 0) {
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_SESSION_FAST_FORWARD));
}
if (rewindMs <= 0) {
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_SESSION_REWIND));
}
}
} else {
if (!loggedUnexpectedSessionPlayerWarning) {
// This can happen if MediaSession#updatePlayer() is called.
Log.e(TAG, "SessionPlayer isn't a SessionPlayerConnector. Guess the allowed command.");
loggedUnexpectedSessionPlayerWarning = true;
}
if (fastForwardMs <= 0) {
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_SESSION_FAST_FORWARD));
}
if (rewindMs <= 0) {
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_SESSION_REWIND));
}
@Nullable List<MediaItem> playlist = sessionPlayer.getPlaylist();
if (playlist == null) {
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_PLAYER_SKIP_TO_PREVIOUS_PLAYLIST_ITEM));
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_PLAYER_SKIP_TO_NEXT_PLAYLIST_ITEM));
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_PLAYER_SKIP_TO_PLAYLIST_ITEM));
} else {
if (playlist.isEmpty() && (sessionPlayer.getRepeatMode() == SessionPlayer.REPEAT_MODE_NONE || sessionPlayer.getRepeatMode() == SessionPlayer.REPEAT_MODE_ONE)) {
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_PLAYER_SKIP_TO_PREVIOUS_PLAYLIST_ITEM));
}
if (playlist.size() == sessionPlayer.getCurrentMediaItemIndex() + 1 && (sessionPlayer.getRepeatMode() == SessionPlayer.REPEAT_MODE_NONE || sessionPlayer.getRepeatMode() == SessionPlayer.REPEAT_MODE_ONE)) {
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_PLAYER_SKIP_TO_NEXT_PLAYLIST_ITEM));
}
if (playlist.size() <= 1) {
build.removeCommand(new SessionCommand(SessionCommand.COMMAND_CODE_PLAYER_SKIP_TO_PLAYLIST_ITEM));
}
}
}
return build.build();
}
use of androidx.annotation.Nullable in project ExoPlayer by google.
the class OkHttpDataSource method makeRequest.
/**
* Establishes a connection.
*/
private Request makeRequest(DataSpec dataSpec) throws HttpDataSourceException {
long position = dataSpec.position;
long length = dataSpec.length;
@Nullable HttpUrl url = HttpUrl.parse(dataSpec.uri.toString());
if (url == null) {
throw new HttpDataSourceException("Malformed URL", dataSpec, PlaybackException.ERROR_CODE_FAILED_RUNTIME_CHECK, HttpDataSourceException.TYPE_OPEN);
}
Request.Builder builder = new Request.Builder().url(url);
if (cacheControl != null) {
builder.cacheControl(cacheControl);
}
Map<String, String> headers = new HashMap<>();
if (defaultRequestProperties != null) {
headers.putAll(defaultRequestProperties.getSnapshot());
}
headers.putAll(requestProperties.getSnapshot());
headers.putAll(dataSpec.httpRequestHeaders);
for (Map.Entry<String, String> header : headers.entrySet()) {
builder.header(header.getKey(), header.getValue());
}
@Nullable String rangeHeader = buildRangeRequestHeader(position, length);
if (rangeHeader != null) {
builder.addHeader(HttpHeaders.RANGE, rangeHeader);
}
if (userAgent != null) {
builder.addHeader(HttpHeaders.USER_AGENT, userAgent);
}
if (!dataSpec.isFlagSet(DataSpec.FLAG_ALLOW_GZIP)) {
builder.addHeader(HttpHeaders.ACCEPT_ENCODING, "identity");
}
@Nullable RequestBody requestBody = null;
if (dataSpec.httpBody != null) {
requestBody = RequestBody.create(null, dataSpec.httpBody);
} else if (dataSpec.httpMethod == DataSpec.HTTP_METHOD_POST) {
// OkHttp requires a non-null body for POST requests.
requestBody = RequestBody.create(null, Util.EMPTY_BYTE_ARRAY);
}
builder.method(dataSpec.getHttpMethodString(), requestBody);
return builder.build();
}
use of androidx.annotation.Nullable in project ExoPlayer by google.
the class MediaMetadata method fromBundle.
private static MediaMetadata fromBundle(Bundle bundle) {
Builder builder = new Builder();
builder.setTitle(bundle.getCharSequence(keyForField(FIELD_TITLE))).setArtist(bundle.getCharSequence(keyForField(FIELD_ARTIST))).setAlbumTitle(bundle.getCharSequence(keyForField(FIELD_ALBUM_TITLE))).setAlbumArtist(bundle.getCharSequence(keyForField(FIELD_ALBUM_ARTIST))).setDisplayTitle(bundle.getCharSequence(keyForField(FIELD_DISPLAY_TITLE))).setSubtitle(bundle.getCharSequence(keyForField(FIELD_SUBTITLE))).setDescription(bundle.getCharSequence(keyForField(FIELD_DESCRIPTION))).setMediaUri(bundle.getParcelable(keyForField(FIELD_MEDIA_URI))).setArtworkData(bundle.getByteArray(keyForField(FIELD_ARTWORK_DATA)), bundle.containsKey(keyForField(FIELD_ARTWORK_DATA_TYPE)) ? bundle.getInt(keyForField(FIELD_ARTWORK_DATA_TYPE)) : null).setArtworkUri(bundle.getParcelable(keyForField(FIELD_ARTWORK_URI))).setWriter(bundle.getCharSequence(keyForField(FIELD_WRITER))).setComposer(bundle.getCharSequence(keyForField(FIELD_COMPOSER))).setConductor(bundle.getCharSequence(keyForField(FIELD_CONDUCTOR))).setGenre(bundle.getCharSequence(keyForField(FIELD_GENRE))).setCompilation(bundle.getCharSequence(keyForField(FIELD_COMPILATION))).setStation(bundle.getCharSequence(keyForField(FIELD_STATION))).setExtras(bundle.getBundle(keyForField(FIELD_EXTRAS)));
if (bundle.containsKey(keyForField(FIELD_USER_RATING))) {
@Nullable Bundle fieldBundle = bundle.getBundle(keyForField(FIELD_USER_RATING));
if (fieldBundle != null) {
builder.setUserRating(Rating.CREATOR.fromBundle(fieldBundle));
}
}
if (bundle.containsKey(keyForField(FIELD_OVERALL_RATING))) {
@Nullable Bundle fieldBundle = bundle.getBundle(keyForField(FIELD_OVERALL_RATING));
if (fieldBundle != null) {
builder.setOverallRating(Rating.CREATOR.fromBundle(fieldBundle));
}
}
if (bundle.containsKey(keyForField(FIELD_TRACK_NUMBER))) {
builder.setTrackNumber(bundle.getInt(keyForField(FIELD_TRACK_NUMBER)));
}
if (bundle.containsKey(keyForField(FIELD_TOTAL_TRACK_COUNT))) {
builder.setTotalTrackCount(bundle.getInt(keyForField(FIELD_TOTAL_TRACK_COUNT)));
}
if (bundle.containsKey(keyForField(FIELD_FOLDER_TYPE))) {
builder.setFolderType(bundle.getInt(keyForField(FIELD_FOLDER_TYPE)));
}
if (bundle.containsKey(keyForField(FIELD_IS_PLAYABLE))) {
builder.setIsPlayable(bundle.getBoolean(keyForField(FIELD_IS_PLAYABLE)));
}
if (bundle.containsKey(keyForField(FIELD_RECORDING_YEAR))) {
builder.setRecordingYear(bundle.getInt(keyForField(FIELD_RECORDING_YEAR)));
}
if (bundle.containsKey(keyForField(FIELD_RECORDING_MONTH))) {
builder.setRecordingMonth(bundle.getInt(keyForField(FIELD_RECORDING_MONTH)));
}
if (bundle.containsKey(keyForField(FIELD_RECORDING_DAY))) {
builder.setRecordingDay(bundle.getInt(keyForField(FIELD_RECORDING_DAY)));
}
if (bundle.containsKey(keyForField(FIELD_RELEASE_YEAR))) {
builder.setReleaseYear(bundle.getInt(keyForField(FIELD_RELEASE_YEAR)));
}
if (bundle.containsKey(keyForField(FIELD_RELEASE_MONTH))) {
builder.setReleaseMonth(bundle.getInt(keyForField(FIELD_RELEASE_MONTH)));
}
if (bundle.containsKey(keyForField(FIELD_RELEASE_DAY))) {
builder.setReleaseDay(bundle.getInt(keyForField(FIELD_RELEASE_DAY)));
}
if (bundle.containsKey(keyForField(FIELD_DISC_NUMBER))) {
builder.setDiscNumber(bundle.getInt(keyForField(FIELD_DISC_NUMBER)));
}
if (bundle.containsKey(keyForField(FIELD_TOTAL_DISC_COUNT))) {
builder.setTotalDiscCount(bundle.getInt(keyForField(FIELD_TOTAL_DISC_COUNT)));
}
return builder.build();
}
Aggregations