UsbAudioManagerpublic class UsbAudioManager extends Object UsbAudioManager manages USB audio devices. |
Fields Summary |
---|
private static final String | TAG | private static final boolean | DEBUG | private final android.content.Context | mContext | private final HashMap | mAudioDevices |
Methods Summary |
---|
void | deviceAdded(android.hardware.usb.UsbDevice usbDevice)
// Is there an audio interface in there?
boolean isAudioDevice = false;
// FIXME - handle multiple configurations?
int interfaceCount = usbDevice.getInterfaceCount();
for (int ntrfaceIndex = 0; !isAudioDevice && ntrfaceIndex < interfaceCount;
ntrfaceIndex++) {
UsbInterface ntrface = usbDevice.getInterface(ntrfaceIndex);
if (ntrface.getInterfaceClass() == UsbConstants.USB_CLASS_AUDIO) {
isAudioDevice = true;
}
}
if (!isAudioDevice) {
return;
}
//TODO(pmclean) The "Parser" objects inspect files in "/proc/asound" which we presume is
// present, unlike the waitForAlsaFile() which waits on a file in /dev/snd. It is not
// clear why this works, or that it can be relied on going forward. Needs further
// research.
AlsaCardsParser cardsParser = new AlsaCardsParser();
cardsParser.scan();
// cardsParser.Log();
// But we need to parse the device to determine its capabilities.
AlsaDevicesParser devicesParser = new AlsaDevicesParser();
devicesParser.scan();
// devicesParser.Log();
// The protocol for now will be to select the last-connected (highest-numbered)
// Alsa Card.
int card = cardsParser.getNumCardRecords() - 1;
int device = 0;
boolean hasPlayback = devicesParser.hasPlaybackDevices(card);
boolean hasCapture = devicesParser.hasCaptureDevices(card);
boolean hasMidi = devicesParser.hasMIDIDevices(card);
// Playback device file needed/present?
if (hasPlayback &&
!waitForAlsaFile(card, device, false)) {
return;
}
// Capture device file needed/present?
if (hasCapture &&
!waitForAlsaFile(card, device, true)) {
return;
}
if (DEBUG) {
Slog.d(TAG,
"usb: hasPlayback:" + hasPlayback + " hasCapture:" + hasCapture);
}
AudioDevice audioDevice = new AudioDevice(card, device, hasPlayback, hasCapture, hasMidi);
mAudioDevices.put(usbDevice, audioDevice);
sendDeviceNotification(audioDevice, true);
| void | deviceRemoved(android.hardware.usb.UsbDevice device)
if (DEBUG) {
Slog.d(TAG, "deviceRemoved(): " + device);
}
AudioDevice audioDevice = mAudioDevices.remove(device);
if (audioDevice != null) {
sendDeviceNotification(audioDevice, false);
}
| public void | dump(java.io.FileDescriptor fd, java.io.PrintWriter pw)
pw.println(" USB AudioDevices:");
for (UsbDevice device : mAudioDevices.keySet()) {
pw.println(" " + device.getDeviceName() + ": " + mAudioDevices.get(device));
}
| private void | sendDeviceNotification(com.android.server.usb.UsbAudioManager$AudioDevice audioDevice, boolean enabled)
// send a sticky broadcast containing current USB state
Intent intent = new Intent(AudioManager.ACTION_USB_AUDIO_DEVICE_PLUG);
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
intent.putExtra("state", enabled ? 1 : 0);
intent.putExtra("card", audioDevice.mCard);
intent.putExtra("device", audioDevice.mDevice);
intent.putExtra("hasPlayback", audioDevice.mHasPlayback);
intent.putExtra("hasCapture", audioDevice.mHasCapture);
intent.putExtra("hasMIDI", audioDevice.mHasMIDI);
mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
| private boolean | waitForAlsaFile(int card, int device, boolean capture)
// These values were empirically determined.
final int kNumRetries = 5;
final int kSleepTime = 500; // ms
String alsaDevPath = "/dev/snd/pcmC" + card + "D" + device + (capture ? "c" : "p");
File alsaDevFile = new File(alsaDevPath);
boolean exists = false;
for (int retry = 0; !exists && retry < kNumRetries; retry++) {
exists = alsaDevFile.exists();
if (!exists) {
try {
Thread.sleep(kSleepTime);
} catch (IllegalThreadStateException ex) {
Slog.d(TAG, "usb: IllegalThreadStateException while waiting for ALSA file.");
} catch (java.lang.InterruptedException ex) {
Slog.d(TAG, "usb: InterruptedException while waiting for ALSA file.");
}
}
}
return exists;
|
|