diff --git a/media/java/android/media/tv/AdRequest.java b/media/java/android/media/tv/AdRequest.java index 536baf264dfbe..adcf541e2bab7 100644 --- a/media/java/android/media/tv/AdRequest.java +++ b/media/java/android/media/tv/AdRequest.java @@ -16,8 +16,9 @@ package android.media.tv; +import android.annotation.IntDef; import android.annotation.NonNull; -import android.annotation.StringDef; +import android.annotation.Nullable; import android.os.Bundle; import android.os.Parcel; import android.os.ParcelFileDescriptor; @@ -26,17 +27,27 @@ import android.os.Parcelable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -/** @hide */ +/** + * An advertisement request which can be sent to TV input to request AD operations. + * @hide + */ public final class AdRequest implements Parcelable { + /** @hide */ @Retention(RetentionPolicy.SOURCE) - @StringDef(prefix = "REQUEST_TYPE_", value = { + @IntDef(prefix = "REQUEST_TYPE_", value = { REQUEST_TYPE_START, REQUEST_TYPE_STOP }) public @interface RequestType {} - public static final String REQUEST_TYPE_START = "START"; - public static final String REQUEST_TYPE_STOP = "STOP"; + /** + * Request to start an advertisement. + */ + public static final int REQUEST_TYPE_START = 1; + /** + * Request to stop an advertisement. + */ + public static final int REQUEST_TYPE_STOP = 2; public static final @NonNull Parcelable.Creator CREATOR = new Parcelable.Creator() { @@ -52,7 +63,7 @@ public final class AdRequest implements Parcelable { }; private final int mId; - private final @RequestType String mRequestType; + private final @RequestType int mRequestType; private final ParcelFileDescriptor mFileDescriptor; private final long mStartTime; private final long mStopTime; @@ -60,9 +71,9 @@ public final class AdRequest implements Parcelable { private final String mMediaFileType; private final Bundle mMetadata; - public AdRequest(int id, @RequestType String requestType, ParcelFileDescriptor fileDescriptor, - long startTime, long stopTime, long echoInterval, String mediaFileType, - Bundle metadata) { + public AdRequest(int id, @RequestType int requestType, + @Nullable ParcelFileDescriptor fileDescriptor, long startTime, long stopTime, + long echoInterval, @Nullable String mediaFileType, @NonNull Bundle metadata) { mId = id; mRequestType = requestType; mFileDescriptor = fileDescriptor; @@ -75,8 +86,12 @@ public final class AdRequest implements Parcelable { private AdRequest(Parcel source) { mId = source.readInt(); - mRequestType = source.readString(); - mFileDescriptor = source.readFileDescriptor(); + mRequestType = source.readInt(); + if (source.readInt() != 0) { + mFileDescriptor = ParcelFileDescriptor.CREATOR.createFromParcel(source); + } else { + mFileDescriptor = null; + } mStartTime = source.readLong(); mStopTime = source.readLong(); mEchoInterval = source.readLong(); @@ -84,34 +99,77 @@ public final class AdRequest implements Parcelable { mMetadata = source.readBundle(); } + /** + * Gets the ID of AD request. + */ public int getId() { return mId; } - public @RequestType String getRequestType() { + /** + * Gets the request type. + */ + @RequestType + public int getRequestType() { return mRequestType; } + /** + * Gets the file descriptor of the AD media. + * + * @return The file descriptor of the AD media. Can be {@code null} for + * {@link #REQUEST_TYPE_STOP} + */ + @Nullable public ParcelFileDescriptor getFileDescriptor() { return mFileDescriptor; } - public long getStartTime() { + /** + * Gets the start time of the AD media in milliseconds. + *

0 means start immediately + */ + public long getStartTimeMillis() { return mStartTime; } - public long getStopTime() { + /** + * Gets the stop time of the AD media in milliseconds. + *

-1 means until the end + */ + public long getStopTimeMillis() { return mStopTime; } - public long getEchoInterval() { + /** + * Gets the echo interval in milliseconds. + *

The interval TV input needs to echo and inform TV interactive app service the video + * playback elapsed time. + * + * @see android.media.tv.AdResponse + */ + public long getEchoIntervalMillis() { return mEchoInterval; } + /** + * Gets the media file type such as mp4, mob, avi. + * + * @return The media file type. Can be {@code null} for {@link #REQUEST_TYPE_STOP}. + */ + @Nullable public String getMediaFileType() { return mMediaFileType; } + /** + * Gets the metadata of the media file. + *

This includes additional information the TV input needs to play the AD media. + * + * @return The metadata of the media file. Can be an empty bundle for + * {@link #REQUEST_TYPE_STOP}. + */ + @NonNull public Bundle getMetadata() { return mMetadata; } @@ -124,8 +182,13 @@ public final class AdRequest implements Parcelable { @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(mId); - dest.writeString(mRequestType); - mFileDescriptor.writeToParcel(dest, flags); + dest.writeInt(mRequestType); + if (mFileDescriptor != null) { + dest.writeInt(1); + mFileDescriptor.writeToParcel(dest, flags); + } else { + dest.writeInt(0); + } dest.writeLong(mStartTime); dest.writeLong(mStopTime); dest.writeLong(mEchoInterval); diff --git a/media/java/android/media/tv/AdResponse.java b/media/java/android/media/tv/AdResponse.java index 28cf5ac5b2b2b..5dba82cd7aeb0 100644 --- a/media/java/android/media/tv/AdResponse.java +++ b/media/java/android/media/tv/AdResponse.java @@ -16,19 +16,22 @@ package android.media.tv; +import android.annotation.IntDef; import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.StringDef; import android.os.Parcel; import android.os.Parcelable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -/** @hide */ +/** + * An advertisement request which can be sent to TV interactive App service to inform AD status. + * @hide + */ public final class AdResponse implements Parcelable { + /** @hide */ @Retention(RetentionPolicy.SOURCE) - @StringDef(prefix = "RESPONSE_TYPE_", value = { + @IntDef(prefix = "RESPONSE_TYPE_", value = { RESPONSE_TYPE_PLAYING, RESPONSE_TYPE_FINISHED, RESPONSE_TYPE_STOPPED, @@ -36,10 +39,10 @@ public final class AdResponse implements Parcelable { }) public @interface ResponseType {} - public static final String RESPONSE_TYPE_PLAYING = "PLAYING"; - public static final String RESPONSE_TYPE_FINISHED = "FINISHED"; - public static final String RESPONSE_TYPE_STOPPED = "STOPPED"; - public static final String RESPONSE_TYPE_ERROR = "ERROR"; + public static final int RESPONSE_TYPE_PLAYING = 1; + public static final int RESPONSE_TYPE_FINISHED = 2; + public static final int RESPONSE_TYPE_STOPPED = 3; + public static final int RESPONSE_TYPE_ERROR = 4; public static final @NonNull Parcelable.Creator CREATOR = new Parcelable.Creator() { @@ -55,10 +58,10 @@ public final class AdResponse implements Parcelable { }; private final int mId; - private final @ResponseType String mResponseType; - private final Long mElapsedTime; + private final @ResponseType int mResponseType; + private final long mElapsedTime; - public AdResponse(int id, @ResponseType String responseType, @Nullable Long elapsedTime) { + public AdResponse(int id, @ResponseType int responseType, long elapsedTime) { mId = id; mResponseType = responseType; mElapsedTime = elapsedTime; @@ -66,19 +69,31 @@ public final class AdResponse implements Parcelable { private AdResponse(Parcel source) { mId = source.readInt(); - mResponseType = source.readString(); - mElapsedTime = (Long) source.readValue(Long.class.getClassLoader()); + mResponseType = source.readInt(); + mElapsedTime = source.readLong(); } + /** + * Gets the ID of AD response. + */ public int getId() { return mId; } - public @ResponseType String getResponseType() { + /** + * Gets the response type. + */ + @ResponseType + public int getResponseType() { return mResponseType; } - public Long getElapsedTime() { + /** + * Gets the playback elapsed time in milliseconds. + * + * @return The playback elapsed time. -1 if no valid elapsed time. + */ + public long getElapsedTimeMillis() { return mElapsedTime; } @@ -90,7 +105,7 @@ public final class AdResponse implements Parcelable { @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(mId); - dest.writeString(mResponseType); - dest.writeValue(mElapsedTime); + dest.writeInt(mResponseType); + dest.writeLong(mElapsedTime); } } diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java index 1a9cab01f902f..98d4182eb97ca 100755 --- a/media/java/android/media/tv/TvInputService.java +++ b/media/java/android/media/tv/TvInputService.java @@ -895,6 +895,7 @@ public abstract class TvInputService extends Service { * Notifies response for advertisement. * * @param response advertisement response. + * @see android.media.tv.interactive.TvInteractiveAppService.Session#requestAd(AdRequest) * @hide */ public void notifyAdResponse(@NonNull final AdResponse response) { @@ -1124,9 +1125,9 @@ public abstract class TvInputService extends Service { } /** - * called when advertisement is requested. + * Called when advertisement request is received. * - * @param request advertisement request + * @param request advertisement request received * @hide */ public void onRequestAd(@NonNull AdRequest request) { diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppManager.java b/media/java/android/media/tv/interactive/TvInteractiveAppManager.java index c5dfaa2470995..f1f0af1a2cc9a 100755 --- a/media/java/android/media/tv/interactive/TvInteractiveAppManager.java +++ b/media/java/android/media/tv/interactive/TvInteractiveAppManager.java @@ -28,6 +28,7 @@ import android.media.tv.AdResponse; import android.media.tv.BroadcastInfoRequest; import android.media.tv.BroadcastInfoResponse; import android.media.tv.TvContentRating; +import android.media.tv.TvInputInfo; import android.media.tv.TvInputManager; import android.media.tv.TvTrackInfo; import android.net.Uri; @@ -768,9 +769,13 @@ public final class TvInteractiveAppManager { /** * Sends app link command. + * + * @param tvIAppServiceId The ID of TV interactive service which the command to be sent to. The + * ID can be found in {@link TvInputInfo#getId()}. + * @param command The command to be sent. * @hide */ - public void sendAppLinkCommand(String tvIAppServiceId, Bundle command) { + public void sendAppLinkCommand(@NonNull String tvIAppServiceId, @NonNull Bundle command) { try { mService.sendAppLinkCommand(tvIAppServiceId, command, mUserId); } catch (RemoteException e) { diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppService.java b/media/java/android/media/tv/interactive/TvInteractiveAppService.java index afa1ff7a36413..4716bed903cee 100755 --- a/media/java/android/media/tv/interactive/TvInteractiveAppService.java +++ b/media/java/android/media/tv/interactive/TvInteractiveAppService.java @@ -223,11 +223,12 @@ public abstract class TvInteractiveAppService extends Service { } /** - * Sends App link info. + * Called when app link command is received. + * + * @see android.media.tv.interactive.TvInteractiveAppManager#sendAppLinkCommand(String, Bundle) * @hide */ - public void onAppLinkCommand(Bundle command) { - // TODO: make it abstract when unhide + public void onAppLinkCommand(@NonNull Bundle command) { } @@ -551,7 +552,7 @@ public abstract class TvInteractiveAppService extends Service { * Called when an advertisement response is received. * @hide */ - public void onAdResponse(AdResponse response) { + public void onAdResponse(@NonNull AdResponse response) { } /** @@ -859,8 +860,9 @@ public abstract class TvInteractiveAppService extends Service { } /** - * requests an advertisement request to be processed by the related TV input. - * @param request advertisement request + * Sends an advertisement request to be processed by the related TV input. + * + * @param request The advertisement request * @hide */ public void requestAd(@NonNull final AdRequest request) { diff --git a/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java b/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java index b3649a75ee5b7..28ca26cb6921b 100644 --- a/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java +++ b/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java @@ -788,10 +788,12 @@ public class TvInteractiveAppManagerService extends SystemService { componentName, tiasId, resolvedUserId); serviceState.addPendingAppLinkCommand(command); userState.mServiceStateMap.put(componentName, serviceState); + updateServiceConnectionLocked(componentName, resolvedUserId); } else if (serviceState.mService != null) { serviceState.mService.sendAppLinkCommand(command); } else { serviceState.addPendingAppLinkCommand(command); + updateServiceConnectionLocked(componentName, resolvedUserId); } } } catch (RemoteException e) { @@ -1673,7 +1675,8 @@ public class TvInteractiveAppManagerService extends SystemService { boolean shouldBind = (!serviceState.mSessionTokens.isEmpty()) || (serviceState.mPendingPrepare) - || (!serviceState.mPendingAppLinkInfo.isEmpty()); + || (!serviceState.mPendingAppLinkInfo.isEmpty()) + || (!serviceState.mPendingAppLinkCommand.isEmpty()); if (serviceState.mService == null && shouldBind) { // This means that the service is not yet connected but its state indicates that we