Skip to content

Commit

Permalink
Notification Improvements
Browse files Browse the repository at this point in the history
- add MediaStyle notifications for Background and Popup playback
- reduce excessive notification updating ( / recreating of Notification.Builder object) when playing background / popup media
- add new buffering state indicator (can be disabled)
- upscale close icon / downscale replay icon
- add notification slot settings
- move notification settings to appearance
- fix Metadata (song title, artist and album art) sometimes not being set correctly
- other misc notification fixes

Co-authored-by: wb9688 <wb9688@users.noreply.github.com>
  • Loading branch information
cool-student and wb9688 committed Jul 31, 2020
1 parent f290b2b commit 4abf6b2
Show file tree
Hide file tree
Showing 19 changed files with 2,025 additions and 481 deletions.
464 changes: 186 additions & 278 deletions app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java

Large diffs are not rendered by default.

1,379 changes: 1,379 additions & 0 deletions app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java

Large diffs are not rendered by default.

333 changes: 176 additions & 157 deletions app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,14 @@
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.media.MediaMetadata;
import android.os.Build;
import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat;
import android.util.Log;
import android.view.KeyEvent;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
import androidx.media.app.NotificationCompat.MediaStyle;
import androidx.media.session.MediaButtonReceiver;

import com.google.android.exoplayer2.Player;
Expand All @@ -30,13 +27,29 @@ public class MediaSessionManager {
private final MediaSessionCompat mediaSession;
@NonNull
private final MediaSessionConnector sessionConnector;
@NonNull
private final PlaybackStateCompat.Builder playbackStateCompatBuilder;

private int tmpThumbHash;

public MediaSessionManager(@NonNull final Context context,
@NonNull final Player player,
@NonNull final MediaSessionCallback callback) {
this.mediaSession = new MediaSessionCompat(context, TAG);
this.mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS
| MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
this.mediaSession.setActive(true);

this.playbackStateCompatBuilder = new PlaybackStateCompat.Builder();
this.playbackStateCompatBuilder.setState(PlaybackStateCompat.STATE_NONE, -1, 1);
this.playbackStateCompatBuilder.setActions(PlaybackStateCompat.ACTION_SEEK_TO
| PlaybackStateCompat.ACTION_PLAY
| PlaybackStateCompat.ACTION_PAUSE // was play and pause now play/pause
| PlaybackStateCompat.ACTION_SKIP_TO_NEXT
| PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS
| PlaybackStateCompat.ACTION_SET_REPEAT_MODE | PlaybackStateCompat.ACTION_STOP);
this.mediaSession.setPlaybackState(playbackStateCompatBuilder.build());

this.sessionConnector = new MediaSessionConnector(mediaSession);
this.sessionConnector.setControlDispatcher(new PlayQueuePlaybackController(callback));
this.sessionConnector.setQueueNavigator(new PlayQueueNavigator(mediaSession, callback));
Expand All @@ -49,37 +62,65 @@ public KeyEvent handleMediaButtonIntent(final Intent intent) {
return MediaButtonReceiver.handleIntent(mediaSession, intent);
}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public void setLockScreenArt(final NotificationCompat.Builder builder,
@Nullable final Bitmap thumbnailBitmap) {
if (thumbnailBitmap == null || !mediaSession.isActive()) {
public MediaSessionCompat.Token getSessionToken() {
return this.mediaSession.getSessionToken();
}

public void setMetadata(final String title, final String artist, final Bitmap albumArt,
final long duration) {
if (albumArt == null || !mediaSession.isActive()) {
return;
}

mediaSession.setMetadata(
new MediaMetadataCompat.Builder()
.putBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART, thumbnailBitmap)
.build()
);
if (getMetadataAlbumArt() == null) {
Log.d(TAG, "N_getMetadataAlbumArt: thumb == null");
}
if (getMetadataTitle() == null) {
Log.d(TAG, "N_getMetadataTitle: title == null");
}
if (getMetadataArtist() == null) {
Log.d(TAG, "N_getMetadataArtist: artist == null");
}
if (getMetadataDuration() <= 1) {
Log.d(TAG, "N_getMetadataDuration: duration <= 1; " + getMetadataDuration());
}

MediaStyle mediaStyle = new MediaStyle()
.setMediaSession(mediaSession.getSessionToken());
if (getMetadataAlbumArt() == null || getMetadataTitle() == null
|| getMetadataArtist() == null || getMetadataDuration() <= 1
|| albumArt.hashCode() != tmpThumbHash) {
Log.d(TAG, "setMetadata: N_Metadata update: t: " + title + " a: " + artist
+ " thumb: " + albumArt.hashCode() + " d: " + duration);
mediaSession.setMetadata(
new MediaMetadataCompat.Builder()
.putString(MediaMetadataCompat.METADATA_KEY_TITLE, title)
.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, artist)
.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, albumArt)
.putBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON, albumArt)
.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, duration)
.build()
);
tmpThumbHash = albumArt.hashCode();
}
}

builder.setStyle(mediaStyle);
private Bitmap getMetadataAlbumArt() {
return mediaSession.getController().getMetadata()
.getBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART);
}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public void clearLockScreenArt(final NotificationCompat.Builder builder) {
mediaSession.setMetadata(
new MediaMetadataCompat.Builder()
.putBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART, null)
.build()
);
private String getMetadataTitle() {
return mediaSession.getController().getMetadata()
.getString(MediaMetadataCompat.METADATA_KEY_TITLE);
}

MediaStyle mediaStyle = new MediaStyle()
.setMediaSession(mediaSession.getSessionToken());
private String getMetadataArtist() {
return mediaSession.getController().getMetadata()
.getString(MediaMetadataCompat.METADATA_KEY_ARTIST);
}

builder.setStyle(mediaStyle);
private long getMetadataDuration() {
return mediaSession.getController().getMetadata()
.getLong(MediaMetadataCompat.METADATA_KEY_DURATION);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import androidx.preference.Preference;

import org.schabi.newpipe.R;
import org.schabi.newpipe.player.NotificationUtil;
import org.schabi.newpipe.util.Constants;

public class AppearanceSettingsFragment extends BasePreferenceFragment {
Expand Down Expand Up @@ -52,8 +53,22 @@ public void onCreate(@Nullable final Bundle savedInstanceState) {
final Preference captionSettings = findPreference(captionSettingsKey);
getPreferenceScreen().removePreference(captionSettings);
}

findPreference(getString(R.string.enable_old_notifications_key))
.setOnPreferenceChangeListener(oldNotificationsOnPreferenceChangeListener);
}

private Preference.OnPreferenceChangeListener oldNotificationsOnPreferenceChangeListener
= (preference, newValue) -> {
// NotificationUtil.getInstance().toast(getContext(),
// "Killed background / popup player notification(s) !");
NotificationUtil.getInstance()
.cancelNotification(NotificationUtil.NOTIFICATION_ID_BACKGROUND);
NotificationUtil.getInstance().cancelNotification(NotificationUtil.NOTIFICATION_ID_POPUP);

return true;
};

@Override
public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) {
addPreferencesFromResource(R.xml.appearance_settings);
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
107 changes: 107 additions & 0 deletions app/src/main/res/values/settings_keys.xml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,113 @@
<item>144p</item>
</string-array>

<string name="enable_old_notifications_key" translatable="false">enable_old_notifications</string>
<string name="settings_notifications_compact_view_key" translatable="false">notifications_compact_view</string>
<string name="settings_notifications_compact_view_default_value" translatable="false">0,1,2</string>
<string name="scale_to_square_image_in_notifications_key" translatable="false">scale_to_square_image_in_notifications</string>

<string name="notification_slot_prev_key" translatable="false">prev</string>
<string name="notification_slot_next_key" translatable="false">next</string>
<string name="notification_slot_rewind_key" translatable="false">rewind</string>
<string name="notification_slot_forward_key" translatable="false">forward</string>
<string name="notification_slot_smart_rewind_prev_key" translatable="false">smart_rewind_prev</string>
<string name="notification_slot_smart_forward_next_key" translatable="false">smart_forward_next</string>
<string name="notification_slot_play_pause_buffering_key" translatable="false">play_pause_buffering</string>
<string name="notification_slot_play_pause_key" translatable="false">play_pause</string>
<string name="notification_slot_repeat_key" translatable="false">repeat</string>
<string name="notification_slot_shuffle_key" translatable="false">shuffle</string>
<string name="notification_slot_close_key" translatable="false">close</string>
<string name="notification_slot_n_a_key" translatable="false">n/a</string>

<string name="notification_slot_0_key" translatable="false">notification_slot_0_key</string>
<string name="notification_slot_0_value" translatable="false">@string/notification_slot_smart_rewind_prev_key</string>
<string-array name="notification_slot_0_description_list" translatable="false">
<item>Rewind / Previous</item>
<item>Previous</item>
<item>Rewind</item>
</string-array>
<string-array name="notification_slot_0_values_list" translatable="false">
<item>@string/notification_slot_smart_rewind_prev_key</item>
<item>@string/notification_slot_prev_key</item>
<item>@string/notification_slot_rewind_key</item>
</string-array>

<string name="notification_slot_1_key" translatable="false">notification_slot_1_key</string>
<string name="notification_slot_1_value" translatable="false">@string/notification_slot_play_pause_buffering_key</string>
<string-array name="notification_slot_1_description_list" translatable="false">
<item>Play / Pause / Buffering</item>
<item>Play / Pause</item>
<item>Rewind</item>
</string-array>
<string-array name="notification_slot_1_values_list" translatable="false">
<item>@string/notification_slot_play_pause_buffering_key</item>
<item>@string/notification_slot_play_pause_key</item>
<item>@string/notification_slot_rewind_key</item>
</string-array>


<string name="notification_slot_2_key" translatable="false">notification_slot_2_key</string>
<string name="notification_slot_2_value" translatable="false">@string/notification_slot_smart_forward_next_key</string>
<string-array name="notification_slot_2_description_list" translatable="false">
<item>Forward / Next</item>
<item>Forward</item>
<item>Next</item>
<item>Play / Pause / Buffering</item>
<item>Play / Pause</item>
</string-array>
<string-array name="notification_slot_2_values_list" translatable="false">
<item>@string/notification_slot_smart_forward_next_key</item>
<item>@string/notification_slot_forward_key</item>
<item>@string/notification_slot_next_key</item>
<item>@string/notification_slot_play_pause_buffering_key</item>
<item>@string/notification_slot_play_pause_key</item>
</string-array>

<string name="notification_slot_3_key" translatable="false">notification_slot_3_key</string>
<string name="notification_slot_3_value" translatable="false">@string/notification_slot_repeat_key</string>
<string-array name="notification_slot_3_description_list" translatable="false">
<item>Repeat</item>
<item>Shuffle</item>
<item>Previous</item>
<item>Forward</item>
<item>Forward / Next</item>
<item>Rewind</item>
<item>Rewind / Previous</item>
<item>Close</item>
<item>N/A</item>
</string-array>
<string-array name="notification_slot_3_values_list" translatable="false">
<item>@string/notification_slot_repeat_key</item>
<item>@string/notification_slot_shuffle_key</item>
<item>@string/notification_slot_prev_key</item>
<item>@string/notification_slot_forward_key</item>
<item>@string/notification_slot_smart_forward_next_key</item>
<item>@string/notification_slot_rewind_key</item>
<item>@string/notification_slot_smart_rewind_prev_key</item>
<item>@string/notification_slot_close_key</item>
<item>@string/notification_slot_n_a_key</item>
</string-array>

<string name="notification_slot_4_key" translatable="false">notification_slot_4_key</string>
<string name="notification_slot_4_value" translatable="false">@string/notification_slot_close_key</string>
<string-array name="notification_slot_4_description_list" translatable="false">
<item>Close</item>
<item>Repeat</item>
<item>Shuffle</item>
<item>Next</item>
<item>Forward</item>
<item>Forward / Next</item>
<item>N/A</item>
</string-array>
<string-array name="notification_slot_4_values_list" translatable="false">
<item>@string/notification_slot_close_key</item>
<item>@string/notification_slot_repeat_key</item>
<item>@string/notification_slot_shuffle_key</item>
<item>@string/notification_slot_next_key</item>
<item>@string/notification_slot_forward_key</item>
<item>@string/notification_slot_smart_forward_next_key</item>
<item>@string/notification_slot_n_a_key</item>
</string-array>

<string name="video_mp4_key" translatable="false">video_mp4</string>
<string name="video_webm_key" translatable="false">video_webm</string>
Expand Down
14 changes: 12 additions & 2 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,18 @@
<string name="kore_not_found">Install missing Kore app?</string>
<string name="kore_package" translatable="false">org.xbmc.kore</string>
<string name="show_play_with_kodi_title">Show \"Play with Kodi\" option</string>
<string name="enable_lock_screen_video_thumbnail_title">Lock screen video thumbnail</string>
<string name="show_play_with_kodi_summary">Display an option to play a video via Kodi media center</string>
<string name="enable_lock_screen_video_thumbnail_summary">A video thumbnail is shown on the lock screen when using the background player</string>
<string name="enable_old_notifications_title">Enable old notifications</string>
<string name="enable_old_notifications_summary">This enables the old \"Custom RemoteViews\" notifications. If disabled modern MediaStyle notifications will be used.</string>
<string name="scale_to_square_image_in_notifications_title">Scale image to 1:1 aspect ratio</string>
<string name="scale_to_square_image_in_notifications_summary">This will scale the notification image from 16:9 to 1:1 aspect ratio</string>
<string name="default_notification_slot_0_title">Notification slot 0</string>
<string name="default_notification_slot_1_title">Notification slot 1</string>
<string name="default_notification_slot_2_title">Notification slot 2</string>
<string name="default_notification_slot_3_title">Notification slot 3</string>
<string name="default_notification_slot_4_title">Notification slot 4</string>
<string name="settings_notifications_compact_view_title">Notification compact view</string>
<string name="settings_notifications_compact_view_summary">Notification slots to show in compact view</string>
<string name="play_audio">Audio</string>
<string name="default_audio_format_title">Default audio format</string>
<string name="default_video_format_title">Default video format</string>
Expand Down Expand Up @@ -129,6 +138,7 @@
<string name="settings_category_other_title">Other</string>
<string name="settings_category_debug_title">Debug</string>
<string name="settings_category_updates_title">Updates</string>
<string name="settings_category_notifications_title">Notifications</string>
<string name="background_player_playing_toast">Playing in background</string>
<string name="popup_playing_toast">Playing in popup mode</string>
<string name="background_player_append">Queued on background player</string>
Expand Down

0 comments on commit 4abf6b2

Please sign in to comment.