aboutsummaryrefslogtreecommitdiff
path: root/src/com/android/tv/ui/TunableTvView.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/tv/ui/TunableTvView.java')
-rw-r--r--src/com/android/tv/ui/TunableTvView.java922
1 files changed, 500 insertions, 422 deletions
diff --git a/src/com/android/tv/ui/TunableTvView.java b/src/com/android/tv/ui/TunableTvView.java
index 48386698..bb98d974 100644
--- a/src/com/android/tv/ui/TunableTvView.java
+++ b/src/com/android/tv/ui/TunableTvView.java
@@ -57,37 +57,37 @@ import android.view.SurfaceView;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
-
-import com.android.tv.ApplicationSingletons;
-import com.android.tv.Features;
import com.android.tv.InputSessionManager;
import com.android.tv.InputSessionManager.TvViewSession;
import com.android.tv.R;
-import com.android.tv.TvApplication;
-import com.android.tv.data.Program;
-import com.android.tv.data.ProgramDataManager;
-import com.android.tv.parental.ParentalControlSettings;
-import com.android.tv.util.DurationTimer;
-import com.android.tv.util.Debug;
+import com.android.tv.TvFeatures;
+import com.android.tv.TvSingletons;
import com.android.tv.analytics.Tracker;
import com.android.tv.common.BuildConfig;
+import com.android.tv.common.CommonConstants;
import com.android.tv.common.feature.CommonFeatures;
-import com.android.tv.data.Channel;
+import com.android.tv.common.util.CommonUtils;
+import com.android.tv.common.util.Debug;
+import com.android.tv.common.util.DurationTimer;
+import com.android.tv.common.util.PermissionUtils;
+import com.android.tv.data.Program;
+import com.android.tv.data.ProgramDataManager;
import com.android.tv.data.StreamInfo;
import com.android.tv.data.WatchedHistoryManager;
+import com.android.tv.data.api.Channel;
import com.android.tv.parental.ContentRatingsManager;
+import com.android.tv.parental.ParentalControlSettings;
import com.android.tv.recommendation.NotificationService;
-import com.android.tv.util.ImageLoader;
import com.android.tv.util.NetworkUtils;
-import com.android.tv.util.PermissionUtils;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;
-
+import com.android.tv.util.images.ImageLoader;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;
-public class TunableTvView extends FrameLayout implements StreamInfo {
+/** Includes the real {@link AppLayerTvView} handling tuning, block and other display events. */
+public class TunableTvView extends FrameLayout implements StreamInfo, TunableTvViewPlayingApi {
private static final boolean DEBUG = false;
private static final String TAG = "TunableTvView";
@@ -96,20 +96,29 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
public static final int VIDEO_UNAVAILABLE_REASON_SCREEN_BLOCKED = -3;
public static final int VIDEO_UNAVAILABLE_REASON_NONE = -100;
+ private OnTalkBackDpadKeyListener mOnTalkBackDpadKeyListener;
+
@Retention(RetentionPolicy.SOURCE)
@IntDef({BLOCK_SCREEN_TYPE_NO_UI, BLOCK_SCREEN_TYPE_SHRUNKEN_TV_VIEW, BLOCK_SCREEN_TYPE_NORMAL})
public @interface BlockScreenType {}
+
public static final int BLOCK_SCREEN_TYPE_NO_UI = 0;
public static final int BLOCK_SCREEN_TYPE_SHRUNKEN_TV_VIEW = 1;
public static final int BLOCK_SCREEN_TYPE_NORMAL = 2;
private static final String PERMISSION_RECEIVE_INPUT_EVENT =
- "com.android.tv.permission.RECEIVE_INPUT_EVENT";
+ CommonConstants.BASE_PACKAGE + ".permission.RECEIVE_INPUT_EVENT";
@Retention(RetentionPolicy.SOURCE)
- @IntDef({ TIME_SHIFT_STATE_NONE, TIME_SHIFT_STATE_PLAY, TIME_SHIFT_STATE_PAUSE,
- TIME_SHIFT_STATE_REWIND, TIME_SHIFT_STATE_FAST_FORWARD })
+ @IntDef({
+ TIME_SHIFT_STATE_NONE,
+ TIME_SHIFT_STATE_PLAY,
+ TIME_SHIFT_STATE_PAUSE,
+ TIME_SHIFT_STATE_REWIND,
+ TIME_SHIFT_STATE_FAST_FORWARD
+ })
private @interface TimeShiftState {}
+
private static final int TIME_SHIFT_STATE_NONE = 0;
private static final int TIME_SHIFT_STATE_PLAY = 1;
private static final int TIME_SHIFT_STATE_PAUSE = 2;
@@ -128,8 +137,7 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
private ContentRatingsManager mContentRatingsManager;
private ParentalControlSettings mParentalControlSettings;
private ProgramDataManager mProgramDataManager;
- @Nullable
- private WatchedHistoryManager mWatchedHistoryManager;
+ @Nullable private WatchedHistoryManager mWatchedHistoryManager;
private boolean mStarted;
private String mTagetInputId;
private TvInputInfo mInputInfo;
@@ -182,230 +190,258 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
private final ConnectivityManager mConnectivityManager;
private final InputSessionManager mInputSessionManager;
- private final TvInputCallback mCallback = new TvInputCallback() {
- @Override
- public void onConnectionFailed(String inputId) {
- Log.w(TAG, "Failed to bind an input");
- mTracker.sendInputConnectionFailure(inputId);
- Channel channel = mCurrentChannel;
- mCurrentChannel = null;
- mInputInfo = null;
- mCanReceiveInputEvent = false;
- if (mOnTuneListener != null) {
- // If tune is called inside onTuneFailed, mOnTuneListener will be set to
- // a new instance. In order to avoid to clear the new mOnTuneListener,
- // we copy mOnTuneListener to l and clear mOnTuneListener before
- // calling onTuneFailed.
- OnTuneListener listener = mOnTuneListener;
- mOnTuneListener = null;
- listener.onTuneFailed(channel);
- }
- }
-
- @Override
- public void onDisconnected(String inputId) {
- Log.w(TAG, "Session is released by crash");
- mTracker.sendInputDisconnected(inputId);
- Channel channel = mCurrentChannel;
- mCurrentChannel = null;
- mInputInfo = null;
- mCanReceiveInputEvent = false;
- if (mOnTuneListener != null) {
- OnTuneListener listener = mOnTuneListener;
- mOnTuneListener = null;
- listener.onUnexpectedStop(channel);
- }
- }
-
- @Override
- public void onChannelRetuned(String inputId, Uri channelUri) {
- if (DEBUG) {
- Log.d(TAG, "onChannelRetuned(inputId=" + inputId + ", channelUri="
- + channelUri + ")");
- }
- if (mOnTuneListener != null) {
- mOnTuneListener.onChannelRetuned(channelUri);
- }
- }
+ private final TvInputCallback mCallback =
+ new TvInputCallback() {
+ @Override
+ public void onConnectionFailed(String inputId) {
+ Log.w(TAG, "Failed to bind an input");
+ mTracker.sendInputConnectionFailure(inputId);
+ Channel channel = mCurrentChannel;
+ mCurrentChannel = null;
+ mInputInfo = null;
+ mCanReceiveInputEvent = false;
+ if (mOnTuneListener != null) {
+ // If tune is called inside onTuneFailed, mOnTuneListener will be set to
+ // a new instance. In order to avoid to clear the new mOnTuneListener,
+ // we copy mOnTuneListener to l and clear mOnTuneListener before
+ // calling onTuneFailed.
+ OnTuneListener listener = mOnTuneListener;
+ mOnTuneListener = null;
+ listener.onTuneFailed(channel);
+ }
+ }
- @Override
- public void onTracksChanged(String inputId, List<TvTrackInfo> tracks) {
- mHasClosedCaption = false;
- for (TvTrackInfo track : tracks) {
- if (track.getType() == TvTrackInfo.TYPE_SUBTITLE) {
- mHasClosedCaption = true;
- break;
+ @Override
+ public void onDisconnected(String inputId) {
+ Log.w(TAG, "Session is released by crash");
+ mTracker.sendInputDisconnected(inputId);
+ Channel channel = mCurrentChannel;
+ mCurrentChannel = null;
+ mInputInfo = null;
+ mCanReceiveInputEvent = false;
+ if (mOnTuneListener != null) {
+ OnTuneListener listener = mOnTuneListener;
+ mOnTuneListener = null;
+ listener.onUnexpectedStop(channel);
+ }
}
- }
- if (mOnTuneListener != null) {
- mOnTuneListener.onStreamInfoChanged(TunableTvView.this);
- }
- }
- @Override
- public void onTrackSelected(String inputId, int type, String trackId) {
- if (trackId == null) {
- // A track is unselected.
- if (type == TvTrackInfo.TYPE_VIDEO) {
- mVideoWidth = 0;
- mVideoHeight = 0;
- mVideoFormat = StreamInfo.VIDEO_DEFINITION_LEVEL_UNKNOWN;
- mVideoFrameRate = 0f;
- mVideoDisplayAspectRatio = 0f;
- } else if (type == TvTrackInfo.TYPE_AUDIO) {
- mAudioChannelCount = StreamInfo.AUDIO_CHANNEL_COUNT_UNKNOWN;
+ @Override
+ public void onChannelRetuned(String inputId, Uri channelUri) {
+ if (DEBUG) {
+ Log.d(
+ TAG,
+ "onChannelRetuned(inputId="
+ + inputId
+ + ", channelUri="
+ + channelUri
+ + ")");
+ }
+ if (mOnTuneListener != null) {
+ mOnTuneListener.onChannelRetuned(channelUri);
+ }
}
- } else {
- List<TvTrackInfo> tracks = getTracks(type);
- boolean trackFound = false;
- if (tracks != null) {
+
+ @Override
+ public void onTracksChanged(String inputId, List<TvTrackInfo> tracks) {
+ mHasClosedCaption = false;
for (TvTrackInfo track : tracks) {
- if (track.getId().equals(trackId)) {
- if (type == TvTrackInfo.TYPE_VIDEO) {
- mVideoWidth = track.getVideoWidth();
- mVideoHeight = track.getVideoHeight();
- mVideoFormat = Utils.getVideoDefinitionLevelFromSize(
- mVideoWidth, mVideoHeight);
- mVideoFrameRate = track.getVideoFrameRate();
- if (mVideoWidth <= 0 || mVideoHeight <= 0) {
- mVideoDisplayAspectRatio = 0.0f;
- } else {
- float VideoPixelAspectRatio =
- track.getVideoPixelAspectRatio();
- mVideoDisplayAspectRatio = VideoPixelAspectRatio
- * mVideoWidth / mVideoHeight;
- }
- } else if (type == TvTrackInfo.TYPE_AUDIO) {
- mAudioChannelCount = track.getAudioChannelCount();
- }
- trackFound = true;
+ if (track.getType() == TvTrackInfo.TYPE_SUBTITLE) {
+ mHasClosedCaption = true;
break;
}
}
+ if (mOnTuneListener != null) {
+ mOnTuneListener.onStreamInfoChanged(TunableTvView.this);
+ }
}
- if (!trackFound) {
- Log.w(TAG, "Invalid track ID: " + trackId);
+
+ @Override
+ public void onTrackSelected(String inputId, int type, String trackId) {
+ if (trackId == null) {
+ // A track is unselected.
+ if (type == TvTrackInfo.TYPE_VIDEO) {
+ mVideoWidth = 0;
+ mVideoHeight = 0;
+ mVideoFormat = StreamInfo.VIDEO_DEFINITION_LEVEL_UNKNOWN;
+ mVideoFrameRate = 0f;
+ mVideoDisplayAspectRatio = 0f;
+ } else if (type == TvTrackInfo.TYPE_AUDIO) {
+ mAudioChannelCount = StreamInfo.AUDIO_CHANNEL_COUNT_UNKNOWN;
+ }
+ } else {
+ List<TvTrackInfo> tracks = getTracks(type);
+ boolean trackFound = false;
+ if (tracks != null) {
+ for (TvTrackInfo track : tracks) {
+ if (track.getId().equals(trackId)) {
+ if (type == TvTrackInfo.TYPE_VIDEO) {
+ mVideoWidth = track.getVideoWidth();
+ mVideoHeight = track.getVideoHeight();
+ mVideoFormat =
+ Utils.getVideoDefinitionLevelFromSize(
+ mVideoWidth, mVideoHeight);
+ mVideoFrameRate = track.getVideoFrameRate();
+ if (mVideoWidth <= 0 || mVideoHeight <= 0) {
+ mVideoDisplayAspectRatio = 0.0f;
+ } else {
+ float VideoPixelAspectRatio =
+ track.getVideoPixelAspectRatio();
+ mVideoDisplayAspectRatio =
+ VideoPixelAspectRatio
+ * mVideoWidth
+ / mVideoHeight;
+ }
+ } else if (type == TvTrackInfo.TYPE_AUDIO) {
+ mAudioChannelCount = track.getAudioChannelCount();
+ }
+ trackFound = true;
+ break;
+ }
+ }
+ }
+ if (!trackFound) {
+ Log.w(TAG, "Invalid track ID: " + trackId);
+ }
+ }
+ if (mOnTuneListener != null) {
+ mOnTuneListener.onStreamInfoChanged(TunableTvView.this);
+ }
}
- }
- if (mOnTuneListener != null) {
- mOnTuneListener.onStreamInfoChanged(TunableTvView.this);
- }
- }
- @Override
- public void onVideoAvailable(String inputId) {
- if (DEBUG) Log.d(TAG, "onVideoAvailable: {inputId=" + inputId + "}");
- Debug.getTimer(Debug.TAG_START_UP_TIMER).log("Start up of Live TV ends," +
- " TunableTvView.onVideoAvailable resets timer");
- long startUpDurationTime = Debug.getTimer(Debug.TAG_START_UP_TIMER).reset();
- Debug.removeTimer(Debug.TAG_START_UP_TIMER);
- if (BuildConfig.ENG && startUpDurationTime > Debug.TIME_START_UP_DURATION_THRESHOLD) {
- showAlertDialogForLongStartUp();
- }
- mVideoUnavailableReason = VIDEO_UNAVAILABLE_REASON_NONE;
- updateBlockScreenAndMuting();
- if (mOnTuneListener != null) {
- mOnTuneListener.onStreamInfoChanged(TunableTvView.this);
- }
- }
+ @Override
+ public void onVideoAvailable(String inputId) {
+ if (DEBUG) Log.d(TAG, "onVideoAvailable: {inputId=" + inputId + "}");
+ Debug.getTimer(Debug.TAG_START_UP_TIMER)
+ .log(
+ "Start up of Live TV ends,"
+ + " TunableTvView.onVideoAvailable resets timer");
+ long startUpDurationTime = Debug.getTimer(Debug.TAG_START_UP_TIMER).reset();
+ Debug.removeTimer(Debug.TAG_START_UP_TIMER);
+ if (BuildConfig.ENG
+ && startUpDurationTime > Debug.TIME_START_UP_DURATION_THRESHOLD) {
+ showAlertDialogForLongStartUp();
+ }
+ mVideoUnavailableReason = VIDEO_UNAVAILABLE_REASON_NONE;
+ updateBlockScreenAndMuting();
+ if (mOnTuneListener != null) {
+ mOnTuneListener.onStreamInfoChanged(TunableTvView.this);
+ }
+ }
- private void showAlertDialogForLongStartUp() {
- new AlertDialog.Builder(getContext()).setTitle(
- getContext().getString(R.string.settings_send_feedback))
- .setMessage("Because the start up time of Live channels is too long," +
- " please send feedback")
- .setPositiveButton(android.R.string.ok,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialogInterface, int i) {
- Intent intent = new Intent(Intent.ACTION_APP_ERROR);
- ApplicationErrorReport report = new ApplicationErrorReport();
- report.packageName = report.processName = getContext()
- .getApplicationContext().getPackageName();
- report.time = System.currentTimeMillis();
- report.type = ApplicationErrorReport.TYPE_CRASH;
-
- // Add the crash info to add title of feedback automatically.
- ApplicationErrorReport.CrashInfo crash = new
- ApplicationErrorReport.CrashInfo();
- crash.exceptionClassName =
- "Live TV start up takes long time";
- crash.exceptionMessage =
- "The start up time of Live TV is too long";
- report.crashInfo = crash;
-
- intent.putExtra(Intent.EXTRA_BUG_REPORT, report);
- getContext().startActivity(intent);
- }
- })
- .setNegativeButton(android.R.string.no, null)
- .show();
- }
+ private void showAlertDialogForLongStartUp() {
+ new AlertDialog.Builder(getContext())
+ .setTitle(getContext().getString(R.string.settings_send_feedback))
+ .setMessage(
+ "Because the start up time of Live channels is too long,"
+ + " please send feedback")
+ .setPositiveButton(
+ android.R.string.ok,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(
+ DialogInterface dialogInterface, int i) {
+ Intent intent = new Intent(Intent.ACTION_APP_ERROR);
+ ApplicationErrorReport report =
+ new ApplicationErrorReport();
+ report.packageName =
+ report.processName =
+ getContext()
+ .getApplicationContext()
+ .getPackageName();
+ report.time = System.currentTimeMillis();
+ report.type = ApplicationErrorReport.TYPE_CRASH;
+
+ // Add the crash info to add title of feedback
+ // automatically.
+ ApplicationErrorReport.CrashInfo crash =
+ new ApplicationErrorReport.CrashInfo();
+ crash.exceptionClassName =
+ "Live TV start up takes long time";
+ crash.exceptionMessage =
+ "The start up time of Live TV is too long";
+ report.crashInfo = crash;
+
+ intent.putExtra(Intent.EXTRA_BUG_REPORT, report);
+ getContext().startActivity(intent);
+ }
+ })
+ .setNegativeButton(android.R.string.cancel, null)
+ .show();
+ }
- @Override
- public void onVideoUnavailable(String inputId, int reason) {
- if (reason != TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING
- && reason != TvInputManager.VIDEO_UNAVAILABLE_REASON_BUFFERING) {
- Debug.getTimer(Debug.TAG_START_UP_TIMER).log(
- "TunableTvView.onVideoUnAvailable reason = (" + reason
- + ") and removes timer");
- Debug.removeTimer(Debug.TAG_START_UP_TIMER);
- } else {
- Debug.getTimer(Debug.TAG_START_UP_TIMER).log(
- "TunableTvView.onVideoUnAvailable reason = (" + reason + ")");
- }
- mVideoUnavailableReason = reason;
- if (closePipIfNeeded()) {
- return;
- }
- updateBlockScreenAndMuting();
- if (mOnTuneListener != null) {
- mOnTuneListener.onStreamInfoChanged(TunableTvView.this);
- }
- switch (reason) {
- case TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN:
- case TvInputManager.VIDEO_UNAVAILABLE_REASON_BUFFERING:
- case TvInputManager.VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL:
- mTracker.sendChannelVideoUnavailable(mCurrentChannel, reason);
- default:
- // do nothing
- }
- }
+ @Override
+ public void onVideoUnavailable(String inputId, int reason) {
+ if (reason != TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING
+ && reason != TvInputManager.VIDEO_UNAVAILABLE_REASON_BUFFERING) {
+ Debug.getTimer(Debug.TAG_START_UP_TIMER)
+ .log(
+ "TunableTvView.onVideoUnAvailable reason = ("
+ + reason
+ + ") and removes timer");
+ Debug.removeTimer(Debug.TAG_START_UP_TIMER);
+ } else {
+ Debug.getTimer(Debug.TAG_START_UP_TIMER)
+ .log("TunableTvView.onVideoUnAvailable reason = (" + reason + ")");
+ }
+ mVideoUnavailableReason = reason;
+ if (closePipIfNeeded()) {
+ return;
+ }
+ updateBlockScreenAndMuting();
+ if (mOnTuneListener != null) {
+ mOnTuneListener.onStreamInfoChanged(TunableTvView.this);
+ }
+ switch (reason) {
+ case TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN:
+ case TvInputManager.VIDEO_UNAVAILABLE_REASON_BUFFERING:
+ case TvInputManager.VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL:
+ mTracker.sendChannelVideoUnavailable(mCurrentChannel, reason);
+ break;
+ default:
+ // do nothing
+ }
+ }
- @Override
- public void onContentAllowed(String inputId) {
- mBlockedContentRating = null;
- updateBlockScreenAndMuting();
- if (mOnTuneListener != null) {
- mOnTuneListener.onContentAllowed();
- }
- }
+ @Override
+ public void onContentAllowed(String inputId) {
+ mBlockedContentRating = null;
+ updateBlockScreenAndMuting();
+ if (mOnTuneListener != null) {
+ mOnTuneListener.onContentAllowed();
+ }
+ }
- @Override
- public void onContentBlocked(String inputId, TvContentRating rating) {
- if (rating != null && rating.equals(mBlockedContentRating)) {
- return;
- }
- mBlockedContentRating = rating;
- if (closePipIfNeeded()) {
- return;
- }
- updateBlockScreenAndMuting();
- if (mOnTuneListener != null) {
- mOnTuneListener.onContentBlocked();
- }
- }
+ @Override
+ public void onContentBlocked(String inputId, TvContentRating rating) {
+ if (rating != null && rating.equals(mBlockedContentRating)) {
+ return;
+ }
+ mBlockedContentRating = rating;
+ if (closePipIfNeeded()) {
+ return;
+ }
+ updateBlockScreenAndMuting();
+ if (mOnTuneListener != null) {
+ mOnTuneListener.onContentBlocked();
+ }
+ }
- @Override
- public void onTimeShiftStatusChanged(String inputId, int status) {
- if (DEBUG) {
- Log.d(TAG, "onTimeShiftStatusChanged: {inputId=" + inputId + ", status=" + status +
- "}");
- }
- boolean available = status == TvInputManager.TIME_SHIFT_STATUS_AVAILABLE;
- setTimeShiftAvailable(available);
- }
- };
+ @Override
+ public void onTimeShiftStatusChanged(String inputId, int status) {
+ if (DEBUG) {
+ Log.d(
+ TAG,
+ "onTimeShiftStatusChanged: {inputId="
+ + inputId
+ + ", status="
+ + status
+ + "}");
+ }
+ boolean available = status == TvInputManager.TIME_SHIFT_STATUS_AVAILABLE;
+ setTimeShiftAvailable(available);
+ }
+ };
public TunableTvView(Context context) {
this(context, null);
@@ -423,49 +459,77 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
super(context, attrs, defStyleAttr, defStyleRes);
inflate(getContext(), R.layout.tunable_tv_view, this);
- ApplicationSingletons appSingletons = TvApplication.getSingletons(context);
+ TvSingletons tvSingletons = TvSingletons.getSingletons(context);
if (CommonFeatures.DVR.isEnabled(context)) {
- mInputSessionManager = appSingletons.getInputSessionManager();
+ mInputSessionManager = tvSingletons.getInputSessionManager();
} else {
mInputSessionManager = null;
}
- mInputManager = appSingletons.getTvInputManagerHelper();
- mConnectivityManager = (ConnectivityManager) context
- .getSystemService(Context.CONNECTIVITY_SERVICE);
+ mInputManager = tvSingletons.getTvInputManagerHelper();
+ mConnectivityManager =
+ (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
mCanModifyParentalControls = PermissionUtils.hasModifyParentalControls(context);
- mTracker = appSingletons.getTracker();
+ mTracker = tvSingletons.getTracker();
mBlockScreenType = BLOCK_SCREEN_TYPE_NORMAL;
mBlockScreenView = (BlockScreenView) findViewById(R.id.block_screen);
- mBlockScreenView.addInfoFadeInAnimationListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- adjustBlockScreenSpacingAndText();
- }
- });
+ mBlockScreenView.addInfoFadeInAnimationListener(
+ new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ adjustBlockScreenSpacingAndText();
+ }
+ });
mBufferingSpinnerView = findViewById(R.id.buffering_spinner);
- mTuningImageColorFilter = getResources()
- .getColor(R.color.tvview_block_image_color_filter, null);
+ mTuningImageColorFilter =
+ getResources().getColor(R.color.tvview_block_image_color_filter, null);
mDimScreenView = findViewById(R.id.dim_screen);
- mDimScreenView.animate().setListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- if (mActionAfterFade != null) {
- mActionAfterFade.run();
- }
- }
+ mDimScreenView
+ .animate()
+ .setListener(
+ new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (mActionAfterFade != null) {
+ mActionAfterFade.run();
+ }
+ }
- @Override
- public void onAnimationCancel(Animator animation) {
- if (mActionAfterFade != null) {
- mActionAfterFade.run();
- }
- }
- });
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ if (mActionAfterFade != null) {
+ mActionAfterFade.run();
+ }
+ }
+ });
+ View placeholder = findViewById(R.id.placeholder);
+ placeholder.requestFocus();
+ findViewById(R.id.channel_up)
+ .setOnFocusChangeListener(
+ (v, hasFocus) -> {
+ if (hasFocus) {
+ placeholder.requestFocus();
+ if (mOnTalkBackDpadKeyListener != null) {
+ mOnTalkBackDpadKeyListener.onTalkBackDpadKey(
+ KeyEvent.KEYCODE_DPAD_UP);
+ }
+ }
+ });
+ findViewById(R.id.channel_down)
+ .setOnFocusChangeListener(
+ (v, hasFocus) -> {
+ if (hasFocus) {
+ placeholder.requestFocus();
+ if (mOnTalkBackDpadKeyListener != null) {
+ mOnTalkBackDpadKeyListener.onTalkBackDpadKey(
+ KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+ }
+ });
}
- public void initialize(ProgramDataManager programDataManager,
- TvInputManagerHelper tvInputManagerHelper) {
+ public void initialize(
+ ProgramDataManager programDataManager, TvInputManagerHelper tvInputManagerHelper) {
mTvView = (AppLayerTvView) findViewById(R.id.tv_view);
mProgramDataManager = programDataManager;
mInputManagerHelper = tvInputManagerHelper;
@@ -482,9 +546,7 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
mStarted = true;
}
- /**
- * Warms up the input to reduce the start time.
- */
+ /** Warms up the input to reduce the start time. */
public void warmUpInput(String inputId, Uri channelUri) {
if (!mStarted && inputId != null && channelUri != null) {
if (mTvViewSession != null) {
@@ -506,16 +568,14 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
long duration = mChannelViewTimer.reset();
mTracker.sendChannelViewStop(mCurrentChannel, duration);
if (mWatchedHistoryManager != null && !mCurrentChannel.isPassthrough()) {
- mWatchedHistoryManager.logChannelViewStop(mCurrentChannel,
- System.currentTimeMillis(), duration);
+ mWatchedHistoryManager.logChannelViewStop(
+ mCurrentChannel, System.currentTimeMillis(), duration);
}
}
reset();
}
- /**
- * Releases the resources.
- */
+ /** Releases the resources. */
public void release() {
if (mInputSessionManager != null) {
mInputSessionManager.releaseTvViewSession(mTvViewSession);
@@ -523,18 +583,14 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
}
}
- /**
- * Resets TV view.
- */
+ /** Resets TV view. */
public void reset() {
resetInternal();
mVideoUnavailableReason = VIDEO_UNAVAILABLE_REASON_NOT_TUNED;
updateBlockScreenAndMuting();
}
- /**
- * Resets TV view to acquire the recording session.
- */
+ /** Resets TV view to acquire the recording session. */
public void resetByRecording() {
resetInternal();
}
@@ -560,20 +616,17 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
mWatchedHistoryManager = watchedHistoryManager;
}
- /**
- * Sets if the TunableTvView is under shrunken.
- */
+ /** Sets if the TunableTvView is under shrunken. */
public void setIsUnderShrunken(boolean isUnderShrunken) {
mIsUnderShrunken = isUnderShrunken;
}
+ @Override
public boolean isPlaying() {
return mStarted;
}
- /**
- * Called when parental control is changed.
- */
+ /** Called when parental control is changed. */
public void onParentalControlChanged(boolean enabled) {
mParentControlEnabled = enabled;
if (!enabled) {
@@ -586,8 +639,8 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
* Tunes to a channel with the {@code channelId}.
*
* @param params extra data to send it to TIS and store the data in TIMS.
- * @return false, if the TV input is not a proper state to tune to a channel. For example,
- * if the state is disconnected or channelId doesn't exist, it returns false.
+ * @return false, if the TV input is not a proper state to tune to a channel. For example, if
+ * the state is disconnected or channelId doesn't exist, it returns false.
*/
public boolean tuneTo(Channel channel, Bundle params, OnTuneListener listener) {
Debug.getTimer(Debug.TAG_START_UP_TIMER).log("TunableTvView.tuneTo");
@@ -603,24 +656,34 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
long duration = mChannelViewTimer.reset();
mTracker.sendChannelViewStop(mCurrentChannel, duration);
if (mWatchedHistoryManager != null && !mCurrentChannel.isPassthrough()) {
- mWatchedHistoryManager.logChannelViewStop(mCurrentChannel,
- System.currentTimeMillis(), duration);
+ mWatchedHistoryManager.logChannelViewStop(
+ mCurrentChannel, System.currentTimeMillis(), duration);
}
}
mOnTuneListener = listener;
mCurrentChannel = channel;
- boolean tunedByRecommendation = params != null
- && params.getString(NotificationService.TUNE_PARAMS_RECOMMENDATION_TYPE) != null;
+ boolean tunedByRecommendation =
+ params != null
+ && params.getString(NotificationService.TUNE_PARAMS_RECOMMENDATION_TYPE)
+ != null;
boolean needSurfaceSizeUpdate = false;
if (!inputInfo.equals(mInputInfo)) {
mTagetInputId = inputInfo.getId();
mInputInfo = inputInfo;
- mCanReceiveInputEvent = getContext().getPackageManager().checkPermission(
- PERMISSION_RECEIVE_INPUT_EVENT, mInputInfo.getServiceInfo().packageName)
+ mCanReceiveInputEvent =
+ getContext()
+ .getPackageManager()
+ .checkPermission(
+ PERMISSION_RECEIVE_INPUT_EVENT,
+ mInputInfo.getServiceInfo().packageName)
== PackageManager.PERMISSION_GRANTED;
if (DEBUG) {
- Log.d(TAG, "Input \'" + mInputInfo.getId() + "\' can receive input event: "
- + mCanReceiveInputEvent);
+ Log.d(
+ TAG,
+ "Input \'"
+ + mInputInfo.getId()
+ + "\' can receive input event: "
+ + mCanReceiveInputEvent);
}
needSurfaceSizeUpdate = true;
}
@@ -671,6 +734,7 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
mCurrentChannel = currentChannel;
}
+ @Override
public void setStreamVolume(float volume) {
if (!mStarted) {
throw new IllegalStateException("TvView isn't started");
@@ -683,13 +747,13 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
}
/**
- * Sets fixed size for the internal {@link android.view.Surface} of
- * {@link android.media.tv.TvView}. If either {@code width} or {@code height} is non positive,
- * the {@link android.view.Surface}'s size will be matched to the layout.
+ * Sets fixed size for the internal {@link android.view.Surface} of {@link
+ * android.media.tv.TvView}. If either {@code width} or {@code height} is non positive, the
+ * {@link android.view.Surface}'s size will be matched to the layout.
*
- * Note: Once {@link android.view.SurfaceHolder#setFixedSize} is called,
- * {@link android.view.SurfaceView} and its underlying window can be misaligned, when the size
- * of {@link android.view.SurfaceView} is changed without changing either left position or top
+ * <p>Note: Once {@link android.view.SurfaceHolder#setFixedSize} is called, {@link
+ * android.view.SurfaceView} and its underlying window can be misaligned, when the size of
+ * {@link android.view.SurfaceView} is changed without changing either left position or top
* position. For detail, please refer the codes of android.view.SurfaceView.updateWindow().
*/
public void setFixedSurfaceSize(int width, int height) {
@@ -728,10 +792,15 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
public interface OnTuneListener {
void onTuneFailed(Channel channel);
+
void onUnexpectedStop(Channel channel);
+
void onStreamInfoChanged(StreamInfo info);
+
void onChannelRetuned(Uri channel);
+
void onContentBlocked();
+
void onContentAllowed();
}
@@ -759,9 +828,7 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
return mVideoFrameRate;
}
- /**
- * Returns displayed aspect ratio (video width / video height * pixel ratio).
- */
+ /** Returns displayed aspect ratio (video width / video height * pixel ratio). */
@Override
public float getVideoDisplayAspectRatio() {
return mVideoDisplayAspectRatio;
@@ -793,9 +860,7 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
return mVideoUnavailableReason;
}
- /**
- * Returns the {@link android.view.SurfaceView} of the {@link android.media.tv.TvView}.
- */
+ /** Returns the {@link android.view.SurfaceView} of the {@link android.media.tv.TvView}. */
private SurfaceView getSurfaceView() {
return (SurfaceView) mTvView.getChildAt(0);
}
@@ -804,6 +869,10 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
mTvView.setOnUnhandledInputEventListener(listener);
}
+ public void setOnTalkBackDpadKeyListener(OnTalkBackDpadKeyListener listener) {
+ mOnTalkBackDpadKeyListener = listener;
+ }
+
public void setClosedCaptionEnabled(boolean enabled) {
mTvView.setCaptionEnabled(enabled);
}
@@ -821,16 +890,16 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
}
/**
- * Gets {@link android.view.ViewGroup.MarginLayoutParams} of the underlying
- * {@link TvView}, which is the actual view to play live TV videos.
+ * Gets {@link android.view.ViewGroup.MarginLayoutParams} of the underlying {@link TvView},
+ * which is the actual view to play live TV videos.
*/
public MarginLayoutParams getTvViewLayoutParams() {
return (MarginLayoutParams) mTvView.getLayoutParams();
}
/**
- * Sets {@link android.view.ViewGroup.MarginLayoutParams} of the underlying
- * {@link TvView}, which is the actual view to play live TV videos.
+ * Sets {@link android.view.ViewGroup.MarginLayoutParams} of the underlying {@link TvView},
+ * which is the actual view to play live TV videos.
*/
public void setTvViewLayoutParams(MarginLayoutParams layoutParams) {
mTvView.setLayoutParams(layoutParams);
@@ -851,16 +920,12 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
return isScreenBlocked() || isContentBlocked();
}
- /**
- * Returns if the screen is blocked by {@link #blockOrUnblockScreen(boolean)}.
- */
+ /** Returns if the screen is blocked by {@link #blockOrUnblockScreen(boolean)}. */
public boolean isScreenBlocked() {
return mScreenBlocked;
}
- /**
- * Returns {@code true} if the content is blocked, otherwise {@code false}.
- */
+ /** Returns {@code true} if the content is blocked, otherwise {@code false}. */
public boolean isContentBlocked() {
return mBlockedContentRating != null;
}
@@ -869,18 +934,15 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
mOnScreenBlockedListener = listener;
}
- /**
- * Returns currently blocked content rating. {@code null} if it's not blocked.
- */
+ /** Returns currently blocked content rating. {@code null} if it's not blocked. */
@Override
public TvContentRating getBlockedContentRating() {
return mBlockedContentRating;
}
/**
- * Blocks/unblocks current TV screen and mutes.
- * There would be black screen with lock icon in order to show that
- * screen block is intended and not an error.
+ * Blocks/unblocks current TV screen and mutes. There would be black screen with lock icon in
+ * order to show that screen block is intended and not an error.
*
* @param blockOrUnblock {@code true} to block the screen, or {@code false} to unblock.
*/
@@ -909,8 +971,8 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
/**
* Set the type of block screen. If {@code type} is set to {@code BLOCK_SCREEN_TYPE_NO_UI}, the
* block screen will not show any description such as a lock icon and a text for the blocked
- * reason, if {@code type} is set to {@code BLOCK_SCREEN_TYPE_SHRUNKEN_TV_VIEW}, the block screen
- * will show the description for shrunken tv view (Small icon and short text), and if
+ * reason, if {@code type} is set to {@code BLOCK_SCREEN_TYPE_SHRUNKEN_TV_VIEW}, the block
+ * screen will show the description for shrunken tv view (Small icon and short text), and if
* {@code type} is set to {@code BLOCK_SCREEN_TYPE_NORMAL}, the block screen will show the
* description for normal tv view (Big icon and long text).
*
@@ -925,14 +987,16 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
private void updateBlockScreen(boolean animation) {
mBlockScreenView.endAnimations();
- int blockReason = (mScreenBlocked || mBlockedContentRating != null)
- && mParentControlEnabled ? VIDEO_UNAVAILABLE_REASON_SCREEN_BLOCKED
+ int blockReason =
+ (mScreenBlocked || mBlockedContentRating != null) && mParentControlEnabled
+ ? VIDEO_UNAVAILABLE_REASON_SCREEN_BLOCKED
: mVideoUnavailableReason;
if (blockReason != VIDEO_UNAVAILABLE_REASON_NONE) {
mBufferingSpinnerView.setVisibility(
blockReason == TvInputManager.VIDEO_UNAVAILABLE_REASON_BUFFERING
- || blockReason == TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING ?
- VISIBLE : GONE);
+ || blockReason == TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING
+ ? VISIBLE
+ : GONE);
if (!animation) {
adjustBlockScreenSpacingAndText();
}
@@ -959,7 +1023,8 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
if (blockReason == TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING) {
showImageForTuningIfNeeded();
} else if (blockReason == TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN
- && mCurrentChannel != null && !mCurrentChannel.isPhysicalTunerChannel()) {
+ && mCurrentChannel != null
+ && !mCurrentChannel.isPhysicalTunerChannel()) {
mInternetCheckTask = new InternetCheckTask();
mInternetCheckTask.execute();
}
@@ -982,8 +1047,8 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
}
/**
- * Returns the block screen text corresponding to the current status.
- * Note that returning {@code null} value means that the current text should not be changed.
+ * Returns the block screen text corresponding to the current status. Note that returning {@code
+ * null} value means that the current text should not be changed.
*/
private String getBlockScreenText() {
// TODO: add a test for this method
@@ -1051,7 +1116,7 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
}
private boolean closePipIfNeeded() {
- if (Features.PICTURE_IN_PICTURE.isEnabled(getContext())
+ if (TvFeatures.PICTURE_IN_PICTURE.isEnabled(getContext())
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
&& ((Activity) getContext()).isInPictureInPictureMode()
&& (mScreenBlocked
@@ -1071,8 +1136,13 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
private boolean shouldShowImageForTuning() {
if (mVideoUnavailableReason != TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING
- || mScreenBlocked || mBlockedContentRating != null || mCurrentChannel == null
- || mIsUnderShrunken || getWidth() == 0 || getWidth() == 0 || !isBundledInput()) {
+ || mScreenBlocked
+ || mBlockedContentRating != null
+ || mCurrentChannel == null
+ || mIsUnderShrunken
+ || getWidth() == 0
+ || getWidth() == 0
+ || !isBundledInput()) {
return false;
}
Program currentProgram = mProgramDataManager.getCurrentProgram(mCurrentChannel.getId());
@@ -1091,7 +1161,10 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
}
Program currentProgram = mProgramDataManager.getCurrentProgram(mCurrentChannel.getId());
if (currentProgram != null) {
- currentProgram.loadPosterArt(getContext(), getWidth(), getHeight(),
+ currentProgram.loadPosterArt(
+ getContext(),
+ getWidth(),
+ getHeight(),
createProgramPosterArtCallback(mCurrentChannel.getId()));
}
}
@@ -1102,16 +1175,19 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
TvInputInfo input = mInputManager.getTvInputInfo(mTagetInputId);
Long timeMs = mInputSessionManager.getEarliestRecordingSessionEndTimeMs(mTagetInputId);
if (timeMs != null) {
- return getResources().getQuantityString(R.plurals.tvview_msg_input_no_resource,
- input.getTunerCount(),
- DateUtils.formatDateTime(getContext(), timeMs, DateUtils.FORMAT_SHOW_TIME));
+ return getResources()
+ .getQuantityString(
+ R.plurals.tvview_msg_input_no_resource,
+ input.getTunerCount(),
+ DateUtils.formatDateTime(
+ getContext(), timeMs, DateUtils.FORMAT_SHOW_TIME));
}
}
return null;
}
private void updateMuteStatus() {
- // Workaround: TunerTvInputService uses AC3 pass-through implementation, which disables
+ // Workaround: BaseTunerTvInputService uses AC3 pass-through implementation, which disables
// audio tracks to enforce the mute request. We don't want to send mute request if we are
// not going to block the screen to prevent the video jankiness resulted by disabling audio
// track before the playback is started. In other way, we should send unmute request before
@@ -1119,7 +1195,8 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
// itself right way when the playback is going to be started, which results the initial
// jankiness, too.
boolean isBundledInput = isBundledInput();
- if ((isBundledInput || isVideoOrAudioAvailable()) && !mScreenBlocked
+ if ((isBundledInput || isVideoOrAudioAvailable())
+ && !mScreenBlocked
&& mBlockedContentRating == null) {
if (mIsMuted) {
mIsMuted = false;
@@ -1128,7 +1205,8 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
} else {
if (!mIsMuted) {
if ((mInputInfo == null || isBundledInput)
- && !mScreenBlocked && mBlockedContentRating == null) {
+ && !mScreenBlocked
+ && mBlockedContentRating == null) {
return;
}
mIsMuted = true;
@@ -1138,8 +1216,9 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
}
private boolean isBundledInput() {
- return mInputInfo != null && mInputInfo.getType() == TvInputInfo.TYPE_TUNER
- && Utils.isBundledInput(mInputInfo.getId());
+ return mInputInfo != null
+ && mInputInfo.getType() == TvInputInfo.TYPE_TUNER
+ && CommonUtils.isBundledInput(mInputInfo.getId());
}
/** Returns true if this view is faded out. */
@@ -1148,52 +1227,58 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
}
/** Fade out this TunableTvView. Fade out by increasing the dimming. */
- public void fadeOut(int durationMillis, TimeInterpolator interpolator,
- final Runnable actionAfterFade) {
+ public void fadeOut(
+ int durationMillis, TimeInterpolator interpolator, final Runnable actionAfterFade) {
mDimScreenView.setAlpha(0f);
mDimScreenView.setVisibility(View.VISIBLE);
- mDimScreenView.animate()
+ mDimScreenView
+ .animate()
.alpha(1f)
.setDuration(durationMillis)
.setInterpolator(interpolator)
- .withStartAction(new Runnable() {
- @Override
- public void run() {
- mFadeState = FADING_OUT;
- mActionAfterFade = actionAfterFade;
- }
- })
- .withEndAction(new Runnable() {
- @Override
- public void run() {
- mFadeState = FADED_OUT;
- }
- });
+ .withStartAction(
+ new Runnable() {
+ @Override
+ public void run() {
+ mFadeState = FADING_OUT;
+ mActionAfterFade = actionAfterFade;
+ }
+ })
+ .withEndAction(
+ new Runnable() {
+ @Override
+ public void run() {
+ mFadeState = FADED_OUT;
+ }
+ });
}
/** Fade in this TunableTvView. Fade in by decreasing the dimming. */
- public void fadeIn(int durationMillis, TimeInterpolator interpolator,
- final Runnable actionAfterFade) {
+ public void fadeIn(
+ int durationMillis, TimeInterpolator interpolator, final Runnable actionAfterFade) {
mDimScreenView.setAlpha(1f);
mDimScreenView.setVisibility(View.VISIBLE);
- mDimScreenView.animate()
+ mDimScreenView
+ .animate()
.alpha(0f)
.setDuration(durationMillis)
.setInterpolator(interpolator)
- .withStartAction(new Runnable() {
- @Override
- public void run() {
- mFadeState = FADING_IN;
- mActionAfterFade = actionAfterFade;
- }
- })
- .withEndAction(new Runnable() {
- @Override
- public void run() {
- mFadeState = FADED_IN;
- mDimScreenView.setVisibility(View.GONE);
- }
- });
+ .withStartAction(
+ new Runnable() {
+ @Override
+ public void run() {
+ mFadeState = FADING_IN;
+ mActionAfterFade = actionAfterFade;
+ }
+ })
+ .withEndAction(
+ new Runnable() {
+ @Override
+ public void run() {
+ mFadeState = FADED_IN;
+ mDimScreenView.setVisibility(View.GONE);
+ }
+ });
}
/** Remove the fade effect. */
@@ -1208,6 +1293,7 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
*
* @param listener The instance of {@link TimeShiftListener}.
*/
+ @Override
public void setTimeShiftListener(TimeShiftListener listener) {
mTimeShiftListener = listener;
}
@@ -1218,20 +1304,22 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
}
mTimeShiftAvailable = isTimeShiftAvailable;
if (isTimeShiftAvailable) {
- mTvView.setTimeShiftPositionCallback(new TvView.TimeShiftPositionCallback() {
- @Override
- public void onTimeShiftStartPositionChanged(String inputId, long timeMs) {
- if (mTimeShiftListener != null && mCurrentChannel != null
- && mCurrentChannel.getInputId().equals(inputId)) {
- mTimeShiftListener.onRecordStartTimeChanged(timeMs);
- }
- }
+ mTvView.setTimeShiftPositionCallback(
+ new TvView.TimeShiftPositionCallback() {
+ @Override
+ public void onTimeShiftStartPositionChanged(String inputId, long timeMs) {
+ if (mTimeShiftListener != null
+ && mCurrentChannel != null
+ && mCurrentChannel.getInputId().equals(inputId)) {
+ mTimeShiftListener.onRecordStartTimeChanged(timeMs);
+ }
+ }
- @Override
- public void onTimeShiftCurrentPositionChanged(String inputId, long timeMs) {
- mTimeShiftCurrentPositionMs = timeMs;
- }
- });
+ @Override
+ public void onTimeShiftCurrentPositionChanged(String inputId, long timeMs) {
+ mTimeShiftCurrentPositionMs = timeMs;
+ }
+ });
} else {
mTvView.setTimeShiftPositionCallback(null);
}
@@ -1240,16 +1328,14 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
}
}
- /**
- * Returns if the time shift is available for the current channel.
- */
+ /** Returns if the time shift is available for the current channel. */
+ @Override
public boolean isTimeShiftAvailable() {
return mTimeShiftAvailable;
}
- /**
- * Plays the media, if the current input supports time-shifting.
- */
+ /** Plays the media, if the current input supports time-shifting. */
+ @Override
public void timeshiftPlay() {
if (!isTimeShiftAvailable()) {
throw new IllegalStateException("Time-shift is not supported for the current channel");
@@ -1260,9 +1346,8 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
mTvView.timeShiftResume();
}
- /**
- * Pauses the media, if the current input supports time-shifting.
- */
+ /** Pauses the media, if the current input supports time-shifting. */
+ @Override
public void timeshiftPause() {
if (!isTimeShiftAvailable()) {
throw new IllegalStateException("Time-shift is not supported for the current channel");
@@ -1278,6 +1363,7 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
*
* @param speed The speed to rewind the media. e.g. 2 for 2x, 3 for 3x and 4 for 4x.
*/
+ @Override
public void timeshiftRewind(int speed) {
if (!isTimeShiftAvailable()) {
throw new IllegalStateException("Time-shift is not supported for the current channel");
@@ -1297,6 +1383,7 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
*
* @param speed The speed to forward the media. e.g. 2 for 2x, 3 for 3x and 4 for 4x.
*/
+ @Override
public void timeshiftFastForward(int speed) {
if (!isTimeShiftAvailable()) {
throw new IllegalStateException("Time-shift is not supported for the current channel");
@@ -1316,6 +1403,7 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
*
* @param timeMs The time in milliseconds to seek to.
*/
+ @Override
public void timeshiftSeekTo(long timeMs) {
if (!isTimeShiftAvailable()) {
throw new IllegalStateException("Time-shift is not supported for the current channel");
@@ -1323,16 +1411,17 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
mTvView.timeShiftSeekTo(timeMs);
}
- /**
- * Returns the current playback position in milliseconds.
- */
+ /** Returns the current playback position in milliseconds. */
+ @Override
public long timeshiftGetCurrentPositionMs() {
if (!isTimeShiftAvailable()) {
throw new IllegalStateException("Time-shift is not supported for the current channel");
}
if (DEBUG) {
- Log.d(TAG, "timeshiftGetCurrentPositionMs: current position ="
- + Utils.toTimeString(mTimeShiftCurrentPositionMs));
+ Log.d(
+ TAG,
+ "timeshiftGetCurrentPositionMs: current position ="
+ + Utils.toTimeString(mTimeShiftCurrentPositionMs));
}
return mTimeShiftCurrentPositionMs;
}
@@ -1342,43 +1431,30 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
return new ImageLoader.ImageLoaderCallback<BlockScreenView>(mBlockScreenView) {
@Override
public void onBitmapLoaded(BlockScreenView view, @Nullable Bitmap posterArt) {
- if (posterArt == null || getCurrentChannel() == null
+ if (posterArt == null
+ || getCurrentChannel() == null
|| channelId != getCurrentChannel().getId()
|| !shouldShowImageForTuning()) {
return;
}
Drawable drawablePosterArt = new BitmapDrawable(view.getResources(), posterArt);
- drawablePosterArt.mutate().setColorFilter(
- mTuningImageColorFilter, PorterDuff.Mode.SRC_OVER);
+ drawablePosterArt
+ .mutate()
+ .setColorFilter(mTuningImageColorFilter, PorterDuff.Mode.SRC_OVER);
view.setBackgroundImage(drawablePosterArt);
}
};
}
- /**
- * Used to receive the time-shift events.
- */
- public static abstract class TimeShiftListener {
- /**
- * Called when the availability of the time-shift for the current channel has been changed.
- * It should be guaranteed that this is called only when the availability is really changed.
- */
- public abstract void onAvailabilityChanged();
+ /** Listens for dpad actions that are otherwise trapped by talkback */
+ public interface OnTalkBackDpadKeyListener {
- /**
- * Called when the record start time has been changed.
- * This is not called when the recorded programs is played.
- */
- public abstract void onRecordStartTimeChanged(long recordStartTimeMs);
+ void onTalkBackDpadKey(int keycode);
}
- /**
- * A listener which receives the notification when the screen is blocked/unblocked.
- */
- public static abstract class OnScreenBlockingChangedListener {
- /**
- * Called when the screen is blocked/unblocked.
- */
+ /** A listener which receives the notification when the screen is blocked/unblocked. */
+ public abstract static class OnScreenBlockingChangedListener {
+ /** Called when the screen is blocked/unblocked. */
public abstract void onScreenBlockingChanged(boolean blocked);
}
@@ -1391,8 +1467,10 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
@Override
protected void onPostExecute(Boolean networkAvailable) {
mInternetCheckTask = null;
- if (!networkAvailable && isAttachedToWindow()
- && !mScreenBlocked && mBlockedContentRating == null
+ if (!networkAvailable
+ && isAttachedToWindow()
+ && !mScreenBlocked
+ && mBlockedContentRating == null
&& mVideoUnavailableReason == TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN) {
mBlockScreenView.setIconVisibility(true);
mBlockScreenView.setIconImage(R.drawable.ic_sad_cloud);