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

Commit 2be69d4c authored by Oscar Azucena's avatar Oscar Azucena Committed by Android (Google) Code Review
Browse files

Merge "Audio: manage volume per group ID" into main

parents 06523e8e abfbff30
Loading
Loading
Loading
Loading
+84 −23
Original line number Diff line number Diff line
@@ -788,12 +788,8 @@ static jint android_media_AudioSystem_setVolumeIndexForAttributes(JNIEnv *env, j
                                                     static_cast<audio_devices_t>(device)));
}

static jint
android_media_AudioSystem_getVolumeIndexForAttributes(JNIEnv *env,
                                                      jobject thiz,
                                                      jobject jaa,
                                                      jint device)
{
static jint android_media_AudioSystem_getMinVolumeIndexForAttributes(JNIEnv *env, jobject thiz,
                                                                     jobject jaa) {
    // read the AudioAttributes values
    JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique();
    jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get());
@@ -801,19 +797,16 @@ android_media_AudioSystem_getVolumeIndexForAttributes(JNIEnv *env,
        return jStatus;
    }
    int index;
    if (AudioSystem::getVolumeIndexForAttributes(*(paa.get()), index,
                                                 static_cast<audio_devices_t>(device)) !=
        NO_ERROR) {
    status_t status = AudioSystem::getMinVolumeIndexForAttributes(*(paa.get()), index);
    if (status != NO_ERROR) {
        index = -1;
        ALOGE("%s AudioSystem::getMinVolumeIndexForAttributes error %d", __func__, status);
    }
    return index;
}

static jint
android_media_AudioSystem_getMinVolumeIndexForAttributes(JNIEnv *env,
                                                         jobject thiz,
                                                         jobject jaa)
{
static jint android_media_AudioSystem_getMaxVolumeIndexForAttributes(JNIEnv *env, jobject thiz,
                                                                     jobject jaa) {
    // read the AudioAttributes values
    JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique();
    jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get());
@@ -821,18 +814,16 @@ android_media_AudioSystem_getMinVolumeIndexForAttributes(JNIEnv *env,
        return jStatus;
    }
    int index;
    if (AudioSystem::getMinVolumeIndexForAttributes(*(paa.get()), index)
            != NO_ERROR) {
    status_t status = AudioSystem::getMaxVolumeIndexForAttributes(*(paa.get()), index);
    if (status != NO_ERROR) {
        index = -1;
        ALOGE("%s AudioSystem::getMaxVolumeIndexForAttributes error %d", __func__, status);
    }
    return index;
}

static jint
android_media_AudioSystem_getMaxVolumeIndexForAttributes(JNIEnv *env,
                                                         jobject thiz,
                                                         jobject jaa)
{
static jint android_media_AudioSystem_getVolumeIndexForAttributes(JNIEnv *env, jobject thiz,
                                                                  jobject jaa, jint device) {
    // read the AudioAttributes values
    JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique();
    jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jaa, paa.get());
@@ -840,13 +831,71 @@ android_media_AudioSystem_getMaxVolumeIndexForAttributes(JNIEnv *env,
        return jStatus;
    }
    int index;
    if (AudioSystem::getMaxVolumeIndexForAttributes(*(paa.get()), index)
            != NO_ERROR) {
    status_t status =
            AudioSystem::getVolumeIndexForAttributes(*(paa.get()), index,
                                                     static_cast<audio_devices_t>(device));
    if (status != NO_ERROR) {
        ALOGE("%s AudioSystem::getVolumeIndexForAttributes error %d", __func__, status);
        index = -1;
    }
    return index;
}

static jint android_media_AudioSystem_setVolumeIndexForGroup(JNIEnv *env, jobject thiz,
                                                             jint groupId, jint index,
                                                             jboolean muted, int device) {
    return (jint)check_AudioSystem_Command(
            AudioSystem::setVolumeIndexForGroup(static_cast<volume_group_t>(groupId), index, muted,
                                                static_cast<audio_devices_t>(device)));
}

static jint android_media_AudioSystem_getVolumeIndexForGroup(JNIEnv *env, jobject thiz,
                                                             jint groupId, jint device) {
    int index;
    status_t status =
            AudioSystem::getVolumeIndexForGroup(static_cast<volume_group_t>(groupId), index,
                                                static_cast<audio_devices_t>(device));
    if (status != NO_ERROR) {
        ALOGE("%s AudioSystem::getVolumeIndexForGroup error %d", __func__, status);
        index = -1;
    }
    return (jint)index;
}

static jint android_media_AudioSystem_getMinVolumeIndexForGroup(JNIEnv *env, jobject thiz,
                                                                jint groupId) {
    int index;
    if (AudioSystem::getMinVolumeIndexForGroup(static_cast<volume_group_t>(groupId), index) !=
        NO_ERROR) {
        index = -1;
    }
    return index;
}

static jint android_media_AudioSystem_setMinVolumeIndexForGroup(JNIEnv *env, jobject thiz,
                                                                jint groupId, jint index) {
    return check_AudioSystem_Command(
            AudioSystem::setMinVolumeIndexForGroup(static_cast<volume_group_t>(groupId), index));
}

static jint android_media_AudioSystem_getMaxVolumeIndexForGroup(JNIEnv *env, jobject thiz,
                                                                jint groupId) {
    int index;
    status_t status =
            AudioSystem::getMaxVolumeIndexForGroup(static_cast<volume_group_t>(groupId), index);
    if (status != NO_ERROR) {
        ALOGE("%s AudioSystem::getMaxVolumeIndexForGroup error %d", __func__, status);
        index = -1;
    }
    return index;
}

static jint android_media_AudioSystem_setMaxVolumeIndexForGroup(JNIEnv *env, jobject thiz,
                                                                jint groupId, jint index) {
    return check_AudioSystem_Command(
            AudioSystem::setMaxVolumeIndexForGroup(static_cast<volume_group_t>(groupId), index));
}

static jint
android_media_AudioSystem_setMasterVolume(JNIEnv *env, jobject thiz, jfloat value)
{
@@ -3497,6 +3546,18 @@ static const JNINativeMethod gMethods[] = {
        MAKE_JNI_NATIVE_METHOD("getMaxVolumeIndexForAttributes",
                               "(Landroid/media/AudioAttributes;)I",
                               android_media_AudioSystem_getMaxVolumeIndexForAttributes),
        MAKE_JNI_NATIVE_METHOD("setVolumeIndexForGroup", "(IIZI)I",
                               android_media_AudioSystem_setVolumeIndexForGroup),
        MAKE_JNI_NATIVE_METHOD("getVolumeIndexForGroup", "(II)I",
                               android_media_AudioSystem_getVolumeIndexForGroup),
        MAKE_JNI_NATIVE_METHOD("getMinVolumeIndexForGroup", "(I)I",
                               android_media_AudioSystem_getMinVolumeIndexForGroup),
        MAKE_JNI_NATIVE_METHOD("setMinVolumeIndexForGroup", "(II)I",
                               android_media_AudioSystem_setMinVolumeIndexForGroup),
        MAKE_JNI_NATIVE_METHOD("getMaxVolumeIndexForGroup", "(I)I",
                               android_media_AudioSystem_getMaxVolumeIndexForGroup),
        MAKE_JNI_NATIVE_METHOD("setMaxVolumeIndexForGroup", "(II)I",
                               android_media_AudioSystem_setMaxVolumeIndexForGroup),
        MAKE_AUDIO_SYSTEM_METHOD(setMasterVolume),
        MAKE_AUDIO_SYSTEM_METHOD(getMasterVolume),
        MAKE_AUDIO_SYSTEM_METHOD(setMasterMute),
+81 −5
Original line number Diff line number Diff line
@@ -1814,11 +1814,13 @@ public class AudioSystem
        return 0;
    }
    /**
     * @hide
     * Send the current audio mode to audio policy manager and audio HAL.
     *
     * @param state the audio mode
     * @param uid the UID of the app owning the audio mode
     * @return command completion status.
     *
     * @hide
     */
    public static native int setPhoneState(int state, int uid);
    /** @hide */
@@ -1839,41 +1841,115 @@ public class AudioSystem
            int device);
    /** @hide */
    public static native int getStreamVolumeIndex(int stream, int device);

    /**
     * @hide
     * set a volume for the given {@link AudioAttributes} and for all other stream that belong to
     * the same volume group.
     *
     * @param attributes the {@link AudioAttributes} to be considered
     * @param index to be applied
     * @param device the volume device to be considered
     * @return command completion status.
     *
     * @hide
     */
    public static native int setVolumeIndexForAttributes(@NonNull AudioAttributes attributes,
                                                         int index, boolean muted, int device);
   /**
    * @hide
    * get the volume index for the given {@link AudioAttributes}.
    *
    * @param attributes the {@link AudioAttributes} to be considered
    * @param device the volume device to be considered
    * @return volume index for the given {@link AudioAttributes} and volume device.
    *
    * @hide
    */
    public static native int getVolumeIndexForAttributes(@NonNull AudioAttributes attributes,
                                                         int device);
    /**
     * @hide
     * get the minimum volume index for the given {@link AudioAttributes}.
     *
     * @param attributes the {@link AudioAttributes} to be considered
     * @return minimum volume index for the given {@link AudioAttributes}.
     *
     * @hide
     */
    public static native int getMinVolumeIndexForAttributes(@NonNull AudioAttributes attributes);
    /**
     * @hide
     * get the maximum volume index for the given {@link AudioAttributes}.
     *
     * @param attributes the {@link AudioAttributes} to be considered
     * @return maximum volume index for the given {@link AudioAttributes}.
     *
     * @hide
     */
    public static native int getMaxVolumeIndexForAttributes(@NonNull AudioAttributes attributes);

    /**
     * Set a volume for the given group id and device type.
     *
     * @param groupId the {@link AudioVolumeGroup} id to be considered
     * @param index to be applied
     * @param muted state of the group
     * @param device the volume device to be considered
     * @return command completion status.
     *
     * @hide
     */
    public static native int setVolumeIndexForGroup(int groupId, int index,
            boolean muted, int device);

    /**
     * Get the volume index for the given group id and device.
     *
     * @param groupId the {@link AudioVolumeGroup} id to be considered
     * @param device the volume device to be considered
     * @return volume index for the given volume group and volume device.
     *
     * @hide
     */
    public static native int getVolumeIndexForGroup(int groupId, int device);

    /**
     * Get the minimum volume index for the given group id.
     *
     * @param groupId the {@link AudioVolumeGroup} id to be considered
     * @return minimum volume index for the given volume group.
     *
     * @hide
     */
    public static native int getMinVolumeIndexForGroup(int groupId);

    /**
     * Set the minimum volume index for the given group id.
     *
     * @param groupId the {@link AudioVolumeGroup} id to be set
     * @return minimum volume index for the given volume group.
     *
     * @hide
     */
    public static native int setMinVolumeIndexForGroup(int groupId, int index);

    /**
     * Get the maximum volume index for the given group id.
     *
     * @param groupId the {@link AudioVolumeGroup} id to be considered
     * @return maximum volume index for the given volume group.
     *
     * @hide
     */
    public static native int getMaxVolumeIndexForGroup(int groupId);

    /**
     * Set the maximum volume index for the given group id.
     *
     * @param groupId the {@link AudioVolumeGroup} id to be set
     * @return maximum volume index for the given volume group.
     *
     * @hide
     */
    public static native int setMaxVolumeIndexForGroup(int groupId, int index);

    /** @hide */
    public static native int setMasterVolume(float value);
    /** @hide */
+104 −21
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ import static android.media.audio.Flags.roForegroundAudioControl;
import static android.media.audio.Flags.scoManagedByAudio;
import static android.media.audio.Flags.unifyAbsoluteVolumeManagement;
import static android.media.audiopolicy.Flags.enableFadeManagerConfiguration;
import static android.media.audiopolicy.Flags.volumeGroupManagementUpdate;
import static android.os.Process.FIRST_APPLICATION_UID;
import static android.os.Process.INVALID_UID;
import static android.provider.Settings.Secure.VOLUME_HUSH_MUTE;
@@ -1410,14 +1411,25 @@ public class AudioService extends IAudioService.Stub
            int numStreamTypes = AudioSystem.getNumStreamTypes();
            for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
                int maxVolume = -1;
                int minVolume = -1;
                if (volumeGroupManagementUpdate()) {
                    int groupId = getVolumeGroupForStreamType(streamType);
                    if (groupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) {
                        maxVolume = AudioSystem.getMaxVolumeIndexForGroup(groupId);
                        minVolume = AudioSystem.getMinVolumeIndexForGroup(groupId);
                    }
                } else {
                    AudioAttributes attr =
                            AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(
                                    streamType);
                int maxVolume = AudioSystem.getMaxVolumeIndexForAttributes(attr);
                    maxVolume = AudioSystem.getMaxVolumeIndexForAttributes(attr);
                    minVolume = AudioSystem.getMinVolumeIndexForAttributes(attr);
                }
                if (maxVolume != -1) {
                    MAX_STREAM_VOLUME[streamType] = maxVolume;
                }
                int minVolume = AudioSystem.getMinVolumeIndexForAttributes(attr);
                if (minVolume != -1) {
                    MIN_STREAM_VOLUME[streamType] = minVolume;
                }
@@ -2283,11 +2295,21 @@ public class AudioService extends IAudioService.Stub
            if (streamState == null) {
                continue;
            }
            final int res = AudioSystem.initStreamVolume(
                    streamType, MIN_STREAM_VOLUME[streamType], MAX_STREAM_VOLUME[streamType]);
            if (res != AudioSystem.AUDIO_STATUS_OK) {
                status = res;
                Log.e(TAG, "Failed to initStreamVolume (" + res + ") for stream " + streamType);
            int result;
            if (volumeGroupManagementUpdate()) {
                int groupId = getVolumeGroupForStreamType(streamType);
                result = initMinMaxForVolumeGroup(groupId, MIN_STREAM_VOLUME[streamType],
                        MAX_STREAM_VOLUME[streamType], /* logEvent= */ false);
            } else {
                result = AudioSystem.initStreamVolume(streamType, MIN_STREAM_VOLUME[streamType],
                        MAX_STREAM_VOLUME[streamType]);
                if (result != AudioSystem.AUDIO_STATUS_OK) {
                    Log.e(TAG, "Failed to initStreamVolume (" + result + ") for stream "
                            + streamType);
                }
            }
            if (result != AudioSystem.AUDIO_STATUS_OK) {
                status = result;
                // stream volume initialization failed, no need to try the others, it will be
                // attempted again when MSG_REINIT_VOLUMES is handled
                break;
@@ -2341,10 +2363,23 @@ public class AudioService extends IAudioService.Stub
                AudioSystem.STREAM_MUSIC, AudioSystem.STREAM_VOICE_CALL,
                AudioSystem.STREAM_ACCESSIBILITY };
        for (int streamType : basicStreams) {
            int maxVolumeIndex;
            int minVolumeIndex;
            if (volumeGroupManagementUpdate()) {
                int groupId = getVolumeGroupForStreamType(streamType);
                if (groupId == AudioVolumeGroup.DEFAULT_VOLUME_GROUP) {
                    success = false;
                    break;
                }
                maxVolumeIndex = AudioSystem.getMaxVolumeIndexForGroup(groupId);
                minVolumeIndex = AudioSystem.getMinVolumeIndexForGroup(groupId);
            } else {
                final AudioAttributes aa = new AudioAttributes.Builder()
                        .setInternalLegacyStreamType(streamType).build();
            if (AudioSystem.getMaxVolumeIndexForAttributes(aa) < 0
                    || AudioSystem.getMinVolumeIndexForAttributes(aa) < 0) {
                maxVolumeIndex = AudioSystem.getMaxVolumeIndexForAttributes(aa);
                minVolumeIndex = AudioSystem.getMinVolumeIndexForAttributes(aa);
            }
            if (maxVolumeIndex < 0 || minVolumeIndex < 0) {
                success = false;
                break;
            }
@@ -8859,6 +8894,35 @@ public class AudioService extends IAudioService.Stub
                attributes, /* fallbackOnDefault= */ false);
    }
    private static int initMinMaxForVolumeGroup(int groupId, int minVol, int maxVol,
            boolean logEvent) {
        int status = AudioSystem.setMinVolumeIndexForGroup(groupId, minVol);
        if (status != AudioSystem.AUDIO_STATUS_OK) {
            if (logEvent) {
                sVolumeLogger.enqueue(new EventLogger.StringEvent(
                        "Failed setMinVolumeIndexForGroup with status=" + status)
                        .printSlog(ALOGE, TAG));
            } else {
                Log.e(TAG, "Failed to setMinVolumeIndexForGroup (" + status + ") for group "
                        + groupId);
            }
            return status;
        }
        status = AudioSystem.setMaxVolumeIndexForGroup(groupId, maxVol);
        if (status != AudioSystem.AUDIO_STATUS_OK) {
            if (logEvent) {
                sVolumeLogger.enqueue(new EventLogger.StringEvent(
                        "Failed setMaxVolumeIndexForGroup with status=" + status)
                        .printSlog(ALOGE, TAG));
            } else {
                Log.e(TAG, "Failed to setMaxVolumeIndexForGroup (" + status + ") for group "
                        + groupId);
            }
        }
        return status;
    }
    // NOTE: Locking order for synchronized objects related to volume management:
    //  1     mSettingsLock
    //  2       mVolumeStateLock
@@ -8913,8 +8977,13 @@ public class AudioService extends IAudioService.Stub
                    mIndexMax = MAX_STREAM_VOLUME[mPublicStreamType];
                }
            } else if (!avg.getAudioAttributes().isEmpty()) {
                if (volumeGroupManagementUpdate()) {
                    mIndexMin = AudioSystem.getMinVolumeIndexForGroup(mAudioVolumeGroup.getId());
                    mIndexMax = AudioSystem.getMaxVolumeIndexForGroup(mAudioVolumeGroup.getId());
                } else {
                    mIndexMin = AudioSystem.getMinVolumeIndexForAttributes(mAudioAttributes);
                    mIndexMax = AudioSystem.getMaxVolumeIndexForAttributes(mAudioAttributes);
                }
            } else {
                throw new IllegalArgumentException("volume group: " + mAudioVolumeGroup.name()
                        + " has neither valid attributes nor valid stream types assigned");
@@ -9110,8 +9179,13 @@ public class AudioService extends IAudioService.Stub
            }
            // Set the volume index
            if (volumeGroupManagementUpdate()) {
                mAudioSystem.setVolumeIndexForGroup(mAudioVolumeGroup.getId(), index, muted,
                        device);
            } else {
                mAudioSystem.setVolumeIndexForAttributes(mAudioAttributes, index, muted, device);
            }
        }
        @GuardedBy("AudioService.this.mVolumeStateLock")
        private int getIndex(int device) {
@@ -9531,15 +9605,24 @@ public class AudioService extends IAudioService.Stub
                AudioManager.clearVolumeCache(AudioManager.VOLUME_MIN_CACHING_API);
            }
            final int status = AudioSystem.initStreamVolume(
                    mStreamType, indexMinVolCurve, indexMaxVolCurve);
            int status;
            if (volumeGroupManagementUpdate()) {
                int groupId = getVolumeGroupForStreamType(mStreamType);
                status = initMinMaxForVolumeGroup(groupId, indexMinVolCurve, indexMaxVolCurve,
                        /* logEvent= */ true);
            } else {
                status = AudioSystem.initStreamVolume(mStreamType, indexMinVolCurve,
                        indexMaxVolCurve);
                if (status != AudioSystem.AUDIO_STATUS_OK) {
                    sVolumeLogger.enqueue(new EventLogger.StringEvent(
                            "Failed initStreamVolume with status=" + status).printSlog(ALOGE, TAG));
                }
            }
            sVolumeLogger.enqueue(new EventLogger.StringEvent(
                    "updateIndexFactors() stream:" + mStreamType + " index min/max:"
                            + mIndexMin / 10 + "/" + mIndexMax / 10 + " indexStepFactor:"
                            + mIndexStepFactor).printSlog(ALOGI, TAG));
            if (status != AudioSystem.AUDIO_STATUS_OK) {
                sVolumeLogger.enqueue(new EventLogger.StringEvent(
                        "Failed initStreamVolume with status=" + status).printSlog(ALOGE, TAG));
                sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0,
                        "updateIndexFactors()" /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
            }
+30 −0
Original line number Diff line number Diff line
@@ -558,6 +558,36 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback,
        return AudioSystem.setVolumeIndexForAttributes(attributes, index, muted, device);
    }

    /** Same as {@link AudioSystem#setVolumeIndexForGroup(int, int, boolean, int)} */
    public int setVolumeIndexForGroup(int groupId, int index, boolean muted, int device) {
        return AudioSystem.setVolumeIndexForGroup(groupId, index, muted, device);
    }

    /** Same as {@link AudioSystem#getVolumeIndexForGroup(int, int)} */
    public int getVolumeIndexForGroup(int groupId, int device) {
        return AudioSystem.getVolumeIndexForGroup(groupId, device);
    }

    /** Same as {@link AudioSystem#getMinVolumeIndexForGroup(int)} */
    public int getMinVolumeIndexForGroup(int groupId) {
        return AudioSystem.getMinVolumeIndexForGroup(groupId);
    }

    /** Same as {@link AudioSystem#setMinVolumeIndexForGroup(int, int)} */
    public int setMinVolumeIndexForGroup(int groupId, int index) {
        return AudioSystem.setMinVolumeIndexForGroup(groupId, index);
    }

    /** Same as {@link AudioSystem#getMaxVolumeIndexForGroup(int)} */
    public int getMaxVolumeIndexForGroup(int groupId) {
        return AudioSystem.getMaxVolumeIndexForGroup(groupId);
    }

    /** Same as {@link AudioSystem#setMaxVolumeIndexForGroup(int, int)} */
    public int setMaxVolumeIndexForGroup(int groupId, int index) {
        return AudioSystem.setMaxVolumeIndexForGroup(groupId, index);
    }

    /**
     * Same as {@link AudioSystem#setPhoneState(int, int)}
     * @param state
+30 −0
Original line number Diff line number Diff line
@@ -142,6 +142,36 @@ public class NoOpAudioSystemAdapter extends AudioSystemAdapter {
        return AudioSystem.AUDIO_STATUS_OK;
    }

    @Override
    public int setVolumeIndexForGroup(int groupId, int index, boolean muted, int device) {
        return AudioSystem.AUDIO_STATUS_OK;
    }

    @Override
    public int getVolumeIndexForGroup(int groupId, int device) {
        return AudioSystem.AUDIO_STATUS_OK;
    }

    @Override
    public int getMinVolumeIndexForGroup(int groupId) {
        return AudioSystem.AUDIO_STATUS_OK;
    }

    @Override
    public int setMinVolumeIndexForGroup(int groupId, int index) {
        return AudioSystem.AUDIO_STATUS_OK;
    }

    @Override
    public int getMaxVolumeIndexForGroup(int groupId) {
        return AudioSystem.AUDIO_STATUS_OK;
    }

    @Override
    public int setMaxVolumeIndexForGroup(int groupId, int index) {
        return AudioSystem.AUDIO_STATUS_OK;
    }

    @Override
    @NonNull
    public ArrayList<AudioDeviceAttributes> getDevicesForAttributes(