Loading services/core/java/com/android/server/audio/AudioDeviceBroker.java +29 −25 Original line number Diff line number Diff line Loading @@ -772,7 +772,6 @@ public class AudioDeviceBroker { final int mVolume; final boolean mIsLeOutput; final @NonNull String mEventSource; final @AudioSystem.AudioFormatNativeEnumForBtCodec int mCodec; final int mAudioSystemDevice; final int mMusicDevice; Loading @@ -787,7 +786,6 @@ public class AudioDeviceBroker { mEventSource = d.mEventSource; mAudioSystemDevice = audioDevice; mMusicDevice = AudioSystem.DEVICE_NONE; mCodec = codec; } // constructor used by AudioDeviceBroker to search similar message Loading @@ -796,7 +794,6 @@ public class AudioDeviceBroker { mProfile = profile; mEventSource = ""; mMusicDevice = AudioSystem.DEVICE_NONE; mCodec = AudioSystem.AUDIO_FORMAT_DEFAULT; mAudioSystemDevice = 0; mState = 0; mSupprNoisy = false; Loading @@ -811,7 +808,6 @@ public class AudioDeviceBroker { mProfile = profile; mEventSource = ""; mMusicDevice = musicDevice; mCodec = AudioSystem.AUDIO_FORMAT_DEFAULT; mAudioSystemDevice = audioSystemDevice; mState = state; mSupprNoisy = false; Loading @@ -829,7 +825,6 @@ public class AudioDeviceBroker { mEventSource = src.mEventSource; mAudioSystemDevice = src.mAudioSystemDevice; mMusicDevice = src.mMusicDevice; mCodec = src.mCodec; } // redefine equality op so we can match messages intended for this device Loading @@ -847,6 +842,19 @@ public class AudioDeviceBroker { } return false; } @Override public String toString() { return "BtDeviceInfo: device=" + mDevice.toString() + " state=" + mState + " prof=" + mProfile + " supprNoisy=" + mSupprNoisy + " volume=" + mVolume + " isLeOutput=" + mIsLeOutput + " eventSource=" + mEventSource + " audioSystemDevice=" + mAudioSystemDevice + " musicDevice=" + mMusicDevice; } } BtDeviceInfo createBtDeviceInfo(@NonNull BtDeviceChangedData d, @NonNull BluetoothDevice device, Loading @@ -859,9 +867,6 @@ public class AudioDeviceBroker { break; case BluetoothProfile.A2DP: audioDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP; synchronized (mDeviceStateLock) { codec = mBtHelper.getA2dpCodec(device); } break; case BluetoothProfile.HEARING_AID: audioDevice = AudioSystem.DEVICE_OUT_HEARING_AID; Loading Loading @@ -1696,8 +1701,11 @@ public class AudioDeviceBroker { case MSG_L_SET_BT_ACTIVE_DEVICE: synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { BtDeviceInfo btInfo = (BtDeviceInfo) msg.obj; mDeviceInventory.onSetBtActiveDevice(btInfo, final BtDeviceInfo btInfo = (BtDeviceInfo) msg.obj; @AudioSystem.AudioFormatNativeEnumForBtCodec final int codec = mBtHelper.getA2dpCodecWithFallbackToSBC( btInfo.mDevice, "MSG_L_SET_BT_ACTIVE_DEVICE"); mDeviceInventory.onSetBtActiveDevice(btInfo, codec, (btInfo.mProfile != BluetoothProfile.LE_AUDIO || btInfo.mIsLeOutput) ? mAudioService.getBluetoothContextualVolumeStream() Loading Loading @@ -1730,12 +1738,16 @@ public class AudioDeviceBroker { (String) msg.obj, msg.arg1); } break; case MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE: case MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE: { final BtDeviceInfo btInfo = (BtDeviceInfo) msg.obj; synchronized (mDeviceStateLock) { @AudioSystem.AudioFormatNativeEnumForBtCodec final int codec = mBtHelper.getA2dpCodecWithFallbackToSBC( btInfo.mDevice, "MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE"); mDeviceInventory.onBluetoothDeviceConfigChange( (BtDeviceInfo) msg.obj, BtHelper.EVENT_DEVICE_CONFIG_CHANGE); btInfo, codec, BtHelper.EVENT_DEVICE_CONFIG_CHANGE); } break; } break; case MSG_BROADCAST_AUDIO_BECOMING_NOISY: onSendBecomingNoisyIntent(); break; Loading Loading @@ -1831,20 +1843,12 @@ public class AudioDeviceBroker { } break; case MSG_L_BT_ACTIVE_DEVICE_CHANGE_EXT: { final BtDeviceInfo info = (BtDeviceInfo) msg.obj; if (info.mDevice == null) break; final BtDeviceInfo btInfo = (BtDeviceInfo) msg.obj; if (btInfo.mDevice == null) break; AudioService.sDeviceLogger.enqueue((new EventLogger.StringEvent( "msg: onBluetoothActiveDeviceChange " + " state=" + info.mState // only querying address as this is the only readily available // field on the device + " addr=" + info.mDevice.getAddress() + " prof=" + info.mProfile + " supprNoisy=" + info.mSupprNoisy + " src=" + info.mEventSource )).printLog(TAG)); "msg: onBluetoothActiveDeviceChange " + btInfo)).printLog(TAG)); synchronized (mDeviceStateLock) { mDeviceInventory.setBluetoothActiveDevice(info); mDeviceInventory.setBluetoothActiveDevice(btInfo); } } break; case MSG_IL_SAVE_PREF_DEVICES_FOR_STRATEGY: { Loading services/core/java/com/android/server/audio/AudioDeviceInventory.java +31 −38 Original line number Diff line number Diff line Loading @@ -503,9 +503,11 @@ public class AudioDeviceInventory { } } // @GuardedBy("AudioDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.mDeviceStateLock") void onSetBtActiveDevice(@NonNull AudioDeviceBroker.BtDeviceInfo btInfo, int streamType) { // @GuardedBy("mDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") void onSetBtActiveDevice(@NonNull AudioDeviceBroker.BtDeviceInfo btInfo, @AudioSystem.AudioFormatNativeEnumForBtCodec int codec, int streamType) { if (AudioService.DEBUG_DEVICES) { Log.d(TAG, "onSetBtActiveDevice" + " btDevice=" + btInfo.mDevice Loading @@ -518,10 +520,7 @@ public class AudioDeviceInventory { } AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent("BT connected:" + " addr=" + address + " profile=" + btInfo.mProfile + " state=" + btInfo.mState + " codec=" + AudioSystem.audioFormatToString(btInfo.mCodec))); + btInfo + " codec=" + AudioSystem.audioFormatToString(codec))); new MediaMetrics.Item(mMetricsId + "onSetBtActiveDevice") .set(MediaMetrics.Property.STATUS, btInfo.mProfile) Loading @@ -529,7 +528,7 @@ public class AudioDeviceInventory { AudioSystem.getDeviceName(btInfo.mAudioSystemDevice)) .set(MediaMetrics.Property.ADDRESS, address) .set(MediaMetrics.Property.ENCODING, AudioSystem.audioFormatToString(btInfo.mCodec)) AudioSystem.audioFormatToString(codec)) .set(MediaMetrics.Property.EVENT, "onSetBtActiveDevice") .set(MediaMetrics.Property.STREAM_TYPE, AudioSystem.streamToString(streamType)) Loading Loading @@ -568,7 +567,7 @@ public class AudioDeviceInventory { btInfo.mVolume * 10, btInfo.mAudioSystemDevice, "onSetBtActiveDevice"); } makeA2dpDeviceAvailable(btInfo, "onSetBtActiveDevice"); makeA2dpDeviceAvailable(btInfo, codec, "onSetBtActiveDevice"); } break; case BluetoothProfile.HEARING_AID: Loading @@ -594,9 +593,10 @@ public class AudioDeviceInventory { } @GuardedBy("AudioDeviceBroker.mDeviceStateLock") @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") /*package*/ void onBluetoothDeviceConfigChange( @NonNull AudioDeviceBroker.BtDeviceInfo btInfo, int event) { @NonNull AudioDeviceBroker.BtDeviceInfo btInfo, @AudioSystem.AudioFormatNativeEnumForBtCodec int codec, int event) { MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "onBluetoothDeviceConfigChange") .set(MediaMetrics.Property.EVENT, BtHelper.deviceEventToString(event)); Loading @@ -610,7 +610,6 @@ public class AudioDeviceInventory { Log.d(TAG, "onBluetoothDeviceConfigChange btDevice=" + btDevice); } int volume = btInfo.mVolume; @AudioSystem.AudioFormatNativeEnumForBtCodec final int audioCodec = btInfo.mCodec; String address = btDevice.getAddress(); if (!BluetoothAdapter.checkBluetoothAddress(address)) { Loading Loading @@ -639,8 +638,7 @@ public class AudioDeviceInventory { } mmi.set(MediaMetrics.Property.ADDRESS, address) .set(MediaMetrics.Property.ENCODING, AudioSystem.audioFormatToString(audioCodec)) .set(MediaMetrics.Property.ENCODING, AudioSystem.audioFormatToString(codec)) .set(MediaMetrics.Property.INDEX, volume) .set(MediaMetrics.Property.NAME, di.mDeviceName); Loading @@ -648,20 +646,19 @@ public class AudioDeviceInventory { if (event == BtHelper.EVENT_DEVICE_CONFIG_CHANGE) { boolean a2dpCodecChange = false; if (btInfo.mProfile == BluetoothProfile.A2DP) { if (di.mDeviceCodecFormat != audioCodec) { di.mDeviceCodecFormat = audioCodec; if (di.mDeviceCodecFormat != codec) { di.mDeviceCodecFormat = codec; mConnectedDevices.replace(key, di); a2dpCodecChange = true; } final int res = mAudioSystem.handleDeviceConfigChange( btInfo.mAudioSystemDevice, address, BtHelper.getName(btDevice), audioCodec); btInfo.mAudioSystemDevice, address, BtHelper.getName(btDevice), codec); if (res != AudioSystem.AUDIO_STATUS_OK) { AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent( "APM handleDeviceConfigChange failed for A2DP device addr=" + address + " codec=" + AudioSystem.audioFormatToString(audioCodec)) + AudioSystem.audioFormatToString(codec)) .printLog(TAG)); // force A2DP device disconnection in case of error so that AudioService Loading @@ -672,7 +669,7 @@ public class AudioDeviceInventory { AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent( "APM handleDeviceConfigChange success for A2DP device addr=" + address + " codec=" + AudioSystem.audioFormatToString(audioCodec)) + " codec=" + AudioSystem.audioFormatToString(codec)) .printLog(TAG)); } Loading Loading @@ -1338,7 +1335,7 @@ public class AudioDeviceInventory { * @param device the device whose connection state is queried * @return true if connected */ // called with AudioDeviceBroker.mDeviceStateLock lock held @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") public boolean isDeviceConnected(@NonNull AudioDeviceAttributes device) { final String key = DeviceInfo.makeDeviceListKey(device.getInternalType(), device.getAddress()); Loading Loading @@ -1489,7 +1486,7 @@ public class AudioDeviceInventory { } } @GuardedBy("AudioDeviceBroker.mDeviceStateLock") @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") /*package*/ void onBtProfileDisconnected(int profile) { switch (profile) { case BluetoothProfile.HEADSET: Loading Loading @@ -1554,7 +1551,7 @@ public class AudioDeviceInventory { disconnectLeAudio(AudioSystem.DEVICE_OUT_BLE_BROADCAST); } @GuardedBy("AudioDeviceBroker.mDeviceStateLock") @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") private void disconnectHeadset() { boolean disconnect = false; synchronized (mDevicesLock) { Loading Loading @@ -1594,9 +1591,10 @@ public class AudioDeviceInventory { return mCurAudioRoutes; } // only public for mocking/spying @GuardedBy("AudioDeviceBroker.mDeviceStateLock") @VisibleForTesting /** * Set a Bluetooth device to active. */ @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") public int setBluetoothActiveDevice(@NonNull AudioDeviceBroker.BtDeviceInfo info) { int delay; synchronized (mDevicesLock) { Loading @@ -1617,12 +1615,7 @@ public class AudioDeviceInventory { } if (AudioService.DEBUG_DEVICES) { Log.i(TAG, "setBluetoothActiveDevice device: " + info.mDevice + " profile: " + BluetoothProfile.getProfileName(info.mProfile) + " state: " + BluetoothProfile.getConnectionStateName(info.mState) + " delay(ms): " + delay + " codec:" + Integer.toHexString(info.mCodec) + " suppressNoisyIntent: " + info.mSupprNoisy); Log.i(TAG, "setBluetoothActiveDevice " + info.toString() + " delay(ms): " + delay); } mDeviceBroker.postBluetoothActiveDevice(info, delay); if (info.mProfile == BluetoothProfile.HEARING_AID Loading Loading @@ -1658,10 +1651,10 @@ public class AudioDeviceInventory { @GuardedBy("mDevicesLock") private void makeA2dpDeviceAvailable(AudioDeviceBroker.BtDeviceInfo btInfo, @AudioSystem.AudioFormatNativeEnumForBtCodec int codec, String eventSource) { final String address = btInfo.mDevice.getAddress(); final String name = BtHelper.getName(btInfo.mDevice); final int a2dpCodec = btInfo.mCodec; // enable A2DP before notifying A2DP connection to avoid unnecessary processing in // audio policy manager Loading @@ -1671,7 +1664,7 @@ public class AudioDeviceInventory { AudioDeviceAttributes ada = new AudioDeviceAttributes( AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address, name); final int res = mAudioSystem.setDeviceConnectionState(ada, AudioSystem.DEVICE_STATE_AVAILABLE, a2dpCodec); AudioSystem.DEVICE_STATE_AVAILABLE, codec); // TODO: log in MediaMetrics once distinction between connection failure and // double connection is made. Loading @@ -1694,7 +1687,7 @@ public class AudioDeviceInventory { // time_low = 0, time_mid = 0, time_hi = 0, clock_seq = 0, node = MAC Address UUID sensorUuid = UuidUtils.uuidFromAudioDeviceAttributes(ada); final DeviceInfo di = new DeviceInfo(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, name, address, a2dpCodec, sensorUuid); address, codec, sensorUuid); final String diKey = di.getKey(); mConnectedDevices.put(diKey, di); // on a connection always overwrite the device seen by AudioPolicy, see comment above when Loading Loading @@ -1910,9 +1903,9 @@ public class AudioDeviceInventory { } @GuardedBy("mDevicesLock") private void makeA2dpDeviceUnavailableNow(String address, int a2dpCodec) { private void makeA2dpDeviceUnavailableNow(String address, int codec) { MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "a2dp." + address) .set(MediaMetrics.Property.ENCODING, AudioSystem.audioFormatToString(a2dpCodec)) .set(MediaMetrics.Property.ENCODING, AudioSystem.audioFormatToString(codec)) .set(MediaMetrics.Property.EVENT, "makeA2dpDeviceUnavailableNow"); if (address == null) { Loading @@ -1939,7 +1932,7 @@ public class AudioDeviceInventory { AudioDeviceAttributes ada = new AudioDeviceAttributes( AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address); final int res = mAudioSystem.setDeviceConnectionState(ada, AudioSystem.DEVICE_STATE_UNAVAILABLE, a2dpCodec); AudioSystem.DEVICE_STATE_UNAVAILABLE, codec); if (res != AudioSystem.AUDIO_STATUS_OK) { AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent( Loading services/core/java/com/android/server/audio/BtHelper.java +34 −20 Original line number Diff line number Diff line Loading @@ -173,8 +173,8 @@ public class BtHelper { //---------------------------------------------------------------------- // Interface for AudioDeviceBroker // @GuardedBy("AudioDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.mDeviceStateLock") // @GuardedBy("mDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") /*package*/ synchronized void onSystemReady() { mScoConnectionState = android.media.AudioManager.SCO_AUDIO_STATE_ERROR; resetBluetoothSco(); Loading Loading @@ -263,8 +263,20 @@ public class BtHelper { return AudioSystem.bluetoothCodecToAudioFormat(btCodecConfig.getCodecType()); } // @GuardedBy("AudioDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.mDeviceStateLock") /*package*/ synchronized @AudioSystem.AudioFormatNativeEnumForBtCodec int getA2dpCodecWithFallbackToSBC( @NonNull BluetoothDevice device, @NonNull String source) { @AudioSystem.AudioFormatNativeEnumForBtCodec int codec = getA2dpCodec(device); if (codec == AudioSystem.AUDIO_FORMAT_DEFAULT) { AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent( "getA2dpCodec DEFAULT from " + source + " fallback to SBC")); return AudioSystem.AUDIO_FORMAT_SBC; } return codec; } // @GuardedBy("mDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") /*package*/ synchronized void onReceiveBtEvent(Intent intent) { final String action = intent.getAction(); Loading @@ -283,8 +295,8 @@ public class BtHelper { * Exclusively called from AudioDeviceBroker when handling MSG_L_RECEIVED_BT_EVENT * as part of the serialization of the communication route selection */ // @GuardedBy("AudioDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.mDeviceStateLock") // @GuardedBy("mDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") private void onScoAudioStateChanged(int state) { boolean broadcast = false; int scoAudioState = AudioManager.SCO_AUDIO_STATE_ERROR; Loading Loading @@ -355,16 +367,16 @@ public class BtHelper { == BluetoothHeadset.STATE_AUDIO_CONNECTED; } // @GuardedBy("AudioDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.mDeviceStateLock") // @GuardedBy("mDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") /*package*/ synchronized boolean startBluetoothSco(int scoAudioMode, @NonNull String eventSource) { AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(eventSource)); return requestScoState(BluetoothHeadset.STATE_AUDIO_CONNECTED, scoAudioMode); } // @GuardedBy("AudioDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.mDeviceStateLock") // @GuardedBy("mDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") /*package*/ synchronized boolean stopBluetoothSco(@NonNull String eventSource) { AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(eventSource)); return requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED, SCO_MODE_VIRTUAL_CALL); Loading Loading @@ -435,8 +447,8 @@ public class BtHelper { mScoConnectionState = state; } // @GuardedBy("AudioDeviceBroker.mSetModeLock") //@GuardedBy("AudioDeviceBroker.mDeviceStateLock") // @GuardedBy("mDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") /*package*/ synchronized void resetBluetoothSco() { mScoAudioState = SCO_STATE_INACTIVE; broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED); Loading @@ -445,7 +457,8 @@ public class BtHelper { mDeviceBroker.setBluetoothScoOn(false, "resetBluetoothSco"); } //@GuardedBy("AudioDeviceBroker.mDeviceStateLock") // @GuardedBy("mDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") /*package*/ synchronized void onBtProfileDisconnected(int profile) { AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent( "BT profile " + BluetoothProfile.getProfileName(profile) + " disconnected")); Loading Loading @@ -474,7 +487,8 @@ public class BtHelper { } } @GuardedBy("AudioDeviceBroker.mDeviceStateLock") // @GuardedBy("mDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") /*package*/ synchronized void onBtProfileConnected(int profile, BluetoothProfile proxy) { AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent( "BT profile " + BluetoothProfile.getProfileName(profile) + " connected to proxy " Loading Loading @@ -522,8 +536,8 @@ public class BtHelper { } } // @GuardedBy("AudioDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.mDeviceStateLock") // @GuardedBy("mDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") private void onHeadsetProfileConnected(BluetoothHeadset headset) { // Discard timeout message mDeviceBroker.handleCancelFailureToConnectToBtHeadsetService(); Loading Loading @@ -642,8 +656,8 @@ public class BtHelper { return btDevice == null ? "(null)" : btDevice.getAnonymizedAddress(); } // @GuardedBy("AudioDeviceBroker.mSetModeLock") //@GuardedBy("AudioDeviceBroker.mDeviceStateLock") // @GuardedBy("mDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") /*package */ synchronized void onSetBtScoActiveDevice(BluetoothDevice btDevice) { Log.i(TAG, "onSetBtScoActiveDevice: " + getAnonymizedAddress(mBluetoothHeadsetDevice) + " -> " + getAnonymizedAddress(btDevice)); Loading Loading @@ -712,8 +726,8 @@ public class BtHelper { //---------------------------------------------------------------------- // @GuardedBy("AudioDeviceBroker.mSetModeLock") //@GuardedBy("AudioDeviceBroker.mDeviceStateLock") // @GuardedBy("mDeviceBroker.mSetModeLock") // @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") @GuardedBy("BtHelper.this") private boolean requestScoState(int state, int scoAudioMode) { checkScoAudioState(); Loading services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java +2 −1 Original line number Diff line number Diff line Loading @@ -261,7 +261,8 @@ public class AudioDeviceBrokerTest { // Verify disconnection has been cancelled and we're seeing two connections attempts, // with the device connected at the end of the test verify(mSpyDevInventory, times(2)).onSetBtActiveDevice( any(AudioDeviceBroker.BtDeviceInfo.class), anyInt()); any(AudioDeviceBroker.BtDeviceInfo.class), anyInt() /*codec*/, anyInt() /*streamType*/); Assert.assertTrue("Mock device not connected", mSpyDevInventory.isA2dpDeviceConnected(mFakeBtDevice)); Loading Loading
services/core/java/com/android/server/audio/AudioDeviceBroker.java +29 −25 Original line number Diff line number Diff line Loading @@ -772,7 +772,6 @@ public class AudioDeviceBroker { final int mVolume; final boolean mIsLeOutput; final @NonNull String mEventSource; final @AudioSystem.AudioFormatNativeEnumForBtCodec int mCodec; final int mAudioSystemDevice; final int mMusicDevice; Loading @@ -787,7 +786,6 @@ public class AudioDeviceBroker { mEventSource = d.mEventSource; mAudioSystemDevice = audioDevice; mMusicDevice = AudioSystem.DEVICE_NONE; mCodec = codec; } // constructor used by AudioDeviceBroker to search similar message Loading @@ -796,7 +794,6 @@ public class AudioDeviceBroker { mProfile = profile; mEventSource = ""; mMusicDevice = AudioSystem.DEVICE_NONE; mCodec = AudioSystem.AUDIO_FORMAT_DEFAULT; mAudioSystemDevice = 0; mState = 0; mSupprNoisy = false; Loading @@ -811,7 +808,6 @@ public class AudioDeviceBroker { mProfile = profile; mEventSource = ""; mMusicDevice = musicDevice; mCodec = AudioSystem.AUDIO_FORMAT_DEFAULT; mAudioSystemDevice = audioSystemDevice; mState = state; mSupprNoisy = false; Loading @@ -829,7 +825,6 @@ public class AudioDeviceBroker { mEventSource = src.mEventSource; mAudioSystemDevice = src.mAudioSystemDevice; mMusicDevice = src.mMusicDevice; mCodec = src.mCodec; } // redefine equality op so we can match messages intended for this device Loading @@ -847,6 +842,19 @@ public class AudioDeviceBroker { } return false; } @Override public String toString() { return "BtDeviceInfo: device=" + mDevice.toString() + " state=" + mState + " prof=" + mProfile + " supprNoisy=" + mSupprNoisy + " volume=" + mVolume + " isLeOutput=" + mIsLeOutput + " eventSource=" + mEventSource + " audioSystemDevice=" + mAudioSystemDevice + " musicDevice=" + mMusicDevice; } } BtDeviceInfo createBtDeviceInfo(@NonNull BtDeviceChangedData d, @NonNull BluetoothDevice device, Loading @@ -859,9 +867,6 @@ public class AudioDeviceBroker { break; case BluetoothProfile.A2DP: audioDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP; synchronized (mDeviceStateLock) { codec = mBtHelper.getA2dpCodec(device); } break; case BluetoothProfile.HEARING_AID: audioDevice = AudioSystem.DEVICE_OUT_HEARING_AID; Loading Loading @@ -1696,8 +1701,11 @@ public class AudioDeviceBroker { case MSG_L_SET_BT_ACTIVE_DEVICE: synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { BtDeviceInfo btInfo = (BtDeviceInfo) msg.obj; mDeviceInventory.onSetBtActiveDevice(btInfo, final BtDeviceInfo btInfo = (BtDeviceInfo) msg.obj; @AudioSystem.AudioFormatNativeEnumForBtCodec final int codec = mBtHelper.getA2dpCodecWithFallbackToSBC( btInfo.mDevice, "MSG_L_SET_BT_ACTIVE_DEVICE"); mDeviceInventory.onSetBtActiveDevice(btInfo, codec, (btInfo.mProfile != BluetoothProfile.LE_AUDIO || btInfo.mIsLeOutput) ? mAudioService.getBluetoothContextualVolumeStream() Loading Loading @@ -1730,12 +1738,16 @@ public class AudioDeviceBroker { (String) msg.obj, msg.arg1); } break; case MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE: case MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE: { final BtDeviceInfo btInfo = (BtDeviceInfo) msg.obj; synchronized (mDeviceStateLock) { @AudioSystem.AudioFormatNativeEnumForBtCodec final int codec = mBtHelper.getA2dpCodecWithFallbackToSBC( btInfo.mDevice, "MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE"); mDeviceInventory.onBluetoothDeviceConfigChange( (BtDeviceInfo) msg.obj, BtHelper.EVENT_DEVICE_CONFIG_CHANGE); btInfo, codec, BtHelper.EVENT_DEVICE_CONFIG_CHANGE); } break; } break; case MSG_BROADCAST_AUDIO_BECOMING_NOISY: onSendBecomingNoisyIntent(); break; Loading Loading @@ -1831,20 +1843,12 @@ public class AudioDeviceBroker { } break; case MSG_L_BT_ACTIVE_DEVICE_CHANGE_EXT: { final BtDeviceInfo info = (BtDeviceInfo) msg.obj; if (info.mDevice == null) break; final BtDeviceInfo btInfo = (BtDeviceInfo) msg.obj; if (btInfo.mDevice == null) break; AudioService.sDeviceLogger.enqueue((new EventLogger.StringEvent( "msg: onBluetoothActiveDeviceChange " + " state=" + info.mState // only querying address as this is the only readily available // field on the device + " addr=" + info.mDevice.getAddress() + " prof=" + info.mProfile + " supprNoisy=" + info.mSupprNoisy + " src=" + info.mEventSource )).printLog(TAG)); "msg: onBluetoothActiveDeviceChange " + btInfo)).printLog(TAG)); synchronized (mDeviceStateLock) { mDeviceInventory.setBluetoothActiveDevice(info); mDeviceInventory.setBluetoothActiveDevice(btInfo); } } break; case MSG_IL_SAVE_PREF_DEVICES_FOR_STRATEGY: { Loading
services/core/java/com/android/server/audio/AudioDeviceInventory.java +31 −38 Original line number Diff line number Diff line Loading @@ -503,9 +503,11 @@ public class AudioDeviceInventory { } } // @GuardedBy("AudioDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.mDeviceStateLock") void onSetBtActiveDevice(@NonNull AudioDeviceBroker.BtDeviceInfo btInfo, int streamType) { // @GuardedBy("mDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") void onSetBtActiveDevice(@NonNull AudioDeviceBroker.BtDeviceInfo btInfo, @AudioSystem.AudioFormatNativeEnumForBtCodec int codec, int streamType) { if (AudioService.DEBUG_DEVICES) { Log.d(TAG, "onSetBtActiveDevice" + " btDevice=" + btInfo.mDevice Loading @@ -518,10 +520,7 @@ public class AudioDeviceInventory { } AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent("BT connected:" + " addr=" + address + " profile=" + btInfo.mProfile + " state=" + btInfo.mState + " codec=" + AudioSystem.audioFormatToString(btInfo.mCodec))); + btInfo + " codec=" + AudioSystem.audioFormatToString(codec))); new MediaMetrics.Item(mMetricsId + "onSetBtActiveDevice") .set(MediaMetrics.Property.STATUS, btInfo.mProfile) Loading @@ -529,7 +528,7 @@ public class AudioDeviceInventory { AudioSystem.getDeviceName(btInfo.mAudioSystemDevice)) .set(MediaMetrics.Property.ADDRESS, address) .set(MediaMetrics.Property.ENCODING, AudioSystem.audioFormatToString(btInfo.mCodec)) AudioSystem.audioFormatToString(codec)) .set(MediaMetrics.Property.EVENT, "onSetBtActiveDevice") .set(MediaMetrics.Property.STREAM_TYPE, AudioSystem.streamToString(streamType)) Loading Loading @@ -568,7 +567,7 @@ public class AudioDeviceInventory { btInfo.mVolume * 10, btInfo.mAudioSystemDevice, "onSetBtActiveDevice"); } makeA2dpDeviceAvailable(btInfo, "onSetBtActiveDevice"); makeA2dpDeviceAvailable(btInfo, codec, "onSetBtActiveDevice"); } break; case BluetoothProfile.HEARING_AID: Loading @@ -594,9 +593,10 @@ public class AudioDeviceInventory { } @GuardedBy("AudioDeviceBroker.mDeviceStateLock") @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") /*package*/ void onBluetoothDeviceConfigChange( @NonNull AudioDeviceBroker.BtDeviceInfo btInfo, int event) { @NonNull AudioDeviceBroker.BtDeviceInfo btInfo, @AudioSystem.AudioFormatNativeEnumForBtCodec int codec, int event) { MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "onBluetoothDeviceConfigChange") .set(MediaMetrics.Property.EVENT, BtHelper.deviceEventToString(event)); Loading @@ -610,7 +610,6 @@ public class AudioDeviceInventory { Log.d(TAG, "onBluetoothDeviceConfigChange btDevice=" + btDevice); } int volume = btInfo.mVolume; @AudioSystem.AudioFormatNativeEnumForBtCodec final int audioCodec = btInfo.mCodec; String address = btDevice.getAddress(); if (!BluetoothAdapter.checkBluetoothAddress(address)) { Loading Loading @@ -639,8 +638,7 @@ public class AudioDeviceInventory { } mmi.set(MediaMetrics.Property.ADDRESS, address) .set(MediaMetrics.Property.ENCODING, AudioSystem.audioFormatToString(audioCodec)) .set(MediaMetrics.Property.ENCODING, AudioSystem.audioFormatToString(codec)) .set(MediaMetrics.Property.INDEX, volume) .set(MediaMetrics.Property.NAME, di.mDeviceName); Loading @@ -648,20 +646,19 @@ public class AudioDeviceInventory { if (event == BtHelper.EVENT_DEVICE_CONFIG_CHANGE) { boolean a2dpCodecChange = false; if (btInfo.mProfile == BluetoothProfile.A2DP) { if (di.mDeviceCodecFormat != audioCodec) { di.mDeviceCodecFormat = audioCodec; if (di.mDeviceCodecFormat != codec) { di.mDeviceCodecFormat = codec; mConnectedDevices.replace(key, di); a2dpCodecChange = true; } final int res = mAudioSystem.handleDeviceConfigChange( btInfo.mAudioSystemDevice, address, BtHelper.getName(btDevice), audioCodec); btInfo.mAudioSystemDevice, address, BtHelper.getName(btDevice), codec); if (res != AudioSystem.AUDIO_STATUS_OK) { AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent( "APM handleDeviceConfigChange failed for A2DP device addr=" + address + " codec=" + AudioSystem.audioFormatToString(audioCodec)) + AudioSystem.audioFormatToString(codec)) .printLog(TAG)); // force A2DP device disconnection in case of error so that AudioService Loading @@ -672,7 +669,7 @@ public class AudioDeviceInventory { AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent( "APM handleDeviceConfigChange success for A2DP device addr=" + address + " codec=" + AudioSystem.audioFormatToString(audioCodec)) + " codec=" + AudioSystem.audioFormatToString(codec)) .printLog(TAG)); } Loading Loading @@ -1338,7 +1335,7 @@ public class AudioDeviceInventory { * @param device the device whose connection state is queried * @return true if connected */ // called with AudioDeviceBroker.mDeviceStateLock lock held @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") public boolean isDeviceConnected(@NonNull AudioDeviceAttributes device) { final String key = DeviceInfo.makeDeviceListKey(device.getInternalType(), device.getAddress()); Loading Loading @@ -1489,7 +1486,7 @@ public class AudioDeviceInventory { } } @GuardedBy("AudioDeviceBroker.mDeviceStateLock") @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") /*package*/ void onBtProfileDisconnected(int profile) { switch (profile) { case BluetoothProfile.HEADSET: Loading Loading @@ -1554,7 +1551,7 @@ public class AudioDeviceInventory { disconnectLeAudio(AudioSystem.DEVICE_OUT_BLE_BROADCAST); } @GuardedBy("AudioDeviceBroker.mDeviceStateLock") @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") private void disconnectHeadset() { boolean disconnect = false; synchronized (mDevicesLock) { Loading Loading @@ -1594,9 +1591,10 @@ public class AudioDeviceInventory { return mCurAudioRoutes; } // only public for mocking/spying @GuardedBy("AudioDeviceBroker.mDeviceStateLock") @VisibleForTesting /** * Set a Bluetooth device to active. */ @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") public int setBluetoothActiveDevice(@NonNull AudioDeviceBroker.BtDeviceInfo info) { int delay; synchronized (mDevicesLock) { Loading @@ -1617,12 +1615,7 @@ public class AudioDeviceInventory { } if (AudioService.DEBUG_DEVICES) { Log.i(TAG, "setBluetoothActiveDevice device: " + info.mDevice + " profile: " + BluetoothProfile.getProfileName(info.mProfile) + " state: " + BluetoothProfile.getConnectionStateName(info.mState) + " delay(ms): " + delay + " codec:" + Integer.toHexString(info.mCodec) + " suppressNoisyIntent: " + info.mSupprNoisy); Log.i(TAG, "setBluetoothActiveDevice " + info.toString() + " delay(ms): " + delay); } mDeviceBroker.postBluetoothActiveDevice(info, delay); if (info.mProfile == BluetoothProfile.HEARING_AID Loading Loading @@ -1658,10 +1651,10 @@ public class AudioDeviceInventory { @GuardedBy("mDevicesLock") private void makeA2dpDeviceAvailable(AudioDeviceBroker.BtDeviceInfo btInfo, @AudioSystem.AudioFormatNativeEnumForBtCodec int codec, String eventSource) { final String address = btInfo.mDevice.getAddress(); final String name = BtHelper.getName(btInfo.mDevice); final int a2dpCodec = btInfo.mCodec; // enable A2DP before notifying A2DP connection to avoid unnecessary processing in // audio policy manager Loading @@ -1671,7 +1664,7 @@ public class AudioDeviceInventory { AudioDeviceAttributes ada = new AudioDeviceAttributes( AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address, name); final int res = mAudioSystem.setDeviceConnectionState(ada, AudioSystem.DEVICE_STATE_AVAILABLE, a2dpCodec); AudioSystem.DEVICE_STATE_AVAILABLE, codec); // TODO: log in MediaMetrics once distinction between connection failure and // double connection is made. Loading @@ -1694,7 +1687,7 @@ public class AudioDeviceInventory { // time_low = 0, time_mid = 0, time_hi = 0, clock_seq = 0, node = MAC Address UUID sensorUuid = UuidUtils.uuidFromAudioDeviceAttributes(ada); final DeviceInfo di = new DeviceInfo(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, name, address, a2dpCodec, sensorUuid); address, codec, sensorUuid); final String diKey = di.getKey(); mConnectedDevices.put(diKey, di); // on a connection always overwrite the device seen by AudioPolicy, see comment above when Loading Loading @@ -1910,9 +1903,9 @@ public class AudioDeviceInventory { } @GuardedBy("mDevicesLock") private void makeA2dpDeviceUnavailableNow(String address, int a2dpCodec) { private void makeA2dpDeviceUnavailableNow(String address, int codec) { MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "a2dp." + address) .set(MediaMetrics.Property.ENCODING, AudioSystem.audioFormatToString(a2dpCodec)) .set(MediaMetrics.Property.ENCODING, AudioSystem.audioFormatToString(codec)) .set(MediaMetrics.Property.EVENT, "makeA2dpDeviceUnavailableNow"); if (address == null) { Loading @@ -1939,7 +1932,7 @@ public class AudioDeviceInventory { AudioDeviceAttributes ada = new AudioDeviceAttributes( AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address); final int res = mAudioSystem.setDeviceConnectionState(ada, AudioSystem.DEVICE_STATE_UNAVAILABLE, a2dpCodec); AudioSystem.DEVICE_STATE_UNAVAILABLE, codec); if (res != AudioSystem.AUDIO_STATUS_OK) { AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent( Loading
services/core/java/com/android/server/audio/BtHelper.java +34 −20 Original line number Diff line number Diff line Loading @@ -173,8 +173,8 @@ public class BtHelper { //---------------------------------------------------------------------- // Interface for AudioDeviceBroker // @GuardedBy("AudioDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.mDeviceStateLock") // @GuardedBy("mDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") /*package*/ synchronized void onSystemReady() { mScoConnectionState = android.media.AudioManager.SCO_AUDIO_STATE_ERROR; resetBluetoothSco(); Loading Loading @@ -263,8 +263,20 @@ public class BtHelper { return AudioSystem.bluetoothCodecToAudioFormat(btCodecConfig.getCodecType()); } // @GuardedBy("AudioDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.mDeviceStateLock") /*package*/ synchronized @AudioSystem.AudioFormatNativeEnumForBtCodec int getA2dpCodecWithFallbackToSBC( @NonNull BluetoothDevice device, @NonNull String source) { @AudioSystem.AudioFormatNativeEnumForBtCodec int codec = getA2dpCodec(device); if (codec == AudioSystem.AUDIO_FORMAT_DEFAULT) { AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent( "getA2dpCodec DEFAULT from " + source + " fallback to SBC")); return AudioSystem.AUDIO_FORMAT_SBC; } return codec; } // @GuardedBy("mDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") /*package*/ synchronized void onReceiveBtEvent(Intent intent) { final String action = intent.getAction(); Loading @@ -283,8 +295,8 @@ public class BtHelper { * Exclusively called from AudioDeviceBroker when handling MSG_L_RECEIVED_BT_EVENT * as part of the serialization of the communication route selection */ // @GuardedBy("AudioDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.mDeviceStateLock") // @GuardedBy("mDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") private void onScoAudioStateChanged(int state) { boolean broadcast = false; int scoAudioState = AudioManager.SCO_AUDIO_STATE_ERROR; Loading Loading @@ -355,16 +367,16 @@ public class BtHelper { == BluetoothHeadset.STATE_AUDIO_CONNECTED; } // @GuardedBy("AudioDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.mDeviceStateLock") // @GuardedBy("mDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") /*package*/ synchronized boolean startBluetoothSco(int scoAudioMode, @NonNull String eventSource) { AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(eventSource)); return requestScoState(BluetoothHeadset.STATE_AUDIO_CONNECTED, scoAudioMode); } // @GuardedBy("AudioDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.mDeviceStateLock") // @GuardedBy("mDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") /*package*/ synchronized boolean stopBluetoothSco(@NonNull String eventSource) { AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(eventSource)); return requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED, SCO_MODE_VIRTUAL_CALL); Loading Loading @@ -435,8 +447,8 @@ public class BtHelper { mScoConnectionState = state; } // @GuardedBy("AudioDeviceBroker.mSetModeLock") //@GuardedBy("AudioDeviceBroker.mDeviceStateLock") // @GuardedBy("mDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") /*package*/ synchronized void resetBluetoothSco() { mScoAudioState = SCO_STATE_INACTIVE; broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED); Loading @@ -445,7 +457,8 @@ public class BtHelper { mDeviceBroker.setBluetoothScoOn(false, "resetBluetoothSco"); } //@GuardedBy("AudioDeviceBroker.mDeviceStateLock") // @GuardedBy("mDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") /*package*/ synchronized void onBtProfileDisconnected(int profile) { AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent( "BT profile " + BluetoothProfile.getProfileName(profile) + " disconnected")); Loading Loading @@ -474,7 +487,8 @@ public class BtHelper { } } @GuardedBy("AudioDeviceBroker.mDeviceStateLock") // @GuardedBy("mDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") /*package*/ synchronized void onBtProfileConnected(int profile, BluetoothProfile proxy) { AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent( "BT profile " + BluetoothProfile.getProfileName(profile) + " connected to proxy " Loading Loading @@ -522,8 +536,8 @@ public class BtHelper { } } // @GuardedBy("AudioDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.mDeviceStateLock") // @GuardedBy("mDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") private void onHeadsetProfileConnected(BluetoothHeadset headset) { // Discard timeout message mDeviceBroker.handleCancelFailureToConnectToBtHeadsetService(); Loading Loading @@ -642,8 +656,8 @@ public class BtHelper { return btDevice == null ? "(null)" : btDevice.getAnonymizedAddress(); } // @GuardedBy("AudioDeviceBroker.mSetModeLock") //@GuardedBy("AudioDeviceBroker.mDeviceStateLock") // @GuardedBy("mDeviceBroker.mSetModeLock") @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") /*package */ synchronized void onSetBtScoActiveDevice(BluetoothDevice btDevice) { Log.i(TAG, "onSetBtScoActiveDevice: " + getAnonymizedAddress(mBluetoothHeadsetDevice) + " -> " + getAnonymizedAddress(btDevice)); Loading Loading @@ -712,8 +726,8 @@ public class BtHelper { //---------------------------------------------------------------------- // @GuardedBy("AudioDeviceBroker.mSetModeLock") //@GuardedBy("AudioDeviceBroker.mDeviceStateLock") // @GuardedBy("mDeviceBroker.mSetModeLock") // @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock") @GuardedBy("BtHelper.this") private boolean requestScoState(int state, int scoAudioMode) { checkScoAudioState(); Loading
services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java +2 −1 Original line number Diff line number Diff line Loading @@ -261,7 +261,8 @@ public class AudioDeviceBrokerTest { // Verify disconnection has been cancelled and we're seeing two connections attempts, // with the device connected at the end of the test verify(mSpyDevInventory, times(2)).onSetBtActiveDevice( any(AudioDeviceBroker.BtDeviceInfo.class), anyInt()); any(AudioDeviceBroker.BtDeviceInfo.class), anyInt() /*codec*/, anyInt() /*streamType*/); Assert.assertTrue("Mock device not connected", mSpyDevInventory.isA2dpDeviceConnected(mFakeBtDevice)); Loading