Merge "Updates to remote control client (un)registration"

This commit is contained in:
Jean-Michel Trivi
2013-01-02 11:04:40 -08:00
committed by Android (Google) Code Review

View File

@@ -5324,58 +5324,62 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
synchronized(mAudioFocusLock) { synchronized(mAudioFocusLock) {
synchronized(mRCStack) { synchronized(mRCStack) {
// store the new display information // store the new display information
Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator(); try {
while(stackIterator.hasNext()) { for (int index = mRCStack.size()-1; index >= 0; index--) {
RemoteControlStackEntry rcse = stackIterator.next(); final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
if(rcse.mMediaIntent.equals(mediaIntent)) { if(rcse.mMediaIntent.equals(mediaIntent)) {
// already had a remote control client? // already had a remote control client?
if (rcse.mRcClientDeathHandler != null) { if (rcse.mRcClientDeathHandler != null) {
// stop monitoring the old client's death // stop monitoring the old client's death
rcse.unlinkToRcClientDeath(); rcse.unlinkToRcClientDeath();
} }
// save the new remote control client // save the new remote control client
rcse.mRcClient = rcClient; rcse.mRcClient = rcClient;
rcse.mCallingPackageName = callingPackageName; rcse.mCallingPackageName = callingPackageName;
rcse.mCallingUid = Binder.getCallingUid(); rcse.mCallingUid = Binder.getCallingUid();
if (rcClient == null) { if (rcClient == null) {
// here rcse.mRcClientDeathHandler is null; // here rcse.mRcClientDeathHandler is null;
rcse.resetPlaybackInfo(); rcse.resetPlaybackInfo();
break;
}
rccId = rcse.mRccId;
// there is a new (non-null) client:
// 1/ give the new client the current display (if any)
if (mRcDisplay != null) {
try {
rcse.mRcClient.plugRemoteControlDisplay(mRcDisplay);
} catch (RemoteException e) {
Log.e(TAG, "Error connecting RCD to RCC in RCC registration",e);
}
}
// 2/ monitor the new client's death
IBinder b = rcse.mRcClient.asBinder();
RcClientDeathHandler rcdh =
new RcClientDeathHandler(b, rcse.mMediaIntent);
try {
b.linkToDeath(rcdh, 0);
} catch (RemoteException e) {
// remote control client is DOA, disqualify it
Log.w(TAG, "registerRemoteControlClient() has a dead client " + b);
rcse.mRcClient = null;
}
rcse.mRcClientDeathHandler = rcdh;
break; break;
} }
rccId = rcse.mRccId; }//for
} catch (ArrayIndexOutOfBoundsException e) {
// there is a new (non-null) client: // not expected to happen, indicates improper concurrent modification
// 1/ give the new client the current display (if any) Log.e(TAG, "Wrong index accessing RC stack, lock error? ", e);
if (mRcDisplay != null) {
try {
rcse.mRcClient.plugRemoteControlDisplay(mRcDisplay);
} catch (RemoteException e) {
Log.e(TAG, "Error connecting remote control display to client: "+e);
e.printStackTrace();
}
}
// 2/ monitor the new client's death
IBinder b = rcse.mRcClient.asBinder();
RcClientDeathHandler rcdh =
new RcClientDeathHandler(b, rcse.mMediaIntent);
try {
b.linkToDeath(rcdh, 0);
} catch (RemoteException e) {
// remote control client is DOA, disqualify it
Log.w(TAG, "registerRemoteControlClient() has a dead client " + b);
rcse.mRcClient = null;
}
rcse.mRcClientDeathHandler = rcdh;
break;
}
} }
// if the eventReceiver is at the top of the stack // if the eventReceiver is at the top of the stack
// then check for potential refresh of the remote controls // then check for potential refresh of the remote controls
if (isCurrentRcController(mediaIntent)) { if (isCurrentRcController(mediaIntent)) {
checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL); checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
} }
} }//synchronized(mRCStack)
} }//synchronized(mAudioFocusLock)
return rccId; return rccId;
} }
@@ -5387,18 +5391,30 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
IRemoteControlClient rcClient) { IRemoteControlClient rcClient) {
synchronized(mAudioFocusLock) { synchronized(mAudioFocusLock) {
synchronized(mRCStack) { synchronized(mRCStack) {
Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator(); boolean topRccChange = false;
while(stackIterator.hasNext()) { try {
RemoteControlStackEntry rcse = stackIterator.next(); for (int index = mRCStack.size()-1; index >= 0; index--) {
if ((rcse.mMediaIntent.equals(mediaIntent)) final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
&& rcClient.equals(rcse.mRcClient)) { if ((rcse.mMediaIntent.equals(mediaIntent))
// we found the IRemoteControlClient to unregister && rcClient.equals(rcse.mRcClient)) {
// stop monitoring its death // we found the IRemoteControlClient to unregister
rcse.unlinkToRcClientDeath(); // stop monitoring its death
// reset the client-related fields rcse.unlinkToRcClientDeath();
rcse.mRcClient = null; // reset the client-related fields
rcse.mCallingPackageName = null; rcse.mRcClient = null;
rcse.mCallingPackageName = null;
topRccChange = (index == mRCStack.size()-1);
// there can only be one matching RCC in the RC stack, we're done
break;
}
} }
} catch (ArrayIndexOutOfBoundsException e) {
// not expected to happen, indicates improper concurrent modification
Log.e(TAG, "Wrong index accessing RC stack, lock error? ", e);
}
if (topRccChange) {
// no more RCC for the RCD, check for potential refresh of the remote controls
checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
} }
} }
} }