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
  • Loading branch information
cool-student committed Mar 2, 2020
1 parent 4674431 commit 04e88c1
Show file tree
Hide file tree
Showing 19 changed files with 1,283 additions and 387 deletions.
337 changes: 100 additions & 237 deletions app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java

Large diffs are not rendered by default.

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

Large diffs are not rendered by default.

200 changes: 86 additions & 114 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,18 +3,15 @@
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.session.MediaButtonReceiver;
import androidx.media.app.NotificationCompat.MediaStyle;

import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;
Expand All @@ -30,13 +27,23 @@ 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 | PlaybackStateCompat.ACTION_SKIP_TO_NEXT | PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS | PlaybackStateCompat.ACTION_SET_REPEAT_MODE | PlaybackStateCompat.ACTION_STOP); // was play and pause now play/pause
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,36 +56,54 @@ public KeyEvent handleMediaButtonIntent(final Intent intent) {
return MediaButtonReceiver.handleIntent(mediaSession, intent);
}

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

public void setMetadata(String title, String artist, Bitmap albumArt, long duration) {

if (albumArt == null || !mediaSession.isActive()) {
return;
}

mediaSession.setMetadata(
new MediaMetadataCompat.Builder()
.putBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART, thumbnailBitmap)
.build()
);

MediaStyle mediaStyle = new MediaStyle()
.setMediaSession(mediaSession.getSessionToken());
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());

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(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 @@ -8,6 +8,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 All @@ -32,8 +33,19 @@ public void onCreate(@Nullable 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(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.appearance_settings);
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
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 @@ -95,6 +95,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 @@ -58,9 +58,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 @@ -130,6 +139,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
73 changes: 73 additions & 0 deletions app/src/main/res/xml/appearance_settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,77 @@
android:key="@string/main_page_content_key"
android:title="@string/main_page_content"/>

<PreferenceCategory
app:iconSpaceReserved="false"
android:layout="@layout/settings_category_header_layout"
android:title="@string/settings_category_notifications_title">

<SwitchPreference
app:iconSpaceReserved="false"
android:defaultValue="false"
android:key="@string/enable_old_notifications_key"
android:summary="@string/enable_old_notifications_summary"
android:title="@string/enable_old_notifications_title"/>

<SwitchPreference
app:iconSpaceReserved="false"
android:defaultValue="false"
android:key="@string/scale_to_square_image_in_notifications_key"
android:summary="@string/scale_to_square_image_in_notifications_summary"
android:title="@string/scale_to_square_image_in_notifications_title"/>

<ListPreference
app:iconSpaceReserved="false"
android:defaultValue="@string/notification_slot_0_value"
android:entries="@array/notification_slot_0_description_list"
android:entryValues="@array/notification_slot_0_values_list"
android:key="@string/notification_slot_0_key"
android:summary="%s"
android:title="@string/default_notification_slot_0_title"/>

<ListPreference
app:iconSpaceReserved="false"
android:defaultValue="@string/notification_slot_1_value"
android:entries="@array/notification_slot_1_description_list"
android:entryValues="@array/notification_slot_1_values_list"
android:key="@string/notification_slot_1_key"
android:summary="%s"
android:title="@string/default_notification_slot_1_title"/>

<ListPreference
app:iconSpaceReserved="false"
android:defaultValue="@string/notification_slot_2_value"
android:entries="@array/notification_slot_2_description_list"
android:entryValues="@array/notification_slot_2_values_list"
android:key="@string/notification_slot_2_key"
android:summary="%s"
android:title="@string/default_notification_slot_2_title"/>

<ListPreference
app:iconSpaceReserved="false"
android:defaultValue="@string/notification_slot_3_value"
android:entries="@array/notification_slot_3_description_list"
android:entryValues="@array/notification_slot_3_values_list"
android:key="@string/notification_slot_3_key"
android:summary="%s"
android:title="@string/default_notification_slot_3_title"/>

<ListPreference
app:iconSpaceReserved="false"
android:defaultValue="@string/notification_slot_4_value"
android:entries="@array/notification_slot_4_description_list"
android:entryValues="@array/notification_slot_4_values_list"
android:key="@string/notification_slot_4_key"
android:summary="%s"
android:title="@string/default_notification_slot_4_title"/>

<EditTextPreference
app:iconSpaceReserved="false"
android:defaultValue="@string/settings_notifications_compact_view_default_value"
android:key="@string/settings_notifications_compact_view_key"
android:summary="@string/settings_notifications_compact_view_summary"
android:title="@string/settings_notifications_compact_view_title"/>

</PreferenceCategory>

</PreferenceScreen>
Loading

0 comments on commit 04e88c1

Please sign in to comment.