Loading services/core/java/com/android/server/audio/AudioDeviceBroker.java +9 −4 Original line number Diff line number Diff line Loading @@ -85,6 +85,7 @@ import java.util.concurrent.atomic.AtomicBoolean; private final @NonNull AudioService mAudioService; private final @NonNull Context mContext; private final @NonNull AudioSystemAdapter mAudioSystem; /** ID for Communication strategy retrieved form audio policy manager */ private int mCommunicationStrategyId = -1; Loading Loading @@ -159,12 +160,14 @@ import java.util.concurrent.atomic.AtomicBoolean; public static final long USE_SET_COMMUNICATION_DEVICE = 243827847L; //------------------------------------------------------------------- /*package*/ AudioDeviceBroker(@NonNull Context context, @NonNull AudioService service) { /*package*/ AudioDeviceBroker(@NonNull Context context, @NonNull AudioService service, @NonNull AudioSystemAdapter audioSystem) { mContext = context; mAudioService = service; mBtHelper = new BtHelper(this); mDeviceInventory = new AudioDeviceInventory(this); mSystemServer = SystemServerAdapter.getDefaultAdapter(mContext); mAudioSystem = audioSystem; init(); } Loading @@ -173,12 +176,14 @@ import java.util.concurrent.atomic.AtomicBoolean; * in system_server */ AudioDeviceBroker(@NonNull Context context, @NonNull AudioService service, @NonNull AudioDeviceInventory mockDeviceInventory, @NonNull SystemServerAdapter mockSystemServer) { @NonNull SystemServerAdapter mockSystemServer, @NonNull AudioSystemAdapter audioSystem) { mContext = context; mAudioService = service; mBtHelper = new BtHelper(this); mDeviceInventory = mockDeviceInventory; mSystemServer = mockSystemServer; mAudioSystem = audioSystem; init(); } Loading Loading @@ -540,7 +545,7 @@ import java.util.concurrent.atomic.AtomicBoolean; AudioAttributes attr = AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType( AudioSystem.STREAM_VOICE_CALL); List<AudioDeviceAttributes> devices = AudioSystem.getDevicesForAttributes( List<AudioDeviceAttributes> devices = mAudioSystem.getDevicesForAttributes( attr, false /* forVolume */); if (devices.isEmpty()) { if (mAudioService.isPlatformVoice()) { Loading Loading @@ -1493,7 +1498,7 @@ import java.util.concurrent.atomic.AtomicBoolean; Log.v(TAG, "onSetForceUse(useCase<" + useCase + ">, config<" + config + ">, fromA2dp<" + fromA2dp + ">, eventSource<" + eventSource + ">)"); } AudioSystem.setForceUse(useCase, config); mAudioSystem.setForceUse(useCase, config); } private void onSendBecomingNoisyIntent() { Loading services/core/java/com/android/server/audio/AudioService.java +31 −11 Original line number Diff line number Diff line Loading @@ -199,6 +199,7 @@ import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.audio.AudioServiceEvents.DeviceVolumeEvent; import com.android.server.audio.AudioServiceEvents.PhoneStateEvent; import com.android.server.audio.AudioServiceEvents.VolChangedBroadcastEvent; import com.android.server.audio.AudioServiceEvents.VolumeEvent; import com.android.server.pm.UserManagerInternal; import com.android.server.pm.UserManagerInternal.UserRestrictionsListener; Loading Loading @@ -1214,7 +1215,7 @@ public class AudioService extends IAudioService.Stub mUseFixedVolume = mContext.getResources().getBoolean( com.android.internal.R.bool.config_useFixedVolume); mDeviceBroker = new AudioDeviceBroker(mContext, this); mDeviceBroker = new AudioDeviceBroker(mContext, this, mAudioSystem); mRecordMonitor = new RecordingActivityMonitor(mContext); mRecordMonitor.registerRecordingCallback(mVoiceRecordingActivityMonitor, true); Loading Loading @@ -1687,7 +1688,7 @@ public class AudioService extends IAudioService.Stub synchronized (mSettingsLock) { final int forDock = mDockAudioMediaEnabled ? AudioSystem.FORCE_ANALOG_DOCK : AudioSystem.FORCE_NONE; AudioSystem.FORCE_DIGITAL_DOCK : AudioSystem.FORCE_NONE; mDeviceBroker.setForceUse_Async(AudioSystem.FOR_DOCK, forDock, "onAudioServerDied"); sendEncodedSurroundMode(mContentResolver, "onAudioServerDied"); sendEnabledSurroundFormats(mContentResolver, true); Loading Loading @@ -2323,9 +2324,10 @@ public class AudioService extends IAudioService.Stub SENDMSG_QUEUE, AudioSystem.FOR_DOCK, mDockAudioMediaEnabled ? AudioSystem.FORCE_ANALOG_DOCK : AudioSystem.FORCE_NONE, AudioSystem.FORCE_DIGITAL_DOCK : AudioSystem.FORCE_NONE, new String("readDockAudioSettings"), 0); } Loading Loading @@ -3972,13 +3974,25 @@ public class AudioService extends IAudioService.Stub Log.e(TAG, "Unsupported non-stream type based VolumeInfo", new Exception()); return; } int index = vi.getVolumeIndex(); if (index == VolumeInfo.INDEX_NOT_SET && !vi.hasMuteCommand()) { throw new IllegalArgumentException( "changing device volume requires a volume index or mute command"); } // TODO handle unmuting if current audio device // force a cache clear to force reevaluating stream type to audio device selection // that can interfere with the sending of the VOLUME_CHANGED_ACTION intent mAudioSystem.clearRoutingCache(); // log the current device that will be used when evaluating the sending of the // VOLUME_CHANGED_ACTION intent to see if the current device is the one being modified final int currDev = getDeviceForStream(vi.getStreamType()); AudioService.sVolumeLogger.enqueue(new DeviceVolumeEvent(vi.getStreamType(), index, ada, currDev, callingPackage)); // TODO handle unmuting of current audio device // if a stream is not muted but the VolumeInfo is for muting, set the volume index // for the device to min volume if (vi.hasMuteCommand() && vi.isMuted() && !isStreamMute(vi.getStreamType())) { Loading Loading @@ -4129,11 +4143,11 @@ public class AudioService extends IAudioService.Stub return; } final EventLogger.Event event = (device == null) ? new VolumeEvent(VolumeEvent.VOL_SET_STREAM_VOL, streamType, index/*val1*/, flags/*val2*/, callingPackage) : new DeviceVolumeEvent(streamType, index, device, callingPackage); sVolumeLogger.enqueue(event); if (device == null) { // call was already logged in setDeviceVolume() sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_SET_STREAM_VOL, streamType, index/*val1*/, flags/*val2*/, callingPackage)); } setStreamVolume(streamType, index, flags, device, callingPackage, callingPackage, attributionTag, Binder.getCallingUid(), callingOrSelfHasAudioSettingsPermission()); Loading Loading @@ -4547,8 +4561,12 @@ public class AudioService extends IAudioService.Stub maybeSendSystemAudioStatusCommand(false); } } if (ada == null) { // only non-null when coming here from setDeviceVolume // TODO change test to check early if device is current device or not sendVolumeUpdate(streamType, oldIndex, index, flags, device); } } private void dispatchAbsoluteVolumeChanged(int streamType, AbsoluteVolumeDeviceInfo deviceInfo, int index) { Loading Loading @@ -8561,6 +8579,8 @@ public class AudioService extends IAudioService.Stub mVolumeChanged.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex); mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE_ALIAS, mStreamVolumeAlias[mStreamType]); AudioService.sVolumeLogger.enqueue(new VolChangedBroadcastEvent( mStreamType, mStreamVolumeAlias[mStreamType], index)); sendBroadcastToAll(mVolumeChanged, mVolumeChangedOptions); } } Loading Loading @@ -10837,7 +10857,7 @@ public class AudioService extends IAudioService.Stub static final int LOG_NB_EVENTS_PHONE_STATE = 20; static final int LOG_NB_EVENTS_DEVICE_CONNECTION = 50; static final int LOG_NB_EVENTS_FORCE_USE = 20; static final int LOG_NB_EVENTS_VOLUME = 40; static final int LOG_NB_EVENTS_VOLUME = 100; static final int LOG_NB_EVENTS_DYN_POLICY = 10; static final int LOG_NB_EVENTS_SPATIAL = 30; static final int LOG_NB_EVENTS_SOUND_DOSE = 30; Loading services/core/java/com/android/server/audio/AudioServiceEvents.java +27 −2 Original line number Diff line number Diff line Loading @@ -147,19 +147,42 @@ public class AudioServiceEvents { } } static final class VolChangedBroadcastEvent extends EventLogger.Event { final int mStreamType; final int mAliasStreamType; final int mIndex; VolChangedBroadcastEvent(int stream, int alias, int index) { mStreamType = stream; mAliasStreamType = alias; mIndex = index; } @Override public String eventToString() { return new StringBuilder("sending VOLUME_CHANGED stream:") .append(AudioSystem.streamToString(mStreamType)) .append(" index:").append(mIndex) .append(" alias:").append(AudioSystem.streamToString(mAliasStreamType)) .toString(); } } static final class DeviceVolumeEvent extends EventLogger.Event { final int mStream; final int mVolIndex; final String mDeviceNativeType; final String mDeviceAddress; final String mCaller; final int mDeviceForStream; DeviceVolumeEvent(int streamType, int index, @NonNull AudioDeviceAttributes device, String callingPackage) { int deviceForStream, String callingPackage) { mStream = streamType; mVolIndex = index; mDeviceNativeType = "0x" + Integer.toHexString(device.getInternalType()); mDeviceAddress = device.getAddress(); mDeviceForStream = deviceForStream; mCaller = callingPackage; // log metrics new MediaMetrics.Item(MediaMetrics.Name.AUDIO_VOLUME_EVENT) Loading @@ -180,7 +203,9 @@ public class AudioServiceEvents { .append(" index:").append(mVolIndex) .append(" device:").append(mDeviceNativeType) .append(" addr:").append(mDeviceAddress) .append(") from ").append(mCaller).toString(); .append(") from ").append(mCaller) .append(" currDevForStream:Ox").append(Integer.toHexString(mDeviceForStream)) .toString(); } } Loading services/core/java/com/android/server/audio/AudioSystemAdapter.java +11 −0 Original line number Diff line number Diff line Loading @@ -161,6 +161,16 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback, } } /** * Empties the routing cache if enabled. */ public void clearRoutingCache() { if (DEBUG_CACHE) { Log.d(TAG, "---- routing cache clear (from java) ----------"); } invalidateRoutingCache(); } /** * @see AudioManager#addOnDevicesForAttributesChangedListener( * AudioAttributes, Executor, OnDevicesForAttributesChangedListener) Loading Loading @@ -464,6 +474,7 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback, * @return */ public int setParameters(String keyValuePairs) { invalidateRoutingCache(); return AudioSystem.setParameters(keyValuePairs); } Loading services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -74,7 +74,7 @@ public class AudioDeviceBrokerTest { mSpyDevInventory = spy(new AudioDeviceInventory(mSpyAudioSystem)); mSpySystemServer = spy(new NoOpSystemServerAdapter()); mAudioDeviceBroker = new AudioDeviceBroker(mContext, mMockAudioService, mSpyDevInventory, mSpySystemServer); mSpySystemServer, mSpyAudioSystem); mSpyDevInventory.setDeviceBroker(mAudioDeviceBroker); BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); Loading Loading
services/core/java/com/android/server/audio/AudioDeviceBroker.java +9 −4 Original line number Diff line number Diff line Loading @@ -85,6 +85,7 @@ import java.util.concurrent.atomic.AtomicBoolean; private final @NonNull AudioService mAudioService; private final @NonNull Context mContext; private final @NonNull AudioSystemAdapter mAudioSystem; /** ID for Communication strategy retrieved form audio policy manager */ private int mCommunicationStrategyId = -1; Loading Loading @@ -159,12 +160,14 @@ import java.util.concurrent.atomic.AtomicBoolean; public static final long USE_SET_COMMUNICATION_DEVICE = 243827847L; //------------------------------------------------------------------- /*package*/ AudioDeviceBroker(@NonNull Context context, @NonNull AudioService service) { /*package*/ AudioDeviceBroker(@NonNull Context context, @NonNull AudioService service, @NonNull AudioSystemAdapter audioSystem) { mContext = context; mAudioService = service; mBtHelper = new BtHelper(this); mDeviceInventory = new AudioDeviceInventory(this); mSystemServer = SystemServerAdapter.getDefaultAdapter(mContext); mAudioSystem = audioSystem; init(); } Loading @@ -173,12 +176,14 @@ import java.util.concurrent.atomic.AtomicBoolean; * in system_server */ AudioDeviceBroker(@NonNull Context context, @NonNull AudioService service, @NonNull AudioDeviceInventory mockDeviceInventory, @NonNull SystemServerAdapter mockSystemServer) { @NonNull SystemServerAdapter mockSystemServer, @NonNull AudioSystemAdapter audioSystem) { mContext = context; mAudioService = service; mBtHelper = new BtHelper(this); mDeviceInventory = mockDeviceInventory; mSystemServer = mockSystemServer; mAudioSystem = audioSystem; init(); } Loading Loading @@ -540,7 +545,7 @@ import java.util.concurrent.atomic.AtomicBoolean; AudioAttributes attr = AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType( AudioSystem.STREAM_VOICE_CALL); List<AudioDeviceAttributes> devices = AudioSystem.getDevicesForAttributes( List<AudioDeviceAttributes> devices = mAudioSystem.getDevicesForAttributes( attr, false /* forVolume */); if (devices.isEmpty()) { if (mAudioService.isPlatformVoice()) { Loading Loading @@ -1493,7 +1498,7 @@ import java.util.concurrent.atomic.AtomicBoolean; Log.v(TAG, "onSetForceUse(useCase<" + useCase + ">, config<" + config + ">, fromA2dp<" + fromA2dp + ">, eventSource<" + eventSource + ">)"); } AudioSystem.setForceUse(useCase, config); mAudioSystem.setForceUse(useCase, config); } private void onSendBecomingNoisyIntent() { Loading
services/core/java/com/android/server/audio/AudioService.java +31 −11 Original line number Diff line number Diff line Loading @@ -199,6 +199,7 @@ import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.audio.AudioServiceEvents.DeviceVolumeEvent; import com.android.server.audio.AudioServiceEvents.PhoneStateEvent; import com.android.server.audio.AudioServiceEvents.VolChangedBroadcastEvent; import com.android.server.audio.AudioServiceEvents.VolumeEvent; import com.android.server.pm.UserManagerInternal; import com.android.server.pm.UserManagerInternal.UserRestrictionsListener; Loading Loading @@ -1214,7 +1215,7 @@ public class AudioService extends IAudioService.Stub mUseFixedVolume = mContext.getResources().getBoolean( com.android.internal.R.bool.config_useFixedVolume); mDeviceBroker = new AudioDeviceBroker(mContext, this); mDeviceBroker = new AudioDeviceBroker(mContext, this, mAudioSystem); mRecordMonitor = new RecordingActivityMonitor(mContext); mRecordMonitor.registerRecordingCallback(mVoiceRecordingActivityMonitor, true); Loading Loading @@ -1687,7 +1688,7 @@ public class AudioService extends IAudioService.Stub synchronized (mSettingsLock) { final int forDock = mDockAudioMediaEnabled ? AudioSystem.FORCE_ANALOG_DOCK : AudioSystem.FORCE_NONE; AudioSystem.FORCE_DIGITAL_DOCK : AudioSystem.FORCE_NONE; mDeviceBroker.setForceUse_Async(AudioSystem.FOR_DOCK, forDock, "onAudioServerDied"); sendEncodedSurroundMode(mContentResolver, "onAudioServerDied"); sendEnabledSurroundFormats(mContentResolver, true); Loading Loading @@ -2323,9 +2324,10 @@ public class AudioService extends IAudioService.Stub SENDMSG_QUEUE, AudioSystem.FOR_DOCK, mDockAudioMediaEnabled ? AudioSystem.FORCE_ANALOG_DOCK : AudioSystem.FORCE_NONE, AudioSystem.FORCE_DIGITAL_DOCK : AudioSystem.FORCE_NONE, new String("readDockAudioSettings"), 0); } Loading Loading @@ -3972,13 +3974,25 @@ public class AudioService extends IAudioService.Stub Log.e(TAG, "Unsupported non-stream type based VolumeInfo", new Exception()); return; } int index = vi.getVolumeIndex(); if (index == VolumeInfo.INDEX_NOT_SET && !vi.hasMuteCommand()) { throw new IllegalArgumentException( "changing device volume requires a volume index or mute command"); } // TODO handle unmuting if current audio device // force a cache clear to force reevaluating stream type to audio device selection // that can interfere with the sending of the VOLUME_CHANGED_ACTION intent mAudioSystem.clearRoutingCache(); // log the current device that will be used when evaluating the sending of the // VOLUME_CHANGED_ACTION intent to see if the current device is the one being modified final int currDev = getDeviceForStream(vi.getStreamType()); AudioService.sVolumeLogger.enqueue(new DeviceVolumeEvent(vi.getStreamType(), index, ada, currDev, callingPackage)); // TODO handle unmuting of current audio device // if a stream is not muted but the VolumeInfo is for muting, set the volume index // for the device to min volume if (vi.hasMuteCommand() && vi.isMuted() && !isStreamMute(vi.getStreamType())) { Loading Loading @@ -4129,11 +4143,11 @@ public class AudioService extends IAudioService.Stub return; } final EventLogger.Event event = (device == null) ? new VolumeEvent(VolumeEvent.VOL_SET_STREAM_VOL, streamType, index/*val1*/, flags/*val2*/, callingPackage) : new DeviceVolumeEvent(streamType, index, device, callingPackage); sVolumeLogger.enqueue(event); if (device == null) { // call was already logged in setDeviceVolume() sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_SET_STREAM_VOL, streamType, index/*val1*/, flags/*val2*/, callingPackage)); } setStreamVolume(streamType, index, flags, device, callingPackage, callingPackage, attributionTag, Binder.getCallingUid(), callingOrSelfHasAudioSettingsPermission()); Loading Loading @@ -4547,8 +4561,12 @@ public class AudioService extends IAudioService.Stub maybeSendSystemAudioStatusCommand(false); } } if (ada == null) { // only non-null when coming here from setDeviceVolume // TODO change test to check early if device is current device or not sendVolumeUpdate(streamType, oldIndex, index, flags, device); } } private void dispatchAbsoluteVolumeChanged(int streamType, AbsoluteVolumeDeviceInfo deviceInfo, int index) { Loading Loading @@ -8561,6 +8579,8 @@ public class AudioService extends IAudioService.Stub mVolumeChanged.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex); mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE_ALIAS, mStreamVolumeAlias[mStreamType]); AudioService.sVolumeLogger.enqueue(new VolChangedBroadcastEvent( mStreamType, mStreamVolumeAlias[mStreamType], index)); sendBroadcastToAll(mVolumeChanged, mVolumeChangedOptions); } } Loading Loading @@ -10837,7 +10857,7 @@ public class AudioService extends IAudioService.Stub static final int LOG_NB_EVENTS_PHONE_STATE = 20; static final int LOG_NB_EVENTS_DEVICE_CONNECTION = 50; static final int LOG_NB_EVENTS_FORCE_USE = 20; static final int LOG_NB_EVENTS_VOLUME = 40; static final int LOG_NB_EVENTS_VOLUME = 100; static final int LOG_NB_EVENTS_DYN_POLICY = 10; static final int LOG_NB_EVENTS_SPATIAL = 30; static final int LOG_NB_EVENTS_SOUND_DOSE = 30; Loading
services/core/java/com/android/server/audio/AudioServiceEvents.java +27 −2 Original line number Diff line number Diff line Loading @@ -147,19 +147,42 @@ public class AudioServiceEvents { } } static final class VolChangedBroadcastEvent extends EventLogger.Event { final int mStreamType; final int mAliasStreamType; final int mIndex; VolChangedBroadcastEvent(int stream, int alias, int index) { mStreamType = stream; mAliasStreamType = alias; mIndex = index; } @Override public String eventToString() { return new StringBuilder("sending VOLUME_CHANGED stream:") .append(AudioSystem.streamToString(mStreamType)) .append(" index:").append(mIndex) .append(" alias:").append(AudioSystem.streamToString(mAliasStreamType)) .toString(); } } static final class DeviceVolumeEvent extends EventLogger.Event { final int mStream; final int mVolIndex; final String mDeviceNativeType; final String mDeviceAddress; final String mCaller; final int mDeviceForStream; DeviceVolumeEvent(int streamType, int index, @NonNull AudioDeviceAttributes device, String callingPackage) { int deviceForStream, String callingPackage) { mStream = streamType; mVolIndex = index; mDeviceNativeType = "0x" + Integer.toHexString(device.getInternalType()); mDeviceAddress = device.getAddress(); mDeviceForStream = deviceForStream; mCaller = callingPackage; // log metrics new MediaMetrics.Item(MediaMetrics.Name.AUDIO_VOLUME_EVENT) Loading @@ -180,7 +203,9 @@ public class AudioServiceEvents { .append(" index:").append(mVolIndex) .append(" device:").append(mDeviceNativeType) .append(" addr:").append(mDeviceAddress) .append(") from ").append(mCaller).toString(); .append(") from ").append(mCaller) .append(" currDevForStream:Ox").append(Integer.toHexString(mDeviceForStream)) .toString(); } } Loading
services/core/java/com/android/server/audio/AudioSystemAdapter.java +11 −0 Original line number Diff line number Diff line Loading @@ -161,6 +161,16 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback, } } /** * Empties the routing cache if enabled. */ public void clearRoutingCache() { if (DEBUG_CACHE) { Log.d(TAG, "---- routing cache clear (from java) ----------"); } invalidateRoutingCache(); } /** * @see AudioManager#addOnDevicesForAttributesChangedListener( * AudioAttributes, Executor, OnDevicesForAttributesChangedListener) Loading Loading @@ -464,6 +474,7 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback, * @return */ public int setParameters(String keyValuePairs) { invalidateRoutingCache(); return AudioSystem.setParameters(keyValuePairs); } Loading
services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -74,7 +74,7 @@ public class AudioDeviceBrokerTest { mSpyDevInventory = spy(new AudioDeviceInventory(mSpyAudioSystem)); mSpySystemServer = spy(new NoOpSystemServerAdapter()); mAudioDeviceBroker = new AudioDeviceBroker(mContext, mMockAudioService, mSpyDevInventory, mSpySystemServer); mSpySystemServer, mSpyAudioSystem); mSpyDevInventory.setDeviceBroker(mAudioDeviceBroker); BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); Loading