diff options
author | Mike Lockwood <lockwood@google.com> | 2015-01-08 14:38:40 -0800 |
---|---|---|
committer | Mike Lockwood <lockwood@google.com> | 2015-01-16 09:23:15 -0800 |
commit | 2e3434149e00f921ca3555ae55cba04d3c64eeb1 (patch) | |
tree | 98af168ad274f8dd3fc42b096f67525d6d11ed37 /services/usb/java | |
parent | 1b69655d7d2630ab9825c2fd08cf76c5d3382d9f (diff) | |
download | frameworks_base-2e3434149e00f921ca3555ae55cba04d3c64eeb1.zip frameworks_base-2e3434149e00f921ca3555ae55cba04d3c64eeb1.tar.gz frameworks_base-2e3434149e00f921ca3555ae55cba04d3c64eeb1.tar.bz2 |
Replace broadcasts with calls to IAudioService.setWiredDeviceConnectionState() to report USB device status
Change-Id: Ic96cffaa63b6c6350b76e7cb29398c5f5dc86962
Diffstat (limited to 'services/usb/java')
4 files changed, 104 insertions, 48 deletions
diff --git a/services/usb/java/com/android/server/usb/UsbAlsaManager.java b/services/usb/java/com/android/server/usb/UsbAlsaManager.java index 6589135..01a044e 100644 --- a/services/usb/java/com/android/server/usb/UsbAlsaManager.java +++ b/services/usb/java/com/android/server/usb/UsbAlsaManager.java @@ -23,12 +23,15 @@ import android.content.Intent; import android.hardware.usb.UsbConstants; import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbInterface; -import android.media.AudioManager; +import android.media.AudioSystem; +import android.media.IAudioService; import android.os.FileObserver; import android.os.IBinder; +import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; import android.os.UserHandle; +import android.provider.Settings; import android.util.Slog; import libcore.io.IoUtils; @@ -49,6 +52,7 @@ public final class UsbAlsaManager { private static final String ALSA_DIRECTORY = "/dev/snd/"; private final Context mContext; + private IAudioService mAudioService; private final AlsaCardsParser mCardsParser = new AlsaCardsParser(); private final AlsaDevicesParser mDevicesParser = new AlsaDevicesParser(); @@ -65,6 +69,8 @@ public final class UsbAlsaManager { private final HashMap<String,AlsaDevice> mAlsaDevices = new HashMap<String,AlsaDevice>(); + private UsbAudioDevice mAccessoryAudioDevice = null; + private UsbAudioDevice mSelectedAudioDevice = null; private final class AlsaDevice { @@ -123,6 +129,9 @@ public final class UsbAlsaManager { } public void systemReady() { + mAudioService = IAudioService.Stub.asInterface( + ServiceManager.getService(Context.AUDIO_SERVICE)); + mAlsaObserver.startWatching(); // add existing alsa devices @@ -132,27 +141,59 @@ public final class UsbAlsaManager { } } - // Broadcasts the arrival/departure of a USB audio interface - // audioDevice - the UsbAudioDevice that was added or removed + // Notifies AudioService when a device is added or removed + // audioDevice - the AudioDevice that was added or removed // enabled - if true, we're connecting a device (it's arrived), else disconnecting - private void sendDeviceNotification(UsbAudioDevice audioDevice, boolean enabled) { - if (DEBUG) { - Slog.d(TAG, "sendDeviceNotification(enabled:" + enabled + - " c:" + audioDevice.mCard + - " d:" + audioDevice.mDevice + ")"); - } - - // 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("class", audioDevice.mDeviceClass); - mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); + private void notifyDeviceState(UsbAudioDevice audioDevice, boolean enabled) { + if (DEBUG) { + Slog.d(TAG, "notifyDeviceState " + enabled + " " + audioDevice); + } + + if (mAudioService == null) { + Slog.e(TAG, "no AudioService"); + return; + } + + // FIXME Does not yet handle the case where the setting is changed + // after device connection. Ideally we should handle the settings change + // in SettingsObserver. Here we should log that a USB device is connected + // and disconnected with its address (card , device) and force the + // connection or disconnection when the setting changes. + int isDisabled = Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.USB_AUDIO_AUTOMATIC_ROUTING_DISABLED, 0); + if (isDisabled != 0) { + return; + } + + int state = (enabled ? 1 : 0); + int alsaCard = audioDevice.mCard; + int alsaDevice = audioDevice.mDevice; + if (alsaCard < 0 || alsaDevice < 0) { + Slog.e(TAG, "Invalid alsa card or device alsaCard: " + alsaCard + + " alsaDevice: " + alsaDevice); + return; + } + String params = ("card=" + alsaCard + ";device=" + alsaDevice); + + try { + // Playback Device + if (audioDevice.mHasPlayback) { + int device = (audioDevice == mAccessoryAudioDevice ? + AudioSystem.DEVICE_OUT_USB_ACCESSORY : + AudioSystem.DEVICE_OUT_USB_DEVICE); + mAudioService.setWiredDeviceConnectionState(device, state, params); + } + + // Capture Device + if (audioDevice.mHasCapture) { + int device = (audioDevice == mAccessoryAudioDevice ? + AudioSystem.DEVICE_IN_USB_ACCESSORY : + AudioSystem.DEVICE_IN_USB_DEVICE); + mAudioService.setWiredDeviceConnectionState(device, state, params); + } + } catch (RemoteException e) { + Slog.e(TAG, "RemoteException in setWiredDeviceConnectionState"); + } } private AlsaDevice waitForAlsaDevice(int card, int device, int type) { @@ -249,7 +290,7 @@ public final class UsbAlsaManager { return false; } // "disconnect" the AudioPolicyManager from the previously selected device. - sendDeviceNotification(mSelectedAudioDevice, false); + notifyDeviceState(mSelectedAudioDevice, false); mSelectedAudioDevice = null; } @@ -284,7 +325,7 @@ public final class UsbAlsaManager { mSelectedAudioDevice.mDeviceDescription = mCardsParser.getCardRecordFor(card).mCardDescription; - sendDeviceNotification(mSelectedAudioDevice, true); + notifyDeviceState(mSelectedAudioDevice, true); return true; } @@ -297,9 +338,9 @@ public final class UsbAlsaManager { return selectAudioCard(mCardsParser.getDefaultCard()); } - /* package */ void deviceAdded(UsbDevice usbDevice) { + /* package */ void usbDeviceAdded(UsbDevice usbDevice) { if (DEBUG) { - Slog.d(TAG, "deviceAdded(): " + usbDevice); + Slog.d(TAG, "usbDeviceAdded(): " + usbDevice); } // Is there an audio interface in there? @@ -360,7 +401,7 @@ public final class UsbAlsaManager { } } - /* package */ void deviceRemoved(UsbDevice usbDevice) { + /* package */ void usbDeviceRemoved(UsbDevice usbDevice) { if (DEBUG) { Slog.d(TAG, "deviceRemoved(): " + usbDevice); } @@ -368,7 +409,7 @@ public final class UsbAlsaManager { UsbAudioDevice audioDevice = mAudioDevices.remove(usbDevice); if (audioDevice != null) { if (audioDevice.mHasPlayback || audioDevice.mHasPlayback) { - sendDeviceNotification(audioDevice, false); + notifyDeviceState(audioDevice, false); } } UsbMidiDevice usbMidiDevice = mMidiDevices.remove(usbDevice); @@ -382,6 +423,20 @@ public final class UsbAlsaManager { selectDefaultDevice(); } + /* package */ void setAccessoryAudioState(boolean enabled, int card, int device) { + if (DEBUG) { + Slog.d(TAG, "setAccessoryAudioState " + enabled + " " + card + " " + device); + } + if (enabled) { + mAccessoryAudioDevice = new UsbAudioDevice(card, device, true, false, + UsbAudioDevice.kAudioDeviceClass_External); + notifyDeviceState(mAccessoryAudioDevice, true); + } else if (mAccessoryAudioDevice != null) { + notifyDeviceState(mAccessoryAudioDevice, false); + mAccessoryAudioDevice = null; + } + } + // // Devices List // diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java index f3fa747..1426551 100644 --- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java @@ -127,6 +127,7 @@ public class UsbDeviceManager { private Map<String, List<Pair<String, String>>> mOemModeMap; private String[] mAccessoryStrings; private UsbDebuggingManager mDebuggingManager; + private final UsbAlsaManager mUsbAlsaManager; private class AdbSettingsObserver extends ContentObserver { public AdbSettingsObserver() { @@ -159,8 +160,9 @@ public class UsbDeviceManager { } }; - public UsbDeviceManager(Context context) { + public UsbDeviceManager(Context context, UsbAlsaManager alsaManager) { mContext = context; + mUsbAlsaManager = alsaManager; mContentResolver = context.getContentResolver(); PackageManager pm = mContext.getPackageManager(); mHasUsbAccessory = pm.hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY); @@ -594,19 +596,15 @@ public class UsbDeviceManager { boolean enabled = containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_AUDIO_SOURCE); if (enabled != mAudioSourceEnabled) { - // send a sticky broadcast containing current USB state - Intent intent = new Intent(AudioManager.ACTION_USB_AUDIO_ACCESSORY_PLUG); - intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); - intent.putExtra("state", (enabled ? 1 : 0)); + int card = -1; + int device = -1; + if (enabled) { Scanner scanner = null; try { scanner = new Scanner(new File(AUDIO_SOURCE_PCM_PATH)); - int card = scanner.nextInt(); - int device = scanner.nextInt(); - intent.putExtra("card", card); - intent.putExtra("device", device); + card = scanner.nextInt(); + device = scanner.nextInt(); } catch (FileNotFoundException e) { Slog.e(TAG, "could not open audio source PCM file", e); } finally { @@ -615,7 +613,7 @@ public class UsbDeviceManager { } } } - mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); + mUsbAlsaManager.setAccessoryAudioState(enabled, card, device); mAudioSourceEnabled = enabled; } } diff --git a/services/usb/java/com/android/server/usb/UsbHostManager.java b/services/usb/java/com/android/server/usb/UsbHostManager.java index cd0f41a..c53fea2 100644 --- a/services/usb/java/com/android/server/usb/UsbHostManager.java +++ b/services/usb/java/com/android/server/usb/UsbHostManager.java @@ -60,16 +60,16 @@ public class UsbHostManager { private ArrayList<UsbInterface> mNewInterfaces; private ArrayList<UsbEndpoint> mNewEndpoints; - private UsbAlsaManager mUsbAlsaManager; + private final UsbAlsaManager mUsbAlsaManager; @GuardedBy("mLock") private UsbSettingsManager mCurrentSettings; - public UsbHostManager(Context context) { + public UsbHostManager(Context context, UsbAlsaManager alsaManager) { mContext = context; mHostBlacklist = context.getResources().getStringArray( com.android.internal.R.array.config_usbHostBlacklist); - mUsbAlsaManager = new UsbAlsaManager(context); + mUsbAlsaManager = alsaManager; } public void setCurrentSettings(UsbSettingsManager settings) { @@ -222,7 +222,7 @@ public class UsbHostManager { mDevices.put(mNewDevice.getDeviceName(), mNewDevice); Slog.d(TAG, "Added device " + mNewDevice); getCurrentSettings().deviceAttached(mNewDevice); - mUsbAlsaManager.deviceAdded(mNewDevice); + mUsbAlsaManager.usbDeviceAdded(mNewDevice); } else { Slog.e(TAG, "mNewDevice is null in endUsbDeviceAdded"); } @@ -238,15 +238,13 @@ public class UsbHostManager { synchronized (mLock) { UsbDevice device = mDevices.remove(deviceName); if (device != null) { - mUsbAlsaManager.deviceRemoved(device); + mUsbAlsaManager.usbDeviceRemoved(device); getCurrentSettings().deviceDetached(device); } } } public void systemReady() { - mUsbAlsaManager.systemReady(); - synchronized (mLock) { // Create a thread to call into native code to wait for USB host events. // This thread will call us back on usbDeviceAdded and usbDeviceRemoved. @@ -292,7 +290,6 @@ public class UsbHostManager { pw.println(" " + name + ": " + mDevices.get(name)); } } - mUsbAlsaManager.dump(fd, pw); } private native void monitorUsbHostBus(); diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java index fd83f92..fda8076 100644 --- a/services/usb/java/com/android/server/usb/UsbService.java +++ b/services/usb/java/com/android/server/usb/UsbService.java @@ -73,6 +73,7 @@ public class UsbService extends IUsbManager.Stub { private UsbDeviceManager mDeviceManager; private UsbHostManager mHostManager; + private final UsbAlsaManager mAlsaManager; private final Object mLock = new Object(); @@ -95,12 +96,14 @@ public class UsbService extends IUsbManager.Stub { public UsbService(Context context) { mContext = context; + mAlsaManager = new UsbAlsaManager(context); + final PackageManager pm = mContext.getPackageManager(); if (pm.hasSystemFeature(PackageManager.FEATURE_USB_HOST)) { - mHostManager = new UsbHostManager(context); + mHostManager = new UsbHostManager(context, mAlsaManager); } if (new File("/sys/class/android_usb").exists()) { - mDeviceManager = new UsbDeviceManager(context); + mDeviceManager = new UsbDeviceManager(context, mAlsaManager); } setCurrentUser(UserHandle.USER_OWNER); @@ -137,6 +140,8 @@ public class UsbService extends IUsbManager.Stub { } public void systemReady() { + mAlsaManager.systemReady(); + if (mDeviceManager != null) { mDeviceManager.systemReady(); } @@ -305,6 +310,7 @@ public class UsbService extends IUsbManager.Stub { if (mHostManager != null) { mHostManager.dump(fd, pw); } + mAlsaManager.dump(fd, pw); synchronized (mLock) { for (int i = 0; i < mSettingsByUser.size(); i++) { |