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

Commit 1007b656 authored by Yan Han's avatar Yan Han Committed by Automerger Merge Worker
Browse files

Merge "AudioService: Add general support for Absolute Volume behavior" into tm-dev am: f4cdc8b1

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17034563

Change-Id: I9cbc4ac76d5695de133675f0da05f8745a3a0148
parents 9de4ef41 f4cdc8b1
Loading
Loading
Loading
Loading
+77 −10
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.media;

import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -27,6 +28,8 @@ import android.os.ServiceManager;

import com.android.internal.annotations.GuardedBy;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@@ -40,6 +43,22 @@ public class AudioDeviceVolumeManager {

    // define when using Log.*
    //private static final String TAG = "AudioDeviceVolumeManager";

    /** Indicates no special treatment in the handling of the volume adjustment */
    public static final int ADJUST_MODE_NORMAL = 0;
    /** Indicates the start of a volume adjustment */
    public static final int ADJUST_MODE_START = 1;
    /** Indicates the end of a volume adjustment */
    public static final int ADJUST_MODE_END = 2;

    @IntDef(flag = false, prefix = "ADJUST_MODE", value = {
            ADJUST_MODE_NORMAL,
            ADJUST_MODE_START,
            ADJUST_MODE_END}
    )
    @Retention(RetentionPolicy.SOURCE)
    public @interface VolumeAdjustmentMode {}

    private static IAudioService sService;

    private final String mPackageName;
@@ -65,18 +84,33 @@ public class AudioDeviceVolumeManager {
        void onAudioDeviceVolumeChanged(
                @NonNull AudioDeviceAttributes device,
                @NonNull VolumeInfo vol);

        /**
         * Called when the volume for the given audio device has been adjusted.
         * @param device the audio device whose volume has been adjusted
         * @param vol the volume info for the device
         * @param direction the direction of the adjustment
         * @param mode the volume adjustment mode
         */
        void onAudioDeviceVolumeAdjusted(
                @NonNull AudioDeviceAttributes device,
                @NonNull VolumeInfo vol,
                @AudioManager.VolumeAdjustment int direction,
                @VolumeAdjustmentMode int mode);
    }

    static class ListenerInfo {
        final @NonNull OnAudioDeviceVolumeChangedListener mListener;
        final @NonNull Executor mExecutor;
        final @NonNull AudioDeviceAttributes mDevice;
        final @NonNull boolean mHandlesVolumeAdjustment;

        ListenerInfo(@NonNull OnAudioDeviceVolumeChangedListener listener, @NonNull Executor exe,
                @NonNull AudioDeviceAttributes device) {
                @NonNull AudioDeviceAttributes device, boolean handlesVolumeAdjustment) {
            mListener = listener;
            mExecutor = exe;
            mDevice = device;
            mHandlesVolumeAdjustment = handlesVolumeAdjustment;
        }
    }

@@ -98,11 +132,12 @@ public class AudioDeviceVolumeManager {
         * @param device device for which volume is monitored
         */
        public void register(boolean register, @NonNull AudioDeviceAttributes device,
                @NonNull List<VolumeInfo> volumes) {
                @NonNull List<VolumeInfo> volumes, boolean handlesVolumeAdjustment) {
            try {
                getService().registerDeviceVolumeDispatcherForAbsoluteVolume(register,
                        this, mPackageName,
                        Objects.requireNonNull(device), Objects.requireNonNull(volumes));
                        Objects.requireNonNull(device), Objects.requireNonNull(volumes),
                        handlesVolumeAdjustment);
            } catch (RemoteException e) {
                e.rethrowFromSystemServer();
            }
@@ -116,12 +151,29 @@ public class AudioDeviceVolumeManager {
                volumeListeners = (ArrayList<ListenerInfo>) mDeviceVolumeListeners.clone();
            }
            for (ListenerInfo listenerInfo : volumeListeners) {
                if (listenerInfo.mDevice.equals(device)) {
                if (listenerInfo.mDevice.equalTypeAddress(device)) {
                    listenerInfo.mExecutor.execute(
                            () -> listenerInfo.mListener.onAudioDeviceVolumeChanged(device, vol));
                }
            }
        }

        @Override
        public void dispatchDeviceVolumeAdjusted(
                @NonNull AudioDeviceAttributes device, @NonNull VolumeInfo vol, int direction,
                int mode) {
            final ArrayList<ListenerInfo> volumeListeners;
            synchronized (mDeviceVolumeListenerLock) {
                volumeListeners = (ArrayList<ListenerInfo>) mDeviceVolumeListeners.clone();
            }
            for (ListenerInfo listenerInfo : volumeListeners) {
                if (listenerInfo.mDevice.equalTypeAddress(device)) {
                    listenerInfo.mExecutor.execute(
                            () -> listenerInfo.mListener.onAudioDeviceVolumeAdjusted(device, vol,
                                    direction, mode));
                }
            }
        }
    }

    /**
@@ -139,10 +191,12 @@ public class AudioDeviceVolumeManager {
            @NonNull AudioDeviceAttributes device,
            @NonNull VolumeInfo volume,
            @NonNull @CallbackExecutor Executor executor,
            @NonNull OnAudioDeviceVolumeChangedListener vclistener) {
            @NonNull OnAudioDeviceVolumeChangedListener vclistener,
            boolean handlesVolumeAdjustment) {
        final ArrayList<VolumeInfo> volumes = new ArrayList<>(1);
        volumes.add(volume);
        setDeviceAbsoluteMultiVolumeBehavior(device, volumes, executor, vclistener);
        setDeviceAbsoluteMultiVolumeBehavior(device, volumes, executor, vclistener,
                handlesVolumeAdjustment);
    }

    /**
@@ -153,6 +207,9 @@ public class AudioDeviceVolumeManager {
     * @param volumes the list of volumes the given device responds to
     * @param executor the Executor used for receiving volume updates through the listener
     * @param vclistener the callback for volume updates
     * @param handlesVolumeAdjustment whether the controller handles volume adjustments separately
     *  from volume changes. If true, adjustments from {@link AudioManager#adjustStreamVolume}
     *  will be sent via {@link OnAudioDeviceVolumeChangedListener#onAudioDeviceVolumeAdjusted}.
     */
    @RequiresPermission(anyOf = { android.Manifest.permission.MODIFY_AUDIO_ROUTING,
            android.Manifest.permission.BLUETOOTH_PRIVILEGED })
@@ -160,14 +217,15 @@ public class AudioDeviceVolumeManager {
            @NonNull AudioDeviceAttributes device,
            @NonNull List<VolumeInfo> volumes,
            @NonNull @CallbackExecutor Executor executor,
            @NonNull OnAudioDeviceVolumeChangedListener vclistener) {
            @NonNull OnAudioDeviceVolumeChangedListener vclistener,
            boolean handlesVolumeAdjustment) {
        Objects.requireNonNull(device);
        Objects.requireNonNull(volumes);
        Objects.requireNonNull(executor);
        Objects.requireNonNull(vclistener);

        // TODO verify not already registered
        //final ListenerInfo listenerInfo = new ListenerInfo(vclistener, executor, device);
        final ListenerInfo listenerInfo = new ListenerInfo(
                vclistener, executor, device, handlesVolumeAdjustment);
        synchronized (mDeviceVolumeListenerLock) {
            if (mDeviceVolumeListeners == null) {
                mDeviceVolumeListeners = new ArrayList<>();
@@ -176,8 +234,17 @@ public class AudioDeviceVolumeManager {
                if (mDeviceVolumeDispatcherStub == null) {
                    mDeviceVolumeDispatcherStub = new DeviceVolumeDispatcherStub();
                }
            } else {
                for (ListenerInfo info : mDeviceVolumeListeners) {
                    if (info.mListener == vclistener) {
                        throw new IllegalArgumentException(
                                "attempt to call setDeviceAbsoluteMultiVolumeBehavior() "
                                        + "on a previously registered listener");
                    }
                }
            }
            mDeviceVolumeDispatcherStub.register(true, device, volumes);
            mDeviceVolumeListeners.add(listenerInfo);
            mDeviceVolumeDispatcherStub.register(true, device, volumes, handlesVolumeAdjustment);
        }
    }

+9 −0
Original line number Diff line number Diff line
@@ -604,6 +604,13 @@ public class AudioManager {
    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
    public static final int FLAG_FROM_KEY = 1 << 12;

    /**
     * Indicates that an absolute volume controller is notifying AudioService of a change in the
     * volume or mute status of an external audio system.
     * @hide
     */
    public static final int FLAG_ABSOLUTE_VOLUME = 1 << 13;

    /** @hide */
    @IntDef(prefix = {"ENCODED_SURROUND_OUTPUT_"}, value = {
            ENCODED_SURROUND_OUTPUT_UNKNOWN,
@@ -661,6 +668,7 @@ public class AudioManager {
            FLAG_SHOW_UI_WARNINGS,
            FLAG_SHOW_VIBRATE_HINT,
            FLAG_FROM_KEY,
            FLAG_ABSOLUTE_VOLUME,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface Flags {}
@@ -682,6 +690,7 @@ public class AudioManager {
        FLAG_NAMES.put(FLAG_SHOW_UI_WARNINGS, "FLAG_SHOW_UI_WARNINGS");
        FLAG_NAMES.put(FLAG_SHOW_VIBRATE_HINT, "FLAG_SHOW_VIBRATE_HINT");
        FLAG_NAMES.put(FLAG_FROM_KEY, "FLAG_FROM_KEY");
        FLAG_NAMES.put(FLAG_ABSOLUTE_VOLUME, "FLAG_ABSOLUTE_VOLUME");
    }

    /** @hide */
+2 −0
Original line number Diff line number Diff line
@@ -27,5 +27,7 @@ import android.media.VolumeInfo;
oneway interface IAudioDeviceVolumeDispatcher {

    void dispatchDeviceVolumeChanged(in AudioDeviceAttributes device, in VolumeInfo vol);
    void dispatchDeviceVolumeAdjusted(in AudioDeviceAttributes device, in VolumeInfo vol,
            int direction, int mode);

}
+2 −1
Original line number Diff line number Diff line
@@ -509,7 +509,8 @@ interface IAudioService {
    void registerDeviceVolumeDispatcherForAbsoluteVolume(boolean register,
            in IAudioDeviceVolumeDispatcher cb,
            in String packageName,
            in AudioDeviceAttributes device, in List<VolumeInfo> volumes);
            in AudioDeviceAttributes device, in List<VolumeInfo> volumes,
            boolean handlesvolumeAdjustment);

    String getHalVersion();
}
+251 −50

File changed.

Preview size limit exceeded, changes collapsed.

Loading