Search in sources :

Example 16 with Commands

use of androidx.media3.common.Player.Commands in project media by androidx.

the class ConnectedControllersManager method addController.

public void addController(T controllerKey, ControllerInfo controllerInfo, SessionCommands sessionCommands, Player.Commands playerCommands) {
    synchronized (lock) {
        @Nullable ControllerInfo savedInfo = getController(controllerKey);
        if (savedInfo == null) {
            controllerInfoMap.put(controllerKey, controllerInfo);
            controllerRecords.put(controllerInfo, new ConnectedControllerRecord<>(controllerKey, new SequencedFutureManager(), sessionCommands, playerCommands));
        } else {
            // already exist. Only update allowed commands.
            ConnectedControllerRecord<T> record = checkStateNotNull(controllerRecords.get(savedInfo));
            record.sessionCommands = sessionCommands;
            record.playerCommands = playerCommands;
        }
    }
}
Also used : Nullable(androidx.annotation.Nullable) ControllerInfo(androidx.media3.session.MediaSession.ControllerInfo)

Example 17 with Commands

use of androidx.media3.common.Player.Commands in project media by androidx.

the class DefaultMediaNotificationProvider method createNotification.

@Override
public MediaNotification createNotification(MediaController mediaController, MediaNotification.ActionFactory actionFactory, Callback onNotificationChangedCallback) {
    ensureNotificationChannel();
    NotificationCompat.Builder builder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID);
    // TODO(b/193193926): Filter actions depending on the player's available commands.
    // Skip to previous action.
    builder.addAction(actionFactory.createMediaAction(IconCompat.createWithResource(context, R.drawable.media3_notification_seek_to_previous), context.getString(R.string.media3_controls_seek_to_previous_description), MediaNotification.ActionFactory.COMMAND_SKIP_TO_PREVIOUS));
    if (mediaController.getPlaybackState() == Player.STATE_ENDED || !mediaController.getPlayWhenReady()) {
        // Play action.
        builder.addAction(actionFactory.createMediaAction(IconCompat.createWithResource(context, R.drawable.media3_notification_play), context.getString(R.string.media3_controls_play_description), MediaNotification.ActionFactory.COMMAND_PLAY));
    } else {
        // Pause action.
        builder.addAction(actionFactory.createMediaAction(IconCompat.createWithResource(context, R.drawable.media3_notification_pause), context.getString(R.string.media3_controls_pause_description), MediaNotification.ActionFactory.COMMAND_PAUSE));
    }
    // Skip to next action.
    builder.addAction(actionFactory.createMediaAction(IconCompat.createWithResource(context, R.drawable.media3_notification_seek_to_next), context.getString(R.string.media3_controls_seek_to_next_description), MediaNotification.ActionFactory.COMMAND_SKIP_TO_NEXT));
    // Set metadata info in the notification.
    MediaMetadata metadata = mediaController.getMediaMetadata();
    builder.setContentTitle(metadata.title).setContentText(metadata.artist);
    if (metadata.artworkData != null) {
        Bitmap artworkBitmap = BitmapFactory.decodeByteArray(metadata.artworkData, 0, metadata.artworkData.length);
        builder.setLargeIcon(artworkBitmap);
    }
    androidx.media.app.NotificationCompat.MediaStyle mediaStyle = new androidx.media.app.NotificationCompat.MediaStyle().setCancelButtonIntent(actionFactory.createMediaActionPendingIntent(MediaNotification.ActionFactory.COMMAND_STOP)).setShowActionsInCompactView(1);
    Notification notification = builder.setContentIntent(mediaController.getSessionActivity()).setDeleteIntent(actionFactory.createMediaActionPendingIntent(MediaNotification.ActionFactory.COMMAND_STOP)).setOnlyAlertOnce(true).setSmallIcon(getSmallIconResId(context)).setStyle(mediaStyle).setVisibility(NotificationCompat.VISIBILITY_PUBLIC).setOngoing(false).build();
    return new MediaNotification(NOTIFICATION_ID, notification);
}
Also used : Bitmap(android.graphics.Bitmap) NotificationCompat(androidx.core.app.NotificationCompat) MediaMetadata(androidx.media3.common.MediaMetadata) Notification(android.app.Notification)

Example 18 with Commands

use of androidx.media3.common.Player.Commands in project media by androidx.

the class MediaControllerImplBase method onAvailableCommandsChangedFromSession.

void onAvailableCommandsChangedFromSession(SessionCommands sessionCommands, Commands playerCommands) {
    if (!isConnected()) {
        return;
    }
    boolean playerCommandsChanged = !Util.areEqual(playerCommandsFromSession, playerCommands);
    boolean sessionCommandsChanged = !Util.areEqual(this.sessionCommands, sessionCommands);
    if (!playerCommandsChanged && !sessionCommandsChanged) {
        return;
    }
    boolean intersectedPlayerCommandsChanged = false;
    if (playerCommandsChanged) {
        playerCommandsFromSession = playerCommands;
        Commands prevIntersectedPlayerCommands = intersectedPlayerCommands;
        intersectedPlayerCommands = intersect(playerCommandsFromSession, playerCommandsFromPlayer);
        intersectedPlayerCommandsChanged = !Util.areEqual(intersectedPlayerCommands, prevIntersectedPlayerCommands);
    }
    if (sessionCommandsChanged) {
        this.sessionCommands = sessionCommands;
    }
    if (intersectedPlayerCommandsChanged) {
        listeners.sendEvent(EVENT_AVAILABLE_COMMANDS_CHANGED, listener -> listener.onAvailableCommandsChanged(intersectedPlayerCommands));
    }
    if (sessionCommandsChanged) {
        instance.notifyControllerListener(listener -> listener.onAvailableSessionCommandsChanged(instance, sessionCommands));
    }
}
Also used : Commands(androidx.media3.common.Player.Commands)

Example 19 with Commands

use of androidx.media3.common.Player.Commands in project media by androidx.

the class MediaControllerListenerTest method onTimelineChanged_emptyMediaItemAndMediaMetadata_whenCommandUnavailableFromPlayer.

@Test
public void onTimelineChanged_emptyMediaItemAndMediaMetadata_whenCommandUnavailableFromPlayer() throws Exception {
    int testMediaItemsSize = 2;
    List<MediaItem> testMediaItemList = MediaTestUtils.createMediaItems(testMediaItemsSize);
    Timeline testTimeline = new PlaylistTimeline(testMediaItemList);
    Bundle playerConfig = new RemoteMediaSession.MockPlayerConfigBuilder().setTimeline(testTimeline).build();
    remoteSession.setPlayer(playerConfig);
    MediaController controller = controllerTestRule.createController(remoteSession.getToken());
    CountDownLatch latch = new CountDownLatch(1);
    AtomicReference<Timeline> timelineFromParamRef = new AtomicReference<>();
    AtomicReference<Timeline> timelineFromGetterRef = new AtomicReference<>();
    AtomicReference<MediaMetadata> metadataFromGetterRef = new AtomicReference<>();
    AtomicReference<MediaItem> currentMediaItemGetterRef = new AtomicReference<>();
    Player.Listener listener = new Player.Listener() {

        @Override
        public void onTimelineChanged(Timeline timeline, int reason) {
            timelineFromParamRef.set(timeline);
            timelineFromGetterRef.set(controller.getCurrentTimeline());
            metadataFromGetterRef.set(controller.getMediaMetadata());
            currentMediaItemGetterRef.set(controller.getCurrentMediaItem());
            latch.countDown();
        }
    };
    controller.addListener(listener);
    Commands commandsWithoutGetTimeline = createPlayerCommandsWithout(Player.COMMAND_GET_TIMELINE);
    remoteSession.getMockPlayer().notifyAvailableCommandsChanged(commandsWithoutGetTimeline);
    assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
    assertThat(timelineFromParamRef.get().getWindowCount()).isEqualTo(testMediaItemsSize);
    for (int i = 0; i < timelineFromParamRef.get().getWindowCount(); i++) {
        assertThat(timelineFromParamRef.get().getWindow(/* windowIndex= */
        i, new Timeline.Window()).mediaItem).isEqualTo(MediaItem.EMPTY);
    }
    assertThat(timelineFromGetterRef.get().getWindowCount()).isEqualTo(testMediaItemsSize);
    for (int i = 0; i < timelineFromGetterRef.get().getWindowCount(); i++) {
        assertThat(timelineFromGetterRef.get().getWindow(/* windowIndex= */
        i, new Timeline.Window()).mediaItem).isEqualTo(MediaItem.EMPTY);
    }
    assertThat(metadataFromGetterRef.get()).isEqualTo(MediaMetadata.EMPTY);
    assertThat(currentMediaItemGetterRef.get()).isEqualTo(MediaItem.EMPTY);
}
Also used : RemoteMockPlayer(androidx.media3.session.RemoteMediaSession.RemoteMockPlayer) Player(androidx.media3.common.Player) Bundle(android.os.Bundle) AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch) MediaTestUtils.createTimeline(androidx.media3.session.MediaTestUtils.createTimeline) Timeline(androidx.media3.common.Timeline) MediaItem(androidx.media3.common.MediaItem) Commands(androidx.media3.common.Player.Commands) MediaMetadata(androidx.media3.common.MediaMetadata) LargeTest(androidx.test.filters.LargeTest) Test(org.junit.Test)

Aggregations

Commands (androidx.media3.common.Player.Commands)10 LargeTest (androidx.test.filters.LargeTest)9 Test (org.junit.Test)9 CountDownLatch (java.util.concurrent.CountDownLatch)7 Bundle (android.os.Bundle)5 Player (androidx.media3.common.Player)5 ControllerInfo (androidx.media3.session.MediaSession.ControllerInfo)5 RemoteMockPlayer (androidx.media3.session.RemoteMediaSession.RemoteMockPlayer)5 MediaItem (androidx.media3.common.MediaItem)4 MediaMetadata (androidx.media3.common.MediaMetadata)4 AtomicReference (java.util.concurrent.atomic.AtomicReference)4 Nullable (androidx.annotation.Nullable)3 SessionCallback (androidx.media3.session.MediaSession.SessionCallback)3 ArrayList (java.util.ArrayList)3 Timeline (androidx.media3.common.Timeline)2 MediaTestUtils.createTimeline (androidx.media3.session.MediaTestUtils.createTimeline)2 Notification (android.app.Notification)1 Bitmap (android.graphics.Bitmap)1 IBinder (android.os.IBinder)1 RemoteException (android.os.RemoteException)1