New features and fixes

- added autoplay options inside settings: always, only on wifi, never
- now statusbar will be shown in fullscreen mode
- playlists, channels can be autoplayed too (if enabled)
- changed title of background activity to Play queue
- fixed a crash
This commit is contained in:
Avently 2020-01-08 19:16:50 +03:00
parent a2d5314cf7
commit 4c57893312
15 changed files with 146 additions and 54 deletions

View File

@ -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() {

View File

@ -389,7 +389,7 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
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(

View File

@ -295,7 +295,7 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
.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 ->

View File

@ -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 ->

View File

@ -319,7 +319,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
setVideoCount(itemListAdapter.getItemsList().size());
headerPlayAllButton.setOnClickListener(view ->
NavigationHelper.playOnMainPlayer(activity, getPlayQueue(), false));
NavigationHelper.playOnMainPlayer(activity, getPlayQueue(), true));
headerPopupButton.setOnClickListener(view ->
NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(), false));
headerBackgroundButton.setOnClickListener(view ->

View File

@ -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

View File

@ -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() {

View File

@ -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);

View File

@ -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;

View File

@ -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) {

View File

@ -134,6 +134,12 @@
android:visibility="gone"
tools:visibility="visible">
<View
android:layout_width="match_parent"
android:layout_height="30dp"
android:background="@drawable/player_top_controls_bg"
android:layout_alignParentTop="true" />
<!-- All top controls in this layout -->
<RelativeLayout
android:id="@+id/playbackWindowRoot"
@ -141,12 +147,6 @@
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<View
android:layout_width="match_parent"
android:layout_height="30dp"
android:background="@drawable/player_top_controls_bg"
android:layout_alignParentTop="true" />
<!-- It will be hidden in popup -->
<Space
android:id="@+id/spaceBeforeControls"

View File

@ -132,6 +132,12 @@
android:visibility="gone"
tools:visibility="visible">
<View
android:layout_width="match_parent"
android:layout_height="30dp"
android:background="@drawable/player_top_controls_bg"
android:layout_alignParentTop="true" />
<!-- All top controls in this layout -->
<RelativeLayout
android:id="@+id/playbackWindowRoot"
@ -139,12 +145,6 @@
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<View
android:layout_width="match_parent"
android:layout_height="30dp"
android:background="@drawable/player_top_controls_bg"
android:layout_alignParentTop="true" />
<!-- It will be hidden in popup -->
<Space
android:id="@+id/spaceBeforeControls"

View File

@ -63,6 +63,23 @@
<item>@string/minimize_on_exit_popup_description</item>
</string-array>
<string name="autoplay_key" translatable="false">autoplay_key</string>
<string name="autoplay_value" translatable="false">@string/autoplay_always_key</string>
<string name="autoplay_always_key" translatable="false">autoplay_always_key</string>
<string name="autoplay_wifi_key" translatable="false">autoplay_wifi_key</string>
<string name="autoplay_never_key" translatable="false">autoplay_never_key</string>
<string-array name="autoplay_type_key" translatable="false">
<item>@string/autoplay_always_key</item>
<item>@string/autoplay_wifi_key</item>
<item>@string/autoplay_never_key</item>
</string-array>
<string-array name="autoplay_type_description" translatable="false">
<item>@string/autoplay_always_description</item>
<item>@string/autoplay_wifi_description</item>
<item>@string/autoplay_never_description</item>
</string-array>
<string name="default_resolution_key" translatable="false">default_resolution</string>
<string name="default_resolution_value" translatable="false">360p</string>
<string name="show_higher_resolutions_key" translatable="false">show_higher_resolutions</string>

View File

@ -411,6 +411,7 @@
<string name="conferences">Conferences</string>
<string name="service_kiosk_string" translatable="false">%1$s/%2$s</string>
<!-- Play Queue -->
<string name="title_activity_play_queue">Play queue</string>
<string name="title_activity_background_player">Background player</string>
<string name="title_activity_popup_player">Popup player</string>
<string name="play_queue_remove">Remove</string>
@ -520,6 +521,11 @@
<string name="minimize_on_exit_none_description">None</string>
<string name="minimize_on_exit_background_description">Minimize to background player</string>
<string name="minimize_on_exit_popup_description">Minimize to popup player</string>
<!-- Autoplay behavior -->
<string name="autoplay_summary">Start playback automatically — %s</string>
<string name="autoplay_always_description">Always</string>
<string name="autoplay_wifi_description">Only on WiFi</string>
<string name="autoplay_never_description">Never</string>
<string name="list_view_mode">List view mode</string>
<string name="list">List</string>
<string name="grid">Grid</string>

View File

@ -105,6 +105,15 @@
android:summary="@string/minimize_on_exit_summary"
android:title="@string/minimize_on_exit_title"/>
<ListPreference
app:iconSpaceReserved="false"
android:defaultValue="@string/autoplay_value"
android:entries="@array/autoplay_type_description"
android:entryValues="@array/autoplay_type_key"
android:key="@string/autoplay_key"
android:summary="@string/autoplay_summary"
android:title="@string/autoplay_title"/>
<SwitchPreference
app:iconSpaceReserved="false"
android:defaultValue="false"