Merge "USB string descriptors are not UTF8, so it is not safe to treat them as such." into lmp-dev
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 1573106..1f4105f 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -905,6 +905,20 @@
     return result;
 }
 
+/** Create a Java string from an ASCII or Latin-1 string */
+jstring AndroidRuntime::NewStringLatin1(JNIEnv* env, const char* bytes) {
+    if (!bytes) return NULL;
+    int length = strlen(bytes);
+    jchar* buffer = (jchar *)alloca(length * sizeof(jchar));
+    if (!buffer) return NULL;
+    jchar* chp = buffer;
+    for (int i = 0; i < length; i++) {
+        *chp++ = *bytes++;
+    }
+    return env->NewString(buffer, length);
+}
+
+
 /*
  * Start the Android runtime.  This involves starting the virtual machine
  * and calling the "static void main(String[] args)" method in the class
diff --git a/include/android_runtime/AndroidRuntime.h b/include/android_runtime/AndroidRuntime.h
index f3cfd97..fc33b7e 100644
--- a/include/android_runtime/AndroidRuntime.h
+++ b/include/android_runtime/AndroidRuntime.h
@@ -113,6 +113,9 @@
     /** return a new string corresponding to 'className' with all '.'s replaced by '/'s. */
     static char* toSlashClassName(const char* className);
 
+    /** Create a Java string from an ASCII or Latin-1 string */
+    static jstring NewStringLatin1(JNIEnv* env, const char* bytes);
+
 private:
     static int startReg(JNIEnv* env);
     bool parseRuntimeOption(const char* property,
diff --git a/services/core/jni/com_android_server_UsbHostManager.cpp b/services/core/jni/com_android_server_UsbHostManager.cpp
index 65a28c0..32c3f95 100644
--- a/services/core/jni/com_android_server_UsbHostManager.cpp
+++ b/services/core/jni/com_android_server_UsbHostManager.cpp
@@ -74,9 +74,9 @@
     char *serial = usb_device_get_serial(device);
 
     jstring deviceName = env->NewStringUTF(devname);
-    jstring manufacturerName = env->NewStringUTF(manufacturer);
-    jstring productName = env->NewStringUTF(product);
-    jstring serialNumber = env->NewStringUTF(serial);
+    jstring manufacturerName = AndroidRuntime::NewStringLatin1(env, manufacturer);
+    jstring productName = AndroidRuntime::NewStringLatin1(env, product);
+    jstring serialNumber = AndroidRuntime::NewStringLatin1(env, serial);
 
     jboolean result = env->CallBooleanMethod(thiz, method_beginUsbDeviceAdded,
             deviceName, usb_device_get_vendor_id(device), usb_device_get_product_id(device),
@@ -99,7 +99,7 @@
         if (desc->bDescriptorType == USB_DT_CONFIG) {
             struct usb_config_descriptor *config = (struct usb_config_descriptor *)desc;
             char *name = usb_device_get_string(device, config->iConfiguration);
-            jstring configName = env->NewStringUTF(name);
+            jstring configName = AndroidRuntime::NewStringLatin1(env, name);
 
             env->CallVoidMethod(thiz, method_addUsbConfiguration,
                     config->bConfigurationValue, configName, config->bmAttributes,
@@ -110,7 +110,7 @@
         } else if (desc->bDescriptorType == USB_DT_INTERFACE) {
             struct usb_interface_descriptor *interface = (struct usb_interface_descriptor *)desc;
             char *name = usb_device_get_string(device, interface->iInterface);
-            jstring interfaceName = env->NewStringUTF(name);
+            jstring interfaceName = AndroidRuntime::NewStringLatin1(env, name);
 
             env->CallVoidMethod(thiz, method_addUsbInterface,
                     interface->bInterfaceNumber, interfaceName, interface->bAlternateSetting,