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

Commit c8ec72e3 authored by DvTonder's avatar DvTonder
Browse files

Framework: Make Safe headset volume user configurable (1 of 2)

Patch set 1  : Initial commit
Patch set 2  : Alternative approach using content observer to
               listen for settings changes and react dynamically
Patch set 3  : Rebase

Change-Id: I0bd57334ca1307786eaed6578b216323e442f00e
parent f97e4f34
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1960,7 +1960,7 @@ public final class Settings {
         * Whether to prevent loud volume levels when headset is first plugged in.
         * @hide
         */
        public static final String SAFE_HEADSET_VOLUME_RESTORE = "safe_headset_volume_restore";
        public static final String SAFE_HEADSET_VOLUME = "safe_headset_volume";

        /**
         * Master volume (float in the range 0.0f to 1.0f).
+67 −39
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import android.content.res.Resources;
import android.database.ContentObserver;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.Environment;
@@ -681,6 +682,15 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
                0);
    }

    private boolean safeVolumeEnabled(ContentResolver cr) {
        boolean safeMediaVolumeEnabled = mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_safe_media_volume_enabled);
        boolean safeHeadsetVolumeEnabled = Settings.System.getIntForUser(cr,
                Settings.System.SAFE_HEADSET_VOLUME, safeMediaVolumeEnabled ? 1 : 0,
                UserHandle.USER_CURRENT_OR_SELF) != 0;
        return safeHeadsetVolumeEnabled;
    }

    private void readPersistedSettings() {
        final ContentResolver cr = mContentResolver;

@@ -746,6 +756,8 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
                    UserHandle.USER_CURRENT);

            readDockAudioSettings(cr);

            mSafeVolumeEnabled = new Boolean(safeVolumeEnabled(cr));
        }

        mLinkNotificationWithVolume = Settings.System.getIntForUser(cr,
@@ -1844,7 +1856,8 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
        checkAllAliasStreamVolumes();

        synchronized (mSafeMediaVolumeState) {
            if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE) {
            if (mSafeVolumeEnabled &&
                    mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE) {
                enforceSafeMediaVolume();
            }
        }
@@ -2305,7 +2318,8 @@ public class AudioService extends IAudioService.Stub implements OnFinished {

    private void onCheckMusicActive() {
        synchronized (mSafeMediaVolumeState) {
            if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_INACTIVE) {
            if (mSafeVolumeEnabled &&
                    mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_INACTIVE) {
                int device = getDeviceForStream(AudioSystem.STREAM_MUSIC);

                if ((device & mSafeMediaVolumeDevices) != 0) {
@@ -2339,9 +2353,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
            if ((mMcc != mcc) || ((mMcc == 0) && force)) {
                mSafeMediaVolumeIndex = mContext.getResources().getInteger(
                        com.android.internal.R.integer.config_safe_media_volume_index) * 10;
                boolean safeMediaVolumeEnabled = mContext.getResources().getBoolean(
                        com.android.internal.R.bool.config_safe_media_volume_enabled);
                if (safeMediaVolumeEnabled) {
                if (mSafeVolumeEnabled) {
                    mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_ACTIVE;
                    enforceSafeMediaVolume();
                } else {
@@ -3480,16 +3492,21 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
                Settings.System.MODE_RINGER_STREAMS_AFFECTED), false, this);
            mContentResolver.registerContentObserver(Settings.Global.getUriFor(
                Settings.Global.DOCK_AUDIO_MEDIA_ENABLED), false, this);
            mContentResolver.registerContentObserver(Settings.System.getUriFor(
                Settings.System.VOLUME_LINK_NOTIFICATION), false, this);
            mContentResolver.registerContentObserver(Settings.System.getUriFor(
                Settings.System.SAFE_HEADSET_VOLUME), false, this);
        }

        @Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
        public void onChange(boolean selfChange, Uri uri) {
            super.onChange(selfChange, uri);
            // 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) {
                if (uri.equals(Settings.System.getUriFor(Settings.System.MODE_RINGER_STREAMS_AFFECTED))) {
                    int ringerModeAffectedStreams = Settings.System.getIntForUser(mContentResolver,
                           Settings.System.MODE_RINGER_STREAMS_AFFECTED,
                           ((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)|
@@ -3515,15 +3532,22 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
                        mRingerModeAffectedStreams = ringerModeAffectedStreams;
                        setRingerModeInt(getRingerMode(), false);
                    }

                } else if (uri.equals(Settings.Global.getUriFor(Settings.Global.DOCK_AUDIO_MEDIA_ENABLED))) {
                    readDockAudioSettings(mContentResolver);

                mLinkNotificationWithVolume = Settings.System.getIntForUser(mContentResolver,
                        Settings.System.VOLUME_LINK_NOTIFICATION, 1, UserHandle.USER_CURRENT) == 1;
                } else if (uri.equals(Settings.System.getUriFor(Settings.System.VOLUME_LINK_NOTIFICATION))) {
                    mLinkNotificationWithVolume = Settings.System.getInt(mContentResolver,
                            Settings.System.VOLUME_LINK_NOTIFICATION, 1) == 1;
                    if (mLinkNotificationWithVolume) {
                        mStreamVolumeAlias[AudioSystem.STREAM_NOTIFICATION] = AudioSystem.STREAM_RING;
                    } else {
                        mStreamVolumeAlias[AudioSystem.STREAM_NOTIFICATION] = AudioSystem.STREAM_NOTIFICATION;
                    }

                } else if (uri.equals(Settings.System.getUriFor(Settings.System.SAFE_HEADSET_VOLUME))) {
                    mSafeVolumeEnabled = safeVolumeEnabled(mContentResolver);
                }
            }
        }
    }
@@ -6057,6 +6081,8 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
    private Integer mSafeMediaVolumeState;

    private int mMcc = 0;
    // mSafeVolumeEnabled indicates whether to check the volume of media play via headset
    private boolean mSafeVolumeEnabled;
    // mSafeMediaVolumeIndex is the cached value of config_safe_media_volume_index property
    private int mSafeMediaVolumeIndex;
    // mSafeMediaVolumeDevices lists the devices for which safe media volume is enforced,
@@ -6072,7 +6098,8 @@ public class AudioService extends IAudioService.Stub implements OnFinished {

    private void setSafeMediaVolumeEnabled(boolean on) {
        synchronized (mSafeMediaVolumeState) {
            if ((mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_NOT_CONFIGURED) &&
            if (mSafeVolumeEnabled &&
                    (mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_NOT_CONFIGURED) &&
                    (mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_DISABLED)) {
                if (on && (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_INACTIVE)) {
                    mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_ACTIVE;
@@ -6131,7 +6158,8 @@ public class AudioService extends IAudioService.Stub implements OnFinished {

    private boolean checkSafeMediaVolume(int streamType, int index, int device) {
        synchronized (mSafeMediaVolumeState) {
            if ((mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE) &&
            if (mSafeVolumeEnabled &&
                    (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE) &&
                    (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) &&
                    ((device & mSafeMediaVolumeDevices) != 0) &&
                    (index > mSafeMediaVolumeIndex)) {