Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 382f4e6e authored by Jean-Michel Trivi's avatar Jean-Michel Trivi
Browse files

Fix bug 40640864 Use a death handler on audio focus changes from mode

Use a death handler when audio focus changes are caused by audio
 mode changes.

The bug comes from the fact that audio focus clients that use the
 audio mode for automatic focus handling didn't register a death
 handler, which was set to null. When such a client died, this
 handler was compared against the one to remove from the
 audio focus stack, which resulted in an NPE.
The fix consists in registering a valid IBinder object in the
 audio focus stack, even for clients whose focus requests originate
 from a change in audio mode, as implemented in the
 handleFocusForCalls() method.

Change-Id: Id9e1d3d10afcd99969285f6d60fc4d7dde1e4a10
parent ff23352e
Loading
Loading
Loading
Loading
+17 −21
Original line number Original line Diff line number Diff line
@@ -805,7 +805,7 @@ public class AudioService extends IAudioService.Stub {
            if (mode != mMode) {
            if (mode != mMode) {


                // automatically handle audio focus for mode changes
                // automatically handle audio focus for mode changes
                handleFocusForCalls(mMode, mode);
                handleFocusForCalls(mMode, mode, cb);


                if (AudioSystem.setPhoneState(mode) == AudioSystem.AUDIO_STATUS_OK) {
                if (AudioSystem.setPhoneState(mode) == AudioSystem.AUDIO_STATUS_OK) {
                    mMode = mode;
                    mMode = mode;
@@ -864,7 +864,7 @@ public class AudioService extends IAudioService.Stub {
    }
    }


    /** pre-condition: oldMode != newMode */
    /** pre-condition: oldMode != newMode */
    private void handleFocusForCalls(int oldMode, int newMode) {
    private void handleFocusForCalls(int oldMode, int newMode, IBinder cb) {
        // if ringing
        // if ringing
        if (newMode == AudioSystem.MODE_RINGTONE) {
        if (newMode == AudioSystem.MODE_RINGTONE) {
            // if not ringing silently
            // if not ringing silently
@@ -872,8 +872,8 @@ public class AudioService extends IAudioService.Stub {
            if (ringVolume > 0) {
            if (ringVolume > 0) {
                // request audio focus for the communication focus entry
                // request audio focus for the communication focus entry
                requestAudioFocus(AudioManager.STREAM_RING,
                requestAudioFocus(AudioManager.STREAM_RING,
                        AudioManager.AUDIOFOCUS_GAIN_TRANSIENT,
                        AudioManager.AUDIOFOCUS_GAIN_TRANSIENT, cb,
                        null, null /* both allowed to be null only for this clientId */,
                        null /* IAudioFocusDispatcher allowed to be null only for this clientId */,
                        IN_VOICE_COMM_FOCUS_ID /*clientId*/);
                        IN_VOICE_COMM_FOCUS_ID /*clientId*/);


            }
            }
@@ -884,8 +884,8 @@ public class AudioService extends IAudioService.Stub {
            // request audio focus for the communication focus entry
            // request audio focus for the communication focus entry
            // (it's ok if focus was already requested during ringing)
            // (it's ok if focus was already requested during ringing)
            requestAudioFocus(AudioManager.STREAM_RING,
            requestAudioFocus(AudioManager.STREAM_RING,
                    AudioManager.AUDIOFOCUS_GAIN_TRANSIENT,
                    AudioManager.AUDIOFOCUS_GAIN_TRANSIENT, cb,
                    null, null /* both allowed to be null only for this clientId */,
                    null /* IAudioFocusDispatcher allowed to be null only for this clientId */,
                    IN_VOICE_COMM_FOCUS_ID /*clientId*/);
                    IN_VOICE_COMM_FOCUS_ID /*clientId*/);
        }
        }
        // if exiting call
        // if exiting call
@@ -2547,10 +2547,9 @@ public class AudioService extends IAudioService.Stub {
        // the main stream type for the audio focus request is currently not used. It may
        // the main stream type for the audio focus request is currently not used. It may
        // potentially be used to handle multiple stream type-dependent audio focuses.
        // potentially be used to handle multiple stream type-dependent audio focuses.


        // we need a valid binder callback for clients other than the AudioService's phone
        // we need a valid binder callback for clients
        // state listener
        if (!cb.pingBinder()) {
        if (!IN_VOICE_COMM_FOCUS_ID.equals(clientId) && ((cb == null) || !cb.pingBinder())) {
            Log.e(TAG, " AudioFocus DOA client for requestAudioFocus(), aborting.");
            Log.i(TAG, " AudioFocus  DOA client for requestAudioFocus(), exiting");
            return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
            return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
        }
        }


@@ -2591,9 +2590,7 @@ public class AudioService extends IAudioService.Stub {
        }//synchronized(mAudioFocusLock)
        }//synchronized(mAudioFocusLock)


        // handle the potential premature death of the new holder of the focus
        // 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
        // (premature death == death before abandoning focus)
        // AudioService's phone state listener
        if (!IN_VOICE_COMM_FOCUS_ID.equals(clientId)) {
        // Register for client death notification
        // Register for client death notification
        AudioFocusDeathHandler afdh = new AudioFocusDeathHandler(cb);
        AudioFocusDeathHandler afdh = new AudioFocusDeathHandler(cb);
        try {
        try {
@@ -2602,7 +2599,6 @@ public class AudioService extends IAudioService.Stub {
            // client has already died!
            // client has already died!
            Log.w(TAG, "AudioFocus  requestAudioFocus() could not link to "+cb+" binder death");
            Log.w(TAG, "AudioFocus  requestAudioFocus() could not link to "+cb+" binder death");
        }
        }
        }


        return AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
        return AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
    }
    }