Loading services/core/java/com/android/server/audio/AudioService.java +118 −70 Original line number Diff line number Diff line Loading @@ -141,6 +141,9 @@ public class AudioService extends IAudioService.Stub { /** debug calls to media session apis */ private static final boolean DEBUG_SESSIONS = Log.isLoggable(TAG + ".SESSIONS", Log.DEBUG); /** debug calls to devices APIs */ protected static final boolean DEBUG_DEVICES = Log.isLoggable(TAG + ".DEVICES", Log.DEBUG); /** Allow volume changes to set ringer mode to silent? */ private static final boolean VOLUME_SETS_RINGER_MODE_SILENT = false; Loading Loading @@ -376,7 +379,32 @@ public class AudioService extends IAudioService.Stub { private final BroadcastReceiver mReceiver = new AudioServiceBroadcastReceiver(); // Devices currently connected private final HashMap <Integer, String> mConnectedDevices = new HashMap <Integer, String>(); // Use makeDeviceListKey() to make a unique key for this list. private class DeviceListSpec { int mDeviceType; String mDeviceName; String mDeviceAddress; public DeviceListSpec(int deviceType, String deviceName, String deviceAddress) { mDeviceType = deviceType; mDeviceName = deviceName; mDeviceAddress = deviceAddress; } public String toString() { return "[type:0x" + Integer.toHexString(mDeviceType) + " name:" + mDeviceName + " address:" + mDeviceAddress + "]"; } } // Generate a unique key for the mConnectedDevices List by composing the device "type" // and the "address" associated with a specific instance of that device type private String makeDeviceListKey(int device, String deviceAddress) { return "0x" + Integer.toHexString(device) + ":" + deviceAddress; } private final HashMap<String, DeviceListSpec> mConnectedDevices = new HashMap<String, DeviceListSpec>(); // Forced device usage for communications private int mForcedUseForComm; Loading Loading @@ -520,6 +548,8 @@ public class AudioService extends IAudioService.Stub { return "card=" + card + ";device=" + device + ";"; } private final String DEVICE_NAME_A2DP = "a2dp-device"; /////////////////////////////////////////////////////////////////////////// // Construction /////////////////////////////////////////////////////////////////////////// Loading Loading @@ -2771,10 +2801,13 @@ public class AudioService extends IAudioService.Stub { case BluetoothProfile.A2DP: synchronized (mConnectedDevices) { synchronized (mA2dpAvrcpLock) { mA2dp = null; if (mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP)) { makeA2dpDeviceUnavailableNow( mConnectedDevices.get(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP)); // Disconnect ALL DEVICE_OUT_BLUETOOTH_A2DP devices for(Map.Entry<String, DeviceListSpec> entry : mConnectedDevices.entrySet()) { DeviceListSpec deviceSpec = entry.getValue(); if (deviceSpec.mDeviceType == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) { makeA2dpDeviceUnavailableNow(deviceSpec.mDeviceAddress); } } } } Loading @@ -2782,9 +2815,13 @@ public class AudioService extends IAudioService.Stub { case BluetoothProfile.A2DP_SINK: synchronized (mConnectedDevices) { if (mConnectedDevices.containsKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP)) { makeA2dpSrcUnavailable( mConnectedDevices.get(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP)); // Disconnect ALL DEVICE_IN_BLUETOOTH_A2DP devices for(Map.Entry<String, DeviceListSpec> entry : mConnectedDevices.entrySet()) { DeviceListSpec deviceSpec = entry.getValue(); if (deviceSpec.mDeviceType == AudioSystem.DEVICE_IN_BLUETOOTH_A2DP) { makeA2dpSrcUnavailable(deviceSpec.mDeviceAddress); } } } break; Loading Loading @@ -3272,6 +3309,10 @@ public class AudioService extends IAudioService.Stub { public void setWiredDeviceConnectionState(int type, int state, String address, String name) { synchronized (mConnectedDevices) { if (DEBUG_DEVICES) { Slog.i(TAG, "setWiredDeviceConnectionState(" + state + " nm: " + name + " addr:" + address + ")"); } int delay = checkSendBecomingNoisyIntent(type, state); queueMsgUnderWakeLock(mAudioHandler, MSG_SET_WIRED_DEVICE_CONNECTION_STATE, Loading Loading @@ -4236,13 +4277,13 @@ public class AudioService extends IAudioService.Stub { AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0, streamState, 0); setBluetoothA2dpOnInt(true); AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, AudioSystem.DEVICE_STATE_AVAILABLE, address, "a2dp-device"); AudioSystem.DEVICE_STATE_AVAILABLE, address, DEVICE_NAME_A2DP); // Reset A2DP suspend state each time a new sink is connected AudioSystem.setParameters("A2dpSuspended=false"); mConnectedDevices.put( new Integer(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP), address); mConnectedDevices.put( makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address), new DeviceListSpec(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, DEVICE_NAME_A2DP, address)); } private void onSendBecomingNoisyIntent() { Loading @@ -4255,10 +4296,9 @@ public class AudioService extends IAudioService.Stub { mAvrcpAbsVolSupported = false; } AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, AudioSystem.DEVICE_STATE_UNAVAILABLE, address, "a2dp-device"); mConnectedDevices.remove(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP); AudioSystem.DEVICE_STATE_UNAVAILABLE, address, DEVICE_NAME_A2DP); mConnectedDevices.remove( makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address)); synchronized (mCurAudioRoutes) { // Remove A2DP routes as well if (mCurAudioRoutes.bluetoothName != null) { Loading @@ -4275,7 +4315,8 @@ public class AudioService extends IAudioService.Stub { // reconnection of the sink. AudioSystem.setParameters("A2dpSuspended=true"); // the device will be made unavailable later, so consider it disconnected right away mConnectedDevices.remove(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP); mConnectedDevices.remove( makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address)); // send the delayed message to make the device unavailable later Message msg = mAudioHandler.obtainMessage(MSG_BTA2DP_DOCK_TIMEOUT, address); mAudioHandler.sendMessageDelayed(msg, BTA2DP_DOCK_TIMEOUT_MILLIS); Loading @@ -4285,20 +4326,19 @@ public class AudioService extends IAudioService.Stub { // must be called synchronized on mConnectedDevices private void makeA2dpSrcAvailable(String address) { AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, AudioSystem.DEVICE_STATE_AVAILABLE, address, "a2dp-device"); mConnectedDevices.put( new Integer(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP), address); AudioSystem.DEVICE_STATE_AVAILABLE, address, DEVICE_NAME_A2DP); mConnectedDevices.put( makeDeviceListKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address), new DeviceListSpec(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, DEVICE_NAME_A2DP, address)); } // must be called synchronized on mConnectedDevices private void makeA2dpSrcUnavailable(String address) { AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, AudioSystem.DEVICE_STATE_UNAVAILABLE, address, "a2dp-device"); mConnectedDevices.remove(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP); AudioSystem.DEVICE_STATE_UNAVAILABLE, address, DEVICE_NAME_A2DP); mConnectedDevices.remove( makeDeviceListKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address)); } // must be called synchronized on mConnectedDevices Loading @@ -4325,9 +4365,10 @@ public class AudioService extends IAudioService.Stub { } synchronized (mConnectedDevices) { boolean isConnected = (mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) && mConnectedDevices.get(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP).equals(address)); String key = makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, btDevice.getAddress()); DeviceListSpec deviceSpec = mConnectedDevices.get(key); boolean isConnected = deviceSpec != null; if (isConnected && state != BluetoothProfile.STATE_CONNECTED) { if (btDevice.isBluetoothDock()) { Loading Loading @@ -4388,9 +4429,9 @@ public class AudioService extends IAudioService.Stub { } synchronized (mConnectedDevices) { boolean isConnected = (mConnectedDevices.containsKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP) && mConnectedDevices.get(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP).equals(address)); String key = makeDeviceListKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address); DeviceListSpec deviceSpec = mConnectedDevices.get(key); boolean isConnected = deviceSpec != null; if (isConnected && state != BluetoothProfile.STATE_CONNECTED) { makeA2dpSrcUnavailable(address); Loading @@ -4413,26 +4454,31 @@ public class AudioService extends IAudioService.Stub { } } private boolean handleDeviceConnection(boolean connect, int device, String address, String deviceName) { Slog.i(TAG, "handleDeviceConnection(" + connect + " dev:" + Integer.toHexString(device) + " address:" + address + " name:" + deviceName + ")"); private boolean handleDeviceConnection(boolean connect, int device, String address, String deviceName) { if (DEBUG_DEVICES) { Slog.i(TAG, "handleDeviceConnection(" + connect + " dev:" + Integer.toHexString(device) + " address:" + address + " name:" + deviceName + ")"); } synchronized (mConnectedDevices) { boolean isConnected = (mConnectedDevices.containsKey(device) && (address.isEmpty() || mConnectedDevices.get(device).equals(address))); if (isConnected && !connect) { AudioSystem.setDeviceConnectionState(device, AudioSystem.DEVICE_STATE_UNAVAILABLE, String deviceKey = makeDeviceListKey(device, address); if (DEBUG_DEVICES) { Slog.i(TAG, "deviceKey:" + deviceKey); } DeviceListSpec deviceSpec = mConnectedDevices.get(deviceKey); boolean isConnected = deviceSpec != null; if (DEBUG_DEVICES) { Slog.i(TAG, "deviceSpec:" + deviceSpec + " is(already)Connected:" + isConnected); } if (connect && !isConnected) { AudioSystem.setDeviceConnectionState(device, AudioSystem.DEVICE_STATE_AVAILABLE, address, deviceName); mConnectedDevices.remove(device); mConnectedDevices.put(deviceKey, new DeviceListSpec(device, deviceName, address)); return true; } else if (!isConnected && connect) { AudioSystem.setDeviceConnectionState(device, AudioSystem.DEVICE_STATE_AVAILABLE, } else if (!connect && isConnected) { AudioSystem.setDeviceConnectionState(device, AudioSystem.DEVICE_STATE_UNAVAILABLE, address, deviceName); mConnectedDevices.put(new Integer(device), address); mConnectedDevices.remove(deviceKey); return true; } } Loading @@ -4454,9 +4500,10 @@ public class AudioService extends IAudioService.Stub { int delay = 0; if ((state == 0) && ((device & mBecomingNoisyIntentDevices) != 0)) { int devices = 0; for (int dev : mConnectedDevices.keySet()) { if (((dev & AudioSystem.DEVICE_BIT_IN) == 0) && ((dev & mBecomingNoisyIntentDevices) != 0)) { for (String key : mConnectedDevices.keySet()) { int dev = mConnectedDevices.get(key).mDeviceType; if (((dev & AudioSystem.DEVICE_BIT_IN) == 0) && ((dev & mBecomingNoisyIntentDevices) != 0)) { devices |= dev; } } Loading Loading @@ -4485,12 +4532,13 @@ public class AudioService extends IAudioService.Stub { return delay; } private void sendDeviceConnectionIntent(int device, int state, String address, String deviceName) { private void sendDeviceConnectionIntent(int device, int state, String address, String deviceName) { if (DEBUG_DEVICES) { Slog.i(TAG, "sendDeviceConnectionIntent(dev:0x" + Integer.toHexString(device) + " state:0x" + Integer.toHexString(state) + " address:" + address + " state:0x" + Integer.toHexString(state) + " address:" + address + " name:" + deviceName + ");"); } Intent intent = new Intent(); intent.putExtra(CONNECT_INTENT_KEY_STATE, state); Loading Loading @@ -4544,12 +4592,12 @@ public class AudioService extends IAudioService.Stub { } private void onSetWiredDeviceConnectionState(int device, int state, String address, String deviceName) { Slog.i(TAG, "onSetWiredDeviceConnectionState(dev:" + Integer.toHexString(device) + " state:" + Integer.toHexString(state) + " address:" + address + " deviceName:" + deviceName + ");"); String deviceName) { if (DEBUG_DEVICES) { Slog.i(TAG, "onSetWiredDeviceConnectionState(dev:" + Integer.toHexString(device) + " state:" + Integer.toHexString(state) + " address:" + address + " deviceName:" + deviceName + ");"); } synchronized (mConnectedDevices) { if ((state == 0) && ((device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) || Loading services/usb/java/com/android/server/usb/UsbAlsaManager.java +23 −28 Original line number Diff line number Diff line Loading @@ -73,8 +73,6 @@ public final class UsbAlsaManager { private UsbAudioDevice mAccessoryAudioDevice = null; private UsbAudioDevice mSelectedAudioDevice = null; // UsbMidiDevice for USB peripheral mode (gadget) device private UsbMidiDevice mPeripheralMidiDevice = null; Loading Loading @@ -186,6 +184,10 @@ public final class UsbAlsaManager { int device = (audioDevice == mAccessoryAudioDevice ? AudioSystem.DEVICE_OUT_USB_ACCESSORY : AudioSystem.DEVICE_OUT_USB_DEVICE); if (DEBUG) { Slog.i(TAG, "pre-call device:0x" + Integer.toHexString(device) + " addr:" + address + " name:" + audioDevice.mDeviceName); } mAudioService.setWiredDeviceConnectionState( device, state, address, audioDevice.mDeviceName); } Loading Loading @@ -282,23 +284,13 @@ public final class UsbAlsaManager { /* * Select the default device of the specified card. */ /* package */ boolean selectAudioCard(int card) { /* package */ UsbAudioDevice selectAudioCard(int card) { if (DEBUG) { Slog.d(TAG, "selectAudioCard() card:" + card); } if (!mCardsParser.isCardUsb(card)) { // Don't. AudioPolicyManager has logic for falling back to internal devices. return false; } if (mSelectedAudioDevice != null) { if (mSelectedAudioDevice.mCard == card) { // Nothing to do here. return false; } // "disconnect" the AudioPolicyManager from the previously selected device. notifyDeviceState(mSelectedAudioDevice, false); mSelectedAudioDevice = null; return null; } mDevicesParser.scan(); Loading @@ -314,30 +306,30 @@ public final class UsbAlsaManager { // Playback device file needed/present? if (hasPlayback && (waitForAlsaDevice(card, device, AlsaDevice.TYPE_PLAYBACK) == null)) { return false; return null; } // Capture device file needed/present? if (hasCapture && (waitForAlsaDevice(card, device, AlsaDevice.TYPE_CAPTURE) == null)) { return false; return null; } if (DEBUG) { Slog.d(TAG, "usb: hasPlayback:" + hasPlayback + " hasCapture:" + hasCapture); } mSelectedAudioDevice = UsbAudioDevice audioDevice = new UsbAudioDevice(card, device, hasPlayback, hasCapture, deviceClass); mSelectedAudioDevice.mDeviceName = mCardsParser.getCardRecordFor(card).mCardName; mSelectedAudioDevice.mDeviceDescription = mCardsParser.getCardRecordFor(card).mCardDescription; AlsaCardsParser.AlsaCardRecord cardRecord = mCardsParser.getCardRecordFor(card); audioDevice.mDeviceName = cardRecord.mCardName; audioDevice.mDeviceDescription = cardRecord.mCardDescription; notifyDeviceState(mSelectedAudioDevice, true); notifyDeviceState(audioDevice, true); return true; return audioDevice; } /* package */ boolean selectDefaultDevice() { /* package */ UsbAudioDevice selectDefaultDevice() { if (DEBUG) { Slog.d(TAG, "UsbAudioManager.selectDefaultDevice()"); } Loading @@ -347,7 +339,8 @@ public final class UsbAlsaManager { /* package */ void usbDeviceAdded(UsbDevice usbDevice) { if (DEBUG) { Slog.d(TAG, "usbDeviceAdded(): " + usbDevice); Slog.d(TAG, "deviceAdded(): " + usbDevice.getManufacturerName() + "nm:" + usbDevice.getProductName()); } // Is there an audio interface in there? Loading Loading @@ -384,8 +377,10 @@ public final class UsbAlsaManager { // If the default isn't a USB device, let the existing "select internal mechanism" // handle the selection. if (mCardsParser.isCardUsb(addedCard)) { selectAudioCard(addedCard); mAudioDevices.put(usbDevice, mSelectedAudioDevice); UsbAudioDevice audioDevice = selectAudioCard(addedCard); if (audioDevice != null) { mAudioDevices.put(usbDevice, audioDevice); } // look for MIDI devices Loading Loading @@ -420,14 +415,14 @@ public final class UsbAlsaManager { /* package */ void usbDeviceRemoved(UsbDevice usbDevice) { if (DEBUG) { Slog.d(TAG, "deviceRemoved(): " + usbDevice); Slog.d(TAG, "deviceRemoved(): " + usbDevice.getManufacturerName() + " " + usbDevice.getProductName()); } UsbAudioDevice audioDevice = mAudioDevices.remove(usbDevice); if (audioDevice != null) { if (audioDevice.mHasPlayback || audioDevice.mHasPlayback) { notifyDeviceState(audioDevice, false); mSelectedAudioDevice = null; // if there any external devices left, select one of them selectDefaultDevice(); Loading Loading
services/core/java/com/android/server/audio/AudioService.java +118 −70 Original line number Diff line number Diff line Loading @@ -141,6 +141,9 @@ public class AudioService extends IAudioService.Stub { /** debug calls to media session apis */ private static final boolean DEBUG_SESSIONS = Log.isLoggable(TAG + ".SESSIONS", Log.DEBUG); /** debug calls to devices APIs */ protected static final boolean DEBUG_DEVICES = Log.isLoggable(TAG + ".DEVICES", Log.DEBUG); /** Allow volume changes to set ringer mode to silent? */ private static final boolean VOLUME_SETS_RINGER_MODE_SILENT = false; Loading Loading @@ -376,7 +379,32 @@ public class AudioService extends IAudioService.Stub { private final BroadcastReceiver mReceiver = new AudioServiceBroadcastReceiver(); // Devices currently connected private final HashMap <Integer, String> mConnectedDevices = new HashMap <Integer, String>(); // Use makeDeviceListKey() to make a unique key for this list. private class DeviceListSpec { int mDeviceType; String mDeviceName; String mDeviceAddress; public DeviceListSpec(int deviceType, String deviceName, String deviceAddress) { mDeviceType = deviceType; mDeviceName = deviceName; mDeviceAddress = deviceAddress; } public String toString() { return "[type:0x" + Integer.toHexString(mDeviceType) + " name:" + mDeviceName + " address:" + mDeviceAddress + "]"; } } // Generate a unique key for the mConnectedDevices List by composing the device "type" // and the "address" associated with a specific instance of that device type private String makeDeviceListKey(int device, String deviceAddress) { return "0x" + Integer.toHexString(device) + ":" + deviceAddress; } private final HashMap<String, DeviceListSpec> mConnectedDevices = new HashMap<String, DeviceListSpec>(); // Forced device usage for communications private int mForcedUseForComm; Loading Loading @@ -520,6 +548,8 @@ public class AudioService extends IAudioService.Stub { return "card=" + card + ";device=" + device + ";"; } private final String DEVICE_NAME_A2DP = "a2dp-device"; /////////////////////////////////////////////////////////////////////////// // Construction /////////////////////////////////////////////////////////////////////////// Loading Loading @@ -2771,10 +2801,13 @@ public class AudioService extends IAudioService.Stub { case BluetoothProfile.A2DP: synchronized (mConnectedDevices) { synchronized (mA2dpAvrcpLock) { mA2dp = null; if (mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP)) { makeA2dpDeviceUnavailableNow( mConnectedDevices.get(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP)); // Disconnect ALL DEVICE_OUT_BLUETOOTH_A2DP devices for(Map.Entry<String, DeviceListSpec> entry : mConnectedDevices.entrySet()) { DeviceListSpec deviceSpec = entry.getValue(); if (deviceSpec.mDeviceType == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) { makeA2dpDeviceUnavailableNow(deviceSpec.mDeviceAddress); } } } } Loading @@ -2782,9 +2815,13 @@ public class AudioService extends IAudioService.Stub { case BluetoothProfile.A2DP_SINK: synchronized (mConnectedDevices) { if (mConnectedDevices.containsKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP)) { makeA2dpSrcUnavailable( mConnectedDevices.get(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP)); // Disconnect ALL DEVICE_IN_BLUETOOTH_A2DP devices for(Map.Entry<String, DeviceListSpec> entry : mConnectedDevices.entrySet()) { DeviceListSpec deviceSpec = entry.getValue(); if (deviceSpec.mDeviceType == AudioSystem.DEVICE_IN_BLUETOOTH_A2DP) { makeA2dpSrcUnavailable(deviceSpec.mDeviceAddress); } } } break; Loading Loading @@ -3272,6 +3309,10 @@ public class AudioService extends IAudioService.Stub { public void setWiredDeviceConnectionState(int type, int state, String address, String name) { synchronized (mConnectedDevices) { if (DEBUG_DEVICES) { Slog.i(TAG, "setWiredDeviceConnectionState(" + state + " nm: " + name + " addr:" + address + ")"); } int delay = checkSendBecomingNoisyIntent(type, state); queueMsgUnderWakeLock(mAudioHandler, MSG_SET_WIRED_DEVICE_CONNECTION_STATE, Loading Loading @@ -4236,13 +4277,13 @@ public class AudioService extends IAudioService.Stub { AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0, streamState, 0); setBluetoothA2dpOnInt(true); AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, AudioSystem.DEVICE_STATE_AVAILABLE, address, "a2dp-device"); AudioSystem.DEVICE_STATE_AVAILABLE, address, DEVICE_NAME_A2DP); // Reset A2DP suspend state each time a new sink is connected AudioSystem.setParameters("A2dpSuspended=false"); mConnectedDevices.put( new Integer(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP), address); mConnectedDevices.put( makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address), new DeviceListSpec(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, DEVICE_NAME_A2DP, address)); } private void onSendBecomingNoisyIntent() { Loading @@ -4255,10 +4296,9 @@ public class AudioService extends IAudioService.Stub { mAvrcpAbsVolSupported = false; } AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, AudioSystem.DEVICE_STATE_UNAVAILABLE, address, "a2dp-device"); mConnectedDevices.remove(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP); AudioSystem.DEVICE_STATE_UNAVAILABLE, address, DEVICE_NAME_A2DP); mConnectedDevices.remove( makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address)); synchronized (mCurAudioRoutes) { // Remove A2DP routes as well if (mCurAudioRoutes.bluetoothName != null) { Loading @@ -4275,7 +4315,8 @@ public class AudioService extends IAudioService.Stub { // reconnection of the sink. AudioSystem.setParameters("A2dpSuspended=true"); // the device will be made unavailable later, so consider it disconnected right away mConnectedDevices.remove(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP); mConnectedDevices.remove( makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address)); // send the delayed message to make the device unavailable later Message msg = mAudioHandler.obtainMessage(MSG_BTA2DP_DOCK_TIMEOUT, address); mAudioHandler.sendMessageDelayed(msg, BTA2DP_DOCK_TIMEOUT_MILLIS); Loading @@ -4285,20 +4326,19 @@ public class AudioService extends IAudioService.Stub { // must be called synchronized on mConnectedDevices private void makeA2dpSrcAvailable(String address) { AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, AudioSystem.DEVICE_STATE_AVAILABLE, address, "a2dp-device"); mConnectedDevices.put( new Integer(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP), address); AudioSystem.DEVICE_STATE_AVAILABLE, address, DEVICE_NAME_A2DP); mConnectedDevices.put( makeDeviceListKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address), new DeviceListSpec(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, DEVICE_NAME_A2DP, address)); } // must be called synchronized on mConnectedDevices private void makeA2dpSrcUnavailable(String address) { AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, AudioSystem.DEVICE_STATE_UNAVAILABLE, address, "a2dp-device"); mConnectedDevices.remove(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP); AudioSystem.DEVICE_STATE_UNAVAILABLE, address, DEVICE_NAME_A2DP); mConnectedDevices.remove( makeDeviceListKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address)); } // must be called synchronized on mConnectedDevices Loading @@ -4325,9 +4365,10 @@ public class AudioService extends IAudioService.Stub { } synchronized (mConnectedDevices) { boolean isConnected = (mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) && mConnectedDevices.get(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP).equals(address)); String key = makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, btDevice.getAddress()); DeviceListSpec deviceSpec = mConnectedDevices.get(key); boolean isConnected = deviceSpec != null; if (isConnected && state != BluetoothProfile.STATE_CONNECTED) { if (btDevice.isBluetoothDock()) { Loading Loading @@ -4388,9 +4429,9 @@ public class AudioService extends IAudioService.Stub { } synchronized (mConnectedDevices) { boolean isConnected = (mConnectedDevices.containsKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP) && mConnectedDevices.get(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP).equals(address)); String key = makeDeviceListKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address); DeviceListSpec deviceSpec = mConnectedDevices.get(key); boolean isConnected = deviceSpec != null; if (isConnected && state != BluetoothProfile.STATE_CONNECTED) { makeA2dpSrcUnavailable(address); Loading @@ -4413,26 +4454,31 @@ public class AudioService extends IAudioService.Stub { } } private boolean handleDeviceConnection(boolean connect, int device, String address, String deviceName) { Slog.i(TAG, "handleDeviceConnection(" + connect + " dev:" + Integer.toHexString(device) + " address:" + address + " name:" + deviceName + ")"); private boolean handleDeviceConnection(boolean connect, int device, String address, String deviceName) { if (DEBUG_DEVICES) { Slog.i(TAG, "handleDeviceConnection(" + connect + " dev:" + Integer.toHexString(device) + " address:" + address + " name:" + deviceName + ")"); } synchronized (mConnectedDevices) { boolean isConnected = (mConnectedDevices.containsKey(device) && (address.isEmpty() || mConnectedDevices.get(device).equals(address))); if (isConnected && !connect) { AudioSystem.setDeviceConnectionState(device, AudioSystem.DEVICE_STATE_UNAVAILABLE, String deviceKey = makeDeviceListKey(device, address); if (DEBUG_DEVICES) { Slog.i(TAG, "deviceKey:" + deviceKey); } DeviceListSpec deviceSpec = mConnectedDevices.get(deviceKey); boolean isConnected = deviceSpec != null; if (DEBUG_DEVICES) { Slog.i(TAG, "deviceSpec:" + deviceSpec + " is(already)Connected:" + isConnected); } if (connect && !isConnected) { AudioSystem.setDeviceConnectionState(device, AudioSystem.DEVICE_STATE_AVAILABLE, address, deviceName); mConnectedDevices.remove(device); mConnectedDevices.put(deviceKey, new DeviceListSpec(device, deviceName, address)); return true; } else if (!isConnected && connect) { AudioSystem.setDeviceConnectionState(device, AudioSystem.DEVICE_STATE_AVAILABLE, } else if (!connect && isConnected) { AudioSystem.setDeviceConnectionState(device, AudioSystem.DEVICE_STATE_UNAVAILABLE, address, deviceName); mConnectedDevices.put(new Integer(device), address); mConnectedDevices.remove(deviceKey); return true; } } Loading @@ -4454,9 +4500,10 @@ public class AudioService extends IAudioService.Stub { int delay = 0; if ((state == 0) && ((device & mBecomingNoisyIntentDevices) != 0)) { int devices = 0; for (int dev : mConnectedDevices.keySet()) { if (((dev & AudioSystem.DEVICE_BIT_IN) == 0) && ((dev & mBecomingNoisyIntentDevices) != 0)) { for (String key : mConnectedDevices.keySet()) { int dev = mConnectedDevices.get(key).mDeviceType; if (((dev & AudioSystem.DEVICE_BIT_IN) == 0) && ((dev & mBecomingNoisyIntentDevices) != 0)) { devices |= dev; } } Loading Loading @@ -4485,12 +4532,13 @@ public class AudioService extends IAudioService.Stub { return delay; } private void sendDeviceConnectionIntent(int device, int state, String address, String deviceName) { private void sendDeviceConnectionIntent(int device, int state, String address, String deviceName) { if (DEBUG_DEVICES) { Slog.i(TAG, "sendDeviceConnectionIntent(dev:0x" + Integer.toHexString(device) + " state:0x" + Integer.toHexString(state) + " address:" + address + " state:0x" + Integer.toHexString(state) + " address:" + address + " name:" + deviceName + ");"); } Intent intent = new Intent(); intent.putExtra(CONNECT_INTENT_KEY_STATE, state); Loading Loading @@ -4544,12 +4592,12 @@ public class AudioService extends IAudioService.Stub { } private void onSetWiredDeviceConnectionState(int device, int state, String address, String deviceName) { Slog.i(TAG, "onSetWiredDeviceConnectionState(dev:" + Integer.toHexString(device) + " state:" + Integer.toHexString(state) + " address:" + address + " deviceName:" + deviceName + ");"); String deviceName) { if (DEBUG_DEVICES) { Slog.i(TAG, "onSetWiredDeviceConnectionState(dev:" + Integer.toHexString(device) + " state:" + Integer.toHexString(state) + " address:" + address + " deviceName:" + deviceName + ");"); } synchronized (mConnectedDevices) { if ((state == 0) && ((device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) || Loading
services/usb/java/com/android/server/usb/UsbAlsaManager.java +23 −28 Original line number Diff line number Diff line Loading @@ -73,8 +73,6 @@ public final class UsbAlsaManager { private UsbAudioDevice mAccessoryAudioDevice = null; private UsbAudioDevice mSelectedAudioDevice = null; // UsbMidiDevice for USB peripheral mode (gadget) device private UsbMidiDevice mPeripheralMidiDevice = null; Loading Loading @@ -186,6 +184,10 @@ public final class UsbAlsaManager { int device = (audioDevice == mAccessoryAudioDevice ? AudioSystem.DEVICE_OUT_USB_ACCESSORY : AudioSystem.DEVICE_OUT_USB_DEVICE); if (DEBUG) { Slog.i(TAG, "pre-call device:0x" + Integer.toHexString(device) + " addr:" + address + " name:" + audioDevice.mDeviceName); } mAudioService.setWiredDeviceConnectionState( device, state, address, audioDevice.mDeviceName); } Loading Loading @@ -282,23 +284,13 @@ public final class UsbAlsaManager { /* * Select the default device of the specified card. */ /* package */ boolean selectAudioCard(int card) { /* package */ UsbAudioDevice selectAudioCard(int card) { if (DEBUG) { Slog.d(TAG, "selectAudioCard() card:" + card); } if (!mCardsParser.isCardUsb(card)) { // Don't. AudioPolicyManager has logic for falling back to internal devices. return false; } if (mSelectedAudioDevice != null) { if (mSelectedAudioDevice.mCard == card) { // Nothing to do here. return false; } // "disconnect" the AudioPolicyManager from the previously selected device. notifyDeviceState(mSelectedAudioDevice, false); mSelectedAudioDevice = null; return null; } mDevicesParser.scan(); Loading @@ -314,30 +306,30 @@ public final class UsbAlsaManager { // Playback device file needed/present? if (hasPlayback && (waitForAlsaDevice(card, device, AlsaDevice.TYPE_PLAYBACK) == null)) { return false; return null; } // Capture device file needed/present? if (hasCapture && (waitForAlsaDevice(card, device, AlsaDevice.TYPE_CAPTURE) == null)) { return false; return null; } if (DEBUG) { Slog.d(TAG, "usb: hasPlayback:" + hasPlayback + " hasCapture:" + hasCapture); } mSelectedAudioDevice = UsbAudioDevice audioDevice = new UsbAudioDevice(card, device, hasPlayback, hasCapture, deviceClass); mSelectedAudioDevice.mDeviceName = mCardsParser.getCardRecordFor(card).mCardName; mSelectedAudioDevice.mDeviceDescription = mCardsParser.getCardRecordFor(card).mCardDescription; AlsaCardsParser.AlsaCardRecord cardRecord = mCardsParser.getCardRecordFor(card); audioDevice.mDeviceName = cardRecord.mCardName; audioDevice.mDeviceDescription = cardRecord.mCardDescription; notifyDeviceState(mSelectedAudioDevice, true); notifyDeviceState(audioDevice, true); return true; return audioDevice; } /* package */ boolean selectDefaultDevice() { /* package */ UsbAudioDevice selectDefaultDevice() { if (DEBUG) { Slog.d(TAG, "UsbAudioManager.selectDefaultDevice()"); } Loading @@ -347,7 +339,8 @@ public final class UsbAlsaManager { /* package */ void usbDeviceAdded(UsbDevice usbDevice) { if (DEBUG) { Slog.d(TAG, "usbDeviceAdded(): " + usbDevice); Slog.d(TAG, "deviceAdded(): " + usbDevice.getManufacturerName() + "nm:" + usbDevice.getProductName()); } // Is there an audio interface in there? Loading Loading @@ -384,8 +377,10 @@ public final class UsbAlsaManager { // If the default isn't a USB device, let the existing "select internal mechanism" // handle the selection. if (mCardsParser.isCardUsb(addedCard)) { selectAudioCard(addedCard); mAudioDevices.put(usbDevice, mSelectedAudioDevice); UsbAudioDevice audioDevice = selectAudioCard(addedCard); if (audioDevice != null) { mAudioDevices.put(usbDevice, audioDevice); } // look for MIDI devices Loading Loading @@ -420,14 +415,14 @@ public final class UsbAlsaManager { /* package */ void usbDeviceRemoved(UsbDevice usbDevice) { if (DEBUG) { Slog.d(TAG, "deviceRemoved(): " + usbDevice); Slog.d(TAG, "deviceRemoved(): " + usbDevice.getManufacturerName() + " " + usbDevice.getProductName()); } UsbAudioDevice audioDevice = mAudioDevices.remove(usbDevice); if (audioDevice != null) { if (audioDevice.mHasPlayback || audioDevice.mHasPlayback) { notifyDeviceState(audioDevice, false); mSelectedAudioDevice = null; // if there any external devices left, select one of them selectDefaultDevice(); Loading