Loading media/java/android/media/AudioDeviceVolumeManager.java +74 −0 Original line number Diff line number Diff line Loading @@ -181,6 +181,80 @@ public class AudioDeviceVolumeManager { } } /** * Manages the OnDeviceVolumeBehaviorChangedListener listeners and * DeviceVolumeBehaviorDispatcherStub */ private final CallbackUtil.LazyListenerManager<OnDeviceVolumeBehaviorChangedListener> mDeviceVolumeBehaviorChangedListenerMgr = new CallbackUtil.LazyListenerManager(); /** * @hide * Interface definition of a callback to be invoked when the volume behavior of an audio device * is updated. */ public interface OnDeviceVolumeBehaviorChangedListener { /** * Called on the listener to indicate that the volume behavior of a device has changed. * @param device the audio device whose volume behavior changed * @param volumeBehavior the new volume behavior of the audio device */ void onDeviceVolumeBehaviorChanged( @NonNull AudioDeviceAttributes device, @AudioManager.DeviceVolumeBehavior int volumeBehavior); } /** * @hide * Adds a listener for being notified of changes to any device's volume behavior. * @throws SecurityException if the caller doesn't hold the required permission */ @RequiresPermission(anyOf = { android.Manifest.permission.MODIFY_AUDIO_ROUTING, android.Manifest.permission.QUERY_AUDIO_STATE }) public void addOnDeviceVolumeBehaviorChangedListener( @NonNull @CallbackExecutor Executor executor, @NonNull OnDeviceVolumeBehaviorChangedListener listener) throws SecurityException { mDeviceVolumeBehaviorChangedListenerMgr.addListener(executor, listener, "addOnDeviceVolumeBehaviorChangedListener", () -> new DeviceVolumeBehaviorDispatcherStub()); } /** * @hide * Removes a previously added listener of changes to device volume behavior. */ @RequiresPermission(anyOf = { android.Manifest.permission.MODIFY_AUDIO_ROUTING, android.Manifest.permission.QUERY_AUDIO_STATE }) public void removeOnDeviceVolumeBehaviorChangedListener( @NonNull OnDeviceVolumeBehaviorChangedListener listener) { mDeviceVolumeBehaviorChangedListenerMgr.removeListener(listener, "removeOnDeviceVolumeBehaviorChangedListener"); } private final class DeviceVolumeBehaviorDispatcherStub extends IDeviceVolumeBehaviorDispatcher.Stub implements CallbackUtil.DispatcherStub { public void register(boolean register) { try { getService().registerDeviceVolumeBehaviorDispatcher(register, this); } catch (RemoteException e) { e.rethrowFromSystemServer(); } } @Override public void dispatchDeviceVolumeBehaviorChanged(@NonNull AudioDeviceAttributes device, @AudioManager.DeviceVolumeBehavior int volumeBehavior) { mDeviceVolumeBehaviorChangedListenerMgr.callListeners((listener) -> listener.onDeviceVolumeBehaviorChanged(device, volumeBehavior)); } } private static IAudioService getService() { if (sService != null) { return sService; Loading media/java/android/media/IAudioService.aidl +5 −1 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import android.media.IAudioRoutesObserver; import android.media.IAudioServerStateDispatcher; import android.media.ICapturePresetDevicesRoleDispatcher; import android.media.ICommunicationDeviceDispatcher; import android.media.IDeviceVolumeBehaviorDispatcher; import android.media.IMuteAwaitConnectionCallback; import android.media.IPlaybackConfigDispatcher; import android.media.IRecordingConfigDispatcher; Loading @@ -44,7 +45,6 @@ import android.media.ISpatializerHeadTrackingModeCallback; import android.media.ISpatializerHeadToSoundStagePoseCallback; import android.media.ISpatializerOutputCallback; import android.media.IVolumeController; import android.media.IVolumeController; import android.media.PlayerBase; import android.media.VolumeInfo; import android.media.VolumePolicy; Loading Loading @@ -482,6 +482,10 @@ interface IAudioService { void setTestDeviceConnectionState(in AudioDeviceAttributes device, boolean connected); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING,android.Manifest.permission.QUERY_AUDIO_STATE})") void registerDeviceVolumeBehaviorDispatcher(boolean register, in IDeviceVolumeBehaviorDispatcher dispatcher); List<AudioFocusInfo> getFocusStack(); boolean sendFocusLoss(in AudioFocusInfo focusLoser, in IAudioPolicyCallback apcb); Loading media/java/android/media/IDeviceVolumeBehaviorDispatcher.aidl 0 → 100644 +31 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.media; import android.media.AudioDeviceAttributes; /** * AIDL for AudioService to signal changes to an audio device's volume behavior * * {@hide} */ oneway interface IDeviceVolumeBehaviorDispatcher { void dispatchDeviceVolumeBehaviorChanged(in AudioDeviceAttributes device, int deviceVolumeBehavior); } services/core/java/com/android/server/audio/AudioService.java +98 −28 Original line number Diff line number Diff line Loading @@ -96,6 +96,7 @@ import android.media.IAudioServerStateDispatcher; import android.media.IAudioService; import android.media.ICapturePresetDevicesRoleDispatcher; import android.media.ICommunicationDeviceDispatcher; import android.media.IDeviceVolumeBehaviorDispatcher; import android.media.IMuteAwaitConnectionCallback; import android.media.IPlaybackConfigDispatcher; import android.media.IRecordingConfigDispatcher; Loading Loading @@ -341,6 +342,7 @@ public class AudioService extends IAudioService.Stub private static final int MSG_ADD_ASSISTANT_SERVICE_UID = 44; private static final int MSG_REMOVE_ASSISTANT_SERVICE_UID = 45; private static final int MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID = 46; private static final int MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR = 47; // start of messages handled under wakelock // these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(), Loading Loading @@ -876,13 +878,23 @@ public class AudioService extends IAudioService.Stub /** @hide */ public AudioService(Context context) { this(context, AudioSystemAdapter.getDefaultAdapter(), this(context, AudioSystemAdapter.getDefaultAdapter(), SystemServerAdapter.getDefaultAdapter(context), SettingsAdapter.getDefaultAdapter()); SettingsAdapter.getDefaultAdapter(), null); } /** * @param context * @param audioSystem Adapter for {@link AudioSystem} * @param systemServer Adapter for privilieged functionality for system server components * @param settings Adapter for {@link Settings} * @param looper Looper to use for the service's message handler. If this is null, an * {@link AudioSystemThread} is created as the messaging thread instead. */ public AudioService(Context context, AudioSystemAdapter audioSystem, SystemServerAdapter systemServer, SettingsAdapter settings) { SystemServerAdapter systemServer, SettingsAdapter settings, @Nullable Looper looper) { sLifecycleLogger.log(new AudioEventLogger.StringEvent("AudioService()")); mContext = context; mContentResolver = context.getContentResolver(); Loading Loading @@ -1010,7 +1022,11 @@ public class AudioService extends IAudioService.Stub MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM]; } if (looper == null) { createAudioSystemThread(); } else { mAudioHandler = new AudioHandler(looper); } AudioSystem.setErrorCallback(mAudioSystemCallback); Loading Loading @@ -6457,34 +6473,41 @@ public class AudioService extends IAudioService.Stub return; } int audioSystemDeviceOut = AudioDeviceInfo.convertDeviceTypeToInternalDevice( device.getType()); setDeviceVolumeBehaviorInternal(audioSystemDeviceOut, deviceVolumeBehavior, pkgName); persistDeviceVolumeBehavior(audioSystemDeviceOut, deviceVolumeBehavior); setDeviceVolumeBehaviorInternal(device, deviceVolumeBehavior, pkgName); persistDeviceVolumeBehavior(device.getInternalType(), deviceVolumeBehavior); } private void setDeviceVolumeBehaviorInternal(int audioSystemDeviceOut, private void setDeviceVolumeBehaviorInternal(@NonNull AudioDeviceAttributes device, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @NonNull String caller) { int audioSystemDeviceOut = device.getInternalType(); boolean volumeBehaviorChanged = false; // update device masks based on volume behavior switch (deviceVolumeBehavior) { case AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE: removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut); removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut); volumeBehaviorChanged |= removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut) | removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut); break; case AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED: removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut); addAudioSystemDeviceOutToFixedVolumeDevices(audioSystemDeviceOut); volumeBehaviorChanged |= removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut) | addAudioSystemDeviceOutToFixedVolumeDevices(audioSystemDeviceOut); break; case AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL: addAudioSystemDeviceOutToFullVolumeDevices(audioSystemDeviceOut); removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut); volumeBehaviorChanged |= addAudioSystemDeviceOutToFullVolumeDevices(audioSystemDeviceOut) | removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut); break; case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE: case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE: throw new IllegalArgumentException("Absolute volume unsupported for now"); } if (volumeBehaviorChanged) { sendMsg(mAudioHandler, MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR, SENDMSG_QUEUE, deviceVolumeBehavior, 0, device, /*delay*/ 0); } // log event and caller sDeviceLogger.log(new AudioEventLogger.StringEvent( "Volume behavior " + deviceVolumeBehavior + " for dev=0x" Loading Loading @@ -7761,6 +7784,14 @@ public class AudioService extends IAudioService.Stub /** Handles internal volume messages in separate volume thread. */ private class AudioHandler extends Handler { AudioHandler() { super(); } AudioHandler(Looper looper) { super(looper); } private void setAllVolumes(VolumeStreamState streamState) { // Apply volume Loading Loading @@ -8063,6 +8094,10 @@ public class AudioService extends IAudioService.Stub case MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID: updateActiveAssistantServiceUids(); break; case MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR: dispatchDeviceVolumeBehavior((AudioDeviceAttributes) msg.obj, msg.arg1); break; } } } Loading Loading @@ -9080,6 +9115,35 @@ public class AudioService extends IAudioService.Stub mMuteAwaitConnectionDispatchers.finishBroadcast(); } final RemoteCallbackList<IDeviceVolumeBehaviorDispatcher> mDeviceVolumeBehaviorDispatchers = new RemoteCallbackList<IDeviceVolumeBehaviorDispatcher>(); /** * @see AudioDeviceVolumeManager#addOnDeviceVolumeBehaviorChangedListener and * AudioDeviceVolumeManager#removeOnDeviceVolumeBehaviorChangedListener */ public void registerDeviceVolumeBehaviorDispatcher(boolean register, @NonNull IDeviceVolumeBehaviorDispatcher dispatcher) { enforceQueryStateOrModifyRoutingPermission(); Objects.requireNonNull(dispatcher); if (register) { mDeviceVolumeBehaviorDispatchers.register(dispatcher); } else { mDeviceVolumeBehaviorDispatchers.unregister(dispatcher); } } private void dispatchDeviceVolumeBehavior(AudioDeviceAttributes device, int volumeBehavior) { final int dispatchers = mDeviceVolumeBehaviorDispatchers.beginBroadcast(); for (int i = 0; i < dispatchers; i++) { try { mDeviceVolumeBehaviorDispatchers.getBroadcastItem(i) .dispatchDeviceVolumeBehaviorChanged(device, volumeBehavior); } catch (RemoteException e) { } } mDeviceVolumeBehaviorDispatchers.finishBroadcast(); } //========================================================================================== // Device orientation Loading Loading @@ -9310,14 +9374,20 @@ public class AudioService extends IAudioService.Stub if (DEBUG_VOL) { Log.d(TAG, "CEC sink: setting HDMI as full vol device"); } addAudioSystemDeviceOutToFullVolumeDevices(AudioSystem.DEVICE_OUT_HDMI); setDeviceVolumeBehaviorInternal( new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_HDMI, ""), AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL, "AudioService.updateHdmiCecSinkLocked()"); } else { if (DEBUG_VOL) { Log.d(TAG, "TV, no CEC: setting HDMI as regular vol device"); } // Android TV devices without CEC service apply software volume on // HDMI output removeAudioSystemDeviceOutFromFullVolumeDevices(AudioSystem.DEVICE_OUT_HDMI); setDeviceVolumeBehaviorInternal( new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_HDMI, ""), AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE, "AudioService.updateHdmiCecSinkLocked()"); } postUpdateVolumeStatesForAudioDevice(AudioSystem.DEVICE_OUT_HDMI, "HdmiPlaybackClient.DisplayStatusCallback"); Loading Loading @@ -11463,8 +11533,8 @@ public class AudioService extends IAudioService.Stub continue; } setDeviceVolumeBehaviorInternal(deviceType, deviceVolumeBehavior, "AudioService.restoreDeviceVolumeBehavior()"); setDeviceVolumeBehaviorInternal(new AudioDeviceAttributes(deviceType, ""), deviceVolumeBehavior, "AudioService.restoreDeviceVolumeBehavior()"); } } Loading @@ -11479,36 +11549,36 @@ public class AudioService extends IAudioService.Stub != AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET; } private void addAudioSystemDeviceOutToFixedVolumeDevices(int audioSystemDeviceOut) { private boolean addAudioSystemDeviceOutToFixedVolumeDevices(int audioSystemDeviceOut) { if (DEBUG_VOL) { Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) + " to mFixedVolumeDevices"); } mFixedVolumeDevices.add(audioSystemDeviceOut); return mFixedVolumeDevices.add(audioSystemDeviceOut); } private void removeAudioSystemDeviceOutFromFixedVolumeDevices(int audioSystemDeviceOut) { private boolean removeAudioSystemDeviceOutFromFixedVolumeDevices(int audioSystemDeviceOut) { if (DEBUG_VOL) { Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) + " from mFixedVolumeDevices"); } mFixedVolumeDevices.remove(audioSystemDeviceOut); return mFixedVolumeDevices.remove(audioSystemDeviceOut); } private void addAudioSystemDeviceOutToFullVolumeDevices(int audioSystemDeviceOut) { private boolean addAudioSystemDeviceOutToFullVolumeDevices(int audioSystemDeviceOut) { if (DEBUG_VOL) { Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) + " to mFullVolumeDevices"); } mFullVolumeDevices.add(audioSystemDeviceOut); return mFullVolumeDevices.add(audioSystemDeviceOut); } private void removeAudioSystemDeviceOutFromFullVolumeDevices(int audioSystemDeviceOut) { private boolean removeAudioSystemDeviceOutFromFullVolumeDevices(int audioSystemDeviceOut) { if (DEBUG_VOL) { Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) + " from mFullVolumeDevices"); } mFullVolumeDevices.remove(audioSystemDeviceOut); return mFullVolumeDevices.remove(audioSystemDeviceOut); } //==================== Loading services/tests/servicestests/src/com/android/server/audio/AudioServiceTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -62,7 +62,7 @@ public class AudioServiceTest { mSpySystemServer = spy(new NoOpSystemServerAdapter()); mSettingsAdapter = new NoOpSettingsAdapter(); mAudioService = new AudioService(mContext, mAudioSystem, mSpySystemServer, mSettingsAdapter); mSettingsAdapter, null); } /** Loading Loading
media/java/android/media/AudioDeviceVolumeManager.java +74 −0 Original line number Diff line number Diff line Loading @@ -181,6 +181,80 @@ public class AudioDeviceVolumeManager { } } /** * Manages the OnDeviceVolumeBehaviorChangedListener listeners and * DeviceVolumeBehaviorDispatcherStub */ private final CallbackUtil.LazyListenerManager<OnDeviceVolumeBehaviorChangedListener> mDeviceVolumeBehaviorChangedListenerMgr = new CallbackUtil.LazyListenerManager(); /** * @hide * Interface definition of a callback to be invoked when the volume behavior of an audio device * is updated. */ public interface OnDeviceVolumeBehaviorChangedListener { /** * Called on the listener to indicate that the volume behavior of a device has changed. * @param device the audio device whose volume behavior changed * @param volumeBehavior the new volume behavior of the audio device */ void onDeviceVolumeBehaviorChanged( @NonNull AudioDeviceAttributes device, @AudioManager.DeviceVolumeBehavior int volumeBehavior); } /** * @hide * Adds a listener for being notified of changes to any device's volume behavior. * @throws SecurityException if the caller doesn't hold the required permission */ @RequiresPermission(anyOf = { android.Manifest.permission.MODIFY_AUDIO_ROUTING, android.Manifest.permission.QUERY_AUDIO_STATE }) public void addOnDeviceVolumeBehaviorChangedListener( @NonNull @CallbackExecutor Executor executor, @NonNull OnDeviceVolumeBehaviorChangedListener listener) throws SecurityException { mDeviceVolumeBehaviorChangedListenerMgr.addListener(executor, listener, "addOnDeviceVolumeBehaviorChangedListener", () -> new DeviceVolumeBehaviorDispatcherStub()); } /** * @hide * Removes a previously added listener of changes to device volume behavior. */ @RequiresPermission(anyOf = { android.Manifest.permission.MODIFY_AUDIO_ROUTING, android.Manifest.permission.QUERY_AUDIO_STATE }) public void removeOnDeviceVolumeBehaviorChangedListener( @NonNull OnDeviceVolumeBehaviorChangedListener listener) { mDeviceVolumeBehaviorChangedListenerMgr.removeListener(listener, "removeOnDeviceVolumeBehaviorChangedListener"); } private final class DeviceVolumeBehaviorDispatcherStub extends IDeviceVolumeBehaviorDispatcher.Stub implements CallbackUtil.DispatcherStub { public void register(boolean register) { try { getService().registerDeviceVolumeBehaviorDispatcher(register, this); } catch (RemoteException e) { e.rethrowFromSystemServer(); } } @Override public void dispatchDeviceVolumeBehaviorChanged(@NonNull AudioDeviceAttributes device, @AudioManager.DeviceVolumeBehavior int volumeBehavior) { mDeviceVolumeBehaviorChangedListenerMgr.callListeners((listener) -> listener.onDeviceVolumeBehaviorChanged(device, volumeBehavior)); } } private static IAudioService getService() { if (sService != null) { return sService; Loading
media/java/android/media/IAudioService.aidl +5 −1 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import android.media.IAudioRoutesObserver; import android.media.IAudioServerStateDispatcher; import android.media.ICapturePresetDevicesRoleDispatcher; import android.media.ICommunicationDeviceDispatcher; import android.media.IDeviceVolumeBehaviorDispatcher; import android.media.IMuteAwaitConnectionCallback; import android.media.IPlaybackConfigDispatcher; import android.media.IRecordingConfigDispatcher; Loading @@ -44,7 +45,6 @@ import android.media.ISpatializerHeadTrackingModeCallback; import android.media.ISpatializerHeadToSoundStagePoseCallback; import android.media.ISpatializerOutputCallback; import android.media.IVolumeController; import android.media.IVolumeController; import android.media.PlayerBase; import android.media.VolumeInfo; import android.media.VolumePolicy; Loading Loading @@ -482,6 +482,10 @@ interface IAudioService { void setTestDeviceConnectionState(in AudioDeviceAttributes device, boolean connected); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING,android.Manifest.permission.QUERY_AUDIO_STATE})") void registerDeviceVolumeBehaviorDispatcher(boolean register, in IDeviceVolumeBehaviorDispatcher dispatcher); List<AudioFocusInfo> getFocusStack(); boolean sendFocusLoss(in AudioFocusInfo focusLoser, in IAudioPolicyCallback apcb); Loading
media/java/android/media/IDeviceVolumeBehaviorDispatcher.aidl 0 → 100644 +31 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.media; import android.media.AudioDeviceAttributes; /** * AIDL for AudioService to signal changes to an audio device's volume behavior * * {@hide} */ oneway interface IDeviceVolumeBehaviorDispatcher { void dispatchDeviceVolumeBehaviorChanged(in AudioDeviceAttributes device, int deviceVolumeBehavior); }
services/core/java/com/android/server/audio/AudioService.java +98 −28 Original line number Diff line number Diff line Loading @@ -96,6 +96,7 @@ import android.media.IAudioServerStateDispatcher; import android.media.IAudioService; import android.media.ICapturePresetDevicesRoleDispatcher; import android.media.ICommunicationDeviceDispatcher; import android.media.IDeviceVolumeBehaviorDispatcher; import android.media.IMuteAwaitConnectionCallback; import android.media.IPlaybackConfigDispatcher; import android.media.IRecordingConfigDispatcher; Loading Loading @@ -341,6 +342,7 @@ public class AudioService extends IAudioService.Stub private static final int MSG_ADD_ASSISTANT_SERVICE_UID = 44; private static final int MSG_REMOVE_ASSISTANT_SERVICE_UID = 45; private static final int MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID = 46; private static final int MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR = 47; // start of messages handled under wakelock // these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(), Loading Loading @@ -876,13 +878,23 @@ public class AudioService extends IAudioService.Stub /** @hide */ public AudioService(Context context) { this(context, AudioSystemAdapter.getDefaultAdapter(), this(context, AudioSystemAdapter.getDefaultAdapter(), SystemServerAdapter.getDefaultAdapter(context), SettingsAdapter.getDefaultAdapter()); SettingsAdapter.getDefaultAdapter(), null); } /** * @param context * @param audioSystem Adapter for {@link AudioSystem} * @param systemServer Adapter for privilieged functionality for system server components * @param settings Adapter for {@link Settings} * @param looper Looper to use for the service's message handler. If this is null, an * {@link AudioSystemThread} is created as the messaging thread instead. */ public AudioService(Context context, AudioSystemAdapter audioSystem, SystemServerAdapter systemServer, SettingsAdapter settings) { SystemServerAdapter systemServer, SettingsAdapter settings, @Nullable Looper looper) { sLifecycleLogger.log(new AudioEventLogger.StringEvent("AudioService()")); mContext = context; mContentResolver = context.getContentResolver(); Loading Loading @@ -1010,7 +1022,11 @@ public class AudioService extends IAudioService.Stub MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM]; } if (looper == null) { createAudioSystemThread(); } else { mAudioHandler = new AudioHandler(looper); } AudioSystem.setErrorCallback(mAudioSystemCallback); Loading Loading @@ -6457,34 +6473,41 @@ public class AudioService extends IAudioService.Stub return; } int audioSystemDeviceOut = AudioDeviceInfo.convertDeviceTypeToInternalDevice( device.getType()); setDeviceVolumeBehaviorInternal(audioSystemDeviceOut, deviceVolumeBehavior, pkgName); persistDeviceVolumeBehavior(audioSystemDeviceOut, deviceVolumeBehavior); setDeviceVolumeBehaviorInternal(device, deviceVolumeBehavior, pkgName); persistDeviceVolumeBehavior(device.getInternalType(), deviceVolumeBehavior); } private void setDeviceVolumeBehaviorInternal(int audioSystemDeviceOut, private void setDeviceVolumeBehaviorInternal(@NonNull AudioDeviceAttributes device, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @NonNull String caller) { int audioSystemDeviceOut = device.getInternalType(); boolean volumeBehaviorChanged = false; // update device masks based on volume behavior switch (deviceVolumeBehavior) { case AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE: removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut); removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut); volumeBehaviorChanged |= removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut) | removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut); break; case AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED: removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut); addAudioSystemDeviceOutToFixedVolumeDevices(audioSystemDeviceOut); volumeBehaviorChanged |= removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut) | addAudioSystemDeviceOutToFixedVolumeDevices(audioSystemDeviceOut); break; case AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL: addAudioSystemDeviceOutToFullVolumeDevices(audioSystemDeviceOut); removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut); volumeBehaviorChanged |= addAudioSystemDeviceOutToFullVolumeDevices(audioSystemDeviceOut) | removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut); break; case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE: case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE: throw new IllegalArgumentException("Absolute volume unsupported for now"); } if (volumeBehaviorChanged) { sendMsg(mAudioHandler, MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR, SENDMSG_QUEUE, deviceVolumeBehavior, 0, device, /*delay*/ 0); } // log event and caller sDeviceLogger.log(new AudioEventLogger.StringEvent( "Volume behavior " + deviceVolumeBehavior + " for dev=0x" Loading Loading @@ -7761,6 +7784,14 @@ public class AudioService extends IAudioService.Stub /** Handles internal volume messages in separate volume thread. */ private class AudioHandler extends Handler { AudioHandler() { super(); } AudioHandler(Looper looper) { super(looper); } private void setAllVolumes(VolumeStreamState streamState) { // Apply volume Loading Loading @@ -8063,6 +8094,10 @@ public class AudioService extends IAudioService.Stub case MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID: updateActiveAssistantServiceUids(); break; case MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR: dispatchDeviceVolumeBehavior((AudioDeviceAttributes) msg.obj, msg.arg1); break; } } } Loading Loading @@ -9080,6 +9115,35 @@ public class AudioService extends IAudioService.Stub mMuteAwaitConnectionDispatchers.finishBroadcast(); } final RemoteCallbackList<IDeviceVolumeBehaviorDispatcher> mDeviceVolumeBehaviorDispatchers = new RemoteCallbackList<IDeviceVolumeBehaviorDispatcher>(); /** * @see AudioDeviceVolumeManager#addOnDeviceVolumeBehaviorChangedListener and * AudioDeviceVolumeManager#removeOnDeviceVolumeBehaviorChangedListener */ public void registerDeviceVolumeBehaviorDispatcher(boolean register, @NonNull IDeviceVolumeBehaviorDispatcher dispatcher) { enforceQueryStateOrModifyRoutingPermission(); Objects.requireNonNull(dispatcher); if (register) { mDeviceVolumeBehaviorDispatchers.register(dispatcher); } else { mDeviceVolumeBehaviorDispatchers.unregister(dispatcher); } } private void dispatchDeviceVolumeBehavior(AudioDeviceAttributes device, int volumeBehavior) { final int dispatchers = mDeviceVolumeBehaviorDispatchers.beginBroadcast(); for (int i = 0; i < dispatchers; i++) { try { mDeviceVolumeBehaviorDispatchers.getBroadcastItem(i) .dispatchDeviceVolumeBehaviorChanged(device, volumeBehavior); } catch (RemoteException e) { } } mDeviceVolumeBehaviorDispatchers.finishBroadcast(); } //========================================================================================== // Device orientation Loading Loading @@ -9310,14 +9374,20 @@ public class AudioService extends IAudioService.Stub if (DEBUG_VOL) { Log.d(TAG, "CEC sink: setting HDMI as full vol device"); } addAudioSystemDeviceOutToFullVolumeDevices(AudioSystem.DEVICE_OUT_HDMI); setDeviceVolumeBehaviorInternal( new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_HDMI, ""), AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL, "AudioService.updateHdmiCecSinkLocked()"); } else { if (DEBUG_VOL) { Log.d(TAG, "TV, no CEC: setting HDMI as regular vol device"); } // Android TV devices without CEC service apply software volume on // HDMI output removeAudioSystemDeviceOutFromFullVolumeDevices(AudioSystem.DEVICE_OUT_HDMI); setDeviceVolumeBehaviorInternal( new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_HDMI, ""), AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE, "AudioService.updateHdmiCecSinkLocked()"); } postUpdateVolumeStatesForAudioDevice(AudioSystem.DEVICE_OUT_HDMI, "HdmiPlaybackClient.DisplayStatusCallback"); Loading Loading @@ -11463,8 +11533,8 @@ public class AudioService extends IAudioService.Stub continue; } setDeviceVolumeBehaviorInternal(deviceType, deviceVolumeBehavior, "AudioService.restoreDeviceVolumeBehavior()"); setDeviceVolumeBehaviorInternal(new AudioDeviceAttributes(deviceType, ""), deviceVolumeBehavior, "AudioService.restoreDeviceVolumeBehavior()"); } } Loading @@ -11479,36 +11549,36 @@ public class AudioService extends IAudioService.Stub != AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET; } private void addAudioSystemDeviceOutToFixedVolumeDevices(int audioSystemDeviceOut) { private boolean addAudioSystemDeviceOutToFixedVolumeDevices(int audioSystemDeviceOut) { if (DEBUG_VOL) { Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) + " to mFixedVolumeDevices"); } mFixedVolumeDevices.add(audioSystemDeviceOut); return mFixedVolumeDevices.add(audioSystemDeviceOut); } private void removeAudioSystemDeviceOutFromFixedVolumeDevices(int audioSystemDeviceOut) { private boolean removeAudioSystemDeviceOutFromFixedVolumeDevices(int audioSystemDeviceOut) { if (DEBUG_VOL) { Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) + " from mFixedVolumeDevices"); } mFixedVolumeDevices.remove(audioSystemDeviceOut); return mFixedVolumeDevices.remove(audioSystemDeviceOut); } private void addAudioSystemDeviceOutToFullVolumeDevices(int audioSystemDeviceOut) { private boolean addAudioSystemDeviceOutToFullVolumeDevices(int audioSystemDeviceOut) { if (DEBUG_VOL) { Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) + " to mFullVolumeDevices"); } mFullVolumeDevices.add(audioSystemDeviceOut); return mFullVolumeDevices.add(audioSystemDeviceOut); } private void removeAudioSystemDeviceOutFromFullVolumeDevices(int audioSystemDeviceOut) { private boolean removeAudioSystemDeviceOutFromFullVolumeDevices(int audioSystemDeviceOut) { if (DEBUG_VOL) { Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) + " from mFullVolumeDevices"); } mFullVolumeDevices.remove(audioSystemDeviceOut); return mFullVolumeDevices.remove(audioSystemDeviceOut); } //==================== Loading
services/tests/servicestests/src/com/android/server/audio/AudioServiceTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -62,7 +62,7 @@ public class AudioServiceTest { mSpySystemServer = spy(new NoOpSystemServerAdapter()); mSettingsAdapter = new NoOpSettingsAdapter(); mAudioService = new AudioService(mContext, mAudioSystem, mSpySystemServer, mSettingsAdapter); mSettingsAdapter, null); } /** Loading