Merge "Add pause and resume recoding APIs"
This commit is contained in:
@@ -385,6 +385,7 @@ package android {
|
||||
field public static final int calendarViewShown = 16843596; // 0x101034c
|
||||
field public static final int calendarViewStyle = 16843613; // 0x101035d
|
||||
field public static final int canControlMagnification = 16844039; // 0x1010507
|
||||
field public static final int canPauseRecording = 16844311; // 0x1010617
|
||||
field public static final int canPerformGestures = 16844045; // 0x101050d
|
||||
field public static final int canRecord = 16844060; // 0x101051c
|
||||
field @Deprecated public static final int canRequestEnhancedWebAccessibility = 16843736; // 0x10103d8
|
||||
@@ -24265,6 +24266,7 @@ package android.media.tv {
|
||||
}
|
||||
|
||||
public final class TvInputInfo implements android.os.Parcelable {
|
||||
method public boolean canPauseRecording();
|
||||
method public boolean canRecord();
|
||||
method @Deprecated public android.content.Intent createSettingsIntent();
|
||||
method public android.content.Intent createSetupIntent();
|
||||
@@ -24298,6 +24300,7 @@ package android.media.tv {
|
||||
public static final class TvInputInfo.Builder {
|
||||
ctor public TvInputInfo.Builder(android.content.Context, android.content.ComponentName);
|
||||
method public android.media.tv.TvInputInfo build();
|
||||
method @NonNull public android.media.tv.TvInputInfo.Builder setCanPauseRecording(boolean);
|
||||
method public android.media.tv.TvInputInfo.Builder setCanRecord(boolean);
|
||||
method public android.media.tv.TvInputInfo.Builder setExtras(android.os.Bundle);
|
||||
method public android.media.tv.TvInputInfo.Builder setTunerCount(int);
|
||||
@@ -24389,7 +24392,9 @@ package android.media.tv {
|
||||
method public void notifyRecordingStopped(android.net.Uri);
|
||||
method public void notifyTuned(android.net.Uri);
|
||||
method public void onAppPrivateCommand(@NonNull String, android.os.Bundle);
|
||||
method public void onPauseRecording(@NonNull android.os.Bundle);
|
||||
method public abstract void onRelease();
|
||||
method public void onResumeRecording(@NonNull android.os.Bundle);
|
||||
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();
|
||||
@@ -24439,7 +24444,11 @@ package android.media.tv {
|
||||
|
||||
public class TvRecordingClient {
|
||||
ctor public TvRecordingClient(android.content.Context, String, @NonNull android.media.tv.TvRecordingClient.RecordingCallback, android.os.Handler);
|
||||
method public void pauseRecording();
|
||||
method public void pauseRecording(@NonNull android.os.Bundle);
|
||||
method public void release();
|
||||
method public void resumeRecording();
|
||||
method public void resumeRecording(@NonNull android.os.Bundle);
|
||||
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);
|
||||
|
||||
@@ -8968,6 +8968,11 @@
|
||||
changed at runtime by calling
|
||||
{@link android.media.tv.TvInputManager#updateTvInputInfo(android.media.tv.TvInputInfo)}. -->
|
||||
<attr name="tunerCount" format="integer" />
|
||||
<!-- Attribute whether the TV input service can pause recording programs.
|
||||
This value can be changed at runtime by calling
|
||||
{@link android.media.tv.TvInputManager#updateTvInputInfo(android.media.tv.TvInputInfo)}
|
||||
. -->
|
||||
<attr name="canPauseRecording" format="boolean" />
|
||||
</declare-styleable>
|
||||
|
||||
<!-- Attributes that can be used with <code>rating-system-definition</code> tags inside of the
|
||||
|
||||
@@ -3043,6 +3043,7 @@
|
||||
=============================================================== -->
|
||||
|
||||
<public-group type="attr" first-id="0x01010617">
|
||||
<public name="canPauseRecording" />
|
||||
<!-- attribute definitions go here -->
|
||||
</public-group>
|
||||
|
||||
|
||||
@@ -91,6 +91,8 @@ interface ITvInputManager {
|
||||
// For the recording session
|
||||
void startRecording(in IBinder sessionToken, in Uri programUri, in Bundle params, int userId);
|
||||
void stopRecording(in IBinder sessionToken, int userId);
|
||||
void pauseRecording(in IBinder sessionToken, in Bundle params, int userId);
|
||||
void resumeRecording(in IBinder sessionToken, in Bundle params, int userId);
|
||||
|
||||
// For TV input hardware binding
|
||||
List<TvInputHardwareInfo> getHardwareList();
|
||||
|
||||
@@ -58,4 +58,6 @@ oneway interface ITvInputSession {
|
||||
// For the recording session
|
||||
void startRecording(in Uri programUri, in Bundle params);
|
||||
void stopRecording();
|
||||
void pauseRecording(in Bundle params);
|
||||
void resumeRecording(in Bundle params);
|
||||
}
|
||||
|
||||
@@ -68,6 +68,8 @@ public class ITvInputSessionWrapper extends ITvInputSession.Stub implements Hand
|
||||
private static final int DO_TIME_SHIFT_ENABLE_POSITION_TRACKING = 19;
|
||||
private static final int DO_START_RECORDING = 20;
|
||||
private static final int DO_STOP_RECORDING = 21;
|
||||
private static final int DO_PAUSE_RECORDING = 22;
|
||||
private static final int DO_RESUME_RECORDING = 23;
|
||||
|
||||
private final boolean mIsRecordingSession;
|
||||
private final HandlerCaller mCaller;
|
||||
@@ -224,6 +226,14 @@ public class ITvInputSessionWrapper extends ITvInputSession.Stub implements Hand
|
||||
mTvInputRecordingSessionImpl.stopRecording();
|
||||
break;
|
||||
}
|
||||
case DO_PAUSE_RECORDING: {
|
||||
mTvInputRecordingSessionImpl.pauseRecording((Bundle) msg.obj);
|
||||
break;
|
||||
}
|
||||
case DO_RESUME_RECORDING: {
|
||||
mTvInputRecordingSessionImpl.resumeRecording((Bundle) msg.obj);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
Log.w(TAG, "Unhandled message code: " + msg.what);
|
||||
break;
|
||||
@@ -363,6 +373,16 @@ public class ITvInputSessionWrapper extends ITvInputSession.Stub implements Hand
|
||||
mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_STOP_RECORDING));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pauseRecording(@Nullable Bundle params) {
|
||||
mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_PAUSE_RECORDING, params));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resumeRecording(@Nullable Bundle params) {
|
||||
mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_RESUME_RECORDING, params));
|
||||
}
|
||||
|
||||
private final class TvInputEventReceiver extends InputEventReceiver {
|
||||
public TvInputEventReceiver(InputChannel inputChannel, Looper looper) {
|
||||
super(inputChannel, looper);
|
||||
|
||||
@@ -143,6 +143,7 @@ public final class TvInputInfo implements Parcelable {
|
||||
// Attributes from XML meta data.
|
||||
private final String mSetupActivity;
|
||||
private final boolean mCanRecord;
|
||||
private final boolean mCanPauseRecording;
|
||||
private final int mTunerCount;
|
||||
|
||||
// Attributes specific to HDMI
|
||||
@@ -264,8 +265,8 @@ public final class TvInputInfo implements Parcelable {
|
||||
|
||||
private TvInputInfo(ResolveInfo service, String id, int type, boolean isHardwareInput,
|
||||
CharSequence label, int labelResId, Icon icon, Icon iconStandby, Icon iconDisconnected,
|
||||
String setupActivity, boolean canRecord, int tunerCount, HdmiDeviceInfo hdmiDeviceInfo,
|
||||
boolean isConnectedToHdmiSwitch,
|
||||
String setupActivity, boolean canRecord, boolean canPauseRecording, int tunerCount,
|
||||
HdmiDeviceInfo hdmiDeviceInfo, boolean isConnectedToHdmiSwitch,
|
||||
@HdmiAddressRelativePosition int hdmiConnectionRelativePosition, String parentId,
|
||||
Bundle extras) {
|
||||
mService = service;
|
||||
@@ -279,6 +280,7 @@ public final class TvInputInfo implements Parcelable {
|
||||
mIconDisconnected = iconDisconnected;
|
||||
mSetupActivity = setupActivity;
|
||||
mCanRecord = canRecord;
|
||||
mCanPauseRecording = canPauseRecording;
|
||||
mTunerCount = tunerCount;
|
||||
mHdmiDeviceInfo = hdmiDeviceInfo;
|
||||
mIsConnectedToHdmiSwitch = isConnectedToHdmiSwitch;
|
||||
@@ -385,6 +387,14 @@ public final class TvInputInfo implements Parcelable {
|
||||
return mCanRecord;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this TV input can pause recording TV programs,
|
||||
* {@code false} otherwise.
|
||||
*/
|
||||
public boolean canPauseRecording() {
|
||||
return mCanPauseRecording;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns domain-specific extras associated with this TV input.
|
||||
*/
|
||||
@@ -571,6 +581,7 @@ public final class TvInputInfo implements Parcelable {
|
||||
&& Objects.equals(mIconDisconnected, obj.mIconDisconnected)
|
||||
&& TextUtils.equals(mSetupActivity, obj.mSetupActivity)
|
||||
&& mCanRecord == obj.mCanRecord
|
||||
&& mCanPauseRecording == obj.mCanPauseRecording
|
||||
&& mTunerCount == obj.mTunerCount
|
||||
&& Objects.equals(mHdmiDeviceInfo, obj.mHdmiDeviceInfo)
|
||||
&& mIsConnectedToHdmiSwitch == obj.mIsConnectedToHdmiSwitch
|
||||
@@ -606,6 +617,7 @@ public final class TvInputInfo implements Parcelable {
|
||||
dest.writeParcelable(mIconDisconnected, flags);
|
||||
dest.writeString(mSetupActivity);
|
||||
dest.writeByte(mCanRecord ? (byte) 1 : 0);
|
||||
dest.writeByte(mCanPauseRecording ? (byte) 1 : 0);
|
||||
dest.writeInt(mTunerCount);
|
||||
dest.writeParcelable(mHdmiDeviceInfo, flags);
|
||||
dest.writeByte(mIsConnectedToHdmiSwitch ? (byte) 1 : 0);
|
||||
@@ -648,6 +660,7 @@ public final class TvInputInfo implements Parcelable {
|
||||
mIconDisconnected = in.readParcelable(null);
|
||||
mSetupActivity = in.readString();
|
||||
mCanRecord = in.readByte() == 1;
|
||||
mCanPauseRecording = in.readByte() == 1;
|
||||
mTunerCount = in.readInt();
|
||||
mHdmiDeviceInfo = in.readParcelable(null);
|
||||
mIsConnectedToHdmiSwitch = in.readByte() == 1;
|
||||
@@ -695,6 +708,7 @@ public final class TvInputInfo implements Parcelable {
|
||||
private Icon mIconDisconnected;
|
||||
private String mSetupActivity;
|
||||
private Boolean mCanRecord;
|
||||
private Boolean mCanPauseRecording;
|
||||
private Integer mTunerCount;
|
||||
private TvInputHardwareInfo mTvInputHardwareInfo;
|
||||
private HdmiDeviceInfo mHdmiDeviceInfo;
|
||||
@@ -878,6 +892,18 @@ public final class TvInputInfo implements Parcelable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this TV input can pause recording TV programs or not.
|
||||
*
|
||||
* @param canPauseRecording Whether this TV input can pause recording TV programs.
|
||||
* @return This Builder object to allow for chaining of calls to builder methods.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setCanPauseRecording(boolean canPauseRecording) {
|
||||
this.mCanPauseRecording = canPauseRecording;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets domain-specific extras associated with this TV input.
|
||||
*
|
||||
@@ -927,7 +953,9 @@ public final class TvInputInfo implements Parcelable {
|
||||
parseServiceMetadata(type);
|
||||
return new TvInputInfo(mResolveInfo, id, type, isHardwareInput, mLabel, mLabelResId,
|
||||
mIcon, mIconStandby, mIconDisconnected, mSetupActivity,
|
||||
mCanRecord == null ? false : mCanRecord, mTunerCount == null ? 0 : mTunerCount,
|
||||
mCanRecord == null ? false : mCanRecord,
|
||||
mCanPauseRecording == null ? false : mCanPauseRecording,
|
||||
mTunerCount == null ? 0 : mTunerCount,
|
||||
mHdmiDeviceInfo, isConnectedToHdmiSwitch, hdmiConnectionRelativePosition,
|
||||
mParentId, mExtras);
|
||||
}
|
||||
@@ -997,6 +1025,12 @@ public final class TvInputInfo implements Parcelable {
|
||||
mTunerCount = sa.getInt(
|
||||
com.android.internal.R.styleable.TvInputService_tunerCount, 1);
|
||||
}
|
||||
if (mCanPauseRecording == null) {
|
||||
mCanPauseRecording = sa.getBoolean(
|
||||
com.android.internal.R.styleable.TvInputService_canPauseRecording,
|
||||
false);
|
||||
}
|
||||
|
||||
sa.recycle();
|
||||
} catch (IOException | XmlPullParserException e) {
|
||||
throw new IllegalStateException("Failed reading meta-data for " + si.packageName, e);
|
||||
|
||||
@@ -2475,6 +2475,40 @@ public final class TvInputManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pauses TV program recording in the current recording session.
|
||||
*
|
||||
* @param params A set of extra parameters which might be handled with this event.
|
||||
*/
|
||||
void pauseRecording(@NonNull Bundle params) {
|
||||
if (mToken == null) {
|
||||
Log.w(TAG, "The session has been already released");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mService.pauseRecording(mToken, params, mUserId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resumes TV program recording in the current recording session.
|
||||
*
|
||||
* @param params A set of extra parameters which might be handled with this event.
|
||||
*/
|
||||
void resumeRecording(@NonNull Bundle params) {
|
||||
if (mToken == null) {
|
||||
Log.w(TAG, "The session has been already released");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mService.resumeRecording(mToken, params, mUserId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link TvInputService.Session#appPrivateCommand(String, Bundle)
|
||||
* TvInputService.Session.appPrivateCommand()} on the current TvView.
|
||||
|
||||
@@ -1851,6 +1851,28 @@ public abstract class TvInputService extends Service {
|
||||
public abstract void onStopRecording();
|
||||
|
||||
|
||||
/**
|
||||
* Called when the application requests to pause TV program recording. Recording must pause
|
||||
* immediately when this method is called.
|
||||
*
|
||||
* If the pause request cannot be fulfilled, the session must call
|
||||
* {@link #notifyError(int)}.
|
||||
*
|
||||
* @param params Domain-specific data for recording request.
|
||||
*/
|
||||
public void onPauseRecording(@NonNull Bundle params) { }
|
||||
|
||||
/**
|
||||
* Called when the application requests to resume TV program recording. Recording must
|
||||
* resume immediately when this method is called.
|
||||
*
|
||||
* If the resume request cannot be fulfilled, the session must call
|
||||
* {@link #notifyError(int)}.
|
||||
*
|
||||
* @param params Domain-specific data for recording request.
|
||||
*/
|
||||
public void onResumeRecording(@NonNull Bundle params) { }
|
||||
|
||||
/**
|
||||
* Called when the application requests to release all the resources held by this recording
|
||||
* session.
|
||||
@@ -1902,6 +1924,22 @@ public abstract class TvInputService extends Service {
|
||||
onStopRecording();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link #onPauseRecording(Bundle)}.
|
||||
*
|
||||
*/
|
||||
void pauseRecording(@NonNull Bundle params) {
|
||||
onPauseRecording(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link #onResumeRecording(Bundle)}.
|
||||
*
|
||||
*/
|
||||
void resumeRecording(@NonNull Bundle params) {
|
||||
onResumeRecording(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link #onAppPrivateCommand(String, Bundle)}.
|
||||
*/
|
||||
|
||||
@@ -30,6 +30,7 @@ import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Objects;
|
||||
import java.util.Queue;
|
||||
|
||||
/**
|
||||
@@ -49,6 +50,8 @@ public class TvRecordingClient {
|
||||
|
||||
private boolean mIsRecordingStarted;
|
||||
private boolean mIsTuned;
|
||||
private boolean mIsPaused;
|
||||
private boolean mIsRecordingStopping;
|
||||
private final Queue<Pair<String, Bundle>> mPendingAppPrivateCommands = new ArrayDeque<>();
|
||||
|
||||
/**
|
||||
@@ -113,17 +116,22 @@ public class TvRecordingClient {
|
||||
if (TextUtils.isEmpty(inputId)) {
|
||||
throw new IllegalArgumentException("inputId cannot be null or an empty string");
|
||||
}
|
||||
if (mIsRecordingStarted) {
|
||||
if (mIsRecordingStarted && !mIsPaused) {
|
||||
throw new IllegalStateException("tune failed - recording already started");
|
||||
}
|
||||
if (mSessionCallback != null && TextUtils.equals(mSessionCallback.mInputId, inputId)) {
|
||||
if (mSession != null) {
|
||||
mSessionCallback.mChannelUri = channelUri;
|
||||
mSession.tune(channelUri, params);
|
||||
} else {
|
||||
mSessionCallback.mChannelUri = channelUri;
|
||||
mSessionCallback.mConnectionParams = params;
|
||||
}
|
||||
mIsTuned = false;
|
||||
} else {
|
||||
if (mIsPaused) {
|
||||
throw new IllegalStateException("tune failed - inputId is changed during pause");
|
||||
}
|
||||
resetInternal();
|
||||
mSessionCallback = new MySessionCallback(inputId, channelUri, params);
|
||||
if (mTvInputManager != null) {
|
||||
@@ -148,6 +156,8 @@ public class TvRecordingClient {
|
||||
mSession.release();
|
||||
mIsTuned = false;
|
||||
mIsRecordingStarted = false;
|
||||
mIsPaused = false;
|
||||
mIsRecordingStopping = false;
|
||||
mSession = null;
|
||||
}
|
||||
}
|
||||
@@ -169,7 +179,8 @@ public class TvRecordingClient {
|
||||
*
|
||||
* @param programUri The URI for the TV program to record, built by
|
||||
* {@link TvContract#buildProgramUri(long)}. Can be {@code null}.
|
||||
* @throws IllegalStateException If {@link #tune} request hasn't been handled yet.
|
||||
* @throws IllegalStateException If {@link #tune} request hasn't been handled yet or during
|
||||
* pause.
|
||||
*/
|
||||
public void startRecording(@Nullable Uri programUri) {
|
||||
startRecording(programUri, Bundle.EMPTY);
|
||||
@@ -195,11 +206,16 @@ public class TvRecordingClient {
|
||||
* @param params Domain-specific data for this request. Keys <em>must</em> 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.
|
||||
* @throws IllegalStateException If {@link #tune} request hasn't been handled yet or during
|
||||
* pause.
|
||||
*/
|
||||
public void startRecording(@Nullable Uri programUri, @NonNull Bundle params) {
|
||||
if (!mIsTuned) {
|
||||
throw new IllegalStateException("startRecording failed - not yet tuned");
|
||||
if (mIsRecordingStopping || !mIsTuned || mIsPaused) {
|
||||
throw new IllegalStateException("startRecording failed -"
|
||||
+ "recording not yet stopped or not yet tuned or paused");
|
||||
}
|
||||
if (mIsRecordingStarted) {
|
||||
Log.w(TAG, "startRecording failed - recording already started");
|
||||
}
|
||||
if (mSession != null) {
|
||||
mSession.startRecording(programUri, params);
|
||||
@@ -225,6 +241,103 @@ public class TvRecordingClient {
|
||||
}
|
||||
if (mSession != null) {
|
||||
mSession.stopRecording();
|
||||
if (mIsRecordingStarted) {
|
||||
mIsRecordingStopping = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pause TV program recording in the current recording session. Recording is expected to pause
|
||||
* immediately when this method is called. If recording has not yet started in the current
|
||||
* recording session, this method does nothing.
|
||||
*
|
||||
* <p>In pause status, the application can tune during recording. To continue recording,
|
||||
* please call {@link TvRecordingClient#resumeRecording()} to resume instead of
|
||||
* {@link TvRecordingClient#startRecording(Uri)}. Application can stop
|
||||
* the recording with {@link TvRecordingClient#stopRecording()} in recording pause status.
|
||||
*
|
||||
* <p>If the pause request cannot be fulfilled, the recording session will respond by calling
|
||||
* {@link RecordingCallback#onError(int)}.
|
||||
*/
|
||||
public void pauseRecording() {
|
||||
pauseRecording(Bundle.EMPTY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pause TV program recording in the current recording session. Recording is expected to pause
|
||||
* immediately when this method is called. If recording has not yet started in the current
|
||||
* recording session, this method does nothing.
|
||||
*
|
||||
* <p>In pause status, the application can tune during recording. To continue recording,
|
||||
* please call {@link TvRecordingClient#resumeRecording()} to resume instead of
|
||||
* {@link TvRecordingClient#startRecording(Uri)}. Application can stop
|
||||
* the recording with {@link TvRecordingClient#stopRecording()} in recording pause status.
|
||||
*
|
||||
* <p>If the pause request cannot be fulfilled, the recording session will respond by calling
|
||||
* {@link RecordingCallback#onError(int)}.
|
||||
*
|
||||
* @param params Domain-specific data for this request.
|
||||
*/
|
||||
public void pauseRecording(@NonNull Bundle params) {
|
||||
if (!mIsRecordingStarted || mIsRecordingStopping) {
|
||||
throw new IllegalStateException(
|
||||
"pauseRecording failed - recording not yet started or stopping");
|
||||
}
|
||||
TvInputInfo info = mTvInputManager.getTvInputInfo(mSessionCallback.mInputId);
|
||||
if (info == null || !info.canPauseRecording()) {
|
||||
throw new UnsupportedOperationException(
|
||||
"pauseRecording failed - operation not supported");
|
||||
}
|
||||
if (mIsPaused) {
|
||||
Log.w(TAG, "pauseRecording failed - recording already paused");
|
||||
}
|
||||
if (mSession != null) {
|
||||
mSession.pauseRecording(params);
|
||||
mIsPaused = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resume TV program recording only in recording pause status in the current recording session.
|
||||
* Recording is expected to resume immediately when this method is called. If recording has not
|
||||
* yet paused in the current recording session, this method does nothing.
|
||||
*
|
||||
* <p>When record is resumed, the recording is continue and can not re-tune. Application can
|
||||
* stop the recording with {@link TvRecordingClient#stopRecording()} after record resumed.
|
||||
*
|
||||
* <p>If the pause request cannot be fulfilled, the recording session will respond by calling
|
||||
* {@link RecordingCallback#onError(int)}.
|
||||
*/
|
||||
public void resumeRecording() {
|
||||
resumeRecording(Bundle.EMPTY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resume TV program recording only in recording pause status in the current recording session.
|
||||
* Recording is expected to resume immediately when this method is called. If recording has not
|
||||
* yet paused in the current recording session, this method does nothing.
|
||||
*
|
||||
* <p>When record is resumed, the recording is continues and can not re-tune. Application can
|
||||
* stop the recording with {@link TvRecordingClient#stopRecording()} after record resumed.
|
||||
*
|
||||
* <p>If the resume request cannot be fulfilled, the recording session will respond by calling
|
||||
* {@link RecordingCallback#onError(int)}.
|
||||
*
|
||||
* @param params Domain-specific data for this request.
|
||||
*/
|
||||
public void resumeRecording(@NonNull Bundle params) {
|
||||
if (!mIsRecordingStarted || mIsRecordingStopping || !mIsTuned) {
|
||||
throw new IllegalStateException(
|
||||
"resumeRecording failed - recording not yet started or stopping or "
|
||||
+ "not yet tuned");
|
||||
}
|
||||
if (!mIsPaused) {
|
||||
Log.w(TAG, "resumeRecording failed - recording not yet paused");
|
||||
}
|
||||
if (mSession != null) {
|
||||
mSession.resumeRecording(params);
|
||||
mIsPaused = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -367,6 +480,10 @@ public class TvRecordingClient {
|
||||
Log.w(TAG, "onTuned - session not created");
|
||||
return;
|
||||
}
|
||||
if (mIsTuned || !Objects.equals(mChannelUri, channelUri)) {
|
||||
Log.w(TAG, "onTuned - already tuned or not yet tuned to last channel");
|
||||
return;
|
||||
}
|
||||
mIsTuned = true;
|
||||
mCallback.onTuned(channelUri);
|
||||
}
|
||||
@@ -382,6 +499,8 @@ public class TvRecordingClient {
|
||||
}
|
||||
mIsTuned = false;
|
||||
mIsRecordingStarted = false;
|
||||
mIsPaused = false;
|
||||
mIsRecordingStopping = false;
|
||||
mSessionCallback = null;
|
||||
mSession = null;
|
||||
if (mCallback != null) {
|
||||
@@ -398,7 +517,13 @@ public class TvRecordingClient {
|
||||
Log.w(TAG, "onRecordingStopped - session not created");
|
||||
return;
|
||||
}
|
||||
if (!mIsRecordingStarted) {
|
||||
Log.w(TAG, "onRecordingStopped - recording not yet started");
|
||||
return;
|
||||
}
|
||||
mIsRecordingStarted = false;
|
||||
mIsPaused = false;
|
||||
mIsRecordingStopping = false;
|
||||
mCallback.onRecordingStopped(recordedProgramUri);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import static android.media.AudioManager.DEVICE_NONE;
|
||||
import static android.media.tv.TvInputManager.INPUT_STATE_CONNECTED;
|
||||
import static android.media.tv.TvInputManager.INPUT_STATE_CONNECTED_STANDBY;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.ActivityManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
@@ -1727,6 +1728,46 @@ public final class TvInputManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pauseRecording(IBinder sessionToken, @NonNull Bundle params, int userId) {
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
|
||||
userId, "pauseRecording");
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (mLock) {
|
||||
try {
|
||||
getSessionLocked(sessionToken, callingUid, resolvedUserId)
|
||||
.pauseRecording(params);
|
||||
} catch (RemoteException | SessionNotFoundException e) {
|
||||
Slog.e(TAG, "error in pauseRecording", e);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resumeRecording(IBinder sessionToken, @NonNull Bundle params, int userId) {
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
|
||||
userId, "resumeRecording");
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (mLock) {
|
||||
try {
|
||||
getSessionLocked(sessionToken, callingUid, resolvedUserId)
|
||||
.resumeRecording(params);
|
||||
} catch (RemoteException | SessionNotFoundException e) {
|
||||
Slog.e(TAG, "error in resumeRecording", e);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TvInputHardwareInfo> getHardwareList() throws RemoteException {
|
||||
if (mContext.checkCallingPermission(android.Manifest.permission.TV_INPUT_HARDWARE)
|
||||
|
||||
Reference in New Issue
Block a user