From d8f7db4715cea3c405e11ba28cfa809d9c6447a4 Mon Sep 17 00:00:00 2001 From: Avently <7953703+avently@users.noreply.github.com> Date: Tue, 14 Jul 2020 20:21:32 +0300 Subject: [PATCH] Made checkStyle happy --- .../material/appbar/FlingBehavior.java | 20 +- .../java/org/schabi/newpipe/MainActivity.java | 103 ++- .../org/schabi/newpipe/RouterActivity.java | 3 +- .../newpipe/fragments/detail/StackItem.java | 11 +- .../fragments/detail/VideoDetailFragment.java | 571 +++++++++----- .../player/BackgroundPlayerActivity.java | 20 +- .../org/schabi/newpipe/player/BasePlayer.java | 77 +- .../org/schabi/newpipe/player/MainPlayer.java | 169 +++-- .../newpipe/player/MainVideoPlayer.java | 5 +- .../newpipe/player/PopupVideoPlayer.java | 3 +- .../player/PopupVideoPlayerActivity.java | 2 +- .../newpipe/player/ServicePlayerActivity.java | 20 +- .../schabi/newpipe/player/VideoPlayer.java | 12 +- .../newpipe/player/VideoPlayerImpl.java | 694 ++++++++++++------ .../event/CustomBottomSheetBehavior.java | 18 +- .../player/event/OnKeyDownListener.java | 2 +- .../player/event/PlayerGestureListener.java | 266 ++++--- .../event/PlayerServiceEventListener.java | 2 +- .../helper/PlaybackParameterDialog.java | 2 +- .../newpipe/player/helper/PlayerHelper.java | 9 +- .../newpipe/player/playqueue/PlayQueue.java | 26 +- .../newpipe/streams/SubtitleConverter.java | 0 .../schabi/newpipe/util/NavigationHelper.java | 28 +- .../newpipe/views/ExpandableSurfaceView.java | 39 +- checkstyle-suppressions.xml | 6 + checkstyle.xml | 4 + 26 files changed, 1448 insertions(+), 664 deletions(-) delete mode 100644 app/src/main/java/org/schabi/newpipe/streams/SubtitleConverter.java diff --git a/app/src/main/java/com/google/android/material/appbar/FlingBehavior.java b/app/src/main/java/com/google/android/material/appbar/FlingBehavior.java index 2e8a0103f..7bd6a0d17 100644 --- a/app/src/main/java/com/google/android/material/appbar/FlingBehavior.java +++ b/app/src/main/java/com/google/android/material/appbar/FlingBehavior.java @@ -85,15 +85,23 @@ public final class FlingBehavior extends AppBarLayout.Behavior { } @Override - public boolean onStartNestedScroll(@NotNull final CoordinatorLayout parent, @NotNull final AppBarLayout child, - @NotNull final View directTargetChild, final View target, final int nestedScrollAxes, final int type) { - return allowScroll && super.onStartNestedScroll(parent, child, directTargetChild, target, nestedScrollAxes, type); + public boolean onStartNestedScroll(@NotNull final CoordinatorLayout parent, + @NotNull final AppBarLayout child, + @NotNull final View directTargetChild, + final View target, + final int nestedScrollAxes, + final int type) { + return allowScroll && super.onStartNestedScroll( + parent, child, directTargetChild, target, nestedScrollAxes, type); } @Override - public boolean onNestedFling(@NotNull final CoordinatorLayout coordinatorLayout, @NotNull final AppBarLayout child, - @NotNull final View target, final float velocityX, final float velocityY, final boolean consumed) { - return allowScroll && super.onNestedFling(coordinatorLayout, child, target, velocityX, velocityY, consumed); + public boolean onNestedFling(@NotNull final CoordinatorLayout coordinatorLayout, + @NotNull final AppBarLayout child, + @NotNull final View target, final float velocityX, + final float velocityY, final boolean consumed) { + return allowScroll && super.onNestedFling( + coordinatorLayout, child, target, velocityX, velocityY, consumed); } @Nullable diff --git a/app/src/main/java/org/schabi/newpipe/MainActivity.java b/app/src/main/java/org/schabi/newpipe/MainActivity.java index 7aa9cd9ff..ad5741503 100644 --- a/app/src/main/java/org/schabi/newpipe/MainActivity.java +++ b/app/src/main/java/org/schabi/newpipe/MainActivity.java @@ -20,7 +20,8 @@ package org.schabi.newpipe; -import android.content.*; +import android.content.Intent; +import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.os.Build; import android.os.Bundle; @@ -28,9 +29,20 @@ import android.os.Handler; import android.os.Looper; import android.preference.PreferenceManager; 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.appcompat.app.ActionBar; 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.playqueue.PlayQueue; 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 java.util.ArrayList; @@ -504,10 +527,14 @@ public class MainActivity extends AppCompatActivity { @Override public boolean onKeyDown(final int keyCode, final KeyEvent event) { - final Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_player_holder); - if (fragment instanceof OnKeyDownListener && !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); + final Fragment fragment = getSupportFragmentManager() + .findFragmentById(R.id.fragment_player_holder); + if (fragment instanceof OnKeyDownListener + && !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); } @@ -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 - // 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()) { - final Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_holder); - // If current fragment implements BackPressable (i.e. can/wanna handle back press) delegate the back press to it + final Fragment fragment = getSupportFragmentManager() + .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 (((BackPressable) fragment).onBackPressed()) return; + if (((BackPressable) fragment).onBackPressed()) { + return; + } } } else { - final Fragment fragmentPlayer = getSupportFragmentManager().findFragmentById(R.id.fragment_player_holder); - // If current fragment implements BackPressable (i.e. can/wanna handle back press) delegate the back press to it + final Fragment fragmentPlayer = getSupportFragmentManager() + .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 (!((BackPressable) fragmentPlayer).onBackPressed()) { - final FrameLayout bottomSheetLayout = findViewById(R.id.fragment_player_holder); - BottomSheetBehavior.from(bottomSheetLayout).setState(BottomSheetBehavior.STATE_COLLAPSED); + final FrameLayout bottomSheetLayout = + findViewById(R.id.fragment_player_holder); + BottomSheetBehavior.from(bottomSheetLayout) + .setState(BottomSheetBehavior.STATE_COLLAPSED); } return; } @@ -568,7 +604,8 @@ public class MainActivity extends AppCompatActivity { NavigationHelper.openDownloads(this); break; 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) { ((VideoDetailFragment) fragment).openDownloadDialog(); } @@ -661,10 +698,12 @@ public class MainActivity extends AppCompatActivity { } StateSaver.clearStateFiles(); 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 - // he will see a blank fragment on place of kiosk. Let's open it first - if (getSupportFragmentManager().getBackStackEntryCount() == 0) + // When user watch a video inside popup and then tries to open the video in main player + // while the app is closed he will see a blank fragment on place of kiosk. + // Let's open it first + if (getSupportFragmentManager().getBackStackEntryCount() == 0) { NavigationHelper.openMainFragment(getSupportFragmentManager()); + } handleIntent(getIntent()); } else { @@ -712,10 +751,16 @@ public class MainActivity extends AppCompatActivity { switch (((StreamingService.LinkType) intent .getSerializableExtra(Constants.KEY_LINK_TYPE))) { case STREAM: - boolean autoPlay = intent.getBooleanExtra(VideoDetailFragment.AUTO_PLAY, false); - final String intentCacheKey = intent.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); + boolean autoPlay = intent + .getBooleanExtra(VideoDetailFragment.AUTO_PLAY, false); + final String intentCacheKey = intent + .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; case CHANNEL: NavigationHelper.openChannelFragment(getSupportFragmentManager(), @@ -749,14 +794,16 @@ public class MainActivity extends AppCompatActivity { } } /* - * Utils - * */ + * Utils + * */ private boolean bottomSheetHiddenOrCollapsed() { final FrameLayout bottomSheetLayout = findViewById(R.id.fragment_player_holder); - final BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(bottomSheetLayout); + final BottomSheetBehavior bottomSheetBehavior = + BottomSheetBehavior.from(bottomSheetLayout); final int sheetState = bottomSheetBehavior.getState(); - return sheetState == BottomSheetBehavior.STATE_HIDDEN || sheetState == BottomSheetBehavior.STATE_COLLAPSED; + return sheetState == BottomSheetBehavior.STATE_HIDDEN + || sheetState == BottomSheetBehavior.STATE_COLLAPSED; } } diff --git a/app/src/main/java/org/schabi/newpipe/RouterActivity.java b/app/src/main/java/org/schabi/newpipe/RouterActivity.java index 1ce35d6fe..423e88b76 100644 --- a/app/src/main/java/org/schabi/newpipe/RouterActivity.java +++ b/app/src/main/java/org/schabi/newpipe/RouterActivity.java @@ -39,7 +39,6 @@ import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.playlist.PlaylistInfo; import org.schabi.newpipe.extractor.stream.StreamInfo; 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.PlayQueue; 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, choice.url, "", true, true); } diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/StackItem.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/StackItem.java index 1fbc21bf9..2fe615764 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/StackItem.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/StackItem.java @@ -10,18 +10,19 @@ class StackItem implements Serializable { private String title; 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.url = url; this.title = title; this.playQueue = playQueue; } - public void setUrl(String url) { + public void setUrl(final String url) { this.url = url; } - public void setPlayQueue(PlayQueue queue) { + public void setPlayQueue(final PlayQueue queue) { this.playQueue = queue; } @@ -41,7 +42,9 @@ class StackItem implements Serializable { return url; } - public PlayQueue getPlayQueue() { return playQueue; } + public PlayQueue getPlayQueue() { + return playQueue; + } @Override public String toString() { diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java index 396363d31..7586ca241 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java @@ -2,7 +2,13 @@ package org.schabi.newpipe.fragments.detail; import android.animation.ValueAnimator; import android.app.Activity; -import android.content.*; +import android.content.BroadcastReceiver; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.ServiceConnection; +import android.content.SharedPreferences; import android.content.pm.ActivityInfo; import android.database.ContentObserver; import android.graphics.drawable.Drawable; @@ -12,9 +18,18 @@ import android.os.Handler; import android.os.IBinder; import android.preference.PreferenceManager; import android.provider.Settings; -import android.view.*; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; import android.view.animation.DecelerateInterpolator; -import android.widget.*; +import android.widget.FrameLayout; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.RelativeLayout; +import android.widget.TextView; import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -64,12 +79,17 @@ import org.schabi.newpipe.fragments.list.comments.CommentsFragment; import org.schabi.newpipe.fragments.list.videos.RelatedVideosFragment; import org.schabi.newpipe.local.dialog.PlaylistAppendDialog; import org.schabi.newpipe.local.history.HistoryRecordManager; -import org.schabi.newpipe.player.*; +import org.schabi.newpipe.player.BasePlayer; +import org.schabi.newpipe.player.MainPlayer; +import org.schabi.newpipe.player.VideoPlayer; +import org.schabi.newpipe.player.VideoPlayerImpl; import org.schabi.newpipe.player.event.OnKeyDownListener; import org.schabi.newpipe.player.event.PlayerEventListener; import org.schabi.newpipe.player.event.PlayerServiceEventListener; import org.schabi.newpipe.player.helper.PlayerHelper; -import org.schabi.newpipe.player.playqueue.*; +import org.schabi.newpipe.player.playqueue.PlayQueue; +import org.schabi.newpipe.player.playqueue.PlayQueueItem; +import org.schabi.newpipe.player.playqueue.SinglePlayQueue; import org.schabi.newpipe.report.ErrorActivity; import org.schabi.newpipe.report.UserAction; import org.schabi.newpipe.util.AndroidTvUtils; @@ -87,7 +107,11 @@ import org.schabi.newpipe.views.AnimatedProgressBar; import org.schabi.newpipe.views.LargeTextMovementMethod; import java.io.Serializable; -import java.util.*; +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; import java.util.concurrent.TimeUnit; import icepick.State; @@ -121,10 +145,14 @@ public class VideoDetailFragment private static final float MAX_OVERLAY_ALPHA = 0.9f; private static final float MAX_PLAYER_HEIGHT = 0.7f; - public static final String ACTION_SHOW_MAIN_PLAYER = "org.schabi.newpipe.VideoDetailFragment.ACTION_SHOW_MAIN_PLAYER"; - public static final String ACTION_HIDE_MAIN_PLAYER = "org.schabi.newpipe.VideoDetailFragment.ACTION_HIDE_MAIN_PLAYER"; - public static final String ACTION_VIDEO_FRAGMENT_RESUMED = "org.schabi.newpipe.VideoDetailFragment.ACTION_VIDEO_FRAGMENT_RESUMED"; - public static final String ACTION_VIDEO_FRAGMENT_STOPPED = "org.schabi.newpipe.VideoDetailFragment.ACTION_VIDEO_FRAGMENT_STOPPED"; + public static final String ACTION_SHOW_MAIN_PLAYER = + "org.schabi.newpipe.VideoDetailFragment.ACTION_SHOW_MAIN_PLAYER"; + public static final String ACTION_HIDE_MAIN_PLAYER = + "org.schabi.newpipe.VideoDetailFragment.ACTION_HIDE_MAIN_PLAYER"; + public static final String ACTION_VIDEO_FRAGMENT_RESUMED = + "org.schabi.newpipe.VideoDetailFragment.ACTION_VIDEO_FRAGMENT_RESUMED"; + public static final String ACTION_VIDEO_FRAGMENT_STOPPED = + "org.schabi.newpipe.VideoDetailFragment.ACTION_VIDEO_FRAGMENT_STOPPED"; private static final String COMMENTS_TAB_TAG = "COMMENTS"; private static final String RELATED_TAB_TAG = "NEXT VIDEO"; @@ -230,18 +258,23 @@ public class VideoDetailFragment // Service management //////////////////////////////////////////////////////////////////////////*/ - private ServiceConnection getServiceConnection(final boolean playAfterConnect) { + private ServiceConnection getServiceConnection(final Context context, + final boolean playAfterConnect) { return new ServiceConnection() { @Override - public void onServiceDisconnected(final ComponentName name) { - if (DEBUG) Log.d(TAG, "Player service is disconnected"); + public void onServiceDisconnected(final ComponentName compName) { + if (DEBUG) { + Log.d(TAG, "Player service is disconnected"); + } - unbind(); + unbind(context); } @Override public void onServiceConnected(final ComponentName compName, final IBinder service) { - if (DEBUG) Log.d(TAG, "Player service is connected"); + if (DEBUG) { + Log.d(TAG, "Player service is connected"); + } final MainPlayer.LocalBinder localBinder = (MainPlayer.LocalBinder) service; playerService = localBinder.getService(); @@ -252,12 +285,17 @@ public class VideoDetailFragment // It will do nothing if the player is not in fullscreen mode hideSystemUiIfNeeded(); - if (!player.videoPlayerSelected() && !playAfterConnect) return; + if (!player.videoPlayerSelected() && !playAfterConnect) { + return; + } - if (playerIsNotStopped() && player.videoPlayerSelected()) addVideoPlayerView(); + if (playerIsNotStopped() && player.videoPlayerSelected()) { + addVideoPlayerView(); + } if (isLandscape()) { - // If the video is playing but orientation changed let's make the video in fullscreen again + // If the video is playing but orientation changed + // let's make the video in fullscreen again checkLandscape(); } else if (player.isFullscreen()) { // Device is in portrait orientation after rotation but UI is in fullscreen. @@ -265,26 +303,35 @@ public class VideoDetailFragment player.toggleFullscreen(); } - if (playAfterConnect || (currentInfo != null && isAutoplayEnabled() && player.getParentActivity() == null)) { + if (playAfterConnect + || (currentInfo != null + && isAutoplayEnabled() + && player.getParentActivity() == null)) { openVideoPlayer(); } } }; } - private void bind() { - if (DEBUG) Log.d(TAG, "bind() called"); + private void bind(final Context context) { + if (DEBUG) { + Log.d(TAG, "bind() called"); + } - final Intent serviceIntent = new Intent(getContext(), MainPlayer.class); - bound = requireContext().bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE); - if (!bound) requireContext().unbindService(serviceConnection); + final Intent serviceIntent = new Intent(context, MainPlayer.class); + bound = context.bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE); + if (!bound) { + context.unbindService(serviceConnection); + } } - private void unbind() { - if (DEBUG) Log.d(TAG, "unbind() called"); + private void unbind(final Context context) { + if (DEBUG) { + Log.d(TAG, "unbind() called"); + } if (bound) { - requireContext().unbindService(serviceConnection); + context.unbindService(serviceConnection); bound = false; stopPlayerListener(); playerService = null; @@ -293,31 +340,37 @@ public class VideoDetailFragment } private void startPlayerListener() { - if (player != null) player.setFragmentListener(this); + if (player != null) { + player.setFragmentListener(this); + } } private void stopPlayerListener() { - if (player != null) player.removeFragmentListener(this); + if (player != null) { + player.removeFragmentListener(this); + } } - private void startService(boolean playAfterConnect) { - // startService() can be called concurrently and it will give a random crashes and NullPointerExceptions - // inside the service because the service will be bound twice. Prevent it with unbinding first - unbind(); - requireContext().startService(new Intent(getContext(), MainPlayer.class)); - serviceConnection = getServiceConnection(playAfterConnect); - bind(); + private void startService(final Context context, final boolean playAfterConnect) { + // startService() can be called concurrently and it will give a random crashes + // and NullPointerExceptions inside the service because the service will be + // bound twice. Prevent it with unbinding first + unbind(context); + context.startService(new Intent(context, MainPlayer.class)); + serviceConnection = getServiceConnection(context, playAfterConnect); + bind(context); } - private void stopService() { - unbind(); - requireContext().stopService(new Intent(getContext(), MainPlayer.class)); + private void stopService(final Context context) { + unbind(context); + context.stopService(new Intent(context, MainPlayer.class)); } /*////////////////////////////////////////////////////////////////////////*/ - public static VideoDetailFragment getInstance(final int serviceId, final String videoUrl, final String name, final PlayQueue playQueue) { + public static VideoDetailFragment getInstance(final int serviceId, final String videoUrl, + final String name, final PlayQueue playQueue) { VideoDetailFragment instance = new VideoDetailFragment(); instance.setInitialData(serviceId, videoUrl, name, playQueue); return instance; @@ -349,8 +402,9 @@ public class VideoDetailFragment settingsContentObserver = new ContentObserver(new Handler()) { @Override public void onChange(final boolean selfChange) { - if (activity != null && !PlayerHelper.globalScreenOrientationLocked(activity)) + if (activity != null && !PlayerHelper.globalScreenOrientationLocked(activity)) { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); + } } }; activity.getContentResolver().registerContentObserver( @@ -388,33 +442,43 @@ public class VideoDetailFragment if (updateFlags != 0) { if (!isLoading.get() && currentInfo != null) { - if ((updateFlags & RELATED_STREAMS_UPDATE_FLAG) != 0) startLoading(false); - if ((updateFlags & COMMENTS_UPDATE_FLAG) != 0) startLoading(false); + if ((updateFlags & RELATED_STREAMS_UPDATE_FLAG) != 0) { + startLoading(false); + } + if ((updateFlags & COMMENTS_UPDATE_FLAG) != 0) { + startLoading(false); + } } updateFlags = 0; } // Check if it was loading when the fragment was stopped/paused - if (wasLoading.getAndSet(false) && !wasCleared()) + if (wasLoading.getAndSet(false) && !wasCleared()) { startLoading(false); + } } @Override public void onStop() { super.onStop(); - if (!activity.isChangingConfigurations()) + if (!activity.isChangingConfigurations()) { activity.sendBroadcast(new Intent(ACTION_VIDEO_FRAGMENT_STOPPED)); + } } @Override public void onDestroy() { super.onDestroy(); - // Stop the service when user leaves the app with double back press if video player is selected. Otherwise unbind - if (activity.isFinishing() && player != null && player.videoPlayerSelected()) stopService(); - else unbind(); + // Stop the service when user leaves the app with double back press + // if video player is selected. Otherwise unbind + if (activity.isFinishing() && player != null && player.videoPlayerSelected()) { + stopService(requireContext()); + } else { + unbind(requireContext()); + } PreferenceManager.getDefaultSharedPreferences(activity) .unregisterOnSharedPreferenceChangeListener(this); @@ -474,7 +538,9 @@ public class VideoDetailFragment outState.putSerializable(INFO_KEY, currentInfo); } - if (playQueue != null) outState.putSerializable(VideoPlayer.PLAY_QUEUE_KEY, playQueue); + if (playQueue != null) { + outState.putSerializable(VideoPlayer.PLAY_QUEUE_KEY, playQueue); + } outState.putSerializable(STACK_KEY, stack); } @@ -556,7 +622,9 @@ public class VideoDetailFragment player.onPlayPause(); player.hideControls(0, 0); showSystemUi(); - } else openVideoPlayer(); + } else { + openVideoPlayer(); + } setOverlayPlayPauseImage(); break; @@ -596,8 +664,9 @@ public class VideoDetailFragment break; case R.id.overlay_thumbnail: case R.id.overlay_metadata_layout: - if (currentInfo != null) + if (currentInfo != null) { openChannel(currentInfo.getUploaderUrl(), currentInfo.getUploaderName()); + } break; case R.id.detail_uploader_root_layout: if (TextUtils.isEmpty(currentInfo.getSubChannelUrl())) { @@ -740,7 +809,7 @@ public class VideoDetailFragment detailControlsPopup.setOnTouchListener(getOnControlsTouchListener()); setupBottomPlayer(); - startService(false); + startService(requireContext(), false); } private View.OnTouchListener getOnControlsTouchListener() { @@ -810,7 +879,9 @@ public class VideoDetailFragment // If we are in fullscreen mode just exit from it via first back press if (player != null && player.isFullscreen()) { - if (!PlayerHelper.isTablet(activity)) player.onPause(); + if (!PlayerHelper.isTablet(activity)) { + player.onPause(); + } restoreDefaultOrientation(); setAutoplay(false); return true; @@ -851,13 +922,17 @@ public class VideoDetailFragment startLoading(false); // Maybe an item was deleted in background activity - if (item.getPlayQueue().getItem() == null) return; + if (item.getPlayQueue().getItem() == null) { + return; + } final PlayQueueItem playQueueItem = item.getPlayQueue().getItem(); // Update title, url, uploader from the last item in the stack (it's current now) final boolean isPlayerStopped = player == null || player.isPlayerStopped(); - if (playQueueItem != null && isPlayerStopped) - updateOverlayData(playQueueItem.getTitle(), playQueueItem.getUploader(), playQueueItem.getThumbnailUrl()); + if (playQueueItem != null && isPlayerStopped) { + updateOverlayData(playQueueItem.getTitle(), + playQueueItem.getUploader(), playQueueItem.getThumbnailUrl()); + } } /*////////////////////////////////////////////////////////////////////////// @@ -866,7 +941,9 @@ public class VideoDetailFragment @Override protected void doInitialLoadLogic() { - if (wasCleared()) return; + if (wasCleared()) { + return; + } if (currentInfo == null) { prepareAndLoadInfo(); @@ -875,13 +952,15 @@ public class VideoDetailFragment } } - public void selectAndLoadVideo(final int sid, final String videoUrl, final String title, final PlayQueue playQueue) { - // Situation when user switches from players to main player. All needed data is here, we can start watching - if (this.playQueue != null && this.playQueue.equals(playQueue)) { + public void selectAndLoadVideo(final int sid, final String videoUrl, final String title, + final PlayQueue queue) { + // Situation when user switches from players to main player. + // All needed data is here, we can start watching + if (this.playQueue != null && this.playQueue.equals(queue)) { openVideoPlayer(); return; } - setInitialData(sid, videoUrl, title, playQueue); + setInitialData(sid, videoUrl, title, queue); startLoading(false, true); } @@ -894,7 +973,9 @@ public class VideoDetailFragment showLoading(); initTabs(); - if (scrollToTop) scrollToTop(); + if (scrollToTop) { + scrollToTop(); + } handleResult(info); showContent(); @@ -915,17 +996,17 @@ public class VideoDetailFragment currentWorker.dispose(); } - final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); - runWorker(forceLoad, stack.isEmpty()); } private void startLoading(final boolean forceLoad, final boolean addToBackStack) { - super.startLoading(false); + super.startLoading(forceLoad); initTabs(); currentInfo = null; - if (currentWorker != null) currentWorker.dispose(); + if (currentWorker != null) { + currentWorker.dispose(); + } runWorker(forceLoad, addToBackStack); } @@ -945,11 +1026,16 @@ public class VideoDetailFragment handleResult(result); showContent(); if (addToBackStack) { - if (playQueue == null) playQueue = new SinglePlayQueue(result); - if (stack.isEmpty() || !stack.peek().getPlayQueue().equals(playQueue)) + if (playQueue == null) { + playQueue = new SinglePlayQueue(result); + } + if (stack.isEmpty() || !stack.peek().getPlayQueue().equals(playQueue)) { stack.push(new StackItem(serviceId, url, name, playQueue)); + } + } + if (isAutoplayEnabled()) { + openVideoPlayer(); } - if (isAutoplayEnabled()) openVideoPlayer(); } }, (@NonNull final Throwable throwable) -> { isLoading.set(false); @@ -964,7 +1050,8 @@ public class VideoDetailFragment pageAdapter.clearAllItems(); if (shouldShowComments()) { - pageAdapter.addFragment(CommentsFragment.getInstance(serviceId, url, name), COMMENTS_TAB_TAG); + pageAdapter.addFragment( + CommentsFragment.getInstance(serviceId, url, name), COMMENTS_TAB_TAG); } if (showRelatedStreams && null == relatedStreamsLayout) { @@ -1012,11 +1099,15 @@ public class VideoDetailFragment final AudioStream audioStream = currentInfo.getAudioStreams() .get(ListHelper.getDefaultAudioFormat(activity, currentInfo.getAudioStreams())); - final boolean useExternalAudioPlayer = PreferenceManager.getDefaultSharedPreferences(activity) + final boolean useExternalAudioPlayer = PreferenceManager + .getDefaultSharedPreferences(activity) .getBoolean(activity.getString(R.string.use_external_audio_player_key), false); - // If a user watched video inside fullscreen mode and than chose another player return to non-fullscreen mode - if (player != null && player.isFullscreen()) player.toggleFullscreen(); + // If a user watched video inside fullscreen mode and than chose another player + // return to non-fullscreen mode + if (player != null && player.isFullscreen()) { + player.toggleFullscreen(); + } if (!useExternalAudioPlayer && android.os.Build.VERSION.SDK_INT >= 16) { openNormalBackgroundPlayer(append); @@ -1032,16 +1123,22 @@ public class VideoDetailFragment } // See UI changes while remote playQueue changes - if (!bound) startService(false); + if (!bound) { + startService(requireContext(), false); + } - // If a user watched video inside fullscreen mode and than chose another player return to non-fullscreen mode - if (player != null && player.isFullscreen()) player.toggleFullscreen(); + // If a user watched video inside fullscreen mode and than chose another player + // return to non-fullscreen mode + if (player != null && player.isFullscreen()) { + player.toggleFullscreen(); + } final PlayQueue queue = setupPlayQueueForIntent(append); if (append) { NavigationHelper.enqueueOnPopupPlayer(activity, queue, false); } else { - replaceQueueIfUserConfirms(() -> NavigationHelper.playOnPopupPlayer(activity, queue, true)); + replaceQueueIfUserConfirms(() -> NavigationHelper + .playOnPopupPlayer(activity, queue, true)); } } @@ -1049,7 +1146,9 @@ public class VideoDetailFragment if (PreferenceManager.getDefaultSharedPreferences(activity) .getBoolean(this.getString(R.string.use_external_video_player_key), false)) { final VideoStream selectedVideoStream = getSelectedVideoStream(); - if (selectedVideoStream == null) return; + if (selectedVideoStream == null) { + return; + } startOnExternalPlayer(activity, currentInfo, selectedVideoStream); } else { replaceQueueIfUserConfirms(this::openMainPlayer); @@ -1058,36 +1157,46 @@ public class VideoDetailFragment private void openNormalBackgroundPlayer(final boolean append) { // See UI changes while remote playQueue changes - if (!bound) startService(false); + if (!bound) { + startService(requireContext(), false); + } final PlayQueue queue = setupPlayQueueForIntent(append); if (append) { NavigationHelper.enqueueOnBackgroundPlayer(activity, queue, false); } else { - replaceQueueIfUserConfirms(() -> NavigationHelper.playOnBackgroundPlayer(activity, queue, true)); + replaceQueueIfUserConfirms(() -> NavigationHelper + .playOnBackgroundPlayer(activity, queue, true)); } } private void openMainPlayer() { if (playerService == null) { - startService(true); + startService(requireContext(), true); + return; + } + if (currentInfo == null) { return; } - if (currentInfo == null) return; final PlayQueue queue = setupPlayQueueForIntent(false); - // Video view can have elements visible from popup, We hide it here but once it ready the view will be shown in handleIntent() + // Video view can have elements visible from popup, + // We hide it here but once it ready the view will be shown in handleIntent() Objects.requireNonNull(playerService.getView()).setVisibility(View.GONE); addVideoPlayerView(); - final Intent playerIntent = NavigationHelper.getPlayerIntent(requireContext(), MainPlayer.class, queue, null, true); + final Intent playerIntent = NavigationHelper + .getPlayerIntent(requireContext(), MainPlayer.class, queue, null, true); activity.startService(playerIntent); } private void hideMainPlayer() { - if (playerService == null || playerService.getView() == null || !player.videoPlayerSelected()) + if (playerService == null + || playerService.getView() == null + || !player.videoPlayerSelected()) { return; + } removeVideoPlayerView(); playerService.stop(isAutoplayEnabled()); @@ -1095,12 +1204,15 @@ public class VideoDetailFragment } private PlayQueue setupPlayQueueForIntent(final boolean append) { - if (append) return new SinglePlayQueue(currentInfo); + if (append) { + return new SinglePlayQueue(currentInfo); + } PlayQueue queue = playQueue; // Size can be 0 because queue removes bad stream automatically when error occurs - if (queue == null || queue.size() == 0) + if (queue == null || queue.size() == 0) { queue = new SinglePlayQueue(currentInfo); + } return queue; } @@ -1143,7 +1255,9 @@ public class VideoDetailFragment } private boolean isAutoplayAllowedByUser() { - if (activity == null) return false; + if (activity == null) { + return false; + } switch (PlayerHelper.getAutoplayType(activity)) { case PlayerHelper.AutoplayType.AUTOPLAY_TYPE_NEVER: @@ -1157,16 +1271,22 @@ public class VideoDetailFragment } private void addVideoPlayerView() { - if (player == null || getView() == null) return; + if (player == null || getView() == null) { + return; + } final FrameLayout viewHolder = getView().findViewById(R.id.player_placeholder); // Check if viewHolder already contains a child - if (player.getRootView().getParent() != viewHolder) removeVideoPlayerView(); + if (player.getRootView().getParent() != viewHolder) { + removeVideoPlayerView(); + } setHeightThumbnail(); // Prevent from re-adding a view multiple times - if (player.getRootView().getParent() == null) viewHolder.addView(player.getRootView()); + if (player.getRootView().getParent() == null) { + viewHolder.addView(player.getRootView()); + } } private void removeVideoPlayerView() { @@ -1176,7 +1296,9 @@ public class VideoDetailFragment } private void makeDefaultHeightForVideoPlaceholder() { - if (getView() == null) return; + if (getView() == null) { + return; + } final FrameLayout viewHolder = getView().findViewById(R.id.player_placeholder); viewHolder.getLayoutParams().height = FrameLayout.LayoutParams.MATCH_PARENT; @@ -1228,23 +1350,29 @@ public class VideoDetailFragment } /** - * Method which controls the size of thumbnail and the size of main player inside a layout with thumbnail. - * It decides what height the player should have in both screen orientations. It knows about multiWindow feature - * and about videos with aspectRatio ZOOM (the height for them will be a bit higher, {@link #MAX_PLAYER_HEIGHT}) + * Method which controls the size of thumbnail and the size of main player inside + * a layout with thumbnail. It decides what height the player should have in both + * screen orientations. It knows about multiWindow feature + * and about videos with aspectRatio ZOOM (the height for them will be a bit higher, + * {@link #MAX_PLAYER_HEIGHT}) */ private void setHeightThumbnail() { final DisplayMetrics metrics = getResources().getDisplayMetrics(); final boolean isPortrait = metrics.heightPixels > metrics.widthPixels; final int height; - if (player != null && player.isFullscreen()) - height = isInMultiWindow() ? Objects.requireNonNull(getView()).getHeight() : activity.getWindow().getDecorView().getHeight(); - else + if (player != null && player.isFullscreen()) { + height = isInMultiWindow() + ? Objects.requireNonNull(getView()).getHeight() + : activity.getWindow().getDecorView().getHeight(); + } else { height = isPortrait ? (int) (metrics.widthPixels / (16.0f / 9.0f)) : (int) (metrics.heightPixels / 2.0f); + } - thumbnailImageView.setLayoutParams(new FrameLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, height)); + thumbnailImageView.setLayoutParams( + new FrameLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, height)); thumbnailImageView.setMinimumHeight(height); if (player != null) { final int maxHeight = (int) (metrics.heightPixels * MAX_PLAYER_HEIGHT); @@ -1256,11 +1384,12 @@ public class VideoDetailFragment contentRootLayoutHiding.setVisibility(View.VISIBLE); } - protected void setInitialData(final int sid, final String u, final String name, final PlayQueue playQueue) { + protected void setInitialData(final int sid, final String u, final String title, + final PlayQueue queue) { this.serviceId = sid; this.url = u; - this.name = !TextUtils.isEmpty(name) ? name : ""; - this.playQueue = playQueue; + this.name = !TextUtils.isEmpty(title) ? title : ""; + this.playQueue = queue; } private void setErrorImage(final int imageResource) { @@ -1288,7 +1417,7 @@ public class VideoDetailFragment private void setupBroadcastReceiver() { broadcastReceiver = new BroadcastReceiver() { @Override - public void onReceive(Context context, Intent intent) { + public void onReceive(final Context context, final Intent intent) { if (intent.getAction().equals(ACTION_SHOW_MAIN_PLAYER)) { bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED); } else if (intent.getAction().equals(ACTION_HIDE_MAIN_PLAYER)) { @@ -1308,14 +1437,20 @@ public class VideoDetailFragment //////////////////////////////////////////////////////////////////////////*/ private void restoreDefaultOrientation() { - if (player == null || !player.videoPlayerSelected() || activity == null) return; + if (player == null || !player.videoPlayerSelected() || activity == null) { + return; + } - if (player != null && player.isFullscreen()) player.toggleFullscreen(); + if (player != null && player.isFullscreen()) { + player.toggleFullscreen(); + } // This will show systemUI and pause the player. // User can tap on Play button and video will be in fullscreen mode again - // Note for tablet: trying to avoid orientation changes since it's not easy to physically rotate the tablet every time - if (!PlayerHelper.isTablet(activity)) + // Note for tablet: trying to avoid orientation changes since it's not easy + // to physically rotate the tablet every time + if (!PlayerHelper.isTablet(activity)) { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); + } } /*////////////////////////////////////////////////////////////////////////// @@ -1347,7 +1482,8 @@ public class VideoDetailFragment if (relatedStreamsLayout != null) { if (showRelatedStreams) { - relatedStreamsLayout.setVisibility(player != null && player.isFullscreen() ? View.GONE : View.INVISIBLE); + relatedStreamsLayout.setVisibility( + player != null && player.isFullscreen() ? View.GONE : View.INVISIBLE); } else { relatedStreamsLayout.setVisibility(View.GONE); } @@ -1376,10 +1512,10 @@ public class VideoDetailFragment .replace(R.id.relatedStreamsLayout, RelatedVideosFragment.getInstance(info)) .commitNow(); - relatedStreamsLayout.setVisibility(player != null && player.isFullscreen() ? View.GONE : View.VISIBLE); + relatedStreamsLayout.setVisibility( + player != null && player.isFullscreen() ? View.GONE : View.VISIBLE); } } - animateView(thumbnailPlayButton, true, 200); videoTitleTextView.setText(name); @@ -1475,14 +1611,15 @@ public class VideoDetailFragment info.getVideoStreams(), info.getVideoOnlyStreams(), false); - selectedVideoStreamIndex = ListHelper.getDefaultResolutionIndex(activity, sortedVideoStreams); + selectedVideoStreamIndex = ListHelper + .getDefaultResolutionIndex(activity, sortedVideoStreams); prepareDescription(info.getDescription()); updateProgressInfo(info); initThumbnailViews(info); - if (player == null || player.isPlayerStopped()) + if (player == null || player.isPlayerStopped()) { updateOverlayData(info.getName(), info.getUploaderName(), info.getThumbnailUrl()); - + } if (!info.getErrors().isEmpty()) { showSnackBarError(info.getErrors(), @@ -1504,7 +1641,6 @@ public class VideoDetailFragment if (!info.getVideoStreams().isEmpty() || !info.getVideoOnlyStreams().isEmpty()) { break; } - detailControlsPopup.setVisibility(View.GONE); thumbnailPlayButton.setImageResource(R.drawable.ic_headset_shadow); break; @@ -1585,8 +1721,8 @@ public class VideoDetailFragment int errorId = exception instanceof YoutubeStreamExtractor.DecryptException ? R.string.youtube_signature_decryption_error : exception instanceof ExtractionException - ? R.string.parsing_error - : R.string.general_error; + ? R.string.parsing_error + : R.string.general_error; onUnrecoverableError(exception, UserAction.REQUESTED_STREAM, NewPipe.getNameOfService(serviceId), url, errorId); @@ -1606,7 +1742,8 @@ public class VideoDetailFragment activity.getString(R.string.enable_playback_state_lists_key), true); if (!playbackResumeEnabled) { if (playQueue == null || playQueue.getStreams().isEmpty() - || playQueue.getItem().getRecoveryPosition() == RECOVERY_UNSET || !showPlaybackPosition) { + || playQueue.getItem().getRecoveryPosition() == RECOVERY_UNSET + || !showPlaybackPosition) { positionView.setVisibility(View.INVISIBLE); detailPositionView.setVisibility(View.GONE); // TODO: Remove this check when separation of concerns is done. @@ -1622,8 +1759,8 @@ public class VideoDetailFragment animateView(positionView, true, 500); animateView(detailPositionView, true, 500); } - return; - } + return; + } final HistoryRecordManager recordManager = new HistoryRecordManager(requireContext()); // TODO: Separate concerns when updating database data. @@ -1665,26 +1802,35 @@ public class VideoDetailFragment @Override public void onQueueUpdate(final PlayQueue queue) { playQueue = queue; - final StackItem stackWithQueue; - // This should be the only place where we push data to stack. It will allow to have live instance of PlayQueue with actual - // information about deleted/added items inside Channel/Playlist queue and makes possible to have a history of played items + // This should be the only place where we push data to stack. + // It will allow to have live instance of PlayQueue with actual information about + // deleted/added items inside Channel/Playlist queue and makes possible to have + // a history of played items if (stack.isEmpty() || !stack.peek().getPlayQueue().equals(queue)) { stack.push(new StackItem(serviceId, url, name, playQueue)); - } else if ((stackWithQueue = findQueueInStack(queue)) != null) { - // On every MainPlayer service's destroy() playQueue gets disposed and no longer able to track progress. - // That's why we update our cached disposed queue with the new one that is active and have the same history - // Without that the cached playQueue will have an old recovery position - stackWithQueue.setPlayQueue(queue); + } else { + final StackItem stackWithQueue = findQueueInStack(queue); + if (stackWithQueue != null) { + // On every MainPlayer service's destroy() playQueue gets disposed and + // no longer able to track progress. That's why we update our cached disposed + // queue with the new one that is active and have the same history. + // Without that the cached playQueue will have an old recovery position + stackWithQueue.setPlayQueue(queue); + } } if (DEBUG) { Log.d(TAG, "onQueueUpdate() called with: serviceId = [" - + serviceId + "], videoUrl = [" + url + "], name = [" + name + "], playQueue = [" + playQueue + "]"); + + serviceId + "], videoUrl = [" + url + "], name = [" + + name + "], playQueue = [" + playQueue + "]"); } } @Override - public void onPlaybackUpdate(final int state, final int repeatMode, final boolean shuffled, final PlaybackParameters parameters) { + public void onPlaybackUpdate(final int state, + final int repeatMode, + final boolean shuffled, + final PlaybackParameters parameters) { setOverlayPlayPauseImage(); switch (state) { @@ -1704,29 +1850,40 @@ public class VideoDetailFragment } @Override - public void onProgressUpdate(final int currentProgress, final int duration, final int bufferPercent) { + public void onProgressUpdate(final int currentProgress, + final int duration, + final int bufferPercent) { // Progress updates every second even if media is paused. It's useless until playing - if (!player.getPlayer().isPlaying() || playQueue == null) return; + if (!player.getPlayer().isPlaying() || playQueue == null) { + return; + } - if (player.getPlayQueue().getItem().getUrl().equals(url)) + if (player.getPlayQueue().getItem().getUrl().equals(url)) { showPlaybackProgress(currentProgress, duration); + } } @Override public void onMetadataUpdate(final StreamInfo info, final PlayQueue queue) { final StackItem item = findQueueInStack(queue); if (item != null) { - // When PlayQueue can have multiple streams (PlaylistPlayQueue or ChannelPlayQueue) every new played stream gives - // new title and url. StackItem contains information about first played stream. Let's update it here + // When PlayQueue can have multiple streams (PlaylistPlayQueue or ChannelPlayQueue) + // every new played stream gives new title and url. + // StackItem contains information about first played stream. Let's update it here item.setTitle(info.getName()); item.setUrl(info.getUrl()); } - // They are not equal when user watches something in popup while browsing in fragment and then changes screen orientation - // In that case the fragment will set itself as a service listener and will receive initial call to onMetadataUpdate() - if (!queue.equals(playQueue)) return; + // They are not equal when user watches something in popup while browsing in fragment and + // then changes screen orientation. In that case the fragment will set itself as + // a service listener and will receive initial call to onMetadataUpdate() + if (!queue.equals(playQueue)) { + return; + } updateOverlayData(info.getName(), info.getUploaderName(), info.getThumbnailUrl()); - if (currentInfo != null && info.getUrl().equals(currentInfo.getUrl())) return; + if (currentInfo != null && info.getUrl().equals(currentInfo.getUrl())) { + return; + } currentInfo = info; setInitialData(info.getServiceId(), info.getUrl(), info.getName(), queue); @@ -1736,29 +1893,37 @@ public class VideoDetailFragment @Override public void onPlayerError(final ExoPlaybackException error) { - if (error.type == ExoPlaybackException.TYPE_SOURCE || error.type == ExoPlaybackException.TYPE_UNEXPECTED) { + if (error.type == ExoPlaybackException.TYPE_SOURCE + || error.type == ExoPlaybackException.TYPE_UNEXPECTED) { hideMainPlayer(); - if (playerService != null && player.isFullscreen()) + if (playerService != null && player.isFullscreen()) { player.toggleFullscreen(); + } } } @Override public void onServiceStopped() { - unbind(); + unbind(requireContext()); setOverlayPlayPauseImage(); - if (currentInfo != null) - updateOverlayData(currentInfo.getName(), currentInfo.getUploaderName(), currentInfo.getThumbnailUrl()); + if (currentInfo != null) { + updateOverlayData(currentInfo.getName(), + currentInfo.getUploaderName(), + currentInfo.getThumbnailUrl()); + } } @Override public void onFullscreenStateChanged(final boolean fullscreen) { - if (playerService.getView() == null || player.getParentActivity() == null) + if (playerService.getView() == null || player.getParentActivity() == null) { return; + } final View view = playerService.getView(); final ViewGroup parent = (ViewGroup) view.getParent(); - if (parent == null) return; + if (parent == null) { + return; + } if (fullscreen) { hideSystemUiIfNeeded(); @@ -1766,7 +1931,9 @@ public class VideoDetailFragment showSystemUi(); } - if (relatedStreamsLayout != null) relatedStreamsLayout.setVisibility(fullscreen ? View.GONE : View.VISIBLE); + if (relatedStreamsLayout != null) { + relatedStreamsLayout.setVisibility(fullscreen ? View.GONE : View.VISIBLE); + } scrollToTop(); addVideoPlayerView(); @@ -1774,15 +1941,16 @@ public class VideoDetailFragment @Override public void onScreenRotationButtonClicked() { - // In tablet user experience will be better if screen will not be rotated from landscape to portrait every time + // In tablet user experience will be better if screen will not be rotated + // from landscape to portrait every time. // Just turn on fullscreen mode in landscape orientation if (isLandscape() && PlayerHelper.isTablet(activity)) { player.toggleFullscreen(); return; } - final int newOrientation = isLandscape() ? - ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED + final int newOrientation = isLandscape() + ? ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED : ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE; activity.setRequestedOrientation(newOrientation); @@ -1793,9 +1961,11 @@ public class VideoDetailFragment * */ @Override public void onMoreOptionsLongClicked() { - final CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams(); + final CoordinatorLayout.LayoutParams params = + (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams(); final AppBarLayout.Behavior behavior = (AppBarLayout.Behavior) params.getBehavior(); - final ValueAnimator valueAnimator = ValueAnimator.ofInt(0, -getView().findViewById(R.id.player_placeholder).getHeight()); + final ValueAnimator valueAnimator = ValueAnimator + .ofInt(0, -getView().findViewById(R.id.player_placeholder).getHeight()); valueAnimator.setInterpolator(new DecelerateInterpolator()); valueAnimator.addUpdateListener(animation -> { behavior.setTopAndBottomOffset((int) animation.getAnimatedValue()); @@ -1811,18 +1981,26 @@ public class VideoDetailFragment //////////////////////////////////////////////////////////////////////////*/ private void showSystemUi() { - if (DEBUG) Log.d(TAG, "showSystemUi() called"); + if (DEBUG) { + Log.d(TAG, "showSystemUi() called"); + } - if (activity == null) return; + if (activity == null) { + return; + } activity.getWindow().getDecorView().setSystemUiVisibility(0); activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); } private void hideSystemUi() { - if (DEBUG) Log.d(TAG, "hideSystemUi() called"); + if (DEBUG) { + Log.d(TAG, "hideSystemUi() called"); + } - if (activity == null) return; + if (activity == null) { + return; + } final int visibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN @@ -1832,21 +2010,29 @@ public class VideoDetailFragment | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; activity.getWindow().getDecorView().setSystemUiVisibility(visibility); activity.getWindow().setFlags( - WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); + WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, + WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); } // Listener implementation public void hideSystemUiIfNeeded() { - if (player != null && player.isFullscreen() && bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED) + if (player != null + && player.isFullscreen() + && bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED) { hideSystemUi(); + } } private boolean playerIsNotStopped() { - return player != null && player.getPlayer() != null && player.getPlayer().getPlaybackState() != Player.STATE_IDLE; + return player != null + && player.getPlayer() != null + && player.getPlayer().getPlaybackState() != Player.STATE_IDLE; } private void setupBrightness(final boolean save) { - if (activity == null) return; + if (activity == null) { + return; + } final WindowManager.LayoutParams lp = activity.getWindow().getAttributes(); if (save) { @@ -1859,8 +2045,9 @@ public class VideoDetailFragment } else { // Restore already saved brightness level final float brightnessLevel = PlayerHelper.getScreenBrightness(activity); - if (brightnessLevel <= 0.0f && brightnessLevel > 1.0f) + if (brightnessLevel <= 0.0f && brightnessLevel > 1.0f) { return; + } lp.screenBrightness = brightnessLevel; } @@ -1868,8 +2055,10 @@ public class VideoDetailFragment } private void checkLandscape() { - if ((!player.isPlaying() && player.getPlayQueue() != playQueue) || player.getPlayQueue() == null) + if ((!player.isPlaying() && player.getPlayQueue() != playQueue) + || player.getPlayQueue() == null) { setAutoplay(true); + } player.checkLandscape(); final boolean orientationLocked = PlayerHelper.globalScreenOrientationLocked(activity); @@ -1881,7 +2070,8 @@ public class VideoDetailFragment } private boolean isLandscape() { - return getResources().getDisplayMetrics().heightPixels < getResources().getDisplayMetrics().widthPixels; + return getResources().getDisplayMetrics().heightPixels < getResources() + .getDisplayMetrics().widthPixels; } private boolean isInMultiWindow() { @@ -1889,7 +2079,8 @@ public class VideoDetailFragment } /* - * Means that the player fragment was swiped away via BottomSheetLayout and is empty but ready for any new actions. See cleanUp() + * Means that the player fragment was swiped away via BottomSheetLayout + * and is empty but ready for any new actions. See cleanUp() * */ private boolean wasCleared() { return url == null; @@ -1940,8 +2131,10 @@ public class VideoDetailFragment private void cleanUp() { // New beginning stack.clear(); - if (currentWorker != null) currentWorker.dispose(); - stopService(); + if (currentWorker != null) { + currentWorker.dispose(); + } + stopService(requireContext()); setInitialData(0, null, "", null); currentInfo = null; updateOverlayData(null, null, null); @@ -1952,7 +2145,8 @@ public class VideoDetailFragment //////////////////////////////////////////////////////////////////////////*/ private void setupBottomPlayer() { - final CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams(); + final CoordinatorLayout.LayoutParams params = + (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams(); final AppBarLayout.Behavior behavior = (AppBarLayout.Behavior) params.getBehavior(); final FrameLayout bottomSheetLayout = activity.findViewById(R.id.fragment_player_holder); @@ -1981,7 +2175,8 @@ public class VideoDetailFragment break; case BottomSheetBehavior.STATE_EXPANDED: bottomSheetBehavior.setPeekHeight(peekHeight); - // Disable click because overlay buttons located on top of buttons from the player + // Disable click because overlay buttons located on top of buttons + // from the player setOverlayElementsClickable(false); hideSystemUiIfNeeded(); // Conditions when the player should be expanded to fullscreen @@ -1990,17 +2185,25 @@ public class VideoDetailFragment && player.isPlaying() && !player.isFullscreen() && !PlayerHelper.isTablet(activity) - && player.videoPlayerSelected()) player.toggleFullscreen(); + && player.videoPlayerSelected()) { + player.toggleFullscreen(); + } break; case BottomSheetBehavior.STATE_COLLAPSED: // Re-enable clicks setOverlayElementsClickable(true); - if (player != null) player.onQueueClosed(); + if (player != null) { + player.onQueueClosed(); + } break; case BottomSheetBehavior.STATE_DRAGGING: case BottomSheetBehavior.STATE_SETTLING: - if (player != null && player.isFullscreen()) showSystemUi(); - if (player != null && player.isControlsVisible()) player.hideControls(0, 0); + if (player != null && player.isFullscreen()) { + showSystemUi(); + } + if (player != null && player.isControlsVisible()) { + player.hideControls(0, 0); + } break; } } @@ -2013,32 +2216,42 @@ public class VideoDetailFragment // User opened a new page and the player will hide itself activity.getSupportFragmentManager().addOnBackStackChangedListener(() -> { - if (bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED) + if (bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED) { bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED); + } }); } - private void updateOverlayData(@Nullable final String title, @Nullable final String uploader, @Nullable final String thumbnailUrl) { + private void updateOverlayData(@Nullable final String title, + @Nullable final String uploader, + @Nullable final String thumbnailUrl) { overlayTitleTextView.setText(TextUtils.isEmpty(title) ? "" : title); overlayChannelTextView.setText(TextUtils.isEmpty(uploader) ? "" : uploader); overlayThumbnailImageView.setImageResource(R.drawable.dummy_thumbnail_dark); - if (!TextUtils.isEmpty(thumbnailUrl)) + if (!TextUtils.isEmpty(thumbnailUrl)) { IMAGE_LOADER.displayImage(thumbnailUrl, overlayThumbnailImageView, ImageDisplayConstants.DISPLAY_THUMBNAIL_OPTIONS, null); + } } private void setOverlayPlayPauseImage() { - final int attr = player != null && player.getPlayer().getPlayWhenReady() ? R.attr.ic_pause : R.attr.ic_play_arrow; - overlayPlayPauseButton.setImageResource(ThemeHelper.resolveResourceIdFromAttr(activity, attr)); + final int attr = player != null && player.getPlayer().getPlayWhenReady() + ? R.attr.ic_pause + : R.attr.ic_play_arrow; + overlayPlayPauseButton.setImageResource( + ThemeHelper.resolveResourceIdFromAttr(activity, attr)); } - private void setOverlayLook(final AppBarLayout appBarLayout, final AppBarLayout.Behavior behavior, final float slideOffset) { + private void setOverlayLook(final AppBarLayout appBar, + final AppBarLayout.Behavior behavior, + final float slideOffset) { if (behavior != null) { overlay.setAlpha(Math.min(MAX_OVERLAY_ALPHA, 1 - slideOffset)); // These numbers are not special. They just do a cool transition - behavior.setTopAndBottomOffset((int) (-thumbnailImageView.getHeight() * 2 * (1 - slideOffset) / 3)); - appBarLayout.requestLayout(); + behavior.setTopAndBottomOffset( + (int) (-thumbnailImageView.getHeight() * 2 * (1 - slideOffset) / 3)); + appBar.requestLayout(); } } diff --git a/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayerActivity.java b/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayerActivity.java index 2577665ff..0e5222f5e 100644 --- a/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayerActivity.java +++ b/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayerActivity.java @@ -8,8 +8,6 @@ import org.schabi.newpipe.R; import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.PermissionHelper; -import static org.schabi.newpipe.player.BackgroundPlayer.ACTION_CLOSE; - public final class BackgroundPlayerActivity extends ServicePlayerActivity { private static final String TAG = "BackgroundPlayerActivity"; @@ -58,13 +56,15 @@ public final class BackgroundPlayerActivity extends ServicePlayerActivity { } this.player.setRecovery(); - NavigationHelper.playOnPopupPlayer(getApplicationContext(), player.playQueue, this.player.isPlaying()); + NavigationHelper.playOnPopupPlayer( + getApplicationContext(), player.playQueue, this.player.isPlaying()); return true; } if (item.getItemId() == R.id.action_switch_background) { this.player.setRecovery(); - NavigationHelper.playOnBackgroundPlayer(getApplicationContext(), player.playQueue, this.player.isPlaying()); + NavigationHelper.playOnBackgroundPlayer( + getApplicationContext(), player.playQueue, this.player.isPlaying()); return true; } @@ -72,10 +72,14 @@ public final class BackgroundPlayerActivity extends ServicePlayerActivity { } @Override - public void setupMenu(Menu menu) { - if(player == null) return; + public void setupMenu(final Menu menu) { + if (player == null) { + return; + } - menu.findItem(R.id.action_switch_popup).setVisible(!((VideoPlayerImpl)player).popupPlayerSelected()); - menu.findItem(R.id.action_switch_background).setVisible(!((VideoPlayerImpl)player).audioPlayerSelected()); + menu.findItem(R.id.action_switch_popup) + .setVisible(!((VideoPlayerImpl) player).popupPlayerSelected()); + menu.findItem(R.id.action_switch_background) + .setVisible(!((VideoPlayerImpl) player).audioPlayerSelected()); } } diff --git a/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java b/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java index f232c018a..1a8c98fd2 100644 --- a/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java @@ -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 PROGRESS_LOOP_INTERVAL_MILLIS = 500; - public final static int PLAYER_TYPE_VIDEO = 0; - public final static int PLAYER_TYPE_AUDIO = 1; - public final static int PLAYER_TYPE_POPUP = 2; + public static final int PLAYER_TYPE_VIDEO = 0; + public static final int PLAYER_TYPE_AUDIO = 1; + public static final int PLAYER_TYPE_POPUP = 2; protected SimpleExoPlayer simpleExoPlayer; protected AudioReactor audioReactor; @@ -257,7 +257,8 @@ public abstract class BasePlayer implements registerBroadcastReceiver(); } - public void initListeners() { } + public void initListeners() { + } public void handleIntent(final Intent intent) { if (DEBUG) { @@ -302,13 +303,13 @@ public abstract class BasePlayer implements .getBooleanExtra(IS_MUTED, simpleExoPlayer != null && isMuted()); /* - * 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 - * 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 - * In those cases time will be saved because re-init of the play queue is a not an instant task - * and requires network calls - * */ + * 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 the timestamp + * 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 + * In those cases time will be saved because re-init of the play queue is a not an instant + * task and requires network calls + * */ // seek to timestamp if stream is already playing if (simpleExoPlayer != null && queue.size() == 1 @@ -317,15 +318,21 @@ public abstract class BasePlayer implements && playQueue.getItem() != null && queue.getItem().getUrl().equals(playQueue.getItem().getUrl()) && queue.getItem().getRecoveryPosition() != PlayQueueItem.RECOVERY_UNSET) { - // Player can have state = IDLE when playback is stopped or failed and we should retry() in this case - if (simpleExoPlayer.getPlaybackState() == Player.STATE_IDLE) simpleExoPlayer.retry(); + // Player can have state = IDLE when playback is stopped or failed + // and we should retry() in this case + if (simpleExoPlayer.getPlaybackState() == Player.STATE_IDLE) { + simpleExoPlayer.retry(); + } simpleExoPlayer.seekTo(playQueue.getIndex(), queue.getItem().getRecoveryPosition()); return; } else if (samePlayQueue && !playQueue.isDisposed() && simpleExoPlayer != null) { // 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 - if (simpleExoPlayer.getPlaybackState() == Player.STATE_IDLE) simpleExoPlayer.retry(); + // Player can have state = IDLE when playback is stopped or failed + // and we should retry() in this case + if (simpleExoPlayer.getPlaybackState() == Player.STATE_IDLE) { + simpleExoPlayer.retry(); + } return; } else if (intent.getBooleanExtra(RESUME_PLAYBACK, false) && isPlaybackResumeEnabled() @@ -334,21 +341,27 @@ public abstract class BasePlayer implements if (item != null && item.getRecoveryPosition() == PlayQueueItem.RECOVERY_UNSET) { stateLoader = recordManager.loadStreamState(item) .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() .subscribe( state -> { queue.setRecovery(queue.getIndex(), state.getProgressTime()); - initPlayback(queue, repeatMode, playbackSpeed, playbackPitch, playbackSkipSilence, true, isMuted); + initPlayback(queue, repeatMode, playbackSpeed, playbackPitch, + playbackSkipSilence, true, isMuted); }, error -> { - if (DEBUG) error.printStackTrace(); + if (DEBUG) { + error.printStackTrace(); + } // 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 - initPlayback(queue, repeatMode, playbackSpeed, playbackPitch, playbackSkipSilence, true, isMuted); + initPlayback(queue, repeatMode, playbackSpeed, playbackPitch, + playbackSkipSilence, true, isMuted); } ); databaseUpdateReactor.add(stateLoader); @@ -357,8 +370,10 @@ public abstract class BasePlayer implements } // Good to go... // 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, - !intent.getBooleanExtra(START_PAUSED, false), isMuted); + initPlayback(samePlayQueue ? playQueue : queue, repeatMode, + playbackSpeed, playbackPitch, playbackSkipSilence, + !intent.getBooleanExtra(START_PAUSED, false), + isMuted); } private PlaybackParameters retrievePlaybackParametersFromPreferences() { @@ -596,7 +611,8 @@ public abstract class BasePlayer implements } } - public void onPausedSeek() { } + public void onPausedSeek() { + } public void onCompleted() { if (DEBUG) { @@ -1514,8 +1530,9 @@ public abstract class BasePlayer implements /** * 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. - * @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 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 skipSilence skip silence during playback */ public void setPlaybackParameters(final float speed, final float pitch, @@ -1531,11 +1548,11 @@ public abstract class BasePlayer implements private void savePlaybackParametersToPreferences(final float speed, final float pitch, final boolean skipSilence) { PreferenceManager.getDefaultSharedPreferences(context) - .edit() - .putFloat(context.getString(R.string.playback_speed_key), speed) - .putFloat(context.getString(R.string.playback_pitch_key), pitch) - .putBoolean(context.getString(R.string.playback_skip_silence_key), skipSilence) - .apply(); + .edit() + .putFloat(context.getString(R.string.playback_speed_key), speed) + .putFloat(context.getString(R.string.playback_pitch_key), pitch) + .putBoolean(context.getString(R.string.playback_skip_silence_key), skipSilence) + .apply(); } public PlayQueue getPlayQueue() { diff --git a/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java b/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java index f6c0c9761..53296d915 100644 --- a/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java @@ -54,7 +54,7 @@ import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage; /** - * One service for all players + * One service for all players. * * @author mauriciocolli */ @@ -84,14 +84,22 @@ public final class MainPlayer extends Service { private RemoteViews notRemoteView; private RemoteViews bigNotRemoteView; - static final String ACTION_CLOSE = "org.schabi.newpipe.player.MainPlayer.CLOSE"; - static final String ACTION_PLAY_PAUSE = "org.schabi.newpipe.player.MainPlayer.PLAY_PAUSE"; - static final String ACTION_OPEN_CONTROLS = "org.schabi.newpipe.player.MainPlayer.OPEN_CONTROLS"; - static final String ACTION_REPEAT = "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"; + static final String ACTION_CLOSE = + "org.schabi.newpipe.player.MainPlayer.CLOSE"; + static final String ACTION_PLAY_PAUSE = + "org.schabi.newpipe.player.MainPlayer.PLAY_PAUSE"; + static final String ACTION_OPEN_CONTROLS = + "org.schabi.newpipe.player.MainPlayer.OPEN_CONTROLS"; + static final String ACTION_REPEAT = + "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"; @@ -101,7 +109,9 @@ public final class MainPlayer extends Service { @Override public void onCreate() { - if (DEBUG) Log.d(TAG, "onCreate() called"); + if (DEBUG) { + Log.d(TAG, "onCreate() called"); + } assureCorrectAppLanguage(this); notificationManager = ((NotificationManager) getSystemService(NOTIFICATION_SERVICE)); windowManager = (WindowManager) getSystemService(WINDOW_SERVICE); @@ -120,12 +130,16 @@ public final class MainPlayer extends Service { } @Override - public int onStartCommand(Intent intent, int flags, int startId) { - if (DEBUG) Log.d(TAG, "onStartCommand() called with: intent = [" + intent + - "], flags = [" + flags + "], startId = [" + startId + "]"); + public int onStartCommand(final Intent intent, final int flags, final int startId) { + if (DEBUG) { + 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(); + } playerImpl.handleIntent(intent); if (playerImpl.mediaSessionManager != null) { @@ -135,24 +149,32 @@ public final class MainPlayer extends Service { } public void stop(final boolean autoplayEnabled) { - if (DEBUG) Log.d(TAG, "stop() called"); + if (DEBUG) { + Log.d(TAG, "stop() called"); + } if (playerImpl.getPlayer() != null) { playerImpl.wasPlaying = playerImpl.getPlayer().getPlayWhenReady(); // Releases wifi & cpu, disables keepScreenOn, etc. - if (!autoplayEnabled) playerImpl.onPause(); - // We can't just pause the player here because it will make transition from one stream to a new stream not smooth + if (!autoplayEnabled) { + 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.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. // When autoplay enabled such notification flashing is annoying so skip this case - if (!autoplayEnabled) stopForeground(true); + if (!autoplayEnabled) { + stopForeground(true); + } } } @Override - public void onTaskRemoved(Intent rootIntent) { + public void onTaskRemoved(final Intent rootIntent) { super.onTaskRemoved(rootIntent); onDestroy(); // Unload from memory completely @@ -161,17 +183,19 @@ public final class MainPlayer extends Service { @Override public void onDestroy() { - if (DEBUG) Log.d(TAG, "destroy() called"); + if (DEBUG) { + Log.d(TAG, "destroy() called"); + } onClose(); } @Override - protected void attachBaseContext(Context base) { + protected void attachBaseContext(final Context base) { super.attachBaseContext(AudioServiceLeakFix.preventLeakOf(base)); } @Override - public IBinder onBind(Intent intent) { + public IBinder onBind(final Intent intent) { return mBinder; } @@ -179,7 +203,9 @@ public final class MainPlayer extends Service { // Actions //////////////////////////////////////////////////////////////////////////*/ private void onClose() { - if (DEBUG) Log.d(TAG, "onClose() called"); + if (DEBUG) { + Log.d(TAG, "onClose() called"); + } if (playerImpl != null) { removeViewFromParent(); @@ -190,7 +216,9 @@ public final class MainPlayer extends Service { playerImpl.removePopupFromView(); playerImpl.destroy(); } - if (notificationManager != null) notificationManager.cancel(NOTIFICATION_ID); + if (notificationManager != null) { + notificationManager.cancel(NOTIFICATION_ID); + } stopForeground(true); stopSelf(); @@ -201,16 +229,19 @@ public final class MainPlayer extends Service { //////////////////////////////////////////////////////////////////////////*/ boolean isLandscape() { - // DisplayMetrics from activity context knows about MultiWindow feature while DisplayMetrics from app context doesn't - final DisplayMetrics metrics = (playerImpl != null && playerImpl.getParentActivity() != null) ? - playerImpl.getParentActivity().getResources().getDisplayMetrics() + // DisplayMetrics from activity context knows about MultiWindow feature + // while DisplayMetrics from app context doesn't + final DisplayMetrics metrics = (playerImpl != null + && playerImpl.getParentActivity() != null) + ? playerImpl.getParentActivity().getResources().getDisplayMetrics() : getResources().getDisplayMetrics(); return metrics.heightPixels < metrics.widthPixels; } public View getView() { - if (playerImpl == null) + if (playerImpl == null) { return null; + } return playerImpl.getRootView(); } @@ -221,18 +252,21 @@ public final class MainPlayer extends Service { // This means view was added to fragment final ViewGroup parent = (ViewGroup) getView().getParent(); parent.removeView(getView()); - } else + } else { // This means view was added by windowManager for popup player windowManager.removeViewImmediate(getView()); + } } } private void showNotificationAndStartForeground() { resetNotification(); - if (getBigNotRemoteView() != null) + if (getBigNotRemoteView() != null) { getBigNotRemoteView().setProgressBar(R.id.notificationProgressBar, 100, 0, false); - if (getNotRemoteView() != null) + } + if (getNotRemoteView() != null) { getNotRemoteView().setProgressBar(R.id.notificationProgressBar, 100, 0, false); + } startForeground(NOTIFICATION_ID, getNotBuilder().build()); } @@ -246,8 +280,10 @@ public final class MainPlayer extends Service { } private NotificationCompat.Builder createNotification() { - notRemoteView = new RemoteViews(BuildConfig.APPLICATION_ID, R.layout.player_background_notification); - bigNotRemoteView = new RemoteViews(BuildConfig.APPLICATION_ID, R.layout.player_background_notification_expanded); + notRemoteView = new RemoteViews(BuildConfig.APPLICATION_ID, + R.layout.player_background_notification); + bigNotRemoteView = new RemoteViews(BuildConfig.APPLICATION_ID, + R.layout.player_background_notification_expanded); setupNotification(notRemoteView); setupNotification(bigNotRemoteView); @@ -294,37 +330,51 @@ public final class MainPlayer extends Service { private void setupNotification(final RemoteViews remoteViews) { // 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.notificationArtist, playerImpl.getUploaderName()); remoteViews.setImageViewBitmap(R.id.notificationCover, playerImpl.getThumbnail()); 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, - 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. 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, - 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) { - remoteViews.setInt(R.id.notificationFRewind, SET_IMAGE_RESOURCE_METHOD, R.drawable.exo_controls_previous); - remoteViews.setInt(R.id.notificationFForward, SET_IMAGE_RESOURCE_METHOD, R.drawable.exo_controls_next); + remoteViews.setInt(R.id.notificationFRewind, SET_IMAGE_RESOURCE_METHOD, + R.drawable.exo_controls_previous); + remoteViews.setInt(R.id.notificationFForward, SET_IMAGE_RESOURCE_METHOD, + R.drawable.exo_controls_next); 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, - 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 { - remoteViews.setInt(R.id.notificationFRewind, SET_IMAGE_RESOURCE_METHOD, R.drawable.exo_controls_rewind); - remoteViews.setInt(R.id.notificationFForward, SET_IMAGE_RESOURCE_METHOD, R.drawable.exo_controls_fastforward); + remoteViews.setInt(R.id.notificationFRewind, SET_IMAGE_RESOURCE_METHOD, + R.drawable.exo_controls_rewind); + remoteViews.setInt(R.id.notificationFForward, SET_IMAGE_RESOURCE_METHOD, + R.drawable.exo_controls_fastforward); 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, - 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()); @@ -340,10 +390,16 @@ public final class MainPlayer extends Service { /*if (DEBUG) { Log.d(TAG, "updateNotification() called with: drawableId = [" + drawableId + "]"); }*/ - if (notBuilder == null) return; + if (notBuilder == null) { + return; + } if (drawableId != -1) { - if (notRemoteView != null) notRemoteView.setImageViewResource(R.id.notificationPlayPause, drawableId); - if (bigNotRemoteView != null) bigNotRemoteView.setImageViewResource(R.id.notificationPlayPause, drawableId); + if (notRemoteView != null) { + notRemoteView.setImageViewResource(R.id.notificationPlayPause, drawableId); + } + if (bigNotRemoteView != null) { + bigNotRemoteView.setImageViewResource(R.id.notificationPlayPause, drawableId); + } } notificationManager.notify(NOTIFICATION_ID, notBuilder.build()); playerImpl.timesNotificationUpdated++; @@ -354,17 +410,22 @@ public final class MainPlayer extends Service { //////////////////////////////////////////////////////////////////////////*/ private void setRepeatModeIcon(final RemoteViews remoteViews, final int repeatMode) { - if (remoteViews == null) return; + if (remoteViews == null) { + return; + } switch (repeatMode) { 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; 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; 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; } } diff --git a/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java index a3cdd42e2..51e159469 100644 --- a/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java @@ -914,7 +914,10 @@ public final class MainVideoPlayer extends AppCompatActivity @Override public void onPlaybackSpeedClicked() { PlaybackParameterDialog - .newInstance(getPlaybackSpeed(), getPlaybackPitch(), getPlaybackSkipSilence(), MainVideoPlayer.this) + .newInstance(getPlaybackSpeed(), + getPlaybackPitch(), + getPlaybackSkipSilence(), + MainVideoPlayer.this) .show(getSupportFragmentManager(), TAG); } diff --git a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java index c0de59275..bffcaa6d1 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java @@ -584,7 +584,7 @@ public final class PopupVideoPlayer extends Service { } @Override - public void initViews(View rootView) { + public void initViews(final View rootView) { super.initViews(rootView); resizingIndicator = rootView.findViewById(R.id.resizing_indicator); fullScreenButton = rootView.findViewById(R.id.fullScreenButton); @@ -612,6 +612,7 @@ public final class PopupVideoPlayer extends Service { } @Override + @SuppressWarnings("checkstyle:ParameterNumber") 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 oldRight, final int oldBottom) { diff --git a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayerActivity.java b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayerActivity.java index 7b41220ee..7c5813bc4 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayerActivity.java +++ b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayerActivity.java @@ -61,7 +61,7 @@ public final class PopupVideoPlayerActivity extends ServicePlayerActivity { } @Override - public void setupMenu(Menu menu) { + public void setupMenu(final Menu menu) { } diff --git a/app/src/main/java/org/schabi/newpipe/player/ServicePlayerActivity.java b/app/src/main/java/org/schabi/newpipe/player/ServicePlayerActivity.java index f62f815be..3043a7fc3 100644 --- a/app/src/main/java/org/schabi/newpipe/player/ServicePlayerActivity.java +++ b/app/src/main/java/org/schabi/newpipe/player/ServicePlayerActivity.java @@ -35,7 +35,12 @@ import org.schabi.newpipe.fragments.OnScrollBelowItemsListener; import org.schabi.newpipe.local.dialog.PlaylistAppendDialog; import org.schabi.newpipe.player.event.PlayerEventListener; 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.Localization; import org.schabi.newpipe.util.NavigationHelper; @@ -109,7 +114,7 @@ public abstract class ServicePlayerActivity extends AppCompatActivity public abstract boolean onPlayerOptionSelected(MenuItem item); - public abstract void setupMenu(Menu menu); + public abstract void setupMenu(Menu m); //////////////////////////////////////////////////////////////////////////// // Activity Lifecycle //////////////////////////////////////////////////////////////////////////// @@ -153,9 +158,9 @@ public abstract class ServicePlayerActivity extends AppCompatActivity // Allow to setup visibility of menuItems @Override - public boolean onPrepareOptionsMenu(Menu menu) { - setupMenu(menu); - return super.onPrepareOptionsMenu(menu); + public boolean onPrepareOptionsMenu(final Menu m) { + setupMenu(m); + return super.onPrepareOptionsMenu(m); } @Override @@ -208,7 +213,8 @@ public abstract class ServicePlayerActivity extends AppCompatActivity .putExtra(Constants.KEY_LINK_TYPE, StreamingService.LinkType.STREAM) .putExtra(Constants.KEY_URL, this.player.getVideoUrl()) .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); } @@ -586,7 +592,7 @@ public abstract class ServicePlayerActivity extends AppCompatActivity //////////////////////////////////////////////////////////////////////////// @Override - public void onQueueUpdate(PlayQueue queue) { + public void onQueueUpdate(final PlayQueue queue) { } @Override diff --git a/app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java index 1b00d872d..51f9f3ca2 100644 --- a/app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java @@ -34,9 +34,16 @@ import android.os.Build; import android.os.Handler; import android.preference.PreferenceManager; 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.Nullable; 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.util.AnimationUtils; import org.schabi.newpipe.views.ExpandableSurfaceView; -import org.schabi.newpipe.views.ExpandableSurfaceView; import java.util.ArrayList; import java.util.List; diff --git a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java index d102a93ec..8aa7120d7 100644 --- a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java +++ b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java @@ -22,7 +22,11 @@ package org.schabi.newpipe.player; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.annotation.SuppressLint; -import android.content.*; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.SharedPreferences; import android.database.ContentObserver; import android.graphics.Bitmap; import android.graphics.PixelFormat; @@ -35,9 +39,25 @@ import android.provider.Settings; import android.util.DisplayMetrics; import android.util.Log; import android.util.TypedValue; -import android.view.*; +import android.view.Display; +import android.view.GestureDetector; +import android.view.Gravity; +import android.view.KeyEvent; +import android.view.MotionEvent; +import android.view.Surface; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; import android.view.animation.AnticipateInterpolator; -import android.widget.*; +import android.widget.FrameLayout; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.PopupMenu; +import android.widget.ProgressBar; +import android.widget.RelativeLayout; +import android.widget.SeekBar; +import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; @@ -66,17 +86,35 @@ import org.schabi.newpipe.player.event.PlayerGestureListener; import org.schabi.newpipe.player.event.PlayerServiceEventListener; import org.schabi.newpipe.player.helper.PlaybackParameterDialog; import org.schabi.newpipe.player.helper.PlayerHelper; -import org.schabi.newpipe.player.playqueue.*; +import org.schabi.newpipe.player.playqueue.PlayQueue; +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.player.resolver.AudioPlaybackResolver; import org.schabi.newpipe.player.resolver.MediaSourceTag; import org.schabi.newpipe.player.resolver.VideoPlaybackResolver; -import org.schabi.newpipe.util.*; +import org.schabi.newpipe.util.AndroidTvUtils; +import org.schabi.newpipe.util.AnimationUtils; +import org.schabi.newpipe.util.Constants; +import org.schabi.newpipe.util.KoreUtil; +import org.schabi.newpipe.util.ListHelper; +import org.schabi.newpipe.util.NavigationHelper; +import org.schabi.newpipe.util.ShareUtils; import java.util.List; import static android.content.Context.WINDOW_SERVICE; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; -import static org.schabi.newpipe.player.MainPlayer.*; +import static org.schabi.newpipe.player.BackgroundPlayer.ACTION_CLOSE; +import static org.schabi.newpipe.player.MainPlayer.ACTION_FAST_FORWARD; +import static org.schabi.newpipe.player.MainPlayer.ACTION_FAST_REWIND; +import static org.schabi.newpipe.player.MainPlayer.ACTION_OPEN_CONTROLS; +import static org.schabi.newpipe.player.MainPlayer.ACTION_PLAY_NEXT; +import static org.schabi.newpipe.player.MainPlayer.ACTION_PLAY_PAUSE; +import static org.schabi.newpipe.player.MainPlayer.ACTION_PLAY_PREVIOUS; +import static org.schabi.newpipe.player.MainPlayer.ACTION_REPEAT; +import static org.schabi.newpipe.player.MainPlayer.NOTIFICATION_ID; import static org.schabi.newpipe.player.helper.PlayerHelper.MinimizeMode.MINIMIZE_ON_EXIT_MODE_BACKGROUND; import static org.schabi.newpipe.player.helper.PlayerHelper.getTimeString; import static org.schabi.newpipe.player.helper.PlayerHelper.isTablet; @@ -88,7 +126,7 @@ import static org.schabi.newpipe.util.ListHelper.getResolutionIndex; import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage; /** - * Unified UI for all players + * Unified UI for all players. * * @author mauriciocolli */ @@ -103,10 +141,10 @@ public class VideoPlayerImpl extends VideoPlayer static final String POPUP_SAVED_X = "popup_saved_x"; static final String POPUP_SAVED_Y = "popup_saved_y"; private static final int MINIMUM_SHOW_EXTRA_WIDTH_DP = 300; - private static final int IDLE_WINDOW_FLAGS = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | - WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; - private static final int ONGOING_PLAYBACK_WINDOW_FLAGS = IDLE_WINDOW_FLAGS | - WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; + private static final int IDLE_WINDOW_FLAGS = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE + | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; + private static final int ONGOING_PLAYBACK_WINDOW_FLAGS = IDLE_WINDOW_FLAGS + | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; private static final float MAX_GESTURE_LENGTH = 0.75f; private static final int NOTIFICATION_UPDATES_BEFORE_RESET = 60; @@ -163,7 +201,7 @@ public class VideoPlayerImpl extends VideoPlayer private final SharedPreferences defaultPreferences; private ContentObserver settingsContentObserver; @NonNull - final private AudioPlaybackResolver resolver; + private final AudioPlaybackResolver resolver; private int cachedDuration; private String cachedDurationString; @@ -178,16 +216,22 @@ public class VideoPlayerImpl extends VideoPlayer public boolean isPopupClosing = false; - private float screenWidth, screenHeight; - private float popupWidth, popupHeight; - private float minimumWidth, minimumHeight; - private float maximumWidth, maximumHeight; + private float screenWidth; + private float screenHeight; + private float popupWidth; + private float popupHeight; + private float minimumWidth; + private float minimumHeight; + private float maximumWidth; + private float maximumHeight; // Popup end @Override - public void handleIntent(Intent intent) { - if (intent.getStringExtra(VideoPlayer.PLAY_QUEUE_KEY) == null) return; + public void handleIntent(final Intent intent) { + if (intent.getStringExtra(VideoPlayer.PLAY_QUEUE_KEY) == null) { + return; + } final MainPlayer.PlayerType oldPlayerType = playerType; choosePlayerTypeFromIntent(intent); @@ -231,7 +275,7 @@ public class VideoPlayerImpl extends VideoPlayer @SuppressLint("ClickableViewAccessibility") @Override - public void initViews(View view) { + public void initViews(final View view) { super.initViews(view); this.titleTextView = view.findViewById(R.id.titleTextView); this.channelTextView = view.findViewById(R.id.channelTextView); @@ -272,7 +316,7 @@ public class VideoPlayerImpl extends VideoPlayer } @Override - protected void setupSubtitleView(@NonNull SubtitleView view, + protected void setupSubtitleView(final @NonNull SubtitleView view, final float captionScale, @NonNull final CaptionStyleCompat captionStyle) { if (popupPlayerSelected()) { @@ -292,8 +336,9 @@ public class VideoPlayerImpl extends VideoPlayer } /** - * This method ensures that popup and main players have different look. We use one layout for both players and - * need to decide what to show and what to hide. Additional measuring should be done inside {@link #setupElementsSize}. + * This method ensures that popup and main players have different look. + * We use one layout for both players and need to decide what to show and what to hide. + * Additional measuring should be done inside {@link #setupElementsSize}. * {@link #setControlsSize} is used to adapt the UI to fullscreen mode, multiWindow, navBar, etc */ private void setupElementsVisibility() { @@ -334,13 +379,14 @@ public class VideoPlayerImpl extends VideoPlayer final boolean supportedByKore = playQueue != null && playQueue.getItem() != null && KoreUtil.isServiceSupportedByKore(playQueue.getItem().getServiceId()); - final boolean kodiEnabled = defaultPreferences.getBoolean(service.getString(R.string.show_play_with_kodi_key), false); + final boolean kodiEnabled = defaultPreferences.getBoolean( + service.getString(R.string.show_play_with_kodi_key), false); playWithKodi.setVisibility(kodiEnabled && supportedByKore ? View.VISIBLE : View.GONE); openInBrowser.setVisibility(View.VISIBLE); muteButton.setVisibility(View.VISIBLE); playerCloseButton.setVisibility(isFullscreen ? View.GONE : View.VISIBLE); - // Top controls have a large minHeight which is allows to drag the player down in fullscreen mode (just larger area - // to make easy to locate by finger) + // Top controls have a large minHeight which is allows to drag the player + // down in fullscreen mode (just larger area to make easy to locate by finger) getTopControlsRoot().setClickable(true); getTopControlsRoot().setFocusable(true); } @@ -357,33 +403,47 @@ public class VideoPlayerImpl extends VideoPlayer } /** - * Changes padding, size of elements based on player selected right now. Popup player has small padding in comparison with the - * main player + * Changes padding, size of elements based on player selected right now. + * Popup player has small padding in comparison with the main player */ private void setupElementsSize() { if (popupPlayerSelected()) { - final int controlsPadding = service.getResources().getDimensionPixelSize(R.dimen.player_popup_controls_padding); - final int buttonsPadding = service.getResources().getDimensionPixelSize(R.dimen.player_popup_buttons_padding); + final int controlsPadding = service.getResources() + .getDimensionPixelSize(R.dimen.player_popup_controls_padding); + final int buttonsPadding = service.getResources() + .getDimensionPixelSize(R.dimen.player_popup_buttons_padding); getTopControlsRoot().setPaddingRelative(controlsPadding, 0, controlsPadding, 0); getBottomControlsRoot().setPaddingRelative(controlsPadding, 0, controlsPadding, 0); - getQualityTextView().setPadding(buttonsPadding, buttonsPadding, buttonsPadding, buttonsPadding); - getPlaybackSpeedTextView().setPadding(buttonsPadding, buttonsPadding, buttonsPadding, buttonsPadding); - getQualityTextView().setPadding(buttonsPadding, buttonsPadding, buttonsPadding, buttonsPadding); - getCaptionTextView().setPadding(buttonsPadding, buttonsPadding, buttonsPadding, buttonsPadding); + getQualityTextView().setPadding( + buttonsPadding, buttonsPadding, buttonsPadding, buttonsPadding); + getPlaybackSpeedTextView().setPadding( + buttonsPadding, buttonsPadding, buttonsPadding, buttonsPadding); + getQualityTextView().setPadding( + buttonsPadding, buttonsPadding, buttonsPadding, buttonsPadding); + getCaptionTextView().setPadding( + buttonsPadding, buttonsPadding, buttonsPadding, buttonsPadding); getQualityTextView().setMinimumWidth(0); getPlaybackSpeedTextView().setMinimumWidth(0); } else if (videoPlayerSelected()) { - final int buttonsMinWidth = service.getResources().getDimensionPixelSize(R.dimen.player_main_buttons_min_width); - final int playerTopPadding = service.getResources().getDimensionPixelSize(R.dimen.player_main_top_padding); - final int controlsPadding = service.getResources().getDimensionPixelSize(R.dimen.player_main_controls_padding); - final int buttonsPadding = service.getResources().getDimensionPixelSize(R.dimen.player_main_buttons_padding); - getTopControlsRoot().setPaddingRelative(controlsPadding, playerTopPadding, controlsPadding, 0); + final int buttonsMinWidth = service.getResources() + .getDimensionPixelSize(R.dimen.player_main_buttons_min_width); + final int playerTopPadding = service.getResources() + .getDimensionPixelSize(R.dimen.player_main_top_padding); + final int controlsPadding = service.getResources() + .getDimensionPixelSize(R.dimen.player_main_controls_padding); + final int buttonsPadding = service.getResources() + .getDimensionPixelSize(R.dimen.player_main_buttons_padding); + getTopControlsRoot().setPaddingRelative( + controlsPadding, playerTopPadding, controlsPadding, 0); getBottomControlsRoot().setPaddingRelative(controlsPadding, 0, controlsPadding, 0); - getQualityTextView().setPadding(buttonsPadding, buttonsPadding, buttonsPadding, buttonsPadding); - getPlaybackSpeedTextView().setPadding(buttonsPadding, buttonsPadding, buttonsPadding, buttonsPadding); + getQualityTextView().setPadding( + buttonsPadding, buttonsPadding, buttonsPadding, buttonsPadding); + getPlaybackSpeedTextView().setPadding( + buttonsPadding, buttonsPadding, buttonsPadding, buttonsPadding); getQualityTextView().setMinimumWidth(buttonsMinWidth); getPlaybackSpeedTextView().setMinimumWidth(buttonsMinWidth); - getCaptionTextView().setPadding(buttonsPadding, buttonsPadding, buttonsPadding, buttonsPadding); + getCaptionTextView().setPadding( + buttonsPadding, buttonsPadding, buttonsPadding, buttonsPadding); } } @@ -415,7 +475,9 @@ public class VideoPlayerImpl extends VideoPlayer settingsContentObserver = new ContentObserver(new Handler()) { @Override - public void onChange(boolean selfChange) { setupScreenRotationButton(); } + public void onChange(final boolean selfChange) { + setupScreenRotationButton(); + } }; service.getContentResolver().registerContentObserver( Settings.System.getUriFor(Settings.System.ACCELEROMETER_ROTATION), false, @@ -464,8 +526,11 @@ public class VideoPlayerImpl extends VideoPlayer public AppCompatActivity getParentActivity() { // ! instanceof ViewGroup means that view was added via windowManager for Popup - if (getRootView() == null || getRootView().getParent() == null || !(getRootView().getParent() instanceof ViewGroup)) + if (getRootView() == null + || getRootView().getParent() == null + || !(getRootView().getParent() instanceof ViewGroup)) { return null; + } final ViewGroup parent = (ViewGroup) getRootView().getParent(); return (AppCompatActivity) parent.getContext(); @@ -489,9 +554,9 @@ public class VideoPlayerImpl extends VideoPlayer } } - private void setShuffleButton(final ImageButton shuffleButton, final boolean shuffled) { + private void setShuffleButton(final ImageButton button, final boolean shuffled) { final int shuffleAlpha = shuffled ? 255 : 77; - shuffleButton.setImageAlpha(shuffleAlpha); + button.setImageAlpha(shuffleAlpha); } //////////////////////////////////////////////////////////////////////////// @@ -499,12 +564,15 @@ public class VideoPlayerImpl extends VideoPlayer //////////////////////////////////////////////////////////////////////////// @Override - public void onPlaybackParameterChanged(float playbackTempo, float playbackPitch, boolean playbackSkipSilence) { + public void onPlaybackParameterChanged(final float playbackTempo, final float playbackPitch, + final boolean playbackSkipSilence) { setPlaybackParameters(playbackTempo, playbackPitch, playbackSkipSilence); } @Override - public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) { + public void onVideoSizeChanged(final int width, final int height, + final int unappliedRotationDegrees, + final float pixelWidthHeightRatio) { super.onVideoSizeChanged(width, height, unappliedRotationDegrees, pixelWidthHeightRatio); isVerticalVideo = width < height; prepareOrientation(); @@ -516,7 +584,7 @@ public class VideoPlayerImpl extends VideoPlayer //////////////////////////////////////////////////////////////////////////*/ @Override - public void onRepeatModeChanged(int i) { + public void onRepeatModeChanged(final int i) { super.onRepeatModeChanged(i); updatePlaybackButtons(); updatePlayback(); @@ -536,11 +604,12 @@ public class VideoPlayerImpl extends VideoPlayer //////////////////////////////////////////////////////////////////////////*/ @Override - public void onPlayerError(ExoPlaybackException error) { + public void onPlayerError(final ExoPlaybackException error) { super.onPlayerError(error); - if (fragmentListener != null) + if (fragmentListener != null) { fragmentListener.onPlayerError(error); + } } protected void onMetadataChanged(@NonNull final MediaSourceTag tag) { @@ -563,7 +632,9 @@ public class VideoPlayerImpl extends VideoPlayer @Override public void onPlaybackShutdown() { - if (DEBUG) Log.d(TAG, "onPlaybackShutdown() called"); + if (DEBUG) { + Log.d(TAG, "onPlaybackShutdown() called"); + } // Override it because we don't want playerImpl destroyed } @@ -575,14 +646,16 @@ public class VideoPlayerImpl extends VideoPlayer } @Override - public void onUpdateProgress(final int currentProgress, final int duration, final int bufferPercent) { + public void onUpdateProgress(final int currentProgress, + final int duration, final int bufferPercent) { super.onUpdateProgress(currentProgress, duration, bufferPercent); updateProgress(currentProgress, duration, bufferPercent); if (!shouldUpdateOnProgress || getCurrentState() == BasePlayer.STATE_COMPLETED - || getCurrentState() == BasePlayer.STATE_PAUSED || getPlayQueue() == null) + || getCurrentState() == BasePlayer.STATE_PAUSED || getPlayQueue() == null) { return; + } if (timesNotificationUpdated > NOTIFICATION_UPDATES_BEFORE_RESET) { service.resetNotification(); @@ -594,9 +667,11 @@ public class VideoPlayerImpl extends VideoPlayer cachedDurationString = getTimeString(duration); } service.getBigNotRemoteView() - .setProgressBar(R.id.notificationProgressBar, duration, currentProgress, false); + .setProgressBar(R.id.notificationProgressBar, + duration, currentProgress, false); service.getBigNotRemoteView() - .setTextViewText(R.id.notificationTime, getTimeString(currentProgress) + " / " + cachedDurationString); + .setTextViewText(R.id.notificationTime, + getTimeString(currentProgress) + " / " + cachedDurationString); } if (service.getNotRemoteView() != null) { service.getNotRemoteView() @@ -610,9 +685,9 @@ public class VideoPlayerImpl extends VideoPlayer public MediaSource sourceOf(final PlayQueueItem item, final StreamInfo info) { // For LiveStream or video/popup players we can use super() method // but not for audio player - if (!audioOnly) + if (!audioOnly) { return super.sourceOf(item, info); - else { + } else { return resolver.resolve(info); } } @@ -630,10 +705,12 @@ public class VideoPlayerImpl extends VideoPlayer } @Override - protected void initPlayback(@NonNull final PlayQueue queue, final int repeatMode, final float playbackSpeed, - final float playbackPitch, final boolean playbackSkipSilence, + protected void initPlayback(@NonNull final PlayQueue queue, final int repeatMode, + final float playbackSpeed, final float playbackPitch, + final boolean playbackSkipSilence, final boolean playOnReady, final boolean isMuted) { - super.initPlayback(queue, repeatMode, playbackSpeed, playbackPitch, playbackSkipSilence, playOnReady, isMuted); + super.initPlayback(queue, repeatMode, playbackSpeed, playbackPitch, + playbackSkipSilence, playOnReady, isMuted); updateQueue(); } @@ -643,8 +720,12 @@ public class VideoPlayerImpl extends VideoPlayer @Override public void toggleFullscreen() { - if (DEBUG) Log.d(TAG, "toggleFullscreen() called"); - if (simpleExoPlayer == null || getCurrentMetadata() == null) return; + if (DEBUG) { + Log.d(TAG, "toggleFullscreen() called"); + } + if (simpleExoPlayer == null || getCurrentMetadata() == null) { + return; + } if (popupPlayerSelected()) { setRecovery(); @@ -663,7 +744,8 @@ public class VideoPlayerImpl extends VideoPlayer isMuted() ); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.putExtra(Constants.KEY_SERVICE_ID, getCurrentMetadata().getMetadata().getServiceId()); + intent.putExtra(Constants.KEY_SERVICE_ID, + getCurrentMetadata().getMetadata().getServiceId()); intent.putExtra(Constants.KEY_LINK_TYPE, StreamingService.LinkType.STREAM); intent.putExtra(Constants.KEY_URL, getVideoUrl()); intent.putExtra(Constants.KEY_TITLE, getVideoTitle()); @@ -672,7 +754,9 @@ public class VideoPlayerImpl extends VideoPlayer context.startActivity(intent); return; } else { - if (fragmentListener == null) return; + if (fragmentListener == null) { + return; + } isFullscreen = !isFullscreen; setControlsSize(); @@ -692,7 +776,7 @@ public class VideoPlayerImpl extends VideoPlayer } @Override - public void onClick(View v) { + public void onClick(final View v) { super.onClick(v); if (v.getId() == playPauseButton.getId()) { onPlayPause(); @@ -720,8 +804,11 @@ public class VideoPlayerImpl extends VideoPlayer } else if (v.getId() == fullscreenButton.getId()) { toggleFullscreen(); } else if (v.getId() == screenRotationButton.getId()) { - if (!isVerticalVideo) fragmentListener.onScreenRotationButtonClicked(); - else toggleFullscreen(); + if (!isVerticalVideo) { + fragmentListener.onScreenRotationButtonClicked(); + } else { + toggleFullscreen(); + } } else if (v.getId() == muteButton.getId()) { onMuteUnmuteButtonClicked(); } else if (v.getId() == playerCloseButton.getId()) { @@ -732,15 +819,18 @@ public class VideoPlayerImpl extends VideoPlayer getControlsVisibilityHandler().removeCallbacksAndMessages(null); animateView(getControlsRoot(), true, DEFAULT_CONTROLS_DURATION, 0, () -> { if (getCurrentState() == STATE_PLAYING && !isSomePopupMenuVisible()) { - if (v.getId() == playPauseButton.getId()) hideControls(0, 0); - else safeHideControls(DEFAULT_CONTROLS_DURATION, DEFAULT_CONTROLS_HIDE_TIME); + if (v.getId() == playPauseButton.getId()) { + hideControls(0, 0); + } else { + safeHideControls(DEFAULT_CONTROLS_DURATION, DEFAULT_CONTROLS_HIDE_TIME); + } } }); } } @Override - public boolean onLongClick(View v) { + public boolean onLongClick(final View v) { if (v.getId() == moreOptionsButton.getId() && isFullscreen()) { fragmentListener.onMoreOptionsLongClicked(); hideControls(0, 0); @@ -757,25 +847,30 @@ public class VideoPlayerImpl extends VideoPlayer updatePlaybackButtons(); getControlsRoot().setVisibility(View.INVISIBLE); - animateView(queueLayout, SLIDE_AND_ALPHA,true, + animateView(queueLayout, SLIDE_AND_ALPHA, true, DEFAULT_CONTROLS_DURATION); itemsList.scrollToPosition(playQueue.getIndex()); } public void onQueueClosed() { - if (!queueVisible) return; + if (!queueVisible) { + return; + } - animateView(queueLayout, SLIDE_AND_ALPHA,false, + animateView(queueLayout, SLIDE_AND_ALPHA, false, DEFAULT_CONTROLS_DURATION, 0, () -> { - // Even when queueLayout is GONE it receives touch events and ruins normal behavior of the app. This line fixes it + // Even when queueLayout is GONE it receives touch events + // and ruins normal behavior of the app. This line fixes it queueLayout.setTranslationY(-queueLayout.getHeight() * 5); }); queueVisible = false; } private void onMoreOptionsClicked() { - if (DEBUG) Log.d(TAG, "onMoreOptionsClicked() called"); + if (DEBUG) { + Log.d(TAG, "onMoreOptionsClicked() called"); + } final boolean isMoreControlsVisible = secondaryControls.getVisibility() == View.VISIBLE; @@ -784,9 +879,12 @@ public class VideoPlayerImpl extends VideoPlayer animateView(secondaryControls, SLIDE_AND_ALPHA, !isMoreControlsVisible, DEFAULT_CONTROLS_DURATION, 0, () -> { - // Fix for a ripple effect on background drawable. When view returns from GONE state it takes more - // milliseconds than returning from INVISIBLE state. And the delay makes ripple background end to fast - if (isMoreControlsVisible) secondaryControls.setVisibility(View.INVISIBLE); + // Fix for a ripple effect on background drawable. + // When view returns from GONE state it takes more milliseconds than returning + // from INVISIBLE state. And the delay makes ripple background end to fast + if (isMoreControlsVisible) { + secondaryControls.setVisibility(View.INVISIBLE); + } }); showControls(DEFAULT_CONTROLS_DURATION); } @@ -799,20 +897,27 @@ public class VideoPlayerImpl extends VideoPlayer } private void onPlayWithKodiClicked() { - if (getCurrentMetadata() == null) return; + if (getCurrentMetadata() == null) { + return; + } onPause(); try { NavigationHelper.playWithKore(getParentActivity(), Uri.parse(getVideoUrl())); } catch (Exception e) { - if (DEBUG) Log.i(TAG, "Failed to start kore", e); + if (DEBUG) { + Log.i(TAG, "Failed to start kore", e); + } showInstallKoreDialog(getParentActivity()); } } private void onOpenInBrowserClicked() { - if (getCurrentMetadata() == null) return; + if (getCurrentMetadata() == null) { + return; + } - ShareUtils.openUrlInBrowser(getParentActivity(), getCurrentMetadata().getMetadata().getOriginalUrl()); + ShareUtils.openUrlInBrowser(getParentActivity(), + getCurrentMetadata().getMetadata().getOriginalUrl()); } private static void showInstallKoreDialog(final Context context) { @@ -828,23 +933,30 @@ public class VideoPlayerImpl extends VideoPlayer private void setupScreenRotationButton() { final boolean orientationLocked = PlayerHelper.globalScreenOrientationLocked(service); final boolean tabletInLandscape = isTablet(service) && service.isLandscape(); - final boolean showButton = videoPlayerSelected() && (orientationLocked || isVerticalVideo || tabletInLandscape); + final boolean showButton = videoPlayerSelected() + && (orientationLocked || isVerticalVideo || tabletInLandscape); screenRotationButton.setVisibility(showButton ? View.VISIBLE : View.GONE); - screenRotationButton.setImageDrawable(service.getResources().getDrawable( - isFullscreen() ? R.drawable.ic_fullscreen_exit_white_24dp : R.drawable.ic_fullscreen_white_24dp)); + screenRotationButton.setImageDrawable(service.getResources().getDrawable(isFullscreen() + ? R.drawable.ic_fullscreen_exit_white_24dp + : R.drawable.ic_fullscreen_white_24dp)); } private void prepareOrientation() { final boolean orientationLocked = PlayerHelper.globalScreenOrientationLocked(service); - if (orientationLocked && isFullscreen() && service.isLandscape() == isVerticalVideo && fragmentListener != null) + if (orientationLocked + && isFullscreen() + && service.isLandscape() == isVerticalVideo + && fragmentListener != null) { fragmentListener.onScreenRotationButtonClicked(); + } } @Override public void onPlaybackSpeedClicked() { if (videoPlayerSelected()) { PlaybackParameterDialog - .newInstance(getPlaybackSpeed(), getPlaybackPitch(), getPlaybackSkipSilence(), this) + .newInstance( + getPlaybackSpeed(), getPlaybackPitch(), getPlaybackSkipSilence(), this) .show(getParentActivity().getSupportFragmentManager(), null); } else { super.onPlaybackSpeedClicked(); @@ -852,13 +964,15 @@ public class VideoPlayerImpl extends VideoPlayer } @Override - public void onStopTrackingTouch(SeekBar seekBar) { + public void onStopTrackingTouch(final SeekBar seekBar) { super.onStopTrackingTouch(seekBar); - if (wasPlaying()) showControlsThenHide(); + if (wasPlaying()) { + showControlsThenHide(); + } } @Override - public void onDismiss(PopupMenu menu) { + public void onDismiss(final PopupMenu menu) { super.onDismiss(menu); if (isPlaying()) { hideControls(DEFAULT_CONTROLS_DURATION, 0); @@ -866,16 +980,20 @@ public class VideoPlayerImpl extends VideoPlayer } @Override - public void onLayoutChange(final View view, int l, int t, int r, int b, - int ol, int ot, int or, int ob) { + @SuppressWarnings("checkstyle:ParameterNumber") + public void onLayoutChange(final View view, final int l, final int t, final int r, final int b, + final int ol, final int ot, final int or, final int ob) { if (l != ol || t != ot || r != or || b != ob) { // Use smaller value to be consistent between screen orientations // (and to make usage easier) - int width = r - l, height = b - t; + int width = r - l; + int height = b - t; int min = Math.min(width, height); maxGestureLength = (int) (min * MAX_GESTURE_LENGTH); - if (DEBUG) Log.d(TAG, "maxGestureLength = " + maxGestureLength); + if (DEBUG) { + Log.d(TAG, "maxGestureLength = " + maxGestureLength); + } volumeProgressBar.setMax(maxGestureLength); brightnessProgressBar.setMax(maxGestureLength); @@ -884,15 +1002,18 @@ public class VideoPlayerImpl extends VideoPlayer queueLayout.getLayoutParams().height = height - queueLayout.getTop(); if (popupPlayerSelected()) { - float widthDp = Math.abs(r - l) / service.getResources().getDisplayMetrics().density; - final int visibility = widthDp > MINIMUM_SHOW_EXTRA_WIDTH_DP ? View.VISIBLE : View.GONE; + float widthDp = Math.abs(r - l) / service.getResources() + .getDisplayMetrics().density; + final int visibility = widthDp > MINIMUM_SHOW_EXTRA_WIDTH_DP + ? View.VISIBLE + : View.GONE; secondaryControls.setVisibility(visibility); } } } @Override - protected int nextResizeMode(int currentResizeMode) { + protected int nextResizeMode(final int currentResizeMode) { final int newResizeMode; switch (currentResizeMode) { case AspectRatioFrameLayout.RESIZE_MODE_FIT: @@ -910,7 +1031,7 @@ public class VideoPlayerImpl extends VideoPlayer return newResizeMode; } - private void storeResizeMode(@AspectRatioFrameLayout.ResizeMode int resizeMode) { + private void storeResizeMode(final @AspectRatioFrameLayout.ResizeMode int resizeMode) { defaultPreferences.edit() .putInt(service.getString(R.string.last_resize_mode), resizeMode) .apply(); @@ -918,22 +1039,25 @@ public class VideoPlayerImpl extends VideoPlayer private void restoreResizeMode() { setResizeMode(defaultPreferences.getInt( - service.getString(R.string.last_resize_mode), AspectRatioFrameLayout.RESIZE_MODE_FIT)); + service.getString(R.string.last_resize_mode), + AspectRatioFrameLayout.RESIZE_MODE_FIT)); } @Override protected VideoPlaybackResolver.QualityResolver getQualityResolver() { return new VideoPlaybackResolver.QualityResolver() { @Override - public int getDefaultResolutionIndex(List sortedVideos) { - return videoPlayerSelected() ? ListHelper.getDefaultResolutionIndex(context, sortedVideos) + public int getDefaultResolutionIndex(final List sortedVideos) { + return videoPlayerSelected() + ? ListHelper.getDefaultResolutionIndex(context, sortedVideos) : ListHelper.getPopupDefaultResolutionIndex(context, sortedVideos); } @Override - public int getOverrideResolutionIndex(List sortedVideos, - String playbackQuality) { - return videoPlayerSelected() ? getResolutionIndex(context, sortedVideos, playbackQuality) + public int getOverrideResolutionIndex(final List sortedVideos, + final String playbackQuality) { + return videoPlayerSelected() + ? getResolutionIndex(context, sortedVideos, playbackQuality) : getPopupResolutionIndex(context, sortedVideos, playbackQuality); } }; @@ -945,15 +1069,17 @@ public class VideoPlayerImpl extends VideoPlayer private void animatePlayButtons(final boolean show, final int duration) { animateView(playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, show, duration); - if (playQueue.getIndex() > 0) + if (playQueue.getIndex() > 0) { animateView(playPreviousButton, AnimationUtils.Type.SCALE_AND_ALPHA, show, duration); - if (playQueue.getIndex() + 1 < playQueue.getStreams().size()) + } + if (playQueue.getIndex() + 1 < playQueue.getStreams().size()) { animateView(playNextButton, AnimationUtils.Type.SCALE_AND_ALPHA, show, duration); + } } @Override - public void changeState(int state) { + public void changeState(final int state) { super.changeState(state); updatePlayback(); } @@ -1011,9 +1137,11 @@ public class VideoPlayerImpl extends VideoPlayer service.resetNotification(); service.updateNotification(R.drawable.ic_play_arrow_white_24dp); - // Remove running notification when user don't want music (or video in popup) to be played in background - if (!minimizeOnPopupEnabled() && !backgroundPlaybackEnabled() && videoPlayerSelected()) + // Remove running notification when user don't want music (or video in popup) + // to be played in background + if (!minimizeOnPopupEnabled() && !backgroundPlaybackEnabled() && videoPlayerSelected()) { service.stopForeground(true); + } getRootView().setKeepScreenOn(false); } @@ -1057,9 +1185,12 @@ public class VideoPlayerImpl extends VideoPlayer //////////////////////////////////////////////////////////////////////////*/ @Override - protected void setupBroadcastReceiver(IntentFilter intentFilter) { + protected void setupBroadcastReceiver(final IntentFilter intentFilter) { super.setupBroadcastReceiver(intentFilter); - if (DEBUG) Log.d(TAG, "setupBroadcastReceiver() called with: intentFilter = [" + intentFilter + "]"); + if (DEBUG) { + Log.d(TAG, "setupBroadcastReceiver() called with: " + + "intentFilter = [" + intentFilter + "]"); + } intentFilter.addAction(ACTION_CLOSE); intentFilter.addAction(ACTION_PLAY_PAUSE); @@ -1081,12 +1212,15 @@ public class VideoPlayerImpl extends VideoPlayer } @Override - public void onBroadcastReceived(Intent intent) { + public void onBroadcastReceived(final Intent intent) { super.onBroadcastReceived(intent); - if (intent == null || intent.getAction() == null) + 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()) { case ACTION_CLOSE: @@ -1115,7 +1249,8 @@ public class VideoPlayerImpl extends VideoPlayer break; case VideoDetailFragment.ACTION_VIDEO_FRAGMENT_STOPPED: // This will be called when user goes to another app/activity, turns off a screen. - // We don't want to interrupt playback and don't want to see notification if player is stopped. + // We don't want to interrupt playback and don't want to see notification + // if player is stopped. // Next lines of code will enable background playback if needed if (videoPlayerSelected() && (isPlaying() || isLoading())) { if (backgroundPlaybackEnabled()) { @@ -1139,29 +1274,42 @@ public class VideoPlayerImpl extends VideoPlayer checkPopupPositionBounds(); } - // The only situation I need to re-calculate elements sizes is when a user rotates a device from landscape to landscape - // because in that case the controls should be aligned to another side of a screen. The problem is when user leaves - // the app and returns back (while the app in landscape) Android reports via DisplayMetrics that orientation is - // portrait and it gives wrong sizes calculations. Let's skip re-calculation in every case but landscape + // The only situation I need to re-calculate elements sizes is + // when a user rotates a device from landscape to landscape + // because in that case the controls should be aligned to another side of a screen. + // The problem is when user leaves the app and returns back + // (while the app in landscape) Android reports via DisplayMetrics that orientation + // is portrait and it gives wrong sizes calculations. + // Let's skip re-calculation in every case but landscape final boolean reportedOrientationIsLandscape = service.isLandscape(); - final boolean actualOrientationIsLandscape = context.getResources().getConfiguration().orientation == ORIENTATION_LANDSCAPE; - if (reportedOrientationIsLandscape && actualOrientationIsLandscape) setControlsSize(); - // Close it because when changing orientation from portrait (in fullscreen mode) the size of queue layout can be - // larger than the screen size + final boolean actualOrientationIsLandscape = context.getResources() + .getConfiguration().orientation == ORIENTATION_LANDSCAPE; + if (reportedOrientationIsLandscape && actualOrientationIsLandscape) { + setControlsSize(); + } + // Close it because when changing orientation from portrait + // (in fullscreen mode) the size of queue layout can be larger than the screen size onQueueClosed(); break; case Intent.ACTION_SCREEN_ON: shouldUpdateOnProgress = true; - // Interrupt playback only when screen turns on and user is watching video in popup player - // Same action for video player will be handled in ACTION_VIDEO_FRAGMENT_RESUMED event - if (backgroundPlaybackEnabled() && popupPlayerSelected() && (isPlaying() || isLoading())) + // Interrupt playback only when screen turns on + // and user is watching video in popup player. + // Same actions for video player will be handled in ACTION_VIDEO_FRAGMENT_RESUMED + if (backgroundPlaybackEnabled() + && popupPlayerSelected() + && (isPlaying() || isLoading())) { useVideoSource(true); + } break; case Intent.ACTION_SCREEN_OFF: shouldUpdateOnProgress = false; // Interrupt playback only when screen turns off with popup player working - if (backgroundPlaybackEnabled() && popupPlayerSelected() && (isPlaying() || isLoading())) + if (backgroundPlaybackEnabled() + && popupPlayerSelected() + && (isPlaying() || isLoading())) { useVideoSource(false); + } break; } service.resetNotification(); @@ -1172,8 +1320,9 @@ public class VideoPlayerImpl extends VideoPlayer //////////////////////////////////////////////////////////////////////////*/ @Override - public void onLoadingComplete(String imageUri, View view, - Bitmap loadedImage) { + public void onLoadingComplete(final String imageUri, + final View view, + final Bitmap loadedImage) { super.onLoadingComplete(imageUri, view, loadedImage); // rebuild notification here since remote view does not release bitmaps, // causing memory leaks @@ -1182,14 +1331,16 @@ public class VideoPlayerImpl extends VideoPlayer } @Override - public void onLoadingFailed(String imageUri, View view, FailReason failReason) { + public void onLoadingFailed(final String imageUri, + final View view, + final FailReason failReason) { super.onLoadingFailed(imageUri, view, failReason); service.resetNotification(); service.updateNotification(-1); } @Override - public void onLoadingCancelled(String imageUri, View view) { + public void onLoadingCancelled(final String imageUri, final View view) { super.onLoadingCancelled(imageUri, view); service.resetNotification(); service.updateNotification(-1); @@ -1201,8 +1352,10 @@ public class VideoPlayerImpl extends VideoPlayer private void setInitialGestureValues() { if (getAudioReactor() != null) { - final float currentVolumeNormalized = (float) getAudioReactor().getVolume() / getAudioReactor().getMaxVolume(); - volumeProgressBar.setProgress((int) (volumeProgressBar.getMax() * currentVolumeNormalized)); + final float currentVolumeNormalized = (float) getAudioReactor() + .getVolume() / getAudioReactor().getMaxVolume(); + volumeProgressBar.setProgress( + (int) (volumeProgressBar.getMax() * currentVolumeNormalized)); } } @@ -1222,7 +1375,8 @@ public class VideoPlayerImpl extends VideoPlayer } public boolean minimizeOnPopupEnabled() { - return PlayerHelper.getMinimizeOnExitAction(service) == PlayerHelper.MinimizeMode.MINIMIZE_ON_EXIT_MODE_POPUP; + return PlayerHelper.getMinimizeOnExitAction(service) + == PlayerHelper.MinimizeMode.MINIMIZE_ON_EXIT_MODE_POPUP; } public boolean audioPlayerSelected() { @@ -1270,7 +1424,9 @@ public class VideoPlayerImpl extends VideoPlayer @Override public void showControlsThenHide() { - if (queueVisible) return; + if (queueVisible) { + return; + } showOrHideButtons(); showSystemUIPartially(); @@ -1279,7 +1435,9 @@ public class VideoPlayerImpl extends VideoPlayer @Override public void showControls(final long duration) { - if (queueVisible) return; + if (queueVisible) { + return; + } showOrHideButtons(); showSystemUIPartially(); @@ -1288,31 +1446,40 @@ public class VideoPlayerImpl extends VideoPlayer @Override public void hideControls(final long duration, final long delay) { - if (DEBUG) Log.d(TAG, "hideControls() called with: delay = [" + delay + "]"); + if (DEBUG) { + Log.d(TAG, "hideControls() called with: delay = [" + delay + "]"); + } showOrHideButtons(); getControlsVisibilityHandler().removeCallbacksAndMessages(null); getControlsVisibilityHandler().postDelayed(() -> - animateView(getControlsRoot(), false, duration, 0, - this::hideSystemUIIfNeeded), delay + animateView(getControlsRoot(), false, duration, 0, + this::hideSystemUIIfNeeded), delay ); } @Override - public void safeHideControls(long duration, long delay) { + public void safeHideControls(final long duration, final long delay) { if (getControlsRoot().isInTouchMode()) { hideControls(duration, delay); } } private void showOrHideButtons() { - if (playQueue == null) + if (playQueue == null) { return; + } - playPreviousButton.setVisibility(playQueue.getIndex() == 0 ? View.INVISIBLE : View.VISIBLE); - playNextButton.setVisibility(playQueue.getIndex() + 1 == playQueue.getStreams().size() ? View.INVISIBLE : View.VISIBLE); - queueButton.setVisibility(playQueue.getStreams().size() <= 1 || popupPlayerSelected() ? View.GONE : View.VISIBLE); + playPreviousButton.setVisibility(playQueue.getIndex() == 0 + ? View.INVISIBLE + : View.VISIBLE); + playNextButton.setVisibility(playQueue.getIndex() + 1 == playQueue.getStreams().size() + ? View.INVISIBLE + : View.VISIBLE); + queueButton.setVisibility(playQueue.getStreams().size() <= 1 || popupPlayerSelected() + ? View.GONE + : View.VISIBLE); } private void showSystemUIPartially() { @@ -1324,46 +1491,62 @@ public class VideoPlayerImpl extends VideoPlayer @Override public void hideSystemUIIfNeeded() { - if (fragmentListener != null) + if (fragmentListener != null) { fragmentListener.hideSystemUiIfNeeded(); + } } /** - * Measures width and height of controls visible on screen. It ensures that controls will be side-by-side with - * NavigationBar and notches but not under them. Tablets have only bottom NavigationBar + * Measures width and height of controls visible on screen. + * It ensures that controls will be side-by-side with NavigationBar and notches + * but not under them. Tablets have only bottom NavigationBar */ public void setControlsSize() { final Point size = new Point(); final Display display = getRootView().getDisplay(); - if (display == null || !videoPlayerSelected()) return; + if (display == null || !videoPlayerSelected()) { + return; + } // This method will give a correct size of a usable area of a window. // It doesn't include NavigationBar, notches, etc. display.getSize(size); - final int width = isFullscreen ? (service.isLandscape() ? size.x : size.y) : ViewGroup.LayoutParams.MATCH_PARENT; - final int gravity = isFullscreen ? (display.getRotation() == Surface.ROTATION_90 ? Gravity.START : Gravity.END) : Gravity.TOP; + final int width = isFullscreen + ? (service.isLandscape() + ? size.x : size.y) : ViewGroup.LayoutParams.MATCH_PARENT; + final int gravity = isFullscreen + ? (display.getRotation() == Surface.ROTATION_90 + ? Gravity.START : Gravity.END) + : Gravity.TOP; getTopControlsRoot().getLayoutParams().width = width; - final RelativeLayout.LayoutParams topParams = ((RelativeLayout.LayoutParams) getTopControlsRoot().getLayoutParams()); + final RelativeLayout.LayoutParams topParams = + ((RelativeLayout.LayoutParams) getTopControlsRoot().getLayoutParams()); topParams.removeRule(RelativeLayout.ALIGN_PARENT_START); topParams.removeRule(RelativeLayout.ALIGN_PARENT_END); - topParams.addRule(gravity == Gravity.END ? RelativeLayout.ALIGN_PARENT_END : RelativeLayout.ALIGN_PARENT_START); + topParams.addRule(gravity == Gravity.END + ? RelativeLayout.ALIGN_PARENT_END + : RelativeLayout.ALIGN_PARENT_START); getTopControlsRoot().requestLayout(); getBottomControlsRoot().getLayoutParams().width = width; - final RelativeLayout.LayoutParams bottomParams = ((RelativeLayout.LayoutParams) getBottomControlsRoot().getLayoutParams()); + final RelativeLayout.LayoutParams bottomParams = + ((RelativeLayout.LayoutParams) getBottomControlsRoot().getLayoutParams()); bottomParams.removeRule(RelativeLayout.ALIGN_PARENT_START); bottomParams.removeRule(RelativeLayout.ALIGN_PARENT_END); - bottomParams.addRule(gravity == Gravity.END ? RelativeLayout.ALIGN_PARENT_END : RelativeLayout.ALIGN_PARENT_START); + bottomParams.addRule(gravity == Gravity.END + ? RelativeLayout.ALIGN_PARENT_END + : RelativeLayout.ALIGN_PARENT_START); getBottomControlsRoot().requestLayout(); final ViewGroup controlsRoot = getRootView().findViewById(R.id.playbackWindowRoot); - // In tablet navigationBar located at the bottom of the screen. And the situations when we need to set custom height is - // in fullscreen mode in tablet in non-multiWindow mode or with vertical video. Other than that MATCH_PARENT is good + // In tablet navigationBar located at the bottom of the screen. + // And the situations when we need to set custom height is + // in fullscreen mode in tablet in non-multiWindow mode or with vertical video. + // Other than that MATCH_PARENT is good final boolean navBarAtTheBottom = PlayerHelper.isTablet(service) || !service.isLandscape(); - controlsRoot.getLayoutParams().height = isFullscreen && !isInMultiWindow() && navBarAtTheBottom - ? size.y - : ViewGroup.LayoutParams.MATCH_PARENT; + controlsRoot.getLayoutParams().height = isFullscreen && !isInMultiWindow() + && navBarAtTheBottom ? size.y : ViewGroup.LayoutParams.MATCH_PARENT; controlsRoot.requestLayout(); final int topPadding = isFullscreen && !isInMultiWindow() ? getStatusBarHeight() : 0; @@ -1372,22 +1555,28 @@ public class VideoPlayerImpl extends VideoPlayer } /** - * @return statusBar height that was found inside system resources or default value if no value was provided inside resources + * @return statusBar height that was found inside system resources + * or default value if no value was provided inside resources */ private int getStatusBarHeight() { int statusBarHeight = 0; - final int resourceId = service.getResources().getIdentifier("status_bar_height_landscape", "dimen", "android"); - if (resourceId > 0) statusBarHeight = service.getResources().getDimensionPixelSize(resourceId); + final int resourceId = service.getResources().getIdentifier( + "status_bar_height_landscape", "dimen", "android"); + if (resourceId > 0) { + statusBarHeight = service.getResources().getDimensionPixelSize(resourceId); + } if (statusBarHeight == 0) { - // Some devices provide wrong value for status bar height in landscape mode, this is workaround + // Some devices provide wrong value for status bar height in landscape mode, + // this is workaround final DisplayMetrics metrics = getRootView().getResources().getDisplayMetrics(); - statusBarHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24, metrics); + statusBarHeight = (int) TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, 24, metrics); } return statusBarHeight; } - protected void setMuteButton(final ImageButton muteButton, final boolean isMuted) { - muteButton.setImageDrawable(AppCompatResources.getDrawable(service, isMuted + protected void setMuteButton(final ImageButton button, final boolean isMuted) { + button.setImageDrawable(AppCompatResources.getDrawable(service, isMuted ? R.drawable.ic_volume_off_white_24dp : R.drawable.ic_volume_up_white_24dp)); } @@ -1396,12 +1585,18 @@ public class VideoPlayerImpl extends VideoPlayer */ private boolean isInMultiWindow() { final AppCompatActivity parent = getParentActivity(); - return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && parent != null && parent.isInMultiWindowMode(); + return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N + && parent != null + && parent.isInMultiWindowMode(); } private void updatePlaybackButtons() { - if (repeatButton == null || shuffleButton == null || - simpleExoPlayer == null || playQueue == null) return; + if (repeatButton == null + || shuffleButton == null + || simpleExoPlayer == null + || playQueue == null) { + return; + } setRepeatModeButton(repeatButton, getRepeatMode()); setShuffleButton(shuffleButton, playQueue.isShuffled()); @@ -1409,10 +1604,19 @@ public class VideoPlayerImpl extends VideoPlayer public void checkLandscape() { final AppCompatActivity parent = getParentActivity(); - final boolean videoInLandscapeButNotInFullscreen = service.isLandscape() && !isFullscreen() && videoPlayerSelected() && !audioOnly; - final boolean playingState = getCurrentState() != STATE_COMPLETED && getCurrentState() != STATE_PAUSED; - if (parent != null && videoInLandscapeButNotInFullscreen && playingState && !PlayerHelper.isTablet(service)) + final boolean videoInLandscapeButNotInFullscreen = service.isLandscape() + && !isFullscreen() + && videoPlayerSelected() + && !audioOnly; + + final boolean playingState = getCurrentState() != STATE_COMPLETED + && getCurrentState() != STATE_PAUSED; + if (parent != null + && videoInLandscapeButNotInFullscreen + && playingState + && !PlayerHelper.isTablet(service)) { toggleFullscreen(); + } setControlsSize(); } @@ -1434,12 +1638,16 @@ public class VideoPlayerImpl extends VideoPlayer } public void useVideoSource(final boolean video) { - if (playQueue == null || audioOnly == !video || audioPlayerSelected()) + if (playQueue == null || audioOnly == !video || audioPlayerSelected()) { return; + } audioOnly = !video; - // When a user returns from background controls could be hidden but systemUI will be shown 100%. Hide it - if (!audioOnly && !isControlsVisible()) hideSystemUIIfNeeded(); + // When a user returns from background controls could be hidden + // but systemUI will be shown 100%. Hide it + if (!audioOnly && !isControlsVisible()) { + hideSystemUIIfNeeded(); + } setRecovery(); reload(); } @@ -1447,7 +1655,7 @@ public class VideoPlayerImpl extends VideoPlayer private OnScrollBelowItemsListener getQueueScrollListener() { return new OnScrollBelowItemsListener() { @Override - public void onScrolledDown(RecyclerView recyclerView) { + public void onScrolledDown(final RecyclerView recyclerView) { if (playQueue != null && !playQueue.isComplete()) { playQueue.fetch(); } else if (itemsList != null) { @@ -1460,13 +1668,17 @@ public class VideoPlayerImpl extends VideoPlayer private ItemTouchHelper.SimpleCallback getItemTouchCallback() { return new PlayQueueItemTouchCallback() { @Override - public void onMove(int sourceIndex, int targetIndex) { - if (playQueue != null) playQueue.move(sourceIndex, targetIndex); + public void onMove(final int sourceIndex, final int targetIndex) { + if (playQueue != null) { + playQueue.move(sourceIndex, targetIndex); + } } @Override - public void onSwiped(int index) { - if (index != -1) playQueue.remove(index); + public void onSwiped(final int index) { + if (index != -1) { + playQueue.remove(index); + } } }; } @@ -1474,19 +1686,23 @@ public class VideoPlayerImpl extends VideoPlayer private PlayQueueItemBuilder.OnSelectedListener getOnSelectedListener() { return new PlayQueueItemBuilder.OnSelectedListener() { @Override - public void selected(PlayQueueItem item, View view) { + public void selected(final PlayQueueItem item, final View view) { onSelected(item); } @Override - public void held(PlayQueueItem item, View view) { + public void held(final PlayQueueItem item, final View view) { final int index = playQueue.indexOf(item); - if (index != -1) playQueue.remove(index); + if (index != -1) { + playQueue.remove(index); + } } @Override - public void onStartDrag(PlayQueueItemHolder viewHolder) { - if (itemTouchHelper != null) itemTouchHelper.startDrag(viewHolder); + public void onStartDrag(final PlayQueueItemHolder viewHolder) { + if (itemTouchHelper != null) { + itemTouchHelper.startDrag(viewHolder); + } } }; } @@ -1497,17 +1713,24 @@ public class VideoPlayerImpl extends VideoPlayer @SuppressLint("RtlHardcoded") private void initPopup() { - if (DEBUG) Log.d(TAG, "initPopup() called"); + if (DEBUG) { + Log.d(TAG, "initPopup() called"); + } // Popup is already added to windowManager - if (popupHasParent()) return; + if (popupHasParent()) { + return; + } updateScreenSize(); final boolean popupRememberSizeAndPos = PlayerHelper.isRememberingPopupDimensions(service); final float defaultSize = service.getResources().getDimension(R.dimen.popup_default_width); - final SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(service); - popupWidth = popupRememberSizeAndPos ? sharedPreferences.getFloat(POPUP_SAVED_WIDTH, defaultSize) : defaultSize; + final SharedPreferences sharedPreferences = + PreferenceManager.getDefaultSharedPreferences(service); + popupWidth = popupRememberSizeAndPos + ? sharedPreferences.getFloat(POPUP_SAVED_WIDTH, defaultSize) + : defaultSize; popupHeight = getMinimumVideoHeight(popupWidth); popupLayoutParams = new WindowManager.LayoutParams( @@ -1521,8 +1744,10 @@ public class VideoPlayerImpl extends VideoPlayer final int centerX = (int) (screenWidth / 2f - popupWidth / 2f); final int centerY = (int) (screenHeight / 2f - popupHeight / 2f); - popupLayoutParams.x = popupRememberSizeAndPos ? sharedPreferences.getInt(POPUP_SAVED_X, centerX) : centerX; - popupLayoutParams.y = popupRememberSizeAndPos ? sharedPreferences.getInt(POPUP_SAVED_Y, centerY) : centerY; + popupLayoutParams.x = popupRememberSizeAndPos + ? sharedPreferences.getInt(POPUP_SAVED_X, centerX) : centerX; + popupLayoutParams.y = popupRememberSizeAndPos + ? sharedPreferences.getInt(POPUP_SAVED_Y, centerY) : centerY; checkPopupPositionBounds(); @@ -1538,15 +1763,20 @@ public class VideoPlayerImpl extends VideoPlayer @SuppressLint("RtlHardcoded") private void initPopupCloseOverlay() { - if (DEBUG) Log.d(TAG, "initPopupCloseOverlay() called"); + if (DEBUG) { + Log.d(TAG, "initPopupCloseOverlay() called"); + } // closeOverlayView is already added to windowManager - if (closeOverlayView != null) return; + if (closeOverlayView != null) { + return; + } closeOverlayView = View.inflate(service, R.layout.player_popup_close_overlay, null); closeOverlayButton = closeOverlayView.findViewById(R.id.closeButton); - final int flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE + final int flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE + | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; final WindowManager.LayoutParams closeOverlayLayoutParams = new WindowManager.LayoutParams( @@ -1555,7 +1785,8 @@ public class VideoPlayerImpl extends VideoPlayer flags, PixelFormat.TRANSLUCENT); closeOverlayLayoutParams.gravity = Gravity.LEFT | Gravity.TOP; - closeOverlayLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; + closeOverlayLayoutParams.softInputMode = + WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; closeOverlayButton.setVisibility(View.GONE); windowManager.addView(closeOverlayView, closeOverlayLayoutParams); @@ -1572,8 +1803,8 @@ public class VideoPlayerImpl extends VideoPlayer //////////////////////////////////////////////////////////////////////////*/ /** - * @see #checkPopupPositionBounds(float, float) * @return if the popup was out of bounds and have been moved back to it + * @see #checkPopupPositionBounds(float, float) */ @SuppressWarnings("UnusedReturnValue") public boolean checkPopupPositionBounds() { @@ -1629,7 +1860,8 @@ public class VideoPlayerImpl extends VideoPlayer private float getMinimumVideoHeight(final float width) { final float height = width / (16.0f / 9.0f); // Respect the 16:9 ratio that most videos have /*if (DEBUG) { - Log.d(TAG, "getMinimumVideoHeight() called with: width = [" + width + "], returned: " + height); + Log.d(TAG, "getMinimumVideoHeight() called with: width = [" + + width + "], returned: " + height); }*/ return height; } @@ -1640,8 +1872,10 @@ public class VideoPlayerImpl extends VideoPlayer screenWidth = metrics.widthPixels; screenHeight = metrics.heightPixels; - if (DEBUG) - Log.d(TAG, "updateScreenSize() called > screenWidth = " + screenWidth + ", screenHeight = " + screenHeight); + if (DEBUG) { + Log.d(TAG, "updateScreenSize() called > screenWidth = " + + screenWidth + ", screenHeight = " + screenHeight); + } popupWidth = service.getResources().getDimension(R.dimen.popup_default_width); popupHeight = getMinimumVideoHeight(popupWidth); @@ -1654,15 +1888,28 @@ public class VideoPlayerImpl extends VideoPlayer } public void updatePopupSize(final int width, final int height) { - if (DEBUG) Log.d(TAG, "updatePopupSize() called with: width = [" + width + "], height = [" + height + "]"); + if (DEBUG) { + Log.d(TAG, "updatePopupSize() called with: width = [" + + width + "], height = [" + height + "]"); + } - if (popupLayoutParams == null || windowManager == null || getParentActivity() != null || getRootView().getParent() == null) + if (popupLayoutParams == null + || windowManager == null + || getParentActivity() != null + || getRootView().getParent() == null) { return; + } - final int actualWidth = (int) (width > maximumWidth ? maximumWidth : width < minimumWidth ? minimumWidth : width); + final int actualWidth = (int) (width > maximumWidth + ? maximumWidth : width < minimumWidth ? minimumWidth : width); final int actualHeight; - if (height == -1) actualHeight = (int) getMinimumVideoHeight(width); - else actualHeight = (int) (height > maximumHeight ? maximumHeight : height < minimumHeight ? minimumHeight : height); + if (height == -1) { + actualHeight = (int) getMinimumVideoHeight(width); + } else { + actualHeight = (int) (height > maximumHeight + ? maximumHeight : height < minimumHeight + ? minimumHeight : height); + } popupLayoutParams.width = actualWidth; popupLayoutParams.height = actualHeight; @@ -1670,23 +1917,29 @@ public class VideoPlayerImpl extends VideoPlayer popupHeight = actualHeight; getSurfaceView().setHeights((int) popupHeight, (int) popupHeight); - if (DEBUG) Log.d(TAG, "updatePopupSize() updated values:" + - " width = [" + actualWidth + "], height = [" + actualHeight + "]"); + if (DEBUG) { + Log.d(TAG, "updatePopupSize() updated values:" + + " width = [" + actualWidth + "], height = [" + actualHeight + "]"); + } windowManager.updateViewLayout(getRootView(), popupLayoutParams); } private void updateWindowFlags(final int flags) { - if (popupLayoutParams == null || windowManager == null || getParentActivity() != null || getRootView().getParent() == null) + if (popupLayoutParams == null + || windowManager == null + || getParentActivity() != null + || getRootView().getParent() == null) { return; + } popupLayoutParams.flags = flags; windowManager.updateViewLayout(getRootView(), popupLayoutParams); } private int popupLayoutParamType() { - return Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O ? - WindowManager.LayoutParams.TYPE_PHONE : - WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; + return Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O + ? WindowManager.LayoutParams.TYPE_PHONE + : WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; } /*////////////////////////////////////////////////////////////////////////// @@ -1694,8 +1947,12 @@ public class VideoPlayerImpl extends VideoPlayer //////////////////////////////////////////////////////////////////////////*/ public void closePopup() { - if (DEBUG) Log.d(TAG, "closePopup() called, isPopupClosing = " + isPopupClosing); - if (isPopupClosing) return; + if (DEBUG) { + Log.d(TAG, "closePopup() called, isPopupClosing = " + isPopupClosing); + } + if (isPopupClosing) { + return; + } isPopupClosing = true; savePlaybackState(); @@ -1705,11 +1962,14 @@ public class VideoPlayerImpl extends VideoPlayer } public void removePopupFromView() { - final boolean isCloseOverlayHasParent = closeOverlayView != null && closeOverlayView.getParent() != null; - if (popupHasParent()) + final boolean isCloseOverlayHasParent = closeOverlayView != null + && closeOverlayView.getParent() != null; + if (popupHasParent()) { windowManager.removeView(getRootView()); - if (isCloseOverlayHasParent) + } + if (isCloseOverlayHasParent) { windowManager.removeView(closeOverlayView); + } } private void animateOverlayAndFinishService() { @@ -1743,7 +2003,9 @@ public class VideoPlayerImpl extends VideoPlayer private boolean popupHasParent() { final View root = getRootView(); - return root != null && root.getLayoutParams() instanceof WindowManager.LayoutParams && root.getParent() != null; + return root != null + && root.getLayoutParams() instanceof WindowManager.LayoutParams + && root.getParent() != null; } /////////////////////////////////////////////////////////////////////////// diff --git a/app/src/main/java/org/schabi/newpipe/player/event/CustomBottomSheetBehavior.java b/app/src/main/java/org/schabi/newpipe/player/event/CustomBottomSheetBehavior.java index 24ef5dffc..1d0b3ae26 100644 --- a/app/src/main/java/org/schabi/newpipe/player/event/CustomBottomSheetBehavior.java +++ b/app/src/main/java/org/schabi/newpipe/player/event/CustomBottomSheetBehavior.java @@ -24,16 +24,23 @@ public class CustomBottomSheetBehavior extends BottomSheetBehavior Rect globalRect = new Rect(); private boolean skippingInterception = false; private final List 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 - 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 - if (event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_UP) + if (event.getAction() == MotionEvent.ACTION_CANCEL + || event.getAction() == MotionEvent.ACTION_UP) { skippingInterception = false; + } // 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 if (getState() == BottomSheetBehavior.STATE_EXPANDED) { @@ -42,7 +49,8 @@ public class CustomBottomSheetBehavior extends BottomSheetBehavior final ViewGroup viewGroup = child.findViewById(element); if (viewGroup != null) { 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; return false; } diff --git a/app/src/main/java/org/schabi/newpipe/player/event/OnKeyDownListener.java b/app/src/main/java/org/schabi/newpipe/player/event/OnKeyDownListener.java index ada8fef2a..fc1f9d80d 100644 --- a/app/src/main/java/org/schabi/newpipe/player/event/OnKeyDownListener.java +++ b/app/src/main/java/org/schabi/newpipe/player/event/OnKeyDownListener.java @@ -1,5 +1,5 @@ package org.schabi.newpipe.player.event; public interface OnKeyDownListener { - boolean onKeyDown(final int keyCode); + boolean onKeyDown(int keyCode); } diff --git a/app/src/main/java/org/schabi/newpipe/player/event/PlayerGestureListener.java b/app/src/main/java/org/schabi/newpipe/player/event/PlayerGestureListener.java index 559a4d02b..9eb56ff84 100644 --- a/app/src/main/java/org/schabi/newpipe/player/event/PlayerGestureListener.java +++ b/app/src/main/java/org/schabi/newpipe/player/event/PlayerGestureListener.java @@ -3,7 +3,12 @@ package org.schabi.newpipe.player.event; import android.app.Activity; import android.content.Context; 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 org.schabi.newpipe.R; 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.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_HIDE_TIME; import static org.schabi.newpipe.util.AnimationUtils.Type.SCALE_AND_ALPHA; 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 boolean DEBUG = BasePlayer.DEBUG; private final VideoPlayerImpl playerImpl; 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; @@ -60,60 +69,96 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen //////////////////////////////////////////////////////////////////////////*/ /* - * Main and popup players' gesture listeners is too different. - * So it will be better to have different implementations of them - * */ + * Main and popup players' gesture listeners is too different. + * So it will be better to have different implementations of them + * */ @Override - public boolean onDoubleTap(MotionEvent e) { - if (DEBUG) Log.d(TAG, "onDoubleTap() called with: e = [" + e + "]" + "rawXy = " + e.getRawX() + ", " + e.getRawY() + ", xy = " + e.getX() + ", " + e.getY()); + 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 (playerImpl.popupPlayerSelected()) return onDoubleTapInPopup(e); - else return onDoubleTapInMain(e); + if (playerImpl.popupPlayerSelected()) { + return onDoubleTapInPopup(e); + } else { + return onDoubleTapInMain(e); + } } @Override - public boolean onSingleTapConfirmed(MotionEvent e) { - if (DEBUG) Log.d(TAG, "onSingleTapConfirmed() called with: e = [" + e + "]"); + public boolean onSingleTapConfirmed(final MotionEvent e) { + if (DEBUG) { + Log.d(TAG, "onSingleTapConfirmed() called with: e = [" + e + "]"); + } - if (playerImpl.popupPlayerSelected()) return onSingleTapConfirmedInPopup(e); - else return onSingleTapConfirmedInMain(e); + if (playerImpl.popupPlayerSelected()) { + return onSingleTapConfirmedInPopup(e); + } else { + return onSingleTapConfirmedInMain(e); + } } @Override - public boolean onDown(MotionEvent e) { - if (DEBUG) Log.d(TAG, "onDown() called with: e = [" + e + "]"); + public boolean onDown(final MotionEvent 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 - public boolean onScroll(MotionEvent initialEvent, MotionEvent movingEvent, float distanceX, float distanceY) { - if (playerImpl.popupPlayerSelected()) return onScrollInPopup(initialEvent, movingEvent, distanceX, distanceY); - else return onScrollInMain(initialEvent, movingEvent, distanceX, distanceY); + public void onLongPress(final MotionEvent e) { + if (DEBUG) { + Log.d(TAG, "onLongPress() called with: e = [" + e + "]"); + } + + if (playerImpl.popupPlayerSelected()) { + onLongPressInPopup(e); + } } @Override - public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { - if (DEBUG) Log.d(TAG, "onFling() called with velocity: dX=[" + velocityX + "], dY=[" + velocityY + "]"); - - if (playerImpl.popupPlayerSelected()) return onFlingInPopup(e1, e2, velocityX, velocityY); - else return true; + public boolean onScroll(final MotionEvent initialEvent, final MotionEvent movingEvent, + final float distanceX, final float distanceY) { + if (playerImpl.popupPlayerSelected()) { + return onScrollInPopup(initialEvent, movingEvent, distanceX, distanceY); + } else { + return onScrollInMain(initialEvent, movingEvent, distanceX, distanceY); + } } @Override - public boolean onTouch(View v, MotionEvent event) { - //noinspection PointlessBooleanExpression,ConstantConditions - if (DEBUG && false) Log.d(TAG, "onTouch() called with: v = [" + v + "], event = [" + event + "]"); + public boolean onFling(final MotionEvent e1, final MotionEvent e2, + final float velocityX, final float velocityY) { + if (DEBUG) { + Log.d(TAG, "onFling() called with velocity: dX=[" + + velocityX + "], dY=[" + velocityY + "]"); + } - if (playerImpl.popupPlayerSelected()) return onTouchInPopup(v, event); - else return onTouchInMain(v, event); + if (playerImpl.popupPlayerSelected()) { + 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 //////////////////////////////////////////////////////////////////////////*/ - private boolean onDoubleTapInMain(MotionEvent e) { + private boolean onDoubleTapInMain(final MotionEvent e) { if (e.getX() > playerImpl.getRootView().getWidth() * 2.0 / 3.0) { playerImpl.onFastForward(); } else if (e.getX() < playerImpl.getRootView().getWidth() / 3.0) { @@ -134,10 +179,14 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen } - private boolean onSingleTapConfirmedInMain(MotionEvent e) { - if (DEBUG) Log.d(TAG, "onSingleTapConfirmed() called with: e = [" + e + "]"); + private boolean onSingleTapConfirmedInMain(final MotionEvent 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()) { playerImpl.hideControls(150, 0); @@ -153,7 +202,9 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen private boolean onScrollInMain(final MotionEvent initialEvent, final MotionEvent movingEvent, 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 isTouchingNavigationBar = initialEvent.getY() @@ -167,7 +218,8 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen ", e2.getRaw = [" + movingEvent.getRawX() + ", " + movingEvent.getRawY() + "]" + ", 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)) || playerImpl.getCurrentState() == BasePlayer.STATE_COMPLETED) { return false; @@ -181,15 +233,18 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen if (isVolumeGestureEnabled && acceptVolumeArea) { playerImpl.getVolumeProgressBar().incrementProgressBy((int) distanceY); - final float currentProgressPercent = - (float) playerImpl.getVolumeProgressBar().getProgress() / playerImpl.getMaxGestureLength(); + final float currentProgressPercent = (float) playerImpl + .getVolumeProgressBar().getProgress() / playerImpl.getMaxGestureLength(); final int currentVolume = (int) (maxVolume * currentProgressPercent); 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( - 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.75 ? R.drawable.ic_volume_down_white_24dp : R.drawable.ic_volume_up_white_24dp) @@ -203,23 +258,30 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen } } else { final Activity parent = playerImpl.getParentActivity(); - if (parent == null) return true; + if (parent == null) { + return true; + } final Window window = parent.getWindow(); playerImpl.getBrightnessProgressBar().incrementProgressBy((int) distanceY); - final float currentProgressPercent = - (float) playerImpl.getBrightnessProgressBar().getProgress() / playerImpl.getMaxGestureLength(); + final float currentProgressPercent = (float) playerImpl.getBrightnessProgressBar() + .getProgress() / playerImpl.getMaxGestureLength(); final WindowManager.LayoutParams layoutParams = window.getAttributes(); layoutParams.screenBrightness = currentProgressPercent; window.setAttributes(layoutParams); - if (DEBUG) Log.d(TAG, "onScroll().brightnessControl, currentBrightness = " + currentProgressPercent); + if (DEBUG) { + Log.d(TAG, "onScroll().brightnessControl, " + + "currentBrightness = " + currentProgressPercent); + } playerImpl.getBrightnessImageView().setImageDrawable( AppCompatResources.getDrawable(service, - currentProgressPercent < 0.25 ? R.drawable.ic_brightness_low_white_24dp - : currentProgressPercent < 0.75 ? R.drawable.ic_brightness_medium_white_24dp + currentProgressPercent < 0.25 + ? R.drawable.ic_brightness_low_white_24dp + : currentProgressPercent < 0.75 + ? R.drawable.ic_brightness_medium_white_24dp : R.drawable.ic_brightness_high_white_24dp) ); @@ -234,7 +296,9 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen } private void onScrollEndInMain() { - if (DEBUG) Log.d(TAG, "onScrollEnd() called"); + if (DEBUG) { + Log.d(TAG, "onScrollEnd() called"); + } if (playerImpl.getVolumeRelativeLayout().getVisibility() == View.VISIBLE) { 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); if (event.getAction() == MotionEvent.ACTION_UP && isMovingInMain) { isMovingInMain = false; 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()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_MOVE: @@ -272,8 +337,10 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen // Popup player listener //////////////////////////////////////////////////////////////////////////*/ - private boolean onDoubleTapInPopup(MotionEvent e) { - if (playerImpl == null || !playerImpl.isPlaying()) return false; + private boolean onDoubleTapInPopup(final MotionEvent e) { + if (playerImpl == null || !playerImpl.isPlaying()) { + return false; + } playerImpl.hideControls(0, 0); @@ -286,8 +353,10 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen return true; } - private boolean onSingleTapConfirmedInPopup(MotionEvent e) { - if (playerImpl == null || playerImpl.getPlayer() == null) return false; + private boolean onSingleTapConfirmedInPopup(final MotionEvent e) { + if (playerImpl == null || playerImpl.getPlayer() == null) { + return false; + } if (playerImpl.isControlsVisible()) { playerImpl.hideControls(100, 100); } else { @@ -297,7 +366,7 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen 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 // because the soft input is visible (the draggable area is currently resized). playerImpl.updateScreenSize(); @@ -310,14 +379,19 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen return super.onDown(e); } - private void onLongPressInPopup(MotionEvent e) { + private void onLongPressInPopup(final MotionEvent e) { playerImpl.updateScreenSize(); playerImpl.checkPopupPositionBounds(); playerImpl.updatePopupSize((int) playerImpl.getScreenWidth(), -1); } - private boolean onScrollInPopup(MotionEvent initialEvent, MotionEvent movingEvent, float distanceX, float distanceY) { - if (isResizing || playerImpl == null) return super.onScroll(initialEvent, movingEvent, distanceX, distanceY); + private boolean onScrollInPopup(final MotionEvent initialEvent, + final MotionEvent movingEvent, + final float distanceX, + final float distanceY) { + if (isResizing || playerImpl == null) { + return super.onScroll(initialEvent, movingEvent, distanceX, distanceY); + } if (!isMovingInPopup) { animateView(playerImpl.getCloseOverlayButton(), true, 200); @@ -369,12 +443,15 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen // + "posX,Y = [" + posX + ", " + posY + "], " // + "popupW,H = [" + popupWidth + " x " + popupHeight + "]"); // } - playerImpl.windowManager.updateViewLayout(playerImpl.getRootView(), playerImpl.getPopupLayoutParams()); + playerImpl.windowManager + .updateViewLayout(playerImpl.getRootView(), playerImpl.getPopupLayoutParams()); return true; } - private void onScrollEndInPopup(MotionEvent event) { - if (playerImpl == null) return; + private void onScrollEndInPopup(final MotionEvent event) { + if (playerImpl == null) { + return; + } if (playerImpl.isControlsVisible() && playerImpl.getCurrentState() == STATE_PLAYING) { 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) { - if (playerImpl == null) return false; + private boolean onFlingInPopup(final MotionEvent e1, + final MotionEvent e2, + final float velocityX, + final float velocityY) { + if (playerImpl == null) { + return false; + } final float absVelocityX = Math.abs(velocityX); final float absVelocityY = Math.abs(velocityY); if (Math.max(absVelocityX, absVelocityY) > tossFlingVelocity) { - if (absVelocityX > tossFlingVelocity) playerImpl.getPopupLayoutParams().x = (int) velocityX; - if (absVelocityY > tossFlingVelocity) playerImpl.getPopupLayoutParams().y = (int) velocityY; + if (absVelocityX > tossFlingVelocity) { + playerImpl.getPopupLayoutParams().x = (int) velocityX; + } + if (absVelocityY > tossFlingVelocity) { + playerImpl.getPopupLayoutParams().y = (int) velocityY; + } playerImpl.checkPopupPositionBounds(); - playerImpl.windowManager.updateViewLayout(playerImpl.getRootView(), playerImpl.getPopupLayoutParams()); + playerImpl.windowManager + .updateViewLayout(playerImpl.getRootView(), playerImpl.getPopupLayoutParams()); return true; } return false; } - private boolean onTouchInPopup(View v, MotionEvent event) { + private boolean onTouchInPopup(final View v, final MotionEvent event) { if (playerImpl == null) { return false; } playerImpl.getGestureDetector().onTouchEvent(event); 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.getLoadingPanel().setVisibility(View.GONE); @@ -432,13 +521,18 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen } 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); } if (event.getAction() == MotionEvent.ACTION_UP) { - if (DEBUG) - Log.d(TAG, "onTouch() ACTION_UP > v = [" + v + "], e1.getRaw = [" + event.getRawX() + ", " + event.getRawY() + "]"); + if (DEBUG) { + Log.d(TAG, "onTouch() ACTION_UP > v = [" + v + "], " + + "e1.getRaw = [" + event.getRawX() + ", " + event.getRawY() + "]"); + } if (isMovingInPopup) { isMovingInPopup = false; onScrollEndInPopup(event); @@ -492,7 +586,9 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen playerImpl.checkPopupPositionBounds(); playerImpl.updateScreenSize(); - playerImpl.updatePopupSize((int) Math.min(playerImpl.getScreenWidth(), newWidth), -1); + playerImpl.updatePopupSize( + (int) Math.min(playerImpl.getScreenWidth(), newWidth), + -1); return true; } } @@ -504,16 +600,18 @@ public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListen * Utils * */ - private int getNavigationBarHeight(Context context) { - int resId = context.getResources().getIdentifier("navigation_bar_height", "dimen", "android"); + private int getNavigationBarHeight(final Context context) { + int resId = context.getResources() + .getIdentifier("navigation_bar_height", "dimen", "android"); if (resId > 0) { return context.getResources().getDimensionPixelSize(resId); } return 0; } - private int getStatusBarHeight(Context context) { - int resId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); + private int getStatusBarHeight(final Context context) { + int resId = context.getResources() + .getIdentifier("status_bar_height", "dimen", "android"); if (resId > 0) { return context.getResources().getDimensionPixelSize(resId); } diff --git a/app/src/main/java/org/schabi/newpipe/player/event/PlayerServiceEventListener.java b/app/src/main/java/org/schabi/newpipe/player/event/PlayerServiceEventListener.java index 69e23f8fb..f8d03087e 100644 --- a/app/src/main/java/org/schabi/newpipe/player/event/PlayerServiceEventListener.java +++ b/app/src/main/java/org/schabi/newpipe/player/event/PlayerServiceEventListener.java @@ -12,4 +12,4 @@ public interface PlayerServiceEventListener extends PlayerEventListener { void onPlayerError(ExoPlaybackException error); void hideSystemUiIfNeeded(); -} \ No newline at end of file +} diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/PlaybackParameterDialog.java b/app/src/main/java/org/schabi/newpipe/player/helper/PlaybackParameterDialog.java index 4693797c3..ae547de9f 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/PlaybackParameterDialog.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/PlaybackParameterDialog.java @@ -93,7 +93,7 @@ public class PlaybackParameterDialog extends DialogFragment { public static PlaybackParameterDialog newInstance(final double playbackTempo, final double playbackPitch, final boolean playbackSkipSilence, - Callback callback) { + final Callback callback) { PlaybackParameterDialog dialog = new PlaybackParameterDialog(); dialog.callback = callback; dialog.initialTempo = playbackTempo; diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java index 4c0301541..f96adac49 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java @@ -217,7 +217,8 @@ public final class PlayerHelper { } 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 @@ -353,7 +354,7 @@ public final class PlayerHelper { setScreenBrightness(context, setScreenBrightness, System.currentTimeMillis()); } - public static boolean globalScreenOrientationLocked(Context context) { + public static boolean globalScreenOrientationLocked(final Context context) { // 1: Screen orientation changes using accelerometer // 0: Screen orientation is locked return android.provider.Settings.System.getInt( @@ -361,7 +362,9 @@ public final class PlayerHelper { } 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; } diff --git a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueue.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueue.java index 08f3ab43a..dc5803462 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueue.java +++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueue.java @@ -63,7 +63,9 @@ public abstract class PlayQueue implements Serializable { streams = new ArrayList<>(); streams.addAll(startWith); 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); disposed = false; @@ -156,7 +158,9 @@ public abstract class PlayQueue implements Serializable { if (index >= streams.size()) { 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); 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 * 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() { - if (history.size() <= 1) return false; + if (history.size() <= 1) { + return false; + } history.remove(history.size() - 1); @@ -504,18 +510,22 @@ public abstract class PlayQueue implements Serializable { /* * 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 * */ @Override 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; + } final PlayQueue other = (PlayQueue) obj; 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 true; diff --git a/app/src/main/java/org/schabi/newpipe/streams/SubtitleConverter.java b/app/src/main/java/org/schabi/newpipe/streams/SubtitleConverter.java deleted file mode 100644 index e69de29bb..000000000 diff --git a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java index 7136453e4..0c8f83474 100644 --- a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java @@ -47,7 +47,10 @@ import org.schabi.newpipe.local.history.StatisticsPlaylistFragment; import org.schabi.newpipe.local.playlist.LocalPlaylistFragment; import org.schabi.newpipe.local.subscription.SubscriptionFragment; 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.PlayQueueItem; import org.schabi.newpipe.settings.SettingsActivity; @@ -174,8 +177,11 @@ public final class NavigationHelper { startService(context, intent); } - public static void playOnBackgroundPlayer(final Context context, final PlayQueue queue, final boolean resumePlayback) { - Toast.makeText(context, R.string.background_player_playing_toast, Toast.LENGTH_SHORT).show(); + public static void playOnBackgroundPlayer(final Context context, + 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); intent.putExtra(VideoPlayer.PLAYER_TYPE, VideoPlayer.PLAYER_TYPE_AUDIO); startService(context, intent); @@ -195,7 +201,8 @@ public final class NavigationHelper { } 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); startService(context, intent); } @@ -205,10 +212,13 @@ public final class NavigationHelper { 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) { 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); startService(context, intent); } @@ -357,12 +367,14 @@ public final class NavigationHelper { expandMainPlayer(fragment.requireActivity()); final VideoDetailFragment detailFragment = (VideoDetailFragment) fragment; detailFragment.setAutoplay(autoPlay); - detailFragment.selectAndLoadVideo(serviceId, url, title == null ? "" : title, playQueue); + detailFragment + .selectAndLoadVideo(serviceId, url, title == null ? "" : title, playQueue); detailFragment.scrollToTop(); 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); defaultTransaction(fragmentManager) diff --git a/app/src/main/java/org/schabi/newpipe/views/ExpandableSurfaceView.java b/app/src/main/java/org/schabi/newpipe/views/ExpandableSurfaceView.java index 3d69e9cdc..798712b6b 100644 --- a/app/src/main/java/org/schabi/newpipe/views/ExpandableSurfaceView.java +++ b/app/src/main/java/org/schabi/newpipe/views/ExpandableSurfaceView.java @@ -5,7 +5,7 @@ import android.util.AttributeSet; import android.view.SurfaceView; 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 { private int resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT; @@ -15,21 +15,27 @@ public class ExpandableSurfaceView extends SurfaceView { private float scaleX = 1.0f; private float scaleY = 1.0f; - public ExpandableSurfaceView(Context context, AttributeSet attrs) { + public ExpandableSurfaceView(final Context context, final AttributeSet attrs) { super(context, attrs); } @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); - if (videoAspectRatio == 0.0f) return; + if (videoAspectRatio == 0.0f) { + return; + } int width = MeasureSpec.getSize(widthMeasureSpec); final boolean verticalVideo = videoAspectRatio < 1; // 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 aspectDeformation = videoAspectRatio / viewAspectRatio - 1; @@ -61,27 +67,32 @@ 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 - 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); setScaleY(scaleY); } /** * @param base The height that will be used in every resize mode as a minimum height - * @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) { - if (baseHeight == base && maxHeight == max) return; + if (baseHeight == base && maxHeight == max) { + return; + } baseHeight = base; maxHeight = max; requestLayout(); } public void setResizeMode(@AspectRatioFrameLayout.ResizeMode final int newResizeMode) { - if (resizeMode == newResizeMode) return; + if (resizeMode == newResizeMode) { + return; + } resizeMode = newResizeMode; requestLayout(); @@ -93,9 +104,11 @@ public class ExpandableSurfaceView extends SurfaceView { } public void setAspectRatio(final float aspectRatio) { - if (videoAspectRatio == aspectRatio) return; + if (videoAspectRatio == aspectRatio) { + return; + } videoAspectRatio = aspectRatio; requestLayout(); } -} \ No newline at end of file +} diff --git a/checkstyle-suppressions.xml b/checkstyle-suppressions.xml index b29789eca..7c4a7a935 100644 --- a/checkstyle-suppressions.xml +++ b/checkstyle-suppressions.xml @@ -19,4 +19,10 @@ + + + + diff --git a/checkstyle.xml b/checkstyle.xml index 60a1406f9..c61b92247 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -67,6 +67,8 @@ + + @@ -174,6 +176,8 @@ --> + +