Merge "[TIAF] Time shift APIs"

This commit is contained in:
Shubang Lu
2023-01-12 22:40:19 +00:00
committed by Android (Google) Code Review
9 changed files with 573 additions and 0 deletions

View File

@@ -41,6 +41,7 @@ oneway interface ITvInteractiveAppClient {
void onTeletextAppStateChanged(int state, int seq);
void onAdBuffer(in AdBuffer buffer, int seq);
void onCommandRequest(in String cmdType, in Bundle parameters, int seq);
void onTimeShiftCommandRequest(in String cmdType, in Bundle parameters, int seq);
void onSetVideoBounds(in Rect rect, int seq);
void onRequestCurrentChannelUri(int seq);
void onRequestCurrentChannelLcn(int seq);

View File

@@ -26,6 +26,7 @@ import android.media.tv.interactive.AppLinkInfo;
import android.media.tv.interactive.ITvInteractiveAppClient;
import android.media.tv.interactive.ITvInteractiveAppManagerCallback;
import android.media.tv.interactive.TvInteractiveAppServiceInfo;
import android.media.PlaybackParams;
import android.net.Uri;
import android.os.Bundle;
import android.view.Surface;
@@ -57,6 +58,14 @@ interface ITvInteractiveAppManager {
void sendTvRecordingInfoList(in IBinder sessionToken,
in List<TvRecordingInfo> recordingInfoList, int userId);
void notifyError(in IBinder sessionToken, in String errMsg, in Bundle params, int userId);
void notifyTimeShiftPlaybackParams(
in IBinder sessionToken, in PlaybackParams params, int userId);
void notifyTimeShiftStatusChanged(
in IBinder sessionToken, in String inputId, int status, int userId);
void notifyTimeShiftStartPositionChanged(
in IBinder sessionToken, in String inputId, long timeMs, int userId);
void notifyTimeShiftCurrentPositionChanged(
in IBinder sessionToken, in String inputId, long timeMs, int userId);
void createSession(in ITvInteractiveAppClient client, in String iAppServiceId, int type,
int seq, int userId);
void releaseSession(in IBinder sessionToken, int userId);

View File

@@ -20,6 +20,7 @@ import android.graphics.Rect;
import android.media.tv.BroadcastInfoResponse;
import android.net.Uri;
import android.media.tv.AdBuffer;
import android.media.PlaybackParams;
import android.media.tv.AdResponse;
import android.media.tv.BroadcastInfoResponse;
import android.media.tv.TvTrackInfo;
@@ -48,6 +49,10 @@ oneway interface ITvInteractiveAppSession {
void sendTvRecordingInfo(in TvRecordingInfo recordingInfo);
void sendTvRecordingInfoList(in List<TvRecordingInfo> recordingInfoList);
void notifyError(in String errMsg, in Bundle params);
void notifyTimeShiftPlaybackParams(in PlaybackParams params);
void notifyTimeShiftStatusChanged(in String inputId, int status);
void notifyTimeShiftStartPositionChanged(in String inputId, long timeMs);
void notifyTimeShiftCurrentPositionChanged(in String inputId, long timeMs);
void release();
void notifyTuned(in Uri channelUri);
void notifyTrackSelected(int type, in String trackId);

View File

@@ -40,6 +40,7 @@ oneway interface ITvInteractiveAppSessionCallback {
void onTeletextAppStateChanged(int state);
void onAdBuffer(in AdBuffer buffer);
void onCommandRequest(in String cmdType, in Bundle parameters);
void onTimeShiftCommandRequest(in String cmdType, in Bundle parameters);
void onSetVideoBounds(in Rect rect);
void onRequestCurrentChannelUri();
void onRequestCurrentChannelLcn();

View File

@@ -20,6 +20,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.graphics.Rect;
import android.media.PlaybackParams;
import android.media.tv.AdBuffer;
import android.media.tv.AdResponse;
import android.media.tv.BroadcastInfoResponse;
@@ -89,6 +90,10 @@ public class ITvInteractiveAppSessionWrapper
private static final int DO_NOTIFY_TV_MESSAGE = 33;
private static final int DO_SEND_RECORDING_INFO = 34;
private static final int DO_SEND_RECORDING_INFO_LIST = 35;
private static final int DO_NOTIFY_TIME_SHIFT_PLAYBACK_PARAMS = 36;
private static final int DO_NOTIFY_TIME_SHIFT_STATUS_CHANGED = 37;
private static final int DO_NOTIFY_TIME_SHIFT_START_POSITION_CHANGED = 38;
private static final int DO_NOTIFY_TIME_SHIFT_CURRENT_POSITION_CHANGED = 39;
private final HandlerCaller mCaller;
private Session mSessionImpl;
@@ -277,6 +282,30 @@ public class ITvInteractiveAppSessionWrapper
mSessionImpl.notifyAdBufferConsumed((AdBuffer) msg.obj);
break;
}
case DO_NOTIFY_TIME_SHIFT_PLAYBACK_PARAMS: {
mSessionImpl.notifyTimeShiftPlaybackParams((PlaybackParams) msg.obj);
break;
}
case DO_NOTIFY_TIME_SHIFT_STATUS_CHANGED: {
SomeArgs args = (SomeArgs) msg.obj;
mSessionImpl.notifyTimeShiftStatusChanged((String) args.arg1, (Integer) args.arg2);
args.recycle();
break;
}
case DO_NOTIFY_TIME_SHIFT_START_POSITION_CHANGED: {
SomeArgs args = (SomeArgs) msg.obj;
mSessionImpl.notifyTimeShiftStartPositionChanged(
(String) args.arg1, (Long) args.arg2);
args.recycle();
break;
}
case DO_NOTIFY_TIME_SHIFT_CURRENT_POSITION_CHANGED: {
SomeArgs args = (SomeArgs) msg.obj;
mSessionImpl.notifyTimeShiftCurrentPositionChanged(
(String) args.arg1, (Long) args.arg2);
args.recycle();
break;
}
default: {
Log.w(TAG, "Unhandled message code: " + msg.what);
break;
@@ -379,6 +408,30 @@ public class ITvInteractiveAppSessionWrapper
mCaller.obtainMessageOO(DO_NOTIFY_ERROR, errMsg, params));
}
@Override
public void notifyTimeShiftPlaybackParams(@NonNull PlaybackParams params) {
mCaller.executeOrSendMessage(
mCaller.obtainMessageO(DO_NOTIFY_TIME_SHIFT_PLAYBACK_PARAMS, params));
}
@Override
public void notifyTimeShiftStatusChanged(@NonNull String inputId, int status) {
mCaller.executeOrSendMessage(
mCaller.obtainMessageOO(DO_NOTIFY_TIME_SHIFT_STATUS_CHANGED, inputId, status));
}
@Override
public void notifyTimeShiftStartPositionChanged(@NonNull String inputId, long timeMs) {
mCaller.executeOrSendMessage(mCaller.obtainMessageOO(
DO_NOTIFY_TIME_SHIFT_START_POSITION_CHANGED, inputId, timeMs));
}
@Override
public void notifyTimeShiftCurrentPositionChanged(@NonNull String inputId, long timeMs) {
mCaller.executeOrSendMessage(mCaller.obtainMessageOO(
DO_NOTIFY_TIME_SHIFT_CURRENT_POSITION_CHANGED, inputId, timeMs));
}
@Override
public void release() {
mSessionImpl.scheduleMediaViewCleanup();

View File

@@ -23,6 +23,7 @@ import android.annotation.Nullable;
import android.annotation.SystemService;
import android.content.Context;
import android.graphics.Rect;
import android.media.PlaybackParams;
import android.media.tv.AdBuffer;
import android.media.tv.AdRequest;
import android.media.tv.AdResponse;
@@ -404,6 +405,21 @@ public final class TvInteractiveAppManager {
}
}
@Override
public void onTimeShiftCommandRequest(
@TvInteractiveAppService.TimeShiftCommandType String cmdType,
Bundle parameters,
int seq) {
synchronized (mSessionCallbackRecordMap) {
SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
if (record == null) {
Log.e(TAG, "Callback not found for seq " + seq);
return;
}
record.postTimeShiftCommandRequest(cmdType, parameters);
}
}
@Override
public void onSetVideoBounds(Rect rect, int seq) {
synchronized (mSessionCallbackRecordMap) {
@@ -1182,6 +1198,55 @@ public final class TvInteractiveAppManager {
}
}
void notifyTimeShiftPlaybackParams(@NonNull PlaybackParams params) {
if (mToken == null) {
Log.w(TAG, "The session has been already released");
return;
}
try {
mService.notifyTimeShiftPlaybackParams(mToken, params, mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
void notifyTimeShiftStatusChanged(
@NonNull String inputId, @TvInputManager.TimeShiftStatus int status) {
if (mToken == null) {
Log.w(TAG, "The session has been already released");
return;
}
try {
mService.notifyTimeShiftStatusChanged(mToken, inputId, status, mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
void notifyTimeShiftStartPositionChanged(@NonNull String inputId, long timeMs) {
if (mToken == null) {
Log.w(TAG, "The session has been already released");
return;
}
try {
mService.notifyTimeShiftStartPositionChanged(mToken, inputId, timeMs, mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
void notifyTimeShiftCurrentPositionChanged(@NonNull String inputId, long timeMs) {
if (mToken == null) {
Log.w(TAG, "The session has been already released");
return;
}
try {
mService.notifyTimeShiftCurrentPositionChanged(mToken, inputId, timeMs, mUserId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Sets the {@link android.view.Surface} for this session.
*
@@ -1795,6 +1860,17 @@ public final class TvInteractiveAppManager {
});
}
void postTimeShiftCommandRequest(
final @TvInteractiveAppService.TimeShiftCommandType String cmdType,
final Bundle parameters) {
mHandler.post(new Runnable() {
@Override
public void run() {
mSessionCallback.onTimeShiftCommandRequest(mSession, cmdType, parameters);
}
});
}
void postSetVideoBounds(Rect rect) {
mHandler.post(new Runnable() {
@Override
@@ -2002,6 +2078,20 @@ public final class TvInteractiveAppManager {
Bundle parameters) {
}
/**
* This is called when {@link TvInteractiveAppService.Session#requestTimeShiftCommand} is
* called.
*
* @param session A {@link TvInteractiveAppManager.Session} associated with this callback.
* @param cmdType type of the time shift command.
* @param parameters parameters of the command.
*/
public void onTimeShiftCommandRequest(
Session session,
@TvInteractiveAppService.TimeShiftCommandType String cmdType,
Bundle parameters) {
}
/**
* This is called when {@link TvInteractiveAppService.Session#SetVideoBounds} is called.
*

View File

@@ -30,6 +30,7 @@ import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.media.PlaybackParams;
import android.media.tv.AdBuffer;
import android.media.tv.AdRequest;
import android.media.tv.AdResponse;
@@ -182,6 +183,78 @@ public abstract class TvInteractiveAppService extends Service {
public static final String COMMAND_PARAMETER_KEY_CHANGE_CHANNEL_QUIETLY =
"command_change_channel_quietly";
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@StringDef(prefix = "TIME_SHIFT_COMMAND_TYPE_", value = {
TIME_SHIFT_COMMAND_TYPE_PLAY,
TIME_SHIFT_COMMAND_TYPE_PAUSE,
TIME_SHIFT_COMMAND_TYPE_RESUME,
TIME_SHIFT_COMMAND_TYPE_SEEK_TO,
TIME_SHIFT_COMMAND_TYPE_SET_PLAYBACK_PARAMS,
})
public @interface TimeShiftCommandType {}
/**
* Time shift command type: play.
*
* @see TvView#timeShiftPlay(String, Uri)
* @hide
*/
public static final String TIME_SHIFT_COMMAND_TYPE_PLAY = "play";
/**
* Time shift command type: pause.
*
* @see TvView#timeShiftPause()
* @hide
*/
public static final String TIME_SHIFT_COMMAND_TYPE_PAUSE = "pause";
/**
* Time shift command type: resume.
*
* @see TvView#timeShiftResume()
* @hide
*/
public static final String TIME_SHIFT_COMMAND_TYPE_RESUME = "resume";
/**
* Time shift command type: seek to.
*
* @see TvView#timeShiftSeekTo(long)
* @hide
*/
public static final String TIME_SHIFT_COMMAND_TYPE_SEEK_TO = "seek_to";
/**
* Time shift command type: set playback params.
*
* @see TvView#timeShiftSetPlaybackParams(PlaybackParams)
* @hide
*/
public static final String TIME_SHIFT_COMMAND_TYPE_SET_PLAYBACK_PARAMS = "set_playback_params";
/**
* Time shift command parameter: program URI.
* <p>Type: android.net.Uri
*
* @see #TIME_SHIFT_COMMAND_TYPE_PLAY
* @hide
*/
public static final String COMMAND_PARAMETER_KEY_PROGRAM_URI = "command_program_uri";
/**
* Time shift command parameter: time position for time shifting, in milliseconds.
* <p>Type: long
*
* @see #TIME_SHIFT_COMMAND_TYPE_SEEK_TO
* @hide
*/
public static final String COMMAND_PARAMETER_KEY_TIME_POSITION = "command_time_position";
/**
* Time shift command parameter: playback params.
* <p>Type: android.media.PlaybackParams
*
* @see #TIME_SHIFT_COMMAND_TYPE_SET_PLAYBACK_PARAMS
* @hide
*/
public static final String COMMAND_PARAMETER_KEY_PLAYBACK_PARAMS = "command_playback_params";
private final Handler mServiceHandler = new ServiceHandler();
private final RemoteCallbackList<ITvInteractiveAppServiceCallback> mCallbacks =
new RemoteCallbackList<>();
@@ -519,6 +592,44 @@ public abstract class TvInteractiveAppService extends Service {
public void onError(@NonNull String errMsg, @NonNull Bundle params) {
}
/**
* Called when the time shift {@link android.media.PlaybackParams} is set or changed.
*
* @see TvView#timeShiftSetPlaybackParams(PlaybackParams)
* @hide
*/
public void onTimeShiftPlaybackParams(@NonNull PlaybackParams params) {
}
/**
* Called when time shift status is changed.
*
* @see TvView.TvInputCallback#onTimeShiftStatusChanged(String, int)
* @see android.media.tv.TvInputService.Session#notifyTimeShiftStatusChanged(int)
* @hide
*/
public void onTimeShiftStatusChanged(
@NonNull String inputId, @TvInputManager.TimeShiftStatus int status) {
}
/**
* Called when time shift start position is changed.
*
* @see TvView.TimeShiftPositionCallback#onTimeShiftStartPositionChanged(String, long)
* @hide
*/
public void onTimeShiftStartPositionChanged(@NonNull String inputId, long timeMs) {
}
/**
* Called when time shift current position is changed.
*
* @see TvView.TimeShiftPositionCallback#onTimeShiftCurrentPositionChanged(String, long)
* @hide
*/
public void onTimeShiftCurrentPositionChanged(@NonNull String inputId, long timeMs) {
}
/**
* Called when the application sets the surface.
*
@@ -819,6 +930,35 @@ public abstract class TvInteractiveAppService extends Service {
});
}
/**
* Sends a specific time shift command to be processed by the related TV input.
*
* @param cmdType type of the specific command
* @param parameters parameters of the specific command
* @hide
*/
@CallSuper
public void sendTimeShiftCommandRequest(
@TimeShiftCommandType @NonNull String cmdType, @Nullable Bundle parameters) {
executeOrPostRunnableOnMainThread(new Runnable() {
@MainThread
@Override
public void run() {
try {
if (DEBUG) {
Log.d(TAG, "requestTimeShiftCommand (cmdType=" + cmdType
+ ", parameters=" + parameters.toString() + ")");
}
if (mSessionCallback != null) {
mSessionCallback.onTimeShiftCommandRequest(cmdType, parameters);
}
} catch (RemoteException e) {
Log.w(TAG, "error in requestTimeShiftCommand", e);
}
}
});
}
/**
* Sets broadcast video bounds.
*/
@@ -1329,6 +1469,34 @@ public abstract class TvInteractiveAppService extends Service {
onRecordingStopped(recordingId);
}
/**
* Calls {@link #onTimeShiftPlaybackParams(PlaybackParams)}.
*/
void notifyTimeShiftPlaybackParams(PlaybackParams params) {
onTimeShiftPlaybackParams(params);
}
/**
* Calls {@link #onTimeShiftStatusChanged(String, int)}.
*/
void notifyTimeShiftStatusChanged(String inputId, int status) {
onTimeShiftStatusChanged(inputId, status);
}
/**
* Calls {@link #onTimeShiftStartPositionChanged(String, long)}.
*/
void notifyTimeShiftStartPositionChanged(String inputId, long timeMs) {
onTimeShiftStartPositionChanged(inputId, timeMs);
}
/**
* Calls {@link #onTimeShiftCurrentPositionChanged(String, long)}.
*/
void notifyTimeShiftCurrentPositionChanged(String inputId, long timeMs) {
onTimeShiftCurrentPositionChanged(inputId, timeMs);
}
/**
* Notifies when the session state is changed.
*

View File

@@ -25,6 +25,7 @@ import android.content.res.XmlResourceParser;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.media.PlaybackParams;
import android.media.tv.TvInputManager;
import android.media.tv.TvRecordingInfo;
import android.media.tv.TvTrackInfo;
@@ -684,6 +685,75 @@ public class TvInteractiveAppView extends ViewGroup {
}
}
/**
* Notifies the corresponding {@link TvInteractiveAppService} when a time shift
* {@link android.media.PlaybackParams} is set or changed.
*
* @see TvView#timeShiftSetPlaybackParams(PlaybackParams)
* @hide
*/
public void notifyTimeShiftPlaybackParams(@NonNull PlaybackParams params) {
if (DEBUG) {
Log.d(TAG, "notifyTimeShiftPlaybackParams params=" + params);
}
if (mSession != null) {
mSession.notifyTimeShiftPlaybackParams(params);
}
}
/**
* Notifies the corresponding {@link TvInteractiveAppService} when time shift
* status is changed.
*
* @see TvView.TvInputCallback#onTimeShiftStatusChanged(String, int)
* @see android.media.tv.TvInputService.Session#notifyTimeShiftStatusChanged(int)
* @hide
*/
public void notifyTimeShiftStatusChanged(
@NonNull String inputId, @TvInputManager.TimeShiftStatus int status) {
if (DEBUG) {
Log.d(TAG,
"notifyTimeShiftStatusChanged inputId=" + inputId + "; status=" + status);
}
if (mSession != null) {
mSession.notifyTimeShiftStatusChanged(inputId, status);
}
}
/**
* Notifies the corresponding {@link TvInteractiveAppService} when time shift
* start position is changed.
*
* @see TvView.TimeShiftPositionCallback#onTimeShiftStartPositionChanged(String, long)
* @hide
*/
public void notifyTimeShiftStartPositionChanged(@NonNull String inputId, long timeMs) {
if (DEBUG) {
Log.d(TAG, "notifyTimeShiftStartPositionChanged inputId=" + inputId
+ "; timeMs=" + timeMs);
}
if (mSession != null) {
mSession.notifyTimeShiftStartPositionChanged(inputId, timeMs);
}
}
/**
* Notifies the corresponding {@link TvInteractiveAppService} when time shift
* current position is changed.
*
* @see TvView.TimeShiftPositionCallback#onTimeShiftCurrentPositionChanged(String, long)
* @hide
*/
public void notifyTimeShiftCurrentPositionChanged(@NonNull String inputId, long timeMs) {
if (DEBUG) {
Log.d(TAG, "notifyTimeShiftCurrentPositionChanged inputId=" + inputId
+ "; timeMs=" + timeMs);
}
if (mSession != null) {
mSession.notifyTimeShiftCurrentPositionChanged(inputId, timeMs);
}
}
private void resetInternal() {
mSessionCallback = null;
if (mSession != null) {
@@ -807,6 +877,21 @@ public class TvInteractiveAppView extends ViewGroup {
@NonNull Bundle parameters) {
}
/**
* This is called when a time shift command is requested to be processed by the related TV
* input.
*
* @param iAppServiceId The ID of the TV interactive app service bound to this view.
* @param cmdType type of the command
* @param parameters parameters of the command
* @hide
*/
public void onTimeShiftCommandRequest(
@NonNull String iAppServiceId,
@NonNull @TvInteractiveAppService.TimeShiftCommandType String cmdType,
@NonNull Bundle parameters) {
}
/**
* This is called when the state of corresponding interactive app is changed.
*
@@ -1067,6 +1152,33 @@ public class TvInteractiveAppView extends ViewGroup {
}
}
@Override
public void onTimeShiftCommandRequest(
Session session,
@TvInteractiveAppService.TimeShiftCommandType String cmdType,
Bundle parameters) {
if (DEBUG) {
Log.d(TAG, "onTimeShiftCommandRequest (cmdType=" + cmdType + ", parameters="
+ parameters.toString() + ")");
}
if (this != mSessionCallback) {
Log.w(TAG, "onTimeShiftCommandRequest - session not created");
return;
}
synchronized (mCallbackLock) {
if (mCallbackExecutor != null) {
mCallbackExecutor.execute(() -> {
synchronized (mCallbackLock) {
if (mCallback != null) {
mCallback.onTimeShiftCommandRequest(
mIAppServiceId, cmdType, parameters);
}
}
});
}
}
}
@Override
public void onSessionStateChanged(
Session session,

View File

@@ -29,6 +29,7 @@ import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo;
import android.graphics.Rect;
import android.media.PlaybackParams;
import android.media.tv.AdBuffer;
import android.media.tv.AdRequest;
import android.media.tv.AdResponse;
@@ -1495,6 +1496,118 @@ public class TvInteractiveAppManagerService extends SystemService {
}
}
@Override
public void notifyTimeShiftPlaybackParams(
IBinder sessionToken, PlaybackParams params, int userId) {
if (DEBUG) {
Slogf.d(TAG, "notifyTimeShiftPlaybackParams(params=%s)", params);
}
final int callingUid = Binder.getCallingUid();
final int resolvedUserId = resolveCallingUserId(
Binder.getCallingPid(), callingUid, userId, "notifyTimeShiftPlaybackParams");
SessionState sessionState = null;
final long identity = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
try {
sessionState =
getSessionStateLocked(sessionToken, callingUid, resolvedUserId);
getSessionLocked(sessionState).notifyTimeShiftPlaybackParams(params);
} catch (RemoteException | SessionNotFoundException e) {
Slogf.e(TAG, "error in notifyTimeShiftPlaybackParams", e);
}
}
} finally {
Binder.restoreCallingIdentity(identity);
}
}
@Override
public void notifyTimeShiftStatusChanged(
IBinder sessionToken, String inputId, int status, int userId) {
if (DEBUG) {
Slogf.d(TAG, "notifyTimeShiftStatusChanged(inputId=%s, status=%d)",
inputId, status);
}
final int callingUid = Binder.getCallingUid();
final int resolvedUserId = resolveCallingUserId(
Binder.getCallingPid(), callingUid, userId, "notifyTimeShiftStatusChanged");
SessionState sessionState = null;
final long identity = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
try {
sessionState =
getSessionStateLocked(sessionToken, callingUid, resolvedUserId);
getSessionLocked(sessionState).notifyTimeShiftStatusChanged(
inputId, status);
} catch (RemoteException | SessionNotFoundException e) {
Slogf.e(TAG, "error in notifyTimeShiftStatusChanged", e);
}
}
} finally {
Binder.restoreCallingIdentity(identity);
}
}
@Override
public void notifyTimeShiftStartPositionChanged(
IBinder sessionToken, String inputId, long timeMs, int userId) {
if (DEBUG) {
Slogf.d(TAG, "notifyTimeShiftStartPositionChanged(inputId=%s, timeMs=%d)",
inputId, timeMs);
}
final int callingUid = Binder.getCallingUid();
final int resolvedUserId = resolveCallingUserId(
Binder.getCallingPid(), callingUid, userId,
"notifyTimeShiftStartPositionChanged");
SessionState sessionState = null;
final long identity = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
try {
sessionState =
getSessionStateLocked(sessionToken, callingUid, resolvedUserId);
getSessionLocked(sessionState).notifyTimeShiftStartPositionChanged(
inputId, timeMs);
} catch (RemoteException | SessionNotFoundException e) {
Slogf.e(TAG, "error in notifyTimeShiftStartPositionChanged", e);
}
}
} finally {
Binder.restoreCallingIdentity(identity);
}
}
@Override
public void notifyTimeShiftCurrentPositionChanged(
IBinder sessionToken, String inputId, long timeMs, int userId) {
if (DEBUG) {
Slogf.d(TAG, "notifyTimeShiftCurrentPositionChanged(inputId=%s, timeMs=%d)",
inputId, timeMs);
}
final int callingUid = Binder.getCallingUid();
final int resolvedUserId = resolveCallingUserId(
Binder.getCallingPid(), callingUid, userId,
"notifyTimeShiftCurrentPositionChanged");
SessionState sessionState = null;
final long identity = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
try {
sessionState =
getSessionStateLocked(sessionToken, callingUid, resolvedUserId);
getSessionLocked(sessionState).notifyTimeShiftCurrentPositionChanged(
inputId, timeMs);
} catch (RemoteException | SessionNotFoundException e) {
Slogf.e(TAG, "error in notifyTimeShiftCurrentPositionChanged", e);
}
}
} finally {
Binder.restoreCallingIdentity(identity);
}
}
@Override
public void setSurface(IBinder sessionToken, Surface surface, int userId) {
final int callingUid = Binder.getCallingUid();
@@ -2254,6 +2367,27 @@ public class TvInteractiveAppManagerService extends SystemService {
}
}
@Override
public void onTimeShiftCommandRequest(
@TvInteractiveAppService.TimeShiftCommandType String cmdType,
Bundle parameters) {
synchronized (mLock) {
if (DEBUG) {
Slogf.d(TAG, "onTimeShiftCommandRequest (cmdType=" + cmdType
+ ", parameters=" + parameters.toString() + ")");
}
if (mSessionState.mSession == null || mSessionState.mClient == null) {
return;
}
try {
mSessionState.mClient.onTimeShiftCommandRequest(
cmdType, parameters, mSessionState.mSeq);
} catch (RemoteException e) {
Slogf.e(TAG, "error in onTimeShiftCommandRequest", e);
}
}
}
@Override
public void onSetVideoBounds(Rect rect) {
synchronized (mLock) {