aboutsummaryrefslogtreecommitdiff
path: root/src/com/android
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android')
-rw-r--r--src/com/android/tv/TvActivity.java24
-rw-r--r--src/com/android/tv/notification/NotificationService.java33
-rw-r--r--src/com/android/tv/ui/TunableTvView.java46
-rw-r--r--src/com/android/tv/util/TvInputManagerHelper.java7
4 files changed, 65 insertions, 45 deletions
diff --git a/src/com/android/tv/TvActivity.java b/src/com/android/tv/TvActivity.java
index b5671bfc..23cb4596 100644
--- a/src/com/android/tv/TvActivity.java
+++ b/src/com/android/tv/TvActivity.java
@@ -126,10 +126,13 @@ public class TvActivity extends Activity implements AudioManager.OnAudioFocusCha
private static final int REQUEST_START_SETUP_ACTIIVTY = 0;
private static final int REQUEST_START_SETTINGS_ACTIIVTY = 1;
+ private static final String KEY_INIT_CHANNEL_ID = "com.android.tv.init_channel_id";
+
private static final HashSet<String> AVAILABLE_DIALOG_TAGS = new HashSet<String>();
private View mContentView;
private TunableTvView mTvView;
+ private Bundle mTuneParams;
private LinearLayout mControlGuide;
private MainMenuView mMainMenuView;
private ChannelBannerView mChannelBanner;
@@ -344,6 +347,11 @@ public class TvActivity extends Activity implements AudioManager.OnAudioFocusCha
if (Intent.ACTION_VIEW.equals(intent.getAction())) {
// In case the channel is given explicitly, use it.
mInitChannelId = ContentUris.parseId(intent.getData());
+ mTuneParams = intent.getExtras();
+ if (mTuneParams == null) {
+ mTuneParams = new Bundle();
+ }
+ mTuneParams.putLong(KEY_INIT_CHANNEL_ID, mInitChannelId);
} else {
mInitChannelId = Channel.INVALID_ID;
}
@@ -428,6 +436,7 @@ public class TvActivity extends Activity implements AudioManager.OnAudioFocusCha
if (TextUtils.isEmpty(inputId)) {
// If the channel is invalid, try to use the last selected physical tv input.
inputId = Utils.getLastSelectedPhysInputId(this);
+ channelId = Channel.INVALID_ID;
if (TextUtils.isEmpty(inputId)) {
// If failed to determine the input for that channel, try a different input.
showInputPicker(BaseSideFragment.INITIATOR_UNKNOWN);
@@ -838,7 +847,7 @@ public class TvActivity extends Activity implements AudioManager.OnAudioFocusCha
}
if (DEBUG) Log.d(TAG, "startPip()");
mPipView.start(mTvInputManagerHelper);
- boolean success = mPipView.tuneTo(mPipChannelId, new OnTuneListener() {
+ boolean success = mPipView.tuneTo(mPipChannelId, null, new OnTuneListener() {
@Override
public void onUnexpectedStop(long channelId) {
Log.w(TAG, "The PIP is Unexpectedly stopped");
@@ -888,7 +897,7 @@ public class TvActivity extends Activity implements AudioManager.OnAudioFocusCha
}
mChannelNumberView.setChannels(
- (mChannelMap == null) ? null : mChannelMap.getChannelList(false));
+ (mChannelMap == null) ? null : mChannelMap.getChannelList(true));
mMainMenuView.setChannelMap(mChannelMap);
}
};
@@ -910,7 +919,14 @@ public class TvActivity extends Activity implements AudioManager.OnAudioFocusCha
return;
}
- mTvView.tuneTo(channelId, new OnTuneListener() {
+ if (mTuneParams != null) {
+ if (channelId == mTuneParams.getLong(KEY_INIT_CHANNEL_ID)) {
+ mTuneParams.remove(KEY_INIT_CHANNEL_ID);
+ } else {
+ mTuneParams = null;
+ }
+ }
+ mTvView.tuneTo(channelId, mTuneParams, new OnTuneListener() {
@Override
public void onUnexpectedStop(long channelId) {
stopTv();
@@ -939,6 +955,7 @@ public class TvActivity extends Activity implements AudioManager.OnAudioFocusCha
// TODO: update {@code mChannelMap} and the banner.
}
});
+ mTuneParams = null;
updateChannelBanner(true);
if (mChildActivityCanceled) {
displayMainMenu(false);
@@ -1064,6 +1081,7 @@ public class TvActivity extends Activity implements AudioManager.OnAudioFocusCha
protected void onDestroy() {
if (DEBUG) Log.d(TAG, "onDestroy()");
mTvInputManagerHelper.stop();
+
super.onDestroy();
}
diff --git a/src/com/android/tv/notification/NotificationService.java b/src/com/android/tv/notification/NotificationService.java
index 01998065..5b2a77c8 100644
--- a/src/com/android/tv/notification/NotificationService.java
+++ b/src/com/android/tv/notification/NotificationService.java
@@ -32,6 +32,7 @@ import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.net.Uri;
+import android.media.tv.TvContract;
import android.media.tv.TvInputInfo;
import android.media.tv.TvInputManager;
import android.os.Handler;
@@ -44,6 +45,7 @@ import android.util.Log;
import com.android.tv.R;
import com.android.tv.data.Program;
import com.android.tv.recommendation.RandomRecommender;
+import com.android.tv.recommendation.RoutineWatchRecommender;
import com.android.tv.recommendation.TvRecommendation;
import com.android.tv.recommendation.TvRecommendation.ChannelRecord;
import com.android.tv.util.TvInputManagerHelper;
@@ -60,7 +62,7 @@ import java.net.URL;
* A local service for notify recommendation at home launcher.
*/
public class NotificationService extends Service {
- private static final boolean DEBUG = false;
+ private static final boolean DEBUG = true;
private static final String TAG = "NotificationService";
public static final String ACTION_SHOW_RECOMMENDATION =
@@ -68,6 +70,11 @@ public class NotificationService extends Service {
public static final String ACTION_HIDE_RECOMMENDATION =
"com.android.tv.notification.ACTION_HIDE_RECOMMENDATION";
+ private static final String TUNE_PARAMS_RECOMMENDATION_TYPE =
+ "com.android.tv.recommendation_type";
+ private static final String TYPE_RANDOM_RECOMMENDATION = "random";
+ private static final String TYPE_ROUTINE_WATCH_RECOMMENDATION = "routine_watch";
+
private static final String NOTIFY_TAG = "tv_recommendation";
// TODO: find out proper number of notifications and whether to make it dynamically
// configurable from system property or etc.
@@ -88,6 +95,7 @@ public class NotificationService extends Service {
private NotificationManager mNotificationManager;
private final HandlerThread mHandlerThread;
private final Handler mHandler;
+ private final String mRecommendationType;
private float mNotificationCardMaxWidth;
private float mNotificationCardHeight;
@@ -124,6 +132,7 @@ public class NotificationService extends Service {
}
}
};
+ mRecommendationType = TYPE_RANDOM_RECOMMENDATION;
}
@Override
@@ -136,9 +145,15 @@ public class NotificationService extends Service {
R.dimen.notif_card_img_height);
mTvRecommendation = new TvRecommendation(this, mHandler, true);
- mTvRecommendation.registerTvRecommender(new RandomRecommender());
- mNotificationManager = (NotificationManager) getSystemService(
- Context.NOTIFICATION_SERVICE);
+ if (TYPE_RANDOM_RECOMMENDATION.equals(mRecommendationType)) {
+ mTvRecommendation.registerTvRecommender(new RandomRecommender());
+ } else if (TYPE_ROUTINE_WATCH_RECOMMENDATION.equals(mRecommendationType)) {
+ mTvRecommendation.registerTvRecommender(new RoutineWatchRecommender(this));
+ } else {
+ throw new IllegalStateException("Undefined recommendation type: "
+ + mRecommendationType);
+ }
+ mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mTvInputManager = (TvInputManager) getSystemService(Context.TV_INPUT_SERVICE);
mTvInputManagerHelper = new TvInputManagerHelper(mTvInputManager);
mTvInputManagerHelper.start();
@@ -152,11 +167,11 @@ public class NotificationService extends Service {
if (ACTION_SHOW_RECOMMENDATION.equals(action)) {
mHandler.removeMessages(MSG_SHOW_RECOMMENDATION);
mHandler.removeMessages(MSG_HIDE_RECOMMENDATION);
- mHandler.obtainMessage(MSG_SHOW_RECOMMENDATION).sendToTarget();;
+ mHandler.obtainMessage(MSG_SHOW_RECOMMENDATION).sendToTarget();
} else if (ACTION_HIDE_RECOMMENDATION.equals(action)) {
mHandler.removeMessages(MSG_SHOW_RECOMMENDATION);
mHandler.removeMessages(MSG_HIDE_RECOMMENDATION);
- mHandler.obtainMessage(MSG_HIDE_RECOMMENDATION).sendToTarget();;
+ mHandler.obtainMessage(MSG_HIDE_RECOMMENDATION).sendToTarget();
}
}
return START_STICKY;
@@ -196,6 +211,7 @@ public class NotificationService extends Service {
if (DEBUG) Log.d(TAG, "sendNotification (" + cr.getChannel().getDisplayName()
+ " notifyId=" + notifyId + ")");
Intent intent = new Intent(Intent.ACTION_VIEW, cr.getChannelUri());
+ intent.putExtra(TUNE_PARAMS_RECOMMENDATION_TYPE, mRecommendationType);
PendingIntent notificationIntent = PendingIntent.getActivity(this, 0, intent, 0);
// TODO: Move some checking logic into TvRecommendation.
@@ -216,7 +232,8 @@ public class NotificationService extends Service {
}
long programDurationMs = program.getEndTimeUtcMillis() - program.getStartTimeUtcMillis();
long programLeftTimsMs = program.getEndTimeUtcMillis() - System.currentTimeMillis();
- int programProgress = 100 - (int) (programLeftTimsMs * 100 / programDurationMs);
+ int programProgress = (programDurationMs <= 0) ? -1
+ : 100 - (int) (programLeftTimsMs * 100 / programDurationMs);
// We doesn't trust TIS to provide us with proper sized image
Bitmap posterArtBitmap = BitmapUtils.decodeSampledBitmapFromUriString(this,
@@ -239,7 +256,7 @@ public class NotificationService extends Service {
.setLargeIcon(largeIconBitmap)
.setSmallIcon(R.drawable.ic_launcher_s)
.setCategory(Notification.CATEGORY_RECOMMENDATION)
- .setProgress(100, programProgress, false)
+ .setProgress((programProgress > 0) ? 100 : 0, programProgress, false)
.build();
notification.color =
getResources().getColor(R.color.recommendation_card_background);
diff --git a/src/com/android/tv/ui/TunableTvView.java b/src/com/android/tv/ui/TunableTvView.java
index 90e73122..b0db3a1d 100644
--- a/src/com/android/tv/ui/TunableTvView.java
+++ b/src/com/android/tv/ui/TunableTvView.java
@@ -9,11 +9,11 @@ import android.media.tv.TvView;
import android.media.tv.TvView.OnUnhandledInputEventListener;
import android.media.tv.TvView.TvInputListener;
import android.net.Uri;
+import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
-import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.ViewGroup;
import android.widget.FrameLayout;
@@ -24,14 +24,15 @@ import com.android.tv.data.StreamInfo;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
public class TunableTvView extends FrameLayout implements StreamInfo {
// STOPSHIP: Turn debugging off
private static final boolean DEBUG = true;
private static final String TAG = "TunableTvView";
- private static final int DELAY_FOR_SURFACE_RELEASE = 300;
public static final String PERMISSION_RECEIVE_INPUT_EVENT =
"android.permission.RECEIVE_INPUT_EVENT";
@@ -52,27 +53,7 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
private boolean mCanReceiveInputEvent;
private boolean mIsMuted;
private float mVolume;
-
- private final SurfaceHolder.Callback mSurfaceHolderCallback = new SurfaceHolder.Callback() {
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { }
-
- @Override
- public void surfaceCreated(SurfaceHolder holder) { }
-
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- // 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 {
- if (DEBUG) Log.d(TAG, "Sleep to wait destroying a surface");
- Thread.sleep(DELAY_FOR_SURFACE_RELEASE);
- if (DEBUG) Log.d(TAG, "Wake up from sleeping");
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- };
+ private final Map<Long, String> mChannelToInputMap = new HashMap<Long, String>();
private final TvInputListener mListener =
new TvInputListener() {
@@ -205,7 +186,7 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
return mStarted;
}
- public boolean tuneTo(long channelId, OnTuneListener listener) {
+ public boolean tuneTo(long channelId, Bundle params, OnTuneListener listener) {
if (!mStarted) {
throw new IllegalStateException("TvView isn't started");
}
@@ -215,7 +196,12 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
mVideoFormat = StreamInfo.VIDEO_DEFINITION_LEVEL_UNKNOWN;
mAudioChannelCount = StreamInfo.AUDIO_CHANNEL_COUNT_UNKNOWN;
mHasClosedCaption = false;
- String inputId = Utils.getInputIdForChannel(getContext(), channelId);
+ String inputId = null;
+ inputId = mChannelToInputMap.get(channelId);
+ if (inputId == null) {
+ inputId = Utils.getInputIdForChannel(getContext(), channelId);
+ mChannelToInputMap.put(channelId, inputId);
+ }
TvInputInfo inputInfo = mInputManagerHelper.getTvInputInfo(inputId);
if (inputInfo == null
|| mInputManagerHelper.getInputState(inputInfo) ==
@@ -226,20 +212,13 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
mChannelId = channelId;
if (!inputInfo.equals(mInputInfo)) {
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 {
- Thread.sleep(DELAY_FOR_SURFACE_RELEASE);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
mInputInfo = inputInfo;
mCanReceiveInputEvent = getContext().getPackageManager().checkPermission(
PERMISSION_RECEIVE_INPUT_EVENT, mInputInfo.getComponent().getPackageName())
== PackageManager.PERMISSION_GRANTED;
}
mTvView.setTvInputListener(mListener);
- mTvView.tune(mInputInfo.getId(), Utils.getChannelUri(mChannelId));
+ mTvView.tune(mInputInfo.getId(), Utils.getChannelUri(mChannelId), params);
if (mOnTuneListener != null) {
// TODO: Add a callback for tune complete and call onTuned when it was successful.
mOnTuneListener.onTuned(true, mChannelId);
@@ -384,7 +363,6 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
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;
}
}
diff --git a/src/com/android/tv/util/TvInputManagerHelper.java b/src/com/android/tv/util/TvInputManagerHelper.java
index 6e152970..6ce7a42c 100644
--- a/src/com/android/tv/util/TvInputManagerHelper.java
+++ b/src/com/android/tv/util/TvInputManagerHelper.java
@@ -19,6 +19,7 @@ package com.android.tv.util;
import android.media.tv.TvInputInfo;
import android.media.tv.TvInputManager;
import android.media.tv.TvInputManager.TvInputListener;
+import android.net.Uri;
import android.os.Handler;
import android.util.Log;
@@ -54,6 +55,7 @@ public class TvInputManagerHelper {
private final Handler mHandler = new Handler();
private boolean mStarted;
private final HashSet<TvInputListener> mListeners = new HashSet<TvInputListener>();
+ private List<Uri> mTvContentRatingSystemXmls;
public TvInputManagerHelper(TvInputManager tvInputManager) {
mTvInputManager = tvInputManager;
@@ -87,6 +89,7 @@ public class TvInputManagerHelper {
mInputStateMap.put(inputId, state);
}
Assert.assertEquals(mInputStateMap.size(), mInputMap.size());
+ mTvContentRatingSystemXmls = mTvInputManager.getTvContentRatingSystemXmls();
}
public void stop() {
@@ -155,6 +158,10 @@ public class TvInputManagerHelper {
return state;
}
+ public List<Uri> getTvContentRatingSystemXmls() {
+ return mTvContentRatingSystemXmls;
+ }
+
public void addListener(TvInputListener listener) {
mListeners.add(listener);
}