aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristofer Ã…kersten <akersten@google.com>2014-07-23 17:58:11 +0900
committerChristofer Ã…kersten <akersten@google.com>2014-07-28 20:18:09 +0900
commitd82ca62a0fefaed41493540df7d622cfcfb2cb6c (patch)
tree42f5ab29f99f0d6d105b82ce6c1ec2365c1f7cc4 /src
parent903b8cf0ae7dc7f8b037311ab28615b0a212a31d (diff)
downloadTV-d82ca62a0fefaed41493540df7d622cfcfb2cb6c.tar.gz
Block screen when onVideoUnavailable is received.
Bug: 16272325 Change-Id: Id3c99312099c71f1899d22579ff2dfc1b684e506
Diffstat (limited to 'src')
-rw-r--r--src/com/android/tv/TvActivity.java13
-rw-r--r--src/com/android/tv/ui/TunableTvView.java128
2 files changed, 109 insertions, 32 deletions
diff --git a/src/com/android/tv/TvActivity.java b/src/com/android/tv/TvActivity.java
index 04d13da8..a27942b4 100644
--- a/src/com/android/tv/TvActivity.java
+++ b/src/com/android/tv/TvActivity.java
@@ -32,6 +32,7 @@ import android.media.AudioManager;
import android.media.tv.TvInputInfo;
import android.media.tv.TvInputManager;
import android.media.tv.TvTrackInfo;
+import android.media.tv.TvView.OnUnhandledInputEventListener;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -189,8 +190,8 @@ public class TvActivity extends Activity implements AudioManager.OnAudioFocusCha
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tv);
- mTvView = (TunableTvView) findViewById(R.id.tv_view);
- mTvView.setOnUnhandledInputEventListener(new TunableTvView.OnUnhandledInputEventListener() {
+ mTvView = (TunableTvView) findViewById(R.id.main_tv_view);
+ mTvView.setOnUnhandledInputEventListener(new OnUnhandledInputEventListener() {
@Override
public boolean onUnhandledInputEvent(InputEvent event) {
if (event instanceof KeyEvent) {
@@ -214,7 +215,7 @@ public class TvActivity extends Activity implements AudioManager.OnAudioFocusCha
return false;
}
});
- mPipView = (TunableTvView) findViewById(R.id.pip_view);
+ mPipView = (TunableTvView) findViewById(R.id.pip_tv_view);
mPipView.setPip(true);
mControlGuide = (LinearLayout) findViewById(R.id.control_guide);
@@ -240,7 +241,7 @@ public class TvActivity extends Activity implements AudioManager.OnAudioFocusCha
@Override
public void run() {
if (mPipEnabled) {
- mPipView.setVisibility(View.INVISIBLE);
+ mPipView.setVisibility(View.GONE);
}
}
},
@@ -385,7 +386,7 @@ public class TvActivity extends Activity implements AudioManager.OnAudioFocusCha
protected void onPause() {
hideOverlays(true, true, true);
if (mPipEnabled) {
- mPipView.setVisibility(View.INVISIBLE);
+ mPipView.setVisibility(View.GONE);
}
mActivityResumed = false;
super.onPause();
@@ -864,7 +865,7 @@ public class TvActivity extends Activity implements AudioManager.OnAudioFocusCha
private void stopPip() {
if (DEBUG) Log.d(TAG, "stopPip");
if (mPipView.isPlaying()) {
- mPipView.setVisibility(View.INVISIBLE);
+ mPipView.setVisibility(View.GONE);
mPipView.stop();
}
}
diff --git a/src/com/android/tv/ui/TunableTvView.java b/src/com/android/tv/ui/TunableTvView.java
index 6ff38626..09c23435 100644
--- a/src/com/android/tv/ui/TunableTvView.java
+++ b/src/com/android/tv/ui/TunableTvView.java
@@ -6,6 +6,8 @@ import android.media.tv.TvInputInfo;
import android.media.tv.TvInputManager;
import android.media.tv.TvTrackInfo;
import android.media.tv.TvView;
+import android.media.tv.TvView.OnUnhandledInputEventListener;
+import android.media.tv.TvView.TvInputListener;
import android.net.Uri;
import android.util.AttributeSet;
import android.util.Log;
@@ -13,6 +15,8 @@ import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
import com.android.tv.R;
import com.android.tv.data.Channel;
@@ -22,7 +26,8 @@ import com.android.tv.util.Utils;
import java.util.List;
-public class TunableTvView extends TvView implements StreamInfo {
+public class TunableTvView extends FrameLayout implements StreamInfo {
+ // STOPSHIP: Turn debugging off
private static final boolean DEBUG = true;
private static final String TAG = "TunableTvView";
@@ -30,6 +35,8 @@ public class TunableTvView extends TvView implements StreamInfo {
public static final String PERMISSION_RECEIVE_INPUT_EVENT =
"android.permission.RECEIVE_INPUT_EVENT";
+ private final TvView mTvView;
+ private final SurfaceView mSurfaceView;
private long mChannelId = Channel.INVALID_ID;
private TvInputManagerHelper mInputManagerHelper;
private boolean mStarted;
@@ -42,8 +49,9 @@ public class TunableTvView extends TvView implements StreamInfo {
private boolean mHasClosedCaption = false;
private boolean mIsVideoAvailable;
private int mVideoUnavailableReason;
- private SurfaceView mSurface;
private boolean mCanReceiveInputEvent;
+ private boolean mIsMuted;
+ private float mVolume;
private final SurfaceHolder.Callback mSurfaceHolderCallback = new SurfaceHolder.Callback() {
@Override
@@ -129,6 +137,7 @@ public class TunableTvView extends TvView implements StreamInfo {
@Override
public void onVideoAvailable(String inputId) {
mIsVideoAvailable = true;
+ unblock();
if (mOnTuneListener != null) {
mOnTuneListener.onStreamInfoChanged(TunableTvView.this);
}
@@ -138,6 +147,7 @@ public class TunableTvView extends TvView implements StreamInfo {
public void onVideoUnavailable(String inputId, int reason) {
mIsVideoAvailable = false;
mVideoUnavailableReason = reason;
+ block(reason);
if (mOnTuneListener != null) {
mOnTuneListener.onStreamInfoChanged(TunableTvView.this);
}
@@ -145,7 +155,7 @@ public class TunableTvView extends TvView implements StreamInfo {
};
public TunableTvView(Context context) {
- this(context, null, 0);
+ this(context, null);
}
public TunableTvView(Context context, AttributeSet attrs) {
@@ -153,15 +163,15 @@ public class TunableTvView extends TvView implements StreamInfo {
}
public TunableTvView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- for (int i = 0; i < getChildCount(); ++i) {
- if (getChildAt(i) instanceof SurfaceView) {
- mSurface = (SurfaceView) getChildAt(i);
- mSurface.getHolder().addCallback(mSurfaceHolderCallback);
- return;
- }
- }
- throw new RuntimeException("TvView does not have SurfaceView.");
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public TunableTvView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ inflate(getContext(), R.layout.tunable_tv_view, this);
+
+ mTvView = (TvView) findViewById(R.id.tv_view);
+ mSurfaceView = findSurfaceView(mTvView);
}
public void start(TvInputManagerHelper tvInputManagerHelper) {
@@ -177,7 +187,7 @@ public class TunableTvView extends TvView implements StreamInfo {
return;
}
mStarted = false;
- reset();
+ mTvView.reset();
mChannelId = Channel.INVALID_ID;
mInputInfo = null;
mCanReceiveInputEvent = false;
@@ -208,7 +218,7 @@ public class TunableTvView extends TvView implements StreamInfo {
mOnTuneListener = listener;
mChannelId = channelId;
if (!inputInfo.equals(mInputInfo)) {
- reset();
+ mTvView.reset();
// TODO: It is a hack to wait to release a surface at TIS. If there is a way to
// know when the surface is released at TIS, we don't need this hack.
try {
@@ -217,12 +227,12 @@ public class TunableTvView extends TvView implements StreamInfo {
e.printStackTrace();
}
mInputInfo = inputInfo;
- mCanReceiveInputEvent = mContext.getPackageManager().checkPermission(
+ mCanReceiveInputEvent = getContext().getPackageManager().checkPermission(
PERMISSION_RECEIVE_INPUT_EVENT, mInputInfo.getComponent().getPackageName())
== PackageManager.PERMISSION_GRANTED;
}
- setTvInputListener(mListener);
- tune(mInputInfo.getId(), Utils.getChannelUri(mChannelId));
+ mTvView.setTvInputListener(mListener);
+ mTvView.tune(mInputInfo.getId(), Utils.getChannelUri(mChannelId));
if (mOnTuneListener != null) {
// TODO: Add a callback for tune complete and call onTuned when it was successful.
mOnTuneListener.onTuned(true, mChannelId);
@@ -240,37 +250,38 @@ public class TunableTvView extends TvView implements StreamInfo {
}
public void setPip(boolean isPip) {
- mSurface.setZOrderMediaOverlay(isPip);
+ mSurfaceView.setZOrderMediaOverlay(isPip);
}
- @Override
public void setStreamVolume(float volume) {
if (!mStarted) {
throw new IllegalStateException("TvView isn't started");
}
- if (DEBUG)
- Log.d(TAG, "setStreamVolume " + volume);
- super.setStreamVolume(volume);
+ if (DEBUG) Log.d(TAG, "setStreamVolume " + volume);
+ mVolume = volume;
+ if (!mIsMuted) {
+ mTvView.setStreamVolume(volume);
+ }
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
- return mCanReceiveInputEvent && super.dispatchKeyEvent(event);
+ return mCanReceiveInputEvent && mTvView.dispatchKeyEvent(event);
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
- return mCanReceiveInputEvent && super.dispatchTouchEvent(event);
+ return mCanReceiveInputEvent && mTvView.dispatchTouchEvent(event);
}
@Override
public boolean dispatchTrackballEvent(MotionEvent event) {
- return mCanReceiveInputEvent && super.dispatchTrackballEvent(event);
+ return mCanReceiveInputEvent && mTvView.dispatchTrackballEvent(event);
}
@Override
public boolean dispatchGenericMotionEvent(MotionEvent event) {
- return mCanReceiveInputEvent && super.dispatchGenericMotionEvent(event);
+ return mCanReceiveInputEvent && mTvView.dispatchGenericMotionEvent(event);
}
public interface OnTuneListener {
@@ -314,4 +325,69 @@ public class TunableTvView extends TvView implements StreamInfo {
public int getVideoUnavailableReason() {
return mVideoUnavailableReason;
}
+
+ public void setOnUnhandledInputEventListener(OnUnhandledInputEventListener listener) {
+ mTvView.setOnUnhandledInputEventListener(listener);
+ }
+
+ public List<TvTrackInfo> getTracks() {
+ return mTvView.getTracks();
+ }
+
+ public void selectTrack(TvTrackInfo track) {
+ mTvView.selectTrack(track);
+ }
+
+ private void block(int reason) {
+ hideBlock();
+ switch (reason) {
+ case TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN:
+ default:
+ findViewById(R.id.block_reason_unknown).setVisibility(VISIBLE);
+ break;
+ case TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNE:
+ findViewById(R.id.block_reason_tune).setVisibility(VISIBLE);
+ break;
+ case TvInputManager.VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL:
+ findViewById(R.id.block_reason_weak_signal).setVisibility(VISIBLE);
+ break;
+ case TvInputManager.VIDEO_UNAVAILABLE_REASON_BUFFERING:
+ findViewById(R.id.block_reason_buffering).setVisibility(VISIBLE);
+ break;
+ }
+ mute();
+ }
+
+ private void unblock() {
+ hideBlock();
+ unmute();
+ }
+
+ private void mute() {
+ mIsMuted = true;
+ mTvView.setStreamVolume(0);
+ }
+
+ private void unmute() {
+ mIsMuted = false;
+ mTvView.setStreamVolume(mVolume);
+ }
+
+ private SurfaceView findSurfaceView(ViewGroup view) {
+ for (int i = 0; i < view.getChildCount(); ++i) {
+ if (view.getChildAt(i) instanceof SurfaceView) {
+ SurfaceView surfaceView = (SurfaceView) mTvView.getChildAt(i);
+ surfaceView.getHolder().addCallback(mSurfaceHolderCallback);
+ return surfaceView;
+ }
+ }
+ throw new RuntimeException("TvView does not have SurfaceView.");
+ }
+
+ private void hideBlock() {
+ findViewById(R.id.block_reason_unknown).setVisibility(GONE);
+ findViewById(R.id.block_reason_tune).setVisibility(GONE);
+ findViewById(R.id.block_reason_weak_signal).setVisibility(GONE);
+ findViewById(R.id.block_reason_buffering).setVisibility(GONE);
+ }
}