diff options
9 files changed, 172 insertions, 2 deletions
diff --git a/media/java/android/media/tv/interactive/ITvInteractiveAppClient.aidl b/media/java/android/media/tv/interactive/ITvInteractiveAppClient.aidl index e3dba03d6093..7b5853169923 100644 --- a/media/java/android/media/tv/interactive/ITvInteractiveAppClient.aidl +++ b/media/java/android/media/tv/interactive/ITvInteractiveAppClient.aidl @@ -61,7 +61,8 @@ oneway interface ITvInteractiveAppClient { void onSetTvRecordingInfo(in String recordingId, in TvRecordingInfo recordingInfo, int seq); void onRequestTvRecordingInfo(in String recordingId, int seq); void onRequestTvRecordingInfoList(in int type, int seq); - void onRequestSigning( - in String id, in String algorithm, in String alias, in byte[] data, int seq); + void onRequestSigning(in String id, in String algorithm, in String alias, in byte[] data, + int seq); + void onRequestCertificate(in String host, int port, int seq); void onAdRequest(in AdRequest request, int Seq); } diff --git a/media/java/android/media/tv/interactive/ITvInteractiveAppManager.aidl b/media/java/android/media/tv/interactive/ITvInteractiveAppManager.aidl index 0f58b29247bb..1b9450b240ac 100644 --- a/media/java/android/media/tv/interactive/ITvInteractiveAppManager.aidl +++ b/media/java/android/media/tv/interactive/ITvInteractiveAppManager.aidl @@ -58,6 +58,8 @@ interface ITvInteractiveAppManager { void sendAvailableSpeeds(in IBinder sessionToken, in float[] speeds, int userId); void sendSigningResult(in IBinder sessionToken, in String signingId, in byte[] result, int userId); + void sendCertificate(in IBinder sessionToken, in String host, int port, + in Bundle certBundle, int userId); void sendTvRecordingInfo(in IBinder sessionToken, in TvRecordingInfo recordingInfo, int userId); void sendTvRecordingInfoList(in IBinder sessionToken, in List<TvRecordingInfo> recordingInfoList, int userId); diff --git a/media/java/android/media/tv/interactive/ITvInteractiveAppSession.aidl b/media/java/android/media/tv/interactive/ITvInteractiveAppSession.aidl index 06808c9ff915..3969315ab655 100644 --- a/media/java/android/media/tv/interactive/ITvInteractiveAppSession.aidl +++ b/media/java/android/media/tv/interactive/ITvInteractiveAppSession.aidl @@ -49,6 +49,7 @@ oneway interface ITvInteractiveAppSession { void sendTimeShiftMode(int mode); void sendAvailableSpeeds(in float[] speeds); void sendSigningResult(in String signingId, in byte[] result); + void sendCertificate(in String host, int port, in Bundle certBundle); void sendTvRecordingInfo(in TvRecordingInfo recordingInfo); void sendTvRecordingInfoList(in List<TvRecordingInfo> recordingInfoList); void notifyError(in String errMsg, in Bundle params); diff --git a/media/java/android/media/tv/interactive/ITvInteractiveAppSessionCallback.aidl b/media/java/android/media/tv/interactive/ITvInteractiveAppSessionCallback.aidl index 416b8f12d5ea..cb89181fd714 100644 --- a/media/java/android/media/tv/interactive/ITvInteractiveAppSessionCallback.aidl +++ b/media/java/android/media/tv/interactive/ITvInteractiveAppSessionCallback.aidl @@ -61,5 +61,6 @@ oneway interface ITvInteractiveAppSessionCallback { void onRequestTvRecordingInfo(in String recordingId); void onRequestTvRecordingInfoList(in int type); void onRequestSigning(in String id, in String algorithm, in String alias, in byte[] data); + void onRequestCertificate(in String host, int port); void onAdRequest(in AdRequest request); } diff --git a/media/java/android/media/tv/interactive/ITvInteractiveAppSessionWrapper.java b/media/java/android/media/tv/interactive/ITvInteractiveAppSessionWrapper.java index 77730aa46d0a..ec6c2bfab576 100644 --- a/media/java/android/media/tv/interactive/ITvInteractiveAppSessionWrapper.java +++ b/media/java/android/media/tv/interactive/ITvInteractiveAppSessionWrapper.java @@ -104,6 +104,7 @@ public class ITvInteractiveAppSessionWrapper private static final int DO_SEND_AVAILABLE_SPEEDS = 47; private static final int DO_SEND_SELECTED_TRACK_INFO = 48; private static final int DO_NOTIFY_VIDEO_FREEZE_UPDATED = 49; + private static final int DO_SEND_CERTIFICATE = 50; private final HandlerCaller mCaller; private Session mSessionImpl; @@ -369,6 +370,13 @@ public class ITvInteractiveAppSessionWrapper mSessionImpl.notifyVideoFreezeUpdated((Boolean) msg.obj); break; } + case DO_SEND_CERTIFICATE: { + SomeArgs args = (SomeArgs) msg.obj; + mSessionImpl.sendCertificate((String) args.arg1, (Integer) args.arg2, + (Bundle) args.arg3); + args.recycle(); + break; + } default: { Log.w(TAG, "Unhandled message code: " + msg.what); break; @@ -483,6 +491,12 @@ public class ITvInteractiveAppSessionWrapper } @Override + public void sendCertificate(@NonNull String host, int port, @NonNull Bundle certBundle) { + mCaller.executeOrSendMessage( + mCaller.obtainMessageOOO(DO_SEND_CERTIFICATE, host, port, certBundle)); + } + + @Override public void notifyError(@NonNull String errMsg, @NonNull Bundle params) { mCaller.executeOrSendMessage( mCaller.obtainMessageOO(DO_NOTIFY_ERROR, errMsg, params)); diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppManager.java b/media/java/android/media/tv/interactive/TvInteractiveAppManager.java index 8a340f6862bb..011744f94edb 100755 --- a/media/java/android/media/tv/interactive/TvInteractiveAppManager.java +++ b/media/java/android/media/tv/interactive/TvInteractiveAppManager.java @@ -34,6 +34,7 @@ import android.media.tv.TvInputManager; import android.media.tv.TvRecordingInfo; import android.media.tv.TvTrackInfo; import android.net.Uri; +import android.net.http.SslCertificate; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; @@ -656,6 +657,18 @@ public final class TvInteractiveAppManager { } @Override + public void onRequestCertificate(String host, int port, int seq) { + synchronized (mSessionCallbackRecordMap) { + SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); + if (record == null) { + Log.e(TAG, "Callback not found for seq " + seq); + return; + } + record.postRequestCertificate(host, port); + } + } + + @Override public void onSessionStateChanged(int state, int err, int seq) { synchronized (mSessionCallbackRecordMap) { SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); @@ -1328,6 +1341,19 @@ public final class TvInteractiveAppManager { } } + void sendCertificate(@NonNull String host, int port, @NonNull SslCertificate cert) { + if (mToken == null) { + Log.w(TAG, "The session has been already released"); + return; + } + try { + mService.sendCertificate(mToken, host, port, SslCertificate.saveState(cert), + mUserId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + void notifyError(@NonNull String errMsg, @NonNull Bundle params) { if (mToken == null) { Log.w(TAG, "The session has been already released"); @@ -2232,6 +2258,15 @@ public final class TvInteractiveAppManager { }); } + void postRequestCertificate(String host, int port) { + mHandler.post(new Runnable() { + @Override + public void run() { + mSessionCallback.onRequestCertificate(mSession, host, port); + } + }); + } + void postRequestTvRecordingInfo(String recordingId) { mHandler.post(new Runnable() { @Override @@ -2574,6 +2609,17 @@ public final class TvInteractiveAppManager { } /** + * This is called when the service requests a SSL certificate for client validation. + * + * @param session A {@link TvInteractiveAppService.Session} associated with this callback. + * @param host the host name of the SSL authentication server. + * @param port the port of the SSL authentication server. E.g., 443 + * @hide + */ + public void onRequestCertificate(Session session, String host, int port) { + } + + /** * This is called when {@link TvInteractiveAppService.Session#notifySessionStateChanged} is * called. * diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppService.java b/media/java/android/media/tv/interactive/TvInteractiveAppService.java index 5247a0ebe6e0..054b272d820f 100755 --- a/media/java/android/media/tv/interactive/TvInteractiveAppService.java +++ b/media/java/android/media/tv/interactive/TvInteractiveAppService.java @@ -46,6 +46,7 @@ import android.media.tv.TvTrackInfo; import android.media.tv.TvView; import android.media.tv.interactive.TvInteractiveAppView.TvInteractiveAppCallback; import android.net.Uri; +import android.net.http.SslCertificate; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; @@ -734,6 +735,17 @@ public abstract class TvInteractiveAppService extends Service { } /** + * Receives the requested Certificate + * + * @param host the host name of the SSL authentication server. + * @param port the port of the SSL authentication server. E.g., 443 + * @param cert the SSL certificate received. + * @hide + */ + public void onCertificate(@NonNull String host, int port, @NonNull SslCertificate cert) { + } + + /** * Called when the application sends information of an error. * * @param errMsg the message of the error. @@ -1633,6 +1645,32 @@ public abstract class TvInteractiveAppService extends Service { } /** + * Requests a SSL certificate for client validation. + * + * @param host the host name of the SSL authentication server. + * @param port the port of the SSL authentication server. E.g., 443 + * @hide + */ + public void requestCertificate(@NonNull String host, int port) { + executeOrPostRunnableOnMainThread(new Runnable() { + @MainThread + @Override + public void run() { + try { + if (DEBUG) { + Log.d(TAG, "requestCertificate"); + } + if (mSessionCallback != null) { + mSessionCallback.onRequestCertificate(host, port); + } + } catch (RemoteException e) { + Log.w(TAG, "error in requestCertificate", e); + } + } + }); + } + + /** * Sends an advertisement request to be processed by the related TV input. * * @param request The advertisement request @@ -1725,6 +1763,11 @@ public abstract class TvInteractiveAppService extends Service { onSigningResult(signingId, result); } + void sendCertificate(String host, int port, Bundle certBundle) { + SslCertificate cert = SslCertificate.restoreState(certBundle); + onCertificate(host, port, cert); + } + void notifyError(String errMsg, Bundle params) { onError(errMsg, params); } diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppView.java b/media/java/android/media/tv/interactive/TvInteractiveAppView.java index 5bb61c261ae2..3b295742c244 100755 --- a/media/java/android/media/tv/interactive/TvInteractiveAppView.java +++ b/media/java/android/media/tv/interactive/TvInteractiveAppView.java @@ -34,6 +34,7 @@ import android.media.tv.interactive.TvInteractiveAppManager.Session; import android.media.tv.interactive.TvInteractiveAppManager.Session.FinishedInputEventCallback; import android.media.tv.interactive.TvInteractiveAppManager.SessionCallback; import android.net.Uri; +import android.net.http.SslCertificate; import android.os.Bundle; import android.os.Handler; import android.util.AttributeSet; @@ -756,6 +757,22 @@ public class TvInteractiveAppView extends ViewGroup { } /** + * Send the requested SSL certificate to the TV Interactive App + * @param host the host name of the SSL authentication server. + * @param port the port of the SSL authentication server. E.g., 443 + * @param cert the SSL certificate requested + * @hide + */ + public void sendCertificate(@NonNull String host, int port, @NonNull SslCertificate cert) { + if (DEBUG) { + Log.d(TAG, "sendCertificate"); + } + if (mSession != null) { + mSession.sendCertificate(host, port, cert); + } + } + + /** * Notifies the corresponding {@link TvInteractiveAppService} when there is an error. * * @param errMsg the message of the error. 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 d7b8495929a2..b6d0ca19d484 100644 --- a/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java +++ b/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java @@ -2390,6 +2390,33 @@ public class TvInteractiveAppManagerService extends SystemService { } @Override + public void sendCertificate(IBinder sessionToken, String host, int port, + Bundle certBundle, int userId) { + if (DEBUG) { + Slogf.d(TAG, "sendCertificate(host=%s port=%d cert=%s)", host, port, + certBundle); + } + final int callingUid = Binder.getCallingUid(); + final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid, + userId, "sendCertificate"); + SessionState sessionState = null; + final long identity = Binder.clearCallingIdentity(); + try { + synchronized (mLock) { + try { + sessionState = getSessionStateLocked(sessionToken, callingUid, + resolvedUserId); + getSessionLocked(sessionState).sendCertificate(host, port, certBundle); + } catch (RemoteException | SessionNotFoundException e) { + Slogf.e(TAG, "error in sendCertificate", e); + } + } + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override public void notifyError(IBinder sessionToken, String errMsg, Bundle params, int userId) { if (DEBUG) { Slogf.d(TAG, "notifyError(errMsg=%s)", errMsg); @@ -4125,6 +4152,24 @@ public class TvInteractiveAppManagerService extends SystemService { } @Override + public void onRequestCertificate(String host, int port) { + synchronized (mLock) { + if (DEBUG) { + Slogf.d(TAG, "onRequestCertificate"); + } + if (mSessionState.mSession == null || mSessionState.mClient == null) { + return; + } + try { + mSessionState.mClient.onRequestCertificate(host, port, mSessionState.mSeq); + } catch (RemoteException e) { + Slogf.e(TAG, "error in onRequestCertificate", e); + } + } + } + + + @Override public void onAdRequest(AdRequest request) { synchronized (mLock) { if (DEBUG) { |