From 39b0b2f03213b125293fde64faf9f7cbb4f07ccc Mon Sep 17 00:00:00 2001 From: John Zhen Mo Date: Wed, 3 Jan 2018 22:53:31 -0800 Subject: [PATCH] -Added player conversion to background and popup players. -[#919] Fixed custom notification does not trigger unlocking on lockscreen. -[#947] Fixes player crashing on internet outage, issue partially addressed. -Fixed main player losing state after destroy while in background. -Fixed main player controls not hiding automatically after orientation change. -Fixed dialog uploader not marqueeing when too long. -Fixed popup permission throwing NPE on BaseList. -Refactored popup permissions to start in NavigationHelper. -Extracted hardcoded string for player menus. -Bump Java version to 1.8. -Some lambda conversions. --- app/build.gradle | 4 +- .../schabi/newpipe/RouterPopupActivity.java | 5 +- .../fragments/detail/VideoDetailFragment.java | 9 +- .../fragments/list/BaseListFragment.java | 9 +- .../list/channel/ChannelFragment.java | 16 +-- .../list/playlist/PlaylistFragment.java | 17 +-- .../newpipe/player/BackgroundPlayer.java | 14 +-- .../player/BackgroundPlayerActivity.java | 24 ++++ .../newpipe/player/MainVideoPlayer.java | 117 +++++++++--------- .../newpipe/player/PopupVideoPlayer.java | 78 ++++-------- .../player/PopupVideoPlayerActivity.java | 24 ++++ .../newpipe/player/ServicePlayerActivity.java | 68 +++++----- .../schabi/newpipe/util/ExtractorHelper.java | 8 +- .../schabi/newpipe/util/NavigationHelper.java | 51 ++++---- .../schabi/newpipe/util/PermissionHelper.java | 17 +++ app/src/main/res/layout/dialog_title.xml | 6 +- app/src/main/res/menu/menu_play_queue.xml | 5 + app/src/main/res/menu/menu_play_queue_bg.xml | 10 ++ .../main/res/menu/menu_play_queue_popup.xml | 10 ++ app/src/main/res/menu/menu_videooptions.xml | 6 +- app/src/main/res/values/strings.xml | 5 + 21 files changed, 282 insertions(+), 221 deletions(-) create mode 100644 app/src/main/res/menu/menu_play_queue_bg.xml create mode 100644 app/src/main/res/menu/menu_play_queue_popup.xml diff --git a/app/build.gradle b/app/build.gradle index 8c60a1da7..276f99ece 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -42,8 +42,8 @@ android { abortOnError false } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_7 - targetCompatibility JavaVersion.VERSION_1_7 + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 } } diff --git a/app/src/main/java/org/schabi/newpipe/RouterPopupActivity.java b/app/src/main/java/org/schabi/newpipe/RouterPopupActivity.java index 2e7089300..fe0b6e907 100644 --- a/app/src/main/java/org/schabi/newpipe/RouterPopupActivity.java +++ b/app/src/main/java/org/schabi/newpipe/RouterPopupActivity.java @@ -18,9 +18,8 @@ public class RouterPopupActivity extends RouterActivity { @Override protected void handleUrl(String url) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M - && !PermissionHelper.checkSystemAlertWindowPermission(this)) { - Toast.makeText(this, R.string.msg_popup_permission, Toast.LENGTH_LONG).show(); + if (!PermissionHelper.isPopupEnabled(this)) { + PermissionHelper.showPopupEnablementToast(this); finish(); return; } 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 fdf6ca5bb..5fb9e0105 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 @@ -505,7 +505,7 @@ public class VideoDetailFragment extends BaseStateFragment implement NavigationHelper.enqueueOnBackgroundPlayer(context, new SinglePlayQueue(item)); break; case 1: - NavigationHelper.enqueueOnPopupPlayer(context, new SinglePlayQueue(item)); + NavigationHelper.enqueueOnPopupPlayer(getActivity(), new SinglePlayQueue(item)); break; default: break; @@ -813,11 +813,8 @@ public class VideoDetailFragment extends BaseStateFragment implement } private void openPopupPlayer(final boolean append) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !PermissionHelper.checkSystemAlertWindowPermission(activity)) { - Toast toast = Toast.makeText(activity, R.string.msg_popup_permission, Toast.LENGTH_LONG); - TextView messageView = toast.getView().findViewById(android.R.id.message); - if (messageView != null) messageView.setGravity(Gravity.CENTER); - toast.show(); + if (!PermissionHelper.isPopupEnabled(activity)) { + PermissionHelper.showPopupEnablementToast(activity); return; } diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java index 8b20f0122..a09a472a5 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java @@ -1,16 +1,21 @@ package org.schabi.newpipe.fragments.list; +import android.app.Activity; import android.content.Context; import android.content.DialogInterface; +import android.os.Build; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v7.app.ActionBar; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Log; +import android.view.Gravity; import android.view.Menu; import android.view.MenuInflater; import android.view.View; +import android.widget.TextView; +import android.widget.Toast; import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.InfoItem; @@ -24,6 +29,7 @@ import org.schabi.newpipe.info_list.InfoItemDialog; import org.schabi.newpipe.info_list.InfoListAdapter; import org.schabi.newpipe.playlist.SinglePlayQueue; import org.schabi.newpipe.util.NavigationHelper; +import org.schabi.newpipe.util.PermissionHelper; import org.schabi.newpipe.util.StateSaver; import java.util.List; @@ -192,6 +198,7 @@ public abstract class BaseListFragment extends BaseStateFragment implem protected void showStreamDialog(final StreamInfoItem item) { final Context context = getContext(); + final Activity activity = getActivity(); if (context == null || context.getResources() == null || getActivity() == null) return; final String[] commands = new String[]{ @@ -207,7 +214,7 @@ public abstract class BaseListFragment extends BaseStateFragment implem NavigationHelper.enqueueOnBackgroundPlayer(context, new SinglePlayQueue(item)); break; case 1: - NavigationHelper.enqueueOnPopupPlayer(context, new SinglePlayQueue(item)); + NavigationHelper.enqueueOnPopupPlayer(activity, new SinglePlayQueue(item)); break; default: break; 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 89f43795a..000aff487 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 @@ -1,10 +1,10 @@ package org.schabi.newpipe.fragments.list.channel; +import android.app.Activity; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; -import android.os.Build; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -12,7 +12,6 @@ import android.support.v4.content.ContextCompat; import android.support.v7.app.ActionBar; import android.text.TextUtils; import android.util.Log; -import android.view.Gravity; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -23,7 +22,6 @@ import android.widget.Button; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; -import android.widget.Toast; import com.jakewharton.rxbinding2.view.RxView; @@ -153,6 +151,7 @@ public class ChannelFragment extends BaseListInfoFragment { @Override protected void showStreamDialog(final StreamInfoItem item) { + final Activity activity = getActivity(); final Context context = getContext(); if (context == null || context.getResources() == null || getActivity() == null) return; @@ -173,7 +172,7 @@ public class ChannelFragment extends BaseListInfoFragment { NavigationHelper.enqueueOnBackgroundPlayer(context, new SinglePlayQueue(item)); break; case 1: - NavigationHelper.enqueueOnPopupPlayer(context, new SinglePlayQueue(item)); + NavigationHelper.enqueueOnPopupPlayer(activity, new SinglePlayQueue(item)); break; case 2: NavigationHelper.playOnMainPlayer(context, getPlayQueue(index)); @@ -182,7 +181,7 @@ public class ChannelFragment extends BaseListInfoFragment { NavigationHelper.playOnBackgroundPlayer(context, getPlayQueue(index)); break; case 4: - NavigationHelper.playOnPopupPlayer(context, getPlayQueue(index)); + NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(index)); break; default: break; @@ -454,13 +453,6 @@ public class ChannelFragment extends BaseListInfoFragment { headerPopupButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !PermissionHelper.checkSystemAlertWindowPermission(activity)) { - Toast toast = Toast.makeText(activity, R.string.msg_popup_permission, Toast.LENGTH_LONG); - TextView messageView = toast.getView().findViewById(android.R.id.message); - if (messageView != null) messageView.setGravity(Gravity.CENTER); - toast.show(); - return; - } NavigationHelper.playOnPopupPlayer(activity, getPlayQueue()); } }); 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 fcddafef6..c798bf349 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 @@ -1,14 +1,13 @@ package org.schabi.newpipe.fragments.list.playlist; +import android.app.Activity; import android.content.Context; import android.content.DialogInterface; -import android.os.Build; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.text.TextUtils; import android.util.Log; -import android.view.Gravity; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -17,7 +16,6 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; -import android.widget.Toast; import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.ListExtractor; @@ -33,7 +31,6 @@ import org.schabi.newpipe.playlist.SinglePlayQueue; import org.schabi.newpipe.report.UserAction; import org.schabi.newpipe.util.ExtractorHelper; import org.schabi.newpipe.util.NavigationHelper; -import org.schabi.newpipe.util.PermissionHelper; import io.reactivex.Single; @@ -102,6 +99,7 @@ public class PlaylistFragment extends BaseListInfoFragment { @Override protected void showStreamDialog(final StreamInfoItem item) { final Context context = getContext(); + final Activity activity = getActivity(); if (context == null || context.getResources() == null || getActivity() == null) return; final String[] commands = new String[]{ @@ -121,7 +119,7 @@ public class PlaylistFragment extends BaseListInfoFragment { NavigationHelper.enqueueOnBackgroundPlayer(context, new SinglePlayQueue(item)); break; case 1: - NavigationHelper.enqueueOnPopupPlayer(context, new SinglePlayQueue(item)); + NavigationHelper.enqueueOnPopupPlayer(activity, new SinglePlayQueue(item)); break; case 2: NavigationHelper.playOnMainPlayer(context, getPlayQueue(index)); @@ -130,7 +128,7 @@ public class PlaylistFragment extends BaseListInfoFragment { NavigationHelper.playOnBackgroundPlayer(context, getPlayQueue(index)); break; case 4: - NavigationHelper.playOnPopupPlayer(context, getPlayQueue(index)); + NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(index)); break; default: break; @@ -230,13 +228,6 @@ public class PlaylistFragment extends BaseListInfoFragment { headerPopupButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !PermissionHelper.checkSystemAlertWindowPermission(activity)) { - Toast toast = Toast.makeText(activity, R.string.msg_popup_permission, Toast.LENGTH_LONG); - TextView messageView = toast.getView().findViewById(android.R.id.message); - if (messageView != null) messageView.setGravity(Gravity.CENTER); - toast.show(); - return; - } NavigationHelper.playOnPopupPlayer(activity, getPlayQueue()); } }); diff --git a/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java b/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java index 482f8f803..fd47a7167 100644 --- a/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java @@ -65,7 +65,6 @@ public final class BackgroundPlayer extends Service { public static final String ACTION_CLOSE = "org.schabi.newpipe.player.BackgroundPlayer.CLOSE"; public static final String ACTION_PLAY_PAUSE = "org.schabi.newpipe.player.BackgroundPlayer.PLAY_PAUSE"; - public static final String ACTION_OPEN_CONTROLS = "org.schabi.newpipe.player.BackgroundPlayer.OPEN_CONTROLS"; public static final String ACTION_REPEAT = "org.schabi.newpipe.player.BackgroundPlayer.REPEAT"; public static final String ACTION_PLAY_NEXT = "org.schabi.newpipe.player.BackgroundPlayer.ACTION_PLAY_NEXT"; public static final String ACTION_PLAY_PREVIOUS = "org.schabi.newpipe.player.BackgroundPlayer.ACTION_PLAY_PREVIOUS"; @@ -195,11 +194,14 @@ public final class BackgroundPlayer extends Service { 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)); - remoteViews.setOnClickPendingIntent(R.id.notificationContent, - PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_OPEN_CONTROLS), PendingIntent.FLAG_UPDATE_CURRENT)); remoteViews.setOnClickPendingIntent(R.id.notificationRepeat, PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_REPEAT), PendingIntent.FLAG_UPDATE_CURRENT)); + // Starts background player activity -- attempts to unlock lockscreen + final Intent intent = NavigationHelper.getBackgroundPlayerActivityIntent(this); + remoteViews.setOnClickPendingIntent(R.id.notificationContent, + PendingIntent.getActivity(this, NOTIFICATION_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT)); + if (basePlayerImpl.playQueue != null && basePlayerImpl.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); @@ -393,7 +395,7 @@ public final class BackgroundPlayer extends Service { if (index < 0 || index >= info.audio_streams.size()) return null; final AudioStream audio = info.audio_streams.get(index); - return buildMediaSource(audio.getUrl(), MediaFormat.getSuffixById(audio.format)); + return buildMediaSource(audio.getUrl(), MediaFormat.getSuffixById(audio.getFormatId())); } @Override @@ -453,7 +455,6 @@ public final class BackgroundPlayer extends Service { super.setupBroadcastReceiver(intentFilter); intentFilter.addAction(ACTION_CLOSE); intentFilter.addAction(ACTION_PLAY_PAUSE); - intentFilter.addAction(ACTION_OPEN_CONTROLS); intentFilter.addAction(ACTION_REPEAT); intentFilter.addAction(ACTION_PLAY_PREVIOUS); intentFilter.addAction(ACTION_PLAY_NEXT); @@ -478,9 +479,6 @@ public final class BackgroundPlayer extends Service { case ACTION_PLAY_PAUSE: onVideoPlayPause(); break; - case ACTION_OPEN_CONTROLS: - NavigationHelper.openBackgroundPlayerControl(getApplicationContext()); - break; case ACTION_REPEAT: onRepeatClicked(); break; 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 e5115f2e8..de711f9ac 100644 --- a/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayerActivity.java +++ b/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayerActivity.java @@ -1,9 +1,12 @@ package org.schabi.newpipe.player; import android.content.Intent; +import android.view.MenuItem; import org.schabi.newpipe.R; +import static org.schabi.newpipe.player.BackgroundPlayer.ACTION_CLOSE; + public final class BackgroundPlayerActivity extends ServicePlayerActivity { private static final String TAG = "BackgroundPlayerActivity"; @@ -36,4 +39,25 @@ public final class BackgroundPlayerActivity extends ServicePlayerActivity { ((BackgroundPlayer.BasePlayerImpl) player).removeActivityListener(this); } } + + @Override + public int getPlayerOptionMenuResource() { + return R.menu.menu_play_queue_bg; + } + + @Override + public boolean onPlayerOptionSelected(MenuItem item) { + if (item.getItemId() == R.id.action_switch_popup) { + this.player.setRecovery(); + getApplicationContext().sendBroadcast(getPlayerShutdownIntent()); + getApplicationContext().startService(getSwitchIntent(PopupVideoPlayer.class)); + return true; + } + return false; + } + + @Override + public Intent getPlayerShutdownIntent() { + return new Intent(ACTION_CLOSE); + } } 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 e68f56edb..98dd99c3c 100644 --- a/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java @@ -78,6 +78,7 @@ import static org.schabi.newpipe.util.AnimationUtils.animateView; public final class MainVideoPlayer extends Activity { private static final String TAG = ".MainVideoPlayer"; private static final boolean DEBUG = BasePlayer.DEBUG; + private static final String PLAYER_STATE_INTENT = "player_state_intent"; private GestureDetector gestureDetector; @@ -99,19 +100,41 @@ public final class MainVideoPlayer extends Activity { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) getWindow().setStatusBarColor(Color.BLACK); setVolumeControlStream(AudioManager.STREAM_MUSIC); - if (getIntent() == null) { + final Intent intent; + if (savedInstanceState != null && savedInstanceState.getParcelable(PLAYER_STATE_INTENT) != null) { + intent = savedInstanceState.getParcelable(PLAYER_STATE_INTENT); + } else { + intent = getIntent(); + } + + if (intent == null) { Toast.makeText(this, R.string.general_error, Toast.LENGTH_SHORT).show(); finish(); return; } - - showSystemUi(); setContentView(R.layout.activity_main_player); playerImpl = new VideoPlayerImpl(this); playerImpl.setup(findViewById(android.R.id.content)); - playerImpl.handleIntent(getIntent()); + playerImpl.handleIntent(intent); + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + if (this.playerImpl == null) return; + + final Intent intent = NavigationHelper.getPlayerIntent( + getApplicationContext(), + this.getClass(), + this.playerImpl.getPlayQueue(), + this.playerImpl.getRepeatMode(), + this.playerImpl.getPlaybackSpeed(), + this.playerImpl.getPlaybackPitch(), + this.playerImpl.getPlaybackQuality() + ); + outState.putParcelable(PLAYER_STATE_INTENT, intent); } @Override @@ -448,12 +471,9 @@ public final class MainVideoPlayer extends Activity { if (getCurrentState() != STATE_COMPLETED) { getControlsVisibilityHandler().removeCallbacksAndMessages(null); - animateView(getControlsRoot(), true, 300, 0, new Runnable() { - @Override - public void run() { - if (getCurrentState() == STATE_PLAYING && !isSomePopupMenuVisible()) { - hideControls(300, DEFAULT_CONTROLS_HIDE_TIME); - } + animateView(getControlsRoot(), true, 300, 0, () -> { + if (getCurrentState() == STATE_PLAYING && !isSomePopupMenuVisible()) { + hideControls(300, DEFAULT_CONTROLS_HIDE_TIME); } }); } @@ -506,6 +526,7 @@ public final class MainVideoPlayer extends Activity { private void onScreenRotationClicked() { if (DEBUG) Log.d(TAG, "onScreenRotationClicked() called"); toggleOrientation(); + showControlsThenHide(); } @Override @@ -561,12 +582,9 @@ public final class MainVideoPlayer extends Activity { @Override public void onPlaying() { super.onPlaying(); - animateView(playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, false, 80, 0, new Runnable() { - @Override - public void run() { - playPauseButton.setImageResource(R.drawable.ic_pause_white); - animatePlayButtons(true, 200); - } + animateView(playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, false, 80, 0, () -> { + playPauseButton.setImageResource(R.drawable.ic_pause_white); + animatePlayButtons(true, 200); }); showSystemUi(); getRootView().setKeepScreenOn(true); @@ -575,12 +593,9 @@ public final class MainVideoPlayer extends Activity { @Override public void onPaused() { super.onPaused(); - animateView(playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, false, 80, 0, new Runnable() { - @Override - public void run() { - playPauseButton.setImageResource(R.drawable.ic_play_arrow_white); - animatePlayButtons(true, 200); - } + animateView(playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, false, 80, 0, () -> { + playPauseButton.setImageResource(R.drawable.ic_play_arrow_white); + animatePlayButtons(true, 200); }); showSystemUi(); @@ -598,12 +613,9 @@ public final class MainVideoPlayer extends Activity { @Override public void onCompleted() { showSystemUi(); - animateView(playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, false, 0, 0, new Runnable() { - @Override - public void run() { - playPauseButton.setImageResource(R.drawable.ic_replay_white); - animatePlayButtons(true, 300); - } + animateView(playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, false, 0, 0, () -> { + playPauseButton.setImageResource(R.drawable.ic_replay_white); + animatePlayButtons(true, 300); }); getRootView().setKeepScreenOn(false); @@ -632,17 +644,10 @@ public final class MainVideoPlayer extends Activity { public void hideControls(final long duration, long delay) { if (DEBUG) Log.d(TAG, "hideControls() called with: delay = [" + delay + "]"); getControlsVisibilityHandler().removeCallbacksAndMessages(null); - getControlsVisibilityHandler().postDelayed(new Runnable() { - @Override - public void run() { - animateView(getControlsRoot(), false, duration, 0, new Runnable() { - @Override - public void run() { - hideSystemUi(); - } - }); - } - }, delay); + getControlsVisibilityHandler().postDelayed(() -> + animateView(getControlsRoot(), false, duration, 0, MainVideoPlayer.this::hideSystemUi), + delay + ); } private void updatePlaybackButtons() { @@ -655,22 +660,19 @@ public final class MainVideoPlayer extends Activity { private void buildMoreOptionsMenu() { if (moreOptionsPopupMenu == null) return; - moreOptionsPopupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem menuItem) { - switch (menuItem.getItemId()) { - case R.id.toggleOrientation: - onScreenRotationClicked(); - break; - case R.id.switchPopup: - onFullScreenButtonClicked(); - break; - case R.id.switchBackground: - onPlayBackgroundButtonClicked(); - break; - } - return false; + moreOptionsPopupMenu.setOnMenuItemClickListener(menuItem -> { + switch (menuItem.getItemId()) { + case R.id.toggleOrientation: + onScreenRotationClicked(); + break; + case R.id.switchPopup: + onFullScreenButtonClicked(); + break; + case R.id.switchBackground: + onPlayBackgroundButtonClicked(); + break; } + return false; }); } @@ -692,12 +694,7 @@ public final class MainVideoPlayer extends Activity { playQueueAdapter.setSelectedListener(getOnSelectedListener()); - itemsListCloseButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - onQueueClosed(); - } - }); + itemsListCloseButton.setOnClickListener(view -> onQueueClosed()); } private OnScrollBelowItemsListener getQueueScrollListener() { 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 50a02beec..0f0d8d785 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java @@ -66,9 +66,9 @@ import org.schabi.newpipe.extractor.services.youtube.YoutubeStreamExtractor; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.VideoStream; import org.schabi.newpipe.player.event.PlayerEventListener; +import org.schabi.newpipe.player.helper.LockManager; import org.schabi.newpipe.player.helper.PlayerHelper; import org.schabi.newpipe.player.old.PlayVideoActivity; -import org.schabi.newpipe.player.helper.LockManager; import org.schabi.newpipe.playlist.PlayQueueItem; import org.schabi.newpipe.playlist.SinglePlayQueue; import org.schabi.newpipe.report.ErrorActivity; @@ -84,7 +84,6 @@ import java.util.List; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.Disposable; -import io.reactivex.functions.Consumer; import io.reactivex.schedulers.Schedulers; import static org.schabi.newpipe.player.helper.PlayerHelper.isUsingOldPlayer; @@ -102,7 +101,6 @@ public final class PopupVideoPlayer extends Service { private static final int NOTIFICATION_ID = 40028922; public static final String ACTION_CLOSE = "org.schabi.newpipe.player.PopupVideoPlayer.CLOSE"; public static final String ACTION_PLAY_PAUSE = "org.schabi.newpipe.player.PopupVideoPlayer.PLAY_PAUSE"; - public static final String ACTION_OPEN_CONTROLS = "org.schabi.newpipe.player.PopupVideoPlayer.OPEN_CONTROLS"; public static final String ACTION_REPEAT = "org.schabi.newpipe.player.PopupVideoPlayer.REPEAT"; private static final String POPUP_SAVED_WIDTH = "popup_saved_width"; @@ -169,17 +167,7 @@ public final class PopupVideoPlayer extends Service { currentWorker = ExtractorHelper.getStreamInfo(serviceId,url,false) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) - .subscribe(new Consumer() { - @Override - public void accept(@NonNull StreamInfo info) throws Exception { - fetcherRunnable.onReceive(info); - } - }, new Consumer() { - @Override - public void accept(@NonNull Throwable throwable) throws Exception { - fetcherRunnable.onError(throwable); - } - }); + .subscribe(fetcherRunnable::onReceive, fetcherRunnable::onError); } else { playerImpl.setStartedFromNewPipe(true); playerImpl.handleIntent(intent); @@ -267,11 +255,14 @@ public final class PopupVideoPlayer extends Service { PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_PLAY_PAUSE), PendingIntent.FLAG_UPDATE_CURRENT)); notRemoteView.setOnClickPendingIntent(R.id.notificationStop, PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_CLOSE), PendingIntent.FLAG_UPDATE_CURRENT)); - notRemoteView.setOnClickPendingIntent(R.id.notificationContent, - PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_OPEN_CONTROLS), PendingIntent.FLAG_UPDATE_CURRENT)); notRemoteView.setOnClickPendingIntent(R.id.notificationRepeat, PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_REPEAT), PendingIntent.FLAG_UPDATE_CURRENT)); + // Starts popup player activity -- attempts to unlock lockscreen + final Intent intent = NavigationHelper.getPopupPlayerActivityIntent(this); + notRemoteView.setOnClickPendingIntent(R.id.notificationContent, + PendingIntent.getActivity(this, NOTIFICATION_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT)); + setRepeatModeRemote(notRemoteView, playerImpl.getRepeatMode()); return new NotificationCompat.Builder(this, getString(R.string.notification_channel_id)) @@ -421,12 +412,7 @@ public final class PopupVideoPlayer extends Service { super.initViews(rootView); resizingIndicator = rootView.findViewById(R.id.resizing_indicator); fullScreenButton = rootView.findViewById(R.id.fullScreenButton); - fullScreenButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - onFullScreenButtonClicked(); - } - }); + fullScreenButton.setOnClickListener(v -> onFullScreenButtonClicked()); } @Override @@ -604,7 +590,6 @@ public final class PopupVideoPlayer extends Service { if (DEBUG) Log.d(TAG, "setupBroadcastReceiver() called with: intentFilter = [" + intentFilter + "]"); intentFilter.addAction(ACTION_CLOSE); intentFilter.addAction(ACTION_PLAY_PAUSE); - intentFilter.addAction(ACTION_OPEN_CONTROLS); intentFilter.addAction(ACTION_REPEAT); intentFilter.addAction(Intent.ACTION_SCREEN_ON); @@ -623,9 +608,6 @@ public final class PopupVideoPlayer extends Service { case ACTION_PLAY_PAUSE: onVideoPlayPause(); break; - case ACTION_OPEN_CONTROLS: - NavigationHelper.openPopupPlayerControl(getApplicationContext()); - break; case ACTION_REPEAT: onRepeatClicked(); break; @@ -899,37 +881,31 @@ public final class PopupVideoPlayer extends Service { } private void onReceive(final StreamInfo info) { - mainHandler.post(new Runnable() { - @Override - public void run() { - final Intent intent = NavigationHelper.getPlayerIntent(getApplicationContext(), - PopupVideoPlayer.class, new SinglePlayQueue(info)); - playerImpl.handleIntent(intent); - } + mainHandler.post(() -> { + final Intent intent = NavigationHelper.getPlayerIntent(getApplicationContext(), + PopupVideoPlayer.class, new SinglePlayQueue(info)); + playerImpl.handleIntent(intent); }); } private void onError(final Throwable exception) { if (DEBUG) Log.d(TAG, "onError() called with: exception = [" + exception + "]"); exception.printStackTrace(); - mainHandler.post(new Runnable() { - @Override - public void run() { - if (exception instanceof ReCaptchaException) { - onReCaptchaException(); - } else if (exception instanceof IOException) { - Toast.makeText(context, R.string.network_error, Toast.LENGTH_LONG).show(); - } else if (exception instanceof YoutubeStreamExtractor.GemaException) { - Toast.makeText(context, R.string.blocked_by_gema, Toast.LENGTH_LONG).show(); - } else if (exception instanceof YoutubeStreamExtractor.LiveStreamException) { - Toast.makeText(context, R.string.live_streams_not_supported, Toast.LENGTH_LONG).show(); - } else if (exception instanceof ContentNotAvailableException) { - Toast.makeText(context, R.string.content_not_available, Toast.LENGTH_LONG).show(); - } else { - int errorId = exception instanceof YoutubeStreamExtractor.DecryptException ? R.string.youtube_signature_decryption_error : - exception instanceof ParsingException ? R.string.parsing_error : R.string.general_error; - ErrorActivity.reportError(mainHandler, context, exception, MainActivity.class, null, ErrorActivity.ErrorInfo.make(UserAction.REQUESTED_STREAM, NewPipe.getNameOfService(serviceId), url, errorId)); - } + mainHandler.post(() -> { + if (exception instanceof ReCaptchaException) { + onReCaptchaException(); + } else if (exception instanceof IOException) { + Toast.makeText(context, R.string.network_error, Toast.LENGTH_LONG).show(); + } else if (exception instanceof YoutubeStreamExtractor.GemaException) { + Toast.makeText(context, R.string.blocked_by_gema, Toast.LENGTH_LONG).show(); + } else if (exception instanceof YoutubeStreamExtractor.LiveStreamException) { + Toast.makeText(context, R.string.live_streams_not_supported, Toast.LENGTH_LONG).show(); + } else if (exception instanceof ContentNotAvailableException) { + Toast.makeText(context, R.string.content_not_available, Toast.LENGTH_LONG).show(); + } else { + int errorId = exception instanceof YoutubeStreamExtractor.DecryptException ? R.string.youtube_signature_decryption_error : + exception instanceof ParsingException ? R.string.parsing_error : R.string.general_error; + ErrorActivity.reportError(mainHandler, context, exception, MainActivity.class, null, ErrorActivity.ErrorInfo.make(UserAction.REQUESTED_STREAM, NewPipe.getNameOfService(serviceId), url, errorId)); } }); stopSelf(); 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 2230c9c52..44fcdb8dd 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayerActivity.java +++ b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayerActivity.java @@ -1,9 +1,12 @@ package org.schabi.newpipe.player; import android.content.Intent; +import android.view.MenuItem; import org.schabi.newpipe.R; +import static org.schabi.newpipe.player.PopupVideoPlayer.ACTION_CLOSE; + public final class PopupVideoPlayerActivity extends ServicePlayerActivity { private static final String TAG = "PopupVideoPlayerActivity"; @@ -36,4 +39,25 @@ public final class PopupVideoPlayerActivity extends ServicePlayerActivity { ((PopupVideoPlayer.VideoPlayerImpl) player).removeActivityListener(this); } } + + @Override + public int getPlayerOptionMenuResource() { + return R.menu.menu_play_queue_popup; + } + + @Override + public boolean onPlayerOptionSelected(MenuItem item) { + if (item.getItemId() == R.id.action_switch_background) { + this.player.setRecovery(); + getApplicationContext().sendBroadcast(getPlayerShutdownIntent()); + getApplicationContext().startService(getSwitchIntent(BackgroundPlayer.class)); + return true; + } + return false; + } + + @Override + public Intent getPlayerShutdownIntent() { + return new Intent(ACTION_CLOSE); + } } 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 37b8920b5..58c117017 100644 --- a/app/src/main/java/org/schabi/newpipe/player/ServicePlayerActivity.java +++ b/app/src/main/java/org/schabi/newpipe/player/ServicePlayerActivity.java @@ -100,6 +100,11 @@ public abstract class ServicePlayerActivity extends AppCompatActivity public abstract void stopPlayerListener(); + public abstract int getPlayerOptionMenuResource(); + + public abstract boolean onPlayerOptionSelected(MenuItem item); + + public abstract Intent getPlayerShutdownIntent(); //////////////////////////////////////////////////////////////////////////// // Activity Lifecycle //////////////////////////////////////////////////////////////////////////// @@ -134,6 +139,7 @@ public abstract class ServicePlayerActivity extends AppCompatActivity @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_play_queue, menu); + getMenuInflater().inflate(getPlayerOptionMenuResource(), menu); return true; } @@ -153,8 +159,13 @@ public abstract class ServicePlayerActivity extends AppCompatActivity case R.id.action_system_audio: startActivity(new Intent(Settings.ACTION_SOUND_SETTINGS)); return true; + case R.id.action_switch_main: + this.player.setRecovery(); + getApplicationContext().sendBroadcast(getPlayerShutdownIntent()); + getApplicationContext().startActivity(getSwitchIntent(MainVideoPlayer.class)); + return true; } - return super.onOptionsItemSelected(item); + return onPlayerOptionSelected(item) || super.onOptionsItemSelected(item); } @Override @@ -163,6 +174,17 @@ public abstract class ServicePlayerActivity extends AppCompatActivity unbind(); } + protected Intent getSwitchIntent(final Class clazz) { + return NavigationHelper.getPlayerIntent( + getApplicationContext(), + clazz, + this.player.getPlayQueue(), + this.player.getRepeatMode(), + this.player.getPlaybackSpeed(), + this.player.getPlaybackPitch(), + null + ); + } //////////////////////////////////////////////////////////////////////////// // Service Connection //////////////////////////////////////////////////////////////////////////// @@ -288,14 +310,11 @@ public abstract class ServicePlayerActivity extends AppCompatActivity final float playbackSpeed = BasePlayer.PLAYBACK_SPEEDS[i]; final String formattedSpeed = formatSpeed(playbackSpeed); final MenuItem item = playbackSpeedPopupMenu.getMenu().add(PLAYBACK_SPEED_POPUP_MENU_GROUP_ID, i, Menu.NONE, formattedSpeed); - item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem menuItem) { - if (player == null) return false; + item.setOnMenuItemClickListener(menuItem -> { + if (player == null) return false; - player.setPlaybackSpeed(playbackSpeed); - return true; - } + player.setPlaybackSpeed(playbackSpeed); + return true; }); } } @@ -308,14 +327,11 @@ public abstract class ServicePlayerActivity extends AppCompatActivity final float playbackPitch = BasePlayer.PLAYBACK_PITCHES[i]; final String formattedPitch = formatPitch(playbackPitch); final MenuItem item = playbackPitchPopupMenu.getMenu().add(PLAYBACK_PITCH_POPUP_MENU_GROUP_ID, i, Menu.NONE, formattedPitch); - item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem menuItem) { - if (player == null) return false; + item.setOnMenuItemClickListener(menuItem -> { + if (player == null) return false; - player.setPlaybackPitch(playbackPitch); - return true; - } + player.setPlaybackPitch(playbackPitch); + return true; }); } } @@ -323,24 +339,18 @@ public abstract class ServicePlayerActivity extends AppCompatActivity private void buildItemPopupMenu(final PlayQueueItem item, final View view) { final PopupMenu menu = new PopupMenu(this, view); final MenuItem remove = menu.getMenu().add(RECYCLER_ITEM_POPUP_MENU_GROUP_ID, 0, Menu.NONE, R.string.play_queue_remove); - remove.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem menuItem) { - if (player == null) return false; + remove.setOnMenuItemClickListener(menuItem -> { + if (player == null) return false; - final int index = player.getPlayQueue().indexOf(item); - if (index != -1) player.getPlayQueue().remove(index); - return true; - } + final int index = player.getPlayQueue().indexOf(item); + if (index != -1) player.getPlayQueue().remove(index); + return true; }); final MenuItem detail = menu.getMenu().add(RECYCLER_ITEM_POPUP_MENU_GROUP_ID, 1, Menu.NONE, R.string.play_queue_stream_detail); - detail.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem menuItem) { - onOpenDetail(item.getServiceId(), item.getUrl(), item.getTitle()); - return true; - } + detail.setOnMenuItemClickListener(menuItem -> { + onOpenDetail(item.getServiceId(), item.getUrl(), item.getTitle()); + return true; }); menu.show(); diff --git a/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java b/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java index 5293ff3d6..af6473780 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java @@ -219,16 +219,20 @@ public final class ExtractorHelper { // as it will cause a infinite loop if it is Throwable cause, getCause = throwable; + // Check if throwable is a subclass of any of the filtered classes + final Class throwableClass = throwable.getClass(); for (Class causesEl : causesToCheck) { - if (throwable.getClass().isAssignableFrom(causesEl)) { + if (causesEl.isAssignableFrom(throwableClass)) { return true; } } + // Iteratively checks if the root cause of the throwable is a subclass of the filtered class while ((cause = throwable.getCause()) != null && getCause != cause) { getCause = cause; + final Class causeClass = cause.getClass(); for (Class causesEl : causesToCheck) { - if (cause.getClass().isAssignableFrom(causesEl)) { + if (causesEl.isAssignableFrom(causeClass)) { return true; } } 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 4475356fa..3a9125bdf 100644 --- a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java @@ -1,7 +1,6 @@ package org.schabi.newpipe.util; import android.app.Activity; -import android.app.PendingIntent; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; @@ -21,9 +20,7 @@ import org.schabi.newpipe.download.DownloadActivity; import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.ServiceList; import org.schabi.newpipe.extractor.StreamingService; -import org.schabi.newpipe.extractor.channel.ChannelInfoItem; import org.schabi.newpipe.extractor.exceptions.ExtractionException; -import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.fragments.MainFragment; import org.schabi.newpipe.fragments.detail.VideoDetailFragment; import org.schabi.newpipe.fragments.list.channel.ChannelFragment; @@ -46,8 +43,6 @@ import org.schabi.newpipe.settings.SettingsActivity; public class NavigationHelper { public static final String MAIN_FRAGMENT_TAG = "main_fragment_tag"; - public static final int PENDING_INTENT_OPEN_PLAYER_ACTIVITY = 1546; - /*////////////////////////////////////////////////////////////////////////// // Players //////////////////////////////////////////////////////////////////////////*/ @@ -92,9 +87,13 @@ public class NavigationHelper { context.startActivity(getPlayerIntent(context, MainVideoPlayer.class, queue)); } - public static void playOnPopupPlayer(final Context context, final PlayQueue queue) { - Toast.makeText(context, R.string.popup_playing_toast, Toast.LENGTH_SHORT).show(); - context.startService(getPlayerIntent(context, PopupVideoPlayer.class, queue)); + public static void playOnPopupPlayer(final Activity activity, final PlayQueue queue) { + if (!PermissionHelper.isPopupEnabled(activity)) { + PermissionHelper.showPopupEnablementToast(activity); + return; + } + Toast.makeText(activity, R.string.popup_playing_toast, Toast.LENGTH_SHORT).show(); + activity.startService(getPlayerIntent(activity, PopupVideoPlayer.class, queue)); } public static void playOnBackgroundPlayer(final Context context, final PlayQueue queue) { @@ -102,9 +101,13 @@ public class NavigationHelper { context.startService(getPlayerIntent(context, BackgroundPlayer.class, queue)); } - public static void enqueueOnPopupPlayer(final Context context, final PlayQueue queue) { - Toast.makeText(context, R.string.popup_playing_append, Toast.LENGTH_SHORT).show(); - context.startService(getPlayerEnqueueIntent(context, PopupVideoPlayer.class, queue)); + public static void enqueueOnPopupPlayer(final Activity activity, final PlayQueue queue) { + if (!PermissionHelper.isPopupEnabled(activity)) { + PermissionHelper.showPopupEnablementToast(activity); + return; + } + Toast.makeText(activity, R.string.popup_playing_append, Toast.LENGTH_SHORT).show(); + activity.startService(getPlayerEnqueueIntent(activity, PopupVideoPlayer.class, queue)); } public static void enqueueOnBackgroundPlayer(final Context context, final PlayQueue queue) { @@ -264,34 +267,22 @@ public class NavigationHelper { return true; } - public static void openBackgroundPlayerControl(final Context context) { - openServicePlayerControl(context, BackgroundPlayerActivity.class); + public static Intent getBackgroundPlayerActivityIntent(final Context context) { + return getServicePlayerActivityIntent(context, BackgroundPlayerActivity.class); } - public static void openPopupPlayerControl(final Context context) { - openServicePlayerControl(context, PopupVideoPlayerActivity.class); + public static Intent getPopupPlayerActivityIntent(final Context context) { + return getServicePlayerActivityIntent(context, PopupVideoPlayerActivity.class); } - private static void openServicePlayerControl(final Context context, final Class activityClass) { - Intent intent = getServicePlayerControlIntent(context, activityClass); - context.startActivity(intent); - context.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); - } - - public static Intent getServicePlayerControlIntent(final Context context, final Class activityClass) { - final Intent intent = new Intent(context, activityClass); + private static Intent getServicePlayerActivityIntent(final Context context, + final Class activityClass) { + Intent intent = new Intent(context, activityClass); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); } return intent; } - - public static PendingIntent getServicePlayerControlPendingIntent(final Context context, final Class activityClass) { - Intent intent = getServicePlayerControlIntent(context, activityClass); - PendingIntent pIntent = PendingIntent.getActivity(context, PENDING_INTENT_OPEN_PLAYER_ACTIVITY, intent, 0); - return pIntent; - } - /*////////////////////////////////////////////////////////////////////////// // Link handling //////////////////////////////////////////////////////////////////////////*/ diff --git a/app/src/main/java/org/schabi/newpipe/util/PermissionHelper.java b/app/src/main/java/org/schabi/newpipe/util/PermissionHelper.java index a5707ecb2..7cf804401 100644 --- a/app/src/main/java/org/schabi/newpipe/util/PermissionHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/PermissionHelper.java @@ -11,6 +11,11 @@ import android.provider.Settings; import android.support.annotation.RequiresApi; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; +import android.view.Gravity; +import android.widget.TextView; +import android.widget.Toast; + +import org.schabi.newpipe.R; public class PermissionHelper { public static final int PERMISSION_WRITE_STORAGE = 778; @@ -92,4 +97,16 @@ public class PermissionHelper { return false; }else return true; } + + public static boolean isPopupEnabled(Activity activity) { + return Build.VERSION.SDK_INT < Build.VERSION_CODES.M || + PermissionHelper.checkSystemAlertWindowPermission(activity); + } + + public static void showPopupEnablementToast(Context context) { + Toast toast = Toast.makeText(context, R.string.msg_popup_permission, Toast.LENGTH_LONG); + TextView messageView = toast.getView().findViewById(android.R.id.message); + if (messageView != null) messageView.setGravity(Gravity.CENTER); + toast.show(); + } } diff --git a/app/src/main/res/layout/dialog_title.xml b/app/src/main/res/layout/dialog_title.xml index fa7e155d2..36af65eb3 100644 --- a/app/src/main/res/layout/dialog_title.xml +++ b/app/src/main/res/layout/dialog_title.xml @@ -31,10 +31,14 @@ android:layout_below="@+id/itemTitleView" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" + android:ellipsize="marquee" + android:fadingEdge="horizontal" + android:marqueeRepeatLimit="marquee_forever" + android:scrollHorizontally="true" android:singleLine="true" android:textAppearance="?android:attr/textAppearanceSmall" android:textSize="@dimen/video_item_search_uploader_text_size" android:visibility="gone" tools:visibility="visible" - tools:text="TYPE" /> + tools:text="UPLOADER" /> \ No newline at end of file diff --git a/app/src/main/res/menu/menu_play_queue.xml b/app/src/main/res/menu/menu_play_queue.xml index 8fd0c9b6b..671d46329 100644 --- a/app/src/main/res/menu/menu_play_queue.xml +++ b/app/src/main/res/menu/menu_play_queue.xml @@ -17,4 +17,9 @@ android:orderInCategory="996" android:title="@string/play_queue_audio_settings" app:showAsAction="never"/> + + diff --git a/app/src/main/res/menu/menu_play_queue_bg.xml b/app/src/main/res/menu/menu_play_queue_bg.xml new file mode 100644 index 000000000..1a3ed0e5a --- /dev/null +++ b/app/src/main/res/menu/menu_play_queue_bg.xml @@ -0,0 +1,10 @@ + + + + diff --git a/app/src/main/res/menu/menu_play_queue_popup.xml b/app/src/main/res/menu/menu_play_queue_popup.xml new file mode 100644 index 000000000..dd5177da9 --- /dev/null +++ b/app/src/main/res/menu/menu_play_queue_popup.xml @@ -0,0 +1,10 @@ + + + + diff --git a/app/src/main/res/menu/menu_videooptions.xml b/app/src/main/res/menu/menu_videooptions.xml index 2fbde0412..1887ec1dd 100644 --- a/app/src/main/res/menu/menu_videooptions.xml +++ b/app/src/main/res/menu/menu_videooptions.xml @@ -6,16 +6,16 @@ diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4b0d64239..0f667d171 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -124,6 +124,11 @@ [Unknown] + Toggle Orientation + Switch to Background + Switch to Popup + Switch to Main + Error Network error