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