1
0
mirror of https://github.com/TeamNewPipe/NewPipe.git synced 2024-11-22 11:02:35 +01:00

Made checkStyle happy

This commit is contained in:
Avently 2020-07-14 20:21:32 +03:00
parent bff238774e
commit d8f7db4715
26 changed files with 1448 additions and 664 deletions

View File

@ -85,15 +85,23 @@ public final class FlingBehavior extends AppBarLayout.Behavior {
} }
@Override @Override
public boolean onStartNestedScroll(@NotNull final CoordinatorLayout parent, @NotNull final AppBarLayout child, public boolean onStartNestedScroll(@NotNull final CoordinatorLayout parent,
@NotNull final View directTargetChild, final View target, final int nestedScrollAxes, final int type) { @NotNull final AppBarLayout child,
return allowScroll && super.onStartNestedScroll(parent, child, directTargetChild, target, nestedScrollAxes, type); @NotNull final View directTargetChild,
final View target,
final int nestedScrollAxes,
final int type) {
return allowScroll && super.onStartNestedScroll(
parent, child, directTargetChild, target, nestedScrollAxes, type);
} }
@Override @Override
public boolean onNestedFling(@NotNull final CoordinatorLayout coordinatorLayout, @NotNull final AppBarLayout child, public boolean onNestedFling(@NotNull final CoordinatorLayout coordinatorLayout,
@NotNull final View target, final float velocityX, final float velocityY, final boolean consumed) { @NotNull final AppBarLayout child,
return allowScroll && super.onNestedFling(coordinatorLayout, child, target, velocityX, velocityY, consumed); @NotNull final View target, final float velocityX,
final float velocityY, final boolean consumed) {
return allowScroll && super.onNestedFling(
coordinatorLayout, child, target, velocityX, velocityY, consumed);
} }
@Nullable @Nullable

View File

@ -20,7 +20,8 @@
package org.schabi.newpipe; package org.schabi.newpipe;
import android.content.*; import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
@ -28,9 +29,20 @@ import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import android.view.*;
import android.widget.*;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.ActionBarDrawerToggle; import androidx.appcompat.app.ActionBarDrawerToggle;
@ -56,7 +68,18 @@ import org.schabi.newpipe.player.VideoPlayer;
import org.schabi.newpipe.player.event.OnKeyDownListener; import org.schabi.newpipe.player.event.OnKeyDownListener;
import org.schabi.newpipe.player.playqueue.PlayQueue; import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.report.ErrorActivity; import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.util.*; import org.schabi.newpipe.util.AndroidTvUtils;
import org.schabi.newpipe.util.Constants;
import org.schabi.newpipe.util.KioskTranslator;
import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.PeertubeHelper;
import org.schabi.newpipe.util.PermissionHelper;
import org.schabi.newpipe.util.SerializedCache;
import org.schabi.newpipe.util.ServiceHelper;
import org.schabi.newpipe.util.StateSaver;
import org.schabi.newpipe.util.TLSSocketFactoryCompat;
import org.schabi.newpipe.util.ThemeHelper;
import org.schabi.newpipe.views.FocusOverlayView; import org.schabi.newpipe.views.FocusOverlayView;
import java.util.ArrayList; import java.util.ArrayList;
@ -504,10 +527,14 @@ public class MainActivity extends AppCompatActivity {
@Override @Override
public boolean onKeyDown(final int keyCode, final KeyEvent event) { public boolean onKeyDown(final int keyCode, final KeyEvent event) {
final Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_player_holder); final Fragment fragment = getSupportFragmentManager()
if (fragment instanceof OnKeyDownListener && !bottomSheetHiddenOrCollapsed()) { .findFragmentById(R.id.fragment_player_holder);
// Provide keyDown event to fragment which then sends this event to the main player service if (fragment instanceof OnKeyDownListener
return ((OnKeyDownListener) fragment).onKeyDown(keyCode) || super.onKeyDown(keyCode, event); && !bottomSheetHiddenOrCollapsed()) {
// Provide keyDown event to fragment which then sends this event
// to the main player service
return ((OnKeyDownListener) fragment).onKeyDown(keyCode)
|| super.onKeyDown(keyCode, event);
} }
return super.onKeyDown(keyCode, event); return super.onKeyDown(keyCode, event);
} }
@ -527,21 +554,30 @@ public class MainActivity extends AppCompatActivity {
} }
// In case bottomSheet is not visible on the screen or collapsed we can assume that the user // In case bottomSheet is not visible on the screen or collapsed we can assume that the user
// interacts with a fragment inside fragment_holder so all back presses should be handled by it // interacts with a fragment inside fragment_holder so all back presses should be
// handled by it
if (bottomSheetHiddenOrCollapsed()) { if (bottomSheetHiddenOrCollapsed()) {
final Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_holder); final Fragment fragment = getSupportFragmentManager()
// If current fragment implements BackPressable (i.e. can/wanna handle back press) delegate the back press to it .findFragmentById(R.id.fragment_holder);
// If current fragment implements BackPressable (i.e. can/wanna handle back press)
// delegate the back press to it
if (fragment instanceof BackPressable) { if (fragment instanceof BackPressable) {
if (((BackPressable) fragment).onBackPressed()) return; if (((BackPressable) fragment).onBackPressed()) {
return;
}
} }
} else { } else {
final Fragment fragmentPlayer = getSupportFragmentManager().findFragmentById(R.id.fragment_player_holder); final Fragment fragmentPlayer = getSupportFragmentManager()
// If current fragment implements BackPressable (i.e. can/wanna handle back press) delegate the back press to it .findFragmentById(R.id.fragment_player_holder);
// If current fragment implements BackPressable (i.e. can/wanna handle back press)
// delegate the back press to it
if (fragmentPlayer instanceof BackPressable) { if (fragmentPlayer instanceof BackPressable) {
if (!((BackPressable) fragmentPlayer).onBackPressed()) { if (!((BackPressable) fragmentPlayer).onBackPressed()) {
final FrameLayout bottomSheetLayout = findViewById(R.id.fragment_player_holder); final FrameLayout bottomSheetLayout =
BottomSheetBehavior.from(bottomSheetLayout).setState(BottomSheetBehavior.STATE_COLLAPSED); findViewById(R.id.fragment_player_holder);
BottomSheetBehavior.from(bottomSheetLayout)
.setState(BottomSheetBehavior.STATE_COLLAPSED);
} }
return; return;
} }
@ -568,7 +604,8 @@ public class MainActivity extends AppCompatActivity {
NavigationHelper.openDownloads(this); NavigationHelper.openDownloads(this);
break; break;
case PermissionHelper.DOWNLOAD_DIALOG_REQUEST_CODE: case PermissionHelper.DOWNLOAD_DIALOG_REQUEST_CODE:
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_player_holder); Fragment fragment = getSupportFragmentManager()
.findFragmentById(R.id.fragment_player_holder);
if (fragment instanceof VideoDetailFragment) { if (fragment instanceof VideoDetailFragment) {
((VideoDetailFragment) fragment).openDownloadDialog(); ((VideoDetailFragment) fragment).openDownloadDialog();
} }
@ -661,10 +698,12 @@ public class MainActivity extends AppCompatActivity {
} }
StateSaver.clearStateFiles(); StateSaver.clearStateFiles();
if (getIntent() != null && getIntent().hasExtra(Constants.KEY_LINK_TYPE)) { if (getIntent() != null && getIntent().hasExtra(Constants.KEY_LINK_TYPE)) {
// When user watch a video inside popup and then tries to open the video in main player while the app is closed // When user watch a video inside popup and then tries to open the video in main player
// he will see a blank fragment on place of kiosk. Let's open it first // while the app is closed he will see a blank fragment on place of kiosk.
if (getSupportFragmentManager().getBackStackEntryCount() == 0) // Let's open it first
if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
NavigationHelper.openMainFragment(getSupportFragmentManager()); NavigationHelper.openMainFragment(getSupportFragmentManager());
}
handleIntent(getIntent()); handleIntent(getIntent());
} else { } else {
@ -712,10 +751,16 @@ public class MainActivity extends AppCompatActivity {
switch (((StreamingService.LinkType) intent switch (((StreamingService.LinkType) intent
.getSerializableExtra(Constants.KEY_LINK_TYPE))) { .getSerializableExtra(Constants.KEY_LINK_TYPE))) {
case STREAM: case STREAM:
boolean autoPlay = intent.getBooleanExtra(VideoDetailFragment.AUTO_PLAY, false); boolean autoPlay = intent
final String intentCacheKey = intent.getStringExtra(VideoPlayer.PLAY_QUEUE_KEY); .getBooleanExtra(VideoDetailFragment.AUTO_PLAY, false);
final PlayQueue playQueue = intentCacheKey != null ? SerializedCache.getInstance().take(intentCacheKey, PlayQueue.class) : null; final String intentCacheKey = intent
NavigationHelper.openVideoDetailFragment(getSupportFragmentManager(), serviceId, url, title, autoPlay, playQueue); .getStringExtra(VideoPlayer.PLAY_QUEUE_KEY);
final PlayQueue playQueue = intentCacheKey != null
? SerializedCache.getInstance()
.take(intentCacheKey, PlayQueue.class)
: null;
NavigationHelper.openVideoDetailFragment(getSupportFragmentManager(),
serviceId, url, title, autoPlay, playQueue);
break; break;
case CHANNEL: case CHANNEL:
NavigationHelper.openChannelFragment(getSupportFragmentManager(), NavigationHelper.openChannelFragment(getSupportFragmentManager(),
@ -754,9 +799,11 @@ public class MainActivity extends AppCompatActivity {
private boolean bottomSheetHiddenOrCollapsed() { private boolean bottomSheetHiddenOrCollapsed() {
final FrameLayout bottomSheetLayout = findViewById(R.id.fragment_player_holder); final FrameLayout bottomSheetLayout = findViewById(R.id.fragment_player_holder);
final BottomSheetBehavior<FrameLayout> bottomSheetBehavior = BottomSheetBehavior.from(bottomSheetLayout); final BottomSheetBehavior<FrameLayout> bottomSheetBehavior =
BottomSheetBehavior.from(bottomSheetLayout);
final int sheetState = bottomSheetBehavior.getState(); final int sheetState = bottomSheetBehavior.getState();
return sheetState == BottomSheetBehavior.STATE_HIDDEN || sheetState == BottomSheetBehavior.STATE_COLLAPSED; return sheetState == BottomSheetBehavior.STATE_HIDDEN
|| sheetState == BottomSheetBehavior.STATE_COLLAPSED;
} }
} }

View File

@ -39,7 +39,6 @@ import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.playlist.PlaylistInfo; import org.schabi.newpipe.extractor.playlist.PlaylistInfo;
import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.extractor.stream.VideoStream; import org.schabi.newpipe.extractor.stream.VideoStream;
import org.schabi.newpipe.fragments.detail.VideoDetailFragment;
import org.schabi.newpipe.player.playqueue.ChannelPlayQueue; import org.schabi.newpipe.player.playqueue.ChannelPlayQueue;
import org.schabi.newpipe.player.playqueue.PlayQueue; import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.player.playqueue.PlaylistPlayQueue; import org.schabi.newpipe.player.playqueue.PlaylistPlayQueue;
@ -727,7 +726,7 @@ public class RouterActivity extends AppCompatActivity {
}; };
} }
private void openMainPlayer(PlayQueue playQueue, Choice choice) { private void openMainPlayer(final PlayQueue playQueue, final Choice choice) {
NavigationHelper.playOnMainPlayer(this, playQueue, choice.linkType, NavigationHelper.playOnMainPlayer(this, playQueue, choice.linkType,
choice.url, "", true, true); choice.url, "", true, true);
} }

View File

@ -10,18 +10,19 @@ class StackItem implements Serializable {
private String title; private String title;
private PlayQueue playQueue; private PlayQueue playQueue;
StackItem(final int serviceId, final String url, final String title, final PlayQueue playQueue) { StackItem(final int serviceId, final String url,
final String title, final PlayQueue playQueue) {
this.serviceId = serviceId; this.serviceId = serviceId;
this.url = url; this.url = url;
this.title = title; this.title = title;
this.playQueue = playQueue; this.playQueue = playQueue;
} }
public void setUrl(String url) { public void setUrl(final String url) {
this.url = url; this.url = url;
} }
public void setPlayQueue(PlayQueue queue) { public void setPlayQueue(final PlayQueue queue) {
this.playQueue = queue; this.playQueue = queue;
} }
@ -41,7 +42,9 @@ class StackItem implements Serializable {
return url; return url;
} }
public PlayQueue getPlayQueue() { return playQueue; } public PlayQueue getPlayQueue() {
return playQueue;
}
@Override @Override
public String toString() { public String toString() {

View File

@ -8,8 +8,6 @@ import org.schabi.newpipe.R;
import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.PermissionHelper; import org.schabi.newpipe.util.PermissionHelper;
import static org.schabi.newpipe.player.BackgroundPlayer.ACTION_CLOSE;
public final class BackgroundPlayerActivity extends ServicePlayerActivity { public final class BackgroundPlayerActivity extends ServicePlayerActivity {
private static final String TAG = "BackgroundPlayerActivity"; private static final String TAG = "BackgroundPlayerActivity";
@ -58,13 +56,15 @@ public final class BackgroundPlayerActivity extends ServicePlayerActivity {
} }
this.player.setRecovery(); this.player.setRecovery();
NavigationHelper.playOnPopupPlayer(getApplicationContext(), player.playQueue, this.player.isPlaying()); NavigationHelper.playOnPopupPlayer(
getApplicationContext(), player.playQueue, this.player.isPlaying());
return true; return true;
} }
if (item.getItemId() == R.id.action_switch_background) { if (item.getItemId() == R.id.action_switch_background) {
this.player.setRecovery(); this.player.setRecovery();
NavigationHelper.playOnBackgroundPlayer(getApplicationContext(), player.playQueue, this.player.isPlaying()); NavigationHelper.playOnBackgroundPlayer(
getApplicationContext(), player.playQueue, this.player.isPlaying());
return true; return true;
} }
@ -72,10 +72,14 @@ public final class BackgroundPlayerActivity extends ServicePlayerActivity {
} }
@Override @Override
public void setupMenu(Menu menu) { public void setupMenu(final Menu menu) {
if(player == null) return; if (player == null) {
return;
}
menu.findItem(R.id.action_switch_popup).setVisible(!((VideoPlayerImpl)player).popupPlayerSelected()); menu.findItem(R.id.action_switch_popup)
menu.findItem(R.id.action_switch_background).setVisible(!((VideoPlayerImpl)player).audioPlayerSelected()); .setVisible(!((VideoPlayerImpl) player).popupPlayerSelected());
menu.findItem(R.id.action_switch_background)
.setVisible(!((VideoPlayerImpl) player).audioPlayerSelected());
} }
} }

View File

@ -162,9 +162,9 @@ public abstract class BasePlayer implements
protected static final int PLAY_PREV_ACTIVATION_LIMIT_MILLIS = 5000; // 5 seconds protected static final int PLAY_PREV_ACTIVATION_LIMIT_MILLIS = 5000; // 5 seconds
protected static final int PROGRESS_LOOP_INTERVAL_MILLIS = 500; protected static final int PROGRESS_LOOP_INTERVAL_MILLIS = 500;
public final static int PLAYER_TYPE_VIDEO = 0; public static final int PLAYER_TYPE_VIDEO = 0;
public final static int PLAYER_TYPE_AUDIO = 1; public static final int PLAYER_TYPE_AUDIO = 1;
public final static int PLAYER_TYPE_POPUP = 2; public static final int PLAYER_TYPE_POPUP = 2;
protected SimpleExoPlayer simpleExoPlayer; protected SimpleExoPlayer simpleExoPlayer;
protected AudioReactor audioReactor; protected AudioReactor audioReactor;
@ -257,7 +257,8 @@ public abstract class BasePlayer implements
registerBroadcastReceiver(); registerBroadcastReceiver();
} }
public void initListeners() { } public void initListeners() {
}
public void handleIntent(final Intent intent) { public void handleIntent(final Intent intent) {
if (DEBUG) { if (DEBUG) {
@ -303,11 +304,11 @@ public abstract class BasePlayer implements
/* /*
* There are 3 situations when playback shouldn't be started from scratch (zero timestamp): * There are 3 situations when playback shouldn't be started from scratch (zero timestamp):
* 1. User pressed on a timestamp link and the same video should be rewound to that timestamp * 1. User pressed on a timestamp link and the same video should be rewound to the timestamp
* 2. User changed a player from, for example. main to popup, or from audio to main, etc * 2. User changed a player from, for example. main to popup, or from audio to main, etc
* 3. User chose to resume a video based on a saved timestamp from history of played videos * 3. User chose to resume a video based on a saved timestamp from history of played videos
* In those cases time will be saved because re-init of the play queue is a not an instant task * In those cases time will be saved because re-init of the play queue is a not an instant
* and requires network calls * task and requires network calls
* */ * */
// seek to timestamp if stream is already playing // seek to timestamp if stream is already playing
if (simpleExoPlayer != null if (simpleExoPlayer != null
@ -317,15 +318,21 @@ public abstract class BasePlayer implements
&& playQueue.getItem() != null && playQueue.getItem() != null
&& queue.getItem().getUrl().equals(playQueue.getItem().getUrl()) && queue.getItem().getUrl().equals(playQueue.getItem().getUrl())
&& queue.getItem().getRecoveryPosition() != PlayQueueItem.RECOVERY_UNSET) { && queue.getItem().getRecoveryPosition() != PlayQueueItem.RECOVERY_UNSET) {
// Player can have state = IDLE when playback is stopped or failed and we should retry() in this case // Player can have state = IDLE when playback is stopped or failed
if (simpleExoPlayer.getPlaybackState() == Player.STATE_IDLE) simpleExoPlayer.retry(); // and we should retry() in this case
if (simpleExoPlayer.getPlaybackState() == Player.STATE_IDLE) {
simpleExoPlayer.retry();
}
simpleExoPlayer.seekTo(playQueue.getIndex(), queue.getItem().getRecoveryPosition()); simpleExoPlayer.seekTo(playQueue.getIndex(), queue.getItem().getRecoveryPosition());
return; return;
} else if (samePlayQueue && !playQueue.isDisposed() && simpleExoPlayer != null) { } else if (samePlayQueue && !playQueue.isDisposed() && simpleExoPlayer != null) {
// Do not re-init the same PlayQueue. Save time // Do not re-init the same PlayQueue. Save time
// Player can have state = IDLE when playback is stopped or failed and we should retry() in this case // Player can have state = IDLE when playback is stopped or failed
if (simpleExoPlayer.getPlaybackState() == Player.STATE_IDLE) simpleExoPlayer.retry(); // and we should retry() in this case
if (simpleExoPlayer.getPlaybackState() == Player.STATE_IDLE) {
simpleExoPlayer.retry();
}
return; return;
} else if (intent.getBooleanExtra(RESUME_PLAYBACK, false) } else if (intent.getBooleanExtra(RESUME_PLAYBACK, false)
&& isPlaybackResumeEnabled() && isPlaybackResumeEnabled()
@ -334,21 +341,27 @@ public abstract class BasePlayer implements
if (item != null && item.getRecoveryPosition() == PlayQueueItem.RECOVERY_UNSET) { if (item != null && item.getRecoveryPosition() == PlayQueueItem.RECOVERY_UNSET) {
stateLoader = recordManager.loadStreamState(item) stateLoader = recordManager.loadStreamState(item)
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
// Do not place initPlayback() in doFinally() because it restarts playback after destroy() // Do not place initPlayback() in doFinally() because
// it restarts playback after destroy()
//.doFinally() //.doFinally()
.subscribe( .subscribe(
state -> { state -> {
queue.setRecovery(queue.getIndex(), state.getProgressTime()); queue.setRecovery(queue.getIndex(), state.getProgressTime());
initPlayback(queue, repeatMode, playbackSpeed, playbackPitch, playbackSkipSilence, true, isMuted); initPlayback(queue, repeatMode, playbackSpeed, playbackPitch,
playbackSkipSilence, true, isMuted);
}, },
error -> { error -> {
if (DEBUG) error.printStackTrace(); if (DEBUG) {
error.printStackTrace();
}
// In case any error we can start playback without history // In case any error we can start playback without history
initPlayback(queue, repeatMode, playbackSpeed, playbackPitch, playbackSkipSilence, true, isMuted); initPlayback(queue, repeatMode, playbackSpeed, playbackPitch,
playbackSkipSilence, true, isMuted);
}, },
() -> { () -> {
// Completed but not found in history // Completed but not found in history
initPlayback(queue, repeatMode, playbackSpeed, playbackPitch, playbackSkipSilence, true, isMuted); initPlayback(queue, repeatMode, playbackSpeed, playbackPitch,
playbackSkipSilence, true, isMuted);
} }
); );
databaseUpdateReactor.add(stateLoader); databaseUpdateReactor.add(stateLoader);
@ -357,8 +370,10 @@ public abstract class BasePlayer implements
} }
// Good to go... // Good to go...
// In a case of equal PlayQueues we can re-init old one but only when it is disposed // In a case of equal PlayQueues we can re-init old one but only when it is disposed
initPlayback(samePlayQueue ? playQueue : queue, repeatMode, playbackSpeed, playbackPitch, playbackSkipSilence, initPlayback(samePlayQueue ? playQueue : queue, repeatMode,
!intent.getBooleanExtra(START_PAUSED, false), isMuted); playbackSpeed, playbackPitch, playbackSkipSilence,
!intent.getBooleanExtra(START_PAUSED, false),
isMuted);
} }
private PlaybackParameters retrievePlaybackParametersFromPreferences() { private PlaybackParameters retrievePlaybackParametersFromPreferences() {
@ -596,7 +611,8 @@ public abstract class BasePlayer implements
} }
} }
public void onPausedSeek() { } public void onPausedSeek() {
}
public void onCompleted() { public void onCompleted() {
if (DEBUG) { if (DEBUG) {
@ -1514,6 +1530,7 @@ public abstract class BasePlayer implements
/** /**
* Sets the playback parameters of the player, and also saves them to shared preferences. * Sets the playback parameters of the player, and also saves them to shared preferences.
* Speed and pitch are rounded up to 2 decimal places before being used or saved. * Speed and pitch are rounded up to 2 decimal places before being used or saved.
*
* @param speed the playback speed, will be rounded to up to 2 decimal places * @param speed the playback speed, will be rounded to up to 2 decimal places
* @param pitch the playback pitch, will be rounded to up to 2 decimal places * @param pitch the playback pitch, will be rounded to up to 2 decimal places
* @param skipSilence skip silence during playback * @param skipSilence skip silence during playback

View File

@ -54,7 +54,7 @@ import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
/** /**
* One service for all players * One service for all players.
* *
* @author mauriciocolli * @author mauriciocolli
*/ */
@ -84,14 +84,22 @@ public final class MainPlayer extends Service {
private RemoteViews notRemoteView; private RemoteViews notRemoteView;
private RemoteViews bigNotRemoteView; private RemoteViews bigNotRemoteView;
static final String ACTION_CLOSE = "org.schabi.newpipe.player.MainPlayer.CLOSE"; static final String ACTION_CLOSE =
static final String ACTION_PLAY_PAUSE = "org.schabi.newpipe.player.MainPlayer.PLAY_PAUSE"; "org.schabi.newpipe.player.MainPlayer.CLOSE";
static final String ACTION_OPEN_CONTROLS = "org.schabi.newpipe.player.MainPlayer.OPEN_CONTROLS"; static final String ACTION_PLAY_PAUSE =
static final String ACTION_REPEAT = "org.schabi.newpipe.player.MainPlayer.REPEAT"; "org.schabi.newpipe.player.MainPlayer.PLAY_PAUSE";
static final String ACTION_PLAY_NEXT = "org.schabi.newpipe.player.MainPlayer.ACTION_PLAY_NEXT"; static final String ACTION_OPEN_CONTROLS =
static final String ACTION_PLAY_PREVIOUS = "org.schabi.newpipe.player.MainPlayer.ACTION_PLAY_PREVIOUS"; "org.schabi.newpipe.player.MainPlayer.OPEN_CONTROLS";
static final String ACTION_FAST_REWIND = "org.schabi.newpipe.player.MainPlayer.ACTION_FAST_REWIND"; static final String ACTION_REPEAT =
static final String ACTION_FAST_FORWARD = "org.schabi.newpipe.player.MainPlayer.ACTION_FAST_FORWARD"; "org.schabi.newpipe.player.MainPlayer.REPEAT";
static final String ACTION_PLAY_NEXT =
"org.schabi.newpipe.player.MainPlayer.ACTION_PLAY_NEXT";
static final String ACTION_PLAY_PREVIOUS =
"org.schabi.newpipe.player.MainPlayer.ACTION_PLAY_PREVIOUS";
static final String ACTION_FAST_REWIND =
"org.schabi.newpipe.player.MainPlayer.ACTION_FAST_REWIND";
static final String ACTION_FAST_FORWARD =
"org.schabi.newpipe.player.MainPlayer.ACTION_FAST_FORWARD";
private static final String SET_IMAGE_RESOURCE_METHOD = "setImageResource"; private static final String SET_IMAGE_RESOURCE_METHOD = "setImageResource";
@ -101,7 +109,9 @@ public final class MainPlayer extends Service {
@Override @Override
public void onCreate() { public void onCreate() {
if (DEBUG) Log.d(TAG, "onCreate() called"); if (DEBUG) {
Log.d(TAG, "onCreate() called");
}
assureCorrectAppLanguage(this); assureCorrectAppLanguage(this);
notificationManager = ((NotificationManager) getSystemService(NOTIFICATION_SERVICE)); notificationManager = ((NotificationManager) getSystemService(NOTIFICATION_SERVICE));
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE); windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
@ -120,12 +130,16 @@ public final class MainPlayer extends Service {
} }
@Override @Override
public int onStartCommand(Intent intent, int flags, int startId) { public int onStartCommand(final Intent intent, final int flags, final int startId) {
if (DEBUG) Log.d(TAG, "onStartCommand() called with: intent = [" + intent + if (DEBUG) {
"], flags = [" + flags + "], startId = [" + startId + "]"); Log.d(TAG, "onStartCommand() called with: intent = [" + intent
+ "], flags = [" + flags + "], startId = [" + startId + "]");
}
if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction()) || intent.getStringExtra(VideoPlayer.PLAY_QUEUE_KEY) != null) if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())
|| intent.getStringExtra(VideoPlayer.PLAY_QUEUE_KEY) != null) {
showNotificationAndStartForeground(); showNotificationAndStartForeground();
}
playerImpl.handleIntent(intent); playerImpl.handleIntent(intent);
if (playerImpl.mediaSessionManager != null) { if (playerImpl.mediaSessionManager != null) {
@ -135,24 +149,32 @@ public final class MainPlayer extends Service {
} }
public void stop(final boolean autoplayEnabled) { public void stop(final boolean autoplayEnabled) {
if (DEBUG) Log.d(TAG, "stop() called"); if (DEBUG) {
Log.d(TAG, "stop() called");
}
if (playerImpl.getPlayer() != null) { if (playerImpl.getPlayer() != null) {
playerImpl.wasPlaying = playerImpl.getPlayer().getPlayWhenReady(); playerImpl.wasPlaying = playerImpl.getPlayer().getPlayWhenReady();
// Releases wifi & cpu, disables keepScreenOn, etc. // Releases wifi & cpu, disables keepScreenOn, etc.
if (!autoplayEnabled) playerImpl.onPause(); if (!autoplayEnabled) {
// We can't just pause the player here because it will make transition from one stream to a new stream not smooth playerImpl.onPause();
}
// We can't just pause the player here because it will make transition
// from one stream to a new stream not smooth
playerImpl.getPlayer().stop(false); playerImpl.getPlayer().stop(false);
playerImpl.setRecovery(); playerImpl.setRecovery();
// Notification shows information about old stream but if a user selects a stream from backStack it's not actual anymore // Notification shows information about old stream but if a user selects
// a stream from backStack it's not actual anymore
// So we should hide the notification at all. // So we should hide the notification at all.
// When autoplay enabled such notification flashing is annoying so skip this case // When autoplay enabled such notification flashing is annoying so skip this case
if (!autoplayEnabled) stopForeground(true); if (!autoplayEnabled) {
stopForeground(true);
}
} }
} }
@Override @Override
public void onTaskRemoved(Intent rootIntent) { public void onTaskRemoved(final Intent rootIntent) {
super.onTaskRemoved(rootIntent); super.onTaskRemoved(rootIntent);
onDestroy(); onDestroy();
// Unload from memory completely // Unload from memory completely
@ -161,17 +183,19 @@ public final class MainPlayer extends Service {
@Override @Override
public void onDestroy() { public void onDestroy() {
if (DEBUG) Log.d(TAG, "destroy() called"); if (DEBUG) {
Log.d(TAG, "destroy() called");
}
onClose(); onClose();
} }
@Override @Override
protected void attachBaseContext(Context base) { protected void attachBaseContext(final Context base) {
super.attachBaseContext(AudioServiceLeakFix.preventLeakOf(base)); super.attachBaseContext(AudioServiceLeakFix.preventLeakOf(base));
} }
@Override @Override
public IBinder onBind(Intent intent) { public IBinder onBind(final Intent intent) {
return mBinder; return mBinder;
} }
@ -179,7 +203,9 @@ public final class MainPlayer extends Service {
// Actions // Actions
//////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////*/
private void onClose() { private void onClose() {
if (DEBUG) Log.d(TAG, "onClose() called"); if (DEBUG) {
Log.d(TAG, "onClose() called");
}
if (playerImpl != null) { if (playerImpl != null) {
removeViewFromParent(); removeViewFromParent();
@ -190,7 +216,9 @@ public final class MainPlayer extends Service {
playerImpl.removePopupFromView(); playerImpl.removePopupFromView();
playerImpl.destroy(); playerImpl.destroy();
} }
if (notificationManager != null) notificationManager.cancel(NOTIFICATION_ID); if (notificationManager != null) {
notificationManager.cancel(NOTIFICATION_ID);
}
stopForeground(true); stopForeground(true);
stopSelf(); stopSelf();
@ -201,16 +229,19 @@ public final class MainPlayer extends Service {
//////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////*/
boolean isLandscape() { boolean isLandscape() {
// DisplayMetrics from activity context knows about MultiWindow feature while DisplayMetrics from app context doesn't // DisplayMetrics from activity context knows about MultiWindow feature
final DisplayMetrics metrics = (playerImpl != null && playerImpl.getParentActivity() != null) ? // while DisplayMetrics from app context doesn't
playerImpl.getParentActivity().getResources().getDisplayMetrics() final DisplayMetrics metrics = (playerImpl != null
&& playerImpl.getParentActivity() != null)
? playerImpl.getParentActivity().getResources().getDisplayMetrics()
: getResources().getDisplayMetrics(); : getResources().getDisplayMetrics();
return metrics.heightPixels < metrics.widthPixels; return metrics.heightPixels < metrics.widthPixels;
} }
public View getView() { public View getView() {
if (playerImpl == null) if (playerImpl == null) {
return null; return null;
}
return playerImpl.getRootView(); return playerImpl.getRootView();
} }
@ -221,18 +252,21 @@ public final class MainPlayer extends Service {
// This means view was added to fragment // This means view was added to fragment
final ViewGroup parent = (ViewGroup) getView().getParent(); final ViewGroup parent = (ViewGroup) getView().getParent();
parent.removeView(getView()); parent.removeView(getView());
} else } else {
// This means view was added by windowManager for popup player // This means view was added by windowManager for popup player
windowManager.removeViewImmediate(getView()); windowManager.removeViewImmediate(getView());
} }
} }
}
private void showNotificationAndStartForeground() { private void showNotificationAndStartForeground() {
resetNotification(); resetNotification();
if (getBigNotRemoteView() != null) if (getBigNotRemoteView() != null) {
getBigNotRemoteView().setProgressBar(R.id.notificationProgressBar, 100, 0, false); getBigNotRemoteView().setProgressBar(R.id.notificationProgressBar, 100, 0, false);
if (getNotRemoteView() != null) }
if (getNotRemoteView() != null) {
getNotRemoteView().setProgressBar(R.id.notificationProgressBar, 100, 0, false); getNotRemoteView().setProgressBar(R.id.notificationProgressBar, 100, 0, false);
}
startForeground(NOTIFICATION_ID, getNotBuilder().build()); startForeground(NOTIFICATION_ID, getNotBuilder().build());
} }
@ -246,8 +280,10 @@ public final class MainPlayer extends Service {
} }
private NotificationCompat.Builder createNotification() { private NotificationCompat.Builder createNotification() {
notRemoteView = new RemoteViews(BuildConfig.APPLICATION_ID, R.layout.player_background_notification); notRemoteView = new RemoteViews(BuildConfig.APPLICATION_ID,
bigNotRemoteView = new RemoteViews(BuildConfig.APPLICATION_ID, R.layout.player_background_notification_expanded); R.layout.player_background_notification);
bigNotRemoteView = new RemoteViews(BuildConfig.APPLICATION_ID,
R.layout.player_background_notification_expanded);
setupNotification(notRemoteView); setupNotification(notRemoteView);
setupNotification(bigNotRemoteView); setupNotification(bigNotRemoteView);
@ -294,37 +330,51 @@ public final class MainPlayer extends Service {
private void setupNotification(final RemoteViews remoteViews) { private void setupNotification(final RemoteViews remoteViews) {
// Don't show anything until player is playing // Don't show anything until player is playing
if (playerImpl == null) return; if (playerImpl == null) {
return;
}
remoteViews.setTextViewText(R.id.notificationSongName, playerImpl.getVideoTitle()); remoteViews.setTextViewText(R.id.notificationSongName, playerImpl.getVideoTitle());
remoteViews.setTextViewText(R.id.notificationArtist, playerImpl.getUploaderName()); remoteViews.setTextViewText(R.id.notificationArtist, playerImpl.getUploaderName());
remoteViews.setImageViewBitmap(R.id.notificationCover, playerImpl.getThumbnail()); remoteViews.setImageViewBitmap(R.id.notificationCover, playerImpl.getThumbnail());
remoteViews.setOnClickPendingIntent(R.id.notificationPlayPause, remoteViews.setOnClickPendingIntent(R.id.notificationPlayPause,
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_PLAY_PAUSE), PendingIntent.FLAG_UPDATE_CURRENT)); PendingIntent.getBroadcast(this, NOTIFICATION_ID,
new Intent(ACTION_PLAY_PAUSE), PendingIntent.FLAG_UPDATE_CURRENT));
remoteViews.setOnClickPendingIntent(R.id.notificationStop, remoteViews.setOnClickPendingIntent(R.id.notificationStop,
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_CLOSE), PendingIntent.FLAG_UPDATE_CURRENT)); PendingIntent.getBroadcast(this, NOTIFICATION_ID,
new Intent(ACTION_CLOSE), PendingIntent.FLAG_UPDATE_CURRENT));
// Starts VideoDetailFragment or opens BackgroundPlayerActivity. // Starts VideoDetailFragment or opens BackgroundPlayerActivity.
remoteViews.setOnClickPendingIntent(R.id.notificationContent, remoteViews.setOnClickPendingIntent(R.id.notificationContent,
PendingIntent.getActivity(this, NOTIFICATION_ID, getIntentForNotification(), PendingIntent.FLAG_UPDATE_CURRENT)); PendingIntent.getActivity(this, NOTIFICATION_ID,
getIntentForNotification(), PendingIntent.FLAG_UPDATE_CURRENT));
remoteViews.setOnClickPendingIntent(R.id.notificationRepeat, remoteViews.setOnClickPendingIntent(R.id.notificationRepeat,
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_REPEAT), PendingIntent.FLAG_UPDATE_CURRENT)); PendingIntent.getBroadcast(this, NOTIFICATION_ID,
new Intent(ACTION_REPEAT), PendingIntent.FLAG_UPDATE_CURRENT));
if (playerImpl.playQueue != null && playerImpl.playQueue.size() > 1) { if (playerImpl.playQueue != null && playerImpl.playQueue.size() > 1) {
remoteViews.setInt(R.id.notificationFRewind, SET_IMAGE_RESOURCE_METHOD, R.drawable.exo_controls_previous); remoteViews.setInt(R.id.notificationFRewind, SET_IMAGE_RESOURCE_METHOD,
remoteViews.setInt(R.id.notificationFForward, SET_IMAGE_RESOURCE_METHOD, R.drawable.exo_controls_next); R.drawable.exo_controls_previous);
remoteViews.setInt(R.id.notificationFForward, SET_IMAGE_RESOURCE_METHOD,
R.drawable.exo_controls_next);
remoteViews.setOnClickPendingIntent(R.id.notificationFRewind, remoteViews.setOnClickPendingIntent(R.id.notificationFRewind,
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_PLAY_PREVIOUS), PendingIntent.FLAG_UPDATE_CURRENT)); PendingIntent.getBroadcast(this, NOTIFICATION_ID,
new Intent(ACTION_PLAY_PREVIOUS), PendingIntent.FLAG_UPDATE_CURRENT));
remoteViews.setOnClickPendingIntent(R.id.notificationFForward, remoteViews.setOnClickPendingIntent(R.id.notificationFForward,
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_PLAY_NEXT), PendingIntent.FLAG_UPDATE_CURRENT)); PendingIntent.getBroadcast(this, NOTIFICATION_ID,
new Intent(ACTION_PLAY_NEXT), PendingIntent.FLAG_UPDATE_CURRENT));
} else { } else {
remoteViews.setInt(R.id.notificationFRewind, SET_IMAGE_RESOURCE_METHOD, R.drawable.exo_controls_rewind); remoteViews.setInt(R.id.notificationFRewind, SET_IMAGE_RESOURCE_METHOD,
remoteViews.setInt(R.id.notificationFForward, SET_IMAGE_RESOURCE_METHOD, R.drawable.exo_controls_fastforward); R.drawable.exo_controls_rewind);
remoteViews.setInt(R.id.notificationFForward, SET_IMAGE_RESOURCE_METHOD,
R.drawable.exo_controls_fastforward);
remoteViews.setOnClickPendingIntent(R.id.notificationFRewind, remoteViews.setOnClickPendingIntent(R.id.notificationFRewind,
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_FAST_REWIND), PendingIntent.FLAG_UPDATE_CURRENT)); PendingIntent.getBroadcast(this, NOTIFICATION_ID,
new Intent(ACTION_FAST_REWIND), PendingIntent.FLAG_UPDATE_CURRENT));
remoteViews.setOnClickPendingIntent(R.id.notificationFForward, remoteViews.setOnClickPendingIntent(R.id.notificationFForward,
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_FAST_FORWARD), PendingIntent.FLAG_UPDATE_CURRENT)); PendingIntent.getBroadcast(this, NOTIFICATION_ID,
new Intent(ACTION_FAST_FORWARD), PendingIntent.FLAG_UPDATE_CURRENT));
} }
setRepeatModeIcon(remoteViews, playerImpl.getRepeatMode()); setRepeatModeIcon(remoteViews, playerImpl.getRepeatMode());
@ -340,10 +390,16 @@ public final class MainPlayer extends Service {
/*if (DEBUG) { /*if (DEBUG) {
Log.d(TAG, "updateNotification() called with: drawableId = [" + drawableId + "]"); Log.d(TAG, "updateNotification() called with: drawableId = [" + drawableId + "]");
}*/ }*/
if (notBuilder == null) return; if (notBuilder == null) {
return;
}
if (drawableId != -1) { if (drawableId != -1) {
if (notRemoteView != null) notRemoteView.setImageViewResource(R.id.notificationPlayPause, drawableId); if (notRemoteView != null) {
if (bigNotRemoteView != null) bigNotRemoteView.setImageViewResource(R.id.notificationPlayPause, drawableId); notRemoteView.setImageViewResource(R.id.notificationPlayPause, drawableId);
}
if (bigNotRemoteView != null) {
bigNotRemoteView.setImageViewResource(R.id.notificationPlayPause, drawableId);
}
} }
notificationManager.notify(NOTIFICATION_ID, notBuilder.build()); notificationManager.notify(NOTIFICATION_ID, notBuilder.build());
playerImpl.timesNotificationUpdated++; playerImpl.timesNotificationUpdated++;
@ -354,17 +410,22 @@ public final class MainPlayer extends Service {
//////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////*/
private void setRepeatModeIcon(final RemoteViews remoteViews, final int repeatMode) { private void setRepeatModeIcon(final RemoteViews remoteViews, final int repeatMode) {
if (remoteViews == null) return; if (remoteViews == null) {
return;
}
switch (repeatMode) { switch (repeatMode) {
case Player.REPEAT_MODE_OFF: case Player.REPEAT_MODE_OFF:
remoteViews.setInt(R.id.notificationRepeat, SET_IMAGE_RESOURCE_METHOD, R.drawable.exo_controls_repeat_off); remoteViews.setInt(R.id.notificationRepeat,
SET_IMAGE_RESOURCE_METHOD, R.drawable.exo_controls_repeat_off);
break; break;
case Player.REPEAT_MODE_ONE: case Player.REPEAT_MODE_ONE:
remoteViews.setInt(R.id.notificationRepeat, SET_IMAGE_RESOURCE_METHOD, R.drawable.exo_controls_repeat_one); remoteViews.setInt(R.id.notificationRepeat,
SET_IMAGE_RESOURCE_METHOD, R.drawable.exo_controls_repeat_one);
break; break;
case Player.REPEAT_MODE_ALL: case Player.REPEAT_MODE_ALL:
remoteViews.setInt(R.id.notificationRepeat, SET_IMAGE_RESOURCE_METHOD, R.drawable.exo_controls_repeat_all); remoteViews.setInt(R.id.notificationRepeat,
SET_IMAGE_RESOURCE_METHOD, R.drawable.exo_controls_repeat_all);
break; break;
} }
} }

View File

@ -914,7 +914,10 @@ public final class MainVideoPlayer extends AppCompatActivity
@Override @Override
public void onPlaybackSpeedClicked() { public void onPlaybackSpeedClicked() {
PlaybackParameterDialog PlaybackParameterDialog
.newInstance(getPlaybackSpeed(), getPlaybackPitch(), getPlaybackSkipSilence(), MainVideoPlayer.this) .newInstance(getPlaybackSpeed(),
getPlaybackPitch(),
getPlaybackSkipSilence(),
MainVideoPlayer.this)
.show(getSupportFragmentManager(), TAG); .show(getSupportFragmentManager(), TAG);
} }

View File

@ -584,7 +584,7 @@ public final class PopupVideoPlayer extends Service {
} }
@Override @Override
public void initViews(View rootView) { public void initViews(final View rootView) {
super.initViews(rootView); super.initViews(rootView);
resizingIndicator = rootView.findViewById(R.id.resizing_indicator); resizingIndicator = rootView.findViewById(R.id.resizing_indicator);
fullScreenButton = rootView.findViewById(R.id.fullScreenButton); fullScreenButton = rootView.findViewById(R.id.fullScreenButton);
@ -612,6 +612,7 @@ public final class PopupVideoPlayer extends Service {
} }
@Override @Override
@SuppressWarnings("checkstyle:ParameterNumber")
public void onLayoutChange(final View view, final int left, final int top, final int right, public void onLayoutChange(final View view, final int left, final int top, final int right,
final int bottom, final int oldLeft, final int oldTop, final int bottom, final int oldLeft, final int oldTop,
final int oldRight, final int oldBottom) { final int oldRight, final int oldBottom) {

View File

@ -61,7 +61,7 @@ public final class PopupVideoPlayerActivity extends ServicePlayerActivity {
} }
@Override @Override
public void setupMenu(Menu menu) { public void setupMenu(final Menu menu) {
} }

View File

@ -35,7 +35,12 @@ import org.schabi.newpipe.fragments.OnScrollBelowItemsListener;
import org.schabi.newpipe.local.dialog.PlaylistAppendDialog; import org.schabi.newpipe.local.dialog.PlaylistAppendDialog;
import org.schabi.newpipe.player.event.PlayerEventListener; import org.schabi.newpipe.player.event.PlayerEventListener;
import org.schabi.newpipe.player.helper.PlaybackParameterDialog; import org.schabi.newpipe.player.helper.PlaybackParameterDialog;
import org.schabi.newpipe.player.playqueue.*; import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.player.playqueue.PlayQueueAdapter;
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
import org.schabi.newpipe.player.playqueue.PlayQueueItemBuilder;
import org.schabi.newpipe.player.playqueue.PlayQueueItemHolder;
import org.schabi.newpipe.player.playqueue.PlayQueueItemTouchCallback;
import org.schabi.newpipe.util.Constants; import org.schabi.newpipe.util.Constants;
import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.NavigationHelper;
@ -109,7 +114,7 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
public abstract boolean onPlayerOptionSelected(MenuItem item); public abstract boolean onPlayerOptionSelected(MenuItem item);
public abstract void setupMenu(Menu menu); public abstract void setupMenu(Menu m);
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// Activity Lifecycle // Activity Lifecycle
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@ -153,9 +158,9 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
// Allow to setup visibility of menuItems // Allow to setup visibility of menuItems
@Override @Override
public boolean onPrepareOptionsMenu(Menu menu) { public boolean onPrepareOptionsMenu(final Menu m) {
setupMenu(menu); setupMenu(m);
return super.onPrepareOptionsMenu(menu); return super.onPrepareOptionsMenu(m);
} }
@Override @Override
@ -208,7 +213,8 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
.putExtra(Constants.KEY_LINK_TYPE, StreamingService.LinkType.STREAM) .putExtra(Constants.KEY_LINK_TYPE, StreamingService.LinkType.STREAM)
.putExtra(Constants.KEY_URL, this.player.getVideoUrl()) .putExtra(Constants.KEY_URL, this.player.getVideoUrl())
.putExtra(Constants.KEY_TITLE, this.player.getVideoTitle()) .putExtra(Constants.KEY_TITLE, this.player.getVideoTitle())
.putExtra(Constants.KEY_SERVICE_ID, this.player.getCurrentMetadata().getMetadata().getServiceId()) .putExtra(Constants.KEY_SERVICE_ID,
this.player.getCurrentMetadata().getMetadata().getServiceId())
.putExtra(VideoPlayer.PLAYER_TYPE, playerType); .putExtra(VideoPlayer.PLAYER_TYPE, playerType);
} }
@ -586,7 +592,7 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@Override @Override
public void onQueueUpdate(PlayQueue queue) { public void onQueueUpdate(final PlayQueue queue) {
} }
@Override @Override

View File

@ -34,9 +34,16 @@ import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import android.view.*;
import android.widget.*;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.PopupMenu;
import android.widget.ProgressBar;
import android.widget.SeekBar;
import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.content.res.AppCompatResources; import androidx.appcompat.content.res.AppCompatResources;
@ -63,7 +70,6 @@ import org.schabi.newpipe.player.resolver.MediaSourceTag;
import org.schabi.newpipe.player.resolver.VideoPlaybackResolver; import org.schabi.newpipe.player.resolver.VideoPlaybackResolver;
import org.schabi.newpipe.util.AnimationUtils; import org.schabi.newpipe.util.AnimationUtils;
import org.schabi.newpipe.views.ExpandableSurfaceView; import org.schabi.newpipe.views.ExpandableSurfaceView;
import org.schabi.newpipe.views.ExpandableSurfaceView;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;

View File

@ -24,16 +24,23 @@ public class CustomBottomSheetBehavior extends BottomSheetBehavior<FrameLayout>
Rect globalRect = new Rect(); Rect globalRect = new Rect();
private boolean skippingInterception = false; private boolean skippingInterception = false;
private final List<Integer> skipInterceptionOfElements = Arrays.asList( private final List<Integer> skipInterceptionOfElements = Arrays.asList(
R.id.detail_content_root_layout, R.id.relatedStreamsLayout, R.id.playQueuePanel, R.id.viewpager); R.id.detail_content_root_layout, R.id.relatedStreamsLayout,
R.id.playQueuePanel, R.id.viewpager);
@Override @Override
public boolean onInterceptTouchEvent(@NonNull CoordinatorLayout parent, @NonNull FrameLayout child, MotionEvent event) { public boolean onInterceptTouchEvent(@NonNull final CoordinatorLayout parent,
@NonNull final FrameLayout child,
final MotionEvent event) {
// Drop following when action ends // Drop following when action ends
if (event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_UP) if (event.getAction() == MotionEvent.ACTION_CANCEL
|| event.getAction() == MotionEvent.ACTION_UP) {
skippingInterception = false; skippingInterception = false;
}
// Found that user still swiping, continue following // Found that user still swiping, continue following
if (skippingInterception) return false; if (skippingInterception) {
return false;
}
// Don't need to do anything if bottomSheet isn't expanded // Don't need to do anything if bottomSheet isn't expanded
if (getState() == BottomSheetBehavior.STATE_EXPANDED) { if (getState() == BottomSheetBehavior.STATE_EXPANDED) {
@ -42,7 +49,8 @@ public class CustomBottomSheetBehavior extends BottomSheetBehavior<FrameLayout>
final ViewGroup viewGroup = child.findViewById(element); final ViewGroup viewGroup = child.findViewById(element);
if (viewGroup != null) { if (viewGroup != null) {
visible = viewGroup.getGlobalVisibleRect(globalRect); visible = viewGroup.getGlobalVisibleRect(globalRect);
if (visible && globalRect.contains((int) event.getRawX(), (int) event.getRawY())) { if (visible
&& globalRect.contains((int) event.getRawX(), (int) event.getRawY())) {
skippingInterception = true; skippingInterception = true;
return false; return false;
} }

View File

@ -1,5 +1,5 @@
package org.schabi.newpipe.player.event; package org.schabi.newpipe.player.event;
public interface OnKeyDownListener { public interface OnKeyDownListener {
boolean onKeyDown(final int keyCode); boolean onKeyDown(int keyCode);
} }

View File

@ -3,7 +3,12 @@ package org.schabi.newpipe.player.event;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.util.Log; import android.util.Log;
import android.view.*; import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.Window;
import android.view.WindowManager;
import androidx.appcompat.content.res.AppCompatResources; import androidx.appcompat.content.res.AppCompatResources;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;
import org.schabi.newpipe.player.BasePlayer; import org.schabi.newpipe.player.BasePlayer;
@ -11,22 +16,26 @@ import org.schabi.newpipe.player.MainPlayer;
import org.schabi.newpipe.player.VideoPlayerImpl; import org.schabi.newpipe.player.VideoPlayerImpl;
import org.schabi.newpipe.player.helper.PlayerHelper; import org.schabi.newpipe.player.helper.PlayerHelper;
import static org.schabi.newpipe.player.BasePlayer.*; import static org.schabi.newpipe.player.BasePlayer.STATE_PLAYING;
import static org.schabi.newpipe.player.VideoPlayer.DEFAULT_CONTROLS_DURATION; import static org.schabi.newpipe.player.VideoPlayer.DEFAULT_CONTROLS_DURATION;
import static org.schabi.newpipe.player.VideoPlayer.DEFAULT_CONTROLS_HIDE_TIME; import static org.schabi.newpipe.player.VideoPlayer.DEFAULT_CONTROLS_HIDE_TIME;
import static org.schabi.newpipe.util.AnimationUtils.Type.SCALE_AND_ALPHA; import static org.schabi.newpipe.util.AnimationUtils.Type.SCALE_AND_ALPHA;
import static org.schabi.newpipe.util.AnimationUtils.animateView; import static org.schabi.newpipe.util.AnimationUtils.animateView;
public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListener implements View.OnTouchListener { public class PlayerGestureListener
extends GestureDetector.SimpleOnGestureListener
implements View.OnTouchListener {
private static final String TAG = ".PlayerGestureListener"; private static final String TAG = ".PlayerGestureListener";
private static final boolean DEBUG = BasePlayer.DEBUG; private static final boolean DEBUG = BasePlayer.DEBUG;
private final VideoPlayerImpl playerImpl; private final VideoPlayerImpl playerImpl;
private final MainPlayer service; private final MainPlayer service;
private int initialPopupX, initialPopupY; private int initialPopupX;
private int initialPopupY;
private boolean isMovingInMain, isMovingInPopup; private boolean isMovingInMain;
private boolean isMovingInPopup;
private boolean isResizing; private boolean isResizing;
@ -64,56 +73,92 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen
* So it will be better to have different implementations of them * So it will be better to have different implementations of them
* */ * */
@Override @Override
public boolean onDoubleTap(MotionEvent e) { public boolean onDoubleTap(final MotionEvent e) {
if (DEBUG) Log.d(TAG, "onDoubleTap() called with: e = [" + e + "]" + "rawXy = " + e.getRawX() + ", " + e.getRawY() + ", xy = " + e.getX() + ", " + e.getY()); if (DEBUG) {
Log.d(TAG, "onDoubleTap() called with: e = [" + e + "]" + "rawXy = "
+ e.getRawX() + ", " + e.getRawY() + ", xy = " + e.getX() + ", " + e.getY());
}
if (playerImpl.popupPlayerSelected()) return onDoubleTapInPopup(e); if (playerImpl.popupPlayerSelected()) {
else return onDoubleTapInMain(e); return onDoubleTapInPopup(e);
} else {
return onDoubleTapInMain(e);
}
} }
@Override @Override
public boolean onSingleTapConfirmed(MotionEvent e) { public boolean onSingleTapConfirmed(final MotionEvent e) {
if (DEBUG) Log.d(TAG, "onSingleTapConfirmed() called with: e = [" + e + "]"); if (DEBUG) {
Log.d(TAG, "onSingleTapConfirmed() called with: e = [" + e + "]");
}
if (playerImpl.popupPlayerSelected()) return onSingleTapConfirmedInPopup(e); if (playerImpl.popupPlayerSelected()) {
else return onSingleTapConfirmedInMain(e); return onSingleTapConfirmedInPopup(e);
} else {
return onSingleTapConfirmedInMain(e);
}
} }
@Override @Override
public boolean onDown(MotionEvent e) { public boolean onDown(final MotionEvent e) {
if (DEBUG) Log.d(TAG, "onDown() called with: e = [" + e + "]"); if (DEBUG) {
Log.d(TAG, "onDown() called with: e = [" + e + "]");
if (playerImpl.popupPlayerSelected()) return onDownInPopup(e);
else return true;
} }
@Override
public void onLongPress(MotionEvent e) {
if (DEBUG) Log.d(TAG, "onLongPress() called with: e = [" + e + "]");
if (playerImpl.popupPlayerSelected()) onLongPressInPopup(e); if (playerImpl.popupPlayerSelected()) {
return onDownInPopup(e);
} else {
return true;
}
} }
@Override @Override
public boolean onScroll(MotionEvent initialEvent, MotionEvent movingEvent, float distanceX, float distanceY) { public void onLongPress(final MotionEvent e) {
if (playerImpl.popupPlayerSelected()) return onScrollInPopup(initialEvent, movingEvent, distanceX, distanceY); if (DEBUG) {
else return onScrollInMain(initialEvent, movingEvent, distanceX, distanceY); Log.d(TAG, "onLongPress() called with: e = [" + e + "]");
}
if (playerImpl.popupPlayerSelected()) {
onLongPressInPopup(e);
}
} }
@Override @Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { public boolean onScroll(final MotionEvent initialEvent, final MotionEvent movingEvent,
if (DEBUG) Log.d(TAG, "onFling() called with velocity: dX=[" + velocityX + "], dY=[" + velocityY + "]"); final float distanceX, final float distanceY) {
if (playerImpl.popupPlayerSelected()) {
if (playerImpl.popupPlayerSelected()) return onFlingInPopup(e1, e2, velocityX, velocityY); return onScrollInPopup(initialEvent, movingEvent, distanceX, distanceY);
else return true; } else {
return onScrollInMain(initialEvent, movingEvent, distanceX, distanceY);
}
} }
@Override @Override
public boolean onTouch(View v, MotionEvent event) { public boolean onFling(final MotionEvent e1, final MotionEvent e2,
//noinspection PointlessBooleanExpression,ConstantConditions final float velocityX, final float velocityY) {
if (DEBUG && false) Log.d(TAG, "onTouch() called with: v = [" + v + "], event = [" + event + "]"); if (DEBUG) {
Log.d(TAG, "onFling() called with velocity: dX=["
+ velocityX + "], dY=[" + velocityY + "]");
}
if (playerImpl.popupPlayerSelected()) return onTouchInPopup(v, event); if (playerImpl.popupPlayerSelected()) {
else return onTouchInMain(v, event); return onFlingInPopup(e1, e2, velocityX, velocityY);
} else {
return true;
}
}
@Override
public boolean onTouch(final View v, final MotionEvent event) {
/*if (DEBUG && false) {
Log.d(TAG, "onTouch() called with: v = [" + v + "], event = [" + event + "]");
}*/
if (playerImpl.popupPlayerSelected()) {
return onTouchInPopup(v, event);
} else {
return onTouchInMain(v, event);
}
} }
@ -121,7 +166,7 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen
// Main player listener // Main player listener
//////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////*/
private boolean onDoubleTapInMain(MotionEvent e) { private boolean onDoubleTapInMain(final MotionEvent e) {
if (e.getX() > playerImpl.getRootView().getWidth() * 2.0 / 3.0) { if (e.getX() > playerImpl.getRootView().getWidth() * 2.0 / 3.0) {
playerImpl.onFastForward(); playerImpl.onFastForward();
} else if (e.getX() < playerImpl.getRootView().getWidth() / 3.0) { } else if (e.getX() < playerImpl.getRootView().getWidth() / 3.0) {
@ -134,10 +179,14 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen
} }
private boolean onSingleTapConfirmedInMain(MotionEvent e) { private boolean onSingleTapConfirmedInMain(final MotionEvent e) {
if (DEBUG) Log.d(TAG, "onSingleTapConfirmed() called with: e = [" + e + "]"); if (DEBUG) {
Log.d(TAG, "onSingleTapConfirmed() called with: e = [" + e + "]");
}
if (playerImpl.getCurrentState() == BasePlayer.STATE_BLOCKED) return true; if (playerImpl.getCurrentState() == BasePlayer.STATE_BLOCKED) {
return true;
}
if (playerImpl.isControlsVisible()) { if (playerImpl.isControlsVisible()) {
playerImpl.hideControls(150, 0); playerImpl.hideControls(150, 0);
@ -153,7 +202,9 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen
private boolean onScrollInMain(final MotionEvent initialEvent, final MotionEvent movingEvent, private boolean onScrollInMain(final MotionEvent initialEvent, final MotionEvent movingEvent,
final float distanceX, final float distanceY) { final float distanceX, final float distanceY) {
if (!isVolumeGestureEnabled && !isBrightnessGestureEnabled) return false; if (!isVolumeGestureEnabled && !isBrightnessGestureEnabled) {
return false;
}
final boolean isTouchingStatusBar = initialEvent.getY() < getStatusBarHeight(service); final boolean isTouchingStatusBar = initialEvent.getY() < getStatusBarHeight(service);
final boolean isTouchingNavigationBar = initialEvent.getY() final boolean isTouchingNavigationBar = initialEvent.getY()
@ -167,7 +218,8 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen
", e2.getRaw = [" + movingEvent.getRawX() + ", " + movingEvent.getRawY() + "]" + ", e2.getRaw = [" + movingEvent.getRawX() + ", " + movingEvent.getRawY() + "]" +
", distanceXy = [" + distanceX + ", " + distanceY + "]");*/ ", distanceXy = [" + distanceX + ", " + distanceY + "]");*/
final boolean insideThreshold = Math.abs(movingEvent.getY() - initialEvent.getY()) <= MOVEMENT_THRESHOLD; final boolean insideThreshold =
Math.abs(movingEvent.getY() - initialEvent.getY()) <= MOVEMENT_THRESHOLD;
if (!isMovingInMain && (insideThreshold || Math.abs(distanceX) > Math.abs(distanceY)) if (!isMovingInMain && (insideThreshold || Math.abs(distanceX) > Math.abs(distanceY))
|| playerImpl.getCurrentState() == BasePlayer.STATE_COMPLETED) { || playerImpl.getCurrentState() == BasePlayer.STATE_COMPLETED) {
return false; return false;
@ -181,15 +233,18 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen
if (isVolumeGestureEnabled && acceptVolumeArea) { if (isVolumeGestureEnabled && acceptVolumeArea) {
playerImpl.getVolumeProgressBar().incrementProgressBy((int) distanceY); playerImpl.getVolumeProgressBar().incrementProgressBy((int) distanceY);
final float currentProgressPercent = final float currentProgressPercent = (float) playerImpl
(float) playerImpl.getVolumeProgressBar().getProgress() / playerImpl.getMaxGestureLength(); .getVolumeProgressBar().getProgress() / playerImpl.getMaxGestureLength();
final int currentVolume = (int) (maxVolume * currentProgressPercent); final int currentVolume = (int) (maxVolume * currentProgressPercent);
playerImpl.getAudioReactor().setVolume(currentVolume); playerImpl.getAudioReactor().setVolume(currentVolume);
if (DEBUG) Log.d(TAG, "onScroll().volumeControl, currentVolume = " + currentVolume); if (DEBUG) {
Log.d(TAG, "onScroll().volumeControl, currentVolume = " + currentVolume);
}
playerImpl.getVolumeImageView().setImageDrawable( playerImpl.getVolumeImageView().setImageDrawable(
AppCompatResources.getDrawable(service, currentProgressPercent <= 0 ? R.drawable.ic_volume_off_white_24dp AppCompatResources.getDrawable(service, currentProgressPercent <= 0
? R.drawable.ic_volume_off_white_24dp
: currentProgressPercent < 0.25 ? R.drawable.ic_volume_mute_white_24dp : currentProgressPercent < 0.25 ? R.drawable.ic_volume_mute_white_24dp
: currentProgressPercent < 0.75 ? R.drawable.ic_volume_down_white_24dp : currentProgressPercent < 0.75 ? R.drawable.ic_volume_down_white_24dp
: R.drawable.ic_volume_up_white_24dp) : R.drawable.ic_volume_up_white_24dp)
@ -203,23 +258,30 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen
} }
} else { } else {
final Activity parent = playerImpl.getParentActivity(); final Activity parent = playerImpl.getParentActivity();
if (parent == null) return true; if (parent == null) {
return true;
}
final Window window = parent.getWindow(); final Window window = parent.getWindow();
playerImpl.getBrightnessProgressBar().incrementProgressBy((int) distanceY); playerImpl.getBrightnessProgressBar().incrementProgressBy((int) distanceY);
final float currentProgressPercent = final float currentProgressPercent = (float) playerImpl.getBrightnessProgressBar()
(float) playerImpl.getBrightnessProgressBar().getProgress() / playerImpl.getMaxGestureLength(); .getProgress() / playerImpl.getMaxGestureLength();
final WindowManager.LayoutParams layoutParams = window.getAttributes(); final WindowManager.LayoutParams layoutParams = window.getAttributes();
layoutParams.screenBrightness = currentProgressPercent; layoutParams.screenBrightness = currentProgressPercent;
window.setAttributes(layoutParams); window.setAttributes(layoutParams);
if (DEBUG) Log.d(TAG, "onScroll().brightnessControl, currentBrightness = " + currentProgressPercent); if (DEBUG) {
Log.d(TAG, "onScroll().brightnessControl, "
+ "currentBrightness = " + currentProgressPercent);
}
playerImpl.getBrightnessImageView().setImageDrawable( playerImpl.getBrightnessImageView().setImageDrawable(
AppCompatResources.getDrawable(service, AppCompatResources.getDrawable(service,
currentProgressPercent < 0.25 ? R.drawable.ic_brightness_low_white_24dp currentProgressPercent < 0.25
: currentProgressPercent < 0.75 ? R.drawable.ic_brightness_medium_white_24dp ? R.drawable.ic_brightness_low_white_24dp
: currentProgressPercent < 0.75
? R.drawable.ic_brightness_medium_white_24dp
: R.drawable.ic_brightness_high_white_24dp) : R.drawable.ic_brightness_high_white_24dp)
); );
@ -234,7 +296,9 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen
} }
private void onScrollEndInMain() { private void onScrollEndInMain() {
if (DEBUG) Log.d(TAG, "onScrollEnd() called"); if (DEBUG) {
Log.d(TAG, "onScrollEnd() called");
}
if (playerImpl.getVolumeRelativeLayout().getVisibility() == View.VISIBLE) { if (playerImpl.getVolumeRelativeLayout().getVisibility() == View.VISIBLE) {
animateView(playerImpl.getVolumeRelativeLayout(), SCALE_AND_ALPHA, false, 200, 200); animateView(playerImpl.getVolumeRelativeLayout(), SCALE_AND_ALPHA, false, 200, 200);
@ -248,13 +312,14 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen
} }
} }
private boolean onTouchInMain(View v, MotionEvent event) { private boolean onTouchInMain(final View v, final MotionEvent event) {
playerImpl.getGestureDetector().onTouchEvent(event); playerImpl.getGestureDetector().onTouchEvent(event);
if (event.getAction() == MotionEvent.ACTION_UP && isMovingInMain) { if (event.getAction() == MotionEvent.ACTION_UP && isMovingInMain) {
isMovingInMain = false; isMovingInMain = false;
onScrollEndInMain(); onScrollEndInMain();
} }
// This hack allows to stop receiving touch events on appbar while touching video player view // This hack allows to stop receiving touch events on appbar
// while touching video player's view
switch (event.getAction()) { switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_MOVE:
@ -272,8 +337,10 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen
// Popup player listener // Popup player listener
//////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////*/
private boolean onDoubleTapInPopup(MotionEvent e) { private boolean onDoubleTapInPopup(final MotionEvent e) {
if (playerImpl == null || !playerImpl.isPlaying()) return false; if (playerImpl == null || !playerImpl.isPlaying()) {
return false;
}
playerImpl.hideControls(0, 0); playerImpl.hideControls(0, 0);
@ -286,8 +353,10 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen
return true; return true;
} }
private boolean onSingleTapConfirmedInPopup(MotionEvent e) { private boolean onSingleTapConfirmedInPopup(final MotionEvent e) {
if (playerImpl == null || playerImpl.getPlayer() == null) return false; if (playerImpl == null || playerImpl.getPlayer() == null) {
return false;
}
if (playerImpl.isControlsVisible()) { if (playerImpl.isControlsVisible()) {
playerImpl.hideControls(100, 100); playerImpl.hideControls(100, 100);
} else { } else {
@ -297,7 +366,7 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen
return true; return true;
} }
private boolean onDownInPopup(MotionEvent e) { private boolean onDownInPopup(final MotionEvent e) {
// Fix popup position when the user touch it, it may have the wrong one // Fix popup position when the user touch it, it may have the wrong one
// because the soft input is visible (the draggable area is currently resized). // because the soft input is visible (the draggable area is currently resized).
playerImpl.updateScreenSize(); playerImpl.updateScreenSize();
@ -310,14 +379,19 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen
return super.onDown(e); return super.onDown(e);
} }
private void onLongPressInPopup(MotionEvent e) { private void onLongPressInPopup(final MotionEvent e) {
playerImpl.updateScreenSize(); playerImpl.updateScreenSize();
playerImpl.checkPopupPositionBounds(); playerImpl.checkPopupPositionBounds();
playerImpl.updatePopupSize((int) playerImpl.getScreenWidth(), -1); playerImpl.updatePopupSize((int) playerImpl.getScreenWidth(), -1);
} }
private boolean onScrollInPopup(MotionEvent initialEvent, MotionEvent movingEvent, float distanceX, float distanceY) { private boolean onScrollInPopup(final MotionEvent initialEvent,
if (isResizing || playerImpl == null) return super.onScroll(initialEvent, movingEvent, distanceX, distanceY); final MotionEvent movingEvent,
final float distanceX,
final float distanceY) {
if (isResizing || playerImpl == null) {
return super.onScroll(initialEvent, movingEvent, distanceX, distanceY);
}
if (!isMovingInPopup) { if (!isMovingInPopup) {
animateView(playerImpl.getCloseOverlayButton(), true, 200); animateView(playerImpl.getCloseOverlayButton(), true, 200);
@ -369,12 +443,15 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen
// + "posX,Y = [" + posX + ", " + posY + "], " // + "posX,Y = [" + posX + ", " + posY + "], "
// + "popupW,H = [" + popupWidth + " x " + popupHeight + "]"); // + "popupW,H = [" + popupWidth + " x " + popupHeight + "]");
// } // }
playerImpl.windowManager.updateViewLayout(playerImpl.getRootView(), playerImpl.getPopupLayoutParams()); playerImpl.windowManager
.updateViewLayout(playerImpl.getRootView(), playerImpl.getPopupLayoutParams());
return true; return true;
} }
private void onScrollEndInPopup(MotionEvent event) { private void onScrollEndInPopup(final MotionEvent event) {
if (playerImpl == null) return; if (playerImpl == null) {
return;
}
if (playerImpl.isControlsVisible() && playerImpl.getCurrentState() == STATE_PLAYING) { if (playerImpl.isControlsVisible() && playerImpl.getCurrentState() == STATE_PLAYING) {
playerImpl.hideControls(DEFAULT_CONTROLS_DURATION, DEFAULT_CONTROLS_HIDE_TIME); playerImpl.hideControls(DEFAULT_CONTROLS_DURATION, DEFAULT_CONTROLS_HIDE_TIME);
} }
@ -390,29 +467,41 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen
} }
} }
private boolean onFlingInPopup(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { private boolean onFlingInPopup(final MotionEvent e1,
if (playerImpl == null) return false; final MotionEvent e2,
final float velocityX,
final float velocityY) {
if (playerImpl == null) {
return false;
}
final float absVelocityX = Math.abs(velocityX); final float absVelocityX = Math.abs(velocityX);
final float absVelocityY = Math.abs(velocityY); final float absVelocityY = Math.abs(velocityY);
if (Math.max(absVelocityX, absVelocityY) > tossFlingVelocity) { if (Math.max(absVelocityX, absVelocityY) > tossFlingVelocity) {
if (absVelocityX > tossFlingVelocity) playerImpl.getPopupLayoutParams().x = (int) velocityX; if (absVelocityX > tossFlingVelocity) {
if (absVelocityY > tossFlingVelocity) playerImpl.getPopupLayoutParams().y = (int) velocityY; playerImpl.getPopupLayoutParams().x = (int) velocityX;
}
if (absVelocityY > tossFlingVelocity) {
playerImpl.getPopupLayoutParams().y = (int) velocityY;
}
playerImpl.checkPopupPositionBounds(); playerImpl.checkPopupPositionBounds();
playerImpl.windowManager.updateViewLayout(playerImpl.getRootView(), playerImpl.getPopupLayoutParams()); playerImpl.windowManager
.updateViewLayout(playerImpl.getRootView(), playerImpl.getPopupLayoutParams());
return true; return true;
} }
return false; return false;
} }
private boolean onTouchInPopup(View v, MotionEvent event) { private boolean onTouchInPopup(final View v, final MotionEvent event) {
if (playerImpl == null) { if (playerImpl == null) {
return false; return false;
} }
playerImpl.getGestureDetector().onTouchEvent(event); playerImpl.getGestureDetector().onTouchEvent(event);
if (event.getPointerCount() == 2 && !isMovingInPopup && !isResizing) { if (event.getPointerCount() == 2 && !isMovingInPopup && !isResizing) {
if (DEBUG) Log.d(TAG, "onTouch() 2 finger pointer detected, enabling resizing."); if (DEBUG) {
Log.d(TAG, "onTouch() 2 finger pointer detected, enabling resizing.");
}
playerImpl.showAndAnimateControl(-1, true); playerImpl.showAndAnimateControl(-1, true);
playerImpl.getLoadingPanel().setVisibility(View.GONE); playerImpl.getLoadingPanel().setVisibility(View.GONE);
@ -432,13 +521,18 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen
} }
if (event.getAction() == MotionEvent.ACTION_MOVE && !isMovingInPopup && isResizing) { if (event.getAction() == MotionEvent.ACTION_MOVE && !isMovingInPopup && isResizing) {
if (DEBUG) Log.d(TAG, "onTouch() ACTION_MOVE > v = [" + v + "], e1.getRaw = [" + event.getRawX() + ", " + event.getRawY() + "]"); if (DEBUG) {
Log.d(TAG, "onTouch() ACTION_MOVE > v = [" + v + "], "
+ "e1.getRaw = [" + event.getRawX() + ", " + event.getRawY() + "]");
}
return handleMultiDrag(event); return handleMultiDrag(event);
} }
if (event.getAction() == MotionEvent.ACTION_UP) { if (event.getAction() == MotionEvent.ACTION_UP) {
if (DEBUG) if (DEBUG) {
Log.d(TAG, "onTouch() ACTION_UP > v = [" + v + "], e1.getRaw = [" + event.getRawX() + ", " + event.getRawY() + "]"); Log.d(TAG, "onTouch() ACTION_UP > v = [" + v + "], "
+ "e1.getRaw = [" + event.getRawX() + ", " + event.getRawY() + "]");
}
if (isMovingInPopup) { if (isMovingInPopup) {
isMovingInPopup = false; isMovingInPopup = false;
onScrollEndInPopup(event); onScrollEndInPopup(event);
@ -492,7 +586,9 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen
playerImpl.checkPopupPositionBounds(); playerImpl.checkPopupPositionBounds();
playerImpl.updateScreenSize(); playerImpl.updateScreenSize();
playerImpl.updatePopupSize((int) Math.min(playerImpl.getScreenWidth(), newWidth), -1); playerImpl.updatePopupSize(
(int) Math.min(playerImpl.getScreenWidth(), newWidth),
-1);
return true; return true;
} }
} }
@ -504,16 +600,18 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen
* Utils * Utils
* */ * */
private int getNavigationBarHeight(Context context) { private int getNavigationBarHeight(final Context context) {
int resId = context.getResources().getIdentifier("navigation_bar_height", "dimen", "android"); int resId = context.getResources()
.getIdentifier("navigation_bar_height", "dimen", "android");
if (resId > 0) { if (resId > 0) {
return context.getResources().getDimensionPixelSize(resId); return context.getResources().getDimensionPixelSize(resId);
} }
return 0; return 0;
} }
private int getStatusBarHeight(Context context) { private int getStatusBarHeight(final Context context) {
int resId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); int resId = context.getResources()
.getIdentifier("status_bar_height", "dimen", "android");
if (resId > 0) { if (resId > 0) {
return context.getResources().getDimensionPixelSize(resId); return context.getResources().getDimensionPixelSize(resId);
} }

View File

@ -93,7 +93,7 @@ public class PlaybackParameterDialog extends DialogFragment {
public static PlaybackParameterDialog newInstance(final double playbackTempo, public static PlaybackParameterDialog newInstance(final double playbackTempo,
final double playbackPitch, final double playbackPitch,
final boolean playbackSkipSilence, final boolean playbackSkipSilence,
Callback callback) { final Callback callback) {
PlaybackParameterDialog dialog = new PlaybackParameterDialog(); PlaybackParameterDialog dialog = new PlaybackParameterDialog();
dialog.callback = callback; dialog.callback = callback;
dialog.initialTempo = playbackTempo; dialog.initialTempo = playbackTempo;

View File

@ -217,7 +217,8 @@ public final class PlayerHelper {
} }
public static boolean isClearingQueueConfirmationRequired(@NonNull final Context context) { public static boolean isClearingQueueConfirmationRequired(@NonNull final Context context) {
return getPreferences(context).getBoolean(context.getString(R.string.clear_queue_confirmation_key), false); return getPreferences(context)
.getBoolean(context.getString(R.string.clear_queue_confirmation_key), false);
} }
@MinimizeMode @MinimizeMode
@ -353,7 +354,7 @@ public final class PlayerHelper {
setScreenBrightness(context, setScreenBrightness, System.currentTimeMillis()); setScreenBrightness(context, setScreenBrightness, System.currentTimeMillis());
} }
public static boolean globalScreenOrientationLocked(Context context) { public static boolean globalScreenOrientationLocked(final Context context) {
// 1: Screen orientation changes using accelerometer // 1: Screen orientation changes using accelerometer
// 0: Screen orientation is locked // 0: Screen orientation is locked
return android.provider.Settings.System.getInt( return android.provider.Settings.System.getInt(
@ -361,7 +362,9 @@ public final class PlayerHelper {
} }
public static boolean isTablet(@NonNull final Context context) { public static boolean isTablet(@NonNull final Context context) {
return (context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) return (context
.getResources()
.getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE; >= Configuration.SCREENLAYOUT_SIZE_LARGE;
} }

View File

@ -63,7 +63,9 @@ public abstract class PlayQueue implements Serializable {
streams = new ArrayList<>(); streams = new ArrayList<>();
streams.addAll(startWith); streams.addAll(startWith);
history = new ArrayList<>(); history = new ArrayList<>();
if (streams.size() > index) history.add(streams.get(index)); if (streams.size() > index) {
history.add(streams.get(index));
}
queueIndex = new AtomicInteger(index); queueIndex = new AtomicInteger(index);
disposed = false; disposed = false;
@ -156,7 +158,9 @@ public abstract class PlayQueue implements Serializable {
if (index >= streams.size()) { if (index >= streams.size()) {
newIndex = isComplete() ? index % streams.size() : streams.size() - 1; newIndex = isComplete() ? index % streams.size() : streams.size() - 1;
} }
if (oldIndex != newIndex) history.add(streams.get(newIndex)); if (oldIndex != newIndex) {
history.add(streams.get(newIndex));
}
queueIndex.set(newIndex); queueIndex.set(newIndex);
broadcast(new SelectEvent(oldIndex, newIndex)); broadcast(new SelectEvent(oldIndex, newIndex));
@ -484,15 +488,17 @@ public abstract class PlayQueue implements Serializable {
} }
/** /**
* Selects previous played item * Selects previous played item.
* *
* This method removes currently playing item from history and * This method removes currently playing item from history and
* starts playing the last item from history if it exists * starts playing the last item from history if it exists
* *
* Returns true if history is not empty and the item can be played * @return true if history is not empty and the item can be played
* */ * */
public synchronized boolean previous() { public synchronized boolean previous() {
if (history.size() <= 1) return false; if (history.size() <= 1) {
return false;
}
history.remove(history.size() - 1); history.remove(history.size() - 1);
@ -504,19 +510,23 @@ public abstract class PlayQueue implements Serializable {
/* /*
* Compares two PlayQueues. Useful when a user switches players but queue is the same so * Compares two PlayQueues. Useful when a user switches players but queue is the same so
* we don't have to do anything with new queue. This method also gives a chance to track history of items in a queue in * we don't have to do anything with new queue.
* This method also gives a chance to track history of items in a queue in
* VideoDetailFragment without duplicating items from two identical queues * VideoDetailFragment without duplicating items from two identical queues
* */ * */
@Override @Override
public boolean equals(@Nullable final Object obj) { public boolean equals(@Nullable final Object obj) {
if (!(obj instanceof PlayQueue) || getStreams().size() != ((PlayQueue) obj).getStreams().size()) if (!(obj instanceof PlayQueue)
|| getStreams().size() != ((PlayQueue) obj).getStreams().size()) {
return false; return false;
}
final PlayQueue other = (PlayQueue) obj; final PlayQueue other = (PlayQueue) obj;
for (int i = 0; i < getStreams().size(); i++) { for (int i = 0; i < getStreams().size(); i++) {
if (!getItem(i).getUrl().equals(other.getItem(i).getUrl())) if (!getItem(i).getUrl().equals(other.getItem(i).getUrl())) {
return false; return false;
} }
}
return true; return true;
} }

View File

@ -47,7 +47,10 @@ import org.schabi.newpipe.local.history.StatisticsPlaylistFragment;
import org.schabi.newpipe.local.playlist.LocalPlaylistFragment; import org.schabi.newpipe.local.playlist.LocalPlaylistFragment;
import org.schabi.newpipe.local.subscription.SubscriptionFragment; import org.schabi.newpipe.local.subscription.SubscriptionFragment;
import org.schabi.newpipe.local.subscription.SubscriptionsImportFragment; import org.schabi.newpipe.local.subscription.SubscriptionsImportFragment;
import org.schabi.newpipe.player.*; import org.schabi.newpipe.player.BackgroundPlayerActivity;
import org.schabi.newpipe.player.BasePlayer;
import org.schabi.newpipe.player.MainPlayer;
import org.schabi.newpipe.player.VideoPlayer;
import org.schabi.newpipe.player.playqueue.PlayQueue; import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.player.playqueue.PlayQueueItem; import org.schabi.newpipe.player.playqueue.PlayQueueItem;
import org.schabi.newpipe.settings.SettingsActivity; import org.schabi.newpipe.settings.SettingsActivity;
@ -174,8 +177,11 @@ public final class NavigationHelper {
startService(context, intent); startService(context, intent);
} }
public static void playOnBackgroundPlayer(final Context context, final PlayQueue queue, final boolean resumePlayback) { public static void playOnBackgroundPlayer(final Context context,
Toast.makeText(context, R.string.background_player_playing_toast, Toast.LENGTH_SHORT).show(); final PlayQueue queue,
final boolean resumePlayback) {
Toast.makeText(context, R.string.background_player_playing_toast, Toast.LENGTH_SHORT)
.show();
final Intent intent = getPlayerIntent(context, MainPlayer.class, queue, resumePlayback); final Intent intent = getPlayerIntent(context, MainPlayer.class, queue, resumePlayback);
intent.putExtra(VideoPlayer.PLAYER_TYPE, VideoPlayer.PLAYER_TYPE_AUDIO); intent.putExtra(VideoPlayer.PLAYER_TYPE, VideoPlayer.PLAYER_TYPE_AUDIO);
startService(context, intent); startService(context, intent);
@ -195,7 +201,8 @@ public final class NavigationHelper {
} }
Toast.makeText(context, R.string.popup_playing_append, Toast.LENGTH_SHORT).show(); Toast.makeText(context, R.string.popup_playing_append, Toast.LENGTH_SHORT).show();
final Intent intent = getPlayerEnqueueIntent(context, MainPlayer.class, queue, selectOnAppend, resumePlayback); final Intent intent = getPlayerEnqueueIntent(
context, MainPlayer.class, queue, selectOnAppend, resumePlayback);
intent.putExtra(VideoPlayer.PLAYER_TYPE, VideoPlayer.PLAYER_TYPE_POPUP); intent.putExtra(VideoPlayer.PLAYER_TYPE, VideoPlayer.PLAYER_TYPE_POPUP);
startService(context, intent); startService(context, intent);
} }
@ -205,10 +212,13 @@ public final class NavigationHelper {
enqueueOnBackgroundPlayer(context, queue, false, resumePlayback); enqueueOnBackgroundPlayer(context, queue, false, resumePlayback);
} }
public static void enqueueOnBackgroundPlayer(final Context context, final PlayQueue queue, final boolean selectOnAppend, public static void enqueueOnBackgroundPlayer(final Context context,
final PlayQueue queue,
final boolean selectOnAppend,
final boolean resumePlayback) { final boolean resumePlayback) {
Toast.makeText(context, R.string.background_player_append, Toast.LENGTH_SHORT).show(); Toast.makeText(context, R.string.background_player_append, Toast.LENGTH_SHORT).show();
final Intent intent = getPlayerEnqueueIntent(context, MainPlayer.class, queue, selectOnAppend, resumePlayback); final Intent intent = getPlayerEnqueueIntent(
context, MainPlayer.class, queue, selectOnAppend, resumePlayback);
intent.putExtra(VideoPlayer.PLAYER_TYPE, VideoPlayer.PLAYER_TYPE_AUDIO); intent.putExtra(VideoPlayer.PLAYER_TYPE, VideoPlayer.PLAYER_TYPE_AUDIO);
startService(context, intent); startService(context, intent);
} }
@ -357,12 +367,14 @@ public final class NavigationHelper {
expandMainPlayer(fragment.requireActivity()); expandMainPlayer(fragment.requireActivity());
final VideoDetailFragment detailFragment = (VideoDetailFragment) fragment; final VideoDetailFragment detailFragment = (VideoDetailFragment) fragment;
detailFragment.setAutoplay(autoPlay); detailFragment.setAutoplay(autoPlay);
detailFragment.selectAndLoadVideo(serviceId, url, title == null ? "" : title, playQueue); detailFragment
.selectAndLoadVideo(serviceId, url, title == null ? "" : title, playQueue);
detailFragment.scrollToTop(); detailFragment.scrollToTop();
return; return;
} }
final VideoDetailFragment instance = VideoDetailFragment.getInstance(serviceId, url, title == null ? "" : title, playQueue); final VideoDetailFragment instance = VideoDetailFragment
.getInstance(serviceId, url, title == null ? "" : title, playQueue);
instance.setAutoplay(autoPlay); instance.setAutoplay(autoPlay);
defaultTransaction(fragmentManager) defaultTransaction(fragmentManager)

View File

@ -5,7 +5,7 @@ import android.util.AttributeSet;
import android.view.SurfaceView; import android.view.SurfaceView;
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout; import com.google.android.exoplayer2.ui.AspectRatioFrameLayout;
import static com.google.android.exoplayer2.ui.AspectRatioFrameLayout.*; import static com.google.android.exoplayer2.ui.AspectRatioFrameLayout.RESIZE_MODE_ZOOM;
public class ExpandableSurfaceView extends SurfaceView { public class ExpandableSurfaceView extends SurfaceView {
private int resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT; private int resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT;
@ -15,21 +15,27 @@ public class ExpandableSurfaceView extends SurfaceView {
private float scaleX = 1.0f; private float scaleX = 1.0f;
private float scaleY = 1.0f; private float scaleY = 1.0f;
public ExpandableSurfaceView(Context context, AttributeSet attrs) { public ExpandableSurfaceView(final Context context, final AttributeSet attrs) {
super(context, attrs); super(context, attrs);
} }
@Override @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec); super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (videoAspectRatio == 0.0f) return; if (videoAspectRatio == 0.0f) {
return;
}
int width = MeasureSpec.getSize(widthMeasureSpec); int width = MeasureSpec.getSize(widthMeasureSpec);
final boolean verticalVideo = videoAspectRatio < 1; final boolean verticalVideo = videoAspectRatio < 1;
// Use maxHeight only on non-fit resize mode and in vertical videos // Use maxHeight only on non-fit resize mode and in vertical videos
int height = maxHeight != 0 && resizeMode != AspectRatioFrameLayout.RESIZE_MODE_FIT && verticalVideo ? maxHeight : baseHeight; int height = maxHeight != 0
&& resizeMode != AspectRatioFrameLayout.RESIZE_MODE_FIT
&& verticalVideo ? maxHeight : baseHeight;
if (height == 0) return; if (height == 0) {
return;
}
final float viewAspectRatio = width / ((float) height); final float viewAspectRatio = width / ((float) height);
final float aspectDeformation = videoAspectRatio / viewAspectRatio - 1; final float aspectDeformation = videoAspectRatio / viewAspectRatio - 1;
@ -61,10 +67,11 @@ public class ExpandableSurfaceView extends SurfaceView {
} }
/** /**
* Scale view only in {@link #onLayout} to make transition for ZOOM mode as smooth as possible * Scale view only in {@link #onLayout} to make transition for ZOOM mode as smooth as possible.
*/ */
@Override @Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) { protected void onLayout(final boolean changed,
final int left, final int top, final int right, final int bottom) {
setScaleX(scaleX); setScaleX(scaleX);
setScaleY(scaleY); setScaleY(scaleY);
} }
@ -74,14 +81,18 @@ public class ExpandableSurfaceView extends SurfaceView {
* @param max The max height for vertical videos in non-FIT resize modes * @param max The max height for vertical videos in non-FIT resize modes
*/ */
public void setHeights(final int base, final int max) { public void setHeights(final int base, final int max) {
if (baseHeight == base && maxHeight == max) return; if (baseHeight == base && maxHeight == max) {
return;
}
baseHeight = base; baseHeight = base;
maxHeight = max; maxHeight = max;
requestLayout(); requestLayout();
} }
public void setResizeMode(@AspectRatioFrameLayout.ResizeMode final int newResizeMode) { public void setResizeMode(@AspectRatioFrameLayout.ResizeMode final int newResizeMode) {
if (resizeMode == newResizeMode) return; if (resizeMode == newResizeMode) {
return;
}
resizeMode = newResizeMode; resizeMode = newResizeMode;
requestLayout(); requestLayout();
@ -93,7 +104,9 @@ public class ExpandableSurfaceView extends SurfaceView {
} }
public void setAspectRatio(final float aspectRatio) { public void setAspectRatio(final float aspectRatio) {
if (videoAspectRatio == aspectRatio) return; if (videoAspectRatio == aspectRatio) {
return;
}
videoAspectRatio = aspectRatio; videoAspectRatio = aspectRatio;
requestLayout(); requestLayout();

View File

@ -19,4 +19,10 @@
<suppress checks="LineLength" <suppress checks="LineLength"
files="WebMWriter.java" files="WebMWriter.java"
lines="156,158"/> lines="156,158"/>
<suppress checks="FileLength"
files="VideoPlayerImpl.java"/>
<suppress checks="FileLength"
files="VideoDetailFragment.java"/>
</suppressions> </suppressions>

View File

@ -67,6 +67,8 @@
<!-- <property name="fileExtensions" value="java"/> --> <!-- <property name="fileExtensions" value="java"/> -->
<!-- </module> --> <!-- </module> -->
<module name="SuppressWarningsFilter" />
<module name="TreeWalker"> <module name="TreeWalker">
<!-- Checks for Javadoc comments. --> <!-- Checks for Javadoc comments. -->
<!-- See https://checkstyle.org/config_javadoc.html --> <!-- See https://checkstyle.org/config_javadoc.html -->
@ -174,6 +176,8 @@
</module>--> </module>-->
<module name="UpperEll"/> <module name="UpperEll"/>
<module name="SuppressWarningsHolder" />
<!-- https://checkstyle.org/config_filters.html#SuppressionXpathFilter --> <!-- https://checkstyle.org/config_filters.html#SuppressionXpathFilter -->
<module name="SuppressionXpathFilter"> <module name="SuppressionXpathFilter">
<property name="file" value="${org.checkstyle.sun.suppressionxpathfilter.config}" <property name="file" value="${org.checkstyle.sun.suppressionxpathfilter.config}"