summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Sungsoo Lim <sungsoo@google.com> 2014-07-09 10:40:43 +0900
committer Sungsoo Lim <sungsoo@google.com> 2014-08-01 15:33:32 +0900
commit1a6b25eabcc1fb66e6e8d76f91fd413e18b793a9 (patch)
treea502dc681d7b123a67bbe1af2058396f4d8fa08a
parentf96d229603b97302c7e3224d167da5b67fae3cf1 (diff)
TIF: Add a parameter (Bundle params) of tune method
- tune(Uri, Bundle) is added as a system API. Bug: 15809017 Change-Id: I50bc9b510f469ac3c157f095ccfe27d1cd1d9854
-rw-r--r--media/java/android/media/tv/ITvInputManager.aidl2
-rw-r--r--media/java/android/media/tv/ITvInputSession.aidl2
-rw-r--r--media/java/android/media/tv/ITvInputSessionWrapper.java8
-rw-r--r--media/java/android/media/tv/TvContract.java26
-rw-r--r--media/java/android/media/tv/TvInputManager.java15
-rw-r--r--media/java/android/media/tv/TvInputService.java17
-rw-r--r--media/java/android/media/tv/TvView.java26
-rw-r--r--services/core/java/com/android/server/tv/TvInputManagerService.java43
8 files changed, 116 insertions, 23 deletions
diff --git a/media/java/android/media/tv/ITvInputManager.aidl b/media/java/android/media/tv/ITvInputManager.aidl
index 41c4f07186f2..1939c5635385 100644
--- a/media/java/android/media/tv/ITvInputManager.aidl
+++ b/media/java/android/media/tv/ITvInputManager.aidl
@@ -56,7 +56,7 @@ interface ITvInputManager {
void dispatchSurfaceChanged(in IBinder sessionToken, int format, int width, int height,
int userId);
void setVolume(in IBinder sessionToken, float volume, int userId);
- void tune(in IBinder sessionToken, in Uri channelUri, int userId);
+ void tune(in IBinder sessionToken, in Uri channelUri, in Bundle params, int userId);
void setCaptionEnabled(in IBinder sessionToken, boolean enabled, int userId);
void selectTrack(in IBinder sessionToken, in TvTrackInfo track, int userId);
void unselectTrack(in IBinder sessionToken, in TvTrackInfo track, int userId);
diff --git a/media/java/android/media/tv/ITvInputSession.aidl b/media/java/android/media/tv/ITvInputSession.aidl
index df14ad6bb94c..9a0be25da81e 100644
--- a/media/java/android/media/tv/ITvInputSession.aidl
+++ b/media/java/android/media/tv/ITvInputSession.aidl
@@ -35,7 +35,7 @@ oneway interface ITvInputSession {
// TODO: Remove this once it becomes irrelevant for applications to handle audio focus. The plan
// is to introduce some new concepts that will solve a number of problems in audio policy today.
void setVolume(float volume);
- void tune(in Uri channelUri);
+ void tune(in Uri channelUri, in Bundle params);
void setCaptionEnabled(boolean enabled);
void selectTrack(in TvTrackInfo track);
void unselectTrack(in TvTrackInfo track);
diff --git a/media/java/android/media/tv/ITvInputSessionWrapper.java b/media/java/android/media/tv/ITvInputSessionWrapper.java
index 9fb552c82730..a809da9cc11f 100644
--- a/media/java/android/media/tv/ITvInputSessionWrapper.java
+++ b/media/java/android/media/tv/ITvInputSessionWrapper.java
@@ -111,7 +111,9 @@ public class ITvInputSessionWrapper extends ITvInputSession.Stub implements Hand
return;
}
case DO_TUNE: {
- mTvInputSessionImpl.tune((Uri) msg.obj);
+ SomeArgs args = (SomeArgs) msg.obj;
+ mTvInputSessionImpl.tune((Uri) args.arg1, (Bundle) args.arg2);
+ args.recycle();
return;
}
case DO_SET_CAPTION_ENABLED: {
@@ -184,8 +186,8 @@ public class ITvInputSessionWrapper extends ITvInputSession.Stub implements Hand
}
@Override
- public void tune(Uri channelUri) {
- mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_TUNE, channelUri));
+ public void tune(Uri channelUri, Bundle params) {
+ mCaller.executeOrSendMessage(mCaller.obtainMessageOO(DO_TUNE, channelUri, params));
}
@Override
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index 1a4305127421..5a0ea0df0477 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -509,7 +509,7 @@ public final class TvContract {
* The ID of the TV input service that provides this TV channel.
* <p>
* Use {@link #buildInputId} to build the ID.
- * <p>
+ * </p><p>
* This is a required field.
* </p><p>
* Type: TEXT
@@ -662,7 +662,7 @@ public final class TvContract {
* {@link Programs#COLUMN_VIDEO_HEIGHT} to get more accurate video resolution.
* </p><p>
* Type: TEXT
- * </p><p>
+ * </p>
* @see #getVideoResolution
*/
public static final String COLUMN_VIDEO_FORMAT = "video_format";
@@ -688,8 +688,7 @@ public final class TvContract {
* the channel is searchable and can be included in search results, a value of 0 indicates
* the channel and its TV programs are hidden from search. If not specified, this value is
* set to 1 (searchable) by default.
- * </p>
- * <p>
+ * </p><p>
* Type: INTEGER (boolean)
* </p>
*/
@@ -743,14 +742,12 @@ public final class TvContract {
* To access this directory, append {@link Channels.Logo#CONTENT_DIRECTORY} to the raw
* channel URI. The resulting URI represents an image file, and should be interacted
* using ContentResolver.openAssetFileDescriptor.
- * </p>
- * <p>
+ * </p><p>
* Note that this sub-directory also supports opening the logo as an asset file in write
* mode. Callers can create or replace the primary logo associated with this channel by
* opening the asset file and writing the full-size photo contents into it. When the file
* is closed, the image will be parsed, sized down if necessary, and stored.
- * </p>
- * <p>
+ * </p><p>
* Usage example:
* <pre>
* public void writeChannelLogo(long channelId, byte[] logo) {
@@ -1180,6 +1177,19 @@ public final class TvContract {
*/
public static final String COLUMN_DESCRIPTION = "description";
+ /**
+ * Extra parameters of the tune operation.
+ * <p>
+ * This column contains an encoded string which is comma-separated key-value pairs.
+ * (Ex. "[key1]=[value1], [key2]=[value2]"). COLUMN_TUNE_PARAMS will use '%' as an escape
+ * character for the characters of '%', '=', and ','.
+ * </p><p>
+ * Type: TEXT
+ * </p>
+ * @see TvInputManager.Session.tune(Uri, Bundle)
+ */
+ public static final String COLUMN_TUNE_PARAMS = "tune_params";
+
private WatchedPrograms() {}
}
}
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index 49b224048978..7bb353cd65b3 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -1012,6 +1012,19 @@ public final class TvInputManager {
* @throws IllegalArgumentException if the argument is {@code null}.
*/
public void tune(Uri channelUri) {
+ tune(channelUri, null);
+ }
+
+ /**
+ * Tunes to a given channel.
+ *
+ * @param channelUri The URI of a channel.
+ * @param params A set of extra parameters which might be handled with this tune event.
+ * @throws IllegalArgumentException if {@code channelUri} is {@code null}.
+ * @hide
+ */
+ @SystemApi
+ public void tune(Uri channelUri, Bundle params) {
if (channelUri == null) {
throw new IllegalArgumentException("channelUri cannot be null");
}
@@ -1021,7 +1034,7 @@ public final class TvInputManager {
}
mTracks = null;
try {
- mService.tune(mToken, channelUri, mUserId);
+ mService.tune(mToken, channelUri, params, mUserId);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index 29a223050e8c..7ce278c93d3e 100644
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -558,6 +558,19 @@ public abstract class TvInputService extends Service {
public abstract boolean onTune(Uri channelUri);
/**
+ * Calls {@link #onTune(Uri)}. Override this method in order to handle {@code params}.
+ *
+ * @param channelUri The URI of the channel.
+ * @param params The extra parameters from other applications.
+ * @return {@code true} the tuning was successful, {@code false} otherwise.
+ * @hide
+ */
+ @SystemApi
+ public boolean onTune(Uri channelUri, Bundle params) {
+ return onTune(channelUri);
+ }
+
+ /**
* Enables or disables the caption.
* <p>
* The locale for the user's preferred captioning language can be obtained by calling
@@ -809,8 +822,8 @@ public abstract class TvInputService extends Service {
/**
* Calls {@link #onTune}.
*/
- void tune(Uri channelUri) {
- onTune(channelUri);
+ void tune(Uri channelUri, Bundle params) {
+ onTune(channelUri, params);
// TODO: Handle failure.
}
diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java
index 7031f05affc6..2696a637b6de 100644
--- a/media/java/android/media/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -203,10 +203,23 @@ public class TvView extends ViewGroup {
/**
* Tunes to a given channel.
*
- * @param inputId the id of TV input which will play the given channel.
+ * @param inputId The id of TV input which will play the given channel.
* @param channelUri The URI of a channel.
*/
public void tune(String inputId, Uri channelUri) {
+ tune(inputId, channelUri, null);
+ }
+
+ /**
+ * Tunes to a given channel.
+ *
+ * @param inputId The id of TV input which will play the given channel.
+ * @param channelUri The URI of a channel.
+ * @param params Extra parameters which might be handled with the tune event.
+ * @hide
+ */
+ @SystemApi
+ public void tune(String inputId, Uri channelUri, Bundle params) {
if (DEBUG) Log.d(TAG, "tune(" + channelUri + ")");
if (TextUtils.isEmpty(inputId)) {
throw new IllegalArgumentException("inputId cannot be null or an empty string");
@@ -218,11 +231,12 @@ public class TvView extends ViewGroup {
}
if (mSessionCallback != null && mSessionCallback.mInputId.equals(inputId)) {
if (mSession != null) {
- mSession.tune(channelUri);
+ mSession.tune(channelUri, params);
} else {
// Session is not created yet. Replace the channel which will be set once the
// session is made.
mSessionCallback.mChannelUri = channelUri;
+ mSessionCallback.mTuneParams = params;
}
} else {
reset();
@@ -231,7 +245,7 @@ public class TvView extends ViewGroup {
// The previous callbacks will be ignored. For the logic, mSessionCallback
// is newly assigned for every createSession request and compared with
// MySessionCreateCallback.this.
- mSessionCallback = new MySessionCallback(inputId, channelUri);
+ mSessionCallback = new MySessionCallback(inputId, channelUri, params);
mTvInputManager.createSession(inputId, mSessionCallback, mHandler);
}
}
@@ -722,10 +736,12 @@ public class TvView extends ViewGroup {
private class MySessionCallback extends SessionCallback {
final String mInputId;
Uri mChannelUri;
+ Bundle mTuneParams;
- MySessionCallback(String inputId, Uri channelUri) {
+ MySessionCallback(String inputId, Uri channelUri, Bundle tuneParams) {
mInputId = inputId;
mChannelUri = channelUri;
+ mTuneParams = tuneParams;
}
@Override
@@ -754,7 +770,7 @@ public class TvView extends ViewGroup {
}
}
createSessionOverlayView();
- mSession.tune(mChannelUri);
+ mSession.tune(mChannelUri, mTuneParams);
if (mHasStreamVolume) {
mSession.setStreamVolume(mStreamVolume);
}
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 16597c05b8f4..e9a3c4e472ee 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -51,6 +51,7 @@ import android.media.tv.TvContentRating;
import android.media.tv.TvContract;
import android.media.tv.TvInputHardwareInfo;
import android.media.tv.TvInputInfo;
+import android.media.tv.TvInputManager;
import android.media.tv.TvInputService;
import android.media.tv.TvStreamConfig;
import android.media.tv.TvTrackInfo;
@@ -1135,7 +1136,7 @@ public final class TvInputManagerService extends SystemService {
}
@Override
- public void tune(IBinder sessionToken, final Uri channelUri, int userId) {
+ public void tune(IBinder sessionToken, final Uri channelUri, Bundle params, int userId) {
final int callingUid = Binder.getCallingUid();
final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
userId, "tune");
@@ -1143,7 +1144,8 @@ public final class TvInputManagerService extends SystemService {
try {
synchronized (mLock) {
try {
- getSessionLocked(sessionToken, callingUid, resolvedUserId).tune(channelUri);
+ getSessionLocked(sessionToken, callingUid, resolvedUserId).tune(
+ channelUri, params);
if (TvContract.isChannelUriForPassthroughTvInput(channelUri)) {
// Do not log the watch history for passthrough inputs.
return;
@@ -1170,6 +1172,10 @@ public final class TvInputManagerService extends SystemService {
currentTime);
values.put(TvContract.WatchedPrograms.COLUMN_WATCH_END_TIME_UTC_MILLIS, 0);
values.put(TvContract.WatchedPrograms.COLUMN_CHANNEL_ID, channelId);
+ if (params != null) {
+ values.put(TvContract.WatchedPrograms.COLUMN_TUNE_PARAMS,
+ encodeTuneParams(params));
+ }
sessionState.mLogUri = mContentResolver.insert(
TvContract.WatchedPrograms.CONTENT_URI, values);
@@ -1582,6 +1588,39 @@ public final class TvInputManagerService extends SystemService {
}
}
}
+
+ private String encodeTuneParams(Bundle tuneParams) {
+ StringBuilder builder = new StringBuilder();
+ Set<String> keySet = tuneParams.keySet();
+ Iterator<String> it = keySet.iterator();
+ while (it.hasNext()) {
+ String key = it.next();
+ Object value = tuneParams.get(key);
+ if (value == null) {
+ continue;
+ }
+ builder.append(replaceEscapeCharacters(key));
+ builder.append("=");
+ builder.append(replaceEscapeCharacters(value.toString()));
+ if (it.hasNext()) {
+ builder.append(", ");
+ }
+ }
+ return builder.toString();
+ }
+
+ private String replaceEscapeCharacters(String src) {
+ final char ESCAPE_CHARACTER = '%';
+ final String ENCODING_TARGET_CHARACTERS = "%=,";
+ StringBuilder builder = new StringBuilder();
+ for (char ch : src.toCharArray()) {
+ if (ENCODING_TARGET_CHARACTERS.indexOf(ch) >= 0) {
+ builder.append(ESCAPE_CHARACTER);
+ }
+ builder.append(ch);
+ }
+ return builder.toString();
+ }
}
private static final class TvInputState {