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 d35e27c40..312e4d9e5 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 @@ -330,7 +330,11 @@ public class VideoDetailFragment startService(false); setupBroadcastReceiver(); + settingsContentObserver = new SettingsContentObserver(new Handler(), this); + activity.getContentResolver().registerContentObserver( + android.provider.Settings.System.CONTENT_URI, true, + settingsContentObserver); } @Override @@ -344,7 +348,6 @@ public class VideoDetailFragment if (currentWorker != null) currentWorker.dispose(); setupBrightness(true); - getContext().getContentResolver().unregisterContentObserver(settingsContentObserver); PreferenceManager.getDefaultSharedPreferences(getContext()) .edit() .putString(getString(R.string.stream_info_selected_tab_key), pageAdapter.getItemTitle(viewPager.getCurrentItem())) @@ -356,9 +359,6 @@ public class VideoDetailFragment super.onResume(); isFragmentStopped = false; - getContext().getContentResolver().registerContentObserver( - android.provider.Settings.System.CONTENT_URI, true, - settingsContentObserver); setupBrightness(false); @@ -403,7 +403,8 @@ public class VideoDetailFragment PreferenceManager.getDefaultSharedPreferences(activity) .unregisterOnSharedPreferenceChangeListener(this); - getActivity().unregisterReceiver(broadcastReceiver); + activity.unregisterReceiver(broadcastReceiver); + activity.getContentResolver().unregisterContentObserver(settingsContentObserver); if (positionSubscriber != null) positionSubscriber.dispose(); if (currentWorker != null) currentWorker.dispose(); @@ -566,7 +567,7 @@ public class VideoDetailFragment openPopupPlayer(true); break; case R.id.detail_controls_download: - NavigationHelper.openDownloads(getActivity()); + NavigationHelper.openDownloads(activity); break; case R.id.overlay_thumbnail: case R.id.overlay_metadata_layout: @@ -874,7 +875,7 @@ public class VideoDetailFragment } // If we have something in history of played items we replay it here - if (player != null && player.getPlayQueue().previous()) { + if (player != null && player.getPlayQueue() != null && player.getPlayQueue().previous()) { return true; } // That means that we are on the start of the stack, @@ -1126,7 +1127,7 @@ public class VideoDetailFragment currentInfo.getUploaderUrl(), currentInfo.getUploaderName()); } catch (Exception e) { - ErrorActivity.reportUiError((AppCompatActivity) getActivity(), e); + ErrorActivity.reportUiError(activity, e); } } } @@ -1159,9 +1160,26 @@ public class VideoDetailFragment } // This method overrides default behaviour when setAutoplay() is called. - // Don't auto play if the user selected an external player + // Don't auto play if the user selected an external player or disabled it in settings private boolean isAutoplayEnabled() { - return playQueue != null && playQueue.getStreams().size() != 0 && !isExternalPlayerEnabled() && autoPlayEnabled; + return playQueue != null && playQueue.getStreams().size() != 0 + && autoPlayEnabled + && !isExternalPlayerEnabled() + && isAutoplayAllowedByUser(); + } + + private boolean isAutoplayAllowedByUser () { + if (activity == null) return false; + + switch (PlayerHelper.getAutoplayType(activity)) { + case PlayerHelper.AutoplayType.AUTOPLAY_TYPE_NEVER: + return false; + case PlayerHelper.AutoplayType.AUTOPLAY_TYPE_WIFI: + return !ListHelper.isMeteredNetwork(activity); + case PlayerHelper.AutoplayType.AUTOPLAY_TYPE_ALWAYS: + default: + return true; + } } private void addVideoPlayerView() { @@ -1275,7 +1293,7 @@ public class VideoDetailFragment } }; IntentFilter intentFilter = new IntentFilter(ACTION_SHOW_MAIN_PLAYER); - getActivity().registerReceiver(broadcastReceiver, intentFilter); + activity.registerReceiver(broadcastReceiver, intentFilter); } @@ -1287,23 +1305,23 @@ public class VideoDetailFragment // 1: Screen orientation changes using accelerometer // 0: Screen orientation is locked return !(android.provider.Settings.System.getInt( - getContext().getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, 0) == 1); + activity.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, 0) == 1); } private void restoreDefaultOrientation() { - if (player == null || !player.videoPlayerSelected()) return; + if (player == null || !player.videoPlayerSelected() || activity == null) return; if (player != null && player.isInFullscreen()) player.toggleFullscreen(); // This will show systemUI and pause the player. // User can tap on Play button and video will be in fullscreen mode again if (globalScreenOrientationLocked()) removeVideoPlayerView(); - getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); + activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); } private void setupOrientation() { - if (player == null || !player.videoPlayerSelected()) return; + if (player == null || !player.videoPlayerSelected() || activity == null) return; - SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity()); + SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(activity); int newOrientation; if (globalScreenOrientationLocked()) { boolean lastOrientationWasLandscape @@ -1314,14 +1332,14 @@ public class VideoDetailFragment } else newOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; - if (newOrientation != getActivity().getRequestedOrientation()) - getActivity().setRequestedOrientation(newOrientation); + if (newOrientation != activity.getRequestedOrientation()) + activity.setRequestedOrientation(newOrientation); } @Override public void onSettingsChanged() { - if(!globalScreenOrientationLocked()) - getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); + if(activity != null && !globalScreenOrientationLocked()) + activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); } /*////////////////////////////////////////////////////////////////////////// @@ -1515,7 +1533,7 @@ public class VideoDetailFragment downloadDialog.setSelectedVideoStream(selectedVideoStreamIndex); downloadDialog.setSubtitleStreams(currentInfo.getSubtitles()); - downloadDialog.show(getActivity().getSupportFragmentManager(), "downloadDialog"); + downloadDialog.show(activity.getSupportFragmentManager(), "downloadDialog"); } catch (Exception e) { ErrorActivity.ErrorInfo info = ErrorActivity.ErrorInfo.make(UserAction.UI_ERROR, ServiceList.all() @@ -1525,10 +1543,10 @@ public class VideoDetailFragment .getName(), "", R.string.could_not_setup_download_menu); - ErrorActivity.reportError(getActivity(), + ErrorActivity.reportError(activity, e, - getActivity().getClass(), - getActivity().findViewById(android.R.id.content), info); + activity.getClass(), + activity.findViewById(android.R.id.content), info); } } @@ -1744,13 +1762,17 @@ public class VideoDetailFragment private void showSystemUi() { if (DEBUG) Log.d(TAG, "showSystemUi() called"); - getActivity().getWindow().getDecorView().setSystemUiVisibility(0); - getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); + 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 (activity == null) return; + int visibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION @@ -1769,7 +1791,9 @@ public class VideoDetailFragment } private void setupBrightness(boolean save) { - WindowManager.LayoutParams lp = getActivity().getWindow().getAttributes(); + if (activity == null) return; + + WindowManager.LayoutParams lp = activity.getWindow().getAttributes(); float brightnessLevel; if (save) { @@ -1787,7 +1811,7 @@ public class VideoDetailFragment lp.screenBrightness = brightnessLevel; } - getActivity().getWindow().setAttributes(lp); + activity.getWindow().setAttributes(lp); } private void checkLandscape() { diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index c20ff0fc2..832e2ff9b 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -389,7 +389,7 @@ public class ChannelFragment extends BaseListInfoFragment { monitorSubscription(result); headerPlayAllButton.setOnClickListener( - view -> NavigationHelper.playOnMainPlayer(activity, getPlayQueue(), false)); + view -> NavigationHelper.playOnMainPlayer(activity, getPlayQueue(), true)); headerPopupButton.setOnClickListener( view -> NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(), false)); headerBackgroundButton.setOnClickListener( diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java index 6941741af..f3f14f746 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java @@ -295,7 +295,7 @@ public class PlaylistFragment extends BaseListInfoFragment { .subscribe(getPlaylistBookmarkSubscriber()); headerPlayAllButton.setOnClickListener(view -> - NavigationHelper.playOnMainPlayer(activity, getPlayQueue(), false)); + NavigationHelper.playOnMainPlayer(activity, getPlayQueue(), true)); headerPopupButton.setOnClickListener(view -> NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(), false)); headerBackgroundButton.setOnClickListener(view -> diff --git a/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java index 31ae70954..e40549b88 100644 --- a/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java @@ -310,7 +310,7 @@ public class StatisticsPlaylistFragment } headerPlayAllButton.setOnClickListener(view -> - NavigationHelper.playOnMainPlayer(activity, getPlayQueue(), false)); + NavigationHelper.playOnMainPlayer(activity, getPlayQueue(), true)); headerPopupButton.setOnClickListener(view -> NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(), false)); headerBackgroundButton.setOnClickListener(view -> diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java index 9e72838ad..33f98614c 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java @@ -319,7 +319,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment - NavigationHelper.playOnMainPlayer(activity, getPlayQueue(), false)); + NavigationHelper.playOnMainPlayer(activity, getPlayQueue(), true)); headerPopupButton.setOnClickListener(view -> NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(), false)); headerBackgroundButton.setOnClickListener(view -> 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 bf3e202d2..5078a01b8 100644 --- a/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayerActivity.java +++ b/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayerActivity.java @@ -21,7 +21,7 @@ public final class BackgroundPlayerActivity extends ServicePlayerActivity { @Override public String getSupportActionTitle() { - return getResources().getString(R.string.title_activity_background_player); + return getResources().getString(R.string.title_activity_play_queue); } @Override 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 21934fb70..39a16afae 100644 --- a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java +++ b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java @@ -689,9 +689,6 @@ public class VideoPlayerImpl extends VideoPlayer @Override public void onPlaybackSpeedClicked() { if (videoPlayerSelected()) { - // It hides status bar in fullscreen mode - hideSystemUIIfNeeded(); - PlaybackParameterDialog .newInstance(getPlaybackSpeed(), getPlaybackPitch(), getPlaybackSkipSilence(), this) .show(getParentActivity().getSupportFragmentManager(), null); @@ -1097,9 +1094,7 @@ public class VideoPlayerImpl extends VideoPlayer private void showSystemUIPartially() { if (isInFullscreen() && getParentActivity() != null) { - int visibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE - | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN - | View.SYSTEM_UI_FLAG_FULLSCREEN; + int visibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE; getParentActivity().getWindow().getDecorView().setSystemUiVisibility(visibility); } } @@ -1143,6 +1138,13 @@ public class VideoPlayerImpl extends VideoPlayer ViewGroup controlsRoot = getRootView().findViewById(R.id.playbackControlRoot); controlsRoot.getLayoutParams().height = isFullscreen ? size.y : ViewGroup.LayoutParams.MATCH_PARENT; controlsRoot.requestLayout(); + + int statusBarHeight = 0; + int resourceId = service.getResources().getIdentifier("status_bar_height_landscape", "dimen", "android"); + if (resourceId > 0) statusBarHeight = service.getResources().getDimensionPixelSize(resourceId); + + getRootView().findViewById(R.id.playbackWindowRoot).setPadding(0, isFullscreen ? statusBarHeight : 0, 0, 0); + getRootView().findViewById(R.id.playbackWindowRoot).requestLayout(); } private void updatePlaybackButtons() { 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 5ca02980d..80f38afb2 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 @@ -44,6 +44,9 @@ import static com.google.android.exoplayer2.ui.AspectRatioFrameLayout.RESIZE_MOD import static com.google.android.exoplayer2.ui.AspectRatioFrameLayout.RESIZE_MODE_FIT; import static com.google.android.exoplayer2.ui.AspectRatioFrameLayout.RESIZE_MODE_ZOOM; import static java.lang.annotation.RetentionPolicy.SOURCE; +import static org.schabi.newpipe.player.helper.PlayerHelper.AutoplayType.AUTOPLAY_TYPE_ALWAYS; +import static org.schabi.newpipe.player.helper.PlayerHelper.AutoplayType.AUTOPLAY_TYPE_WIFI; +import static org.schabi.newpipe.player.helper.PlayerHelper.AutoplayType.AUTOPLAY_TYPE_NEVER; import static org.schabi.newpipe.player.helper.PlayerHelper.MinimizeMode.MINIMIZE_ON_EXIT_MODE_BACKGROUND; import static org.schabi.newpipe.player.helper.PlayerHelper.MinimizeMode.MINIMIZE_ON_EXIT_MODE_NONE; import static org.schabi.newpipe.player.helper.PlayerHelper.MinimizeMode.MINIMIZE_ON_EXIT_MODE_POPUP; @@ -64,6 +67,15 @@ public class PlayerHelper { int MINIMIZE_ON_EXIT_MODE_BACKGROUND = 1; int MINIMIZE_ON_EXIT_MODE_POPUP = 2; } + + @Retention(SOURCE) + @IntDef({AUTOPLAY_TYPE_ALWAYS, AUTOPLAY_TYPE_WIFI, + AUTOPLAY_TYPE_NEVER}) + public @interface AutoplayType { + int AUTOPLAY_TYPE_ALWAYS = 0; + int AUTOPLAY_TYPE_WIFI = 1; + int AUTOPLAY_TYPE_NEVER = 2; + } //////////////////////////////////////////////////////////////////////////// // Exposed helpers //////////////////////////////////////////////////////////////////////////// @@ -202,6 +214,22 @@ public class PlayerHelper { } } + @AutoplayType + public static int getAutoplayType(@NonNull final Context context) { + final String defaultType = context.getString(R.string.autoplay_always_key); + final String wifi = context.getString(R.string.autoplay_wifi_key); + final String never = context.getString(R.string.autoplay_never_key); + + final String type = getAutoplayType(context, defaultType); + if (type.equals(wifi)) { + return AUTOPLAY_TYPE_WIFI; + } else if (type.equals(never)) { + return AUTOPLAY_TYPE_NEVER; + } else { + return AUTOPLAY_TYPE_ALWAYS; + } + } + @NonNull public static SeekParameters getSeekParameters(@NonNull final Context context) { return isUsingInexactSeek(context) ? @@ -351,6 +379,12 @@ public class PlayerHelper { key); } + private static String getAutoplayType(@NonNull final Context context, + final String key) { + return getPreferences(context).getString(context.getString(R.string.autoplay_key), + key); + } + private static SinglePlayQueue getAutoQueuedSinglePlayQueue(StreamInfoItem streamInfoItem) { SinglePlayQueue singlePlayQueue = new SinglePlayQueue(streamInfoItem); singlePlayQueue.getItem().setAutoQueued(true); diff --git a/app/src/main/java/org/schabi/newpipe/util/ListHelper.java b/app/src/main/java/org/schabi/newpipe/util/ListHelper.java index eb950b1ed..d878a2b87 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ListHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ListHelper.java @@ -445,7 +445,7 @@ public final class ListHelper { * @param context App context * @return {@code true} if connected to a metered network */ - private static boolean isMeteredNetwork(Context context) + public static boolean isMeteredNetwork(Context context) { ConnectivityManager manager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); if (manager == null || manager.getActiveNetworkInfo() == null) return false; 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 648894cc1..8b867a328 100644 --- a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java @@ -116,8 +116,8 @@ public class NavigationHelper { .putExtra(BasePlayer.PLAYBACK_SKIP_SILENCE, playbackSkipSilence); } - public static void playOnMainPlayer(final AppCompatActivity activity, final PlayQueue queue, final boolean resumePlayback) { - playOnMainPlayer(activity.getSupportFragmentManager(), queue, resumePlayback); + public static void playOnMainPlayer(final AppCompatActivity activity, final PlayQueue queue, final boolean autoPlay) { + playOnMainPlayer(activity.getSupportFragmentManager(), queue, autoPlay); } public static void playOnMainPlayer(final FragmentManager fragmentManager, final PlayQueue queue, boolean autoPlay) { diff --git a/app/src/main/res/layout-large-land/activity_main_player.xml b/app/src/main/res/layout-large-land/activity_main_player.xml index d0602ed75..7fb1872cf 100644 --- a/app/src/main/res/layout-large-land/activity_main_player.xml +++ b/app/src/main/res/layout-large-land/activity_main_player.xml @@ -134,6 +134,12 @@ android:visibility="gone" tools:visibility="visible"> + + - - + + - - @string/minimize_on_exit_popup_description + + autoplay_key + @string/autoplay_always_key + autoplay_always_key + autoplay_wifi_key + autoplay_never_key + + @string/autoplay_always_key + @string/autoplay_wifi_key + @string/autoplay_never_key + + + @string/autoplay_always_description + @string/autoplay_wifi_description + @string/autoplay_never_description + + default_resolution 360p show_higher_resolutions diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 19013322d..3a575ae25 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -411,6 +411,7 @@ Conferences %1$s/%2$s + Play queue Background player Popup player Remove @@ -520,6 +521,11 @@ None Minimize to background player Minimize to popup player + + Start playback automatically — %s + Always + Only on WiFi + Never List view mode List Grid diff --git a/app/src/main/res/xml/video_audio_settings.xml b/app/src/main/res/xml/video_audio_settings.xml index 0ff43ce90..447fa9018 100644 --- a/app/src/main/res/xml/video_audio_settings.xml +++ b/app/src/main/res/xml/video_audio_settings.xml @@ -105,6 +105,15 @@ android:summary="@string/minimize_on_exit_summary" android:title="@string/minimize_on_exit_title"/> + +