diff options
-rw-r--r-- | media/java/android/media/AudioManager.java | 14 | ||||
-rw-r--r-- | media/java/android/media/AudioService.java | 33 | ||||
-rw-r--r-- | services/java/com/android/server/NotificationPlayer.java | 15 |
3 files changed, 34 insertions, 28 deletions
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 47e2da2..affb5ef 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -1382,7 +1382,7 @@ public class AudioManager { } /** - * Register a listener for audio focus updates. + * TODO hide */ public void registerAudioFocusListener(OnAudioFocusChangeListener l) { synchronized(mFocusListenerLock) { @@ -1394,16 +1394,10 @@ public class AudioManager { } /** - * TODO document for SDK + * TODO hide */ public void unregisterAudioFocusListener(OnAudioFocusChangeListener l) { - // notify service to remove it from audio focus stack - IAudioService service = getService(); - try { - service.unregisterAudioFocusClient(getIdForAudioFocusListener(l)); - } catch (RemoteException e) { - Log.e(TAG, "Can't call unregisterFocusClient() from AudioService due to "+e); - } + // remove locally synchronized(mFocusListenerLock) { mAudioFocusIdListenerMap.remove(getIdForAudioFocusListener(l)); @@ -1462,7 +1456,7 @@ public class AudioManager { */ public int abandonAudioFocus(OnAudioFocusChangeListener l) { int status = AUDIOFOCUS_REQUEST_FAILED; - registerAudioFocusListener(l); + unregisterAudioFocusListener(l); IAudioService service = getService(); try { status = service.abandonAudioFocus(mAudioFocusDispatcher, diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java index d55d0a5..5c278d9 100644 --- a/media/java/android/media/AudioService.java +++ b/media/java/android/media/AudioService.java @@ -1930,6 +1930,8 @@ public class AudioService extends IAudioService.Stub { */ private final static String IN_VOICE_COMM_FOCUS_ID = "AudioFocus_For_Phone_Ring_And_Calls"; + private final static Object mAudioFocusLock = new Object(); + private PhoneStateListener mPhoneStateListener = new PhoneStateListener() { @Override public void onCallStateChanged(int state, String incomingNumber) { @@ -2000,7 +2002,7 @@ public class AudioService extends IAudioService.Stub { */ private void dumpFocusStack(PrintWriter pw) { pw.println("\nAudio Focus stack entries:"); - synchronized(mFocusStack) { + synchronized(mAudioFocusLock) { Iterator<FocusStackEntry> stackIterator = mFocusStack.iterator(); while(stackIterator.hasNext()) { FocusStackEntry fse = stackIterator.next(); @@ -2091,7 +2093,7 @@ public class AudioService extends IAudioService.Stub { } public void binderDied() { - synchronized(mFocusStack) { + synchronized(mAudioFocusLock) { Log.w(TAG, " AudioFocus audio focus client died"); removeFocusStackEntryForClient(mCb); } @@ -2117,11 +2119,11 @@ public class AudioService extends IAudioService.Stub { return AudioManager.AUDIOFOCUS_REQUEST_FAILED; } - if (!canReassignAudioFocus()) { - return AudioManager.AUDIOFOCUS_REQUEST_FAILED; - } + synchronized(mAudioFocusLock) { + if (!canReassignAudioFocus()) { + return AudioManager.AUDIOFOCUS_REQUEST_FAILED; + } - synchronized(mFocusStack) { if (!mFocusStack.empty() && mFocusStack.peek().mClientId.equals(clientId)) { // if focus is already owned by this client and the reason for acquiring the focus // hasn't changed, don't do anything @@ -2151,7 +2153,7 @@ public class AudioService extends IAudioService.Stub { // push focus requester at the top of the audio focus stack mFocusStack.push(new FocusStackEntry(mainStreamType, focusChangeHint, false, fd, cb, clientId)); - }//synchronized(mFocusStack) + }//synchronized(mAudioFocusLock) // handle the potential premature death of the new holder of the focus // (premature death == death before abandoning focus) for a client which is not the @@ -2173,10 +2175,17 @@ public class AudioService extends IAudioService.Stub { /** @see AudioManager#abandonAudioFocus(IAudioFocusDispatcher) */ public int abandonAudioFocus(IAudioFocusDispatcher fl, String clientId) { Log.i(TAG, " AudioFocus abandonAudioFocus() from " + clientId); - - // this will take care of notifying the new focus owner if needed - synchronized(mFocusStack) { - removeFocusStackEntry(clientId, true); + try { + // this will take care of notifying the new focus owner if needed + synchronized(mAudioFocusLock) { + removeFocusStackEntry(clientId, true); + } + } catch (java.util.ConcurrentModificationException cme) { + // Catching this exception here is temporary. It is here just to prevent + // a crash seen when the "Silent" notification is played. This is believed to be fixed + // but this try catch block is left just to be safe. + Log.e(TAG, "FATAL EXCEPTION AudioFocus abandonAudioFocus() caused " + cme); + cme.printStackTrace(); } return AudioManager.AUDIOFOCUS_REQUEST_GRANTED; @@ -2184,7 +2193,7 @@ public class AudioService extends IAudioService.Stub { public void unregisterAudioFocusClient(String clientId) { - synchronized(mFocusStack) { + synchronized(mAudioFocusLock) { removeFocusStackEntry(clientId, false); } } diff --git a/services/java/com/android/server/NotificationPlayer.java b/services/java/com/android/server/NotificationPlayer.java index 0b1a03b..52d2381 100644 --- a/services/java/com/android/server/NotificationPlayer.java +++ b/services/java/com/android/server/NotificationPlayer.java @@ -88,12 +88,15 @@ public class NotificationPlayer implements OnCompletionListener { player.setDataSource(mCmd.context, mCmd.uri); player.setLooping(mCmd.looping); player.prepare(); - if (mCmd.looping) { - audioManager.requestAudioFocus(null, mCmd.stream, - AudioManager.AUDIOFOCUS_GAIN); - } else { - audioManager.requestAudioFocus(null, mCmd.stream, - AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK); + if ((mCmd.uri != null) && (mCmd.uri.getEncodedPath() != null) + && (mCmd.uri.getEncodedPath().length() > 0)) { + if (mCmd.looping) { + audioManager.requestAudioFocus(null, mCmd.stream, + AudioManager.AUDIOFOCUS_GAIN); + } else { + audioManager.requestAudioFocus(null, mCmd.stream, + AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK); + } } player.setOnCompletionListener(NotificationPlayer.this); player.start(); |