mirror of
https://github.com/samsonjs/media.git
synced 2026-04-19 13:35:47 +00:00
Implement a DefaultMediaDescriptionAdapter that uses MediaMetadata.
PiperOrigin-RevId: 384681659
This commit is contained in:
parent
6512463280
commit
b9ac5a145f
4 changed files with 174 additions and 9 deletions
|
|
@ -37,6 +37,9 @@
|
|||
These methods are all overrides and are already deprecated on `Player`
|
||||
and the respective `ExoPlayer` component classes (since 2.14.0).
|
||||
* Rename `Player.EventFlags` IntDef to `Player.Event`.
|
||||
* Add a `DefaultMediaDescriptionAdapter` for the
|
||||
`PlayerNotificationManager`, that makes use of the `Player`
|
||||
`MediaMetadata` to populate the notification fields.
|
||||
* Remove deprecated symbols:
|
||||
* Remove `Player.getPlaybackError`. Use `Player.getPlayerError` instead.
|
||||
* Remove `Player.getCurrentTag`. Use `Player.getCurrentMediaItem` and
|
||||
|
|
|
|||
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.google.android.exoplayer2.ui;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.text.TextUtils;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.ui.PlayerNotificationManager.BitmapCallback;
|
||||
import com.google.android.exoplayer2.ui.PlayerNotificationManager.MediaDescriptionAdapter;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link MediaDescriptionAdapter}.
|
||||
*
|
||||
* <p>Uses values from the {@link Player#getMediaMetadata() player mediaMetadata} to populate the
|
||||
* notification.
|
||||
*/
|
||||
public final class DefaultMediaDescriptionAdapter implements MediaDescriptionAdapter {
|
||||
|
||||
@Nullable private final PendingIntent pendingIntent;
|
||||
|
||||
/**
|
||||
* Creates a default {@link MediaDescriptionAdapter}.
|
||||
*
|
||||
* @param pendingIntent The {@link PendingIntent} to be returned from {@link
|
||||
* #createCurrentContentIntent(Player)}, or null if no intent should be fired.
|
||||
*/
|
||||
public DefaultMediaDescriptionAdapter(@Nullable PendingIntent pendingIntent) {
|
||||
this.pendingIntent = pendingIntent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getCurrentContentTitle(Player player) {
|
||||
@Nullable CharSequence displayTitle = player.getMediaMetadata().displayTitle;
|
||||
if (!TextUtils.isEmpty(displayTitle)) {
|
||||
return displayTitle;
|
||||
}
|
||||
|
||||
@Nullable CharSequence title = player.getMediaMetadata().title;
|
||||
return title != null ? title : "";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PendingIntent createCurrentContentIntent(Player player) {
|
||||
return pendingIntent;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public CharSequence getCurrentContentText(Player player) {
|
||||
@Nullable CharSequence artist = player.getMediaMetadata().artist;
|
||||
if (!TextUtils.isEmpty(artist)) {
|
||||
return artist;
|
||||
}
|
||||
|
||||
return player.getMediaMetadata().albumArtist;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Bitmap getCurrentLargeIcon(Player player, BitmapCallback callback) {
|
||||
@Nullable byte[] data = player.getMediaMetadata().artworkData;
|
||||
if (data == null) {
|
||||
return null;
|
||||
}
|
||||
return BitmapFactory.decodeByteArray(data, /* offset= */ 0, data.length);
|
||||
}
|
||||
}
|
||||
|
|
@ -19,6 +19,7 @@ import static com.google.android.exoplayer2.Player.COMMAND_SEEK_IN_CURRENT_WINDO
|
|||
import static com.google.android.exoplayer2.Player.COMMAND_SEEK_TO_NEXT_WINDOW;
|
||||
import static com.google.android.exoplayer2.Player.COMMAND_SEEK_TO_PREVIOUS_WINDOW;
|
||||
import static com.google.android.exoplayer2.Player.EVENT_IS_PLAYING_CHANGED;
|
||||
import static com.google.android.exoplayer2.Player.EVENT_MEDIA_METADATA_CHANGED;
|
||||
import static com.google.android.exoplayer2.Player.EVENT_PLAYBACK_PARAMETERS_CHANGED;
|
||||
import static com.google.android.exoplayer2.Player.EVENT_PLAYBACK_STATE_CHANGED;
|
||||
import static com.google.android.exoplayer2.Player.EVENT_PLAY_WHEN_READY_CHANGED;
|
||||
|
|
@ -307,10 +308,10 @@ public class PlayerNotificationManager {
|
|||
private final Context context;
|
||||
private final int notificationId;
|
||||
private final String channelId;
|
||||
private final MediaDescriptionAdapter mediaDescriptionAdapter;
|
||||
|
||||
@Nullable private NotificationListener notificationListener;
|
||||
@Nullable private CustomActionReceiver customActionReceiver;
|
||||
private MediaDescriptionAdapter mediaDescriptionAdapter;
|
||||
private int channelNameResourceId;
|
||||
private int channelDescriptionResourceId;
|
||||
private int channelImportance;
|
||||
|
|
@ -325,24 +326,33 @@ public class PlayerNotificationManager {
|
|||
@Nullable private String groupKey;
|
||||
|
||||
/**
|
||||
* Creates an instance.
|
||||
*
|
||||
* @param context The {@link Context}.
|
||||
* @param notificationId The id of the notification to be posted. Must be greater than 0.
|
||||
* @param channelId The id of the notification channel.
|
||||
* @param mediaDescriptionAdapter The {@link MediaDescriptionAdapter} to be used.
|
||||
* @deprecated Use {@link #Builder(Context, int, String)} instead, then call {@link
|
||||
* #setMediaDescriptionAdapter(MediaDescriptionAdapter)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public Builder(
|
||||
Context context,
|
||||
int notificationId,
|
||||
String channelId,
|
||||
MediaDescriptionAdapter mediaDescriptionAdapter) {
|
||||
this(context, notificationId, channelId);
|
||||
this.mediaDescriptionAdapter = mediaDescriptionAdapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance.
|
||||
*
|
||||
* @param context The {@link Context}.
|
||||
* @param notificationId The id of the notification to be posted. Must be greater than 0.
|
||||
* @param channelId The id of the notification channel.
|
||||
*/
|
||||
public Builder(Context context, int notificationId, String channelId) {
|
||||
checkArgument(notificationId > 0);
|
||||
this.context = context;
|
||||
this.notificationId = notificationId;
|
||||
this.channelId = channelId;
|
||||
this.mediaDescriptionAdapter = mediaDescriptionAdapter;
|
||||
channelImportance = NotificationUtil.IMPORTANCE_LOW;
|
||||
mediaDescriptionAdapter = new DefaultMediaDescriptionAdapter(/* pendingIntent= */ null);
|
||||
smallIconResourceId = R.drawable.exo_notification_small_icon;
|
||||
playActionIconResourceId = R.drawable.exo_notification_play;
|
||||
pauseActionIconResourceId = R.drawable.exo_notification_pause;
|
||||
|
|
@ -529,6 +539,18 @@ public class PlayerNotificationManager {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link MediaDescriptionAdapter} to be queried for the notification contents.
|
||||
*
|
||||
* <p>The default is {@link DefaultMediaDescriptionAdapter} with no {@link PendingIntent}
|
||||
*
|
||||
* @return This builder.
|
||||
*/
|
||||
public Builder setMediaDescriptionAdapter(MediaDescriptionAdapter mediaDescriptionAdapter) {
|
||||
this.mediaDescriptionAdapter = mediaDescriptionAdapter;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Builds the {@link PlayerNotificationManager}. */
|
||||
public PlayerNotificationManager build() {
|
||||
if (channelNameResourceId != 0) {
|
||||
|
|
@ -539,6 +561,7 @@ public class PlayerNotificationManager {
|
|||
channelDescriptionResourceId,
|
||||
channelImportance);
|
||||
}
|
||||
|
||||
return new PlayerNotificationManager(
|
||||
context,
|
||||
channelId,
|
||||
|
|
@ -1487,7 +1510,8 @@ public class PlayerNotificationManager {
|
|||
EVENT_PLAYBACK_PARAMETERS_CHANGED,
|
||||
EVENT_POSITION_DISCONTINUITY,
|
||||
EVENT_REPEAT_MODE_CHANGED,
|
||||
EVENT_SHUFFLE_MODE_ENABLED_CHANGED)) {
|
||||
EVENT_SHUFFLE_MODE_ENABLED_CHANGED,
|
||||
EVENT_MEDIA_METADATA_CHANGED)) {
|
||||
postStartOrUpdateNotification();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.google.android.exoplayer2.ui;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import com.google.android.exoplayer2.MediaMetadata;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
/** Tests for the {@link DefaultMediaDescriptionAdapter}. */
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class DefaultMediaDescriptionAdapterTest {
|
||||
|
||||
@Test
|
||||
public void getters_returnMediaMetadataValues() {
|
||||
Context context = ApplicationProvider.getApplicationContext();
|
||||
Player player = mock(Player.class);
|
||||
MediaMetadata mediaMetadata =
|
||||
new MediaMetadata.Builder().setDisplayTitle("display title").setArtist("artist").build();
|
||||
PendingIntent pendingIntent =
|
||||
PendingIntent.getActivity(context, 0, new Intent(), PendingIntent.FLAG_IMMUTABLE);
|
||||
DefaultMediaDescriptionAdapter adapter = new DefaultMediaDescriptionAdapter(pendingIntent);
|
||||
|
||||
when(player.getMediaMetadata()).thenReturn(mediaMetadata);
|
||||
|
||||
assertThat(adapter.createCurrentContentIntent(player)).isEqualTo(pendingIntent);
|
||||
assertThat(adapter.getCurrentContentTitle(player).toString())
|
||||
.isEqualTo(mediaMetadata.displayTitle.toString());
|
||||
assertThat(adapter.getCurrentContentText(player).toString())
|
||||
.isEqualTo(mediaMetadata.artist.toString());
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue