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

Commit c73004ae authored by Francois Gaffie's avatar Francois Gaffie Committed by Automerger Merge Worker
Browse files

[IMPR] AudioManager: add adjustAttributesVolume API am: c8e375e0

parents 2029455a c8e375e0
Loading
Loading
Loading
Loading
+167 −17
Original line number Diff line number Diff line
@@ -1337,12 +1337,8 @@ public class AudioManager {
    public void setVolumeIndexForAttributes(@NonNull AudioAttributes attr, int index, int flags) {
        Preconditions.checkNotNull(attr, "attr must not be null");
        final IAudioService service = getService();
        try {
            service.setVolumeIndexForAttributes(attr, index, flags,
                    getContext().getOpPackageName(), getContext().getAttributionTag());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
        int groupId = getVolumeGroupIdForAttributes(attr);
        setVolumeGroupVolumeIndex(groupId, index, flags);
    }

    /**
@@ -1361,11 +1357,8 @@ public class AudioManager {
    public int getVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
        Preconditions.checkNotNull(attr, "attr must not be null");
        final IAudioService service = getService();
        try {
            return service.getVolumeIndexForAttributes(attr);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
        int groupId = getVolumeGroupIdForAttributes(attr);
        return getVolumeGroupVolumeIndex(groupId);
    }

    /**
@@ -1382,11 +1375,8 @@ public class AudioManager {
    public int getMaxVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
        Preconditions.checkNotNull(attr, "attr must not be null");
        final IAudioService service = getService();
        try {
            return service.getMaxVolumeIndexForAttributes(attr);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
        int groupId = getVolumeGroupIdForAttributes(attr);
        return getVolumeGroupMaxVolumeIndex(groupId);
    }

    /**
@@ -1403,8 +1393,168 @@ public class AudioManager {
    public int getMinVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
        Preconditions.checkNotNull(attr, "attr must not be null");
        final IAudioService service = getService();
        int groupId = getVolumeGroupIdForAttributes(attr);
        return getVolumeGroupMinVolumeIndex(groupId);
    }

    /**
     * Returns the volume group id associated to the given {@link AudioAttributes}.
     *
     * @param attributes The {@link AudioAttributes} to consider.
     * @return {@link android.media.audiopolicy.AudioVolumeGroup} id supporting the given
     * {@link AudioAttributes} if found,
     * {@code android.media.audiopolicy.AudioVolumeGroup.DEFAULT_VOLUME_GROUP} otherwise.
     * @hide
     */
    public int getVolumeGroupIdForAttributes(@NonNull AudioAttributes attributes) {
        Preconditions.checkNotNull(attributes, "Audio Attributes must not be null");
        return AudioProductStrategy.getVolumeGroupIdForAudioAttributes(attributes,
                /* fallbackOnDefault= */ false);
    }

    /**
     * Sets the volume index for a particular group associated to given id.
     * <p> Call first in prior {@link getVolumeGroupIdForAttributes} to retrieve the volume group
     * id supporting the given {@link AudioAttributes}.
     *
     * @param groupId of the {@link android.media.audiopolicy.AudioVolumeGroup} to consider.
     * @param index The volume index to set. See
     *          {@link #getVolumeGroupMaxVolumeIndex(id)} for the largest valid value
     *          {@link #getVolumeGroupMinVolumeIndex(id)} for the lowest valid value.
     * @param flags One or more flags.
     * @hide
     */
    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
    public void setVolumeGroupVolumeIndex(int groupId, int index, int flags) {
        final IAudioService service = getService();
        try {
            service.setVolumeGroupVolumeIndex(groupId, index, flags,
                    getContext().getOpPackageName(), getContext().getAttributionTag());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Returns the current volume index for a particular group associated to given id.
     * <p> Call first in prior {@link getVolumeGroupIdForAttributes} to retrieve the volume group
     * id supporting the given {@link AudioAttributes}.
     *
     * @param groupId of the {@link android.media.audiopolicy.AudioVolumeGroup} to consider.
     * @return The current volume index for the stream.
     * @hide
     */
    @IntRange(from = 0)
    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
    public int getVolumeGroupVolumeIndex(int groupId) {
        final IAudioService service = getService();
        try {
            return service.getVolumeGroupVolumeIndex(groupId);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Returns the maximum volume index for a particular group associated to given id.
     * <p> Call first in prior {@link getVolumeGroupIdForAttributes} to retrieve the volume group
     * id supporting the given {@link AudioAttributes}.
     *
     * @param groupId of the {@link android.media.audiopolicy.AudioVolumeGroup} to consider.
     * @return The maximum valid volume index for the {@link AudioAttributes}.
     * @hide
     */
    @IntRange(from = 0)
    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
    public int getVolumeGroupMaxVolumeIndex(int groupId) {
        final IAudioService service = getService();
        try {
            return service.getVolumeGroupMaxVolumeIndex(groupId);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Returns the minimum volume index for a particular group associated to given id.
     * <p> Call first in prior {@link getVolumeGroupIdForAttributes} to retrieve the volume group
     * id supporting the given {@link AudioAttributes}.
     *
     * @param groupId of the {@link android.media.audiopolicy.AudioVolumeGroup} to consider.
     * @return The minimum valid volume index for the {@link AudioAttributes}.
     * @hide
     */
    @IntRange(from = 0)
    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
    public int getVolumeGroupMinVolumeIndex(int groupId) {
        final IAudioService service = getService();
        try {
            return service.getVolumeGroupMinVolumeIndex(groupId);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Adjusts the volume of a particular group associated to given id by one step in a direction.
     * <p> If the volume group is associated to a stream type, it fallbacks on
     * {@link AudioManager#adjustStreamVolume()} for compatibility reason.
     * <p> Call first in prior {@link getVolumeGroupIdForAttributes} to retrieve the volume group
     * id supporting the given {@link AudioAttributes}.
     *
     * @param groupId of the {@link android.media.audiopolicy.AudioVolumeGroup} to consider.
     * @param direction The direction to adjust the volume. One of
     *            {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, or
     *            {@link #ADJUST_SAME}.
     * @param flags One or more flags.
     * @throws SecurityException if the adjustment triggers a Do Not Disturb change and the caller
     * is not granted notification policy access.
     * @hide
     */
    public void adjustVolumeGroupVolume(int groupId, int direction, int flags) {
        IAudioService service = getService();
        try {
            service.adjustVolumeGroupVolume(groupId, direction, flags,
                    getContext().getOpPackageName());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Get last audible volume of the group associated to given id before it was muted.
     * <p> Call first in prior {@link getVolumeGroupIdForAttributes} to retrieve the volume group
     * id supporting the given {@link AudioAttributes}.
     *
     * @param groupId of the {@link android.media.audiopolicy.AudioVolumeGroup} to consider.
     * @return current volume if not muted, volume before muted otherwise.
     * @hide
     */
    @RequiresPermission("android.permission.QUERY_AUDIO_STATE")
    @IntRange(from = 0)
    public int getLastAudibleVolumeGroupVolume(int groupId) {
        IAudioService service = getService();
        try {
            return service.getLastAudibleVolumeGroupVolume(groupId);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Returns the current mute state for a particular volume group associated to the given id.
     * <p> Call first in prior {@link getVolumeGroupIdForAttributes} to retrieve the volume group
     * id supporting the given {@link AudioAttributes}.
     *
     * @param groupId of the {@link android.media.audiopolicy.AudioVolumeGroup} to consider.
     * @return The mute state for the given {@link android.media.audiopolicy.AudioVolumeGroup} id.
     * @see #adjustAttributesVolume(AudioAttributes, int, int)
     * @hide
     */
    public boolean isVolumeGroupMuted(int groupId) {
        IAudioService service = getService();
        try {
            return service.getMinVolumeIndexForAttributes(attr);
            return service.isVolumeGroupMuted(groupId);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
+11 −5
Original line number Diff line number Diff line
@@ -127,14 +127,20 @@ interface IAudioService {

    List<AudioVolumeGroup> getAudioVolumeGroups();

    void setVolumeIndexForAttributes(in AudioAttributes aa, int index, int flags,
            String callingPackage, in String attributionTag);
    void setVolumeGroupVolumeIndex(int groupId, int index, int flags, String callingPackage,
            in String attributionTag);

    int getVolumeGroupVolumeIndex(int groupId);

    int getVolumeGroupMaxVolumeIndex(int groupId);

    int getVolumeGroupMinVolumeIndex(int groupId);

    int getVolumeIndexForAttributes(in AudioAttributes aa);
    int getLastAudibleVolumeGroupVolume(int groupId);

    int getMaxVolumeIndexForAttributes(in AudioAttributes aa);
    boolean isVolumeGroupMuted(int groupId);

    int getMinVolumeIndexForAttributes(in AudioAttributes aa);
    void adjustVolumeGroupVolume(int groupId, int direction, int flags, String callingPackage);

    int getLastAudibleStreamVolume(int streamType);

+111 −26
Original line number Diff line number Diff line
@@ -3667,20 +3667,17 @@ public class AudioService extends IAudioService.Stub
    }
    /** @see AudioManager#setVolumeIndexForAttributes(attr, int, int) */
    public void setVolumeIndexForAttributes(@NonNull AudioAttributes attr, int index, int flags,
    /** @see AudioManager#setVolumeGroupVolumeIndex(int, int, int) */
    public void setVolumeGroupVolumeIndex(int groupId, int index, int flags,
            String callingPackage, String attributionTag) {
        enforceModifyAudioRoutingPermission();
        Objects.requireNonNull(attr, "attr must not be null");
        int volumeGroup = AudioProductStrategy.getVolumeGroupIdForAudioAttributes(
                attr, /* fallbackOnDefault= */false);
        if (sVolumeGroupStates.indexOfKey(volumeGroup) < 0) {
            Log.e(TAG, ": no volume group found for attributes " + attr.toString());
        if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
            Log.e(TAG, ": no volume group found for id " + groupId);
            return;
        }
        VolumeGroupState vgs = sVolumeGroupStates.get(volumeGroup);
        VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
        sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_SET_GROUP_VOL, attr, vgs.name(),
        sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_SET_GROUP_VOL, vgs.name(),
                index, flags, callingPackage + ", user " + getCurrentUserId()));
        vgs.setVolumeIndex(index, flags);
@@ -3690,7 +3687,7 @@ public class AudioService extends IAudioService.Stub
            try {
                ensureValidStreamType(groupedStream);
            } catch (IllegalArgumentException e) {
                Log.d(TAG, "volume group " + volumeGroup + " has internal streams (" + groupedStream
                Log.d(TAG, "volume group " + groupId + " has internal streams (" + groupedStream
                        + "), do not change associated stream volume");
                continue;
            }
@@ -3712,33 +3709,40 @@ public class AudioService extends IAudioService.Stub
        return null;
    }
    /** @see AudioManager#getVolumeIndexForAttributes(attr) */
    public int getVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
    /** @see AudioManager#getVolumeGroupVolumeIndex(int) */
    public int getVolumeGroupVolumeIndex(int groupId) {
        enforceModifyAudioRoutingPermission();
        Objects.requireNonNull(attr, "attr must not be null");
        synchronized (VolumeStreamState.class) {
            int volumeGroup = AudioProductStrategy.getVolumeGroupIdForAudioAttributes(
                    attr, /* fallbackOnDefault= */false);
            if (sVolumeGroupStates.indexOfKey(volumeGroup) < 0) {
                throw new IllegalArgumentException("No volume group for attributes " + attr);
            if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
                throw new IllegalArgumentException("No volume group for id " + groupId);
            }
            VolumeGroupState vgs = sVolumeGroupStates.get(volumeGroup);
            VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
            return vgs.isMuted() ? vgs.getMinIndex() : vgs.getVolumeIndex();
        }
    }
    /** @see AudioManager#getMaxVolumeIndexForAttributes(attr) */
    public int getMaxVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
    /** @see AudioManager#getVolumeGroupMaxVolumeIndex(int) */
    public int getVolumeGroupMaxVolumeIndex(int groupId) {
        enforceModifyAudioRoutingPermission();
        Objects.requireNonNull(attr, "attr must not be null");
        return AudioSystem.getMaxVolumeIndexForAttributes(attr);
        synchronized (VolumeStreamState.class) {
            if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
                throw new IllegalArgumentException("No volume group for id " + groupId);
            }
            VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
            return vgs.getMaxIndex();
        }
    }
    /** @see AudioManager#getMinVolumeIndexForAttributes(attr) */
    public int getMinVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
    /** @see AudioManager#getVolumeGroupMinVolumeIndex(int) */
    public int getVolumeGroupMinVolumeIndex(int groupId) {
        enforceModifyAudioRoutingPermission();
        Objects.requireNonNull(attr, "attr must not be null");
        return AudioSystem.getMinVolumeIndexForAttributes(attr);
        synchronized (VolumeStreamState.class) {
            if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
                throw new IllegalArgumentException("No volume group for id " + groupId);
            }
            VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
            return vgs.getMinIndex();
        }
    }
    /** @see AudioDeviceVolumeManager#setDeviceVolume(VolumeInfo, AudioDeviceAttributes)
@@ -3815,6 +3819,45 @@ public class AudioService extends IAudioService.Stub
                callingPackage, /*attributionTag*/ null);
    }
    /** @see AudioManager#adjustVolumeGroupVolume(int, int, int) */
    public void adjustVolumeGroupVolume(int groupId, int direction, int flags,
                                        String callingPackage) {
        ensureValidDirection(direction);
        if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
            Log.e(TAG, ": no volume group found for id " + groupId);
            return;
        }
        VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
        sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_GROUP_VOL, vgs.name(),
                direction, flags, callingPackage));
        vgs.adjustVolume(direction, flags);
    }
    /** @see AudioManager#getLastAudibleVolumeGroupVolume(int) */
    public int getLastAudibleVolumeGroupVolume(int groupId) {
        enforceQueryStatePermission();
        synchronized (VolumeStreamState.class) {
            if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
                Log.e(TAG, ": no volume group found for id " + groupId);
                return 0;
            }
            VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
            return vgs.getVolumeIndex();
        }
    }
    /** @see AudioManager#isVolumeGroupMuted(int) */
    public boolean isVolumeGroupMuted(int groupId) {
        synchronized (VolumeStreamState.class) {
            if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
                Log.e(TAG, ": no volume group found for id " + groupId);
                return false;
            }
            VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
            return vgs.isMuted();
        }
    }
    /** @see AudioManager#setStreamVolume(int, int, int)
     * Part of service interface, check permissions here */
    public void setStreamVolumeWithAttribution(int streamType, int index, int flags,
@@ -7448,6 +7491,48 @@ public class AudioService extends IAudioService.Stub
            return mIsMuted;
        }
        public void adjustVolume(int direction, int flags) {
            synchronized (VolumeStreamState.class) {
                int device = getDeviceForVolume();
                int previousIndex = getIndex(device);
                switch (direction) {
                    case AudioManager.ADJUST_TOGGLE_MUTE: {
                        // Note: If muted by volume 0, unmute will restore volume 0.
                        mute(!mIsMuted);
                        break;
                    }
                    case AudioManager.ADJUST_UNMUTE:
                        // Note: If muted by volume 0, unmute will restore volume 0.
                        mute(false);
                        break;
                    case AudioManager.ADJUST_MUTE:
                        // May be already muted by setvolume 0, prevent from setting same value
                        if (previousIndex != 0) {
                            // bypass persist
                            mute(true);
                        }
                        mIsMuted = true;
                        break;
                    case AudioManager.ADJUST_RAISE:
                        // As for stream, RAISE during mute will increment the index
                        setVolumeIndex(Math.min(previousIndex + 1, mIndexMax),  device, flags);
                        break;
                    case AudioManager.ADJUST_LOWER:
                        // For stream, ADJUST_LOWER on a muted VSS is a no-op
                        // If we decide to unmute on ADJUST_LOWER, cannot fallback on
                        // adjustStreamVolume for group associated to legacy stream type
                        if (isMuted() && previousIndex != 0) {
                            mute(false);
                        } else {
                            int newIndex = Math.max(previousIndex - 1, mIndexMin);
                            setVolumeIndex(newIndex, device, flags);
                        }
                        break;
                }
            }
        }
        public int getVolumeIndex() {
            synchronized (VolumeStreamState.class) {
                return getIndex(getDeviceForVolume());
+21 −14
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package com.android.server.audio;

import android.annotation.NonNull;
import android.media.AudioAttributes;
import android.media.AudioDeviceAttributes;
import android.media.AudioManager;
import android.media.AudioSystem;
@@ -221,6 +220,7 @@ public class AudioServiceEvents {
        static final int VOL_SET_GROUP_VOL = 8;
        static final int VOL_MUTE_STREAM_INT = 9;
        static final int VOL_SET_LE_AUDIO_VOL = 10;
        static final int VOL_ADJUST_GROUP_VOL = 11;

        final int mOp;
        final int mStream;
@@ -228,7 +228,6 @@ public class AudioServiceEvents {
        final int mVal2;
        final String mCaller;
        final String mGroupName;
        final AudioAttributes mAudioAttributes;

        /** used for VOL_ADJUST_VOL_UID,
         *           VOL_ADJUST_SUGG_VOL,
@@ -241,7 +240,6 @@ public class AudioServiceEvents {
            mVal2 = val2;
            mCaller = caller;
            mGroupName = null;
            mAudioAttributes = null;
            logMetricEvent();
        }

@@ -254,7 +252,6 @@ public class AudioServiceEvents {
            mStream = -1;
            mCaller = null;
            mGroupName = null;
            mAudioAttributes = null;
            logMetricEvent();
        }

@@ -267,7 +264,6 @@ public class AudioServiceEvents {
            mStream = -1;
            mCaller = null;
            mGroupName = null;
            mAudioAttributes = null;
            logMetricEvent();
        }

@@ -280,7 +276,6 @@ public class AudioServiceEvents {
            // unused
            mCaller = null;
            mGroupName = null;
            mAudioAttributes = null;
            logMetricEvent();
        }

@@ -293,19 +288,18 @@ public class AudioServiceEvents {
            // unused
            mCaller = null;
            mGroupName = null;
            mAudioAttributes = null;
            logMetricEvent();
        }

        /** used for VOL_SET_GROUP_VOL */
        VolumeEvent(int op, AudioAttributes aa, String group, int index, int flags, String caller) {
        /** used for VOL_SET_GROUP_VOL,
         *           VOL_ADJUST_GROUP_VOL */
        VolumeEvent(int op, String group, int index, int flags, String caller) {
            mOp = op;
            mStream = -1;
            mVal1 = index;
            mVal2 = flags;
            mCaller = caller;
            mGroupName = group;
            mAudioAttributes = aa;
            logMetricEvent();
        }

@@ -317,7 +311,6 @@ public class AudioServiceEvents {
            mVal2 = 0;
            mCaller = null;
            mGroupName = null;
            mAudioAttributes = null;
            logMetricEvent();
        }

@@ -359,6 +352,15 @@ public class AudioServiceEvents {
                            .record();
                    return;
                }
                case VOL_ADJUST_GROUP_VOL:
                    new MediaMetrics.Item(mMetricsId)
                            .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller)
                            .set(MediaMetrics.Property.DIRECTION, mVal1 > 0 ? "up" : "down")
                            .set(MediaMetrics.Property.EVENT, "adjustVolumeGroupVolume")
                            .set(MediaMetrics.Property.FLAGS, mVal2)
                            .set(MediaMetrics.Property.GROUP, mGroupName)
                            .record();
                    return;
                case VOL_SET_STREAM_VOL:
                    new MediaMetrics.Item(mMetricsId)
                            .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller)
@@ -410,7 +412,6 @@ public class AudioServiceEvents {
                    return;
                case VOL_SET_GROUP_VOL:
                    new MediaMetrics.Item(mMetricsId)
                            .set(MediaMetrics.Property.ATTRIBUTES, mAudioAttributes.toString())
                            .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller)
                            .set(MediaMetrics.Property.EVENT, "setVolumeIndexForAttributes")
                            .set(MediaMetrics.Property.FLAGS, mVal2)
@@ -436,6 +437,13 @@ public class AudioServiceEvents {
                            .append(" flags:0x").append(Integer.toHexString(mVal2))
                            .append(") from ").append(mCaller)
                            .toString();
                case VOL_ADJUST_GROUP_VOL:
                    return new StringBuilder("adjustVolumeGroupVolume(group:")
                            .append(mGroupName)
                            .append(" dir:").append(AudioManager.adjustToString(mVal1))
                            .append(" flags:0x").append(Integer.toHexString(mVal2))
                            .append(") from ").append(mCaller)
                            .toString();
                case VOL_ADJUST_STREAM_VOL:
                    return new StringBuilder("adjustStreamVolume(stream:")
                            .append(AudioSystem.streamToString(mStream))
@@ -484,8 +492,7 @@ public class AudioServiceEvents {
                            .append(" stream:").append(AudioSystem.streamToString(mStream))
                            .toString();
                case VOL_SET_GROUP_VOL:
                    return new StringBuilder("setVolumeIndexForAttributes(attr:")
                            .append(mAudioAttributes.toString())
                    return new StringBuilder("setVolumeIndexForAttributes(group:")
                            .append(" group: ").append(mGroupName)
                            .append(" index:").append(mVal1)
                            .append(" flags:0x").append(Integer.toHexString(mVal2))