TIAF: Ad flow
Bug: 211927650 Change-Id: I5d0fe1ce31f5fe56581ecba25c170b3288ed70e6
This commit is contained in:
19
media/java/android/media/tv/AdRequest.aidl
Normal file
19
media/java/android/media/tv/AdRequest.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.media.tv;
|
||||
|
||||
parcelable AdRequest;
|
||||
135
media/java/android/media/tv/AdRequest.java
Normal file
135
media/java/android/media/tv/AdRequest.java
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.media.tv;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.StringDef;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/** @hide */
|
||||
public final class AdRequest implements Parcelable {
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@StringDef(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";
|
||||
|
||||
public static final @NonNull Parcelable.Creator<AdRequest> CREATOR =
|
||||
new Parcelable.Creator<AdRequest>() {
|
||||
@Override
|
||||
public AdRequest createFromParcel(Parcel source) {
|
||||
return new AdRequest(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AdRequest[] newArray(int size) {
|
||||
return new AdRequest[size];
|
||||
}
|
||||
};
|
||||
|
||||
private final int mId;
|
||||
private final @RequestType String mRequestType;
|
||||
private final ParcelFileDescriptor mFileDescriptor;
|
||||
private final long mStartTime;
|
||||
private final long mStopTime;
|
||||
private final long mEchoInterval;
|
||||
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) {
|
||||
mId = id;
|
||||
mRequestType = requestType;
|
||||
mFileDescriptor = fileDescriptor;
|
||||
mStartTime = startTime;
|
||||
mStopTime = stopTime;
|
||||
mEchoInterval = echoInterval;
|
||||
mMediaFileType = mediaFileType;
|
||||
mMetadata = metadata;
|
||||
}
|
||||
|
||||
private AdRequest(Parcel source) {
|
||||
mId = source.readInt();
|
||||
mRequestType = source.readString();
|
||||
mFileDescriptor = source.readFileDescriptor();
|
||||
mStartTime = source.readLong();
|
||||
mStopTime = source.readLong();
|
||||
mEchoInterval = source.readLong();
|
||||
mMediaFileType = source.readString();
|
||||
mMetadata = source.readBundle();
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return mId;
|
||||
}
|
||||
|
||||
public @RequestType String getRequestType() {
|
||||
return mRequestType;
|
||||
}
|
||||
|
||||
public ParcelFileDescriptor getFileDescriptor() {
|
||||
return mFileDescriptor;
|
||||
}
|
||||
|
||||
public long getStartTime() {
|
||||
return mStartTime;
|
||||
}
|
||||
|
||||
public long getStopTime() {
|
||||
return mStopTime;
|
||||
}
|
||||
|
||||
public long getEchoInterval() {
|
||||
return mEchoInterval;
|
||||
}
|
||||
|
||||
public String getMediaFileType() {
|
||||
return mMediaFileType;
|
||||
}
|
||||
|
||||
public Bundle getMetadata() {
|
||||
return mMetadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeInt(mId);
|
||||
dest.writeString(mRequestType);
|
||||
mFileDescriptor.writeToParcel(dest, flags);
|
||||
dest.writeLong(mStartTime);
|
||||
dest.writeLong(mStopTime);
|
||||
dest.writeLong(mEchoInterval);
|
||||
dest.writeString(mMediaFileType);
|
||||
dest.writeBundle(mMetadata);
|
||||
}
|
||||
}
|
||||
19
media/java/android/media/tv/AdResponse.aidl
Normal file
19
media/java/android/media/tv/AdResponse.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.media.tv;
|
||||
|
||||
parcelable AdResponse;
|
||||
96
media/java/android/media/tv/AdResponse.java
Normal file
96
media/java/android/media/tv/AdResponse.java
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.media.tv;
|
||||
|
||||
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 */
|
||||
public final class AdResponse implements Parcelable {
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@StringDef(prefix = "RESPONSE_TYPE_", value = {
|
||||
RESPONSE_TYPE_PLAYING,
|
||||
RESPONSE_TYPE_FINISHED,
|
||||
RESPONSE_TYPE_STOPPED,
|
||||
RESPONSE_TYPE_ERROR
|
||||
})
|
||||
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 @NonNull Parcelable.Creator<AdResponse> CREATOR =
|
||||
new Parcelable.Creator<AdResponse>() {
|
||||
@Override
|
||||
public AdResponse createFromParcel(Parcel source) {
|
||||
return new AdResponse(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AdResponse[] newArray(int size) {
|
||||
return new AdResponse[size];
|
||||
}
|
||||
};
|
||||
|
||||
private final int mId;
|
||||
private final @ResponseType String mResponseType;
|
||||
private final Long mElapsedTime;
|
||||
|
||||
public AdResponse(int id, @ResponseType String responseType, @Nullable Long elapsedTime) {
|
||||
mId = id;
|
||||
mResponseType = responseType;
|
||||
mElapsedTime = elapsedTime;
|
||||
}
|
||||
|
||||
private AdResponse(Parcel source) {
|
||||
mId = source.readInt();
|
||||
mResponseType = source.readString();
|
||||
mElapsedTime = (Long) source.readValue(Long.class.getClassLoader());
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return mId;
|
||||
}
|
||||
|
||||
public @ResponseType String getResponseType() {
|
||||
return mResponseType;
|
||||
}
|
||||
|
||||
public Long getElapsedTime() {
|
||||
return mElapsedTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeInt(mId);
|
||||
dest.writeString(mResponseType);
|
||||
dest.writeValue(mElapsedTime);
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@
|
||||
package android.media.tv;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.media.tv.AdResponse;
|
||||
import android.media.tv.AitInfo;
|
||||
import android.media.tv.BroadcastInfoResponse;
|
||||
import android.media.tv.ITvInputSession;
|
||||
@@ -54,4 +55,7 @@ oneway interface ITvInputClient {
|
||||
|
||||
// For broadcast info
|
||||
void onBroadcastInfoResponse(in BroadcastInfoResponse response, int seq);
|
||||
|
||||
// For ad response
|
||||
void onAdResponse(in AdResponse response, int seq);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Rect;
|
||||
import android.media.PlaybackParams;
|
||||
import android.media.tv.AdRequest;
|
||||
import android.media.tv.BroadcastInfoRequest;
|
||||
import android.media.tv.DvbDeviceInfo;
|
||||
import android.media.tv.ITvInputClient;
|
||||
@@ -106,6 +107,9 @@ interface ITvInputManager {
|
||||
void requestBroadcastInfo(in IBinder sessionToken, in BroadcastInfoRequest request, int userId);
|
||||
void removeBroadcastInfo(in IBinder sessionToken, int id, int userId);
|
||||
|
||||
// For ad request
|
||||
void requestAd(in IBinder sessionToken, in AdRequest request, int userId);
|
||||
|
||||
// For TV input hardware binding
|
||||
List<TvInputHardwareInfo> getHardwareList();
|
||||
ITvInputHardware acquireTvInputHardware(int deviceId, in ITvInputHardwareCallback callback,
|
||||
|
||||
@@ -18,6 +18,7 @@ package android.media.tv;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.media.PlaybackParams;
|
||||
import android.media.tv.AdRequest;
|
||||
import android.media.tv.BroadcastInfoRequest;
|
||||
import android.media.tv.TvTrackInfo;
|
||||
import android.net.Uri;
|
||||
@@ -67,4 +68,7 @@ oneway interface ITvInputSession {
|
||||
// For broadcast info
|
||||
void requestBroadcastInfo(in BroadcastInfoRequest request);
|
||||
void removeBroadcastInfo(int id);
|
||||
|
||||
// For ad request
|
||||
void requestAd(in AdRequest request);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package android.media.tv;
|
||||
|
||||
import android.media.tv.AdResponse;
|
||||
import android.media.tv.AitInfo;
|
||||
import android.media.tv.BroadcastInfoResponse;
|
||||
import android.media.tv.ITvInputSession;
|
||||
@@ -51,4 +52,7 @@ oneway interface ITvInputSessionCallback {
|
||||
|
||||
// For broadcast info
|
||||
void onBroadcastInfoResponse(in BroadcastInfoResponse response);
|
||||
|
||||
// For ad response
|
||||
void onAdResponse(in AdResponse response);
|
||||
}
|
||||
|
||||
@@ -73,6 +73,7 @@ public class ITvInputSessionWrapper extends ITvInputSession.Stub implements Hand
|
||||
private static final int DO_REQUEST_BROADCAST_INFO = 24;
|
||||
private static final int DO_REMOVE_BROADCAST_INFO = 25;
|
||||
private static final int DO_SET_IAPP_NOTIFICATION_ENABLED = 26;
|
||||
private static final int DO_REQUEST_AD = 27;
|
||||
|
||||
private final boolean mIsRecordingSession;
|
||||
private final HandlerCaller mCaller;
|
||||
@@ -249,6 +250,10 @@ public class ITvInputSessionWrapper extends ITvInputSession.Stub implements Hand
|
||||
mTvInputSessionImpl.setIAppNotificationEnabled((Boolean) msg.obj);
|
||||
break;
|
||||
}
|
||||
case DO_REQUEST_AD: {
|
||||
mTvInputSessionImpl.requestAd((AdRequest) msg.obj);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
Log.w(TAG, "Unhandled message code: " + msg.what);
|
||||
break;
|
||||
@@ -414,6 +419,11 @@ public class ITvInputSessionWrapper extends ITvInputSession.Stub implements Hand
|
||||
mCaller.executeOrSendMessage(mCaller.obtainMessageI(DO_REMOVE_BROADCAST_INFO, requestId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestAd(AdRequest request) {
|
||||
mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_REQUEST_AD, request));
|
||||
}
|
||||
|
||||
private final class TvInputEventReceiver extends InputEventReceiver {
|
||||
public TvInputEventReceiver(InputChannel inputChannel, Looper looper) {
|
||||
super(inputChannel, looper);
|
||||
|
||||
@@ -894,6 +894,19 @@ public final class TvInputManager {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void postAdResponse(final AdResponse response) {
|
||||
if (mSession.mIAppNotificationEnabled) {
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mSession.getIAppSession() != null) {
|
||||
mSession.getIAppSession().notifyAdResponse(response);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1317,6 +1330,18 @@ public final class TvInputManager {
|
||||
record.postBroadcastInfoResponse(response);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAdResponse(AdResponse response, int seq) {
|
||||
synchronized (mSessionCallbackRecordMap) {
|
||||
SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
|
||||
if (record == null) {
|
||||
Log.e(TAG, "Callback not found for seq " + seq);
|
||||
return;
|
||||
}
|
||||
record.postAdResponse(response);
|
||||
}
|
||||
}
|
||||
};
|
||||
ITvInputManagerCallback managerCallback = new ITvInputManagerCallback.Stub() {
|
||||
@Override
|
||||
@@ -3033,6 +3058,18 @@ public final class TvInputManager {
|
||||
}
|
||||
}
|
||||
|
||||
public void requestAd(AdRequest request) {
|
||||
if (mToken == null) {
|
||||
Log.w(TAG, "The session has been already released");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mService.requestAd(mToken, request, mUserId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
private final class InputEventHandler extends Handler {
|
||||
public static final int MSG_SEND_INPUT_EVENT = 1;
|
||||
public static final int MSG_TIMEOUT_INPUT_EVENT = 2;
|
||||
|
||||
@@ -849,7 +849,7 @@ public abstract class TvInputService extends Service {
|
||||
/**
|
||||
* Notifies response for broadcast info.
|
||||
*
|
||||
* @param response
|
||||
* @param response broadcast info response.
|
||||
* @hide
|
||||
*/
|
||||
public void notifyBroadcastInfoResponse(@NonNull final BroadcastInfoResponse response) {
|
||||
@@ -869,6 +869,29 @@ public abstract class TvInputService extends Service {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies response for advertisement.
|
||||
*
|
||||
* @param response advertisement response.
|
||||
* @hide
|
||||
*/
|
||||
public void notifyAdResponse(@NonNull final AdResponse response) {
|
||||
executeOrPostRunnableOnMainThread(new Runnable() {
|
||||
@MainThread
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
if (DEBUG) Log.d(TAG, "notifyAdResponse");
|
||||
if (mSessionCallback != null) {
|
||||
mSessionCallback.onAdResponse(response);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "error in notifyAdResponse", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void notifyTimeShiftStartPositionChanged(final long timeMs) {
|
||||
executeOrPostRunnableOnMainThread(new Runnable() {
|
||||
@MainThread
|
||||
@@ -1038,6 +1061,8 @@ public abstract class TvInputService extends Service {
|
||||
public abstract void onSetStreamVolume(@FloatRange(from = 0.0, to = 1.0) float volume);
|
||||
|
||||
/**
|
||||
* called when broadcast info is requested.
|
||||
*
|
||||
* @param request broadcast info request
|
||||
* @hide
|
||||
*/
|
||||
@@ -1050,6 +1075,15 @@ public abstract class TvInputService extends Service {
|
||||
public void onRemoveBroadcastInfo(int requestId) {
|
||||
}
|
||||
|
||||
/**
|
||||
* called when advertisement is requested.
|
||||
*
|
||||
* @param request advertisement request
|
||||
* @hide
|
||||
*/
|
||||
public void onRequestAd(@NonNull AdRequest request) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Tunes to a given channel.
|
||||
*
|
||||
@@ -1663,6 +1697,10 @@ public abstract class TvInputService extends Service {
|
||||
onRemoveBroadcastInfo(requestId);
|
||||
}
|
||||
|
||||
void requestAd(AdRequest request) {
|
||||
onRequestAd(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes care of dispatching incoming input events and tells whether the event was handled.
|
||||
*/
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package android.media.tv.interactive;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.media.tv.AdRequest;
|
||||
import android.media.tv.BroadcastInfoRequest;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
@@ -41,4 +42,5 @@ oneway interface ITvIAppClient {
|
||||
void onRequestCurrentChannelLcn(int seq);
|
||||
void onRequestStreamVolume(int seq);
|
||||
void onRequestTrackInfoList(int seq);
|
||||
void onAdRequest(in AdRequest request, int Seq);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package android.media.tv.interactive;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.media.tv.AdResponse;
|
||||
import android.media.tv.BroadcastInfoResponse;
|
||||
import android.media.tv.TvTrackInfo;
|
||||
import android.media.tv.interactive.ITvIAppClient;
|
||||
@@ -55,6 +56,7 @@ interface ITvIAppManager {
|
||||
int userId);
|
||||
void notifyBroadcastInfoResponse(in IBinder sessionToken, in BroadcastInfoResponse response,
|
||||
int UserId);
|
||||
void notifyAdResponse(in IBinder sessionToken, in AdResponse response, int UserId);
|
||||
|
||||
void createMediaView(in IBinder sessionToken, in IBinder windowToken, in Rect frame,
|
||||
int userId);
|
||||
@@ -63,4 +65,4 @@ interface ITvIAppManager {
|
||||
|
||||
void registerCallback(in ITvIAppManagerCallback callback, int userId);
|
||||
void unregisterCallback(in ITvIAppManagerCallback callback, int userId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package android.media.tv.interactive;
|
||||
import android.graphics.Rect;
|
||||
import android.media.tv.BroadcastInfoResponse;
|
||||
import android.net.Uri;
|
||||
import android.media.tv.AdResponse;
|
||||
import android.media.tv.BroadcastInfoResponse;
|
||||
import android.media.tv.TvTrackInfo;
|
||||
import android.os.Bundle;
|
||||
@@ -44,8 +45,9 @@ oneway interface ITvIAppSession {
|
||||
void setSurface(in Surface surface);
|
||||
void dispatchSurfaceChanged(int format, int width, int height);
|
||||
void notifyBroadcastInfoResponse(in BroadcastInfoResponse response);
|
||||
void notifyAdResponse(in AdResponse response);
|
||||
|
||||
void createMediaView(in IBinder windowToken, in Rect frame);
|
||||
void relayoutMediaView(in Rect frame);
|
||||
void removeMediaView();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
package android.media.tv.interactive;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.media.tv.AdRequest;
|
||||
import android.media.tv.BroadcastInfoRequest;
|
||||
import android.media.tv.interactive.ITvIAppSession;
|
||||
import android.media.tv.BroadcastInfoRequest;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
|
||||
@@ -41,4 +41,5 @@ oneway interface ITvIAppSessionCallback {
|
||||
void onRequestCurrentChannelLcn();
|
||||
void onRequestStreamVolume();
|
||||
void onRequestTrackInfoList();
|
||||
void onAdRequest(in AdRequest request);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@ import android.annotation.Nullable;
|
||||
import android.annotation.SystemService;
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.media.tv.AdRequest;
|
||||
import android.media.tv.AdResponse;
|
||||
import android.media.tv.BroadcastInfoRequest;
|
||||
import android.media.tv.BroadcastInfoResponse;
|
||||
import android.media.tv.TvInputManager;
|
||||
@@ -281,6 +283,18 @@ public final class TvIAppManager {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAdRequest(AdRequest request, int seq) {
|
||||
synchronized (mSessionCallbackRecordMap) {
|
||||
SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
|
||||
if (record == null) {
|
||||
Log.e(TAG, "Callback not found for seq " + seq);
|
||||
return;
|
||||
}
|
||||
record.postAdRequest(request);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestCurrentChannelUri(int seq) {
|
||||
synchronized (mSessionCallbackRecordMap) {
|
||||
@@ -944,6 +958,23 @@ public final class TvIAppManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies of any advertisement response passed in from TIS.
|
||||
*
|
||||
* @param response response passed in from TIS.
|
||||
*/
|
||||
public void notifyAdResponse(AdResponse response) {
|
||||
if (mToken == null) {
|
||||
Log.w(TAG, "The session has been already released");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mService.notifyAdResponse(mToken, response, mUserId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases this session.
|
||||
*/
|
||||
@@ -1322,6 +1353,17 @@ public final class TvIAppManager {
|
||||
});
|
||||
}
|
||||
|
||||
void postAdRequest(final AdRequest request) {
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mSession.getInputSession() != null) {
|
||||
mSession.getInputSession().requestAd(request);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void postSessionStateChanged(int state) {
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
|
||||
@@ -27,6 +27,8 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Rect;
|
||||
import android.media.tv.AdRequest;
|
||||
import android.media.tv.AdResponse;
|
||||
import android.media.tv.BroadcastInfoRequest;
|
||||
import android.media.tv.BroadcastInfoResponse;
|
||||
import android.media.tv.TvTrackInfo;
|
||||
@@ -433,6 +435,13 @@ public abstract class TvIAppService extends Service {
|
||||
public void onBroadcastInfoResponse(@NonNull BroadcastInfoResponse response) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an advertisement response is received.
|
||||
* @hide
|
||||
*/
|
||||
public void onAdResponse(AdResponse response) {
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: JavaDoc of APIs related to input events.
|
||||
* @hide
|
||||
@@ -703,6 +712,29 @@ public abstract class TvIAppService extends Service {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* requests an advertisement request to be processed by the related TV input.
|
||||
* @param request advertisement request
|
||||
*/
|
||||
public void requestAd(@NonNull final AdRequest request) {
|
||||
executeOrPostRunnableOnMainThread(new Runnable() {
|
||||
@MainThread
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "requestAd (id=" + request.getId() + ")");
|
||||
}
|
||||
if (mSessionCallback != null) {
|
||||
mSessionCallback.onAdRequest(request);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "error in requestAd", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void startIApp() {
|
||||
onStartIApp();
|
||||
}
|
||||
@@ -783,6 +815,16 @@ public abstract class TvIAppService extends Service {
|
||||
onBroadcastInfoResponse(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link #onAdResponse}.
|
||||
*/
|
||||
void notifyAdResponse(AdResponse response) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "notifyAdResponse (requestId=" + response.getId() + ")");
|
||||
}
|
||||
onAdResponse(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies when the session state is changed.
|
||||
* @param state the current state.
|
||||
@@ -1141,6 +1183,11 @@ public abstract class TvIAppService extends Service {
|
||||
mSessionImpl.notifyBroadcastInfoResponse(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyAdResponse(AdResponse response) {
|
||||
mSessionImpl.notifyAdResponse(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createMediaView(IBinder windowToken, Rect frame) {
|
||||
mSessionImpl.createMediaView(windowToken, frame);
|
||||
|
||||
@@ -44,6 +44,8 @@ import android.graphics.Rect;
|
||||
import android.hardware.hdmi.HdmiControlManager;
|
||||
import android.hardware.hdmi.HdmiDeviceInfo;
|
||||
import android.media.PlaybackParams;
|
||||
import android.media.tv.AdRequest;
|
||||
import android.media.tv.AdResponse;
|
||||
import android.media.tv.AitInfo;
|
||||
import android.media.tv.BroadcastInfoRequest;
|
||||
import android.media.tv.BroadcastInfoResponse;
|
||||
@@ -2493,6 +2495,28 @@ public final class TvInputManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestAd(IBinder sessionToken, AdRequest request, int userId) {
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
final int callingPid = Binder.getCallingPid();
|
||||
final int resolvedUserId = resolveCallingUserId(callingPid, callingUid,
|
||||
userId, "requestAd");
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (mLock) {
|
||||
try {
|
||||
SessionState sessionState = getSessionStateLocked(sessionToken, callingUid,
|
||||
resolvedUserId);
|
||||
getSessionLocked(sessionState).requestAd(request);
|
||||
} catch (RemoteException | SessionNotFoundException e) {
|
||||
Slog.e(TAG, "error in requestAd", e);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getClientPid(String sessionId) {
|
||||
ensureTunerResourceAccessPermission();
|
||||
@@ -3557,6 +3581,23 @@ public final class TvInputManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAdResponse (AdResponse response) {
|
||||
synchronized (mLock) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "onAdResponse()");
|
||||
}
|
||||
if (mSessionState.session == null || mSessionState.client == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mSessionState.client.onAdResponse(response, mSessionState.seq);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "error in onAdResponse", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
|
||||
@@ -29,6 +29,8 @@ import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.graphics.Rect;
|
||||
import android.media.tv.AdRequest;
|
||||
import android.media.tv.AdResponse;
|
||||
import android.media.tv.BroadcastInfoRequest;
|
||||
import android.media.tv.BroadcastInfoResponse;
|
||||
import android.media.tv.TvTrackInfo;
|
||||
@@ -1176,6 +1178,28 @@ public class TvIAppManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyAdResponse(IBinder sessionToken, AdResponse response, int userId) {
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
final int callingPid = Binder.getCallingPid();
|
||||
final int resolvedUserId = resolveCallingUserId(callingPid, callingUid, userId,
|
||||
"notifyAdResponse");
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (mLock) {
|
||||
try {
|
||||
SessionState sessionState = getSessionStateLocked(sessionToken, callingUid,
|
||||
resolvedUserId);
|
||||
getSessionLocked(sessionState).notifyAdResponse(response);
|
||||
} catch (RemoteException | SessionNotFoundException e) {
|
||||
Slogf.e(TAG, "error in notifyAdResponse", e);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerCallback(final ITvIAppManagerCallback callback, int userId) {
|
||||
int callingPid = Binder.getCallingPid();
|
||||
@@ -1906,6 +1930,23 @@ public class TvIAppManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAdRequest(AdRequest request) {
|
||||
synchronized (mLock) {
|
||||
if (DEBUG) {
|
||||
Slogf.d(TAG, "onAdRequest (id=" + request.getId() + ")");
|
||||
}
|
||||
if (mSessionState.mSession == null || mSessionState.mClient == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mSessionState.mClient.onAdRequest(request, mSessionState.mSeq);
|
||||
} catch (RemoteException e) {
|
||||
Slogf.e(TAG, "error in onAdRequest", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionStateChanged(int state) {
|
||||
synchronized (mLock) {
|
||||
|
||||
Reference in New Issue
Block a user