diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java index 3df57bcb704f8..ee646c0876088 100644 --- a/core/java/android/hardware/usb/UsbManager.java +++ b/core/java/android/hardware/usb/UsbManager.java @@ -180,6 +180,14 @@ public class UsbManager { */ public static final String USB_DATA_UNLOCKED = "unlocked"; + /** + * Boolean extra indicating whether the intent represents a change in the usb + * configuration (as opposed to a state update). + * + * {@hide} + */ + public static final String USB_CONFIG_CHANGED = "config_changed"; + /** * A placeholder indicating that no USB function is being specified. * Used to distinguish between selecting no function vs. the default function in diff --git a/media/java/android/mtp/MtpServer.java b/media/java/android/mtp/MtpServer.java index 61fbfb902d0d9..3c2ea58e7a2eb 100644 --- a/media/java/android/mtp/MtpServer.java +++ b/media/java/android/mtp/MtpServer.java @@ -67,6 +67,11 @@ public class MtpServer implements Runnable { native_remove_storage(storage.getStorageId()); } + public static void configure(boolean usePtp) { + native_configure(usePtp); + } + + public static native final void native_configure(boolean usePtp); private native final void native_setup(MtpDatabase database, boolean usePtp); private native final void native_run(); private native final void native_cleanup(); diff --git a/media/jni/android_mtp_MtpServer.cpp b/media/jni/android_mtp_MtpServer.cpp index d13187c398469..afd3082ec51b3 100644 --- a/media/jni/android_mtp_MtpServer.cpp +++ b/media/jni/android_mtp_MtpServer.cpp @@ -56,17 +56,16 @@ static inline MtpServer* getMtpServer(JNIEnv *env, jobject thiz) { return (MtpServer*)env->GetLongField(thiz, field_MtpServer_nativeContext); } +static void android_mtp_configure(JNIEnv *, jobject, jboolean usePtp) { + MtpServer::configure(usePtp); +} + static void android_mtp_MtpServer_setup(JNIEnv *env, jobject thiz, jobject javaDatabase, jboolean usePtp) { - int fd = open("/dev/mtp_usb", O_RDWR); - if (fd >= 0) { - MtpServer* server = new MtpServer(fd, getMtpDatabase(env, javaDatabase), - usePtp, AID_MEDIA_RW, 0664, 0775); - env->SetLongField(thiz, field_MtpServer_nativeContext, (jlong)server); - } else { - ALOGE("could not open MTP driver, errno: %d", errno); - } + MtpServer* server = new MtpServer(getMtpDatabase(env, javaDatabase), + usePtp, AID_MEDIA_RW, 0664, 0775); + env->SetLongField(thiz, field_MtpServer_nativeContext, (jlong)server); } static void @@ -180,6 +179,7 @@ android_mtp_MtpServer_remove_storage(JNIEnv *env, jobject thiz, jint storageId) // ---------------------------------------------------------------------------- static const JNINativeMethod gMethods[] = { + {"native_configure", "(Z)V", (void *)android_mtp_configure}, {"native_setup", "(Landroid/mtp/MtpDatabase;Z)V", (void *)android_mtp_MtpServer_setup}, {"native_run", "()V", (void *)android_mtp_MtpServer_run}, diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java index 15a1e760f5283..b3f5630b8e257 100644 --- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java @@ -351,8 +351,6 @@ public class UsbDeviceManager { UsbManager.removeFunction(persisted, UsbManager.USB_FUNCTION_MTP)); } - setEnabledFunctions(null, false, false); - String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim(); updateState(state); @@ -446,13 +444,12 @@ public class UsbDeviceManager { return false; } - private boolean setUsbConfig(String config) { + private void setUsbConfig(String config) { if (DEBUG) Slog.d(TAG, "setUsbConfig(" + config + ")"); // set the new configuration // we always set it due to b/23631400, where adbd was getting killed // and not restarted due to property timeouts on some devices SystemProperties.set(USB_CONFIG_PROPERTY, config); - return waitForState(config); } private void setAdbEnabled(boolean enable) { @@ -547,8 +544,18 @@ public class UsbDeviceManager { // Kick the USB stack to close existing connections. setUsbConfig(UsbManager.USB_FUNCTION_NONE); + if (!waitForState(UsbManager.USB_FUNCTION_NONE)) { + Slog.e(TAG, "Failed to kick USB config"); + return false; + } + // Set the new USB configuration. - if (!setUsbConfig(functions)) { + setUsbConfig(functions); + + // Start up dependent services. + updateUsbStateBroadcastIfNeeded(true); + + if (!waitForState(functions)) { Slog.e(TAG, "Failed to switch USB config to " + functions); return false; } @@ -631,7 +638,7 @@ public class UsbDeviceManager { return false; } - private void updateUsbStateBroadcastIfNeeded() { + private void updateUsbStateBroadcastIfNeeded(boolean configChanged) { // send a sticky broadcast containing current USB state Intent intent = new Intent(UsbManager.ACTION_USB_STATE); intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING @@ -640,6 +647,7 @@ public class UsbDeviceManager { intent.putExtra(UsbManager.USB_HOST_CONNECTED, mHostConnected); intent.putExtra(UsbManager.USB_CONFIGURED, mConfigured); intent.putExtra(UsbManager.USB_DATA_UNLOCKED, isUsbTransferAllowed() && mUsbDataUnlocked); + intent.putExtra(UsbManager.USB_CONFIG_CHANGED, configChanged); if (mCurrentFunctions != null) { String[] functions = mCurrentFunctions.split(","); @@ -737,7 +745,7 @@ public class UsbDeviceManager { setEnabledFunctions(null, false, false); } if (mBootCompleted) { - updateUsbStateBroadcastIfNeeded(); + updateUsbStateBroadcastIfNeeded(false); updateUsbFunctions(); } break; @@ -749,7 +757,7 @@ public class UsbDeviceManager { args.recycle(); updateUsbNotification(); if (mBootCompleted) { - updateUsbStateBroadcastIfNeeded(); + updateUsbStateBroadcastIfNeeded(false); } break; case MSG_ENABLE_ADB: @@ -765,11 +773,11 @@ public class UsbDeviceManager { case MSG_SYSTEM_READY: updateUsbNotification(); updateAdbNotification(); - updateUsbStateBroadcastIfNeeded(); updateUsbFunctions(); break; case MSG_BOOT_COMPLETED: mBootCompleted = true; + setEnabledFunctions(null, false, false); if (mCurrentAccessory != null) { getCurrentSettings().accessoryAttached(mCurrentAccessory); }