am 9de91850: am 2c315fef: am 1becc968: TIF: Call setMain(false) when session is released.

* commit '9de91850dc48e4a65749bda2c9f511e0876a56b0':
  TIF: Call setMain(false) when session is released.
This commit is contained in:
Ji-Hwan Lee
2014-08-19 07:23:13 +00:00
committed by Android Git Automerger
6 changed files with 94 additions and 80 deletions

View File

@@ -29,7 +29,7 @@ import android.view.Surface;
oneway interface ITvInputSession {
void release();
void setMainSession(boolean isMainSession);
void setMain(boolean isMain);
void setSurface(in Surface surface);
void dispatchSurfaceChanged(int format, int width, int height);
// TODO: Remove this once it becomes irrelevant for applications to handle audio focus. The plan

View File

@@ -42,7 +42,7 @@ public class ITvInputSessionWrapper extends ITvInputSession.Stub implements Hand
private static final String TAG = "TvInputSessionWrapper";
private static final int DO_RELEASE = 1;
private static final int DO_SET_MAIN_SESSION = 2;
private static final int DO_SET_MAIN = 2;
private static final int DO_SET_SURFACE = 3;
private static final int DO_DISPATCH_SURFACE_CHANGED = 4;
private static final int DO_SET_STREAM_VOLUME = 5;
@@ -91,8 +91,8 @@ public class ITvInputSessionWrapper extends ITvInputSession.Stub implements Hand
}
return;
}
case DO_SET_MAIN_SESSION: {
mTvInputSessionImpl.setMainSession((Boolean) msg.obj);
case DO_SET_MAIN: {
mTvInputSessionImpl.setMain((Boolean) msg.obj);
return;
}
case DO_SET_SURFACE: {
@@ -162,8 +162,8 @@ public class ITvInputSessionWrapper extends ITvInputSession.Stub implements Hand
}
@Override
public void setMainSession(boolean isMain) {
mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_SET_MAIN_SESSION, isMain));
public void setMain(boolean isMain) {
mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_SET_MAIN, isMain));
}
@Override

View File

@@ -1023,10 +1023,12 @@ public final class TvInputManager {
}
/**
* Sets this as main session. See {@link TvView#setMainTvView} for about meaning of "main".
* @hide
* Sets this as the main session. The main session is a session whose corresponding TV
* input determines the HDMI-CEC active source device.
*
* @see TvView#setMain
*/
public void setMainSession() {
void setMain() {
if (mToken == null) {
Log.w(TAG, "The session has been already released");
return;

View File

@@ -551,29 +551,30 @@ public abstract class TvInputService extends Service {
public abstract void onRelease();
/**
* Set the current session as the "main" session. See {@link TvView#setMainTvView} for the
* meaning of "main".
* Sets the current session as the main session. The main session is a session whose
* corresponding TV input determines the HDMI-CEC active source device.
* <p>
* This is primarily for HDMI-CEC active source management. TV input service that manages
* HDMI-CEC logical device should make sure not only to select the corresponding HDMI
* logical device as source device on {@code onSetMainSession(true)}, but also to select
* internal device on {@code onSetMainSession(false)}. Also, if surface is set to non-main
* session, it needs to select internal device after temporarily selecting corresponding
* HDMI logical device for set up.
* TV input service that manages HDMI-CEC logical device should implement {@link
* #onSetMain} to (1) select the corresponding HDMI logical device as the source device
* when {@code isMain} is {@code true}, and to (2) select the internal device (= TV itself)
* as the source device when {@code isMain} is {@code false} and the session is still main.
* Also, if a surface is passed to a non-main session and active source is changed to
* initiate the surface, the active source should be returned to the main session.
* </p><p>
* It is guaranteed that {@code onSetMainSession(true)} for new session is called first,
* and {@code onSetMainSession(false)} for old session is called afterwards. This allows
* {@code onSetMainSession(false)} to be no-op when TV input service knows that the next
* main session corresponds to another HDMI logical device. Practically, this implies that
* one TV input service should handle all HDMI port and HDMI-CEC logical devices for smooth
* active source transition.
* {@link TvView} guarantees that, when tuning involves a session transition, {@code
* onSetMain(true)} for new session is called first, {@code onSetMain(false)} for old
* session is called afterwards. This allows {@code onSetMain(false)} to be no-op when TV
* input service knows that the next main session corresponds to another HDMI logical
* device. Practically, this implies that one TV input service should handle all HDMI port
* and HDMI-CEC logical devices for smooth active source transition.
* </p>
*
* @param isMainSession If true, session is main.
* @param isMain If true, session should become main.
* @see TvView#setMain
* @hide
*/
@SystemApi
public void onSetMainSession(boolean isMainSession) {
public void onSetMain(boolean isMain) {
}
/**
@@ -841,10 +842,10 @@ public abstract class TvInputService extends Service {
}
/**
* Calls {@link #onSetMainSession}.
* Calls {@link #onSetMain}.
*/
void setMainSession(boolean isMainSession) {
onSetMainSession(isMainSession);
void setMain(boolean isMain) {
onSetMain(isMain);
}
/**

View File

@@ -116,8 +116,10 @@ public class TvView extends ViewGroup {
private final SurfaceHolder.Callback mSurfaceHolderCallback = new SurfaceHolder.Callback() {
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Log.d(TAG, "surfaceChanged(holder=" + holder + ", format=" + format + ", width=" + width
+ ", height=" + height + ")");
if (DEBUG) {
Log.d(TAG, "surfaceChanged(holder=" + holder + ", format=" + format + ", width="
+ width + ", height=" + height + ")");
}
mSurfaceFormat = format;
mSurfaceWidth = width;
mSurfaceHeight = height;
@@ -188,24 +190,27 @@ public class TvView extends ViewGroup {
}
/**
* Sets this as main TvView.
* Sets this as the main {@link TvView}.
* <p>
* Main TvView is the TvView which user is watching and interacting mainly. It is used for
* determining internal behavior of hardware TV input devices. For example, this influences
* how HDMI-CEC active source will be managed.
* The main {@link TvView} is a {@link TvView} whose corresponding TV input determines the
* HDMI-CEC active source device. For an HDMI port input, one of source devices that is
* connected to that HDMI port becomes the active source. For an HDMI-CEC logical device input,
* the corresponding HDMI-CEC logical device becomes the active source. For any non-HDMI input
* (including the tuner, composite, S-Video, etc.), the internal device (= TV itself) becomes
* the active source.
* </p><p>
* First tuned TvView becomes main automatically, and keeps to be main until setMainTvView() is
* called for other TvView. Note that main TvView won't be reset even when current main TvView
* is removed from view hierarchy.
* First tuned {@link TvView} becomes main automatically, and keeps to be main until {@link
* #setMain} is called for other {@link TvView}. Note that main {@link TvView} won't be reset
* even when current main {@link TvView} is removed from view hierarchy.
* </p>
* @hide
*/
@SystemApi
public void setMainTvView() {
public void setMain() {
synchronized (sMainTvViewLock) {
sMainTvView = this;
if (hasWindowFocus() && mSession != null) {
mSession.setMainSession();
mSession.setMain();
}
}
}
@@ -327,6 +332,7 @@ public class TvView extends ViewGroup {
* This method is primarily used to un-tune the current TvView.
*/
public void reset() {
if (DEBUG) Log.d(TAG, "reset()");
if (mSession != null) {
release();
resetSurfaceView();
@@ -538,7 +544,7 @@ public class TvView extends ViewGroup {
// Set main again to regain main session.
synchronized (sMainTvViewLock) {
if (hasFocus && this == sMainTvView && mSession != null) {
mSession.setMainSession();
mSession.setMain();
}
}
}
@@ -596,6 +602,7 @@ public class TvView extends ViewGroup {
mSurfaceView.getHolder().removeCallback(mSurfaceHolderCallback);
removeView(mSurfaceView);
}
mSurface = null;
mSurfaceView = new SurfaceView(getContext(), mAttrs, mDefStyleAttr) {
@Override
protected void updateWindow(boolean force, boolean redrawNeeded) {
@@ -821,11 +828,14 @@ public class TvView extends ViewGroup {
}
return;
}
if (DEBUG) {
Log.d(TAG, "onSessionCreated()");
}
mSession = session;
if (session != null) {
synchronized (sMainTvViewLock) {
if (hasWindowFocus() && TvView.this == sMainTvView) {
mSession.setMainSession();
mSession.setMain();
}
}
// mSurface may not be ready yet as soon as starting an application.

View File

@@ -691,6 +691,10 @@ public final class TvInputManagerService extends SystemService {
private void releaseSessionLocked(IBinder sessionToken, int callingUid, int userId) {
SessionState sessionState = getSessionStateLocked(sessionToken, callingUid, userId);
if (sessionState.mSession != null) {
UserState userState = getUserStateLocked(userId);
if (sessionToken == userState.mainSessionToken) {
setMainLocked(sessionToken, false, callingUid, userId);
}
try {
sessionState.mSession.release();
} catch (RemoteException e) {
@@ -704,6 +708,9 @@ public final class TvInputManagerService extends SystemService {
private void removeSessionStateLocked(IBinder sessionToken, int userId) {
UserState userState = getUserStateLocked(userId);
if (sessionToken == userState.mainSessionToken) {
if (DEBUG) {
Slog.d(TAG, "mainSessionToken=null");
}
userState.mainSessionToken = null;
}
@@ -740,6 +747,25 @@ public final class TvInputManagerService extends SystemService {
mWatchLogHandler.obtainMessage(WatchLogHandler.MSG_LOG_WATCH_END, args).sendToTarget();
}
private void setMainLocked(IBinder sessionToken, boolean isMain, int callingUid, int userId) {
SessionState sessionState = getSessionStateLocked(sessionToken, callingUid, userId);
if (sessionState.mHardwareSessionToken != null) {
sessionState = getSessionStateLocked(sessionState.mHardwareSessionToken,
Process.SYSTEM_UID, userId);
}
ServiceState serviceState = getServiceStateLocked(sessionState.mInfo.getComponent(),
userId);
if (!serviceState.mIsHardware) {
return;
}
ITvInputSession session = getSessionLocked(sessionState);
try {
session.setMain(isMain);
} catch (RemoteException e) {
Slog.e(TAG, "error in setMain", e);
}
}
private void notifyInputAddedLocked(UserState userState, String inputId) {
if (DEBUG) {
Slog.d(TAG, "notifyInputAdded: inputId = " + inputId);
@@ -1050,6 +1076,9 @@ public final class TvInputManagerService extends SystemService {
@Override
public void releaseSession(IBinder sessionToken, int userId) {
if (DEBUG) {
Slog.d(TAG, "releaseSession(): " + sessionToken);
}
final int callingUid = Binder.getCallingUid();
final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
userId, "releaseSession");
@@ -1065,6 +1094,9 @@ public final class TvInputManagerService extends SystemService {
@Override
public void setMainSession(IBinder sessionToken, int userId) {
if (DEBUG) {
Slog.d(TAG, "setMainSession(): " + sessionToken);
}
final int callingUid = Binder.getCallingUid();
final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
userId, "setMainSession");
@@ -1075,50 +1107,19 @@ public final class TvInputManagerService extends SystemService {
if (userState.mainSessionToken == sessionToken) {
return;
}
SessionState newMainSessionState = getSessionStateLocked(
sessionToken, callingUid, resolvedUserId);
if (newMainSessionState.mHardwareSessionToken != null) {
newMainSessionState = getSessionStateLocked(
newMainSessionState.mHardwareSessionToken,
Process.SYSTEM_UID, resolvedUserId);
if (DEBUG) {
Slog.d(TAG, "mainSessionToken=" + sessionToken);
}
ServiceState newMainServiceState = getServiceStateLocked(
newMainSessionState.mInfo.getComponent(), resolvedUserId);
ITvInputSession newMainSession = getSessionLocked(newMainSessionState);
ServiceState oldMainServiceState = null;
ITvInputSession oldMainSession = null;
if (userState.mainSessionToken != null) {
SessionState oldMainSessionState = getSessionStateLocked(
userState.mainSessionToken, Process.SYSTEM_UID, resolvedUserId);
if (oldMainSessionState.mHardwareSessionToken != null) {
oldMainSessionState = getSessionStateLocked(
oldMainSessionState.mHardwareSessionToken,
Process.SYSTEM_UID, resolvedUserId);
}
oldMainServiceState = getServiceStateLocked(
oldMainSessionState.mInfo.getComponent(), resolvedUserId);
oldMainSession = getSessionLocked(oldMainSessionState);
}
IBinder oldMainSessionToken = userState.mainSessionToken;
userState.mainSessionToken = sessionToken;
// Inform the new main session first.
// See {@link TvInputService#onSetMainSession}.
if (newMainServiceState.mIsHardware) {
try {
newMainSession.setMainSession(true);
} catch (RemoteException e) {
Slog.e(TAG, "error in setMainSession", e);
}
// See {@link TvInputService.Session#onSetMain}.
if (sessionToken != null) {
setMainLocked(sessionToken, true, callingUid, userId);
}
if (oldMainSession != null && oldMainServiceState.mIsHardware) {
try {
oldMainSession.setMainSession(false);
} catch (RemoteException e) {
Slog.e(TAG, "error in setMainSession", e);
}
if (oldMainSessionToken != null) {
setMainLocked(oldMainSessionToken, false, Process.SYSTEM_UID, userId);
}
}
} finally {