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

Commit bc0fab1f authored by Eric Laurent's avatar Eric Laurent
Browse files

Add multi user volume management

Notification and Alarm volumes are per user: they are saved and restored
when the foreground user changes.
Media volume is global: it is still saved and restored per user for
implentation reasons but is copied from one user to the next to ensure
media playback volume continuity when switching users.

Ringer mode (silent, vibrate...) is now a global setting.

Bug 7128886.

Change-Id: I9f4f5a0a3985552bca61c2cc3bbe5a144db755a6
parent c31f5a7e
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -18797,6 +18797,7 @@ package android.provider {
    field public static final java.lang.String DEVELOPMENT_SETTINGS_ENABLED = "development_settings_enabled";
    field public static final java.lang.String DEVELOPMENT_SETTINGS_ENABLED = "development_settings_enabled";
    field public static final java.lang.String DEVICE_PROVISIONED = "device_provisioned";
    field public static final java.lang.String DEVICE_PROVISIONED = "device_provisioned";
    field public static final java.lang.String INSTALL_NON_MARKET_APPS = "install_non_market_apps";
    field public static final java.lang.String INSTALL_NON_MARKET_APPS = "install_non_market_apps";
    field public static final java.lang.String MODE_RINGER = "mode_ringer";
    field public static final java.lang.String NETWORK_PREFERENCE = "network_preference";
    field public static final java.lang.String NETWORK_PREFERENCE = "network_preference";
    field public static final java.lang.String RADIO_BLUETOOTH = "bluetooth";
    field public static final java.lang.String RADIO_BLUETOOTH = "bluetooth";
    field public static final java.lang.String RADIO_CELL = "cell";
    field public static final java.lang.String RADIO_CELL = "cell";
@@ -18960,7 +18961,7 @@ package android.provider {
    field public static final deprecated java.lang.String LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED = "lock_pattern_tactile_feedback_enabled";
    field public static final deprecated java.lang.String LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED = "lock_pattern_tactile_feedback_enabled";
    field public static final deprecated java.lang.String LOCK_PATTERN_VISIBLE = "lock_pattern_visible_pattern";
    field public static final deprecated java.lang.String LOCK_PATTERN_VISIBLE = "lock_pattern_visible_pattern";
    field public static final deprecated java.lang.String LOGGING_ID = "logging_id";
    field public static final deprecated java.lang.String LOGGING_ID = "logging_id";
    field public static final java.lang.String MODE_RINGER = "mode_ringer";
    field public static final deprecated java.lang.String MODE_RINGER = "mode_ringer";
    field public static final java.lang.String MODE_RINGER_STREAMS_AFFECTED = "mode_ringer_streams_affected";
    field public static final java.lang.String MODE_RINGER_STREAMS_AFFECTED = "mode_ringer_streams_affected";
    field public static final java.lang.String MUTE_STREAMS_AFFECTED = "mute_streams_affected";
    field public static final java.lang.String MUTE_STREAMS_AFFECTED = "mute_streams_affected";
    field public static final deprecated java.lang.String NETWORK_PREFERENCE = "network_preference";
    field public static final deprecated java.lang.String NETWORK_PREFERENCE = "network_preference";
+12 −8
Original line number Original line Diff line number Diff line
@@ -919,6 +919,7 @@ public final class Settings {
            MOVED_TO_GLOBAL.add(Settings.Global.POWER_SOUNDS_ENABLED);
            MOVED_TO_GLOBAL.add(Settings.Global.POWER_SOUNDS_ENABLED);
            MOVED_TO_GLOBAL.add(Settings.Global.STAY_ON_WHILE_PLUGGED_IN);
            MOVED_TO_GLOBAL.add(Settings.Global.STAY_ON_WHILE_PLUGGED_IN);
            MOVED_TO_GLOBAL.add(Settings.Global.WIFI_SLEEP_POLICY);
            MOVED_TO_GLOBAL.add(Settings.Global.WIFI_SLEEP_POLICY);
            MOVED_TO_GLOBAL.add(Settings.Global.MODE_RINGER);
        }
        }


        private static void lazyInitCache() {
        private static void lazyInitCache() {
@@ -1482,6 +1483,12 @@ public final class Settings {
        @Deprecated
        @Deprecated
        public static final int WIFI_SLEEP_POLICY_NEVER = Global.WIFI_SLEEP_POLICY_NEVER;
        public static final int WIFI_SLEEP_POLICY_NEVER = Global.WIFI_SLEEP_POLICY_NEVER;


        /**
         * @deprecated Use {@link android.provider.Settings.Global#MODE_RINGER} instead
         */
        @Deprecated
        public static final String MODE_RINGER = Global.MODE_RINGER;

        //TODO: deprecate static IP constants
        //TODO: deprecate static IP constants
        /**
        /**
         * Whether to use static IP and other static network attributes.
         * Whether to use static IP and other static network attributes.
@@ -1651,13 +1658,6 @@ public final class Settings {
        public static final String ALWAYS_FINISH_ACTIVITIES =
        public static final String ALWAYS_FINISH_ACTIVITIES =
                "always_finish_activities";
                "always_finish_activities";



        /**
         * Ringer mode. This is used internally, changing this value will not
         * change the ringer mode. See AudioManager.
         */
        public static final String MODE_RINGER = "mode_ringer";

        /**
        /**
         * Determines which streams are affected by ringer mode changes. The
         * Determines which streams are affected by ringer mode changes. The
         * stream type's bit should be set to 1 if it should be muted when going
         * stream type's bit should be set to 1 if it should be muted when going
@@ -5709,7 +5709,11 @@ public final class Settings {
        */
        */
       public static final String WTF_IS_FATAL = "wtf_is_fatal";
       public static final String WTF_IS_FATAL = "wtf_is_fatal";



       /**
        * Ringer mode. This is used internally, changing this value will not
        * change the ringer mode. See AudioManager.
        */
       public static final String MODE_RINGER = "mode_ringer";




        // Populated lazily, guarded by class object:
        // Populated lazily, guarded by class object:
+64 −28
Original line number Original line Diff line number Diff line
@@ -480,6 +480,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
        intentFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
        intentFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
        intentFilter.addAction(Intent.ACTION_SCREEN_ON);
        intentFilter.addAction(Intent.ACTION_SCREEN_ON);
        intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
        intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
        intentFilter.addAction(Intent.ACTION_USER_SWITCHED);


        // Register a configuration change listener only if requested by system properties
        // Register a configuration change listener only if requested by system properties
        // to monitor orientation changes (off by default)
        // to monitor orientation changes (off by default)
@@ -608,7 +609,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
        final ContentResolver cr = mContentResolver;
        final ContentResolver cr = mContentResolver;


        int ringerModeFromSettings =
        int ringerModeFromSettings =
                System.getInt(cr, System.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL);
                Settings.Global.getInt(cr, System.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL);
        int ringerMode = ringerModeFromSettings;
        int ringerMode = ringerModeFromSettings;
        // 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
@@ -619,7 +620,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
            ringerMode = AudioManager.RINGER_MODE_SILENT;
            ringerMode = AudioManager.RINGER_MODE_SILENT;
        }
        }
        if (ringerMode != ringerModeFromSettings) {
        if (ringerMode != ringerModeFromSettings) {
            System.putInt(cr, System.MODE_RINGER, ringerMode);
            Settings.Global.putInt(cr, System.MODE_RINGER, ringerMode);
        }
        }
        synchronized(mSettingsLock) {
        synchronized(mSettingsLock) {
            mRingerMode = ringerMode;
            mRingerMode = ringerMode;
@@ -638,23 +639,30 @@ public class AudioService extends IAudioService.Stub implements OnFinished {


        // make sure settings for ringer mode are consistent with device type: non voice capable
        // make sure settings for ringer mode are consistent with device type: non voice capable
        // devices (tablets) include media stream in silent mode whereas phones don't.
        // devices (tablets) include media stream in silent mode whereas phones don't.
        mRingerModeAffectedStreams = Settings.System.getInt(cr,
        mRingerModeAffectedStreams = Settings.System.getIntForUser(cr,
                Settings.System.MODE_RINGER_STREAMS_AFFECTED,
                Settings.System.MODE_RINGER_STREAMS_AFFECTED,
                ((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)|
                ((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)|
                 (1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)));
                 (1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)),
                 UserHandle.USER_CURRENT);
        if (mVoiceCapable) {
        if (mVoiceCapable) {
            mRingerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_MUSIC);
            mRingerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_MUSIC);
        } else {
        } else {
            mRingerModeAffectedStreams |= (1 << AudioSystem.STREAM_MUSIC);
            mRingerModeAffectedStreams |= (1 << AudioSystem.STREAM_MUSIC);
        }
        }
        Settings.System.putInt(cr,
        Settings.System.putIntForUser(cr,
                Settings.System.MODE_RINGER_STREAMS_AFFECTED, mRingerModeAffectedStreams);
                Settings.System.MODE_RINGER_STREAMS_AFFECTED,
                mRingerModeAffectedStreams,
                UserHandle.USER_CURRENT);


        mMuteAffectedStreams = System.getInt(cr,
        mMuteAffectedStreams = System.getIntForUser(cr,
                System.MUTE_STREAMS_AFFECTED,
                System.MUTE_STREAMS_AFFECTED,
                ((1 << AudioSystem.STREAM_MUSIC)|(1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_SYSTEM)));
                ((1 << AudioSystem.STREAM_MUSIC)|
                 (1 << AudioSystem.STREAM_RING)|
                 (1 << AudioSystem.STREAM_SYSTEM)),
                 UserHandle.USER_CURRENT);


        boolean masterMute = System.getInt(cr, System.VOLUME_MASTER_MUTE, 0) == 1;
        boolean masterMute = System.getIntForUser(cr, System.VOLUME_MASTER_MUTE,
                                                  0, UserHandle.USER_CURRENT) == 1;
        AudioSystem.setMasterMute(masterMute);
        AudioSystem.setMasterMute(masterMute);
        broadcastMasterMuteStatus(masterMute);
        broadcastMasterMuteStatus(masterMute);


@@ -1237,8 +1245,8 @@ public class AudioService extends IAudioService.Stub implements OnFinished {


    private void restoreMasterVolume() {
    private void restoreMasterVolume() {
        if (mUseMasterVolume) {
        if (mUseMasterVolume) {
            float volume = Settings.System.getFloat(mContentResolver,
            float volume = Settings.System.getFloatForUser(mContentResolver,
                    Settings.System.VOLUME_MASTER, -1.0f);
                    Settings.System.VOLUME_MASTER, -1.0f, UserHandle.USER_CURRENT);
            if (volume >= 0.0f) {
            if (volume >= 0.0f) {
                AudioSystem.setMasterVolume(volume);
                AudioSystem.setMasterVolume(volume);
            }
            }
@@ -1674,6 +1682,10 @@ public class AudioService extends IAudioService.Stub implements OnFinished {


    /** @see AudioManager#reloadAudioSettings() */
    /** @see AudioManager#reloadAudioSettings() */
    public void reloadAudioSettings() {
    public void reloadAudioSettings() {
        readAudioSettings(false /*userSwitch*/);
    }

    private void readAudioSettings(boolean userSwitch) {
        // restore ringer mode, ringer mode affected streams, mute affected streams and vibrate settings
        // restore ringer mode, ringer mode affected streams, mute affected streams and vibrate settings
        readPersistedSettings();
        readPersistedSettings();


@@ -1682,6 +1694,10 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
        for (int streamType = 0; streamType < numStreamTypes; streamType++) {
        for (int streamType = 0; streamType < numStreamTypes; streamType++) {
            VolumeStreamState streamState = mStreamStates[streamType];
            VolumeStreamState streamState = mStreamStates[streamType];


            if (userSwitch && mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) {
                continue;
            }

            synchronized (streamState) {
            synchronized (streamState) {
                streamState.readSettings();
                streamState.readSettings();


@@ -2536,7 +2552,8 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
                // device, continue otherwise
                // device, continue otherwise
                int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT) ?
                int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT) ?
                                        AudioManager.DEFAULT_STREAM_VOLUME[mStreamType] : -1;
                                        AudioManager.DEFAULT_STREAM_VOLUME[mStreamType] : -1;
                int index = Settings.System.getInt(mContentResolver, name, defaultIndex);
                int index = Settings.System.getIntForUser(
                        mContentResolver, name, defaultIndex, UserHandle.USER_CURRENT);
                if (index == -1) {
                if (index == -1) {
                    continue;
                    continue;
                }
                }
@@ -2547,7 +2564,8 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
                // or default index
                // or default index
                defaultIndex = (index > 0) ?
                defaultIndex = (index > 0) ?
                                    index : AudioManager.DEFAULT_STREAM_VOLUME[mStreamType];
                                    index : AudioManager.DEFAULT_STREAM_VOLUME[mStreamType];
                int lastAudibleIndex = Settings.System.getInt(mContentResolver, name, defaultIndex);
                int lastAudibleIndex = Settings.System.getIntForUser(
                        mContentResolver, name, defaultIndex, UserHandle.USER_CURRENT);


                // a last audible index of 0 should never be stored for ring and notification
                // a last audible index of 0 should never be stored for ring and notification
                // streams on phones (voice capable devices).
                // streams on phones (voice capable devices).
@@ -2959,19 +2977,21 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
                                   int persistType,
                                   int persistType,
                                   int device) {
                                   int device) {
            if ((persistType & PERSIST_CURRENT) != 0) {
            if ((persistType & PERSIST_CURRENT) != 0) {
                System.putInt(mContentResolver,
                System.putIntForUser(mContentResolver,
                          streamState.getSettingNameForDevice(false /* lastAudible */, device),
                          streamState.getSettingNameForDevice(false /* lastAudible */, device),
                          (streamState.getIndex(device, false /* lastAudible */) + 5)/ 10);
                          (streamState.getIndex(device, false /* lastAudible */) + 5)/ 10,
                          UserHandle.USER_CURRENT);
            }
            }
            if ((persistType & PERSIST_LAST_AUDIBLE) != 0) {
            if ((persistType & PERSIST_LAST_AUDIBLE) != 0) {
                System.putInt(mContentResolver,
                System.putIntForUser(mContentResolver,
                        streamState.getSettingNameForDevice(true /* lastAudible */, device),
                        streamState.getSettingNameForDevice(true /* lastAudible */, device),
                        (streamState.getIndex(device, true  /* lastAudible */) + 5) / 10);
                        (streamState.getIndex(device, true  /* lastAudible */) + 5) / 10,
                        UserHandle.USER_CURRENT);
            }
            }
        }
        }


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


        private void playSoundEffect(int effectType, int volume) {
        private void playSoundEffect(int effectType, int volume) {
@@ -3021,8 +3041,10 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
        }
        }


        private void onHandlePersistMediaButtonReceiver(ComponentName receiver) {
        private void onHandlePersistMediaButtonReceiver(ComponentName receiver) {
            Settings.System.putString(mContentResolver, Settings.System.MEDIA_BUTTON_RECEIVER,
            Settings.System.putStringForUser(mContentResolver,
                    receiver == null ? "" : receiver.flattenToString());
                                             Settings.System.MEDIA_BUTTON_RECEIVER,
                                             receiver == null ? "" : receiver.flattenToString(),
                                             UserHandle.USER_CURRENT);
        }
        }


        private void cleanupPlayer(MediaPlayer mp) {
        private void cleanupPlayer(MediaPlayer mp) {
@@ -3058,13 +3080,17 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
                    break;
                    break;


                case MSG_PERSIST_MASTER_VOLUME:
                case MSG_PERSIST_MASTER_VOLUME:
                    Settings.System.putFloat(mContentResolver, Settings.System.VOLUME_MASTER,
                    Settings.System.putFloatForUser(mContentResolver,
                            (float)msg.arg1 / (float)1000.0);
                                                    Settings.System.VOLUME_MASTER,
                                                    (float)msg.arg1 / (float)1000.0,
                                                    UserHandle.USER_CURRENT);
                    break;
                    break;


                case MSG_PERSIST_MASTER_VOLUME_MUTE:
                case MSG_PERSIST_MASTER_VOLUME_MUTE:
                    Settings.System.putInt(mContentResolver, Settings.System.VOLUME_MASTER_MUTE,
                    Settings.System.putIntForUser(mContentResolver,
                            msg.arg1);
                                                 Settings.System.VOLUME_MASTER_MUTE,
                                                 msg.arg1,
                                                 UserHandle.USER_CURRENT);
                    break;
                    break;


                case MSG_PERSIST_RINGER_MODE:
                case MSG_PERSIST_RINGER_MODE:
@@ -3248,10 +3274,11 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
            //       and mRingerModeAffectedStreams, so will leave this synchronized for now.
            //       and mRingerModeAffectedStreams, so will leave this synchronized for now.
            //       mRingerModeMutedStreams and mMuteAffectedStreams are safe (only accessed once).
            //       mRingerModeMutedStreams and mMuteAffectedStreams are safe (only accessed once).
            synchronized (mSettingsLock) {
            synchronized (mSettingsLock) {
                int ringerModeAffectedStreams = Settings.System.getInt(mContentResolver,
                int ringerModeAffectedStreams = Settings.System.getIntForUser(mContentResolver,
                       Settings.System.MODE_RINGER_STREAMS_AFFECTED,
                       Settings.System.MODE_RINGER_STREAMS_AFFECTED,
                       ((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)|
                       ((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)|
                       (1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)));
                       (1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)),
                       UserHandle.USER_CURRENT);
                if (mVoiceCapable) {
                if (mVoiceCapable) {
                    ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_MUSIC);
                    ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_MUSIC);
                } else {
                } else {
@@ -3670,6 +3697,15 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
                AudioSystem.setParameters("screen_state=off");
                AudioSystem.setParameters("screen_state=off");
            } else if (action.equalsIgnoreCase(Intent.ACTION_CONFIGURATION_CHANGED)) {
            } else if (action.equalsIgnoreCase(Intent.ACTION_CONFIGURATION_CHANGED)) {
                handleConfigurationChanged(context);
                handleConfigurationChanged(context);
            } else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
                readAudioSettings(true /*userSwitch*/);
                // preserve STREAM_MUSIC volume from one user to the next.
                sendMsg(mAudioHandler,
                        MSG_SET_ALL_VOLUMES,
                        SENDMSG_QUEUE,
                        0,
                        0,
                        mStreamStates[AudioSystem.STREAM_MUSIC], 0);
            }
            }
        }
        }
    }
    }
@@ -4544,8 +4580,8 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
     * Restore remote control receiver from the system settings.
     * Restore remote control receiver from the system settings.
     */
     */
    private void restoreMediaButtonReceiver() {
    private void restoreMediaButtonReceiver() {
        String receiverName = Settings.System.getString(mContentResolver,
        String receiverName = Settings.System.getStringForUser(mContentResolver,
                Settings.System.MEDIA_BUTTON_RECEIVER);
                Settings.System.MEDIA_BUTTON_RECEIVER, UserHandle.USER_CURRENT);
        if ((null != receiverName) && !receiverName.isEmpty()) {
        if ((null != receiverName) && !receiverName.isEmpty()) {
            ComponentName eventReceiver = ComponentName.unflattenFromString(receiverName);
            ComponentName eventReceiver = ComponentName.unflattenFromString(receiverName);
            // construct a PendingIntent targeted to the restored component name
            // construct a PendingIntent targeted to the restored component name