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

Commit 83a017b6 authored by Eric Laurent's avatar Eric Laurent
Browse files

audio service: add config option for fixed volume

Add a boolean configuration option config_useFixedVolume indicating if
stream volumes or master volume can be modified.
If the option is true, the AudioManager volume and mute APIs will be no ops and the
volumes will be maxed out.
To be consistent:
- the ringer mode is forced to normal and cannot be modified
- volume panel is never displayed
- volume settings are not available
- ringer mode global action is not displayed.

The default for this option if false.

This is useful for a class of devices intended for connection to a digital
audio output only, where the volume is directly controlled on the audio sink.

Bug 8161458

Change-Id: I2571d5ee79952ef0914d8fd1985816467a80adcd
parent e37478c4
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -1043,4 +1043,9 @@

    <!-- Apps that are authorized to access shared accounts, overridden by product overlays -->
    <string name="config_appsAuthorizedForSharedAccounts"></string>

    <!-- Flag indicating that the media framework should not allow changes or mute on any
         stream or master volumes. -->
    <bool name="config_useFixedVolume">false</bool>

</resources>
+1 −0
Original line number Diff line number Diff line
@@ -277,6 +277,7 @@
  <java-symbol type="bool" name="config_camera_sound_forced" />
  <java-symbol type="bool" name="config_dontPreferApn" />
  <java-symbol type="bool" name="config_speed_up_audio_on_mt_calls" />
  <java-symbol type="bool" name="config_useFixedVolume" />

  <java-symbol type="integer" name="config_cursorWindowSize" />
  <java-symbol type="integer" name="config_longPressOnPowerBehavior" />
+70 −6
Original line number Diff line number Diff line
@@ -257,6 +257,8 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
    };
    private int[] mStreamVolumeAlias;

    private final boolean mUseFixedVolume;

    // stream names used by dumpStreamStates()
    private final String[] STREAM_NAMES = new String[] {
            "STREAM_VOICE_CALL",
@@ -487,6 +489,9 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
        mSafeMediaVolumeIndex = mContext.getResources().getInteger(
                com.android.internal.R.integer.config_safe_media_volume_index) * 10;

        mUseFixedVolume = mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_useFixedVolume);

        readPersistedSettings();
        mSettingsObserver = new SettingsObserver();
        updateStreamVolumeAlias(false /*updateVolumes*/);
@@ -678,6 +683,9 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
        if (ringerMode != ringerModeFromSettings) {
            Settings.Global.putInt(cr, Settings.Global.MODE_RINGER, ringerMode);
        }
        if (mUseFixedVolume) {
            ringerMode = AudioManager.RINGER_MODE_NORMAL;
        }
        synchronized(mSettingsLock) {
            mRingerMode = ringerMode;

@@ -736,6 +744,10 @@ public class AudioService extends IAudioService.Stub implements OnFinished {

        boolean masterMute = System.getIntForUser(cr, System.VOLUME_MASTER_MUTE,
                                                  0, UserHandle.USER_CURRENT) == 1;
        if (mUseFixedVolume) {
            masterMute = false;
            AudioSystem.setMasterVolume(1.0f);
        }
        AudioSystem.setMasterMute(masterMute);
        broadcastMasterMuteStatus(masterMute);

@@ -806,6 +818,9 @@ public class AudioService extends IAudioService.Stub implements OnFinished {

    /** @see AudioManager#adjustStreamVolume(int, int, int) */
    public void adjustStreamVolume(int streamType, int direction, int flags) {
        if (mUseFixedVolume) {
            return;
        }
        if (DEBUG_VOL) Log.d(TAG, "adjustStreamVolume() stream="+streamType+", dir="+direction);

        ensureValidDirection(direction);
@@ -918,6 +933,9 @@ public class AudioService extends IAudioService.Stub implements OnFinished {

    /** @see AudioManager#adjustMasterVolume(int) */
    public void adjustMasterVolume(int steps, int flags) {
        if (mUseFixedVolume) {
            return;
        }
        ensureValidSteps(steps);
        int volume = Math.round(AudioSystem.getMasterVolume() * MAX_MASTER_VOLUME);
        int delta = 0;
@@ -972,6 +990,10 @@ public class AudioService extends IAudioService.Stub implements OnFinished {

    /** @see AudioManager#setStreamVolume(int, int, int) */
    public void setStreamVolume(int streamType, int index, int flags) {
        if (mUseFixedVolume) {
            return;
        }

        ensureValidStreamType(streamType);
        VolumeStreamState streamState = mStreamStates[mStreamVolumeAlias[streamType]];

@@ -1214,6 +1236,10 @@ public class AudioService extends IAudioService.Stub implements OnFinished {

    /** @see AudioManager#setStreamSolo(int, boolean) */
    public void setStreamSolo(int streamType, boolean state, IBinder cb) {
        if (mUseFixedVolume) {
            return;
        }

        for (int stream = 0; stream < mStreamStates.length; stream++) {
            if (!isStreamAffectedByMute(stream) || stream == streamType) continue;
            // Bring back last audible volume
@@ -1223,6 +1249,10 @@ public class AudioService extends IAudioService.Stub implements OnFinished {

    /** @see AudioManager#setStreamMute(int, boolean) */
    public void setStreamMute(int streamType, boolean state, IBinder cb) {
        if (mUseFixedVolume) {
            return;
        }

        if (isStreamAffectedByMute(streamType)) {
            mStreamStates[streamType].mute(cb, state);
        }
@@ -1235,6 +1265,10 @@ public class AudioService extends IAudioService.Stub implements OnFinished {

    /** @see AudioManager#setMasterMute(boolean, IBinder) */
    public void setMasterMute(boolean state, int flags, IBinder cb) {
        if (mUseFixedVolume) {
            return;
        }

        if (state != AudioSystem.getMasterMute()) {
            AudioSystem.setMasterMute(state);
            // Post a persist master volume msg
@@ -1268,6 +1302,10 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
    }

    public void setMasterVolume(int volume, int flags) {
        if (mUseFixedVolume) {
            return;
        }

        if (volume < 0) {
            volume = 0;
        } else if (volume > MAX_MASTER_VOLUME) {
@@ -1339,6 +1377,10 @@ public class AudioService extends IAudioService.Stub implements OnFinished {

    /** @see AudioManager#setRingerMode(int) */
    public void setRingerMode(int ringerMode) {
        if (mUseFixedVolume) {
            return;
        }

        if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) {
            ringerMode = AudioManager.RINGER_MODE_SILENT;
        }
@@ -1398,6 +1440,10 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
    }

    private void restoreMasterVolume() {
        if (mUseFixedVolume) {
            AudioSystem.setMasterVolume(1.0f);
            return;
        }
        if (mUseMasterVolume) {
            float volume = Settings.System.getFloatForUser(mContentResolver,
                    Settings.System.VOLUME_MASTER, -1.0f, UserHandle.USER_CURRENT);
@@ -1951,8 +1997,8 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
                streamState.readSettings();

                // unmute stream that was muted but is not affect by mute anymore
                if (streamState.muteCount() != 0 && !isStreamAffectedByMute(streamType) &&
                        !isStreamMutedByRingerMode(streamType)) {
                if (streamState.muteCount() != 0 && ((!isStreamAffectedByMute(streamType) &&
                        !isStreamMutedByRingerMode(streamType)) || mUseFixedVolume)) {
                    int size = streamState.mDeathHandlers.size();
                    for (int i = 0; i < size; i++) {
                        streamState.mDeathHandlers.get(i).mMuteCount = 1;
@@ -2833,8 +2879,12 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
        }

        public synchronized void readSettings() {
            int remainingDevices = AudioSystem.DEVICE_OUT_ALL;

            // force maximum volume on all streams if fixed volume property is set
            if (mUseFixedVolume) {
                mIndex.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax);
                mLastAudibleIndex.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax);
                return;
            }
            // do not read system stream volume from settings: this stream is always aliased
            // to another stream type and its volume is never persisted. Values in settings can
            // only be stale values
@@ -2855,6 +2905,8 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
                return;
            }

            int remainingDevices = AudioSystem.DEVICE_OUT_ALL;

            for (int i = 0; remainingDevices != 0; i++) {
                int device = (1 << i);
                if ((device & remainingDevices) == 0) {
@@ -2972,7 +3024,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
                    index = mIndexMax;
                }
            }
            mIndex.put(device, getValidIndex(index));
            mIndex.put(device, index);

            if (oldIndex != index) {
                if (lastAudible) {
@@ -3106,7 +3158,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
        private int getValidIndex(int index) {
            if (index < 0) {
                return 0;
            } else if (index > mIndexMax) {
            } else if (mUseFixedVolume || index > mIndexMax) {
                return mIndexMax;
            }

@@ -3328,6 +3380,9 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
        private void persistVolume(VolumeStreamState streamState,
                                   int persistType,
                                   int device) {
            if (mUseFixedVolume) {
                return;
            }
            if ((persistType & PERSIST_CURRENT) != 0) {
                System.putIntForUser(mContentResolver,
                          streamState.getSettingNameForDevice(false /* lastAudible */, device),
@@ -3343,6 +3398,9 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
        }

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

@@ -3439,6 +3497,9 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
                    break;

                case MSG_PERSIST_MASTER_VOLUME:
                    if (mUseFixedVolume) {
                        return;
                    }
                    Settings.System.putFloatForUser(mContentResolver,
                                                    Settings.System.VOLUME_MASTER,
                                                    (float)msg.arg1 / (float)1000.0,
@@ -3446,6 +3507,9 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
                    break;

                case MSG_PERSIST_MASTER_VOLUME_MUTE:
                    if (mUseFixedVolume) {
                        return;
                    }
                    Settings.System.putIntForUser(mContentResolver,
                                                 Settings.System.VOLUME_MASTER_MUTE,
                                                 msg.arg1,
+11 −4
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ public class MediaAudioManagerTest extends ActivityInstrumentationTestCase2<Medi
    private final static int WAIT_FOR_LOOPER_TO_INITIALIZE_MS = 60000;  // 60s
    private int[] ringtoneMode = {AudioManager.RINGER_MODE_NORMAL,
             AudioManager.RINGER_MODE_SILENT, AudioManager.RINGER_MODE_VIBRATE};
    private boolean mUseFixedVolume;

    public MediaAudioManagerTest() {
        super("com.android.mediaframeworktest", MediaFrameworkTest.class);
@@ -65,6 +66,10 @@ public class MediaAudioManagerTest extends ActivityInstrumentationTestCase2<Medi
    @Override
    protected void setUp() throws Exception {
        super.setUp();

        mUseFixedVolume = getActivity().getResources().getBoolean(
                com.android.internal.R.bool.config_useFixedVolume);

        synchronized(mLooperLock) {
            initializeAudioManagerWithLooper();
            try {
@@ -91,10 +96,12 @@ public class MediaAudioManagerTest extends ActivityInstrumentationTestCase2<Medi

     public boolean validateSetRingTone(int i) {
         int getRingtone = mAudioManager.getRingerMode();
         if (i != getRingtone)
             return false;
         else
             return true;

         if (mUseFixedVolume) {
             return (getRingtone == AudioManager.RINGER_MODE_NORMAL);
         } else {
             return (getRingtone == i);
         }
     }

     // Test case 1: Simple test case to validate the set ringtone mode
+7 −3
Original line number Diff line number Diff line
@@ -102,6 +102,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
    private boolean mIsWaitingForEcmExit = false;
    private boolean mHasTelephony;
    private boolean mHasVibrator;
    private final boolean mShowSilentToggle;

    /**
     * @param context everything needs a context :(
@@ -132,6 +133,9 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
                mAirplaneModeObserver);
        Vibrator vibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
        mHasVibrator = vibrator != null && vibrator.hasVibrator();

        mShowSilentToggle = SHOW_SILENT_TOGGLE && !mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_useFixedVolume);
    }

    /**
@@ -309,7 +313,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
        }

        // last: silent mode
        if (SHOW_SILENT_TOGGLE) {
        if (mShowSilentToggle) {
            mItems.add(mSilentModeAction);
        }

@@ -390,7 +394,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
        mAirplaneModeOn.updateState(mAirplaneState);
        mAdapter.notifyDataSetChanged();
        mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
        if (SHOW_SILENT_TOGGLE) {
        if (mShowSilentToggle) {
            IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION);
            mContext.registerReceiver(mRingerModeReceiver, filter);
        }
@@ -407,7 +411,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac

    /** {@inheritDoc} */
    public void onDismiss(DialogInterface dialog) {
        if (SHOW_SILENT_TOGGLE) {
        if (mShowSilentToggle) {
            try {
                mContext.unregisterReceiver(mRingerModeReceiver);
            } catch (IllegalArgumentException ie) {