TIF: Remove the registered callback when the client process has died
Also make error messages more consistent
Bug: 17276418
Change-Id: Ib87e13e1383db4ff623de2e9b68ae9ff4309360a
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 6481944..058210c 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -179,7 +179,7 @@
try {
results = mContentResolver.applyBatch(TvContract.AUTHORITY, operations);
} catch (RemoteException | OperationApplicationException e) {
- Slog.e(TAG, "error in applyBatch" + e);
+ Slog.e(TAG, "error in applyBatch", e);
}
if (DEBUG) {
@@ -216,7 +216,9 @@
UserState userState = getUserStateLocked(userId);
userState.packageSet.clear();
- if (DEBUG) Slog.d(TAG, "buildTvInputList");
+ if (DEBUG) {
+ Slog.d(TAG, "buildTvInputList");
+ }
PackageManager pm = mContext.getPackageManager();
List<ResolveInfo> services = pm.queryIntentServices(
new Intent(TvInputService.SERVICE_INTERFACE),
@@ -246,7 +248,7 @@
try {
inputList.add(TvInputInfo.createTvInputInfo(mContext, ri));
} catch (XmlPullParserException | IOException e) {
- Slog.e(TAG, "Failed to load TV input " + si.name, e);
+ Slog.e(TAG, "failed to load TV input " + si.name, e);
continue;
}
}
@@ -258,7 +260,9 @@
Map<String, TvInputState> inputMap = new HashMap<String, TvInputState>();
for (TvInputInfo info : inputList) {
- if (DEBUG) Slog.d(TAG, "add " + info.getId());
+ if (DEBUG) {
+ Slog.d(TAG, "add " + info.getId());
+ }
TvInputState state = userState.inputMap.get(info.getId());
if (state == null) {
state = new TvInputState();
@@ -342,7 +346,13 @@
}
userState.serviceStateMap.clear();
+ // Clear everything else.
+ userState.inputMap.clear();
+ userState.packageSet.clear();
+ userState.ratingSystemXmlUriSet.clear();
userState.clientStateMap.clear();
+ userState.callbackSet.clear();
+ userState.mainSessionToken = null;
mUserStates.remove(userId);
}
@@ -453,7 +463,7 @@
try {
clientToken.linkToDeath(clientState, 0);
} catch (RemoteException e) {
- Slog.e(TAG, "Client is already died.");
+ Slog.e(TAG, "client process has already died", e);
}
userState.clientStateMap.put(clientToken, clientState);
return clientState;
@@ -487,7 +497,7 @@
try {
session.asBinder().linkToDeath(sessionState, 0);
} catch (RemoteException e) {
- Slog.e(TAG, "Session is already died.");
+ Slog.e(TAG, "session process has already died", e);
}
IBinder clientToken = sessionState.mClient.asBinder();
@@ -521,7 +531,7 @@
// originated from.
sessionState.mClient.onChannelRetuned(channelUri, sessionState.mSeq);
} catch (RemoteException e) {
- Slog.e(TAG, "error in onChannelRetuned");
+ Slog.e(TAG, "error in onChannelRetuned", e);
}
}
}
@@ -538,7 +548,7 @@
try {
sessionState.mClient.onTracksChanged(tracks, sessionState.mSeq);
} catch (RemoteException e) {
- Slog.e(TAG, "error in onTracksChanged");
+ Slog.e(TAG, "error in onTracksChanged", e);
}
}
}
@@ -555,7 +565,7 @@
try {
sessionState.mClient.onTrackSelected(type, trackId, sessionState.mSeq);
} catch (RemoteException e) {
- Slog.e(TAG, "error in onTrackSelected");
+ Slog.e(TAG, "error in onTrackSelected", e);
}
}
}
@@ -572,7 +582,7 @@
try {
sessionState.mClient.onVideoAvailable(sessionState.mSeq);
} catch (RemoteException e) {
- Slog.e(TAG, "error in onVideoAvailable");
+ Slog.e(TAG, "error in onVideoAvailable", e);
}
}
}
@@ -589,7 +599,7 @@
try {
sessionState.mClient.onVideoUnavailable(reason, sessionState.mSeq);
} catch (RemoteException e) {
- Slog.e(TAG, "error in onVideoUnavailable");
+ Slog.e(TAG, "error in onVideoUnavailable", e);
}
}
}
@@ -606,7 +616,7 @@
try {
sessionState.mClient.onContentAllowed(sessionState.mSeq);
} catch (RemoteException e) {
- Slog.e(TAG, "error in onContentAllowed");
+ Slog.e(TAG, "error in onContentAllowed", e);
}
}
}
@@ -623,7 +633,7 @@
try {
sessionState.mClient.onContentBlocked(rating, sessionState.mSeq);
} catch (RemoteException e) {
- Slog.e(TAG, "error in onContentBlocked");
+ Slog.e(TAG, "error in onContentBlocked", e);
}
}
}
@@ -642,7 +652,7 @@
sessionState.mClient.onLayoutSurface(left, top, right, bottom,
sessionState.mSeq);
} catch (RemoteException e) {
- Slog.e(TAG, "error in onLayoutSurface");
+ Slog.e(TAG, "error in onLayoutSurface", e);
}
}
}
@@ -660,7 +670,7 @@
sessionState.mClient.onSessionEvent(eventType, eventArgs,
sessionState.mSeq);
} catch (RemoteException e) {
- Slog.e(TAG, "error in onSessionEvent");
+ Slog.e(TAG, "error in onSessionEvent", e);
}
}
}
@@ -682,8 +692,8 @@
IBinder sessionToken, InputChannel channel, int seq) {
try {
client.onSessionCreated(inputId, sessionToken, channel, seq);
- } catch (RemoteException exception) {
- Slog.e(TAG, "error in onSessionCreated", exception);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "error in onSessionCreated", e);
}
}
@@ -697,7 +707,7 @@
try {
sessionState.mSession.release();
} catch (RemoteException e) {
- Slog.w(TAG, "session is already disapeared", e);
+ Slog.e(TAG, "session process has already died", e);
}
sessionState.mSession = null;
}
@@ -727,6 +737,10 @@
clientState.mSessionTokens.remove(sessionToken);
if (clientState.isEmpty()) {
userState.clientStateMap.remove(sessionState.mClient.asBinder());
+ if (userState.clientStateMap.isEmpty()) {
+ // No longer need to keep the callbacks since there is no client.
+ userState.callbackSet.clear();
+ }
}
}
@@ -767,26 +781,26 @@
private void notifyInputAddedLocked(UserState userState, String inputId) {
if (DEBUG) {
- Slog.d(TAG, "notifyInputAdded: inputId = " + inputId);
+ Slog.d(TAG, "notifyInputAddedLocked(inputId=" + inputId + ")");
}
for (ITvInputManagerCallback callback : userState.callbackSet) {
try {
callback.onInputAdded(inputId);
} catch (RemoteException e) {
- Slog.e(TAG, "Failed to report added input to callback.");
+ Slog.e(TAG, "failed to report added input to callback", e);
}
}
}
private void notifyInputRemovedLocked(UserState userState, String inputId) {
if (DEBUG) {
- Slog.d(TAG, "notifyInputRemovedLocked: inputId = " + inputId);
+ Slog.d(TAG, "notifyInputRemovedLocked(inputId=" + inputId + ")");
}
for (ITvInputManagerCallback callback : userState.callbackSet) {
try {
callback.onInputRemoved(inputId);
} catch (RemoteException e) {
- Slog.e(TAG, "Failed to report removed input to callback.");
+ Slog.e(TAG, "failed to report removed input to callback", e);
}
}
}
@@ -794,22 +808,22 @@
private void notifyInputStateChangedLocked(UserState userState, String inputId,
int state, ITvInputManagerCallback targetCallback) {
if (DEBUG) {
- Slog.d(TAG, "notifyInputStateChangedLocked: inputId = " + inputId
- + "; state = " + state);
+ Slog.d(TAG, "notifyInputStateChangedLocked(inputId=" + inputId
+ + ", state=" + state + ")");
}
if (targetCallback == null) {
for (ITvInputManagerCallback callback : userState.callbackSet) {
try {
callback.onInputStateChanged(inputId, state);
} catch (RemoteException e) {
- Slog.e(TAG, "Failed to report state change to callback.");
+ Slog.e(TAG, "failed to report state change to callback", e);
}
}
} else {
try {
targetCallback.onInputStateChanged(inputId, state);
} catch (RemoteException e) {
- Slog.e(TAG, "Failed to report state change to callback.");
+ Slog.e(TAG, "failed to report state change to callback", e);
}
}
}
@@ -890,8 +904,22 @@
final long identity = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
- UserState userState = getUserStateLocked(resolvedUserId);
+ final UserState userState = getUserStateLocked(resolvedUserId);
userState.callbackSet.add(callback);
+ try {
+ callback.asBinder().linkToDeath(new IBinder.DeathRecipient() {
+ @Override
+ public void binderDied() {
+ synchronized (mLock) {
+ if (userState.callbackSet != null) {
+ userState.callbackSet.remove(callback);
+ }
+ }
+ }
+ }, 0);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "client process has already died", e);
+ }
for (TvInputState state : userState.inputMap.values()) {
notifyInputStateChangedLocked(userState, state.mInfo.getId(),
state.mState, callback);
@@ -1076,7 +1104,7 @@
@Override
public void releaseSession(IBinder sessionToken, int userId) {
if (DEBUG) {
- Slog.d(TAG, "releaseSession(): " + sessionToken);
+ Slog.d(TAG, "releaseSession(sessionToken=" + sessionToken + ")");
}
final int callingUid = Binder.getCallingUid();
final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
@@ -1094,7 +1122,7 @@
@Override
public void setMainSession(IBinder sessionToken, int userId) {
if (DEBUG) {
- Slog.d(TAG, "setMainSession(): " + sessionToken);
+ Slog.d(TAG, "setMainSession(sessionToken=" + sessionToken + ")");
}
final int callingUid = Binder.getCallingUid();
final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
@@ -1263,7 +1291,7 @@
getSessionLocked(sessionToken, callingUid, resolvedUserId)
.requestUnblockContent(unblockedRating);
} catch (RemoteException e) {
- Slog.e(TAG, "error in unblockContent", e);
+ Slog.e(TAG, "error in requestUnblockContent", e);
}
}
} finally {
@@ -1324,7 +1352,7 @@
getSessionLocked(sessionToken, callingUid, resolvedUserId)
.appPrivateCommand(command, data);
} catch (RemoteException e) {
- Slog.e(TAG, "error in sendAppPrivateCommand", e);
+ Slog.e(TAG, "error in appPrivateCommand", e);
}
}
} finally {
@@ -1489,7 +1517,7 @@
synchronized (mLock) {
UserState userState = getUserStateLocked(resolvedUserId);
if (userState.inputMap.get(inputId) == null) {
- Slog.e(TAG, "Input not found for " + inputId);
+ Slog.e(TAG, "input not found for " + inputId);
return false;
}
for (SessionState sessionState : userState.sessionStateMap.values()) {
@@ -1986,7 +2014,7 @@
buildTvInputListLocked(mUserId);
mTvInputHardwareManager.removeTvInput(inputId);
} else {
- Slog.e(TAG, "TvInputInfo with inputId=" + inputId + " not found.");
+ Slog.e(TAG, "failed to remove input " + inputId);
}
}
}