Loading services/core/java/com/android/server/audio/AudioDeviceBroker.java +170 −105 Original line number Diff line number Diff line Loading @@ -15,6 +15,9 @@ */ package com.android.server.audio; import static com.android.server.audio.AudioService.CONNECTION_STATE_CONNECTED; import static com.android.server.audio.AudioService.CONNECTION_STATE_DISCONNECTED; import android.annotation.NonNull; import android.bluetooth.BluetoothA2dp; import android.bluetooth.BluetoothDevice; Loading Loading @@ -43,7 +46,7 @@ import java.util.ArrayList; /** @hide */ /*package*/ final class AudioDeviceBroker { private static final String TAG = "AudioDeviceBroker"; private static final String TAG = "AS.AudioDeviceBroker"; private static final long BROKER_WAKELOCK_TIMEOUT_MS = 5000; //5s Loading @@ -62,27 +65,27 @@ import java.util.ArrayList; private int mForcedUseForCommExt; // Manages all connected devices, only ever accessed on the message loop //### or make it synchronized private final AudioDeviceInventory mDeviceInventory; // Manages notifications to BT service private final BtHelper mBtHelper; //------------------------------------------------------------------- // we use a different lock than mDeviceStateLock so as not to create // lock contention between enqueueing a message and handling them private static final Object sLastDeviceConnectionMsgTimeLock = new Object(); @GuardedBy("sLastDeviceConnectionMsgTimeLock") private static long sLastDeviceConnectMsgTime = 0; private final Object mBluetoothA2dpEnabledLock = new Object(); // General lock to be taken whenever the state of the audio devices is to be checked or changed private final Object mDeviceStateLock = new Object(); // Request to override default use of A2DP for media. @GuardedBy("mBluetoothA2dpEnabledLock") @GuardedBy("mDeviceStateLock") private boolean mBluetoothA2dpEnabled; // lock always taken synchronized on mConnectedDevices /*package*/ final Object mA2dpAvrcpLock = new Object(); // lock always taken synchronized on mConnectedDevices /*package*/ final Object mHearingAidLock = new Object(); // lock always taken when accessing AudioService.mSetModeDeathHandlers // TODO do not "share" the lock between AudioService and BtHelpr, see b/123769055 /*package*/ final Object mSetModeLock = new Object(); //------------------------------------------------------------------- Loading @@ -109,13 +112,17 @@ import java.util.ArrayList; // All post* methods are asynchronous /*package*/ void onSystemReady() { synchronized (mDeviceStateLock) { mBtHelper.onSystemReady(); } } /*package*/ void onAudioServerDied() { // Restore forced usage for communications and record synchronized (mDeviceStateLock) { onSetForceUse(AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, "onAudioServerDied"); onSetForceUse(AudioSystem.FOR_RECORD, mForcedUseForComm, "onAudioServerDied"); } // restore devices sendMsgNoDelay(MSG_RESTORE_DEVICES, SENDMSG_REPLACE); } Loading @@ -130,8 +137,10 @@ import java.util.ArrayList; } /*package*/ void disconnectAllBluetoothProfiles() { synchronized (mDeviceStateLock) { mBtHelper.disconnectAllBluetoothProfiles(); } } /** * Handle BluetoothHeadset intents where the action is one of Loading @@ -140,11 +149,13 @@ import java.util.ArrayList; * @param intent */ /*package*/ void receiveBtEvent(@NonNull Intent intent) { synchronized (mDeviceStateLock) { mBtHelper.receiveBtEvent(intent); } } /*package*/ void setBluetoothA2dpOn_Async(boolean on, String source) { synchronized (mBluetoothA2dpEnabledLock) { synchronized (mDeviceStateLock) { if (mBluetoothA2dpEnabled == on) { return; } Loading @@ -158,6 +169,7 @@ import java.util.ArrayList; } /*package*/ void setSpeakerphoneOn(boolean on, String eventSource) { synchronized (mDeviceStateLock) { if (on) { if (mForcedUseForComm == AudioSystem.FORCE_BT_SCO) { setForceUse_Async(AudioSystem.FOR_RECORD, AudioSystem.FORCE_NONE, eventSource); Loading @@ -170,17 +182,22 @@ import java.util.ArrayList; mForcedUseForCommExt = mForcedUseForComm; setForceUse_Async(AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, eventSource); } } /*package*/ boolean isSpeakerphoneOn() { synchronized (mDeviceStateLock) { return (mForcedUseForCommExt == AudioSystem.FORCE_SPEAKER); } } /*package*/ void setWiredDeviceConnectionState(int type, @AudioService.ConnectionState int state, String address, String name, String caller) { //TODO move logging here just like in setBluetooth* methods synchronized (mDeviceStateLock) { mDeviceInventory.setWiredDeviceConnectionState(type, state, address, name, caller); } } /*package*/ int setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent( @NonNull BluetoothDevice device, @AudioService.BtProfileConnectionState int state, Loading @@ -192,6 +209,7 @@ import java.util.ArrayList; + " addr=" + device.getAddress() + " prof=" + profile + " supprNoisy=" + suppressNoisyIntent + " vol=" + a2dpVolume)).printLog(TAG)); synchronized (mDeviceStateLock) { if (mBrokerHandler.hasMessages(MSG_IL_SET_A2DP_SINK_CONNECTION_STATE, new BtHelper.BluetoothA2dpDeviceInfo(device))) { AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent( Loading @@ -199,16 +217,20 @@ import java.util.ArrayList; return 0; } return mDeviceInventory.setBluetoothA2dpDeviceConnectionState( device, state, profile, suppressNoisyIntent, AudioSystem.DEVICE_NONE, a2dpVolume); device, state, profile, suppressNoisyIntent, AudioSystem.DEVICE_NONE, a2dpVolume); } } /*package*/ int handleBluetoothA2dpActiveDeviceChange( @NonNull BluetoothDevice device, @AudioService.BtProfileConnectionState int state, int profile, boolean suppressNoisyIntent, int a2dpVolume) { synchronized (mDeviceStateLock) { return mDeviceInventory.handleBluetoothA2dpActiveDeviceChange(device, state, profile, suppressNoisyIntent, a2dpVolume); } } /*package*/ int setBluetoothHearingAidDeviceConnectionState( @NonNull BluetoothDevice device, @AudioService.BtProfileConnectionState int state, Loading @@ -218,21 +240,28 @@ import java.util.ArrayList; + " addr=" + device.getAddress() + " supprNoisy=" + suppressNoisyIntent + " src=" + eventSource)).printLog(TAG)); synchronized (mDeviceStateLock) { return mDeviceInventory.setBluetoothHearingAidDeviceConnectionState( device, state, suppressNoisyIntent, musicDevice); } } // never called by system components /*package*/ void setBluetoothScoOnByApp(boolean on) { synchronized (mDeviceStateLock) { mForcedUseForCommExt = on ? AudioSystem.FORCE_BT_SCO : AudioSystem.FORCE_NONE; } } /*package*/ boolean isBluetoothScoOnForApp() { synchronized (mDeviceStateLock) { return mForcedUseForCommExt == AudioSystem.FORCE_BT_SCO; } } /*package*/ void setBluetoothScoOn(boolean on, String eventSource) { //Log.i(TAG, "setBluetoothScoOnInt: " + on + " " + eventSource); synchronized (mDeviceStateLock) { if (on) { // do not accept SCO ON if SCO audio is not connected if (!mBtHelper.isBluetoothScoOn()) { Loading @@ -252,23 +281,28 @@ import java.util.ArrayList; // Un-mute ringtone stream volume mAudioService.setUpdateRingerModeServiceInt(); } } /*package*/ AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) { synchronized (mDeviceStateLock) { return mDeviceInventory.startWatchingRoutes(observer); } } /*package*/ AudioRoutesInfo getCurAudioRoutes() { synchronized (mDeviceStateLock) { return mDeviceInventory.getCurAudioRoutes(); } } /*package*/ boolean isAvrcpAbsoluteVolumeSupported() { synchronized (mA2dpAvrcpLock) { synchronized (mDeviceStateLock) { return mBtHelper.isAvrcpAbsoluteVolumeSupported(); } } /*package*/ boolean isBluetoothA2dpOn() { synchronized (mBluetoothA2dpEnabledLock) { synchronized (mDeviceStateLock) { return mBluetoothA2dpEnabled; } } Loading Loading @@ -355,14 +389,12 @@ import java.util.ArrayList; sendMsgNoDelay(MSG_BROADCAST_AUDIO_BECOMING_NOISY, SENDMSG_REPLACE); } //###TODO unify with handleSetA2dpSinkConnectionState /*package*/ void postA2dpSinkConnection(int state, @NonNull BtHelper.BluetoothA2dpDeviceInfo btDeviceInfo, int delay) { sendILMsg(MSG_IL_SET_A2DP_SINK_CONNECTION_STATE, SENDMSG_QUEUE, state, btDeviceInfo, delay); } //###TODO unify with handleSetA2dpSourceConnectionState /*package*/ void postA2dpSourceConnection(int state, @NonNull BtHelper.BluetoothA2dpDeviceInfo btDeviceInfo, int delay) { sendILMsg(MSG_IL_SET_A2DP_SOURCE_CONNECTION_STATE, SENDMSG_QUEUE, Loading Loading @@ -395,7 +427,7 @@ import java.util.ArrayList; .append(") from u/pid:").append(Binder.getCallingUid()).append("/") .append(Binder.getCallingPid()).append(" src:").append(source).toString(); synchronized (mBluetoothA2dpEnabledLock) { synchronized (mDeviceStateLock) { mBluetoothA2dpEnabled = on; mBrokerHandler.removeMessages(MSG_IIL_SET_FORCE_BT_A2DP_USE); onSetForceUse( Loading @@ -407,25 +439,38 @@ import java.util.ArrayList; /*package*/ boolean handleDeviceConnection(boolean connect, int device, String address, String deviceName) { synchronized (mDeviceStateLock) { return mDeviceInventory.handleDeviceConnection(connect, device, address, deviceName); } } /*package*/ void handleDisconnectA2dp() { synchronized (mDeviceStateLock) { mDeviceInventory.disconnectA2dp(); } } /*package*/ void handleDisconnectA2dpSink() { synchronized (mDeviceStateLock) { mDeviceInventory.disconnectA2dpSink(); } } /*package*/ void handleDisconnectHearingAid() { synchronized (mDeviceStateLock) { mDeviceInventory.disconnectHearingAid(); } } /*package*/ void handleSetA2dpSinkConnectionState(@BluetoothProfile.BtProfileState int state, @NonNull BtHelper.BluetoothA2dpDeviceInfo btDeviceInfo) { final int intState = (state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0; //### DOESN'T HONOR SYNC ON DEVICES -> make a synchronized version? // might be ok here because called on BT thread? + sync happening in // checkSendBecomingNoisyIntent final int delay = mDeviceInventory.checkSendBecomingNoisyIntent( final int intState = (state == BluetoothA2dp.STATE_CONNECTED) ? CONNECTION_STATE_CONNECTED : CONNECTION_STATE_DISCONNECTED; final int delay; synchronized (mDeviceStateLock) { delay = mDeviceInventory.checkSendBecomingNoisyIntent( AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, intState, AudioSystem.DEVICE_NONE); } final String addr = btDeviceInfo == null ? "null" : btDeviceInfo.getBtDevice().getAddress(); if (AudioService.DEBUG_DEVICES) { Loading @@ -437,10 +482,6 @@ import java.util.ArrayList; state, btDeviceInfo, delay); } /*package*/ void handleDisconnectHearingAid() { mDeviceInventory.disconnectHearingAid(); } /*package*/ void handleSetA2dpSourceConnectionState(@BluetoothProfile.BtProfileState int state, @NonNull BtHelper.BluetoothA2dpDeviceInfo btDeviceInfo) { final int intState = (state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0; Loading Loading @@ -468,8 +509,6 @@ import java.util.ArrayList; sendLMsgNoDelay(MSG_L_A2DP_ACTIVE_DEVICE_CHANGE, SENDMSG_QUEUE, btDeviceInfo); } //### // must be called synchronized on mConnectedDevices /*package*/ boolean hasScheduledA2dpDockTimeout() { return mBrokerHandler.hasMessages(MSG_IL_BTA2DP_DOCK_TIMEOUT); } Loading @@ -486,19 +525,19 @@ import java.util.ArrayList; } /*package*/ void setAvrcpAbsoluteVolumeSupported(boolean supported) { synchronized (mA2dpAvrcpLock) { synchronized (mDeviceStateLock) { mBtHelper.setAvrcpAbsoluteVolumeSupported(supported); } } /*package*/ boolean getBluetoothA2dpEnabled() { synchronized (mBluetoothA2dpEnabledLock) { synchronized (mDeviceStateLock) { return mBluetoothA2dpEnabled; } } /*package*/ int getA2dpCodec(@NonNull BluetoothDevice device) { synchronized (mA2dpAvrcpLock) { synchronized (mDeviceStateLock) { return mBtHelper.getA2dpCodec(device); } } Loading Loading @@ -579,71 +618,97 @@ import java.util.ArrayList; public void handleMessage(Message msg) { switch (msg.what) { case MSG_RESTORE_DEVICES: synchronized (mDeviceStateLock) { mDeviceInventory.onRestoreDevices(); synchronized (mBluetoothA2dpEnabledLock) { mBtHelper.onAudioServerDiedRestoreA2dp(); } break; case MSG_L_SET_WIRED_DEVICE_CONNECTION_STATE: synchronized (mDeviceStateLock) { mDeviceInventory.onSetWiredDeviceConnectionState( (AudioDeviceInventory.WiredDeviceConnectionState) msg.obj); } break; case MSG_I_BROADCAST_BT_CONNECTION_STATE: synchronized (mDeviceStateLock) { mBtHelper.onBroadcastScoConnectionState(msg.arg1); } break; case MSG_IIL_SET_FORCE_USE: // intented fall-through case MSG_IIL_SET_FORCE_USE: // intended fall-through case MSG_IIL_SET_FORCE_BT_A2DP_USE: onSetForceUse(msg.arg1, msg.arg2, (String) msg.obj); break; case MSG_REPORT_NEW_ROUTES: synchronized (mDeviceStateLock) { mDeviceInventory.onReportNewRoutes(); } break; case MSG_IL_SET_A2DP_SINK_CONNECTION_STATE: synchronized (mDeviceStateLock) { mDeviceInventory.onSetA2dpSinkConnectionState( (BtHelper.BluetoothA2dpDeviceInfo) msg.obj, msg.arg1); } break; case MSG_IL_SET_A2DP_SOURCE_CONNECTION_STATE: synchronized (mDeviceStateLock) { mDeviceInventory.onSetA2dpSourceConnectionState( (BtHelper.BluetoothA2dpDeviceInfo) msg.obj, msg.arg1); } break; case MSG_IL_SET_HEARING_AID_CONNECTION_STATE: synchronized (mDeviceStateLock) { mDeviceInventory.onSetHearingAidConnectionState( (BluetoothDevice) msg.obj, msg.arg1); } break; case MSG_BT_HEADSET_CNCT_FAILED: synchronized (mDeviceStateLock) { mBtHelper.resetBluetoothSco(); } break; case MSG_IL_BTA2DP_DOCK_TIMEOUT: // msg.obj == address of BTA2DP device synchronized (mDeviceStateLock) { mDeviceInventory.onMakeA2dpDeviceUnavailableNow((String) msg.obj, msg.arg1); } break; case MSG_L_A2DP_DEVICE_CONFIG_CHANGE: final int a2dpCodec; final BluetoothDevice btDevice = (BluetoothDevice) msg.obj; synchronized (mA2dpAvrcpLock) { synchronized (mDeviceStateLock) { a2dpCodec = mBtHelper.getA2dpCodec(btDevice); } mDeviceInventory.onBluetoothA2dpDeviceConfigChange( new BtHelper.BluetoothA2dpDeviceInfo(btDevice, -1, a2dpCodec)); } break; case MSG_BROADCAST_AUDIO_BECOMING_NOISY: onSendBecomingNoisyIntent(); break; case MSG_II_SET_HEARING_AID_VOLUME: synchronized (mDeviceStateLock) { mBtHelper.setHearingAidVolume(msg.arg1, msg.arg2); } break; case MSG_I_SET_AVRCP_ABSOLUTE_VOLUME: synchronized (mDeviceStateLock) { mBtHelper.setAvrcpAbsoluteVolumeIndex(msg.arg1); } break; case MSG_I_DISCONNECT_BT_SCO: synchronized (mDeviceStateLock) { mBtHelper.disconnectBluetoothSco(msg.arg1); } break; case MSG_TOGGLE_HDMI: synchronized (mDeviceStateLock) { mDeviceInventory.onToggleHdmi(); } break; case MSG_L_A2DP_ACTIVE_DEVICE_CHANGE: synchronized (mDeviceStateLock) { mDeviceInventory.onBluetoothA2dpActiveDeviceChange( (BtHelper.BluetoothA2dpDeviceInfo) msg.obj); } break; default: Log.wtf(TAG, "Invalid message " + msg.what); Loading services/core/java/com/android/server/audio/AudioDeviceInventory.java +32 −37 Original line number Diff line number Diff line Loading @@ -162,10 +162,7 @@ public final class AudioDeviceInventory { "A2DP sink connected: device addr=" + address + " state=" + state + " vol=" + a2dpVolume)); final int a2dpCodec; synchronized (mDeviceBroker.mA2dpAvrcpLock) { a2dpCodec = btInfo.getCodec(); } final int a2dpCodec = btInfo.getCodec(); synchronized (mConnectedDevices) { final String key = DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, Loading Loading @@ -508,7 +505,6 @@ public final class AudioDeviceInventory { /*package*/ void disconnectA2dp() { synchronized (mConnectedDevices) { synchronized (mDeviceBroker.mA2dpAvrcpLock) { final ArraySet<String> toRemove = new ArraySet<>(); // Disconnect ALL DEVICE_OUT_BLUETOOTH_A2DP devices mConnectedDevices.values().forEach(deviceInfo -> { Loading @@ -519,14 +515,13 @@ public final class AudioDeviceInventory { if (toRemove.size() > 0) { final int delay = checkSendBecomingNoisyIntentInt( AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0, AudioSystem.DEVICE_NONE); AudioService.CONNECTION_STATE_DISCONNECTED, AudioSystem.DEVICE_NONE); toRemove.stream().forEach(deviceAddress -> makeA2dpDeviceUnavailableLater(deviceAddress, delay) ); } } } } /*package*/ void disconnectA2dpSink() { synchronized (mConnectedDevices) { Loading @@ -543,7 +538,6 @@ public final class AudioDeviceInventory { /*package*/ void disconnectHearingAid() { synchronized (mConnectedDevices) { synchronized (mDeviceBroker.mHearingAidLock) { final ArraySet<String> toRemove = new ArraySet<>(); // Disconnect ALL DEVICE_OUT_HEARING_AID devices mConnectedDevices.values().forEach(deviceInfo -> { Loading @@ -561,12 +555,12 @@ public final class AudioDeviceInventory { } } } } // must be called before removing the device from mConnectedDevices // musicDevice argument is used when not AudioSystem.DEVICE_NONE instead of querying // from AudioSystem /*package*/ int checkSendBecomingNoisyIntent(int device, int state, int musicDevice) { /*package*/ int checkSendBecomingNoisyIntent(int device, @AudioService.ConnectionState int state, int musicDevice) { synchronized (mConnectedDevices) { return checkSendBecomingNoisyIntentInt(device, state, musicDevice); } Loading Loading @@ -840,8 +834,9 @@ public final class AudioDeviceInventory { // musicDevice argument is used when not AudioSystem.DEVICE_NONE instead of querying // from AudioSystem @GuardedBy("mConnectedDevices") private int checkSendBecomingNoisyIntentInt(int device, int state, int musicDevice) { if (state != 0) { private int checkSendBecomingNoisyIntentInt(int device, @AudioService.ConnectionState int state, int musicDevice) { if (state != AudioService.CONNECTION_STATE_DISCONNECTED) { return 0; } if ((device & mBecomingNoisyIntentDevices) == 0) { Loading services/core/java/com/android/server/audio/AudioService.java +0 −2 Original line number Diff line number Diff line Loading @@ -786,7 +786,6 @@ public class AudioService extends IAudioService.Stub mPrescaleAbsoluteVolume[i] = preScale[i]; } } } public void systemReady() { Loading Loading @@ -3821,7 +3820,6 @@ public class AudioService extends IAudioService.Stub private static void sendMsg(Handler handler, int msg, int existingMsgPolicy, int arg1, int arg2, Object obj, int delay) { if (existingMsgPolicy == SENDMSG_REPLACE) { handler.removeMessages(msg); } else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) { Loading services/core/java/com/android/server/audio/BtHelper.java +245 −274 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
services/core/java/com/android/server/audio/AudioDeviceBroker.java +170 −105 Original line number Diff line number Diff line Loading @@ -15,6 +15,9 @@ */ package com.android.server.audio; import static com.android.server.audio.AudioService.CONNECTION_STATE_CONNECTED; import static com.android.server.audio.AudioService.CONNECTION_STATE_DISCONNECTED; import android.annotation.NonNull; import android.bluetooth.BluetoothA2dp; import android.bluetooth.BluetoothDevice; Loading Loading @@ -43,7 +46,7 @@ import java.util.ArrayList; /** @hide */ /*package*/ final class AudioDeviceBroker { private static final String TAG = "AudioDeviceBroker"; private static final String TAG = "AS.AudioDeviceBroker"; private static final long BROKER_WAKELOCK_TIMEOUT_MS = 5000; //5s Loading @@ -62,27 +65,27 @@ import java.util.ArrayList; private int mForcedUseForCommExt; // Manages all connected devices, only ever accessed on the message loop //### or make it synchronized private final AudioDeviceInventory mDeviceInventory; // Manages notifications to BT service private final BtHelper mBtHelper; //------------------------------------------------------------------- // we use a different lock than mDeviceStateLock so as not to create // lock contention between enqueueing a message and handling them private static final Object sLastDeviceConnectionMsgTimeLock = new Object(); @GuardedBy("sLastDeviceConnectionMsgTimeLock") private static long sLastDeviceConnectMsgTime = 0; private final Object mBluetoothA2dpEnabledLock = new Object(); // General lock to be taken whenever the state of the audio devices is to be checked or changed private final Object mDeviceStateLock = new Object(); // Request to override default use of A2DP for media. @GuardedBy("mBluetoothA2dpEnabledLock") @GuardedBy("mDeviceStateLock") private boolean mBluetoothA2dpEnabled; // lock always taken synchronized on mConnectedDevices /*package*/ final Object mA2dpAvrcpLock = new Object(); // lock always taken synchronized on mConnectedDevices /*package*/ final Object mHearingAidLock = new Object(); // lock always taken when accessing AudioService.mSetModeDeathHandlers // TODO do not "share" the lock between AudioService and BtHelpr, see b/123769055 /*package*/ final Object mSetModeLock = new Object(); //------------------------------------------------------------------- Loading @@ -109,13 +112,17 @@ import java.util.ArrayList; // All post* methods are asynchronous /*package*/ void onSystemReady() { synchronized (mDeviceStateLock) { mBtHelper.onSystemReady(); } } /*package*/ void onAudioServerDied() { // Restore forced usage for communications and record synchronized (mDeviceStateLock) { onSetForceUse(AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, "onAudioServerDied"); onSetForceUse(AudioSystem.FOR_RECORD, mForcedUseForComm, "onAudioServerDied"); } // restore devices sendMsgNoDelay(MSG_RESTORE_DEVICES, SENDMSG_REPLACE); } Loading @@ -130,8 +137,10 @@ import java.util.ArrayList; } /*package*/ void disconnectAllBluetoothProfiles() { synchronized (mDeviceStateLock) { mBtHelper.disconnectAllBluetoothProfiles(); } } /** * Handle BluetoothHeadset intents where the action is one of Loading @@ -140,11 +149,13 @@ import java.util.ArrayList; * @param intent */ /*package*/ void receiveBtEvent(@NonNull Intent intent) { synchronized (mDeviceStateLock) { mBtHelper.receiveBtEvent(intent); } } /*package*/ void setBluetoothA2dpOn_Async(boolean on, String source) { synchronized (mBluetoothA2dpEnabledLock) { synchronized (mDeviceStateLock) { if (mBluetoothA2dpEnabled == on) { return; } Loading @@ -158,6 +169,7 @@ import java.util.ArrayList; } /*package*/ void setSpeakerphoneOn(boolean on, String eventSource) { synchronized (mDeviceStateLock) { if (on) { if (mForcedUseForComm == AudioSystem.FORCE_BT_SCO) { setForceUse_Async(AudioSystem.FOR_RECORD, AudioSystem.FORCE_NONE, eventSource); Loading @@ -170,17 +182,22 @@ import java.util.ArrayList; mForcedUseForCommExt = mForcedUseForComm; setForceUse_Async(AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, eventSource); } } /*package*/ boolean isSpeakerphoneOn() { synchronized (mDeviceStateLock) { return (mForcedUseForCommExt == AudioSystem.FORCE_SPEAKER); } } /*package*/ void setWiredDeviceConnectionState(int type, @AudioService.ConnectionState int state, String address, String name, String caller) { //TODO move logging here just like in setBluetooth* methods synchronized (mDeviceStateLock) { mDeviceInventory.setWiredDeviceConnectionState(type, state, address, name, caller); } } /*package*/ int setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent( @NonNull BluetoothDevice device, @AudioService.BtProfileConnectionState int state, Loading @@ -192,6 +209,7 @@ import java.util.ArrayList; + " addr=" + device.getAddress() + " prof=" + profile + " supprNoisy=" + suppressNoisyIntent + " vol=" + a2dpVolume)).printLog(TAG)); synchronized (mDeviceStateLock) { if (mBrokerHandler.hasMessages(MSG_IL_SET_A2DP_SINK_CONNECTION_STATE, new BtHelper.BluetoothA2dpDeviceInfo(device))) { AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent( Loading @@ -199,16 +217,20 @@ import java.util.ArrayList; return 0; } return mDeviceInventory.setBluetoothA2dpDeviceConnectionState( device, state, profile, suppressNoisyIntent, AudioSystem.DEVICE_NONE, a2dpVolume); device, state, profile, suppressNoisyIntent, AudioSystem.DEVICE_NONE, a2dpVolume); } } /*package*/ int handleBluetoothA2dpActiveDeviceChange( @NonNull BluetoothDevice device, @AudioService.BtProfileConnectionState int state, int profile, boolean suppressNoisyIntent, int a2dpVolume) { synchronized (mDeviceStateLock) { return mDeviceInventory.handleBluetoothA2dpActiveDeviceChange(device, state, profile, suppressNoisyIntent, a2dpVolume); } } /*package*/ int setBluetoothHearingAidDeviceConnectionState( @NonNull BluetoothDevice device, @AudioService.BtProfileConnectionState int state, Loading @@ -218,21 +240,28 @@ import java.util.ArrayList; + " addr=" + device.getAddress() + " supprNoisy=" + suppressNoisyIntent + " src=" + eventSource)).printLog(TAG)); synchronized (mDeviceStateLock) { return mDeviceInventory.setBluetoothHearingAidDeviceConnectionState( device, state, suppressNoisyIntent, musicDevice); } } // never called by system components /*package*/ void setBluetoothScoOnByApp(boolean on) { synchronized (mDeviceStateLock) { mForcedUseForCommExt = on ? AudioSystem.FORCE_BT_SCO : AudioSystem.FORCE_NONE; } } /*package*/ boolean isBluetoothScoOnForApp() { synchronized (mDeviceStateLock) { return mForcedUseForCommExt == AudioSystem.FORCE_BT_SCO; } } /*package*/ void setBluetoothScoOn(boolean on, String eventSource) { //Log.i(TAG, "setBluetoothScoOnInt: " + on + " " + eventSource); synchronized (mDeviceStateLock) { if (on) { // do not accept SCO ON if SCO audio is not connected if (!mBtHelper.isBluetoothScoOn()) { Loading @@ -252,23 +281,28 @@ import java.util.ArrayList; // Un-mute ringtone stream volume mAudioService.setUpdateRingerModeServiceInt(); } } /*package*/ AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) { synchronized (mDeviceStateLock) { return mDeviceInventory.startWatchingRoutes(observer); } } /*package*/ AudioRoutesInfo getCurAudioRoutes() { synchronized (mDeviceStateLock) { return mDeviceInventory.getCurAudioRoutes(); } } /*package*/ boolean isAvrcpAbsoluteVolumeSupported() { synchronized (mA2dpAvrcpLock) { synchronized (mDeviceStateLock) { return mBtHelper.isAvrcpAbsoluteVolumeSupported(); } } /*package*/ boolean isBluetoothA2dpOn() { synchronized (mBluetoothA2dpEnabledLock) { synchronized (mDeviceStateLock) { return mBluetoothA2dpEnabled; } } Loading Loading @@ -355,14 +389,12 @@ import java.util.ArrayList; sendMsgNoDelay(MSG_BROADCAST_AUDIO_BECOMING_NOISY, SENDMSG_REPLACE); } //###TODO unify with handleSetA2dpSinkConnectionState /*package*/ void postA2dpSinkConnection(int state, @NonNull BtHelper.BluetoothA2dpDeviceInfo btDeviceInfo, int delay) { sendILMsg(MSG_IL_SET_A2DP_SINK_CONNECTION_STATE, SENDMSG_QUEUE, state, btDeviceInfo, delay); } //###TODO unify with handleSetA2dpSourceConnectionState /*package*/ void postA2dpSourceConnection(int state, @NonNull BtHelper.BluetoothA2dpDeviceInfo btDeviceInfo, int delay) { sendILMsg(MSG_IL_SET_A2DP_SOURCE_CONNECTION_STATE, SENDMSG_QUEUE, Loading Loading @@ -395,7 +427,7 @@ import java.util.ArrayList; .append(") from u/pid:").append(Binder.getCallingUid()).append("/") .append(Binder.getCallingPid()).append(" src:").append(source).toString(); synchronized (mBluetoothA2dpEnabledLock) { synchronized (mDeviceStateLock) { mBluetoothA2dpEnabled = on; mBrokerHandler.removeMessages(MSG_IIL_SET_FORCE_BT_A2DP_USE); onSetForceUse( Loading @@ -407,25 +439,38 @@ import java.util.ArrayList; /*package*/ boolean handleDeviceConnection(boolean connect, int device, String address, String deviceName) { synchronized (mDeviceStateLock) { return mDeviceInventory.handleDeviceConnection(connect, device, address, deviceName); } } /*package*/ void handleDisconnectA2dp() { synchronized (mDeviceStateLock) { mDeviceInventory.disconnectA2dp(); } } /*package*/ void handleDisconnectA2dpSink() { synchronized (mDeviceStateLock) { mDeviceInventory.disconnectA2dpSink(); } } /*package*/ void handleDisconnectHearingAid() { synchronized (mDeviceStateLock) { mDeviceInventory.disconnectHearingAid(); } } /*package*/ void handleSetA2dpSinkConnectionState(@BluetoothProfile.BtProfileState int state, @NonNull BtHelper.BluetoothA2dpDeviceInfo btDeviceInfo) { final int intState = (state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0; //### DOESN'T HONOR SYNC ON DEVICES -> make a synchronized version? // might be ok here because called on BT thread? + sync happening in // checkSendBecomingNoisyIntent final int delay = mDeviceInventory.checkSendBecomingNoisyIntent( final int intState = (state == BluetoothA2dp.STATE_CONNECTED) ? CONNECTION_STATE_CONNECTED : CONNECTION_STATE_DISCONNECTED; final int delay; synchronized (mDeviceStateLock) { delay = mDeviceInventory.checkSendBecomingNoisyIntent( AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, intState, AudioSystem.DEVICE_NONE); } final String addr = btDeviceInfo == null ? "null" : btDeviceInfo.getBtDevice().getAddress(); if (AudioService.DEBUG_DEVICES) { Loading @@ -437,10 +482,6 @@ import java.util.ArrayList; state, btDeviceInfo, delay); } /*package*/ void handleDisconnectHearingAid() { mDeviceInventory.disconnectHearingAid(); } /*package*/ void handleSetA2dpSourceConnectionState(@BluetoothProfile.BtProfileState int state, @NonNull BtHelper.BluetoothA2dpDeviceInfo btDeviceInfo) { final int intState = (state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0; Loading Loading @@ -468,8 +509,6 @@ import java.util.ArrayList; sendLMsgNoDelay(MSG_L_A2DP_ACTIVE_DEVICE_CHANGE, SENDMSG_QUEUE, btDeviceInfo); } //### // must be called synchronized on mConnectedDevices /*package*/ boolean hasScheduledA2dpDockTimeout() { return mBrokerHandler.hasMessages(MSG_IL_BTA2DP_DOCK_TIMEOUT); } Loading @@ -486,19 +525,19 @@ import java.util.ArrayList; } /*package*/ void setAvrcpAbsoluteVolumeSupported(boolean supported) { synchronized (mA2dpAvrcpLock) { synchronized (mDeviceStateLock) { mBtHelper.setAvrcpAbsoluteVolumeSupported(supported); } } /*package*/ boolean getBluetoothA2dpEnabled() { synchronized (mBluetoothA2dpEnabledLock) { synchronized (mDeviceStateLock) { return mBluetoothA2dpEnabled; } } /*package*/ int getA2dpCodec(@NonNull BluetoothDevice device) { synchronized (mA2dpAvrcpLock) { synchronized (mDeviceStateLock) { return mBtHelper.getA2dpCodec(device); } } Loading Loading @@ -579,71 +618,97 @@ import java.util.ArrayList; public void handleMessage(Message msg) { switch (msg.what) { case MSG_RESTORE_DEVICES: synchronized (mDeviceStateLock) { mDeviceInventory.onRestoreDevices(); synchronized (mBluetoothA2dpEnabledLock) { mBtHelper.onAudioServerDiedRestoreA2dp(); } break; case MSG_L_SET_WIRED_DEVICE_CONNECTION_STATE: synchronized (mDeviceStateLock) { mDeviceInventory.onSetWiredDeviceConnectionState( (AudioDeviceInventory.WiredDeviceConnectionState) msg.obj); } break; case MSG_I_BROADCAST_BT_CONNECTION_STATE: synchronized (mDeviceStateLock) { mBtHelper.onBroadcastScoConnectionState(msg.arg1); } break; case MSG_IIL_SET_FORCE_USE: // intented fall-through case MSG_IIL_SET_FORCE_USE: // intended fall-through case MSG_IIL_SET_FORCE_BT_A2DP_USE: onSetForceUse(msg.arg1, msg.arg2, (String) msg.obj); break; case MSG_REPORT_NEW_ROUTES: synchronized (mDeviceStateLock) { mDeviceInventory.onReportNewRoutes(); } break; case MSG_IL_SET_A2DP_SINK_CONNECTION_STATE: synchronized (mDeviceStateLock) { mDeviceInventory.onSetA2dpSinkConnectionState( (BtHelper.BluetoothA2dpDeviceInfo) msg.obj, msg.arg1); } break; case MSG_IL_SET_A2DP_SOURCE_CONNECTION_STATE: synchronized (mDeviceStateLock) { mDeviceInventory.onSetA2dpSourceConnectionState( (BtHelper.BluetoothA2dpDeviceInfo) msg.obj, msg.arg1); } break; case MSG_IL_SET_HEARING_AID_CONNECTION_STATE: synchronized (mDeviceStateLock) { mDeviceInventory.onSetHearingAidConnectionState( (BluetoothDevice) msg.obj, msg.arg1); } break; case MSG_BT_HEADSET_CNCT_FAILED: synchronized (mDeviceStateLock) { mBtHelper.resetBluetoothSco(); } break; case MSG_IL_BTA2DP_DOCK_TIMEOUT: // msg.obj == address of BTA2DP device synchronized (mDeviceStateLock) { mDeviceInventory.onMakeA2dpDeviceUnavailableNow((String) msg.obj, msg.arg1); } break; case MSG_L_A2DP_DEVICE_CONFIG_CHANGE: final int a2dpCodec; final BluetoothDevice btDevice = (BluetoothDevice) msg.obj; synchronized (mA2dpAvrcpLock) { synchronized (mDeviceStateLock) { a2dpCodec = mBtHelper.getA2dpCodec(btDevice); } mDeviceInventory.onBluetoothA2dpDeviceConfigChange( new BtHelper.BluetoothA2dpDeviceInfo(btDevice, -1, a2dpCodec)); } break; case MSG_BROADCAST_AUDIO_BECOMING_NOISY: onSendBecomingNoisyIntent(); break; case MSG_II_SET_HEARING_AID_VOLUME: synchronized (mDeviceStateLock) { mBtHelper.setHearingAidVolume(msg.arg1, msg.arg2); } break; case MSG_I_SET_AVRCP_ABSOLUTE_VOLUME: synchronized (mDeviceStateLock) { mBtHelper.setAvrcpAbsoluteVolumeIndex(msg.arg1); } break; case MSG_I_DISCONNECT_BT_SCO: synchronized (mDeviceStateLock) { mBtHelper.disconnectBluetoothSco(msg.arg1); } break; case MSG_TOGGLE_HDMI: synchronized (mDeviceStateLock) { mDeviceInventory.onToggleHdmi(); } break; case MSG_L_A2DP_ACTIVE_DEVICE_CHANGE: synchronized (mDeviceStateLock) { mDeviceInventory.onBluetoothA2dpActiveDeviceChange( (BtHelper.BluetoothA2dpDeviceInfo) msg.obj); } break; default: Log.wtf(TAG, "Invalid message " + msg.what); Loading
services/core/java/com/android/server/audio/AudioDeviceInventory.java +32 −37 Original line number Diff line number Diff line Loading @@ -162,10 +162,7 @@ public final class AudioDeviceInventory { "A2DP sink connected: device addr=" + address + " state=" + state + " vol=" + a2dpVolume)); final int a2dpCodec; synchronized (mDeviceBroker.mA2dpAvrcpLock) { a2dpCodec = btInfo.getCodec(); } final int a2dpCodec = btInfo.getCodec(); synchronized (mConnectedDevices) { final String key = DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, Loading Loading @@ -508,7 +505,6 @@ public final class AudioDeviceInventory { /*package*/ void disconnectA2dp() { synchronized (mConnectedDevices) { synchronized (mDeviceBroker.mA2dpAvrcpLock) { final ArraySet<String> toRemove = new ArraySet<>(); // Disconnect ALL DEVICE_OUT_BLUETOOTH_A2DP devices mConnectedDevices.values().forEach(deviceInfo -> { Loading @@ -519,14 +515,13 @@ public final class AudioDeviceInventory { if (toRemove.size() > 0) { final int delay = checkSendBecomingNoisyIntentInt( AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0, AudioSystem.DEVICE_NONE); AudioService.CONNECTION_STATE_DISCONNECTED, AudioSystem.DEVICE_NONE); toRemove.stream().forEach(deviceAddress -> makeA2dpDeviceUnavailableLater(deviceAddress, delay) ); } } } } /*package*/ void disconnectA2dpSink() { synchronized (mConnectedDevices) { Loading @@ -543,7 +538,6 @@ public final class AudioDeviceInventory { /*package*/ void disconnectHearingAid() { synchronized (mConnectedDevices) { synchronized (mDeviceBroker.mHearingAidLock) { final ArraySet<String> toRemove = new ArraySet<>(); // Disconnect ALL DEVICE_OUT_HEARING_AID devices mConnectedDevices.values().forEach(deviceInfo -> { Loading @@ -561,12 +555,12 @@ public final class AudioDeviceInventory { } } } } // must be called before removing the device from mConnectedDevices // musicDevice argument is used when not AudioSystem.DEVICE_NONE instead of querying // from AudioSystem /*package*/ int checkSendBecomingNoisyIntent(int device, int state, int musicDevice) { /*package*/ int checkSendBecomingNoisyIntent(int device, @AudioService.ConnectionState int state, int musicDevice) { synchronized (mConnectedDevices) { return checkSendBecomingNoisyIntentInt(device, state, musicDevice); } Loading Loading @@ -840,8 +834,9 @@ public final class AudioDeviceInventory { // musicDevice argument is used when not AudioSystem.DEVICE_NONE instead of querying // from AudioSystem @GuardedBy("mConnectedDevices") private int checkSendBecomingNoisyIntentInt(int device, int state, int musicDevice) { if (state != 0) { private int checkSendBecomingNoisyIntentInt(int device, @AudioService.ConnectionState int state, int musicDevice) { if (state != AudioService.CONNECTION_STATE_DISCONNECTED) { return 0; } if ((device & mBecomingNoisyIntentDevices) == 0) { Loading
services/core/java/com/android/server/audio/AudioService.java +0 −2 Original line number Diff line number Diff line Loading @@ -786,7 +786,6 @@ public class AudioService extends IAudioService.Stub mPrescaleAbsoluteVolume[i] = preScale[i]; } } } public void systemReady() { Loading Loading @@ -3821,7 +3820,6 @@ public class AudioService extends IAudioService.Stub private static void sendMsg(Handler handler, int msg, int existingMsgPolicy, int arg1, int arg2, Object obj, int delay) { if (existingMsgPolicy == SENDMSG_REPLACE) { handler.removeMessages(msg); } else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) { Loading
services/core/java/com/android/server/audio/BtHelper.java +245 −274 File changed.Preview size limit exceeded, changes collapsed. Show changes