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

Commit 13f94dc5 authored by Glenn Kasten's avatar Glenn Kasten Committed by Android (Google) Code Review
Browse files

Merge "Fix race conditions related to ringer mode"

parents 4e719144 ba195ebc
Loading
Loading
Loading
Loading
+54 −35
Original line number Original line Diff line number Diff line
@@ -145,7 +145,8 @@ public class AudioService extends IAudioService.Stub {
    private SettingsObserver mSettingsObserver;
    private SettingsObserver mSettingsObserver;


    private int mMode;
    private int mMode;
    private Object mSettingsLock = new Object();
    // protects mRingerMode
    private final Object mSettingsLock = new Object();
    private boolean mMediaServerOk;
    private boolean mMediaServerOk;


    private SoundPool mSoundPool;
    private SoundPool mSoundPool;
@@ -236,6 +237,7 @@ public class AudioService extends IAudioService.Stub {
     * {@link AudioManager#RINGER_MODE_SILENT}, or
     * {@link AudioManager#RINGER_MODE_SILENT}, or
     * {@link AudioManager#RINGER_MODE_VIBRATE}.
     * {@link AudioManager#RINGER_MODE_VIBRATE}.
     */
     */
    // protected by mSettingsLock
    private int mRingerMode;
    private int mRingerMode;


    /** @see System#MODE_RINGER_STREAMS_AFFECTED */
    /** @see System#MODE_RINGER_STREAMS_AFFECTED */
@@ -442,12 +444,15 @@ public class AudioService extends IAudioService.Stub {
    private void readPersistedSettings() {
    private void readPersistedSettings() {
        final ContentResolver cr = mContentResolver;
        final ContentResolver cr = mContentResolver;


        mRingerMode = System.getInt(cr, System.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL);
        int ringerMode = System.getInt(cr, System.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL);
        // sanity check in case the settings are restored from a device with incompatible
        // sanity check in case the settings are restored from a device with incompatible
        // ringer modes
        // ringer modes
        if (!AudioManager.isValidRingerMode(mRingerMode)) {
        if (!AudioManager.isValidRingerMode(ringerMode)) {
            mRingerMode = AudioManager.RINGER_MODE_NORMAL;
            ringerMode = AudioManager.RINGER_MODE_NORMAL;
            System.putInt(cr, System.MODE_RINGER, mRingerMode);
            System.putInt(cr, System.MODE_RINGER, ringerMode);
        }
        synchronized(mSettingsLock) {
            mRingerMode = ringerMode;
        }
        }


        mVibrateSetting = System.getInt(cr, System.VIBRATE_ON, 0);
        mVibrateSetting = System.getInt(cr, System.VIBRATE_ON, 0);
@@ -473,7 +478,7 @@ public class AudioService extends IAudioService.Stub {
        // Each stream will read its own persisted settings
        // Each stream will read its own persisted settings


        // Broadcast the sticky intent
        // Broadcast the sticky intent
        broadcastRingerMode();
        broadcastRingerMode(ringerMode);


        // Broadcast vibrate settings
        // Broadcast vibrate settings
        broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER);
        broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER);
@@ -538,8 +543,9 @@ public class AudioService extends IAudioService.Stub {
        if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
        if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
                streamTypeAlias == AudioSystem.STREAM_RING ||
                streamTypeAlias == AudioSystem.STREAM_RING ||
                (!mVoiceCapable && streamTypeAlias == AudioSystem.STREAM_MUSIC)) {
                (!mVoiceCapable && streamTypeAlias == AudioSystem.STREAM_MUSIC)) {
            int ringerMode = getRingerMode();
            // do not vibrate if already in vibrate mode
            // do not vibrate if already in vibrate mode
            if (mRingerMode == AudioManager.RINGER_MODE_VIBRATE) {
            if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
                flags &= ~AudioManager.FLAG_VIBRATE;
                flags &= ~AudioManager.FLAG_VIBRATE;
            }
            }
            // Check if the ringer mode changes with this volume adjustment. If
            // Check if the ringer mode changes with this volume adjustment. If
@@ -599,7 +605,7 @@ public class AudioService extends IAudioService.Stub {
        // setting ring or notifications volume to 0 on voice capable devices enters silent mode
        // setting ring or notifications volume to 0 on voice capable devices enters silent mode
        if (mVoiceCapable && (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
        if (mVoiceCapable && (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
                (STREAM_VOLUME_ALIAS[streamType] == AudioSystem.STREAM_RING))) {
                (STREAM_VOLUME_ALIAS[streamType] == AudioSystem.STREAM_RING))) {
            int newRingerMode = mRingerMode;
            int newRingerMode;
            if (index == 0) {
            if (index == 0) {
                newRingerMode = System.getInt(mContentResolver, System.VIBRATE_IN_SILENT, 1) == 1
                newRingerMode = System.getInt(mContentResolver, System.VIBRATE_IN_SILENT, 1) == 1
                    ? AudioManager.RINGER_MODE_VIBRATE
                    ? AudioManager.RINGER_MODE_VIBRATE
@@ -608,10 +614,8 @@ public class AudioService extends IAudioService.Stub {
            } else {
            } else {
                newRingerMode = AudioManager.RINGER_MODE_NORMAL;
                newRingerMode = AudioManager.RINGER_MODE_NORMAL;
            }
            }
            if (newRingerMode != mRingerMode) {
            setRingerMode(newRingerMode);
            setRingerMode(newRingerMode);
        }
        }
        }


        index = rescaleIndex(index * 10, streamType, STREAM_VOLUME_ALIAS[streamType]);
        index = rescaleIndex(index * 10, streamType, STREAM_VOLUME_ALIAS[streamType]);
        setStreamVolumeInt(STREAM_VOLUME_ALIAS[streamType], index, false, true);
        setStreamVolumeInt(STREAM_VOLUME_ALIAS[streamType], index, false, true);
@@ -722,22 +726,31 @@ public class AudioService extends IAudioService.Stub {


    /** @see AudioManager#getRingerMode() */
    /** @see AudioManager#getRingerMode() */
    public int getRingerMode() {
    public int getRingerMode() {
        synchronized(mSettingsLock) {
            return mRingerMode;
            return mRingerMode;
        }
        }
    }

    private void ensureValidRingerMode(int ringerMode) {
        if (!AudioManager.isValidRingerMode(ringerMode)) {
            throw new IllegalArgumentException("Bad ringer mode " + ringerMode);
        }
    }


    /** @see AudioManager#setRingerMode(int) */
    /** @see AudioManager#setRingerMode(int) */
    public void setRingerMode(int ringerMode) {
    public void setRingerMode(int ringerMode) {
        synchronized (mSettingsLock) {
        ensureValidRingerMode(ringerMode);
            if (ringerMode != mRingerMode) {
        if (ringerMode != getRingerMode()) {
            setRingerModeInt(ringerMode, true);
            setRingerModeInt(ringerMode, true);
            // Send sticky broadcast
            // Send sticky broadcast
                broadcastRingerMode();
            broadcastRingerMode(ringerMode);
            }
        }
        }
    }
    }


    private void setRingerModeInt(int ringerMode, boolean persist) {
    private void setRingerModeInt(int ringerMode, boolean persist) {
        synchronized(mSettingsLock) {
            mRingerMode = ringerMode;
            mRingerMode = ringerMode;
        }


        // Mute stream if not previously muted by ringer mode and ringer mode
        // Mute stream if not previously muted by ringer mode and ringer mode
        // is not RINGER_MODE_NORMAL and stream is affected by ringer mode.
        // is not RINGER_MODE_NORMAL and stream is affected by ringer mode.
@@ -747,7 +760,7 @@ public class AudioService extends IAudioService.Stub {
        for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
        for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
            if (isStreamMutedByRingerMode(streamType)) {
            if (isStreamMutedByRingerMode(streamType)) {
                if (!isStreamAffectedByRingerMode(streamType) ||
                if (!isStreamAffectedByRingerMode(streamType) ||
                    mRingerMode == AudioManager.RINGER_MODE_NORMAL) {
                    ringerMode == AudioManager.RINGER_MODE_NORMAL) {
                    // ring and notifications volume should never be 0 when not silenced
                    // ring and notifications volume should never be 0 when not silenced
                    // on voice capable devices
                    // on voice capable devices
                    if (mVoiceCapable &&
                    if (mVoiceCapable &&
@@ -760,7 +773,7 @@ public class AudioService extends IAudioService.Stub {
                }
                }
            } else {
            } else {
                if (isStreamAffectedByRingerMode(streamType) &&
                if (isStreamAffectedByRingerMode(streamType) &&
                    mRingerMode != AudioManager.RINGER_MODE_NORMAL) {
                    ringerMode != AudioManager.RINGER_MODE_NORMAL) {
                   mStreamStates[streamType].mute(null, true);
                   mStreamStates[streamType].mute(null, true);
                   mRingerModeMutedStreams |= (1 << streamType);
                   mRingerModeMutedStreams |= (1 << streamType);
               }
               }
@@ -780,10 +793,10 @@ public class AudioService extends IAudioService.Stub {
        switch (getVibrateSetting(vibrateType)) {
        switch (getVibrateSetting(vibrateType)) {


            case AudioManager.VIBRATE_SETTING_ON:
            case AudioManager.VIBRATE_SETTING_ON:
                return mRingerMode != AudioManager.RINGER_MODE_SILENT;
                return getRingerMode() != AudioManager.RINGER_MODE_SILENT;


            case AudioManager.VIBRATE_SETTING_ONLY_SILENT:
            case AudioManager.VIBRATE_SETTING_ONLY_SILENT:
                return mRingerMode == AudioManager.RINGER_MODE_VIBRATE;
                return getRingerMode() == AudioManager.RINGER_MODE_VIBRATE;


            case AudioManager.VIBRATE_SETTING_OFF:
            case AudioManager.VIBRATE_SETTING_OFF:
                // return false, even for incoming calls
                // return false, even for incoming calls
@@ -1688,11 +1701,12 @@ public class AudioService extends IAudioService.Stub {
     */
     */
    private boolean checkForRingerModeChange(int oldIndex, int direction, int streamType) {
    private boolean checkForRingerModeChange(int oldIndex, int direction, int streamType) {
        boolean adjustVolumeIndex = true;
        boolean adjustVolumeIndex = true;
        int newRingerMode = mRingerMode;
        int ringerMode = getRingerMode();
        int newRingerMode = ringerMode;
        int uiIndex = (oldIndex + 5) / 10;
        int uiIndex = (oldIndex + 5) / 10;
        boolean vibeInSilent = System.getInt(mContentResolver, System.VIBRATE_IN_SILENT, 1) == 1;
        boolean vibeInSilent = System.getInt(mContentResolver, System.VIBRATE_IN_SILENT, 1) == 1;


        if (mRingerMode == RINGER_MODE_NORMAL) {
        if (ringerMode == RINGER_MODE_NORMAL) {
            if ((direction == AudioManager.ADJUST_LOWER) && (uiIndex <= 1)) {
            if ((direction == AudioManager.ADJUST_LOWER) && (uiIndex <= 1)) {
                // enter silent mode if current index is the last audible one and not repeating a
                // enter silent mode if current index is the last audible one and not repeating a
                // volume key down
                // volume key down
@@ -1707,7 +1721,7 @@ public class AudioService extends IAudioService.Stub {
                    adjustVolumeIndex = false;
                    adjustVolumeIndex = false;
                }
                }
            }
            }
        } else if (mRingerMode == RINGER_MODE_VIBRATE) {
        } else if (ringerMode == RINGER_MODE_VIBRATE) {
            if ((direction == AudioManager.ADJUST_LOWER)) {
            if ((direction == AudioManager.ADJUST_LOWER)) {
                // Set it to silent, if it wasn't a long-press
                // Set it to silent, if it wasn't a long-press
                if (mPrevVolDirection != AudioManager.ADJUST_LOWER) {
                if (mPrevVolDirection != AudioManager.ADJUST_LOWER) {
@@ -1726,9 +1740,7 @@ public class AudioService extends IAudioService.Stub {
            adjustVolumeIndex = false;
            adjustVolumeIndex = false;
        }
        }


        if (newRingerMode != mRingerMode) {
        setRingerMode(newRingerMode);
        setRingerMode(newRingerMode);
        }


        mPrevVolDirection = direction;
        mPrevVolDirection = direction;


@@ -1818,10 +1830,10 @@ public class AudioService extends IAudioService.Stub {
        }
        }
    }
    }


    private void broadcastRingerMode() {
    private void broadcastRingerMode(int ringerMode) {
        // Send sticky broadcast
        // Send sticky broadcast
        Intent broadcast = new Intent(AudioManager.RINGER_MODE_CHANGED_ACTION);
        Intent broadcast = new Intent(AudioManager.RINGER_MODE_CHANGED_ACTION);
        broadcast.putExtra(AudioManager.EXTRA_RINGER_MODE, mRingerMode);
        broadcast.putExtra(AudioManager.EXTRA_RINGER_MODE, ringerMode);
        broadcast.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
        broadcast.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
                | Intent.FLAG_RECEIVER_REPLACE_PENDING);
                | Intent.FLAG_RECEIVER_REPLACE_PENDING);
        long origCallerIdentityToken = Binder.clearCallingIdentity();
        long origCallerIdentityToken = Binder.clearCallingIdentity();
@@ -2013,7 +2025,8 @@ public class AudioService extends IAudioService.Stub {
                                if (muteCount() == 0) {
                                if (muteCount() == 0) {
                                    // If the stream is not muted any more, restore it's volume if
                                    // If the stream is not muted any more, restore it's volume if
                                    // ringer mode allows it
                                    // ringer mode allows it
                                    if (!isStreamAffectedByRingerMode(mStreamType) || mRingerMode == AudioManager.RINGER_MODE_NORMAL) {
                                    if (!isStreamAffectedByRingerMode(mStreamType) ||
                                            getRingerMode() == AudioManager.RINGER_MODE_NORMAL) {
                                        setIndex(mLastAudibleIndex, false);
                                        setIndex(mLastAudibleIndex, false);
                                        sendMsg(mAudioHandler, MSG_SET_SYSTEM_VOLUME, SENDMSG_NOOP, 0, 0,
                                        sendMsg(mAudioHandler, MSG_SET_SYSTEM_VOLUME, SENDMSG_NOOP, 0, 0,
                                                VolumeStreamState.this, 0);
                                                VolumeStreamState.this, 0);
@@ -2131,8 +2144,8 @@ public class AudioService extends IAudioService.Stub {
            }
            }
        }
        }


        private void persistRingerMode() {
        private void persistRingerMode(int ringerMode) {
            System.putInt(mContentResolver, System.MODE_RINGER, mRingerMode);
            System.putInt(mContentResolver, System.MODE_RINGER, ringerMode);
        }
        }


        private void persistVibrateSetting() {
        private void persistVibrateSetting() {
@@ -2219,7 +2232,9 @@ public class AudioService extends IAudioService.Stub {
                    break;
                    break;


                case MSG_PERSIST_RINGER_MODE:
                case MSG_PERSIST_RINGER_MODE:
                    persistRingerMode();
                    // note that the value persisted is the current ringer mode, not the
                    // value of ringer mode as of the time the request was made to persist
                    persistRingerMode(getRingerMode());
                    break;
                    break;


                case MSG_PERSIST_VIBRATE_SETTING:
                case MSG_PERSIST_VIBRATE_SETTING:
@@ -2335,6 +2350,10 @@ public class AudioService extends IAudioService.Stub {
        @Override
        @Override
        public void onChange(boolean selfChange) {
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
            super.onChange(selfChange);
            // FIXME This synchronized is not necessary if mSettingsLock only protects mRingerMode.
            //       However there appear to be some missing locks around mRingerModeMutedStreams
            //       and mRingerModeAffectedStreams, so will leave this synchronized for now.
            //       mRingerModeMutedStreams and mMuteAffectedStreams are safe (only accessed once).
            synchronized (mSettingsLock) {
            synchronized (mSettingsLock) {
                int ringerModeAffectedStreams = Settings.System.getInt(mContentResolver,
                int ringerModeAffectedStreams = Settings.System.getInt(mContentResolver,
                       Settings.System.MODE_RINGER_STREAMS_AFFECTED,
                       Settings.System.MODE_RINGER_STREAMS_AFFECTED,