diff options
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) |