TIAF: create & destroy BI IApp
Bug: 211886434 Test: mmm Change-Id: Ie2b4d1d34b57487318f18a6fcdda116a05f9547f
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package android.media.tv.interactive;
|
||||
|
||||
import android.media.tv.BroadcastInfoRequest;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.InputChannel;
|
||||
|
||||
@@ -31,5 +32,6 @@ oneway interface ITvIAppClient {
|
||||
void onLayoutSurface(int left, int top, int right, int bottom, int seq);
|
||||
void onBroadcastInfoRequest(in BroadcastInfoRequest request, int seq);
|
||||
void onSessionStateChanged(int state, int seq);
|
||||
void onBiInteractiveAppCreated(in Uri biIAppUri, in String biIAppId, int seq);
|
||||
void onCommandRequest(in String cmdType, in Bundle parameters, int seq);
|
||||
}
|
||||
|
||||
@@ -35,6 +35,9 @@ interface ITvIAppManager {
|
||||
void notifyAppLinkInfo(String tiasId, in Bundle info, int userId);
|
||||
void sendAppLinkCommand(String tiasId, in Bundle command, int userId);
|
||||
void startIApp(in IBinder sessionToken, int userId);
|
||||
void createBiInteractiveApp(
|
||||
in IBinder sessionToken, in Uri biIAppUri, in Bundle params, int userId);
|
||||
void destroyBiInteractiveApp(in IBinder sessionToken, in String biIAppId, int userId);
|
||||
void createSession(
|
||||
in ITvIAppClient client, in String iAppServiceId, int type, int seq, int userId);
|
||||
void releaseSession(in IBinder sessionToken, int userId);
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
package android.media.tv.interactive;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.media.tv.BroadcastInfoResponse;
|
||||
import android.net.Uri;
|
||||
import android.media.tv.BroadcastInfoResponse;
|
||||
import android.os.Bundle;
|
||||
import android.view.Surface;
|
||||
import android.media.tv.BroadcastInfoResponse;
|
||||
|
||||
/**
|
||||
* Sub-interface of ITvIAppService.aidl which is created per session and has its own context.
|
||||
@@ -28,6 +28,8 @@ import android.media.tv.BroadcastInfoResponse;
|
||||
*/
|
||||
oneway interface ITvIAppSession {
|
||||
void startIApp();
|
||||
void createBiInteractiveApp(in Uri biIAppUri, in Bundle params);
|
||||
void destroyBiInteractiveApp(in String biIAppId);
|
||||
void release();
|
||||
void notifyTuned(in Uri channelUri);
|
||||
void setSurface(in Surface surface);
|
||||
|
||||
@@ -19,6 +19,7 @@ package android.media.tv.interactive;
|
||||
import android.media.tv.BroadcastInfoRequest;
|
||||
import android.media.tv.interactive.ITvIAppSession;
|
||||
import android.media.tv.BroadcastInfoRequest;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
|
||||
/**
|
||||
@@ -31,5 +32,6 @@ oneway interface ITvIAppSessionCallback {
|
||||
void onLayoutSurface(int left, int top, int right, int bottom);
|
||||
void onBroadcastInfoRequest(in BroadcastInfoRequest request);
|
||||
void onSessionStateChanged(int state);
|
||||
void onBiInteractiveAppCreated(in Uri biIAppUri, in String biIAppId);
|
||||
void onCommandRequest(in String cmdType, in Bundle parameters);
|
||||
}
|
||||
|
||||
@@ -267,6 +267,18 @@ public final class TvIAppManager {
|
||||
record.postSessionStateChanged(state);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBiInteractiveAppCreated(Uri biIAppUri, String biIAppId, int seq) {
|
||||
synchronized (mSessionCallbackRecordMap) {
|
||||
SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
|
||||
if (record == null) {
|
||||
Log.e(TAG, "Callback not found for seq " + seq);
|
||||
return;
|
||||
}
|
||||
record.postBiInteractiveAppCreated(biIAppUri, biIAppId);
|
||||
}
|
||||
}
|
||||
};
|
||||
ITvIAppManagerCallback managerCallback = new ITvIAppManagerCallback.Stub() {
|
||||
@Override
|
||||
@@ -375,7 +387,6 @@ public final class TvIAppManager {
|
||||
public void onTvIAppInfoUpdated(TvIAppInfo iAppInfo) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is called when the state of the interactive app service is changed.
|
||||
* @hide
|
||||
@@ -622,6 +633,30 @@ public final class TvIAppManager {
|
||||
}
|
||||
}
|
||||
|
||||
void createBiInteractiveApp(Uri biIAppUri, Bundle params) {
|
||||
if (mToken == null) {
|
||||
Log.w(TAG, "The session has been already released");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mService.createBiInteractiveApp(mToken, biIAppUri, params, mUserId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
void destroyBiInteractiveApp(String biIAppId) {
|
||||
if (mToken == null) {
|
||||
Log.w(TAG, "The session has been already released");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mService.destroyBiInteractiveApp(mToken, biIAppId, mUserId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link android.view.Surface} for this session.
|
||||
*
|
||||
@@ -1077,6 +1112,15 @@ public final class TvIAppManager {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void postBiInteractiveAppCreated(Uri biIAppUri, String biIAppId) {
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mSessionCallback.onBiInteractiveAppCreated(mSession, biIAppUri, biIAppId);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1134,5 +1178,18 @@ public final class TvIAppManager {
|
||||
*/
|
||||
public void onSessionStateChanged(Session session, int state) {
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called when {@link TvIAppService.Session#notifyBiInteractiveAppCreated} is
|
||||
* called.
|
||||
*
|
||||
* @param session A {@link TvIAppManager.Session} associated with this callback.
|
||||
* @param biIAppUri URI associated this BI interactive app. This is the same URI in
|
||||
* {@link Session#createBiInteractiveApp(Uri, Bundle)}
|
||||
* @param biIAppId BI interactive app ID, which can be used to destroy the BI interactive
|
||||
* app.
|
||||
*/
|
||||
public void onBiInteractiveAppCreated(Session session, Uri biIAppUri, String biIAppId) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,6 +287,28 @@ public abstract class TvIAppService extends Service {
|
||||
public void onStartIApp() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates broadcast-independent(BI) interactive application.
|
||||
*
|
||||
* @see #onDestroyBiInteractiveApp(String)
|
||||
* @hide
|
||||
*/
|
||||
public void onCreateBiInteractiveApp(@NonNull Uri biIAppUri, @Nullable Bundle params) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Destroys broadcast-independent(BI) interactive application.
|
||||
*
|
||||
* @param biIAppId the BI interactive app ID from
|
||||
* {@link #createBiInteractiveApp(Uri, Bundle)}
|
||||
*
|
||||
* @see #onCreateBiInteractiveApp(Uri, Bundle)
|
||||
* @hide
|
||||
*/
|
||||
public void onDestroyBiInteractiveApp(@NonNull String biIAppId) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the application sets the surface.
|
||||
*
|
||||
@@ -497,6 +519,14 @@ public abstract class TvIAppService extends Service {
|
||||
onStartIApp();
|
||||
}
|
||||
|
||||
void createBiInteractiveApp(@NonNull Uri biIAppUri, @Nullable Bundle params) {
|
||||
onCreateBiInteractiveApp(biIAppUri, params);
|
||||
}
|
||||
|
||||
void destroyBiInteractiveApp(@NonNull String biIAppId) {
|
||||
onDestroyBiInteractiveApp(biIAppId);
|
||||
}
|
||||
|
||||
void release() {
|
||||
onRelease();
|
||||
if (mSurface != null) {
|
||||
@@ -555,6 +585,32 @@ public abstract class TvIAppService extends Service {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the broadcast-independent(BI) interactive application has been created.
|
||||
* @param biIAppId BI interactive app ID, which can be used to destroy the BI interactive
|
||||
* app.
|
||||
* @hide
|
||||
*/
|
||||
public final void notifyBiInteractiveAppCreated(Uri biIAppUri, String biIAppId) {
|
||||
executeOrPostRunnableOnMainThread(new Runnable() {
|
||||
@MainThread
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "notifyBiInteractiveAppCreated (biIAppId="
|
||||
+ biIAppId + ")");
|
||||
}
|
||||
if (mSessionCallback != null) {
|
||||
mSessionCallback.onBiInteractiveAppCreated(biIAppUri, biIAppId);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "error in notifyBiInteractiveAppCreated", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes care of dispatching incoming input events and tells whether the event was handled.
|
||||
*/
|
||||
@@ -792,6 +848,16 @@ public abstract class TvIAppService extends Service {
|
||||
mSessionImpl.startIApp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createBiInteractiveApp(Uri biIAppUri, Bundle params) {
|
||||
mSessionImpl.createBiInteractiveApp(biIAppUri, params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyBiInteractiveApp(String biIAppId) {
|
||||
mSessionImpl.destroyBiInteractiveApp(biIAppId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
mSessionImpl.scheduleMediaViewCleanup();
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package android.media.tv.interactive;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
@@ -26,6 +27,7 @@ import android.media.tv.TvInputManager;
|
||||
import android.media.tv.TvView;
|
||||
import android.media.tv.interactive.TvIAppManager.Session;
|
||||
import android.media.tv.interactive.TvIAppManager.SessionCallback;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.util.AttributeSet;
|
||||
@@ -301,6 +303,38 @@ public class TvIAppView extends ViewGroup {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates broadcast-independent(BI) interactive application.
|
||||
*
|
||||
* @see #destroyBiInteractiveApp(String)
|
||||
* @hide
|
||||
*/
|
||||
public void createBiInteractiveApp(@NonNull Uri biIAppUri, @Nullable Bundle params) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "createBiInteractiveApp Uri=" + biIAppUri + ", params=" + params);
|
||||
}
|
||||
if (mSession != null) {
|
||||
mSession.createBiInteractiveApp(biIAppUri, params);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys broadcast-independent(BI) interactive application.
|
||||
*
|
||||
* @param biIAppId the BI interactive app ID from {@link #createBiInteractiveApp(Uri, Bundle)}
|
||||
*
|
||||
* @see #createBiInteractiveApp(Uri, Bundle)
|
||||
* @hide
|
||||
*/
|
||||
public void destroyBiInteractiveApp(@NonNull String biIAppId) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "destroyBiInteractiveApp biIAppId=" + biIAppId);
|
||||
}
|
||||
if (mSession != null) {
|
||||
mSession.destroyBiInteractiveApp(biIAppId);
|
||||
}
|
||||
}
|
||||
|
||||
public Session getIAppSession() {
|
||||
return mSession;
|
||||
}
|
||||
@@ -349,6 +383,28 @@ public class TvIAppView extends ViewGroup {
|
||||
public void onCommandRequest(String iAppServiceId,
|
||||
@TvIAppService.IAppServiceCommandType String cmdType, Bundle parameters) {
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called when the session state is changed.
|
||||
*
|
||||
* @param iAppServiceId The ID of the TV interactive app service bound to this view.
|
||||
* @param state current session state.
|
||||
*/
|
||||
public void onSessionStateChanged(String iAppServiceId, int state) {
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called when broadcast-independent (BI) interactive app is created.
|
||||
*
|
||||
* @param iAppServiceId The ID of the TV interactive app service bound to this view.
|
||||
* @param biIAppUri URI associated this BI interactive app. This is the same URI in
|
||||
* {@link Session#createBiInteractiveApp(Uri, Bundle)}
|
||||
* @param biIAppId BI interactive app ID, which can be used to destroy the BI interactive
|
||||
* app.
|
||||
*/
|
||||
public void onBiInteractiveAppCreated(String iAppServiceId, Uri biIAppUri,
|
||||
String biIAppId) {
|
||||
}
|
||||
}
|
||||
|
||||
private class MySessionCallback extends SessionCallback {
|
||||
@@ -440,5 +496,34 @@ public class TvIAppView extends ViewGroup {
|
||||
mCallback.onCommandRequest(mIAppServiceId, cmdType, parameters);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionStateChanged(Session session, int state) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onSessionStateChanged (state=" + state + ")");
|
||||
}
|
||||
if (this != mSessionCallback) {
|
||||
Log.w(TAG, "onSessionStateChanged - session not created");
|
||||
return;
|
||||
}
|
||||
if (mCallback != null) {
|
||||
mCallback.onSessionStateChanged(mIAppServiceId, state);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBiInteractiveAppCreated(Session session, Uri biIAppUri, String biIAppId) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onBiInteractiveAppCreated (biIAppUri=" + biIAppUri + ", biIAppId="
|
||||
+ biIAppId + ")");
|
||||
}
|
||||
if (this != mSessionCallback) {
|
||||
Log.w(TAG, "onBiInteractiveAppCreated - session not created");
|
||||
return;
|
||||
}
|
||||
if (mCallback != null) {
|
||||
mCallback.onBiInteractiveAppCreated(mIAppServiceId, biIAppUri, biIAppId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -652,11 +652,13 @@ public class TvIAppManagerService extends SystemService {
|
||||
serviceState = new ServiceState(
|
||||
componentName, tiasId, resolvedUserId, true, type);
|
||||
userState.mServiceStateMap.put(componentName, serviceState);
|
||||
updateServiceConnectionLocked(componentName, resolvedUserId);
|
||||
} else if (serviceState.mService != null) {
|
||||
serviceState.mService.prepare(type);
|
||||
} else {
|
||||
serviceState.mPendingPrepare = true;
|
||||
serviceState.mPendingPrepareType = type;
|
||||
updateServiceConnectionLocked(componentName, resolvedUserId);
|
||||
}
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
@@ -687,10 +689,12 @@ public class TvIAppManagerService extends SystemService {
|
||||
componentName, tiasId, resolvedUserId);
|
||||
serviceState.addPendingAppLink(appLinkInfo);
|
||||
userState.mServiceStateMap.put(componentName, serviceState);
|
||||
updateServiceConnectionLocked(componentName, resolvedUserId);
|
||||
} else if (serviceState.mService != null) {
|
||||
serviceState.mService.notifyAppLinkInfo(appLinkInfo);
|
||||
} else {
|
||||
serviceState.addPendingAppLink(appLinkInfo);
|
||||
updateServiceConnectionLocked(componentName, resolvedUserId);
|
||||
}
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
@@ -850,7 +854,7 @@ public class TvIAppManagerService extends SystemService {
|
||||
}
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
|
||||
userId, "notifyTuned");
|
||||
userId, "startIApp");
|
||||
SessionState sessionState = null;
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
@@ -868,6 +872,58 @@ public class TvIAppManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createBiInteractiveApp(
|
||||
IBinder sessionToken, Uri biIAppUri, Bundle params, int userId) {
|
||||
if (DEBUG) {
|
||||
Slogf.d(TAG, "createBiInteractiveApp(biIAppUri=%s,params=%s)", biIAppUri, params);
|
||||
}
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
|
||||
userId, "createBiInteractiveApp");
|
||||
SessionState sessionState = null;
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (mLock) {
|
||||
try {
|
||||
sessionState = getSessionStateLocked(sessionToken, callingUid,
|
||||
resolvedUserId);
|
||||
getSessionLocked(sessionState).createBiInteractiveApp(
|
||||
biIAppUri, params);
|
||||
} catch (RemoteException | SessionNotFoundException e) {
|
||||
Slogf.e(TAG, "error in createBiInteractiveApp", e);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyBiInteractiveApp(IBinder sessionToken, String biIAppId, int userId) {
|
||||
if (DEBUG) {
|
||||
Slogf.d(TAG, "destroyBiInteractiveApp(biIAppId=%s)", biIAppId);
|
||||
}
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
|
||||
userId, "destroyBiInteractiveApp");
|
||||
SessionState sessionState = null;
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (mLock) {
|
||||
try {
|
||||
sessionState = getSessionStateLocked(sessionToken, callingUid,
|
||||
resolvedUserId);
|
||||
getSessionLocked(sessionState).destroyBiInteractiveApp(biIAppId);
|
||||
} catch (RemoteException | SessionNotFoundException e) {
|
||||
Slogf.e(TAG, "error in destroyBiInteractiveApp", e);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSurface(IBinder sessionToken, Surface surface, int userId) {
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
@@ -1164,7 +1220,8 @@ public class TvIAppManagerService extends SystemService {
|
||||
serviceState.mReconnecting = false;
|
||||
}
|
||||
|
||||
boolean shouldBind = !serviceState.mSessionTokens.isEmpty();
|
||||
boolean shouldBind = (!serviceState.mSessionTokens.isEmpty())
|
||||
|| (serviceState.mPendingPrepare) || (!serviceState.mPendingAppLinkInfo.isEmpty());
|
||||
|
||||
if (serviceState.mService == null && shouldBind) {
|
||||
// This means that the service is not yet connected but its state indicates that we
|
||||
@@ -1584,6 +1641,25 @@ public class TvIAppManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBiInteractiveAppCreated(Uri biIAppUri, String biIAppId) {
|
||||
synchronized (mLock) {
|
||||
if (DEBUG) {
|
||||
Slogf.d(TAG, "onBiInteractiveAppCreated (biIAppUri=" + biIAppUri
|
||||
+ ", biIAppId=" + biIAppId + ")");
|
||||
}
|
||||
if (mSessionState.mSession == null || mSessionState.mClient == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mSessionState.mClient.onBiInteractiveAppCreated(
|
||||
biIAppUri, biIAppId, mSessionState.mSeq);
|
||||
} catch (RemoteException e) {
|
||||
Slogf.e(TAG, "error in onBiInteractiveAppCreated", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private boolean addSessionTokenToClientStateLocked(ITvIAppSession session) {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user