Merge "TIAF: handle surface and surface view"
This commit is contained in:
@@ -24,4 +24,5 @@ package android.media.tv.interactive;
|
||||
oneway interface ITvIAppClient {
|
||||
void onSessionCreated(in String iAppServiceId, IBinder token, int seq);
|
||||
void onSessionReleased(int seq);
|
||||
void onLayoutSurface(int left, int top, int right, int bottom, int seq);
|
||||
}
|
||||
@@ -17,6 +17,7 @@
|
||||
package android.media.tv.interactive;
|
||||
|
||||
import android.media.tv.interactive.ITvIAppClient;
|
||||
import android.view.Surface;
|
||||
|
||||
/**
|
||||
* Interface to the TV interactive app service.
|
||||
@@ -27,4 +28,7 @@ interface ITvIAppManager {
|
||||
void createSession(
|
||||
in ITvIAppClient client, in String iAppServiceId, int type, int seq, int userId);
|
||||
void releaseSession(in IBinder sessionToken, int userId);
|
||||
void setSurface(in IBinder sessionToken, in Surface surface, int userId);
|
||||
void dispatchSurfaceChanged(in IBinder sessionToken, int format, int width, int height,
|
||||
int userId);
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package android.media.tv.interactive;
|
||||
|
||||
import android.view.Surface;
|
||||
|
||||
/**
|
||||
* Sub-interface of ITvIAppService.aidl which is created per session and has its own context.
|
||||
* @hide
|
||||
@@ -23,4 +25,6 @@ package android.media.tv.interactive;
|
||||
oneway interface ITvIAppSession {
|
||||
void startIApp();
|
||||
void release();
|
||||
void setSurface(in Surface surface);
|
||||
void dispatchSurfaceChanged(int format, int width, int height);
|
||||
}
|
||||
@@ -25,4 +25,5 @@ import android.media.tv.interactive.ITvIAppSession;
|
||||
*/
|
||||
oneway interface ITvIAppSessionCallback {
|
||||
void onSessionCreated(in ITvIAppSession session);
|
||||
void onLayoutSurface(int left, int top, int right, int bottom);
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
import android.view.Surface;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
@@ -88,6 +89,18 @@ public final class TvIAppManager {
|
||||
record.postSessionReleased();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLayoutSurface(int left, int top, int right, int bottom, int seq) {
|
||||
synchronized (mSessionCallbackRecordMap) {
|
||||
SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
|
||||
if (record == null) {
|
||||
Log.e(TAG, "Callback not found for seq " + seq);
|
||||
return;
|
||||
}
|
||||
record.postLayoutSurface(left, top, right, bottom);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -158,6 +171,44 @@ public final class TvIAppManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link android.view.Surface} for this session.
|
||||
*
|
||||
* @param surface A {@link android.view.Surface} used to render video.
|
||||
*/
|
||||
public void setSurface(Surface surface) {
|
||||
if (mToken == null) {
|
||||
Log.w(TAG, "The session has been already released");
|
||||
return;
|
||||
}
|
||||
// surface can be null.
|
||||
try {
|
||||
mService.setSurface(mToken, surface, mUserId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies of any structural changes (format or size) of the surface passed in
|
||||
* {@link #setSurface}.
|
||||
*
|
||||
* @param format The new PixelFormat of the surface.
|
||||
* @param width The new width of the surface.
|
||||
* @param height The new height of the surface.
|
||||
*/
|
||||
public void dispatchSurfaceChanged(int format, int width, int height) {
|
||||
if (mToken == null) {
|
||||
Log.w(TAG, "The session has been already released");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mService.dispatchSurfaceChanged(mToken, format, width, height, mUserId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases this session.
|
||||
*/
|
||||
@@ -211,6 +262,16 @@ public final class TvIAppManager {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void postLayoutSurface(final int left, final int top, final int right,
|
||||
final int bottom) {
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mSessionCallback.onLayoutSurface(mSession, left, top, right, bottom);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -235,5 +296,18 @@ public final class TvIAppManager {
|
||||
*/
|
||||
public void onSessionReleased(@NonNull Session session) {
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called when {@link TvIAppService.Session#layoutSurface} is called to change the
|
||||
* layout of surface.
|
||||
*
|
||||
* @param session A {@link TvIAppManager.Session} associated with this callback.
|
||||
* @param left Left position.
|
||||
* @param top Top position.
|
||||
* @param right Right position.
|
||||
* @param bottom Bottom position.
|
||||
*/
|
||||
public void onLayoutSurface(Session session, int left, int top, int right, int bottom) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,12 @@
|
||||
|
||||
package android.media.tv.interactive;
|
||||
|
||||
import android.annotation.MainThread;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
@@ -27,6 +29,7 @@ import android.os.Message;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.Surface;
|
||||
|
||||
import com.android.internal.os.SomeArgs;
|
||||
|
||||
@@ -94,23 +97,100 @@ public abstract class TvIAppService extends Service {
|
||||
// @GuardedBy("mLock")
|
||||
private final List<Runnable> mPendingActions = new ArrayList<>();
|
||||
|
||||
private final Context mContext;
|
||||
private final Handler mHandler;
|
||||
private Surface mSurface;
|
||||
|
||||
/**
|
||||
* Creates a new Session.
|
||||
*
|
||||
* @param context The context of the application
|
||||
*/
|
||||
public Session(Context context) {
|
||||
mContext = context;
|
||||
mHandler = new Handler(context.getMainLooper());
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts TvIAppService session.
|
||||
*/
|
||||
public void onStartIApp() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the application sets the surface.
|
||||
*
|
||||
* <p>The TV IApp service should render interactive app UI onto the given surface. When
|
||||
* called with {@code null}, the input service should immediately free any references to the
|
||||
* currently set surface and stop using it.
|
||||
*
|
||||
* @param surface The surface to be used for interactive app UI rendering. Can be
|
||||
* {@code null}.
|
||||
* @return {@code true} if the surface was set successfully, {@code false} otherwise.
|
||||
*/
|
||||
public abstract boolean onSetSurface(@Nullable Surface surface);
|
||||
|
||||
/**
|
||||
* Called after any structural changes (format or size) have been made to the surface passed
|
||||
* in {@link #onSetSurface}. This method is always called at least once, after
|
||||
* {@link #onSetSurface} is called with non-null surface.
|
||||
*
|
||||
* @param format The new PixelFormat of the surface.
|
||||
* @param width The new width of the surface.
|
||||
* @param height The new height of the surface.
|
||||
*/
|
||||
public void onSurfaceChanged(int format, int width, int height) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases TvIAppService session.
|
||||
*/
|
||||
public void onRelease() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns a size and position to the surface passed in {@link #onSetSurface}. The position
|
||||
* is relative to the overlay view that sits on top of this surface.
|
||||
*
|
||||
* @param left Left position in pixels, relative to the overlay view.
|
||||
* @param top Top position in pixels, relative to the overlay view.
|
||||
* @param right Right position in pixels, relative to the overlay view.
|
||||
* @param bottom Bottom position in pixels, relative to the overlay view.
|
||||
*/
|
||||
public void layoutSurface(final int left, final int top, final int right,
|
||||
final int bottom) {
|
||||
if (left > right || top > bottom) {
|
||||
throw new IllegalArgumentException("Invalid parameter");
|
||||
}
|
||||
executeOrPostRunnableOnMainThread(new Runnable() {
|
||||
@MainThread
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "layoutSurface (l=" + left + ", t=" + top
|
||||
+ ", r=" + right + ", b=" + bottom + ",)");
|
||||
}
|
||||
if (mSessionCallback != null) {
|
||||
mSessionCallback.onLayoutSurface(left, top, right, bottom);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "error in layoutSurface", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void startIApp() {
|
||||
onStartIApp();
|
||||
}
|
||||
|
||||
void release() {
|
||||
onRelease();
|
||||
if (mSurface != null) {
|
||||
mSurface.release();
|
||||
mSurface = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void initialize(ITvIAppSessionCallback callback) {
|
||||
@@ -122,6 +202,45 @@ public abstract class TvIAppService extends Service {
|
||||
mPendingActions.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link #onSetSurface}.
|
||||
*/
|
||||
void setSurface(Surface surface) {
|
||||
onSetSurface(surface);
|
||||
if (mSurface != null) {
|
||||
mSurface.release();
|
||||
}
|
||||
mSurface = surface;
|
||||
// TODO: Handle failure.
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link #onSurfaceChanged}.
|
||||
*/
|
||||
void dispatchSurfaceChanged(int format, int width, int height) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "dispatchSurfaceChanged(format=" + format + ", width=" + width
|
||||
+ ", height=" + height + ")");
|
||||
}
|
||||
onSurfaceChanged(format, width, height);
|
||||
}
|
||||
|
||||
private void executeOrPostRunnableOnMainThread(Runnable action) {
|
||||
synchronized (mLock) {
|
||||
if (mSessionCallback == null) {
|
||||
// The session is not initialized yet.
|
||||
mPendingActions.add(action);
|
||||
} else {
|
||||
if (mHandler.getLooper().isCurrentThread()) {
|
||||
action.run();
|
||||
} else {
|
||||
// Posts the runnable if this is not called from the main thread
|
||||
mHandler.post(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -143,6 +262,16 @@ public abstract class TvIAppService extends Service {
|
||||
public void release() {
|
||||
mSessionImpl.release();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSurface(Surface surface) {
|
||||
mSessionImpl.setSurface(surface);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchSurfaceChanged(int format, int width, int height) {
|
||||
mSessionImpl.dispatchSurfaceChanged(format, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("HandlerLeak")
|
||||
|
||||
@@ -17,10 +17,18 @@
|
||||
package android.media.tv.interactive;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.XmlResourceParser;
|
||||
import android.media.tv.interactive.TvIAppManager.Session;
|
||||
import android.media.tv.interactive.TvIAppManager.SessionCallback;
|
||||
import android.os.Handler;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.util.Xml;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
/**
|
||||
@@ -35,18 +43,137 @@ public class TvIAppView extends ViewGroup {
|
||||
private final Handler mHandler = new Handler();
|
||||
private Session mSession;
|
||||
private MySessionCallback mSessionCallback;
|
||||
private SurfaceView mSurfaceView;
|
||||
private Surface mSurface;
|
||||
|
||||
private boolean mSurfaceChanged;
|
||||
private int mSurfaceFormat;
|
||||
private int mSurfaceWidth;
|
||||
private int mSurfaceHeight;
|
||||
|
||||
private boolean mUseRequestedSurfaceLayout;
|
||||
private int mSurfaceViewLeft;
|
||||
private int mSurfaceViewRight;
|
||||
private int mSurfaceViewTop;
|
||||
private int mSurfaceViewBottom;
|
||||
|
||||
private final AttributeSet mAttrs;
|
||||
private final int mDefStyleAttr;
|
||||
private final XmlResourceParser mParser;
|
||||
|
||||
private final SurfaceHolder.Callback mSurfaceHolderCallback = new SurfaceHolder.Callback() {
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "surfaceChanged(holder=" + holder + ", format=" + format
|
||||
+ ", width=" + width + ", height=" + height + ")");
|
||||
}
|
||||
mSurfaceFormat = format;
|
||||
mSurfaceWidth = width;
|
||||
mSurfaceHeight = height;
|
||||
mSurfaceChanged = true;
|
||||
dispatchSurfaceChanged(mSurfaceFormat, mSurfaceWidth, mSurfaceHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceCreated(SurfaceHolder holder) {
|
||||
mSurface = holder.getSurface();
|
||||
setSessionSurface(mSurface);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
mSurface = null;
|
||||
mSurfaceChanged = false;
|
||||
setSessionSurface(null);
|
||||
}
|
||||
};
|
||||
|
||||
public TvIAppView(Context context) {
|
||||
this(context, null, 0);
|
||||
}
|
||||
|
||||
public TvIAppView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, /* attrs = */null, /* defStyleAttr = */0);
|
||||
int sourceResId = Resources.getAttributeSetSourceResId(attrs);
|
||||
if (sourceResId != Resources.ID_NULL) {
|
||||
Log.d(TAG, "Build local AttributeSet");
|
||||
mParser = context.getResources().getXml(sourceResId);
|
||||
mAttrs = Xml.asAttributeSet(mParser);
|
||||
} else {
|
||||
Log.d(TAG, "Use passed in AttributeSet");
|
||||
mParser = null;
|
||||
mAttrs = attrs;
|
||||
}
|
||||
mDefStyleAttr = defStyleAttr;
|
||||
resetSurfaceView();
|
||||
mTvIAppManager = (TvIAppManager) getContext().getSystemService("tv_interactive_app");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG,
|
||||
"onLayout (left=" + l + ", top=" + t + ", right=" + r + ", bottom=" + b + ",)");
|
||||
Log.d(TAG, "onLayout (left=" + left + ", top=" + top + ", right=" + right
|
||||
+ ", bottom=" + bottom + ",)");
|
||||
}
|
||||
if (mUseRequestedSurfaceLayout) {
|
||||
mSurfaceView.layout(mSurfaceViewLeft, mSurfaceViewTop, mSurfaceViewRight,
|
||||
mSurfaceViewBottom);
|
||||
} else {
|
||||
mSurfaceView.layout(0, 0, right - left, bottom - top);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
mSurfaceView.measure(widthMeasureSpec, heightMeasureSpec);
|
||||
int width = mSurfaceView.getMeasuredWidth();
|
||||
int height = mSurfaceView.getMeasuredHeight();
|
||||
int childState = mSurfaceView.getMeasuredState();
|
||||
setMeasuredDimension(resolveSizeAndState(width, widthMeasureSpec, childState),
|
||||
resolveSizeAndState(height, heightMeasureSpec,
|
||||
childState << MEASURED_HEIGHT_STATE_SHIFT));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onVisibilityChanged(View changedView, int visibility) {
|
||||
super.onVisibilityChanged(changedView, visibility);
|
||||
mSurfaceView.setVisibility(visibility);
|
||||
}
|
||||
|
||||
private void resetSurfaceView() {
|
||||
if (mSurfaceView != null) {
|
||||
mSurfaceView.getHolder().removeCallback(mSurfaceHolderCallback);
|
||||
removeView(mSurfaceView);
|
||||
}
|
||||
mSurface = null;
|
||||
mSurfaceView = new SurfaceView(getContext(), mAttrs, mDefStyleAttr);
|
||||
// The surface view's content should be treated as secure all the time.
|
||||
mSurfaceView.setSecure(true);
|
||||
mSurfaceView.getHolder().addCallback(mSurfaceHolderCallback);
|
||||
addView(mSurfaceView);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets this TvIAppView.
|
||||
*/
|
||||
public void reset() {
|
||||
if (DEBUG) Log.d(TAG, "reset()");
|
||||
resetInternal();
|
||||
}
|
||||
|
||||
private void setSessionSurface(Surface surface) {
|
||||
if (mSession == null) {
|
||||
return;
|
||||
}
|
||||
mSession.setSurface(surface);
|
||||
}
|
||||
|
||||
private void dispatchSurfaceChanged(int format, int width, int height) {
|
||||
if (mSession == null) {
|
||||
return;
|
||||
}
|
||||
mSession.dispatchSurfaceChanged(format, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,6 +202,17 @@ public class TvIAppView extends ViewGroup {
|
||||
}
|
||||
}
|
||||
|
||||
private void resetInternal() {
|
||||
mSessionCallback = null;
|
||||
if (mSession != null) {
|
||||
setSessionSurface(null);
|
||||
mUseRequestedSurfaceLayout = false;
|
||||
mSession.release();
|
||||
mSession = null;
|
||||
resetSurfaceView();
|
||||
}
|
||||
}
|
||||
|
||||
private class MySessionCallback extends SessionCallback {
|
||||
final String mIAppServiceId;
|
||||
int mType;
|
||||
@@ -99,7 +237,15 @@ public class TvIAppView extends ViewGroup {
|
||||
}
|
||||
mSession = session;
|
||||
if (session != null) {
|
||||
// TODO: handle SurfaceView and InputChannel.
|
||||
// mSurface may not be ready yet as soon as starting an application.
|
||||
// In the case, we don't send Session.setSurface(null) unnecessarily.
|
||||
// setSessionSurface will be called in surfaceCreated.
|
||||
if (mSurface != null) {
|
||||
setSessionSurface(mSurface);
|
||||
if (mSurfaceChanged) {
|
||||
dispatchSurfaceChanged(mSurfaceFormat, mSurfaceWidth, mSurfaceHeight);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Failed to create
|
||||
// Todo: forward error to Tv App
|
||||
@@ -119,5 +265,23 @@ public class TvIAppView extends ViewGroup {
|
||||
mSessionCallback = null;
|
||||
mSession = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLayoutSurface(Session session, int left, int top, int right, int bottom) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onLayoutSurface (left=" + left + ", top=" + top + ", right="
|
||||
+ right + ", bottom=" + bottom + ",)");
|
||||
}
|
||||
if (this != mSessionCallback) {
|
||||
Log.w(TAG, "onLayoutSurface - session not created");
|
||||
return;
|
||||
}
|
||||
mSurfaceViewLeft = left;
|
||||
mSurfaceViewTop = top;
|
||||
mSurfaceViewRight = right;
|
||||
mSurfaceViewBottom = bottom;
|
||||
mUseRequestedSurfaceLayout = true;
|
||||
requestLayout();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.util.SparseArray;
|
||||
import android.view.Surface;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.server.SystemService;
|
||||
@@ -136,6 +137,16 @@ public class TvIAppManagerService extends SystemService {
|
||||
return sessionState;
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private ITvIAppSession getSessionLocked(SessionState sessionState) {
|
||||
ITvIAppSession session = sessionState.mSession;
|
||||
if (session == null) {
|
||||
throw new IllegalStateException("Session not yet created for token "
|
||||
+ sessionState.mSessionToken);
|
||||
}
|
||||
return session;
|
||||
}
|
||||
|
||||
private final class BinderService extends ITvIAppManager.Stub {
|
||||
|
||||
@Override
|
||||
@@ -234,6 +245,55 @@ public class TvIAppManagerService extends SystemService {
|
||||
Slogf.e(TAG, "error in start", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSurface(IBinder sessionToken, Surface surface, int userId) {
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
|
||||
userId, "setSurface");
|
||||
SessionState sessionState = null;
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (mLock) {
|
||||
try {
|
||||
sessionState = getSessionStateLocked(sessionToken, callingUid,
|
||||
resolvedUserId);
|
||||
getSessionLocked(sessionState).setSurface(surface);
|
||||
} catch (RemoteException | SessionNotFoundException e) {
|
||||
Slogf.e(TAG, "error in setSurface", e);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (surface != null) {
|
||||
// surface is not used in TvIAppManagerService.
|
||||
surface.release();
|
||||
}
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchSurfaceChanged(IBinder sessionToken, int format, int width,
|
||||
int height, int userId) {
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
|
||||
userId, "dispatchSurfaceChanged");
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (mLock) {
|
||||
try {
|
||||
SessionState sessionState = getSessionStateLocked(sessionToken, callingUid,
|
||||
resolvedUserId);
|
||||
getSessionLocked(sessionState).dispatchSurfaceChanged(format, width,
|
||||
height);
|
||||
} catch (RemoteException | SessionNotFoundException e) {
|
||||
Slogf.e(TAG, "error in dispatchSurfaceChanged", e);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
@@ -616,6 +676,25 @@ public class TvIAppManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLayoutSurface(int left, int top, int right, int bottom) {
|
||||
synchronized (mLock) {
|
||||
if (DEBUG) {
|
||||
Slogf.d(TAG, "onLayoutSurface (left=" + left + ", top=" + top
|
||||
+ ", right=" + right + ", bottom=" + bottom + ",)");
|
||||
}
|
||||
if (mSessionState.mSession == null || mSessionState.mClient == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mSessionState.mClient.onLayoutSurface(left, top, right, bottom,
|
||||
mSessionState.mSeq);
|
||||
} catch (RemoteException e) {
|
||||
Slogf.e(TAG, "error in onLayoutSurface", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private boolean addSessionTokenToClientStateLocked(ITvIAppSession session) {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user