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

Commit bc00f4c8 authored by Vlad Popa's avatar Vlad Popa Committed by Android (Google) Code Review
Browse files

Merge "AbsVol: send per device the abs volume state to APM" into main

parents e6a95594 dc8653b2
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -713,6 +713,19 @@ android_media_AudioSystem_getForceUse(JNIEnv *env, jobject thiz, jint usage)
            AudioSystem::getForceUse(static_cast<audio_policy_force_use_t>(usage)));
}

static jint android_media_AudioSystem_setDeviceAbsoluteVolumeEnabled(JNIEnv *env, jobject thiz,
                                                                     jint device, jstring address,
                                                                     jboolean enabled,
                                                                     jint stream) {
    const char *c_address = env->GetStringUTFChars(address, nullptr);
    int state = check_AudioSystem_Command(
            AudioSystem::setDeviceAbsoluteVolumeEnabled(static_cast<audio_devices_t>(device),
                                                        c_address, enabled,
                                                        static_cast<audio_stream_type_t>(stream)));
    env->ReleaseStringUTFChars(address, c_address);
    return state;
}

static jint
android_media_AudioSystem_initStreamVolume(JNIEnv *env, jobject thiz, jint stream, jint indexMin, jint indexMax)
{
@@ -3373,6 +3386,7 @@ static const JNINativeMethod gMethods[] =
         MAKE_AUDIO_SYSTEM_METHOD(setPhoneState),
         MAKE_AUDIO_SYSTEM_METHOD(setForceUse),
         MAKE_AUDIO_SYSTEM_METHOD(getForceUse),
         MAKE_AUDIO_SYSTEM_METHOD(setDeviceAbsoluteVolumeEnabled),
         MAKE_AUDIO_SYSTEM_METHOD(initStreamVolume),
         MAKE_AUDIO_SYSTEM_METHOD(setStreamVolumeIndex),
         MAKE_AUDIO_SYSTEM_METHOD(getStreamVolumeIndex),
+4 −0
Original line number Diff line number Diff line
@@ -1764,6 +1764,10 @@ public class AudioSystem
    public static native int getForceUse(int usage);
    /** @hide */
    @UnsupportedAppUsage
    public static native int setDeviceAbsoluteVolumeEnabled(int nativeDeviceType,
            @NonNull String address, boolean enabled, int streamToDriveAbs);
    /** @hide */
    @UnsupportedAppUsage
    public static native int initStreamVolume(int stream, int indexMin, int indexMax);
    @UnsupportedAppUsage
    private static native int setStreamVolumeIndex(int stream, int index, int device);
+123 −22
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ import static android.provider.Settings.Secure.VOLUME_HUSH_OFF;
import static android.provider.Settings.Secure.VOLUME_HUSH_VIBRATE;
import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
import static com.android.media.audio.Flags.absVolumeIndexFix;
import static com.android.media.audio.Flags.alarmMinVolumeZero;
import static com.android.media.audio.Flags.disablePrescaleAbsoluteVolume;
import static com.android.media.audio.Flags.ringerModeAffectsAlarm;
@@ -632,6 +633,17 @@ public class AudioService extends IAudioService.Stub
    // If absolute volume is supported in AVRCP device
    private volatile boolean mAvrcpAbsVolSupported = false;
    private final Object mCachedAbsVolDrivingStreamsLock = new Object();
    // Contains for all the device types which support absolute volume the current streams that
    // are driving the volume changes
    @GuardedBy("mCachedAbsVolDrivingStreamsLock")
    private final HashMap<Integer, Integer> mCachedAbsVolDrivingStreams = new HashMap<>(
            Map.of(AudioSystem.DEVICE_OUT_BLE_HEADSET, AudioSystem.STREAM_MUSIC,
                    AudioSystem.DEVICE_OUT_BLE_SPEAKER, AudioSystem.STREAM_MUSIC,
                    AudioSystem.DEVICE_OUT_BLE_BROADCAST, AudioSystem.STREAM_MUSIC,
                    AudioSystem.DEVICE_OUT_HEARING_AID, AudioSystem.STREAM_MUSIC
            ));
    /**
    * Default stream type used for volume control in the absence of playback
    * e.g. user on homescreen, no app playing anything, presses hardware volume buttons, this
@@ -1472,6 +1484,13 @@ public class AudioService extends IAudioService.Stub
        // check on volume initialization
        checkVolumeRangeInitialization("AudioService()");
        synchronized (mCachedAbsVolDrivingStreamsLock) {
            mCachedAbsVolDrivingStreams.forEach((dev, stream) -> {
                mAudioSystem.setDeviceAbsoluteVolumeEnabled(dev, /*address=*/"", /*enabled=*/true,
                        stream);
            });
        }
    }
    private SubscriptionManager.OnSubscriptionsChangedListener mSubscriptionChangedListener =
@@ -1911,6 +1930,14 @@ public class AudioService extends IAudioService.Stub
        }
        onIndicateSystemReady();
        synchronized (mCachedAbsVolDrivingStreamsLock) {
            mCachedAbsVolDrivingStreams.forEach((dev, stream) -> {
                mAudioSystem.setDeviceAbsoluteVolumeEnabled(dev, /*address=*/"", /*enabled=*/true,
                        stream);
            });
        }
        // indicate the end of reconfiguration phase to audio HAL
        AudioSystem.setParameters("restarting=false");
@@ -3737,8 +3764,10 @@ public class AudioService extends IAudioService.Stub
            int newIndex = mStreamStates[streamType].getIndex(device);
            int streamToDriveAbsVol = absVolumeIndexFix() ? getBluetoothContextualVolumeStream() :
                    AudioSystem.STREAM_MUSIC;
            // Check if volume update should be send to AVRCP
            if (streamTypeAlias == AudioSystem.STREAM_MUSIC
            if (streamTypeAlias == streamToDriveAbsVol
                    && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
                    && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
                if (DEBUG_VOL) {
@@ -4540,6 +4569,8 @@ public class AudioService extends IAudioService.Stub
                + scoManagedByAudio());
        pw.println("\tcom.android.media.audio.vgsVssSyncMuteOrder:"
                + vgsVssSyncMuteOrder());
        pw.println("\tcom.android.media.audio.absVolumeIndexFix:"
                + absVolumeIndexFix());
    }
    private void dumpAudioMode(PrintWriter pw) {
@@ -4735,7 +4766,9 @@ public class AudioService extends IAudioService.Stub
            }
        }
        if (streamTypeAlias == AudioSystem.STREAM_MUSIC
        int streamToDriveAbsVol = absVolumeIndexFix() ? getBluetoothContextualVolumeStream() :
                AudioSystem.STREAM_MUSIC;
        if (streamTypeAlias == streamToDriveAbsVol
                && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
                && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
            if (DEBUG_VOL) {
@@ -6184,6 +6217,17 @@ public class AudioService extends IAudioService.Stub
                setLeAudioVolumeOnModeUpdate(mode, device, streamAlias, index, maxIndex);
                synchronized (mCachedAbsVolDrivingStreamsLock) {
                    mCachedAbsVolDrivingStreams.replaceAll((absDev, stream) -> {
                        int streamToDriveAbs = getBluetoothContextualVolumeStream();
                        if (stream != streamToDriveAbs) {
                            mAudioSystem.setDeviceAbsoluteVolumeEnabled(absDev, /*address=*/
                                    "", /*enabled*/true, streamToDriveAbs);
                        }
                        return streamToDriveAbs;
                    });
                }
                // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all SCO
                // connections not started by the application changing the mode when pid changes
                mDeviceBroker.postSetModeOwner(mode, pid, uid);
@@ -8105,6 +8149,10 @@ public class AudioService extends IAudioService.Stub
            return mAudioVolumeGroup.name();
        }
        public int getId() {
            return mAudioVolumeGroup.getId();
        }
        /**
         * Volume group with non null minimum index are considered as non mutable, thus
         * bijectivity is broken with potential associated stream type.
@@ -8755,12 +8803,17 @@ public class AudioService extends IAudioService.Stub
        }
        private int getAbsoluteVolumeIndex(int index) {
            if (absVolumeIndexFix()) {
                // The attenuation is applied in the APM. No need to manipulate the index here
                return index;
            } else {
                /* Special handling for Bluetooth Absolute Volume scenario
                 * If we send full audio gain, some accessories are too loud even at its lowest
                 * volume. We are not able to enumerate all such accessories, so here is the
                 * workaround from phone side.
                 * Pre-scale volume at lowest volume steps 1 2 and 3.
             * For volume step 0, set audio gain to 0 as some accessories won't mute on their end.
                 * For volume step 0, set audio gain to 0 as some accessories won't mute on their
                 * end.
                 */
                if (index == 0) {
                    // 0% for volume 0
@@ -8774,6 +8827,7 @@ public class AudioService extends IAudioService.Stub
                }
                return index;
            }
        }
        private void setStreamVolumeIndex(int index, int device) {
            // Only set audio policy BT SCO stream volume to 0 when the stream is actually muted.
@@ -8783,6 +8837,11 @@ public class AudioService extends IAudioService.Stub
                    && !isFullyMuted()) {
                index = 1;
            }
            if (DEBUG_VOL) {
                Log.d(TAG, "setStreamVolumeIndexAS(" + mStreamType + ", " + index + ", " + device
                        + ")");
            }
            mAudioSystem.setStreamVolumeIndexAS(mStreamType, index, device);
        }
@@ -8794,14 +8853,24 @@ public class AudioService extends IAudioService.Stub
            } else if (isAbsoluteVolumeDevice(device)
                    || isA2dpAbsoluteVolumeDevice(device)
                    || AudioSystem.isLeAudioDeviceType(device)) {
                // do not change the volume logic for dynamic abs behavior devices like HDMI
                if (absVolumeIndexFix() && isAbsoluteVolumeDevice(device)) {
                    index = getAbsoluteVolumeIndex((mIndexMax + 5) / 10);
                } else {
                    index = getAbsoluteVolumeIndex((getIndex(device) + 5) / 10);
                }
            } else if (isFullVolumeDevice(device)) {
                index = (mIndexMax + 5)/10;
            } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
                if (absVolumeIndexFix()) {
                    index = getAbsoluteVolumeIndex((getIndex(device) + 5) / 10);
                } else {
                    index = (mIndexMax + 5) / 10;
                }
            } else {
                index = (getIndex(device) + 5)/10;
            }
            setStreamVolumeIndex(index, device);
        }
@@ -8819,11 +8888,22 @@ public class AudioService extends IAudioService.Stub
                                || isA2dpAbsoluteVolumeDevice(device)
                                || AudioSystem.isLeAudioDeviceType(device)) {
                            isAbsoluteVolume = true;
                            // do not change the volume logic for dynamic abs behavior devices
                            // like HDMI
                            if (absVolumeIndexFix() && isAbsoluteVolumeDevice(device)) {
                                index = getAbsoluteVolumeIndex((mIndexMax + 5) / 10);
                            } else {
                                index = getAbsoluteVolumeIndex((getIndex(device) + 5) / 10);
                            }
                        } else if (isFullVolumeDevice(device)) {
                            index = (mIndexMax + 5)/10;
                        } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
                            if (absVolumeIndexFix()) {
                                isAbsoluteVolume = true;
                                index = getAbsoluteVolumeIndex((getIndex(device) + 5) / 10);
                            } else {
                                index = (mIndexMax + 5) / 10;
                            }
                        } else {
                            index = (mIndexMap.valueAt(i) + 5)/10;
                        }
@@ -9820,6 +9900,27 @@ public class AudioService extends IAudioService.Stub
    /*package*/ void setAvrcpAbsoluteVolumeSupported(boolean support) {
        mAvrcpAbsVolSupported = support;
        if (absVolumeIndexFix()) {
            int a2dpDev = AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP;
            synchronized (mCachedAbsVolDrivingStreamsLock) {
                mCachedAbsVolDrivingStreams.compute(a2dpDev, (dev, stream) -> {
                    if (stream != null && !mAvrcpAbsVolSupported) {
                        mAudioSystem.setDeviceAbsoluteVolumeEnabled(a2dpDev, /*address=*/
                                "", /*enabled*/false, AudioSystem.DEVICE_NONE);
                        return null;
                    }
                    // For A2DP and AVRCP we need to set the driving stream based on the
                    // BT contextual stream. Hence, we need to make sure in adjustStreamVolume
                    // and setStreamVolume that the driving abs volume stream is consistent.
                    int streamToDriveAbs = getBluetoothContextualVolumeStream();
                    if (stream == null || stream != streamToDriveAbs) {
                        mAudioSystem.setDeviceAbsoluteVolumeEnabled(a2dpDev, /*address=*/
                                "", /*enabled*/true, streamToDriveAbs);
                    }
                    return streamToDriveAbs;
                });
            }
        }
        sendMsg(mAudioHandler, MSG_SET_DEVICE_VOLUME, SENDMSG_QUEUE,
                    AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0,
                    mStreamStates[AudioSystem.STREAM_MUSIC], 0);
+15 −0
Original line number Diff line number Diff line
@@ -597,6 +597,21 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback,
        return AudioSystem.getForceUse(usage);
    }

    /**
     * Same as {@link AudioSystem#setDeviceAbsoluteVolumeEnabled(int, String, boolean, int)}
     * @param nativeDeviceType the internal device type for which absolute volume is
     *                         enabled/disabled
     * @param address the address of the device for which absolute volume is enabled/disabled
     * @param enabled whether the absolute volume is enabled/disabled
     * @param streamToDriveAbs the stream that is controlling the absolute volume
     * @return status of indicating the success of this operation
     */
    public int setDeviceAbsoluteVolumeEnabled(int nativeDeviceType, @NonNull String address,
            boolean enabled, int streamToDriveAbs) {
        return AudioSystem.setDeviceAbsoluteVolumeEnabled(nativeDeviceType, address, enabled,
                streamToDriveAbs);
    }

    /**
     * Same as {@link AudioSystem#registerPolicyMixes(ArrayList, boolean)}
     * @param mixes
+3 −1
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import static android.view.KeyEvent.ACTION_DOWN;
import static android.view.KeyEvent.KEYCODE_VOLUME_UP;

import static com.android.media.audio.Flags.FLAG_DISABLE_PRESCALE_ABSOLUTE_VOLUME;
import static com.android.media.audio.Flags.FLAG_ABS_VOLUME_INDEX_FIX;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
@@ -552,7 +553,7 @@ public class VolumeHelperTest {
    }

    @Test
    @RequiresFlagsDisabled(FLAG_DISABLE_PRESCALE_ABSOLUTE_VOLUME)
    @RequiresFlagsDisabled({FLAG_DISABLE_PRESCALE_ABSOLUTE_VOLUME, FLAG_ABS_VOLUME_INDEX_FIX})
    public void configurablePreScaleAbsoluteVolume_checkIndex() throws Exception {
        final int minIndex = mAm.getStreamMinVolume(STREAM_MUSIC);
        final int maxIndex = mAm.getStreamMaxVolume(STREAM_MUSIC);
@@ -607,6 +608,7 @@ public class VolumeHelperTest {

    @Test
    @RequiresFlagsEnabled(FLAG_DISABLE_PRESCALE_ABSOLUTE_VOLUME)
    @RequiresFlagsDisabled(FLAG_ABS_VOLUME_INDEX_FIX)
    public void disablePreScaleAbsoluteVolume_checkIndex() throws Exception {
        final int minIndex = mAm.getStreamMinVolume(STREAM_MUSIC);
        final int maxIndex = mAm.getStreamMaxVolume(STREAM_MUSIC);