summaryrefslogtreecommitdiffstats
path: root/services/usb/java
diff options
context:
space:
mode:
authorMike Lockwood <lockwood@google.com>2015-01-08 14:38:40 -0800
committerMike Lockwood <lockwood@google.com>2015-01-16 09:23:15 -0800
commit2e3434149e00f921ca3555ae55cba04d3c64eeb1 (patch)
tree98af168ad274f8dd3fc42b096f67525d6d11ed37 /services/usb/java
parent1b69655d7d2630ab9825c2fd08cf76c5d3382d9f (diff)
downloadframeworks_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')
-rw-r--r--services/usb/java/com/android/server/usb/UsbAlsaManager.java109
-rw-r--r--services/usb/java/com/android/server/usb/UsbDeviceManager.java20
-rw-r--r--services/usb/java/com/android/server/usb/UsbHostManager.java13
-rw-r--r--services/usb/java/com/android/server/usb/UsbService.java10
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++) {