Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.liskovsoft.smartyoutubetv2.tv.R;
import com.liskovsoft.smartyoutubetv2.common.misc.MotherActivity;
import com.liskovsoft.smartyoutubetv2.tv.ui.playback.PlaybackActivity;
import com.liskovsoft.smartyoutubetv2.tv.ui.playback.PlaybackFragment;

public class AppDialogActivity extends MotherActivity {
private static final String TAG = AppDialogActivity.class.getSimpleName();
Expand Down Expand Up @@ -62,7 +63,47 @@ public boolean dispatchKeyEvent(KeyEvent event) {

//return mGlobalKeyTranslator.translate(event) || super.dispatchKeyEvent(event);
KeyEvent newEvent = mGlobalKeyTranslator.translate(event);
return handleNavigation(newEvent) || super.dispatchKeyEvent(newEvent);
return handleCommentsDialogMediaControls(newEvent) || handleNavigation(newEvent) || super.dispatchKeyEvent(newEvent);
}

private boolean handleCommentsDialogMediaControls(KeyEvent event) {
if (event == null || mFragment == null || !mFragment.isCommentsDialogShown()) {
return false;
}

PlaybackView view = PlaybackPresenter.instance(this).getView();
if (!(view instanceof Fragment)) {
return false;
}

Fragment playbackView = (Fragment) view;
int keyCode = event.getKeyCode();

if (keyCode == KeyEvent.KEYCODE_MEDIA_REWIND) {
if (event.getAction() == KeyEvent.ACTION_DOWN && playbackView instanceof PlaybackFragment) {
((PlaybackFragment) playbackView).rewind();
}
return true;
}

if (keyCode == KeyEvent.KEYCODE_MEDIA_FAST_FORWARD) {
if (event.getAction() == KeyEvent.ACTION_DOWN && playbackView instanceof PlaybackFragment) {
((PlaybackFragment) playbackView).fastForward();
}
return true;
}

if (keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE ||
keyCode == KeyEvent.KEYCODE_MEDIA_PLAY ||
keyCode == KeyEvent.KEYCODE_MEDIA_PAUSE) {
Activity activity = playbackView.getActivity();
if (activity != null) {
activity.dispatchKeyEvent(event);
}
return true;
}

return false;
}

private boolean handleNavigation(KeyEvent event) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,12 @@ public boolean isOverlay() {
return mIsOverlay;
}

public boolean isCommentsDialogShown() {
Fragment activeDialog =
getChildFragmentManager().findFragmentByTag(PREFERENCE_FRAGMENT_TAG);
return activeDialog instanceof CommentsPreferenceDialogFragment;
}

@Override
public boolean isPaused() {
return mIsPaused;
Expand Down Expand Up @@ -363,4 +369,4 @@ public void enableTransparent(boolean enable) {
mIsTransparent = enable;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ protected void initTheme() {

@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (mPlaybackFragment != null) {
mPlaybackFragment.onDispatchKeyEvent(event);
if (mPlaybackFragment != null && mPlaybackFragment.onDispatchKeyEvent(event)) {
return true;
}

return super.dispatchKeyEvent(event);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
package com.liskovsoft.smartyoutubetv2.tv.ui.playback;

import android.app.Activity;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Handler;
import android.media.session.PlaybackState;
import android.os.Build.VERSION;
import android.os.Bundle;
import android.os.Looper;
import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat;
Expand All @@ -12,7 +17,11 @@
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.Gravity;
import android.widget.FrameLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
Expand Down Expand Up @@ -100,6 +109,7 @@ public class PlaybackFragment extends SeekModePlaybackFragment implements Playba
private static final String SELECTED_VIDEO_ID = "SelectedVideoId";
private static final int UPDATE_DELAY_MS = 100;
private static final int SUGGESTIONS_START_INDEX = 1;
private static final float PLAY_HOLD_SPEED = 2.0f;
private VideoPlayerGlue mPlayerGlue;
private SimpleExoPlayer mPlayer;
private PlaybackPresenter mPlaybackPresenter;
Expand All @@ -124,6 +134,25 @@ public class PlaybackFragment extends SeekModePlaybackFragment implements Playba
private Video mPendingFocus;
private long mProgressShowTimeMs;
private String mSelectedVideoId;
private final Handler mPlayHoldHandler = new Handler(Looper.getMainLooper());
private boolean mIsPlayHoldSpeedApplied;
private boolean mIsPlayKeyPressed;
private float mPlayHoldPrevSpeed = 1.0f;
private TextView mPlayHoldSpeedBadge;
private final Runnable mApplyPlayHoldSpeedRunnable = () -> {
if (!mIsPlayKeyPressed || mIsPlayHoldSpeedApplied || !isPlaying()) {
return;
}

mPlayHoldPrevSpeed = getSpeed();
mIsPlayHoldSpeedApplied = true;

if (!Helpers.floatEquals(mPlayHoldPrevSpeed, PLAY_HOLD_SPEED)) {
setSpeed(PLAY_HOLD_SPEED);
}

showPlayHoldSpeedBadge();
};

@Override
public void onCreate(Bundle savedInstanceState) {
Expand Down Expand Up @@ -237,6 +266,8 @@ public void onResume() {
public void onPause() {
super.onPause();

stopPlayHoldSpeed();

// NOTE: don't move this into another place! Multiple components rely on it.
mPlaybackPresenter.onViewPaused();

Expand All @@ -248,8 +279,137 @@ public void onPause() {
//ExoPlayerInitializer.enableAudioFocus(mPlayer, false); // Disable focus in PIP
}

public void onDispatchKeyEvent(KeyEvent event) {
// NOP
public boolean onDispatchKeyEvent(KeyEvent event) {
if (event == null) {
return false;
}

int keyCode = event.getKeyCode();
boolean isPlayKey = keyCode == KeyEvent.KEYCODE_MEDIA_PLAY || keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE;

if (!isPlayKey) {
return false;
}

int action = event.getAction();

if (action == KeyEvent.ACTION_DOWN) {
if (event.getRepeatCount() == 0) {
mIsPlayKeyPressed = true;
mPlayHoldHandler.removeCallbacks(mApplyPlayHoldSpeedRunnable);
mPlayHoldHandler.postDelayed(mApplyPlayHoldSpeedRunnable, ViewConfiguration.getLongPressTimeout());
return true; // wait until UP to decide short press vs long press
}

// Prevent repeated media key downs from firing extra play/pause actions while the button is held.
return true;
}

if (action == KeyEvent.ACTION_UP) {
mIsPlayKeyPressed = false;
mPlayHoldHandler.removeCallbacks(mApplyPlayHoldSpeedRunnable);

if (mIsPlayHoldSpeedApplied) {
stopPlayHoldSpeed();
return true;
}

// Emulate the original short press behavior after we intercepted DOWN.
if (mPlaybackPresenter != null) {
mPlaybackPresenter.onKeyDown(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE);
}
return true;
}

return false;
}

private void stopPlayHoldSpeed() {
mPlayHoldHandler.removeCallbacks(mApplyPlayHoldSpeedRunnable);

if (!mIsPlayHoldSpeedApplied) {
return;
}

mIsPlayHoldSpeedApplied = false;
hidePlayHoldSpeedBadge();

if (!Helpers.floatEquals(getSpeed(), mPlayHoldPrevSpeed)) {
setSpeed(mPlayHoldPrevSpeed);
}
}

private void showPlayHoldSpeedBadge() {
TextView badgeView = ensurePlayHoldSpeedBadge();

if (badgeView != null) {
badgeView.setVisibility(View.VISIBLE);
}
}

private void hidePlayHoldSpeedBadge() {
if (mPlayHoldSpeedBadge != null) {
mPlayHoldSpeedBadge.setVisibility(View.GONE);
}
}

private TextView ensurePlayHoldSpeedBadge() {
if (mPlayHoldSpeedBadge != null) {
return mPlayHoldSpeedBadge;
}

Activity activity = getActivity();

if (activity == null) {
return null;
}

FrameLayout rootView = activity.findViewById(android.R.id.content);

if (rootView == null) {
return null;
}

float density = activity.getResources().getDisplayMetrics().density;
int paddingHorizontal = (int) (12 * density);
int paddingVertical = (int) (6 * density);
int topMargin = (int) (32 * density);
int rightMargin = (int) (32 * density);

TextView badgeView = new TextView(activity);
badgeView.setText("2x");
badgeView.setTextColor(Color.WHITE);
badgeView.setTypeface(Typeface.DEFAULT_BOLD);
badgeView.setTextSize(18);
badgeView.setPadding(paddingHorizontal, paddingVertical, paddingHorizontal, paddingVertical);
badgeView.setBackgroundColor(0x99000000);
badgeView.setVisibility(View.GONE);

FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams.gravity = Gravity.TOP | Gravity.END;
layoutParams.topMargin = topMargin;
layoutParams.rightMargin = rightMargin;

rootView.addView(badgeView, layoutParams);
mPlayHoldSpeedBadge = badgeView;

return mPlayHoldSpeedBadge;
}

private void removePlayHoldSpeedBadge() {
if (mPlayHoldSpeedBadge == null) {
return;
}

ViewGroup parent = (ViewGroup) mPlayHoldSpeedBadge.getParent();

if (parent != null) {
parent.removeView(mPlayHoldSpeedBadge);
}

mPlayHoldSpeedBadge = null;
}

public void onDispatchTouchEvent(MotionEvent event) {
Expand Down Expand Up @@ -1149,6 +1309,9 @@ public void setVideoGravity(int gravity) {
public void onDestroy() {
super.onDestroy();

stopPlayHoldSpeed();
removePlayHoldSpeedBadge();

Log.d(TAG, "Destroying PlaybackFragment...");

// Fix situations when engine didn't properly destroyed.
Expand Down