TIAF: Ad flow

Bug: 211927650
Change-Id: I5d0fe1ce31f5fe56581ecba25c170b3288ed70e6
This commit is contained in:
Yixiao Luo
2021-12-23 18:39:44 -08:00
parent 6489e997ac
commit 63e957a574
19 changed files with 552 additions and 4 deletions

View 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;

View 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);
}
}

View 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;

View 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);
}
}

View File

@@ -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);
}

View File

@@ -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,

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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.
*/

View File

@@ -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);
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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) {