android/frameworks/base/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
privatevoiddispatchPlaybackChange(boolean iplayerReleased){synchronized(mClients){// typical use case, nobody is listening, don't do any workif(mClients.isEmpty()){return;}}if(DEBUG){ Log.v(TAG,"dispatchPlaybackChange to "+ mClients.size()+" clients");}final List<AudioPlaybackConfiguration> configsSystem;// list of playback configurations for "public consumption". It is only computed if there// are non-system playback activity listeners.final List<AudioPlaybackConfiguration> configsPublic;synchronized(mPlayerLock){if(mPlayers.isEmpty()){return;}
configsSystem =newArrayList<AudioPlaybackConfiguration>(mPlayers.values());}synchronized(mClients){// was done at beginning of method, but could have changedif(mClients.isEmpty()){return;}
configsPublic = mHasPublicClients ?anonymizeForPublicConsumption(configsSystem): null;final Iterator<PlayMonitorClient> clientIterator = mClients.iterator();while(clientIterator.hasNext()){final PlayMonitorClient pmc = clientIterator.next();try{// do not spam the logs if there are problems communicating with this clientif(pmc.mErrorCount < PlayMonitorClient.MAX_ERRORS){if(pmc.mIsPrivileged){
pmc.mDispatcherCb.dispatchPlaybackConfigChange(configsSystem,
iplayerReleased);}else{// non-system clients don't have the control interface IPlayer, so// they don't need to flush commands when a player was released
pmc.mDispatcherCb.dispatchPlaybackConfigChange(configsPublic,false);}}}catch(RemoteException e){
pmc.mErrorCount++;
Log.e(TAG,"Error ("+ pmc.mErrorCount +") trying to dispatch playback config change to "+ pmc, e);}}}}