From 9ca0f7862a982f0f1eebbf0762d73760d9829221 Mon Sep 17 00:00:00 2001 From: bachinger Date: Wed, 4 May 2022 13:02:37 +0100 Subject: [PATCH] Use Media 3 command constants instead of legacy constants PiperOrigin-RevId: 446425897 --- .../media3/session/DefaultActionFactory.java | 47 ++++++++++++++--- .../DefaultMediaNotificationProvider.java | 41 +++++++-------- .../media3/session/MediaNotification.java | 50 ++----------------- .../session/DefaultActionFactoryTest.java | 3 +- 4 files changed, 65 insertions(+), 76 deletions(-) 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 a2085ccabd..06fa56b04c 100644 --- a/libraries/session/src/main/java/androidx/media3/session/DefaultActionFactory.java +++ b/libraries/session/src/main/java/androidx/media3/session/DefaultActionFactory.java @@ -15,17 +15,32 @@ */ package androidx.media3.session; +import static android.view.KeyEvent.KEYCODE_MEDIA_FAST_FORWARD; +import static android.view.KeyEvent.KEYCODE_MEDIA_NEXT; +import static android.view.KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE; +import static android.view.KeyEvent.KEYCODE_MEDIA_PREVIOUS; +import static android.view.KeyEvent.KEYCODE_MEDIA_REWIND; +import static android.view.KeyEvent.KEYCODE_MEDIA_STOP; +import static android.view.KeyEvent.KEYCODE_UNKNOWN; +import static androidx.media3.common.Player.COMMAND_PLAY_PAUSE; +import static androidx.media3.common.Player.COMMAND_SEEK_BACK; +import static androidx.media3.common.Player.COMMAND_SEEK_FORWARD; +import static androidx.media3.common.Player.COMMAND_SEEK_TO_NEXT; +import static androidx.media3.common.Player.COMMAND_SEEK_TO_NEXT_MEDIA_ITEM; +import static androidx.media3.common.Player.COMMAND_SEEK_TO_PREVIOUS; +import static androidx.media3.common.Player.COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM; + import android.app.PendingIntent; import android.app.Service; import android.content.ComponentName; import android.content.Intent; import android.os.Bundle; -import android.support.v4.media.session.PlaybackStateCompat; import android.view.KeyEvent; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import androidx.core.app.NotificationCompat; import androidx.core.graphics.drawable.IconCompat; +import androidx.media3.common.Player; import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.Util; @@ -41,13 +56,15 @@ import androidx.media3.common.util.Util; private final Service service; + private int customActionPendingIntentRequestCode = 0; + public DefaultActionFactory(Service service) { this.service = service; } @Override public NotificationCompat.Action createMediaAction( - IconCompat icon, CharSequence title, @Command long command) { + IconCompat icon, CharSequence title, @Player.Command long command) { return new NotificationCompat.Action(icon, title, createMediaActionPendingIntent(command)); } @@ -59,12 +76,12 @@ import androidx.media3.common.util.Util; } @Override - public PendingIntent createMediaActionPendingIntent(@Command long command) { - int keyCode = PlaybackStateCompat.toKeyCode(command); + public PendingIntent createMediaActionPendingIntent(@Player.Command long command) { + int keyCode = toKeyCode(command); Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON); 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) { + if (Util.SDK_INT >= 26 && command == COMMAND_PLAY_PAUSE) { return Api26.createForegroundServicePendingIntent(service, keyCode, intent); } else { return PendingIntent.getService( @@ -75,6 +92,24 @@ import androidx.media3.common.util.Util; } } + private int toKeyCode(@Player.Command long action) { + if (action == COMMAND_SEEK_TO_NEXT_MEDIA_ITEM || action == COMMAND_SEEK_TO_NEXT) { + return KEYCODE_MEDIA_NEXT; + } else if (action == COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM + || action == COMMAND_SEEK_TO_PREVIOUS) { + return KEYCODE_MEDIA_PREVIOUS; + } else if (action == Player.COMMAND_STOP) { + return KEYCODE_MEDIA_STOP; + } else if (action == COMMAND_SEEK_FORWARD) { + return KEYCODE_MEDIA_FAST_FORWARD; + } else if (action == COMMAND_SEEK_BACK) { + return KEYCODE_MEDIA_REWIND; + } else if (action == COMMAND_PLAY_PAUSE) { + return KEYCODE_MEDIA_PLAY_PAUSE; + } + return KEYCODE_UNKNOWN; + } + private PendingIntent createCustomActionPendingIntent(String action, Bundle extras) { Intent intent = new Intent(ACTION_CUSTOM); intent.setComponent(new ComponentName(service, service.getClass())); @@ -83,7 +118,7 @@ import androidx.media3.common.util.Util; // Custom actions always start the service in the background. return PendingIntent.getService( service, - /* requestCode= */ KeyEvent.KEYCODE_UNKNOWN, + /* requestCode= */ ++customActionPendingIntentRequestCode, intent, Util.SDK_INT >= 23 ? PendingIntent.FLAG_IMMUTABLE : 0); } diff --git a/libraries/session/src/main/java/androidx/media3/session/DefaultMediaNotificationProvider.java b/libraries/session/src/main/java/androidx/media3/session/DefaultMediaNotificationProvider.java index 2550bce010..61b4a3d4af 100644 --- a/libraries/session/src/main/java/androidx/media3/session/DefaultMediaNotificationProvider.java +++ b/libraries/session/src/main/java/androidx/media3/session/DefaultMediaNotificationProvider.java @@ -15,6 +15,12 @@ */ package androidx.media3.session; +import static androidx.media3.common.Player.COMMAND_PLAY_PAUSE; +import static androidx.media3.common.Player.COMMAND_SEEK_TO_NEXT; +import static androidx.media3.common.Player.COMMAND_SEEK_TO_NEXT_MEDIA_ITEM; +import static androidx.media3.common.Player.COMMAND_SEEK_TO_PREVIOUS; +import static androidx.media3.common.Player.COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM; +import static androidx.media3.common.Player.COMMAND_STOP; import static androidx.media3.common.util.Assertions.checkStateNotNull; import static androidx.media3.common.util.Util.castNonNull; @@ -52,13 +58,9 @@ import java.util.concurrent.ExecutionException; * The following actions are included in the provided notifications: * * * *

Drawables

@@ -120,17 +122,17 @@ public final class DefaultMediaNotificationProvider implements MediaNotification // Skip to previous action. boolean skipToPreviousAdded = false; if (availableCommands.containsAny( - Player.COMMAND_SEEK_TO_PREVIOUS, Player.COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM)) { + COMMAND_SEEK_TO_PREVIOUS, COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM)) { skipToPreviousAdded = true; 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)); + COMMAND_SEEK_TO_PREVIOUS)); } boolean playPauseAdded = false; - if (availableCommands.contains(Player.COMMAND_PLAY_PAUSE)) { + if (availableCommands.contains(COMMAND_PLAY_PAUSE)) { playPauseAdded = true; if (mediaController.getPlaybackState() == Player.STATE_ENDED || !mediaController.getPlayWhenReady()) { @@ -139,24 +141,23 @@ public final class DefaultMediaNotificationProvider implements MediaNotification actionFactory.createMediaAction( IconCompat.createWithResource(context, R.drawable.media3_notification_play), context.getString(R.string.media3_controls_play_description), - MediaNotification.ActionFactory.COMMAND_PLAY)); + COMMAND_PLAY_PAUSE)); } 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)); + COMMAND_PLAY_PAUSE)); } } // Skip to next action. - if (availableCommands.containsAny( - Player.COMMAND_SEEK_TO_NEXT, Player.COMMAND_SEEK_TO_NEXT_MEDIA_ITEM)) { + if (availableCommands.containsAny(COMMAND_SEEK_TO_NEXT, COMMAND_SEEK_TO_NEXT_MEDIA_ITEM)) { 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)); + COMMAND_SEEK_TO_NEXT)); } // Set metadata info in the notification. @@ -187,11 +188,9 @@ public final class DefaultMediaNotificationProvider implements MediaNotification } MediaStyle mediaStyle = new MediaStyle(); - if (mediaController.isCommandAvailable(Player.COMMAND_STOP) || Util.SDK_INT < 21) { + if (mediaController.isCommandAvailable(COMMAND_STOP) || Util.SDK_INT < 21) { // We must include a cancel intent for pre-L devices. - mediaStyle.setCancelButtonIntent( - actionFactory.createMediaActionPendingIntent( - MediaNotification.ActionFactory.COMMAND_STOP)); + mediaStyle.setCancelButtonIntent(actionFactory.createMediaActionPendingIntent(COMMAND_STOP)); } if (playPauseAdded) { // Show play/pause button only in compact view. @@ -208,9 +207,7 @@ public final class DefaultMediaNotificationProvider implements MediaNotification Notification notification = builder .setContentIntent(mediaController.getSessionActivity()) - .setDeleteIntent( - actionFactory.createMediaActionPendingIntent( - MediaNotification.ActionFactory.COMMAND_STOP)) + .setDeleteIntent(actionFactory.createMediaActionPendingIntent(COMMAND_STOP)) .setOnlyAlertOnce(true) .setSmallIcon(getSmallIconResId(context)) .setStyle(mediaStyle) diff --git a/libraries/session/src/main/java/androidx/media3/session/MediaNotification.java b/libraries/session/src/main/java/androidx/media3/session/MediaNotification.java index 698ab1efb4..9c0ed3f0db 100644 --- a/libraries/session/src/main/java/androidx/media3/session/MediaNotification.java +++ b/libraries/session/src/main/java/androidx/media3/session/MediaNotification.java @@ -16,22 +16,16 @@ package androidx.media3.session; import static androidx.media3.common.util.Assertions.checkNotNull; -import static java.lang.annotation.ElementType.TYPE_USE; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.os.Bundle; -import android.support.v4.media.session.PlaybackStateCompat; import androidx.annotation.IntRange; -import androidx.annotation.LongDef; import androidx.core.app.NotificationCompat; import androidx.core.graphics.drawable.IconCompat; +import androidx.media3.common.Player; import androidx.media3.common.util.UnstableApi; -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; /** A notification for media playbacks. */ public final class MediaNotification { @@ -43,44 +37,6 @@ public final class MediaNotification { @UnstableApi public interface ActionFactory { - /** - * Commands that can be included in a media action. One of {@link #COMMAND_PLAY}, {@link - * #COMMAND_PAUSE}, {@link #COMMAND_STOP}, {@link #COMMAND_REWIND}, {@link - * #COMMAND_FAST_FORWARD}, {@link #COMMAND_SKIP_TO_PREVIOUS}, {@link #COMMAND_SKIP_TO_NEXT} or - * {@link #COMMAND_SET_CAPTIONING_ENABLED}. - */ - @Documented - @Retention(RetentionPolicy.SOURCE) - @Target({TYPE_USE}) - @LongDef({ - COMMAND_PLAY, - COMMAND_PAUSE, - COMMAND_STOP, - COMMAND_REWIND, - COMMAND_FAST_FORWARD, - COMMAND_SKIP_TO_PREVIOUS, - COMMAND_SKIP_TO_NEXT, - COMMAND_SET_CAPTIONING_ENABLED - }) - @interface Command {} - - /** The command to start playback. */ - long COMMAND_PLAY = PlaybackStateCompat.ACTION_PLAY; - /** The command to pause playback. */ - long COMMAND_PAUSE = PlaybackStateCompat.ACTION_PAUSE; - /** The command to stop playback. */ - long COMMAND_STOP = PlaybackStateCompat.ACTION_STOP; - /** The command to rewind. */ - long COMMAND_REWIND = PlaybackStateCompat.ACTION_REWIND; - /** The command to fast forward. */ - long COMMAND_FAST_FORWARD = PlaybackStateCompat.ACTION_FAST_FORWARD; - /** The command to skip to the previous item in the queue. */ - long COMMAND_SKIP_TO_PREVIOUS = PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS; - /** The command to skip to the next item in the queue. */ - long COMMAND_SKIP_TO_NEXT = PlaybackStateCompat.ACTION_SKIP_TO_NEXT; - /** The command to set captioning enabled. */ - long COMMAND_SET_CAPTIONING_ENABLED = PlaybackStateCompat.ACTION_SET_CAPTIONING_ENABLED; - /** * Creates a {@link NotificationCompat.Action} for a notification. These actions will be handled * by the library. @@ -90,7 +46,7 @@ public final class MediaNotification { * @param command A command to send when users trigger this action. */ NotificationCompat.Action createMediaAction( - IconCompat icon, CharSequence title, @Command long command); + IconCompat icon, CharSequence title, @Player.Command long command); /** * Creates a {@link NotificationCompat.Action} for a notification with a custom action. Actions @@ -112,7 +68,7 @@ public final class MediaNotification { * * @param command The intent's command. */ - PendingIntent createMediaActionPendingIntent(@Command long command); + PendingIntent createMediaActionPendingIntent(@Player.Command long command); } /** 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 d1af51c288..52a11687bf 100644 --- a/libraries/session/src/test/java/androidx/media3/session/DefaultActionFactoryTest.java +++ b/libraries/session/src/test/java/androidx/media3/session/DefaultActionFactoryTest.java @@ -21,6 +21,7 @@ import static org.robolectric.Shadows.shadowOf; import android.app.PendingIntent; import android.content.Intent; import androidx.annotation.Nullable; +import androidx.media3.common.Player; import androidx.test.ext.junit.runners.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; @@ -37,7 +38,7 @@ public class DefaultActionFactoryTest { new DefaultActionFactory(Robolectric.setupService(TestService.class)); PendingIntent pendingIntent = - actionFactory.createMediaActionPendingIntent(MediaNotification.ActionFactory.COMMAND_PLAY); + actionFactory.createMediaActionPendingIntent(Player.COMMAND_PLAY_PAUSE); ShadowPendingIntent shadowPendingIntent = shadowOf(pendingIntent); assertThat(actionFactory.isMediaAction(shadowPendingIntent.getSavedIntent())).isTrue();