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

Commit 6329bf7b authored by Daniel Sandler's avatar Daniel Sandler
Browse files

New vibrate/silent mode behavior.

In earlier versions of Android, "vibrate mode" (in which
only alarms and media produce sound, but notifications may
operate the vibe motor) was only accessible by adjusting the
ringer volume (via the device's volume rocker) down until
the "vibrate" icon appeared (between the lowest ring volume
and silent mode).

Many users prefer that "silent mode" always allow vibration.
Others prefer Android's historical behavior, in which silent
mode stops the vibes as well.

To accommodate these two distinct usage patterns, we now
allow the user to decide whether vibration is allowed in
"silent mode", a user interface abstraction that now spans
both AudioManager.RINGER_MODE_VIBRATE and
AudioManager.RINGER_MODE_SILENT.

To minimize API impact (and therefore maximize backward
compatibility), RINGER_MODE_VIBRATE and RINGER_MODE_SILENT
remain unchanged. What has changed is what happens when the
user activates silent mode, either via Settings,
GlobalActions (longpress on power), volume rocker, or the
keyguard tab. In essence, there is now only one "silent"
position in these controls, and whether RINGER_MODE_VIBRATE
or RINGER_MODE_SILENT is actually set on the AudioService is
determined by a new one-off setting
(System.VIBRATE_IN_SILENT).  This new setting isn't meant to
be a long-term API, however: in the future we hope to
replace and extend this design with a much more
sophisticated set of systemwide feedback profiles. ETA TBD.

Related changes:
  * I09ad7d69 (GlobalActions and keyguard)
  * I22ba7bcf (Settings app)

Bug: 2457183
Change-Id: I14cf91b0910261ffdfd1bf302423f41ec747d057
parent d2095855
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -1278,6 +1278,17 @@ public final class Settings {
        public static final String NOTIFICATIONS_USE_RING_VOLUME =
            "notifications_use_ring_volume";

        /**
         * Whether silent mode should allow vibration feedback. This is used
         * internally in AudioService and the Sound settings activity to
         * coordinate decoupling of vibrate and silent modes. This setting
         * will likely be removed in a future release with support for
         * audio/vibe feedback profiles.
         *
         * @hide
         */
        public static final String VIBRATE_IN_SILENT = "vibrate_in_silent";

        /**
         * The mapping of stream type (integer) to its setting.
         */
+8.16 KiB
Loading image diff...
+4.7 KiB
Loading image diff...
+11 −9
Original line number Diff line number Diff line
@@ -901,18 +901,20 @@ public class AudioService extends IAudioService.Stub {
        boolean adjustVolumeIndex = true;
        int newRingerMode = mRingerMode;

        if (mRingerMode == AudioManager.RINGER_MODE_NORMAL && (oldIndex + 5) / 10 == 1
                && direction == AudioManager.ADJUST_LOWER) {
            newRingerMode = AudioManager.RINGER_MODE_VIBRATE;
        } else if (mRingerMode == AudioManager.RINGER_MODE_VIBRATE) {
        if (mRingerMode == AudioManager.RINGER_MODE_NORMAL) {
            // audible mode, at the bottom of the scale
            if (direction == AudioManager.ADJUST_LOWER
                    && (oldIndex + 5) / 10 == 1) {
                // "silent mode", but which one?
                newRingerMode = System.getInt(mContentResolver, System.VIBRATE_IN_SILENT, 1) == 1
                    ? AudioManager.RINGER_MODE_VIBRATE
                    : AudioManager.RINGER_MODE_SILENT;
            }
        } else {
            if (direction == AudioManager.ADJUST_RAISE) {
                // exiting silent mode
                newRingerMode = AudioManager.RINGER_MODE_NORMAL;
            } else if (direction == AudioManager.ADJUST_LOWER) {
                newRingerMode = AudioManager.RINGER_MODE_SILENT;
            }
        } else if (direction == AudioManager.ADJUST_RAISE
                && mRingerMode == AudioManager.RINGER_MODE_SILENT) {
            newRingerMode = AudioManager.RINGER_MODE_VIBRATE;
        }

        if (newRingerMode != mRingerMode) {