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

Commit d9c3cf85 authored by Behnam Heydarshahi's avatar Behnam Heydarshahi
Browse files

Muting ring volume slider disables notification

With volume_separate_notification flag enbaled, muting ring volume
slice will cause notification volume slice to gray out.

There used to be a bug in which notification slice would not get
updated in response to a change in ring volume mute/unmute broadcast.
The resulting erroneous behavior was notification slider would get to
zero but not get grayed out. To fix that bug, VolumeSliceHelper listens
to ring stream mute/unmute broadcasts and forwards them to notification
slice.

Bug: b/266072907
Test: make DEBUG_ROBOLECTRIC=1 ROBOTEST_FILTER="NotificationVolumePreferenceControllerTest|VolumeSliceHelperTest" RunSettingsRoboTests -j40

Change-Id: I2ab51f1272bf99a0c3d9ca285354052d00910c90
parent d89de473
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -8828,6 +8828,9 @@
    <!-- Sound: Title for the option managing notification volume. [CHAR LIMIT=30] -->
    <string name="notification_volume_option_title">Notification volume</string>
    <!-- Sound: Summary for when notification volume is disabled. [CHAR LIMIT=100] -->
    <string name="notification_volume_disabled_summary">Unavailable because ring is muted</string>
    <!-- Sound: Title for the option defining the phone ringtone. [CHAR LIMIT=30] -->
    <string name="ringtone_title">Phone ringtone</string>
+2 −2
Original line number Diff line number Diff line
@@ -86,8 +86,8 @@
        android:icon="@drawable/ic_notifications"
        android:title="@string/notification_volume_option_title"
        android:order="-150"
        settings:controller=
            "com.android.settings.notification.NotificationVolumePreferenceController"/>
        settings:controller="com.android.settings.notification.NotificationVolumePreferenceController"
        settings:unavailableSliceSubtitle="@string/notification_volume_disabled_summary"/>

    <!-- Alarm volume -->
    <com.android.settings.notification.VolumeSeekBarPreference
+25 −14
Original line number Diff line number Diff line
@@ -51,7 +51,6 @@ public class NotificationVolumePreferenceController extends
    private final RingReceiver mReceiver = new RingReceiver();
    private final H mHandler = new H();


    public NotificationVolumePreferenceController(Context context) {
        this(context, KEY_NOTIFICATION_VOLUME);
    }
@@ -63,7 +62,9 @@ public class NotificationVolumePreferenceController extends
        mVibrateIconId = R.drawable.ic_volume_ringer_vibrate;
        mSilentIconId = R.drawable.ic_notifications_off_24dp;

        updateRingerMode();
        if (updateRingerMode()) {
            updateEnabledState();
        }
    }

    /**
@@ -77,12 +78,10 @@ public class NotificationVolumePreferenceController extends
        if (mPreference == null) {
            setupVolPreference(screen);
        }
        mSeparateNotification = isSeparateNotificationConfigEnabled();
        if (mPreference != null) {
            mPreference.setVisible(getAvailabilityStatus() == AVAILABLE);
        }

        updateEffectsSuppressor();
        selectPreferenceIconState();
        updateEnabledState();
    }

    /**
@@ -95,14 +94,18 @@ public class NotificationVolumePreferenceController extends
            boolean newVal = isSeparateNotificationConfigEnabled();
            if (newVal != mSeparateNotification) {
                mSeparateNotification = newVal;
                // manually hiding the preference because being unavailable does not do the job
                // Update UI if config change happens when Sound Settings page is on the foreground
                if (mPreference != null) {
                    mPreference.setVisible(getAvailabilityStatus() == AVAILABLE);
                    int status = getAvailabilityStatus();
                    mPreference.setVisible(status == AVAILABLE
                            || status == DISABLED_DEPENDENT_SETTING);
                    if (status == DISABLED_DEPENDENT_SETTING) {
                        mPreference.setEnabled(false);
                    }
                }
            }
        }
    }


    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    @Override
@@ -126,10 +129,11 @@ public class NotificationVolumePreferenceController extends
    @Override
    public int getAvailabilityStatus() {
        boolean separateNotification = isSeparateNotificationConfigEnabled();

        return mContext.getResources().getBoolean(R.bool.config_show_notification_volume)
                && !mHelper.isSingleVolume() && separateNotification
                ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
                ? (mRingerMode == AudioManager.RINGER_MODE_NORMAL
                    ? AVAILABLE : DISABLED_DEPENDENT_SETTING)
                : UNSUPPORTED_ON_DEVICE;
    }

    @Override
@@ -158,7 +162,6 @@ public class NotificationVolumePreferenceController extends
            if (mVibrator != null && mRingerMode == AudioManager.RINGER_MODE_VIBRATE) {
                mMuteIcon = mVibrateIconId;
                mPreference.showIcon(mVibrateIconId);

            } else if (mRingerMode == AudioManager.RINGER_MODE_SILENT
                    || mVibrator == null && mRingerMode == AudioManager.RINGER_MODE_VIBRATE) {
                mMuteIcon = mSilentIconId;
@@ -175,6 +178,12 @@ public class NotificationVolumePreferenceController extends
        }
    }

    private void updateEnabledState() {
        if (mPreference != null) {
            mPreference.setEnabled(mRingerMode == AudioManager.RINGER_MODE_NORMAL);
        }
    }

    private final class H extends Handler {
        private static final int UPDATE_EFFECTS_SUPPRESSOR = 1;
        private static final int UPDATE_RINGER_MODE = 2;
@@ -191,10 +200,13 @@ public class NotificationVolumePreferenceController extends
                    updateEffectsSuppressor();
                    break;
                case UPDATE_RINGER_MODE:
                    updateRingerMode();
                    if (updateRingerMode()) {
                        updateEnabledState();
                    }
                    break;
                case NOTIFICATION_VOLUME_CHANGED:
                    selectPreferenceIconState();
                    updateEnabledState();
                    break;
            }
        }
@@ -239,5 +251,4 @@ public class NotificationVolumePreferenceController extends
            }
        }
    }

}
+9 −2
Original line number Diff line number Diff line
@@ -140,11 +140,18 @@ public abstract class RingerModeAffectedVolumePreferenceController extends
        return valueUpdated;
    }

    protected void updateRingerMode() {
    /**
     * Updates UI Icon in response to ringer mode changes.
     * @return whether the ringer mode has changed.
     */
    protected boolean updateRingerMode() {
        final int ringerMode = mHelper.getRingerModeInternal();
        if (mRingerMode == ringerMode) return;
        if (mRingerMode == ringerMode) {
            return false;
        }
        mRingerMode = ringerMode;
        selectPreferenceIconState();
        return true;
    }

    /**
+24 −2
Original line number Diff line number Diff line
@@ -93,8 +93,9 @@ public class VolumeSliceHelper {

        if (AudioManager.VOLUME_CHANGED_ACTION.equals(action)) {
            handleVolumeChanged(context, intent);
        } else if (AudioManager.STREAM_MUTE_CHANGED_ACTION.equals(action)
                || AudioManager.STREAM_DEVICES_CHANGED_ACTION.equals(action)) {
        } else if (AudioManager.STREAM_MUTE_CHANGED_ACTION.equals(action)) {
            handleMuteChanged(context, intent);
        } else if (AudioManager.STREAM_DEVICES_CHANGED_ACTION.equals(action)) {
            handleStreamChanged(context, intent);
        } else {
            notifyAllStreamsChanged(context);
@@ -109,8 +110,29 @@ public class VolumeSliceHelper {
        }
    }

    /**
     *  When mute is changed, notifyChange on relevant Volume Slice ContentResolvers to mark them
     *  as needing update.
     *
     * In addition to the matching stream, we always notifyChange for the Notification stream
     * when Ring events are issued. This is to make sure that Notification always gets updated
     * for RingerMode changes, even if Notification's volume is zero and therefore it would not
     * get its own AudioManager.VOLUME_CHANGED_ACTION.
     */
    private static void handleMuteChanged(Context context, Intent intent) {
        final int inputType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
        handleStreamChanged(context, inputType);
        if (inputType == AudioManager.STREAM_RING) {
            handleStreamChanged(context, AudioManager.STREAM_NOTIFICATION);
        }
    }

    private static void handleStreamChanged(Context context, Intent intent) {
        final int inputType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
        handleStreamChanged(context, inputType);
    }

    private static void handleStreamChanged(Context context, int inputType) {
        synchronized (sRegisteredUri) {
            for (Map.Entry<Uri, Integer> entry : sRegisteredUri.entrySet()) {
                if (entry.getValue() == inputType) {
Loading