diff --git a/api/current.txt b/api/current.txt index 462a3f4d20af6..5d5d379f5d2bc 100644 --- a/api/current.txt +++ b/api/current.txt @@ -29200,6 +29200,7 @@ package android.media.tv { method public void onAppPrivateCommand(@NonNull String, android.os.Bundle); method public abstract void onRelease(); method public abstract void onStartRecording(@Nullable android.net.Uri); + method public void onStartRecording(@Nullable android.net.Uri, @NonNull android.os.Bundle); method public abstract void onStopRecording(); method public abstract void onTune(android.net.Uri); method public void onTune(android.net.Uri, android.os.Bundle); @@ -29250,6 +29251,7 @@ package android.media.tv { method public void release(); method public void sendAppPrivateCommand(@NonNull String, android.os.Bundle); method public void startRecording(@Nullable android.net.Uri); + method public void startRecording(@Nullable android.net.Uri, @NonNull android.os.Bundle); method public void stopRecording(); method public void tune(String, android.net.Uri); method public void tune(String, android.net.Uri, android.os.Bundle); diff --git a/media/java/android/media/tv/ITvInputManager.aidl b/media/java/android/media/tv/ITvInputManager.aidl index c199c6f8b7615..508a46f492dd9 100644 --- a/media/java/android/media/tv/ITvInputManager.aidl +++ b/media/java/android/media/tv/ITvInputManager.aidl @@ -89,7 +89,7 @@ interface ITvInputManager { void timeShiftEnablePositionTracking(in IBinder sessionToken, boolean enable, int userId); // For the recording session - void startRecording(in IBinder sessionToken, in Uri programUri, int userId); + void startRecording(in IBinder sessionToken, in Uri programUri, in Bundle params, int userId); void stopRecording(in IBinder sessionToken, int userId); // For TV input hardware binding diff --git a/media/java/android/media/tv/ITvInputSession.aidl b/media/java/android/media/tv/ITvInputSession.aidl index 356ec3cd1f11f..24b87d50b33e0 100644 --- a/media/java/android/media/tv/ITvInputSession.aidl +++ b/media/java/android/media/tv/ITvInputSession.aidl @@ -56,6 +56,6 @@ oneway interface ITvInputSession { void timeShiftEnablePositionTracking(boolean enable); // For the recording session - void startRecording(in Uri programUri); + void startRecording(in Uri programUri, in Bundle params); void stopRecording(); } diff --git a/media/java/android/media/tv/ITvInputSessionWrapper.java b/media/java/android/media/tv/ITvInputSessionWrapper.java index 07cfbda7ac2b6..e89d33d70d5c7 100644 --- a/media/java/android/media/tv/ITvInputSessionWrapper.java +++ b/media/java/android/media/tv/ITvInputSessionWrapper.java @@ -216,7 +216,8 @@ public class ITvInputSessionWrapper extends ITvInputSession.Stub implements Hand break; } case DO_START_RECORDING: { - mTvInputRecordingSessionImpl.startRecording((Uri) msg.obj); + SomeArgs args = (SomeArgs) msg.obj; + mTvInputRecordingSessionImpl.startRecording((Uri) args.arg1, (Bundle) args.arg2); break; } case DO_STOP_RECORDING: { @@ -352,8 +353,9 @@ public class ITvInputSessionWrapper extends ITvInputSession.Stub implements Hand } @Override - public void startRecording(@Nullable Uri programUri) { - mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_START_RECORDING, programUri)); + public void startRecording(@Nullable Uri programUri, @Nullable Bundle params) { + mCaller.executeOrSendMessage(mCaller.obtainMessageOO(DO_START_RECORDING, programUri, + params)); } @Override diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java index bb867630ca013..2589521ca3700 100644 --- a/media/java/android/media/tv/TvInputManager.java +++ b/media/java/android/media/tv/TvInputManager.java @@ -2381,12 +2381,23 @@ public final class TvInputManager { * {@link TvContract#buildProgramUri(long)}. Can be {@code null}. */ void startRecording(@Nullable Uri programUri) { + startRecording(programUri, null); + } + + /** + * Starts TV program recording in the current recording session. + * + * @param programUri The URI for the TV program to record as a hint, built by + * {@link TvContract#buildProgramUri(long)}. Can be {@code null}. + * @param params A set of extra parameters which might be handled with this event. + */ + void startRecording(@Nullable Uri programUri, @Nullable Bundle params) { if (mToken == null) { Log.w(TAG, "The session has been already released"); return; } try { - mService.startRecording(mToken, programUri, mUserId); + mService.startRecording(mToken, programUri, params, mUserId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java index 7e1f44cb08990..62c7e51f3edf0 100755 --- a/media/java/android/media/tv/TvInputService.java +++ b/media/java/android/media/tv/TvInputService.java @@ -1817,6 +1817,30 @@ public abstract class TvInputService extends Service { */ public abstract void onStartRecording(@Nullable Uri programUri); + /** + * Called when the application requests to start TV program recording. Recording must start + * immediately when this method is called. + * + *

The application may supply the URI for a TV program for filling in program specific + * data fields in the {@link android.media.tv.TvContract.RecordedPrograms} table. + * A non-null {@code programUri} implies the started recording should be of that specific + * program, whereas null {@code programUri} does not impose such a requirement and the + * recording can span across multiple TV programs. In either case, the application must call + * {@link TvRecordingClient#stopRecording()} to stop the recording. + * + *

The session must call {@link #notifyError(int)} if the start request cannot be + * fulfilled. + * + * @param programUri The URI for the TV program to record, built by + * {@link TvContract#buildProgramUri(long)}. Can be {@code null}. + * @param params Domain-specific data for this tune request. Keys must be a scoped + * name, i.e. prefixed with a package name you own, so that different developers + * will not create conflicting keys. + */ + public void onStartRecording(@Nullable Uri programUri, @NonNull Bundle params) { + onStartRecording(programUri); + } + /** * Called when the application requests to stop TV program recording. Recording must stop * immediately when this method is called. @@ -1867,11 +1891,11 @@ public abstract class TvInputService extends Service { } /** - * Calls {@link #onStartRecording(Uri)}. + * Calls {@link #onStartRecording(Uri, Bundle)}. * */ - void startRecording(@Nullable Uri programUri) { - onStartRecording(programUri); + void startRecording(@Nullable Uri programUri, @NonNull Bundle params) { + onStartRecording(programUri, params); } /** diff --git a/media/java/android/media/tv/TvRecordingClient.java b/media/java/android/media/tv/TvRecordingClient.java index 5aadeb6ecfa99..8ae98ae5e937b 100644 --- a/media/java/android/media/tv/TvRecordingClient.java +++ b/media/java/android/media/tv/TvRecordingClient.java @@ -170,11 +170,37 @@ public class TvRecordingClient { * @throws IllegalStateException If {@link #tune} request hasn't been handled yet. */ public void startRecording(@Nullable Uri programUri) { + startRecording(programUri, Bundle.EMPTY); + } + + /** + * Starts TV program recording in the current recording session. Recording is expected to start + * immediately when this method is called. If the current recording session has not yet tuned to + * any channel, this method throws an exception. + * + *

The application may supply the URI for a TV program for filling in program specific data + * fields in the {@link android.media.tv.TvContract.RecordedPrograms} table. + * A non-null {@code programUri} implies the started recording should be of that specific + * program, whereas null {@code programUri} does not impose such a requirement and the + * recording can span across multiple TV programs. In either case, the application must call + * {@link TvRecordingClient#stopRecording()} to stop the recording. + * + *

The recording session will respond by calling {@link RecordingCallback#onError(int)} if + * the start request cannot be fulfilled. + * + * @param programUri The URI for the TV program to record, built by + * {@link TvContract#buildProgramUri(long)}. Can be {@code null}. + * @param params Domain-specific data for this request. Keys must be a scoped + * name, i.e. prefixed with a package name you own, so that different developers will + * not create conflicting keys. + * @throws IllegalStateException If {@link #tune} request hasn't been handled yet. + */ + public void startRecording(@Nullable Uri programUri, @NonNull Bundle params) { if (!mIsTuned) { throw new IllegalStateException("startRecording failed - not yet tuned"); } if (mSession != null) { - mSession.startRecording(programUri); + mSession.startRecording(programUri, params); mIsRecordingStarted = true; } } diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java index e8704ab789f21..4f010d5e0f2cf 100755 --- a/services/core/java/com/android/server/tv/TvInputManagerService.java +++ b/services/core/java/com/android/server/tv/TvInputManagerService.java @@ -1681,7 +1681,8 @@ public final class TvInputManagerService extends SystemService { } @Override - public void startRecording(IBinder sessionToken, @Nullable Uri programUri, int userId) { + public void startRecording(IBinder sessionToken, @Nullable Uri programUri, + @Nullable Bundle params, int userId) { final int callingUid = Binder.getCallingUid(); final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid, userId, "startRecording"); @@ -1690,7 +1691,7 @@ public final class TvInputManagerService extends SystemService { synchronized (mLock) { try { getSessionLocked(sessionToken, callingUid, resolvedUserId).startRecording( - programUri); + programUri, params); } catch (RemoteException | SessionNotFoundException e) { Slog.e(TAG, "error in startRecording", e); }