Loading media/java/android/media/AudioDeviceVolumeManager.java +77 −10 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; } } Loading @@ -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(); } Loading @@ -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)); } } } } /** Loading @@ -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); } /** Loading @@ -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 }) Loading @@ -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<>(); Loading @@ -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); } } Loading media/java/android/media/AudioManager.java +9 −0 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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 {} Loading @@ -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 */ Loading media/java/android/media/IAudioDeviceVolumeDispatcher.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -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); } media/java/android/media/IAudioService.aidl +2 −1 Original line number Diff line number Diff line Loading @@ -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(); } services/core/java/com/android/server/audio/AudioService.java +251 −50 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
media/java/android/media/AudioDeviceVolumeManager.java +77 −10 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; } } Loading @@ -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(); } Loading @@ -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)); } } } } /** Loading @@ -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); } /** Loading @@ -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 }) Loading @@ -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<>(); Loading @@ -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); } } Loading
media/java/android/media/AudioManager.java +9 −0 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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 {} Loading @@ -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 */ Loading
media/java/android/media/IAudioDeviceVolumeDispatcher.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -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); }
media/java/android/media/IAudioService.aidl +2 −1 Original line number Diff line number Diff line Loading @@ -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(); }
services/core/java/com/android/server/audio/AudioService.java +251 −50 File changed.Preview size limit exceeded, changes collapsed. Show changes