mirror of
https://github.com/TeamNewPipe/NewPipe.git
synced 2024-11-26 04:52:29 +01:00
-Fixed popup player not playing in foreground.
-Fixed activity binder memory leak in popup and background players. -Fixed out of bound window after removing last item on play queue. -Fixed MediaSourceManager continues to process update after disposed. -Changed play queue append to shuffle if queue is already shuffled.
This commit is contained in:
parent
052c9a9869
commit
c6e759a94c
@ -27,7 +27,6 @@ import android.content.Intent;
|
|||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
import android.os.Binder;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
@ -84,12 +83,6 @@ public final class BackgroundPlayer extends Service {
|
|||||||
private PlayerEventListener activityListener;
|
private PlayerEventListener activityListener;
|
||||||
private IBinder mBinder;
|
private IBinder mBinder;
|
||||||
|
|
||||||
class LocalBinder extends Binder {
|
|
||||||
BasePlayerImpl getBackgroundPlayerInstance() {
|
|
||||||
return BackgroundPlayer.this.basePlayerImpl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*//////////////////////////////////////////////////////////////////////////
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
// Notification
|
// Notification
|
||||||
//////////////////////////////////////////////////////////////////////////*/
|
//////////////////////////////////////////////////////////////////////////*/
|
||||||
@ -116,10 +109,10 @@ public final class BackgroundPlayer extends Service {
|
|||||||
wifiManager = ((WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE));
|
wifiManager = ((WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE));
|
||||||
|
|
||||||
ThemeHelper.setTheme(this);
|
ThemeHelper.setTheme(this);
|
||||||
basePlayerImpl = new BasePlayerImpl(this);
|
basePlayerImpl = new BasePlayerImpl(getApplicationContext());
|
||||||
basePlayerImpl.setup();
|
basePlayerImpl.setup();
|
||||||
|
|
||||||
mBinder = new LocalBinder();
|
mBinder = new PlayerServiceBinder(basePlayerImpl);
|
||||||
shouldUpdateOnProgress = true;
|
shouldUpdateOnProgress = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,16 +148,19 @@ public final class BackgroundPlayer extends Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void onClose() {
|
private void onClose() {
|
||||||
stopForeground(true);
|
if (DEBUG) Log.d(TAG, "onClose() called");
|
||||||
|
|
||||||
releaseWifiAndCpu();
|
releaseWifiAndCpu();
|
||||||
|
|
||||||
if (basePlayerImpl != null) {
|
if (basePlayerImpl != null) {
|
||||||
basePlayerImpl.stopActivityBinding();
|
basePlayerImpl.stopActivityBinding();
|
||||||
basePlayerImpl.destroy();
|
basePlayerImpl.destroy();
|
||||||
}
|
}
|
||||||
|
if (notificationManager != null) notificationManager.cancel(NOTIFICATION_ID);
|
||||||
basePlayerImpl = null;
|
|
||||||
mBinder = null;
|
mBinder = null;
|
||||||
|
basePlayerImpl = null;
|
||||||
|
|
||||||
|
stopForeground(true);
|
||||||
stopSelf();
|
stopSelf();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,6 +318,7 @@ public final class BackgroundPlayer extends Service {
|
|||||||
|
|
||||||
updateNotification(-1);
|
updateNotification(-1);
|
||||||
}
|
}
|
||||||
|
clearThumbnailCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -460,8 +457,7 @@ public final class BackgroundPlayer extends Service {
|
|||||||
@Override
|
@Override
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
super.shutdown();
|
super.shutdown();
|
||||||
stopActivityBinding();
|
onClose();
|
||||||
stopSelf();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*//////////////////////////////////////////////////////////////////////////
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
@ -538,7 +534,7 @@ public final class BackgroundPlayer extends Service {
|
|||||||
onVideoPlayPause();
|
onVideoPlayPause();
|
||||||
break;
|
break;
|
||||||
case ACTION_OPEN_DETAIL:
|
case ACTION_OPEN_DETAIL:
|
||||||
openControl(BackgroundPlayer.this);
|
openControl(getApplicationContext());
|
||||||
break;
|
break;
|
||||||
case ACTION_REPEAT:
|
case ACTION_REPEAT:
|
||||||
onRepeatClicked();
|
onRepeatClicked();
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package org.schabi.newpipe.player;
|
package org.schabi.newpipe.player;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.IBinder;
|
|
||||||
|
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
|
|
||||||
@ -19,12 +18,6 @@ public final class BackgroundPlayerActivity extends ServicePlayerActivity {
|
|||||||
return getResources().getString(R.string.title_activity_background_player);
|
return getResources().getString(R.string.title_activity_background_player);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public BasePlayer playerFrom(IBinder binder) {
|
|
||||||
final BackgroundPlayer.LocalBinder mLocalBinder = (BackgroundPlayer.LocalBinder) binder;
|
|
||||||
return mLocalBinder.getBackgroundPlayerInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Intent getBindIntent() {
|
public Intent getBindIntent() {
|
||||||
return new Intent(this, BackgroundPlayer.class);
|
return new Intent(this, BackgroundPlayer.class);
|
||||||
|
@ -315,6 +315,8 @@ public abstract class BasePlayer implements Player.EventListener,
|
|||||||
public void destroy() {
|
public void destroy() {
|
||||||
if (DEBUG) Log.d(TAG, "destroy() called");
|
if (DEBUG) Log.d(TAG, "destroy() called");
|
||||||
destroyPlayer();
|
destroyPlayer();
|
||||||
|
clearThumbnailCache();
|
||||||
|
unregisterBroadcastReceiver();
|
||||||
|
|
||||||
if (playQueue != null) {
|
if (playQueue != null) {
|
||||||
playQueue.dispose();
|
playQueue.dispose();
|
||||||
@ -325,8 +327,6 @@ public abstract class BasePlayer implements Player.EventListener,
|
|||||||
playbackManager = null;
|
playbackManager = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
unregisterBroadcastReceiver();
|
|
||||||
|
|
||||||
trackSelector = null;
|
trackSelector = null;
|
||||||
simpleExoPlayer = null;
|
simpleExoPlayer = null;
|
||||||
}
|
}
|
||||||
@ -902,6 +902,10 @@ public abstract class BasePlayer implements Player.EventListener,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void clearThumbnailCache() {
|
||||||
|
ImageLoader.getInstance().clearMemoryCache();
|
||||||
|
}
|
||||||
|
|
||||||
protected void startProgressLoop() {
|
protected void startProgressLoop() {
|
||||||
if (progressUpdateReactor != null) progressUpdateReactor.dispose();
|
if (progressUpdateReactor != null) progressUpdateReactor.dispose();
|
||||||
progressUpdateReactor = getProgressReactor();
|
progressUpdateReactor = getProgressReactor();
|
||||||
|
@ -20,8 +20,10 @@
|
|||||||
package org.schabi.newpipe.player;
|
package org.schabi.newpipe.player;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.ActivityInfo;
|
import android.content.pm.ActivityInfo;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
@ -44,6 +46,7 @@ import android.widget.Toast;
|
|||||||
|
|
||||||
import com.google.android.exoplayer2.Player;
|
import com.google.android.exoplayer2.Player;
|
||||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
||||||
|
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||||
|
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
||||||
@ -97,7 +100,7 @@ public final class MainVideoPlayer extends Activity {
|
|||||||
|
|
||||||
showSystemUi();
|
showSystemUi();
|
||||||
setContentView(R.layout.activity_main_player);
|
setContentView(R.layout.activity_main_player);
|
||||||
playerImpl = new VideoPlayerImpl();
|
playerImpl = new VideoPlayerImpl(getApplicationContext());
|
||||||
playerImpl.setup(findViewById(android.R.id.content));
|
playerImpl.setup(findViewById(android.R.id.content));
|
||||||
playerImpl.handleIntent(getIntent());
|
playerImpl.handleIntent(getIntent());
|
||||||
}
|
}
|
||||||
@ -243,8 +246,8 @@ public final class MainVideoPlayer extends Activity {
|
|||||||
|
|
||||||
private boolean queueVisible;
|
private boolean queueVisible;
|
||||||
|
|
||||||
VideoPlayerImpl() {
|
VideoPlayerImpl(final Context context) {
|
||||||
super("VideoPlayerImpl" + MainVideoPlayer.TAG, MainVideoPlayer.this);
|
super("VideoPlayerImpl" + MainVideoPlayer.TAG, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -285,6 +288,12 @@ public final class MainVideoPlayer extends Activity {
|
|||||||
screenRotationButton.setOnClickListener(this);
|
screenRotationButton.setOnClickListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onThumbnailReceived(Bitmap thumbnail) {
|
||||||
|
super.onThumbnailReceived(thumbnail);
|
||||||
|
clearThumbnailCache();
|
||||||
|
}
|
||||||
|
|
||||||
/*//////////////////////////////////////////////////////////////////////////
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
// ExoPlayer Video Listener
|
// ExoPlayer Video Listener
|
||||||
//////////////////////////////////////////////////////////////////////////*/
|
//////////////////////////////////////////////////////////////////////////*/
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
package org.schabi.newpipe.player;
|
||||||
|
|
||||||
|
import android.os.Binder;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
|
class PlayerServiceBinder extends Binder {
|
||||||
|
private final BasePlayer basePlayer;
|
||||||
|
|
||||||
|
PlayerServiceBinder(@NonNull final BasePlayer basePlayer) {
|
||||||
|
this.basePlayer = basePlayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
BasePlayer getPlayerInstance() {
|
||||||
|
return basePlayer;
|
||||||
|
}
|
||||||
|
}
|
@ -30,7 +30,6 @@ import android.content.SharedPreferences;
|
|||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.PixelFormat;
|
import android.graphics.PixelFormat;
|
||||||
import android.os.Binder;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
@ -133,12 +132,6 @@ public final class PopupVideoPlayer extends Service {
|
|||||||
private PlayerEventListener activityListener;
|
private PlayerEventListener activityListener;
|
||||||
private IBinder mBinder;
|
private IBinder mBinder;
|
||||||
|
|
||||||
class LocalBinder extends Binder {
|
|
||||||
VideoPlayerImpl getPopupPlayerInstance() {
|
|
||||||
return PopupVideoPlayer.this.playerImpl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*//////////////////////////////////////////////////////////////////////////
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
// Service LifeCycle
|
// Service LifeCycle
|
||||||
//////////////////////////////////////////////////////////////////////////*/
|
//////////////////////////////////////////////////////////////////////////*/
|
||||||
@ -148,21 +141,20 @@ public final class PopupVideoPlayer extends Service {
|
|||||||
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
|
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
|
||||||
notificationManager = ((NotificationManager) getSystemService(NOTIFICATION_SERVICE));
|
notificationManager = ((NotificationManager) getSystemService(NOTIFICATION_SERVICE));
|
||||||
|
|
||||||
playerImpl = new VideoPlayerImpl();
|
playerImpl = new VideoPlayerImpl(getApplicationContext());
|
||||||
ThemeHelper.setTheme(this);
|
ThemeHelper.setTheme(this);
|
||||||
|
|
||||||
mBinder = new LocalBinder();
|
mBinder = new PlayerServiceBinder(playerImpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public int onStartCommand(final Intent intent, int flags, int startId) {
|
public int onStartCommand(final Intent intent, int flags, int startId) {
|
||||||
if (DEBUG)
|
if (DEBUG)
|
||||||
Log.d(TAG, "onStartCommand() called with: intent = [" + intent + "], flags = [" + flags + "], startId = [" + startId + "]");
|
Log.d(TAG, "onStartCommand() called with: intent = [" + intent + "], flags = [" + flags + "], startId = [" + startId + "]");
|
||||||
if (playerImpl.getPlayer() == null) initPopup();
|
if (playerImpl.getPlayer() == null) initPopup();
|
||||||
if (!playerImpl.isPlaying()) playerImpl.getPlayer().setPlayWhenReady(true);
|
if (!playerImpl.isPlaying()) playerImpl.getPlayer().setPlayWhenReady(true);
|
||||||
|
|
||||||
if (intent.getStringExtra(Constants.KEY_URL) != null) {
|
if (intent != null && intent.getStringExtra(Constants.KEY_URL) != null) {
|
||||||
final int serviceId = intent.getIntExtra(Constants.KEY_SERVICE_ID, 0);
|
final int serviceId = intent.getIntExtra(Constants.KEY_SERVICE_ID, 0);
|
||||||
final String url = intent.getStringExtra(Constants.KEY_URL);
|
final String url = intent.getStringExtra(Constants.KEY_URL);
|
||||||
|
|
||||||
@ -200,14 +192,7 @@ public final class PopupVideoPlayer extends Service {
|
|||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
if (DEBUG) Log.d(TAG, "onDestroy() called");
|
if (DEBUG) Log.d(TAG, "onDestroy() called");
|
||||||
stopForeground(true);
|
onClose();
|
||||||
if (playerImpl != null) {
|
|
||||||
playerImpl.destroy();
|
|
||||||
if (playerImpl.getRootView() != null) windowManager.removeView(playerImpl.getRootView());
|
|
||||||
}
|
|
||||||
if (notificationManager != null) notificationManager.cancel(NOTIFICATION_ID);
|
|
||||||
if (currentWorker != null) currentWorker.dispose();
|
|
||||||
savePositionAndSize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -251,7 +236,6 @@ public final class PopupVideoPlayer extends Service {
|
|||||||
|
|
||||||
MySimpleOnGestureListener listener = new MySimpleOnGestureListener();
|
MySimpleOnGestureListener listener = new MySimpleOnGestureListener();
|
||||||
gestureDetector = new GestureDetector(this, listener);
|
gestureDetector = new GestureDetector(this, listener);
|
||||||
//gestureDetector.setIsLongpressEnabled(false);
|
|
||||||
rootView.setOnTouchListener(listener);
|
rootView.setOnTouchListener(listener);
|
||||||
playerImpl.getLoadingPanel().setMinimumWidth(windowLayoutParams.width);
|
playerImpl.getLoadingPanel().setMinimumWidth(windowLayoutParams.width);
|
||||||
playerImpl.getLoadingPanel().setMinimumHeight(windowLayoutParams.height);
|
playerImpl.getLoadingPanel().setMinimumHeight(windowLayoutParams.height);
|
||||||
@ -262,6 +246,10 @@ public final class PopupVideoPlayer extends Service {
|
|||||||
// Notification
|
// Notification
|
||||||
//////////////////////////////////////////////////////////////////////////*/
|
//////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
|
private void resetNotification() {
|
||||||
|
notBuilder = createNotification();
|
||||||
|
}
|
||||||
|
|
||||||
private NotificationCompat.Builder createNotification() {
|
private NotificationCompat.Builder createNotification() {
|
||||||
notRemoteView = new RemoteViews(BuildConfig.APPLICATION_ID, R.layout.player_popup_notification);
|
notRemoteView = new RemoteViews(BuildConfig.APPLICATION_ID, R.layout.player_popup_notification);
|
||||||
|
|
||||||
@ -303,9 +291,23 @@ public final class PopupVideoPlayer extends Service {
|
|||||||
// Misc
|
// Misc
|
||||||
//////////////////////////////////////////////////////////////////////////*/
|
//////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
public void onVideoClose() {
|
public void onClose() {
|
||||||
if (DEBUG) Log.d(TAG, "onVideoClose() called");
|
if (DEBUG) Log.d(TAG, "onClose() called");
|
||||||
playerImpl.stopActivityBinding();
|
|
||||||
|
if (playerImpl != null) {
|
||||||
|
if (playerImpl.getRootView() != null) {
|
||||||
|
windowManager.removeView(playerImpl.getRootView());
|
||||||
|
playerImpl.setRootView(null);
|
||||||
|
}
|
||||||
|
playerImpl.stopActivityBinding();
|
||||||
|
playerImpl.destroy();
|
||||||
|
}
|
||||||
|
if (notificationManager != null) notificationManager.cancel(NOTIFICATION_ID);
|
||||||
|
if (currentWorker != null) currentWorker.dispose();
|
||||||
|
mBinder = null;
|
||||||
|
playerImpl = null;
|
||||||
|
|
||||||
|
stopForeground(true);
|
||||||
stopSelf();
|
stopSelf();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,8 +401,16 @@ public final class PopupVideoPlayer extends Service {
|
|||||||
protected class VideoPlayerImpl extends VideoPlayer {
|
protected class VideoPlayerImpl extends VideoPlayer {
|
||||||
private TextView resizingIndicator;
|
private TextView resizingIndicator;
|
||||||
|
|
||||||
VideoPlayerImpl() {
|
@Override
|
||||||
super("VideoPlayerImpl" + PopupVideoPlayer.TAG, PopupVideoPlayer.this);
|
public void handleIntent(Intent intent) {
|
||||||
|
super.handleIntent(intent);
|
||||||
|
|
||||||
|
resetNotification();
|
||||||
|
startForeground(NOTIFICATION_ID, notBuilder.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
VideoPlayerImpl(final Context context) {
|
||||||
|
super("VideoPlayerImpl" + PopupVideoPlayer.TAG, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -411,8 +421,8 @@ public final class PopupVideoPlayer extends Service {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
super.destroy();
|
|
||||||
if (notRemoteView != null) notRemoteView.setImageViewBitmap(R.id.notificationCover, null);
|
if (notRemoteView != null) notRemoteView.setImageViewBitmap(R.id.notificationCover, null);
|
||||||
|
super.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -426,6 +436,7 @@ public final class PopupVideoPlayer extends Service {
|
|||||||
|
|
||||||
updateNotification(-1);
|
updateNotification(-1);
|
||||||
}
|
}
|
||||||
|
clearThumbnailCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -434,7 +445,7 @@ public final class PopupVideoPlayer extends Service {
|
|||||||
|
|
||||||
if (DEBUG) Log.d(TAG, "onFullScreenButtonClicked() called");
|
if (DEBUG) Log.d(TAG, "onFullScreenButtonClicked() called");
|
||||||
|
|
||||||
playerImpl.setRecovery();
|
setRecovery();
|
||||||
Intent intent;
|
Intent intent;
|
||||||
if (!getSharedPreferences().getBoolean(getResources().getString(R.string.use_old_player_key), false)) {
|
if (!getSharedPreferences().getBoolean(getResources().getString(R.string.use_old_player_key), false)) {
|
||||||
intent = NavigationHelper.getPlayerIntent(
|
intent = NavigationHelper.getPlayerIntent(
|
||||||
@ -457,9 +468,7 @@ public final class PopupVideoPlayer extends Service {
|
|||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
}
|
}
|
||||||
context.startActivity(intent);
|
context.startActivity(intent);
|
||||||
playerImpl.stopActivityBinding();
|
onClose();
|
||||||
destroyPlayer();
|
|
||||||
stopSelf();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -595,8 +604,7 @@ public final class PopupVideoPlayer extends Service {
|
|||||||
@Override
|
@Override
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
super.shutdown();
|
super.shutdown();
|
||||||
stopActivityBinding();
|
onClose();
|
||||||
stopSelf();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*//////////////////////////////////////////////////////////////////////////
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
@ -619,16 +627,17 @@ public final class PopupVideoPlayer extends Service {
|
|||||||
@Override
|
@Override
|
||||||
public void onBroadcastReceived(Intent intent) {
|
public void onBroadcastReceived(Intent intent) {
|
||||||
super.onBroadcastReceived(intent);
|
super.onBroadcastReceived(intent);
|
||||||
|
if (intent == null || intent.getAction() == null) return;
|
||||||
if (DEBUG) Log.d(TAG, "onBroadcastReceived() called with: intent = [" + intent + "]");
|
if (DEBUG) Log.d(TAG, "onBroadcastReceived() called with: intent = [" + intent + "]");
|
||||||
switch (intent.getAction()) {
|
switch (intent.getAction()) {
|
||||||
case ACTION_CLOSE:
|
case ACTION_CLOSE:
|
||||||
onVideoClose();
|
onClose();
|
||||||
break;
|
break;
|
||||||
case ACTION_PLAY_PAUSE:
|
case ACTION_PLAY_PAUSE:
|
||||||
onVideoPlayPause();
|
onVideoPlayPause();
|
||||||
break;
|
break;
|
||||||
case ACTION_OPEN_DETAIL:
|
case ACTION_OPEN_DETAIL:
|
||||||
openControl(PopupVideoPlayer.this);
|
openControl(getApplicationContext());
|
||||||
break;
|
break;
|
||||||
case ACTION_REPEAT:
|
case ACTION_REPEAT:
|
||||||
onRepeatClicked();
|
onRepeatClicked();
|
||||||
@ -800,7 +809,7 @@ public final class PopupVideoPlayer extends Service {
|
|||||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
|
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
|
||||||
if (Math.abs(velocityX) > SHUTDOWN_FLING_VELOCITY) {
|
if (Math.abs(velocityX) > SHUTDOWN_FLING_VELOCITY) {
|
||||||
if (DEBUG) Log.d(TAG, "Popup close fling velocity= " + velocityX);
|
if (DEBUG) Log.d(TAG, "Popup close fling velocity= " + velocityX);
|
||||||
onVideoClose();
|
onClose();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package org.schabi.newpipe.player;
|
package org.schabi.newpipe.player;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.IBinder;
|
|
||||||
|
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
|
|
||||||
@ -19,12 +18,6 @@ public final class PopupVideoPlayerActivity extends ServicePlayerActivity {
|
|||||||
return getResources().getString(R.string.title_activity_popup_player);
|
return getResources().getString(R.string.title_activity_popup_player);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public BasePlayer playerFrom(IBinder binder) {
|
|
||||||
final PopupVideoPlayer.LocalBinder mLocalBinder = (PopupVideoPlayer.LocalBinder) binder;
|
|
||||||
return mLocalBinder.getPopupPlayerInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Intent getBindIntent() {
|
public Intent getBindIntent() {
|
||||||
return new Intent(this, PopupVideoPlayer.class);
|
return new Intent(this, PopupVideoPlayer.class);
|
||||||
|
@ -91,8 +91,6 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
|
|||||||
|
|
||||||
public abstract void stopPlayerListener();
|
public abstract void stopPlayerListener();
|
||||||
|
|
||||||
public abstract BasePlayer playerFrom(final IBinder binder);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// Activity Lifecycle
|
// Activity Lifecycle
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
@ -182,7 +180,11 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
|
|||||||
@Override
|
@Override
|
||||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||||
Log.d(getTag(), "Player service is connected");
|
Log.d(getTag(), "Player service is connected");
|
||||||
player = playerFrom(service);
|
|
||||||
|
if (service instanceof PlayerServiceBinder) {
|
||||||
|
player = ((PlayerServiceBinder) service).getPlayerInstance();
|
||||||
|
}
|
||||||
|
|
||||||
if (player == null || player.playQueue == null || player.playQueueAdapter == null || player.simpleExoPlayer == null) {
|
if (player == null || player.playQueue == null || player.playQueueAdapter == null || player.simpleExoPlayer == null) {
|
||||||
unbind();
|
unbind();
|
||||||
finish();
|
finish();
|
||||||
|
@ -139,7 +139,7 @@ public class MediaSourceManager implements DeferredMediaSource.Callback {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNext(@NonNull PlayQueueEvent playQueueMessage) {
|
public void onNext(@NonNull PlayQueueEvent playQueueMessage) {
|
||||||
onPlayQueueChanged(playQueueMessage);
|
if (playQueueReactor != null) onPlayQueueChanged(playQueueMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -153,6 +153,7 @@ public class MediaSourceManager implements DeferredMediaSource.Callback {
|
|||||||
private void onPlayQueueChanged(final PlayQueueEvent event) {
|
private void onPlayQueueChanged(final PlayQueueEvent event) {
|
||||||
if (playQueue.isEmpty()) {
|
if (playQueue.isEmpty()) {
|
||||||
playbackListener.shutdown();
|
playbackListener.shutdown();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// why no pattern matching in Java =(
|
// why no pattern matching in Java =(
|
||||||
@ -170,7 +171,7 @@ public class MediaSourceManager implements DeferredMediaSource.Callback {
|
|||||||
break;
|
break;
|
||||||
case REMOVE:
|
case REMOVE:
|
||||||
final RemoveEvent removeEvent = (RemoveEvent) event;
|
final RemoveEvent removeEvent = (RemoveEvent) event;
|
||||||
remove(removeEvent.index());
|
remove(removeEvent.getRemoveIndex());
|
||||||
sync();
|
sync();
|
||||||
break;
|
break;
|
||||||
case MOVE:
|
case MOVE:
|
||||||
|
@ -18,7 +18,6 @@ import org.schabi.newpipe.playlist.events.SelectEvent;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
@ -210,25 +209,30 @@ public abstract class PlayQueue implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* Appends the given {@link PlayQueueItem}s to the current play queue.
|
* Appends the given {@link PlayQueueItem}s to the current play queue.
|
||||||
*
|
*
|
||||||
* Will emit a {@link AppendEvent} on any given context.
|
* @see #append(List items)
|
||||||
* */
|
* */
|
||||||
public synchronized void append(final PlayQueueItem... items) {
|
public synchronized void append(final PlayQueueItem... items) {
|
||||||
streams.addAll(Arrays.asList(items));
|
append(Arrays.asList(items));
|
||||||
if (backup != null) backup.addAll(Arrays.asList(items));
|
|
||||||
|
|
||||||
broadcast(new AppendEvent(items.length));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Appends the given {@link PlayQueueItem}s to the current play queue.
|
* Appends the given {@link PlayQueueItem}s to the current play queue.
|
||||||
*
|
*
|
||||||
|
* If the play queue is shuffled, then append the items to the backup queue as is and
|
||||||
|
* append the shuffle items to the play queue.
|
||||||
|
*
|
||||||
* Will emit a {@link AppendEvent} on any given context.
|
* Will emit a {@link AppendEvent} on any given context.
|
||||||
* */
|
* */
|
||||||
public synchronized void append(final Collection<PlayQueueItem> items) {
|
public synchronized void append(final List<PlayQueueItem> items) {
|
||||||
streams.addAll(items);
|
List<PlayQueueItem> itemList = new ArrayList<>(items);
|
||||||
if (backup != null) backup.addAll(items);
|
|
||||||
|
|
||||||
broadcast(new AppendEvent(items.size()));
|
if (isShuffled()) {
|
||||||
|
backup.addAll(itemList);
|
||||||
|
Collections.shuffle(itemList);
|
||||||
|
}
|
||||||
|
streams.addAll(itemList);
|
||||||
|
|
||||||
|
broadcast(new AppendEvent(itemList.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -242,7 +246,7 @@ public abstract class PlayQueue implements Serializable {
|
|||||||
public synchronized void remove(final int index) {
|
public synchronized void remove(final int index) {
|
||||||
if (index >= streams.size() || index < 0) return;
|
if (index >= streams.size() || index < 0) return;
|
||||||
removeInternal(index);
|
removeInternal(index);
|
||||||
broadcast(new RemoveEvent(index));
|
broadcast(new RemoveEvent(index, getIndex()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -261,24 +265,28 @@ public abstract class PlayQueue implements Serializable {
|
|||||||
removeInternal(index);
|
removeInternal(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
broadcast(new ErrorEvent(index, skippable));
|
broadcast(new ErrorEvent(index, getIndex(), skippable));
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void removeInternal(final int index) {
|
private synchronized void removeInternal(final int removeIndex) {
|
||||||
final int currentIndex = queueIndex.get();
|
final int currentIndex = queueIndex.get();
|
||||||
final int size = size();
|
final int size = size();
|
||||||
|
|
||||||
if (currentIndex > index) {
|
if (currentIndex > removeIndex) {
|
||||||
queueIndex.decrementAndGet();
|
queueIndex.decrementAndGet();
|
||||||
|
|
||||||
} else if (currentIndex >= size) {
|
} else if (currentIndex >= size) {
|
||||||
queueIndex.set(currentIndex % (size - 1));
|
queueIndex.set(currentIndex % (size - 1));
|
||||||
|
|
||||||
|
} else if (currentIndex == removeIndex && currentIndex == size - 1){
|
||||||
|
queueIndex.set(removeIndex - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (backup != null) {
|
if (backup != null) {
|
||||||
final int backupIndex = backup.indexOf(getItem(index));
|
final int backupIndex = backup.indexOf(getItem(removeIndex));
|
||||||
backup.remove(backupIndex);
|
backup.remove(backupIndex);
|
||||||
}
|
}
|
||||||
streams.remove(index);
|
streams.remove(removeIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -82,7 +82,7 @@ public class PlayQueueAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNext(@NonNull PlayQueueEvent playQueueMessage) {
|
public void onNext(@NonNull PlayQueueEvent playQueueMessage) {
|
||||||
onPlayQueueChanged(playQueueMessage);
|
if (playQueueReactor != null) onPlayQueueChanged(playQueueMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -116,14 +116,15 @@ public class PlayQueueAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
|||||||
case ERROR:
|
case ERROR:
|
||||||
final ErrorEvent errorEvent = (ErrorEvent) message;
|
final ErrorEvent errorEvent = (ErrorEvent) message;
|
||||||
if (!errorEvent.isSkippable()) {
|
if (!errorEvent.isSkippable()) {
|
||||||
notifyItemRemoved(errorEvent.index());
|
notifyItemRemoved(errorEvent.getErrorIndex());
|
||||||
}
|
}
|
||||||
notifyItemChanged(errorEvent.index());
|
notifyItemChanged(errorEvent.getErrorIndex());
|
||||||
|
notifyItemChanged(errorEvent.getQueueIndex());
|
||||||
break;
|
break;
|
||||||
case REMOVE:
|
case REMOVE:
|
||||||
final RemoveEvent removeEvent = (RemoveEvent) message;
|
final RemoveEvent removeEvent = (RemoveEvent) message;
|
||||||
notifyItemRemoved(removeEvent.index());
|
notifyItemRemoved(removeEvent.getRemoveIndex());
|
||||||
notifyItemChanged(removeEvent.index());
|
notifyItemChanged(removeEvent.getQueueIndex());
|
||||||
break;
|
break;
|
||||||
case MOVE:
|
case MOVE:
|
||||||
final MoveEvent moveEvent = (MoveEvent) message;
|
final MoveEvent moveEvent = (MoveEvent) message;
|
||||||
|
@ -2,7 +2,8 @@ package org.schabi.newpipe.playlist.events;
|
|||||||
|
|
||||||
|
|
||||||
public class ErrorEvent implements PlayQueueEvent {
|
public class ErrorEvent implements PlayQueueEvent {
|
||||||
final private int index;
|
final private int errorIndex;
|
||||||
|
final private int queueIndex;
|
||||||
final private boolean skippable;
|
final private boolean skippable;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -10,13 +11,18 @@ public class ErrorEvent implements PlayQueueEvent {
|
|||||||
return PlayQueueEventType.ERROR;
|
return PlayQueueEventType.ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ErrorEvent(final int index, final boolean skippable) {
|
public ErrorEvent(final int errorIndex, final int queueIndex, final boolean skippable) {
|
||||||
this.index = index;
|
this.errorIndex = errorIndex;
|
||||||
|
this.queueIndex = queueIndex;
|
||||||
this.skippable = skippable;
|
this.skippable = skippable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int index() {
|
public int getErrorIndex() {
|
||||||
return index;
|
return errorIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getQueueIndex() {
|
||||||
|
return queueIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSkippable() {
|
public boolean isSkippable() {
|
||||||
|
@ -2,18 +2,24 @@ package org.schabi.newpipe.playlist.events;
|
|||||||
|
|
||||||
|
|
||||||
public class RemoveEvent implements PlayQueueEvent {
|
public class RemoveEvent implements PlayQueueEvent {
|
||||||
final private int index;
|
final private int removeIndex;
|
||||||
|
final private int queueIndex;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PlayQueueEventType type() {
|
public PlayQueueEventType type() {
|
||||||
return PlayQueueEventType.REMOVE;
|
return PlayQueueEventType.REMOVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RemoveEvent(final int index) {
|
public RemoveEvent(final int removeIndex, final int queueIndex) {
|
||||||
this.index = index;
|
this.removeIndex = removeIndex;
|
||||||
|
this.queueIndex = queueIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int index() {
|
public int getQueueIndex() {
|
||||||
return index;
|
return queueIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRemoveIndex() {
|
||||||
|
return removeIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user