summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/hardware/usb/UsbAccessory.java25
-rw-r--r--services/java/com/android/server/usb/UsbDeviceManager.java52
-rw-r--r--services/java/com/android/server/usb/UsbService.java2
-rw-r--r--services/jni/com_android_server_UsbDeviceManager.cpp13
4 files changed, 73 insertions, 19 deletions
diff --git a/core/java/android/hardware/usb/UsbAccessory.java b/core/java/android/hardware/usb/UsbAccessory.java
index 7702044..5719452 100644
--- a/core/java/android/hardware/usb/UsbAccessory.java
+++ b/core/java/android/hardware/usb/UsbAccessory.java
@@ -55,6 +55,19 @@ public class UsbAccessory implements Parcelable {
private final String mUri;
private final String mSerial;
+ /** @hide */
+ public static final int MANUFACTURER_STRING = 0;
+ /** @hide */
+ public static final int MODEL_STRING = 1;
+ /** @hide */
+ public static final int DESCRIPTION_STRING = 2;
+ /** @hide */
+ public static final int VERSION_STRING = 3;
+ /** @hide */
+ public static final int URI_STRING = 4;
+ /** @hide */
+ public static final int SERIAL_STRING = 5;
+
/**
* UsbAccessory should only be instantiated by UsbService implementation
* @hide
@@ -74,12 +87,12 @@ public class UsbAccessory implements Parcelable {
* @hide
*/
public UsbAccessory(String[] strings) {
- mManufacturer = strings[0];
- mModel = strings[1];
- mDescription = strings[2];
- mVersion = strings[3];
- mUri = strings[4];
- mSerial = strings[5];
+ mManufacturer = strings[MANUFACTURER_STRING];
+ mModel = strings[MODEL_STRING];
+ mDescription = strings[DESCRIPTION_STRING];
+ mVersion = strings[VERSION_STRING];
+ mUri = strings[URI_STRING];
+ mSerial = strings[SERIAL_STRING];
}
/**
diff --git a/services/java/com/android/server/usb/UsbDeviceManager.java b/services/java/com/android/server/usb/UsbDeviceManager.java
index 1bd15f6..33612b0 100644
--- a/services/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/java/com/android/server/usb/UsbDeviceManager.java
@@ -87,10 +87,13 @@ public class UsbDeviceManager {
private static final int MSG_UPDATE_STATE = 0;
private static final int MSG_ENABLE_ADB = 1;
- private static final int MSG_SET_CURRENT_FUNCTION = 2;
+ private static final int MSG_SET_CURRENT_FUNCTIONS = 2;
private static final int MSG_SYSTEM_READY = 3;
private static final int MSG_BOOT_COMPLETED = 4;
+ private static final int AUDIO_MODE_NONE = 0;
+ private static final int AUDIO_MODE_SOURCE = 1;
+
// Delay for debouncing USB disconnects.
// We often get rapid connect/disconnect events when enabling USB functions,
// which need debouncing.
@@ -110,6 +113,7 @@ public class UsbDeviceManager {
private boolean mAdbEnabled;
private boolean mAudioSourceEnabled;
private Map<String, List<Pair<String, String>>> mOemModeMap;
+ private String[] mAccessoryStrings;
private class AdbSettingsObserver extends ContentObserver {
public AdbSettingsObserver() {
@@ -137,7 +141,7 @@ public class UsbDeviceManager {
mHandler.updateState(state);
} else if ("START".equals(accessory)) {
if (DEBUG) Slog.d(TAG, "got accessory start");
- setCurrentFunction(UsbManager.USB_FUNCTION_ACCESSORY, false);
+ startAccessoryMode();
}
}
};
@@ -160,7 +164,7 @@ public class UsbDeviceManager {
if (nativeIsStartRequested()) {
if (DEBUG) Slog.d(TAG, "accessory attached at boot");
- setCurrentFunction(UsbManager.USB_FUNCTION_ACCESSORY, false);
+ startAccessoryMode();
}
}
@@ -187,6 +191,29 @@ public class UsbDeviceManager {
mHandler.sendEmptyMessage(MSG_SYSTEM_READY);
}
+ private void startAccessoryMode() {
+ mAccessoryStrings = nativeGetAccessoryStrings();
+ boolean enableAudio = (nativeGetAudioMode() == AUDIO_MODE_SOURCE);
+ // don't start accessory mode if our mandatory strings have not been set
+ boolean enableAccessory = (mAccessoryStrings != null &&
+ mAccessoryStrings[UsbAccessory.MANUFACTURER_STRING] != null &&
+ mAccessoryStrings[UsbAccessory.MODEL_STRING] != null);
+ String functions = null;
+
+ if (enableAccessory && enableAudio) {
+ functions = UsbManager.USB_FUNCTION_ACCESSORY + ","
+ + UsbManager.USB_FUNCTION_AUDIO_SOURCE;
+ } else if (enableAccessory) {
+ functions = UsbManager.USB_FUNCTION_ACCESSORY;
+ } else if (enableAudio) {
+ functions = UsbManager.USB_FUNCTION_AUDIO_SOURCE;
+ }
+
+ if (functions != null) {
+ setCurrentFunctions(functions, false);
+ }
+ }
+
private static void initRndisAddress() {
// configure RNDIS ethernet address based on our serial number using the same algorithm
// we had been previously using in kernel board files
@@ -467,9 +494,8 @@ public class UsbDeviceManager {
if (!mHasUsbAccessory) return;
if (mConfigured) {
- String[] strings = nativeGetAccessoryStrings();
- if (strings != null) {
- mCurrentAccessory = new UsbAccessory(strings);
+ if (mAccessoryStrings != null) {
+ mCurrentAccessory = new UsbAccessory(mAccessoryStrings);
Slog.d(TAG, "entering USB accessory mode: " + mCurrentAccessory);
// defer accessoryAttached if system is not ready
if (mBootCompleted) {
@@ -489,6 +515,7 @@ public class UsbDeviceManager {
mSettingsManager.accessoryDetached(mCurrentAccessory);
}
mCurrentAccessory = null;
+ mAccessoryStrings = null;
}
}
}
@@ -561,10 +588,10 @@ public class UsbDeviceManager {
case MSG_ENABLE_ADB:
setAdbEnabled(msg.arg1 == 1);
break;
- case MSG_SET_CURRENT_FUNCTION:
- String function = (String)msg.obj;
+ case MSG_SET_CURRENT_FUNCTIONS:
+ String functions = (String)msg.obj;
boolean makeDefault = (msg.arg1 == 1);
- setEnabledFunctions(function, makeDefault);
+ setEnabledFunctions(functions, makeDefault);
break;
case MSG_SYSTEM_READY:
updateUsbNotification();
@@ -717,9 +744,9 @@ public class UsbDeviceManager {
return nativeOpenAccessory();
}
- public void setCurrentFunction(String function, boolean makeDefault) {
- if (DEBUG) Slog.d(TAG, "setCurrentFunction(" + function + ") default: " + makeDefault);
- mHandler.sendMessage(MSG_SET_CURRENT_FUNCTION, function, makeDefault);
+ public void setCurrentFunctions(String functions, boolean makeDefault) {
+ if (DEBUG) Slog.d(TAG, "setCurrentFunctions(" + functions + ") default: " + makeDefault);
+ mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions, makeDefault);
}
public void setMassStorageBackingFile(String path) {
@@ -787,4 +814,5 @@ public class UsbDeviceManager {
private native String[] nativeGetAccessoryStrings();
private native ParcelFileDescriptor nativeOpenAccessory();
private native boolean nativeIsStartRequested();
+ private native int nativeGetAudioMode();
}
diff --git a/services/java/com/android/server/usb/UsbService.java b/services/java/com/android/server/usb/UsbService.java
index 9f2c17a..0205ef8 100644
--- a/services/java/com/android/server/usb/UsbService.java
+++ b/services/java/com/android/server/usb/UsbService.java
@@ -149,7 +149,7 @@ public class UsbService extends IUsbManager.Stub {
public void setCurrentFunction(String function, boolean makeDefault) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
if (mDeviceManager != null) {
- mDeviceManager.setCurrentFunction(function, makeDefault);
+ mDeviceManager.setCurrentFunctions(function, makeDefault);
} else {
throw new IllegalStateException("USB device mode not supported");
}
diff --git a/services/jni/com_android_server_UsbDeviceManager.cpp b/services/jni/com_android_server_UsbDeviceManager.cpp
index 0cd94b9..0014db5 100644
--- a/services/jni/com_android_server_UsbDeviceManager.cpp
+++ b/services/jni/com_android_server_UsbDeviceManager.cpp
@@ -111,6 +111,17 @@ static jboolean android_server_UsbDeviceManager_isStartRequested(JNIEnv *env, jo
return (result == 1);
}
+static jint android_server_UsbDeviceManager_getAudioMode(JNIEnv *env, jobject thiz)
+{
+ int fd = open(DRIVER_NAME, O_RDWR);
+ if (fd < 0) {
+ ALOGE("could not open %s", DRIVER_NAME);
+ return false;
+ }
+ int result = ioctl(fd, ACCESSORY_GET_AUDIO_MODE);
+ close(fd);
+ return result;
+}
static JNINativeMethod method_table[] = {
{ "nativeGetAccessoryStrings", "()[Ljava/lang/String;",
@@ -119,6 +130,8 @@ static JNINativeMethod method_table[] = {
(void*)android_server_UsbDeviceManager_openAccessory },
{ "nativeIsStartRequested", "()Z",
(void*)android_server_UsbDeviceManager_isStartRequested },
+ { "nativeGetAudioMode", "()I",
+ (void*)android_server_UsbDeviceManager_getAudioMode },
};
int register_android_server_UsbDeviceManager(JNIEnv *env)