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

Commit 761daf75 authored by The Android Open Source Project's avatar The Android Open Source Project
Browse files

manual merge for b9c9d260

Merge commit 'b9c9d260'
parents d5aa122b b9c9d260
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -65947,7 +65947,7 @@
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 deprecated="deprecated"
 visibility="public"
>
<parameter name="mode" type="int">
@@ -66158,7 +66158,7 @@
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 deprecated="deprecated"
 visibility="public"
>
<parameter name="mode" type="int">
+50 −27
Original line number Diff line number Diff line
@@ -642,7 +642,9 @@ public class AudioManager {
     *           <var>false</var> to turn it off
     */
    public void setSpeakerphoneOn(boolean on){
        setRouting(MODE_IN_CALL, on ? ROUTE_SPEAKER : ROUTE_EARPIECE, ROUTE_ALL);
        // Temporary fix for issue #1713090 until audio routing is refactored in eclair release.
        // MODE_INVALID indicates to AudioService that setRouting() was initiated by AudioManager
        setRoutingP(MODE_INVALID, on ? ROUTE_SPEAKER: 0, ROUTE_SPEAKER);
    }

    /**
@@ -651,7 +653,7 @@ public class AudioManager {
     * @return true if speakerphone is on, false if it's off
     */
    public boolean isSpeakerphoneOn() {
        return (getRouting(MODE_IN_CALL) & ROUTE_SPEAKER) == 0 ? false : true;
        return (getRoutingP(MODE_IN_CALL) & ROUTE_SPEAKER) == 0 ? false : true;
     }

    /**
@@ -661,14 +663,9 @@ public class AudioManager {
     *           headset; <var>false</var> to route audio to/from phone earpiece
     */
    public void setBluetoothScoOn(boolean on){
        // Don't disable A2DP when turning off SCO.
        // A2DP does not affect in-call routing.
        setRouting(MODE_RINGTONE,
               on ? ROUTE_BLUETOOTH_SCO: ROUTE_SPEAKER, ROUTE_ALL & ~ROUTE_BLUETOOTH_A2DP);
        setRouting(MODE_NORMAL,
                on ? ROUTE_BLUETOOTH_SCO: ROUTE_SPEAKER, ROUTE_ALL & ~ROUTE_BLUETOOTH_A2DP);
        setRouting(MODE_IN_CALL,
                on ? ROUTE_BLUETOOTH_SCO: ROUTE_EARPIECE, ROUTE_ALL);
        // Temporary fix for issue #1713090 until audio routing is refactored in eclair release.
        // MODE_INVALID indicates to AudioService that setRouting() was initiated by AudioManager
        setRoutingP(MODE_INVALID, on ? ROUTE_BLUETOOTH_SCO: 0, ROUTE_BLUETOOTH_SCO);
    }

    /**
@@ -678,7 +675,7 @@ public class AudioManager {
     *         false if otherwise
     */
    public boolean isBluetoothScoOn() {
        return (getRouting(MODE_IN_CALL) & ROUTE_BLUETOOTH_SCO) == 0 ? false : true;
        return (getRoutingP(MODE_IN_CALL) & ROUTE_BLUETOOTH_SCO) == 0 ? false : true;
    }

    /**
@@ -688,12 +685,9 @@ public class AudioManager {
     *           headset; <var>false</var> disable A2DP audio
     */
    public void setBluetoothA2dpOn(boolean on){
        // the audio flinger chooses A2DP as a higher priority,
        // so there is no need to disable other routes.
        setRouting(MODE_RINGTONE,
               on ? ROUTE_BLUETOOTH_A2DP: 0, ROUTE_BLUETOOTH_A2DP);
        setRouting(MODE_NORMAL,
                on ? ROUTE_BLUETOOTH_A2DP: 0, ROUTE_BLUETOOTH_A2DP);
        // Temporary fix for issue #1713090 until audio routing is refactored in eclair release.
        // MODE_INVALID indicates to AudioService that setRouting() was initiated by AudioManager
        setRoutingP(MODE_INVALID, on ? ROUTE_BLUETOOTH_A2DP: 0, ROUTE_BLUETOOTH_A2DP);
    }

    /**
@@ -703,7 +697,7 @@ public class AudioManager {
     *         false if otherwise
     */
    public boolean isBluetoothA2dpOn() {
        return (getRouting(MODE_NORMAL) & ROUTE_BLUETOOTH_A2DP) == 0 ? false : true;
        return (getRoutingP(MODE_NORMAL) & ROUTE_BLUETOOTH_A2DP) == 0 ? false : true;
    }

    /**
@@ -714,14 +708,9 @@ public class AudioManager {
     * @hide
     */
    public void setWiredHeadsetOn(boolean on){
        // A2DP has higher priority than wired headset, so headset connect/disconnect events
        // should not affect A2DP routing
        setRouting(MODE_NORMAL,
                on ? ROUTE_HEADSET : ROUTE_SPEAKER, ROUTE_ALL & ~ROUTE_BLUETOOTH_A2DP);
        setRouting(MODE_RINGTONE,
                on ? ROUTE_HEADSET | ROUTE_SPEAKER : ROUTE_SPEAKER, ROUTE_ALL & ~ROUTE_BLUETOOTH_A2DP);
        setRouting(MODE_IN_CALL,
                on ? ROUTE_HEADSET : ROUTE_EARPIECE, ROUTE_ALL);
        // Temporary fix for issue #1713090 until audio routing is refactored in eclair release.
        // MODE_INVALID indicates to AudioService that setRouting() was initiated by AudioManager
        setRoutingP(MODE_INVALID, on ? ROUTE_HEADSET: 0, ROUTE_HEADSET);
    }

    /**
@@ -732,7 +721,7 @@ public class AudioManager {
     * @hide
     */
    public boolean isWiredHeadsetOn() {
        return (getRouting(MODE_NORMAL) & ROUTE_HEADSET) == 0 ? false : true;
        return (getRoutingP(MODE_NORMAL) & ROUTE_HEADSET) == 0 ? false : true;
    }

    /**
@@ -860,7 +849,11 @@ public class AudioManager {
     *               more of ROUTE_xxx types. Set bits indicate that route should be on
     * @param mask   bit vector of routes to change, created from one or more of
     * ROUTE_xxx types. Unset bits indicate the route should be left unchanged
     *
     * @deprecated   Do not set audio routing directly, use setSpeakerphoneOn(),
     * setBluetoothScoOn(), setBluetoothA2dpOn() and setWiredHeadsetOn() methods instead.
     */

    public void setRouting(int mode, int routes, int mask) {
        IAudioService service = getService();
        try {
@@ -876,7 +869,10 @@ public class AudioManager {
     * @param mode audio mode to get route (e.g., MODE_RINGTONE)
     * @return an audio route bit vector that can be compared with ROUTE_xxx
     * bits
     * @deprecated   Do not query audio routing directly, use isSpeakerphoneOn(),
     * isBluetoothScoOn(), isBluetoothA2dpOn() and isWiredHeadsetOn() methods instead.
     */
    @Deprecated
    public int getRouting(int mode) {
        IAudioService service = getService();
        try {
@@ -1076,4 +1072,31 @@ public class AudioManager {
      * {@hide}
      */
     private IBinder mICallBack = new Binder();

     /**
      * {@hide}
      */
     private void setRoutingP(int mode, int routes, int mask) {
         IAudioService service = getService();
         try {
             service.setRouting(mode, routes, mask);
         } catch (RemoteException e) {
             Log.e(TAG, "Dead object in setRouting", e);
         }
     }


     /**
      * {@hide}
      */
     private int getRoutingP(int mode) {
         IAudioService service = getService();
         try {
             return service.getRouting(mode);
         } catch (RemoteException e) {
             Log.e(TAG, "Dead object in getRouting", e);
             return -1;
         }
     }

}
+167 −9
Original line number Diff line number Diff line
@@ -100,6 +100,10 @@ public class AudioService extends IAudioService.Stub {
    private int[] mRoutes = new int[AudioSystem.NUM_MODES];
    private Object mSettingsLock = new Object();
    private boolean mMediaServerOk;
    private boolean mSpeakerIsOn;
    private boolean mBluetoothScoIsConnected;
    private boolean mHeadsetIsConnected;
    private boolean mBluetoothA2dpIsConnected;

    private SoundPool mSoundPool;
    private Object mSoundEffectsLock = new Object();
@@ -189,6 +193,10 @@ public class AudioService extends IAudioService.Stub {
        mMediaServerOk = true;
        AudioSystem.setErrorCallback(mAudioSystemCallback);
        loadSoundEffects();
        mSpeakerIsOn = false;
        mBluetoothScoIsConnected = false;
        mHeadsetIsConnected = false;
        mBluetoothA2dpIsConnected = false;
    }

    private void createAudioSystemThread() {
@@ -606,9 +614,10 @@ public class AudioService extends IAudioService.Stub {
        }
        synchronized (mSettingsLock) {
            if (mode != mMode) {
                AudioSystem.setMode(mode);
                if (AudioSystem.setMode(mode) == AudioSystem.AUDIO_STATUS_OK) {
                    mMode = mode;
                }
            }
            int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE);
            int index = mStreamStates[streamType].mIndex;
            syncRingerAndNotificationStreamVolume(streamType, index, true);
@@ -623,20 +632,169 @@ public class AudioService extends IAudioService.Stub {

    /** @see AudioManager#setRouting(int, int, int) */
    public void setRouting(int mode, int routes, int mask) {
        int incallMask = 0;
        int ringtoneMask = 0;
        int normalMask = 0;

        if (!checkAudioSettingsPermission("setRouting()")) {
            return;
        }
        synchronized (mSettingsLock) {
            if ((mRoutes[mode] & mask) != (routes & mask)) {
                AudioSystem.setRouting(mode, routes, mask);
                mRoutes[mode] = (mRoutes[mode] & ~mask) | (routes & mask);
            // Temporary fix for issue #1713090 until audio routing is refactored in eclair release.
            // mode AudioSystem.MODE_INVALID is used only by the following AudioManager methods:
            // setWiredHeadsetOn(), setBluetoothA2dpOn(), setBluetoothScoOn() and setSpeakerphoneOn().
            // If applications are using AudioManager.setRouting() that is now deprecated, the routing
            // command will be ignored.
            if (mode == AudioSystem.MODE_INVALID) {
                switch (mask) {
                case AudioSystem.ROUTE_SPEAKER:
                    // handle setSpeakerphoneOn()
                    if (routes != 0 && !mSpeakerIsOn) {
                        mSpeakerIsOn = true;
                        mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_SPEAKER;
                        incallMask = AudioSystem.ROUTE_ALL;
                    } else if (mSpeakerIsOn) {
                        mSpeakerIsOn = false;
                        if (mBluetoothScoIsConnected) {
                            mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_BLUETOOTH_SCO;
                        } else if (mHeadsetIsConnected) {
                            mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_HEADSET;
                        } else {
                            mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_EARPIECE;
                        }
                        incallMask = AudioSystem.ROUTE_ALL;
                    }
                    break;

                case AudioSystem.ROUTE_BLUETOOTH_SCO:
                    // handle setBluetoothScoOn()
                    if (routes != 0 && !mBluetoothScoIsConnected) {
                        mBluetoothScoIsConnected = true;
                        mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_BLUETOOTH_SCO;
                        mRoutes[AudioSystem.MODE_RINGTONE] = (mRoutes[AudioSystem.MODE_RINGTONE] & AudioSystem.ROUTE_BLUETOOTH_A2DP) |
                                                              AudioSystem.ROUTE_BLUETOOTH_SCO;
                        mRoutes[AudioSystem.MODE_NORMAL] = (mRoutes[AudioSystem.MODE_NORMAL] & AudioSystem.ROUTE_BLUETOOTH_A2DP) |
                                                            AudioSystem.ROUTE_BLUETOOTH_SCO;
                        incallMask = AudioSystem.ROUTE_ALL;
                        // A2DP has higher priority than SCO headset, so headset connect/disconnect events
                        // should not affect A2DP routing
                        ringtoneMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
                        normalMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
                    } else if (mBluetoothScoIsConnected) {
                        mBluetoothScoIsConnected = false;
                        if (mHeadsetIsConnected) {
                            mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_HEADSET;
                            mRoutes[AudioSystem.MODE_RINGTONE] = (mRoutes[AudioSystem.MODE_RINGTONE] & AudioSystem.ROUTE_BLUETOOTH_A2DP) |
                                                                 (AudioSystem.ROUTE_HEADSET|AudioSystem.ROUTE_SPEAKER);
                            mRoutes[AudioSystem.MODE_NORMAL] = (mRoutes[AudioSystem.MODE_NORMAL] & AudioSystem.ROUTE_BLUETOOTH_A2DP) |
                                                               AudioSystem.ROUTE_HEADSET;
                        } else {
                            if (mSpeakerIsOn) {
                                mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_SPEAKER;
                            } else {
                                mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_EARPIECE;
                            }
                            mRoutes[AudioSystem.MODE_RINGTONE] = (mRoutes[AudioSystem.MODE_RINGTONE] & AudioSystem.ROUTE_BLUETOOTH_A2DP) |
                                                                 AudioSystem.ROUTE_SPEAKER;
                            mRoutes[AudioSystem.MODE_NORMAL] = (mRoutes[AudioSystem.MODE_NORMAL] & AudioSystem.ROUTE_BLUETOOTH_A2DP) |
                                                               AudioSystem.ROUTE_SPEAKER;
                        }
                        incallMask = AudioSystem.ROUTE_ALL;
                        // A2DP has higher priority than SCO headset, so headset connect/disconnect events
                        // should not affect A2DP routing
                        ringtoneMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
                        normalMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
                    }
                    break;

                case AudioSystem.ROUTE_HEADSET:
                    // handle setWiredHeadsetOn()
                    if (routes != 0 && !mHeadsetIsConnected) {
                        mHeadsetIsConnected = true;
                        // do not act upon headset connection if bluetooth SCO is connected to match phone app behavior
                        if (!mBluetoothScoIsConnected) {
                            mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_HEADSET;
                            mRoutes[AudioSystem.MODE_RINGTONE] = (mRoutes[AudioSystem.MODE_RINGTONE] & AudioSystem.ROUTE_BLUETOOTH_A2DP) |
                                                                 (AudioSystem.ROUTE_HEADSET|AudioSystem.ROUTE_SPEAKER);
                            mRoutes[AudioSystem.MODE_NORMAL] = (mRoutes[AudioSystem.MODE_NORMAL] & AudioSystem.ROUTE_BLUETOOTH_A2DP) |
                                                               AudioSystem.ROUTE_HEADSET;
                            incallMask = AudioSystem.ROUTE_ALL;
                            // A2DP has higher priority than wired headset, so headset connect/disconnect events
                            // should not affect A2DP routing
                            ringtoneMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
                            normalMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
                        }
                    } else if (mHeadsetIsConnected) {
                        mHeadsetIsConnected = false;
                        // do not act upon headset disconnection if bluetooth SCO is connected to match phone app behavior
                        if (!mBluetoothScoIsConnected) {
                            if (mSpeakerIsOn) {
                                mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_SPEAKER;
                            } else {
                                mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_EARPIECE;
                            }
                            mRoutes[AudioSystem.MODE_RINGTONE] = (mRoutes[AudioSystem.MODE_RINGTONE] & AudioSystem.ROUTE_BLUETOOTH_A2DP) |
                                                                 AudioSystem.ROUTE_SPEAKER;
                            mRoutes[AudioSystem.MODE_NORMAL] = (mRoutes[AudioSystem.MODE_NORMAL] & AudioSystem.ROUTE_BLUETOOTH_A2DP) |
                                                               AudioSystem.ROUTE_SPEAKER;

                            incallMask = AudioSystem.ROUTE_ALL;
                            // A2DP has higher priority than wired headset, so headset connect/disconnect events
                            // should not affect A2DP routing
                            ringtoneMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
                            normalMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
                        }
                    }
                    break;

                case AudioSystem.ROUTE_BLUETOOTH_A2DP:
                    // handle setBluetoothA2dpOn()
                    if (routes != 0 && !mBluetoothA2dpIsConnected) {
                        mBluetoothA2dpIsConnected = true;
                        mRoutes[AudioSystem.MODE_RINGTONE] |= AudioSystem.ROUTE_BLUETOOTH_A2DP;
                        mRoutes[AudioSystem.MODE_NORMAL] |= AudioSystem.ROUTE_BLUETOOTH_A2DP;
                        // the audio flinger chooses A2DP as a higher priority,
                        // so there is no need to disable other routes.
                        ringtoneMask = AudioSystem.ROUTE_BLUETOOTH_A2DP;
                        normalMask = AudioSystem.ROUTE_BLUETOOTH_A2DP;
                    } else if (mBluetoothA2dpIsConnected) {
                        mBluetoothA2dpIsConnected = false;
                        mRoutes[AudioSystem.MODE_RINGTONE] &= ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
                        mRoutes[AudioSystem.MODE_NORMAL] &= ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
                        // the audio flinger chooses A2DP as a higher priority,
                        // so there is no need to disable other routes.
                        ringtoneMask = AudioSystem.ROUTE_BLUETOOTH_A2DP;
                        normalMask = AudioSystem.ROUTE_BLUETOOTH_A2DP;
                    }
                    break;
                }
                
                // incallMask is != 0 means we must apply ne routing to MODE_IN_CALL mode
                if (incallMask != 0) {
                    AudioSystem.setRouting(AudioSystem.MODE_IN_CALL,
                                           mRoutes[AudioSystem.MODE_IN_CALL],
                                           incallMask);
                }
                // ringtoneMask is != 0 means we must apply ne routing to MODE_RINGTONE mode
                if (ringtoneMask != 0) {
                    AudioSystem.setRouting(AudioSystem.MODE_RINGTONE,
                                           mRoutes[AudioSystem.MODE_RINGTONE],
                                           ringtoneMask);
                }
                // normalMask is != 0 means we must apply ne routing to MODE_NORMAL mode
                if (normalMask != 0) {
                    AudioSystem.setRouting(AudioSystem.MODE_NORMAL,
                                           mRoutes[AudioSystem.MODE_NORMAL],
                                           normalMask);
                }

                int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE);
                int index = mStreamStates[streamType].mIndex;
                syncRingerAndNotificationStreamVolume(streamType, index, true);
                setStreamVolumeInt(streamType, index, true);
            }
        }
    }

    /** @see AudioManager#getRouting(int) */
    public int getRouting(int mode) {