Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
SDK
/
exoplayer
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
9ca0f786
authored
May 04, 2022
by
bachinger
Committed by
Ian Baker
May 09, 2022
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Use Media 3 command constants instead of legacy constants
PiperOrigin-RevId: 446425897
parent
5e139780
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
65 additions
and
76 deletions
libraries/session/src/main/java/androidx/media3/session/DefaultActionFactory.java
libraries/session/src/main/java/androidx/media3/session/DefaultMediaNotificationProvider.java
libraries/session/src/main/java/androidx/media3/session/MediaNotification.java
libraries/session/src/test/java/androidx/media3/session/DefaultActionFactoryTest.java
libraries/session/src/main/java/androidx/media3/session/DefaultActionFactory.java
View file @
9ca0f786
...
...
@@ -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
);
}
...
...
libraries/session/src/main/java/androidx/media3/session/DefaultMediaNotificationProvider.java
View file @
9ca0f786
...
...
@@ -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:
*
* <ul>
* <li>{@link MediaNotification.ActionFactory#COMMAND_PLAY} to start playback. Included when
* {@link MediaController#getPlayWhenReady()} returns {@code false}.
* <li>{@link MediaNotification.ActionFactory#COMMAND_PAUSE}, to pause playback. Included when
* ({@link MediaController#getPlayWhenReady()} returns {@code true}.
* <li>{@link MediaNotification.ActionFactory#COMMAND_SKIP_TO_PREVIOUS} to skip to the previous
* item.
* <li>{@link MediaNotification.ActionFactory#COMMAND_SKIP_TO_NEXT} to skip to the next item.
* <li>{@link MediaController#COMMAND_PLAY_PAUSE} to start or pause playback.
* <li>{@link MediaController#COMMAND_SEEK_TO_PREVIOUS} to seek to the previous item.
* <li>{@link MediaController#COMMAND_SEEK_TO_NEXT} to seek to the next item.
* </ul>
*
* <h2>Drawables</h2>
...
...
@@ -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
)
...
...
libraries/session/src/main/java/androidx/media3/session/MediaNotification.java
View file @
9ca0f786
...
...
@@ -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
{
...
...
@@ -44,44 +38,6 @@ public final class MediaNotification {
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
);
}
/**
...
...
libraries/session/src/test/java/androidx/media3/session/DefaultActionFactoryTest.java
View file @
9ca0f786
...
...
@@ -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
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment