diff options
| author | 2014-07-09 10:40:43 +0900 | |
|---|---|---|
| committer | 2014-08-01 15:33:32 +0900 | |
| commit | 1a6b25eabcc1fb66e6e8d76f91fd413e18b793a9 (patch) | |
| tree | a502dc681d7b123a67bbe1af2058396f4d8fa08a | |
| parent | f96d229603b97302c7e3224d167da5b67fae3cf1 (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.aidl | 2 | ||||
| -rw-r--r-- | media/java/android/media/tv/ITvInputSession.aidl | 2 | ||||
| -rw-r--r-- | media/java/android/media/tv/ITvInputSessionWrapper.java | 8 | ||||
| -rw-r--r-- | media/java/android/media/tv/TvContract.java | 26 | ||||
| -rw-r--r-- | media/java/android/media/tv/TvInputManager.java | 15 | ||||
| -rw-r--r-- | media/java/android/media/tv/TvInputService.java | 17 | ||||
| -rw-r--r-- | media/java/android/media/tv/TvView.java | 26 | ||||
| -rw-r--r-- | services/core/java/com/android/server/tv/TvInputManagerService.java | 43 |
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 { |