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

Commit 4dd3674e authored by Jean-Michel Trivi's avatar Jean-Michel Trivi
Browse files

Bug 5567648 disassociate audio mode and audio focus

Don't automatically change the audio focus when
 the audio mode changes. This is best handled by the
 applications that change the audio mode so they
 can address their usecases as they please (for
 instance to define the behavior when switching calls).
Replaced the implicit "mode to focus" behavior with
 two methods to request and abandon audio focus. These
 methods are only to be used by the framework, and maintain
 the logic in AudioService to prevent other apps to request
 audio focus during a call.
A susequent change will update com.android.internal.telephony.CallManager
 to take advantage of these two methods.

Change-Id: If84ebd508e985083e8cac82ece44940c72b5c669
parent c6854d43
Loading
Loading
Loading
Loading
+37 −2
Original line number Diff line number Diff line
@@ -1649,11 +1649,46 @@ public class AudioManager {
                    mAudioFocusDispatcher, getIdForAudioFocusListener(l),
                    mContext.getPackageName() /* package name */);
        } catch (RemoteException e) {
            Log.e(TAG, "Can't call requestAudioFocus() from AudioService due to "+e);
            Log.e(TAG, "Can't call requestAudioFocus() on AudioService due to "+e);
        }
        return status;
    }

    /**
     * @hide
     * Used internally by telephony package to request audio focus. Will cause the focus request
     * to be associated with the "voice communication" identifier only used in AudioService
     * to identify this use case.
     * @param streamType use STREAM_RING for focus requests when ringing, VOICE_CALL for
     *    the establishment of the call
     * @param durationHint the type of focus request. AUDIOFOCUS_GAIN_TRANSIENT is recommended so
     *    media applications resume after a call
     */
    public void requestAudioFocusForCall(int streamType, int durationHint) {
        IAudioService service = getService();
        try {
            service.requestAudioFocus(streamType, durationHint, mICallBack, null,
                    AudioService.IN_VOICE_COMM_FOCUS_ID,
                    "system" /* dump-friendly package name */);
        } catch (RemoteException e) {
            Log.e(TAG, "Can't call requestAudioFocusForCall() on AudioService due to "+e);
        }
    }

    /**
     * @hide
     * Used internally by telephony package to abandon audio focus, typically after a call or
     * when ringing ends and the call is rejected or not answered.
     * Should match one or more calls to {@link #requestAudioFocusForCall(int, int)}.
     */
    public void abandonAudioFocusForCall() {
        IAudioService service = getService();
        try {
            service.abandonAudioFocus(null, AudioService.IN_VOICE_COMM_FOCUS_ID);
        } catch (RemoteException e) {
            Log.e(TAG, "Can't call abandonAudioFocusForCall() on AudioService due to "+e);
        }
    }

    /**
     *  Abandon audio focus. Causes the previous focus owner, if any, to receive focus.
@@ -1668,7 +1703,7 @@ public class AudioManager {
            status = service.abandonAudioFocus(mAudioFocusDispatcher,
                    getIdForAudioFocusListener(l));
        } catch (RemoteException e) {
            Log.e(TAG, "Can't call abandonAudioFocus() from AudioService due to "+e);
            Log.e(TAG, "Can't call abandonAudioFocus() on AudioService due to "+e);
        }
        return status;
    }
+3 −38
Original line number Diff line number Diff line
@@ -992,8 +992,6 @@ public class AudioService extends IAudioService.Stub {
            if (mode != mMode) {
                status = AudioSystem.setPhoneState(mode);
                if (status == AudioSystem.AUDIO_STATUS_OK) {
                    // automatically handle audio focus for mode changes
                    handleFocusForCalls(mMode, mode, cb);
                    mMode = mode;
                } else {
                    if (hdlr != null) {
@@ -1024,40 +1022,6 @@ public class AudioService extends IAudioService.Stub {
        return newModeOwnerPid;
    }

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

            }
        }
        // if entering call
        else if ((newMode == AudioSystem.MODE_IN_CALL)
                || (newMode == AudioSystem.MODE_IN_COMMUNICATION)) {
            // request audio focus for the communication focus entry
            // (it's ok if focus was already requested during ringing)
            requestAudioFocus(AudioManager.STREAM_RING,
                    AudioManager.AUDIOFOCUS_GAIN_TRANSIENT, cb,
                    null /* IAudioFocusDispatcher allowed to be null only for this clientId */,
                    IN_VOICE_COMM_FOCUS_ID /*clientId*/,
                    "system");
        }
        // if exiting call
        else if (newMode == AudioSystem.MODE_NORMAL) {
            // abandon audio focus for communication focus entry
            abandonAudioFocus(null, IN_VOICE_COMM_FOCUS_ID);
        }
    }

    /** @see AudioManager#getMode() */
    public int getMode() {
        return mMode;
@@ -2896,9 +2860,10 @@ public class AudioService extends IAudioService.Stub {
    //==========================================================================================

    /* constant to identify focus stack entry that is used to hold the focus while the phone
     * is ringing or during a call
     * is ringing or during a call. Used by com.android.internal.telephony.CallManager when
     * entering and exiting calls.
     */
    private final static String IN_VOICE_COMM_FOCUS_ID = "AudioFocus_For_Phone_Ring_And_Calls";
    public final static String IN_VOICE_COMM_FOCUS_ID = "AudioFocus_For_Phone_Ring_And_Calls";

    private final static Object mAudioFocusLock = new Object();