Fix Unicode string handling

Linux uses UTF8 but java and MTP both
use UTF16. In a few places, this results
in the top byte of a UTF16 string being
truncated on conversion to UTF8.

Also, the hardcoded UTF to byte serialization
in MtpStringBuffer is incorrect.
Replace it with conversions from std, and
replace usages of MtpString with MtpStringBuffer.

Remove any remaining usages of libutils
and replace them with corresponding std
libraries.

Bug: 70546563
Test: Mtp works, tests pass
Test: file/folder names containing emoji can be transferred to/from
windows
Change-Id: Idbcb73f1beac17ce8a90843fa254e759dd1a6369
diff --git a/media/mtp/Android.bp b/media/mtp/Android.bp
index acea373..2cf9b82 100644
--- a/media/mtp/Android.bp
+++ b/media/mtp/Android.bp
@@ -49,7 +49,6 @@
     shared_libs: [
         "libasyncio",
         "libbase",
-        "libutils",
         "liblog",
         "libusbhost",
     ],
diff --git a/media/mtp/IMtpDatabase.h b/media/mtp/IMtpDatabase.h
index d09a984..1245092 100644
--- a/media/mtp/IMtpDatabase.h
+++ b/media/mtp/IMtpDatabase.h
@@ -24,6 +24,7 @@
 class MtpDataPacket;
 class MtpProperty;
 class MtpObjectInfo;
+class MtpStringBuffer;
 
 class IMtpDatabase {
 public:
@@ -86,7 +87,7 @@
     virtual void*                   getThumbnail(MtpObjectHandle handle, size_t& outThumbSize) = 0;
 
     virtual MtpResponseCode         getObjectFilePath(MtpObjectHandle handle,
-                                            MtpString& outFilePath,
+                                            MtpStringBuffer& outFilePath,
                                             int64_t& outFileLength,
                                             MtpObjectFormat& outFormat) = 0;
 
diff --git a/media/mtp/MtpDataPacket.cpp b/media/mtp/MtpDataPacket.cpp
index d1c71d7..992dc9a 100644
--- a/media/mtp/MtpDataPacket.cpp
+++ b/media/mtp/MtpDataPacket.cpp
@@ -19,6 +19,7 @@
 #include "MtpDataPacket.h"
 
 #include <algorithm>
+#include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <sys/types.h>
@@ -129,7 +130,7 @@
             delete result;
             return NULL;
         }
-        result->push(value);
+        result->push_back(value);
     }
     return result;
 }
@@ -145,7 +146,7 @@
             delete result;
             return NULL;
         }
-        result->push(value);
+        result->push_back(value);
     }
     return result;
 }
@@ -161,7 +162,7 @@
             delete result;
             return NULL;
         }
-        result->push(value);
+        result->push_back(value);
     }
     return result;
 }
@@ -177,7 +178,7 @@
             delete result;
             return NULL;
         }
-        result->push(value);
+        result->push_back(value);
     }
     return result;
 }
@@ -193,7 +194,7 @@
             delete result;
             return NULL;
         }
-        result->push(value);
+        result->push_back(value);
     }
     return result;
 }
@@ -209,7 +210,7 @@
             delete result;
             return NULL;
         }
-        result->push(value);
+        result->push_back(value);
     }
     return result;
 }
@@ -225,7 +226,7 @@
             delete result;
             return NULL;
         }
-        result->push(value);
+        result->push_back(value);
     }
     return result;
 }
@@ -241,7 +242,7 @@
             delete result;
             return NULL;
         }
-        result->push(value);
+        result->push_back(value);
     }
     return result;
 }
diff --git a/media/mtp/MtpDebug.h b/media/mtp/MtpDebug.h
index 5b53e31..8d48273 100644
--- a/media/mtp/MtpDebug.h
+++ b/media/mtp/MtpDebug.h
@@ -18,10 +18,10 @@
 #define _MTP_DEBUG_H
 
 // #define LOG_NDEBUG 0
-#include <utils/Log.h>
-
 #include "MtpTypes.h"
 
+#include <log/log.h>
+
 namespace android {
 
 class MtpDebug {
diff --git a/media/mtp/MtpDevice.cpp b/media/mtp/MtpDevice.cpp
index 0bf7854..993797a 100644
--- a/media/mtp/MtpDevice.cpp
+++ b/media/mtp/MtpDevice.cpp
@@ -262,7 +262,7 @@
                 MtpDeviceProperty propCode = (*mDeviceInfo->mDeviceProperties)[i];
                 MtpProperty* property = getDevicePropDesc(propCode);
                 if (property)
-                    mDeviceProperties.push(property);
+                    mDeviceProperties.push_back(property);
             }
         }
     }
@@ -327,7 +327,7 @@
 }
 
 bool MtpDevice::openSession() {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     mSessionID = 0;
     mTransactionID = 0;
@@ -353,7 +353,7 @@
 }
 
 MtpDeviceInfo* MtpDevice::getDeviceInfo() {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     mRequest.reset();
     if (!sendRequest(MTP_OPERATION_GET_DEVICE_INFO))
@@ -372,7 +372,7 @@
 }
 
 MtpStorageIDList* MtpDevice::getStorageIDs() {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     mRequest.reset();
     if (!sendRequest(MTP_OPERATION_GET_STORAGE_IDS))
@@ -387,7 +387,7 @@
 }
 
 MtpStorageInfo* MtpDevice::getStorageInfo(MtpStorageID storageID) {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     mRequest.reset();
     mRequest.setParameter(1, storageID);
@@ -408,7 +408,7 @@
 
 MtpObjectHandleList* MtpDevice::getObjectHandles(MtpStorageID storageID,
             MtpObjectFormat format, MtpObjectHandle parent) {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     mRequest.reset();
     mRequest.setParameter(1, storageID);
@@ -426,7 +426,7 @@
 }
 
 MtpObjectInfo* MtpDevice::getObjectInfo(MtpObjectHandle handle) {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     // FIXME - we might want to add some caching here
 
@@ -448,7 +448,7 @@
 }
 
 void* MtpDevice::getThumbnail(MtpObjectHandle handle, int& outLength) {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     mRequest.reset();
     mRequest.setParameter(1, handle);
@@ -463,7 +463,7 @@
 }
 
 MtpObjectHandle MtpDevice::sendObjectInfo(MtpObjectInfo* info) {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     mRequest.reset();
     MtpObjectHandle parent = info->mParent;
@@ -517,7 +517,7 @@
 }
 
 bool MtpDevice::sendObject(MtpObjectHandle handle, int size, int srcFD) {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     if (mLastSendObjectInfoTransactionID + 1 != mTransactionID ||
             mLastSendObjectInfoObjectHandle != handle) {
@@ -537,7 +537,7 @@
 }
 
 bool MtpDevice::deleteObject(MtpObjectHandle handle) {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     mRequest.reset();
     mRequest.setParameter(1, handle);
@@ -572,7 +572,7 @@
 }
 
 MtpObjectPropertyList* MtpDevice::getObjectPropsSupported(MtpObjectFormat format) {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     mRequest.reset();
     mRequest.setParameter(1, format);
@@ -589,7 +589,7 @@
 }
 
 MtpProperty* MtpDevice::getDevicePropDesc(MtpDeviceProperty code) {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     mRequest.reset();
     mRequest.setParameter(1, code);
@@ -609,7 +609,7 @@
 }
 
 MtpProperty* MtpDevice::getObjectPropDesc(MtpObjectProperty code, MtpObjectFormat format) {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     mRequest.reset();
     mRequest.setParameter(1, code);
@@ -633,7 +633,7 @@
     if (property == nullptr)
         return false;
 
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     mRequest.reset();
     mRequest.setParameter(1, handle);
@@ -684,7 +684,7 @@
                                    ReadObjectCallback callback,
                                    const uint32_t* expectedLength,
                                    void* clientData) {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     mRequest.reset();
     mRequest.setParameter(1, handle);
@@ -806,7 +806,7 @@
                                   uint32_t *writtenSize,
                                   ReadObjectCallback callback,
                                   void* clientData) {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     mRequest.reset();
     mRequest.setParameter(1, handle);
@@ -828,7 +828,7 @@
                                     uint32_t *writtenSize,
                                     ReadObjectCallback callback,
                                     void* clientData) {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     mRequest.reset();
     mRequest.setParameter(1, handle);
@@ -908,7 +908,7 @@
 }
 
 int MtpDevice::submitEventRequest() {
-    if (mEventMutex.tryLock()) {
+    if (!mEventMutex.try_lock()) {
         // An event is being reaped on another thread.
         return -1;
     }
@@ -916,7 +916,7 @@
         // An event request was submitted, but no reapEventRequest called so far.
         return -1;
     }
-    Mutex::Autolock autoLock(mEventMutexForInterrupt);
+    std::lock_guard<std::mutex> lg(mEventMutexForInterrupt);
     mEventPacket.sendRequest(mRequestIntr);
     const int currentHandle = ++mCurrentEventHandle;
     mProcessingEvent = true;
@@ -925,7 +925,7 @@
 }
 
 int MtpDevice::reapEventRequest(int handle, uint32_t (*parameters)[3]) {
-    Mutex::Autolock autoLock(mEventMutex);
+    std::lock_guard<std::mutex> lg(mEventMutex);
     if (!mProcessingEvent || mCurrentEventHandle != handle || !parameters) {
         return -1;
     }
@@ -940,7 +940,7 @@
 }
 
 void MtpDevice::discardEventRequest(int handle) {
-    Mutex::Autolock autoLock(mEventMutexForInterrupt);
+    std::lock_guard<std::mutex> lg(mEventMutexForInterrupt);
     if (mCurrentEventHandle != handle) {
         return;
     }
diff --git a/media/mtp/MtpDevice.h b/media/mtp/MtpDevice.h
index a9a3e0e..8cf9e5e 100644
--- a/media/mtp/MtpDevice.h
+++ b/media/mtp/MtpDevice.h
@@ -23,7 +23,7 @@
 #include "MtpResponsePacket.h"
 #include "MtpTypes.h"
 
-#include <utils/threads.h>
+#include <mutex>
 
 struct usb_device;
 struct usb_request;
@@ -67,9 +67,9 @@
     MtpObjectHandle         mLastSendObjectInfoObjectHandle;
 
     // to ensure only one MTP transaction at a time
-    Mutex                   mMutex;
-    Mutex                   mEventMutex;
-    Mutex                   mEventMutexForInterrupt;
+    std::mutex              mMutex;
+    std::mutex              mEventMutex;
+    std::mutex              mEventMutexForInterrupt;
 
     // Remember the device's packet division mode.
     UrbPacketDivisionMode   mPacketDivisionMode;
diff --git a/media/mtp/MtpEventPacket.h b/media/mtp/MtpEventPacket.h
index 3f3b6a3..94d6ebf 100644
--- a/media/mtp/MtpEventPacket.h
+++ b/media/mtp/MtpEventPacket.h
@@ -20,6 +20,8 @@
 #include "MtpPacket.h"
 #include "mtp.h"
 
+#include <errno.h>
+
 class IMtpHandle;
 
 namespace android {
diff --git a/media/mtp/MtpPacket.h b/media/mtp/MtpPacket.h
index d47c91d..9842b28 100644
--- a/media/mtp/MtpPacket.h
+++ b/media/mtp/MtpPacket.h
@@ -19,6 +19,7 @@
 
 #include <android-base/macros.h>
 
+#include "MtpDebug.h"
 #include "MtpTypes.h"
 
 struct usb_device;
diff --git a/media/mtp/MtpProperty.cpp b/media/mtp/MtpProperty.cpp
index 039e4f5..5c02a0d 100644
--- a/media/mtp/MtpProperty.cpp
+++ b/media/mtp/MtpProperty.cpp
@@ -18,6 +18,10 @@
 
 #include <inttypes.h>
 #include <cutils/compiler.h>
+#include <iomanip>
+#include <sstream>
+#include <string>
+
 #include "MtpDataPacket.h"
 #include "MtpDebug.h"
 #include "MtpProperty.h"
@@ -336,7 +340,7 @@
 }
 
 void MtpProperty::print() {
-    MtpString buffer;
+    std::string buffer;
     bool deviceProp = isDeviceProperty();
     if (deviceProp)
         ALOGI("    %s (%04X)", MtpDebug::getDevicePropCodeName(mCode), mCode);
@@ -346,11 +350,11 @@
     ALOGI("    writeable %s", (mWriteable ? "true" : "false"));
     buffer = "    default value: ";
     print(mDefaultValue, buffer);
-    ALOGI("%s", (const char *)buffer);
+    ALOGI("%s", buffer.c_str());
     if (deviceProp) {
         buffer = "    current value: ";
         print(mCurrentValue, buffer);
-        ALOGI("%s", (const char *)buffer);
+        ALOGI("%s", buffer.c_str());
     }
     switch (mFormFlag) {
         case kFormNone:
@@ -363,7 +367,7 @@
             buffer += ", ";
             print(mStepSize, buffer);
             buffer += ")";
-            ALOGI("%s", (const char *)buffer);
+            ALOGI("%s", buffer.c_str());
             break;
         case kFormEnum:
             buffer = "    Enum { ";
@@ -372,7 +376,7 @@
                 buffer += " ";
             }
             buffer += "}";
-            ALOGI("%s", (const char *)buffer);
+            ALOGI("%s", buffer.c_str());
             break;
         case kFormDateTime:
             ALOGI("    DateTime\n");
@@ -383,42 +387,47 @@
     }
 }
 
-void MtpProperty::print(MtpPropertyValue& value, MtpString& buffer) {
+void MtpProperty::print(MtpPropertyValue& value, std::string& buffer) {
+    std::ostringstream s;
     switch (mType) {
         case MTP_TYPE_INT8:
-            buffer.appendFormat("%d", value.u.i8);
+            buffer += std::to_string(value.u.i8);
             break;
         case MTP_TYPE_UINT8:
-            buffer.appendFormat("%d", value.u.u8);
+            buffer += std::to_string(value.u.u8);
             break;
         case MTP_TYPE_INT16:
-            buffer.appendFormat("%d", value.u.i16);
+            buffer += std::to_string(value.u.i16);
             break;
         case MTP_TYPE_UINT16:
-            buffer.appendFormat("%d", value.u.u16);
+            buffer += std::to_string(value.u.u16);
             break;
         case MTP_TYPE_INT32:
-            buffer.appendFormat("%d", value.u.i32);
+            buffer += std::to_string(value.u.i32);
             break;
         case MTP_TYPE_UINT32:
-            buffer.appendFormat("%d", value.u.u32);
+            buffer += std::to_string(value.u.u32);
             break;
         case MTP_TYPE_INT64:
-            buffer.appendFormat("%" PRId64, value.u.i64);
+            buffer += std::to_string(value.u.i64);
             break;
         case MTP_TYPE_UINT64:
-            buffer.appendFormat("%" PRIu64, value.u.u64);
+            buffer += std::to_string(value.u.u64);
             break;
         case MTP_TYPE_INT128:
-            buffer.appendFormat("%08X%08X%08X%08X", value.u.i128[0], value.u.i128[1],
-                    value.u.i128[2], value.u.i128[3]);
+            for (auto i : value.u.i128) {
+                s << std::hex << std::setfill('0') << std::uppercase << i;
+            }
+            buffer += s.str();
             break;
         case MTP_TYPE_UINT128:
-            buffer.appendFormat("%08X%08X%08X%08X", value.u.u128[0], value.u.u128[1],
-                    value.u.u128[2], value.u.u128[3]);
+            for (auto i : value.u.u128) {
+                s << std::hex << std::setfill('0') << std::uppercase << i;
+            }
+            buffer += s.str();
             break;
         case MTP_TYPE_STR:
-            buffer.appendFormat("%s", value.str);
+            buffer += value.str;
             break;
         default:
             ALOGE("unsupported type for MtpProperty::print\n");
diff --git a/media/mtp/MtpProperty.h b/media/mtp/MtpProperty.h
index 03c08e1..bfd5f7f 100644
--- a/media/mtp/MtpProperty.h
+++ b/media/mtp/MtpProperty.h
@@ -19,6 +19,8 @@
 
 #include "MtpTypes.h"
 
+#include <string>
+
 namespace android {
 
 class MtpDataPacket;
@@ -97,7 +99,6 @@
     void                setFormDateTime();
 
     void                print();
-    void                print(MtpPropertyValue& value, MtpString& buffer);
 
     inline bool         isDeviceProperty() const {
                             return (   ((mCode & 0xF000) == 0x5000)
@@ -110,6 +111,7 @@
     MtpPropertyValue*   readArrayValues(MtpDataPacket& packet, uint32_t& length);
     void                writeArrayValues(MtpDataPacket& packet,
                                             MtpPropertyValue* values, uint32_t length);
+    void                print(MtpPropertyValue& value, std::string& buffer);
 };
 
 }; // namespace android
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index e4ac8b0..86d59dd 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -102,10 +102,10 @@
 };
 
 MtpServer::MtpServer(IMtpDatabase* database, int controlFd, bool ptp,
-                    const MtpString& deviceInfoManufacturer,
-                    const MtpString& deviceInfoModel,
-                    const MtpString& deviceInfoDeviceVersion,
-                    const MtpString& deviceInfoSerialNumber)
+                    const char *deviceInfoManufacturer,
+                    const char *deviceInfoModel,
+                    const char *deviceInfoDeviceVersion,
+                    const char *deviceInfoSerialNumber)
     :   mDatabase(database),
         mPtp(ptp),
         mDeviceInfoManufacturer(deviceInfoManufacturer),
@@ -132,14 +132,14 @@
 }
 
 void MtpServer::addStorage(MtpStorage* storage) {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
-    mStorages.push(storage);
+    mStorages.push_back(storage);
     sendStoreAdded(storage->getStorageID());
 }
 
 void MtpServer::removeStorage(MtpStorage* storage) {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
     auto iter = std::find(mStorages.begin(), mStorages.end(), storage);
     if (iter != mStorages.end()) {
         sendStoreRemoved(storage->getStorageID());
@@ -284,10 +284,10 @@
     }
 }
 
-void MtpServer::addEditObject(MtpObjectHandle handle, MtpString& path,
+void MtpServer::addEditObject(MtpObjectHandle handle, MtpStringBuffer& path,
         uint64_t size, MtpObjectFormat format, int fd) {
     ObjectEdit*  edit = new ObjectEdit(handle, path, size, format, fd);
-    mObjectEditList.add(edit);
+    mObjectEditList.push_back(edit);
 }
 
 MtpServer::ObjectEdit* MtpServer::getEditObject(MtpObjectHandle handle) {
@@ -305,7 +305,7 @@
         ObjectEdit* edit = mObjectEditList[i];
         if (edit->mHandle == handle) {
             delete edit;
-            mObjectEditList.removeAt(i);
+            mObjectEditList.erase(mObjectEditList.begin() + i);
             return;
         }
     }
@@ -318,7 +318,7 @@
 
 
 bool MtpServer::handleRequest() {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     MtpOperationCode operation = mRequest.getOperationCode();
     MtpResponseCode response;
@@ -769,7 +769,7 @@
     if (mRequest.getParameterCount() < 1)
         return MTP_RESPONSE_INVALID_PARAMETER;
     MtpObjectHandle handle = mRequest.getParameter(1);
-    MtpString pathBuf;
+    MtpStringBuffer pathBuf;
     int64_t fileLength;
     MtpObjectFormat format;
     int result = mDatabase->getObjectFilePath(handle, pathBuf, fileLength, format);
@@ -855,7 +855,7 @@
         // standard GetPartialObject
         length = mRequest.getParameter(3);
     }
-    MtpString pathBuf;
+    MtpStringBuffer pathBuf;
     int64_t fileLength;
     MtpObjectFormat format;
     int result = mDatabase->getObjectFilePath(handle, pathBuf, fileLength, format);
@@ -892,7 +892,7 @@
 }
 
 MtpResponseCode MtpServer::doSendObjectInfo() {
-    MtpString path;
+    MtpStringBuffer path;
     uint16_t temp16;
     uint32_t temp32;
 
@@ -906,7 +906,7 @@
 
     // special case the root
     if (parent == MTP_PARENT_ROOT) {
-        path = storage->getPath();
+        path.set(storage->getPath());
         parent = 0;
     } else {
         int64_t length;
@@ -938,7 +938,7 @@
     if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER;  // sequence number
     MtpStringBuffer name, created, modified;
     if (!mData.getString(name)) return MTP_RESPONSE_INVALID_PARAMETER;    // file name
-    if (name.getCharCount() == 0) {
+    if (name.isEmpty()) {
         ALOGE("empty name");
         return MTP_RESPONSE_INVALID_PARAMETER;
     }
@@ -952,8 +952,8 @@
         modifiedTime = 0;
 
     if (path[path.size() - 1] != '/')
-        path += "/";
-    path += (const char *)name;
+        path.append("/");
+    path.append(name);
 
     // check space first
     if (mSendObjectFileSize > storage->getFreeSpace())
@@ -1006,10 +1006,10 @@
     MtpObjectHandle parent = mRequest.getParameter(3);
     if (!storage)
         return MTP_RESPONSE_INVALID_STORAGE_ID;
-    MtpString path;
+    MtpStringBuffer path;
     MtpResponseCode result;
 
-    MtpString fromPath;
+    MtpStringBuffer fromPath;
     int64_t fileLength;
     MtpObjectFormat format;
     MtpObjectInfo info(objectHandle);
@@ -1022,7 +1022,7 @@
 
     // special case the root
     if (parent == 0) {
-        path = storage->getPath();
+        path.set(storage->getPath());
     } else {
         int64_t parentLength;
         MtpObjectFormat parentFormat;
@@ -1034,8 +1034,8 @@
     }
 
     if (path[path.size() - 1] != '/')
-        path += "/";
-    path += info.mName;
+        path.append("/");
+    path.append(info.mName);
 
     result = mDatabase->beginMoveObject(objectHandle, parent, storageID);
     if (result != MTP_RESPONSE_OK)
@@ -1085,9 +1085,9 @@
     MtpObjectHandle parent = mRequest.getParameter(3);
     if (!storage)
         return MTP_RESPONSE_INVALID_STORAGE_ID;
-    MtpString path;
+    MtpStringBuffer path;
 
-    MtpString fromPath;
+    MtpStringBuffer fromPath;
     int64_t fileLength;
     MtpObjectFormat format;
     MtpObjectInfo info(objectHandle);
@@ -1100,7 +1100,7 @@
 
     // special case the root
     if (parent == 0) {
-        path = storage->getPath();
+        path.set(storage->getPath());
     } else {
         int64_t parentLength;
         MtpObjectFormat parentFormat;
@@ -1116,8 +1116,8 @@
         return MTP_RESPONSE_STORAGE_FULL;
 
     if (path[path.size() - 1] != '/')
-        path += "/";
-    path += info.mName;
+        path.append("/");
+    path.append(info.mName);
 
     MtpObjectHandle handle = mDatabase->beginCopyObject(objectHandle, parent, storageID);
     if (handle == kInvalidObjectHandle) {
@@ -1264,7 +1264,7 @@
     // FIXME - support deleting all objects if handle is 0xFFFFFFFF
     // FIXME - implement deleting objects by format
 
-    MtpString filePath;
+    MtpStringBuffer filePath;
     int64_t fileLength;
     int result = mDatabase->getObjectFilePath(handle, filePath, fileLength, format);
     if (result != MTP_RESPONSE_OK)
@@ -1414,7 +1414,7 @@
         return MTP_RESPONSE_GENERAL_ERROR;
     }
 
-    MtpString path;
+    MtpStringBuffer path;
     int64_t fileLength;
     MtpObjectFormat format;
     int result = mDatabase->getObjectFilePath(handle, path, fileLength, format);
diff --git a/media/mtp/MtpServer.h b/media/mtp/MtpServer.h
index e633c52..f6939d7 100644
--- a/media/mtp/MtpServer.h
+++ b/media/mtp/MtpServer.h
@@ -21,14 +21,14 @@
 #include "MtpDataPacket.h"
 #include "MtpResponsePacket.h"
 #include "MtpEventPacket.h"
+#include "MtpStringBuffer.h"
 #include "mtp.h"
 #include "MtpUtils.h"
 #include "IMtpHandle.h"
 
-#include <utils/threads.h>
-#include <queue>
 #include <memory>
 #include <mutex>
+#include <queue>
 
 namespace android {
 
@@ -44,13 +44,13 @@
     bool                mPtp;
 
     // Manufacturer to report in DeviceInfo
-    MtpString           mDeviceInfoManufacturer;
+    MtpStringBuffer     mDeviceInfoManufacturer;
     // Model to report in DeviceInfo
-    MtpString           mDeviceInfoModel;
+    MtpStringBuffer     mDeviceInfoModel;
     // Device version to report in DeviceInfo
-    MtpString           mDeviceInfoDeviceVersion;
+    MtpStringBuffer     mDeviceInfoDeviceVersion;
     // Serial number to report in DeviceInfo
-    MtpString           mDeviceInfoSerialNumber;
+    MtpStringBuffer     mDeviceInfoSerialNumber;
 
     // current session ID
     MtpSessionID        mSessionID;
@@ -70,18 +70,18 @@
     // handle for new object, set by SendObjectInfo and used by SendObject
     MtpObjectHandle     mSendObjectHandle;
     MtpObjectFormat     mSendObjectFormat;
-    MtpString           mSendObjectFilePath;
+    MtpStringBuffer     mSendObjectFilePath;
     size_t              mSendObjectFileSize;
     time_t              mSendObjectModifiedTime;
 
-    Mutex               mMutex;
+    std::mutex          mMutex;
 
     // represents an MTP object that is being edited using the android extensions
     // for direct editing (BeginEditObject, SendPartialObject, TruncateObject and EndEditObject)
     class ObjectEdit {
         public:
         MtpObjectHandle     mHandle;
-        MtpString           mPath;
+        MtpStringBuffer           mPath;
         uint64_t            mSize;
         MtpObjectFormat     mFormat;
         int                 mFD;
@@ -95,14 +95,14 @@
             close(mFD);
         }
     };
-    Vector<ObjectEdit*>  mObjectEditList;
+    std::vector<ObjectEdit*>  mObjectEditList;
 
 public:
                         MtpServer(IMtpDatabase* database, int controlFd, bool ptp,
-                                    const MtpString& deviceInfoManufacturer,
-                                    const MtpString& deviceInfoModel,
-                                    const MtpString& deviceInfoDeviceVersion,
-                                    const MtpString& deviceInfoSerialNumber);
+                                    const char *deviceInfoManufacturer,
+                                    const char *deviceInfoModel,
+                                    const char *deviceInfoDeviceVersion,
+                                    const char *deviceInfoSerialNumber);
     virtual             ~MtpServer();
 
     MtpStorage*         getStorage(MtpStorageID id);
@@ -122,7 +122,7 @@
     void                sendStoreRemoved(MtpStorageID id);
     void                sendEvent(MtpEventCode code, uint32_t param1);
 
-    void                addEditObject(MtpObjectHandle handle, MtpString& path,
+    void                addEditObject(MtpObjectHandle handle, MtpStringBuffer& path,
                                 uint64_t size, MtpObjectFormat format, int fd);
     ObjectEdit*         getEditObject(MtpObjectHandle handle);
     void                removeEditObject(MtpObjectHandle handle);
diff --git a/media/mtp/MtpStorage.h b/media/mtp/MtpStorage.h
index cb7e333..e9518dd 100644
--- a/media/mtp/MtpStorage.h
+++ b/media/mtp/MtpStorage.h
@@ -17,6 +17,7 @@
 #ifndef _MTP_STORAGE_H
 #define _MTP_STORAGE_H
 
+#include "MtpStringBuffer.h"
 #include "MtpTypes.h"
 #include "mtp.h"
 
@@ -28,8 +29,8 @@
 
 private:
     MtpStorageID            mStorageID;
-    MtpString               mFilePath;
-    MtpString               mDescription;
+    MtpStringBuffer         mFilePath;
+    MtpStringBuffer         mDescription;
     uint64_t                mMaxCapacity;
     uint64_t                mMaxFileSize;
     bool                    mRemovable;
diff --git a/media/mtp/MtpStringBuffer.cpp b/media/mtp/MtpStringBuffer.cpp
index df04694..cd379bf 100644
--- a/media/mtp/MtpStringBuffer.cpp
+++ b/media/mtp/MtpStringBuffer.cpp
@@ -16,168 +16,97 @@
 
 #define LOG_TAG "MtpStringBuffer"
 
-#include <string.h>
+#include <codecvt>
+#include <locale>
+#include <string>
+#include <vector>
 
 #include "MtpDataPacket.h"
 #include "MtpStringBuffer.h"
 
-namespace android {
+namespace {
 
-MtpStringBuffer::MtpStringBuffer()
-    :   mCharCount(0),
-        mByteCount(1)
-{
-    mBuffer[0] = 0;
+std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t> gConvert;
+
+static std::string utf16ToUtf8(std::u16string input_str) {
+    return gConvert.to_bytes(input_str);
 }
 
+static std::u16string utf8ToUtf16(std::string input_str) {
+    return gConvert.from_bytes(input_str);
+}
+
+} // namespace
+
+namespace android {
+
 MtpStringBuffer::MtpStringBuffer(const char* src)
-    :   mCharCount(0),
-        mByteCount(1)
 {
     set(src);
 }
 
 MtpStringBuffer::MtpStringBuffer(const uint16_t* src)
-    :   mCharCount(0),
-        mByteCount(1)
 {
     set(src);
 }
 
 MtpStringBuffer::MtpStringBuffer(const MtpStringBuffer& src)
-    :   mCharCount(src.mCharCount),
-        mByteCount(src.mByteCount)
 {
-    memcpy(mBuffer, src.mBuffer, mByteCount);
-}
-
-
-MtpStringBuffer::~MtpStringBuffer() {
+    mString = src.mString;
 }
 
 void MtpStringBuffer::set(const char* src) {
-    // count the characters
-    int count = 0;
-    char ch;
-    char* dest = (char*)mBuffer;
-
-    while ((ch = *src++) != 0 && count < MTP_STRING_MAX_CHARACTER_NUMBER) {
-        if ((ch & 0x80) == 0) {
-            // single byte character
-            *dest++ = ch;
-        } else if ((ch & 0xE0) == 0xC0) {
-            // two byte character
-            char ch1 = *src++;
-            if (! ch1) {
-                // last character was truncated, so ignore last byte
-                break;
-            }
-
-            *dest++ = ch;
-            *dest++ = ch1;
-        } else if ((ch & 0xF0) == 0xE0) {
-            // 3 byte char
-            char ch1 = *src++;
-            if (! ch1) {
-                // last character was truncated, so ignore last byte
-                break;
-            }
-            char ch2 = *src++;
-            if (! ch2) {
-                // last character was truncated, so ignore last byte
-                break;
-            }
-
-            *dest++ = ch;
-            *dest++ = ch1;
-            *dest++ = ch2;
-        }
-        count++;
-    }
-
-    *dest++ = 0;
-    mByteCount = dest - (char*)mBuffer;
-    mCharCount = count;
+    mString = std::string(src);
 }
 
 void MtpStringBuffer::set(const uint16_t* src) {
-    int count = 0;
-    uint16_t ch;
-    uint8_t* dest = mBuffer;
-
-    while ((ch = *src++) != 0 && count < MTP_STRING_MAX_CHARACTER_NUMBER) {
-        if (ch >= 0x0800) {
-            *dest++ = (uint8_t)(0xE0 | (ch >> 12));
-            *dest++ = (uint8_t)(0x80 | ((ch >> 6) & 0x3F));
-            *dest++ = (uint8_t)(0x80 | (ch & 0x3F));
-        } else if (ch >= 0x80) {
-            *dest++ = (uint8_t)(0xC0 | (ch >> 6));
-            *dest++ = (uint8_t)(0x80 | (ch & 0x3F));
-        } else {
-            *dest++ = ch;
-        }
-        count++;
-    }
-    *dest++ = 0;
-    mCharCount = count;
-    mByteCount = dest - mBuffer;
+    mString = utf16ToUtf8(std::u16string((const char16_t*)src));
 }
 
 bool MtpStringBuffer::readFromPacket(MtpDataPacket* packet) {
     uint8_t count;
     if (!packet->getUInt8(count))
         return false;
+    if (count == 0)
+        return true;
 
-    uint8_t* dest = mBuffer;
+    std::vector<char16_t> buffer(count);
     for (int i = 0; i < count; i++) {
         uint16_t ch;
-
         if (!packet->getUInt16(ch))
             return false;
-        if (ch >= 0x0800) {
-            *dest++ = (uint8_t)(0xE0 | (ch >> 12));
-            *dest++ = (uint8_t)(0x80 | ((ch >> 6) & 0x3F));
-            *dest++ = (uint8_t)(0x80 | (ch & 0x3F));
-        } else if (ch >= 0x80) {
-            *dest++ = (uint8_t)(0xC0 | (ch >> 6));
-            *dest++ = (uint8_t)(0x80 | (ch & 0x3F));
-        } else {
-            *dest++ = ch;
-        }
+        buffer[i] = ch;
     }
-    *dest++ = 0;
-    mCharCount = count;
-    mByteCount = dest - mBuffer;
+    if (buffer[count-1] != '\0') {
+        ALOGE("Mtp string not null terminated\n");
+        return false;
+    }
+    mString = utf16ToUtf8(std::u16string(buffer.data()));
     return true;
 }
 
 void MtpStringBuffer::writeToPacket(MtpDataPacket* packet) const {
-    int count = mCharCount;
-    const uint8_t* src = mBuffer;
-    packet->putUInt8(count > 0 ? count + 1 : 0);
+    std::u16string src16 = utf8ToUtf16(mString);
+    int count = src16.length();
 
-    // expand utf8 to 16 bit chars
-    for (int i = 0; i < count; i++) {
-        uint16_t ch;
-        uint16_t ch1 = *src++;
-        if ((ch1 & 0x80) == 0) {
-            // single byte character
-            ch = ch1;
-        } else if ((ch1 & 0xE0) == 0xC0) {
-            // two byte character
-            uint16_t ch2 = *src++;
-            ch = ((ch1 & 0x1F) << 6) | (ch2 & 0x3F);
-        } else {
-            // three byte character
-            uint16_t ch2 = *src++;
-            uint16_t ch3 = *src++;
-            ch = ((ch1 & 0x0F) << 12) | ((ch2 & 0x3F) << 6) | (ch3 & 0x3F);
+    if (count == 0) {
+        packet->putUInt8(0);
+        return;
+    }
+    packet->putUInt8(std::min(count + 1, MTP_STRING_MAX_CHARACTER_NUMBER));
+
+    int i = 0;
+    for (char16_t &c : src16) {
+        if (i == MTP_STRING_MAX_CHARACTER_NUMBER - 1) {
+            // Leave a slot for null termination.
+            ALOGI("Mtp truncating long string\n");
+            break;
         }
-        packet->putUInt16(ch);
+        packet->putUInt16(c);
+        i++;
     }
     // only terminate with zero if string is not empty
-    if (count > 0)
-        packet->putUInt16(0);
+    packet->putUInt16(0);
 }
 
 }  // namespace android
diff --git a/media/mtp/MtpStringBuffer.h b/media/mtp/MtpStringBuffer.h
index bcf2a48..4cec58a 100644
--- a/media/mtp/MtpStringBuffer.h
+++ b/media/mtp/MtpStringBuffer.h
@@ -17,7 +17,9 @@
 #ifndef _MTP_STRING_BUFFER_H
 #define _MTP_STRING_BUFFER_H
 
+#include <log/log.h>
 #include <stdint.h>
+#include <string>
 
 // Max Character number of a MTP String
 #define MTP_STRING_MAX_CHARACTER_NUMBER             255
@@ -30,31 +32,39 @@
 class MtpStringBuffer {
 
 private:
-    // mBuffer contains string in UTF8 format
-    // maximum 3 bytes/character, with 1 extra for zero termination
-    uint8_t         mBuffer[MTP_STRING_MAX_CHARACTER_NUMBER * 3 + 1];
-    int             mCharCount;
-    int             mByteCount;
+    std::string     mString;
 
 public:
-                    MtpStringBuffer();
+                    MtpStringBuffer() {};
+                    ~MtpStringBuffer() {};
+
     explicit        MtpStringBuffer(const char* src);
     explicit        MtpStringBuffer(const uint16_t* src);
                     MtpStringBuffer(const MtpStringBuffer& src);
-    virtual         ~MtpStringBuffer();
 
     void            set(const char* src);
     void            set(const uint16_t* src);
 
+    inline void     append(const char* other);
+    inline void     append(MtpStringBuffer &other);
+
     bool            readFromPacket(MtpDataPacket* packet);
     void            writeToPacket(MtpDataPacket* packet) const;
 
-    inline int      getCharCount() const { return mCharCount; }
-    inline int      getByteCount() const { return mByteCount; }
+    inline bool     isEmpty() const { return mString.empty(); }
+    inline int      size() const { return mString.length(); }
 
-	inline operator const char*() const { return (const char *)mBuffer; }
+    inline operator const char*() const { return mString.c_str(); }
 };
 
+inline void MtpStringBuffer::append(const char* other) {
+    mString += other;
+}
+
+inline void MtpStringBuffer::append(MtpStringBuffer &other) {
+    mString += other.mString;
+}
+
 }; // namespace android
 
 #endif // _MTP_STRING_BUFFER_H
diff --git a/media/mtp/MtpTypes.h b/media/mtp/MtpTypes.h
index c749c66..e6ac23c 100644
--- a/media/mtp/MtpTypes.h
+++ b/media/mtp/MtpTypes.h
@@ -18,8 +18,7 @@
 #define _MTP_TYPES_H
 
 #include <stdint.h>
-#include "utils/String8.h"
-#include "utils/Vector.h"
+#include <vector>
 
 namespace android {
 
@@ -51,18 +50,18 @@
 class MtpDevice;
 class MtpProperty;
 
-typedef Vector<MtpStorage *> MtpStorageList;
-typedef Vector<MtpDevice*> MtpDeviceList;
-typedef Vector<MtpProperty*> MtpPropertyList;
+typedef std::vector<MtpStorage *> MtpStorageList;
+typedef std::vector<MtpDevice*> MtpDeviceList;
+typedef std::vector<MtpProperty*> MtpPropertyList;
 
-typedef Vector<uint8_t> UInt8List;
-typedef Vector<uint16_t> UInt16List;
-typedef Vector<uint32_t> UInt32List;
-typedef Vector<uint64_t> UInt64List;
-typedef Vector<int8_t> Int8List;
-typedef Vector<int16_t> Int16List;
-typedef Vector<int32_t> Int32List;
-typedef Vector<int64_t> Int64List;
+typedef std::vector<uint8_t> UInt8List;
+typedef std::vector<uint16_t> UInt16List;
+typedef std::vector<uint32_t> UInt32List;
+typedef std::vector<uint64_t> UInt64List;
+typedef std::vector<int8_t> Int8List;
+typedef std::vector<int16_t> Int16List;
+typedef std::vector<int32_t> Int32List;
+typedef std::vector<int64_t> Int64List;
 
 typedef UInt16List MtpObjectPropertyList;
 typedef UInt16List MtpDevicePropertyList;
@@ -71,8 +70,6 @@
 typedef UInt16List MtpObjectPropertyList;
 typedef UInt32List MtpStorageIDList;
 
-typedef String8    MtpString;
-
 enum UrbPacketDivisionMode {
     // First packet only contains a header.
     FIRST_PACKET_ONLY_HEADER,
diff --git a/media/mtp/tests/MtpFfsHandle_test.cpp b/media/mtp/tests/MtpFfsHandle_test.cpp
index 2174893..d11fe07 100644
--- a/media/mtp/tests/MtpFfsHandle_test.cpp
+++ b/media/mtp/tests/MtpFfsHandle_test.cpp
@@ -23,7 +23,7 @@
 #include <random>
 #include <string>
 #include <unistd.h>
-#include <utils/Log.h>
+#include <log/log.h>
 
 #include "MtpDescriptors.h"
 #include "MtpFfsHandle.h"
diff --git a/media/mtp/tests/PosixAsyncIO_test.cpp b/media/mtp/tests/PosixAsyncIO_test.cpp
index 63b9a35..9e337aa 100644
--- a/media/mtp/tests/PosixAsyncIO_test.cpp
+++ b/media/mtp/tests/PosixAsyncIO_test.cpp
@@ -20,7 +20,7 @@
 #include <gtest/gtest.h>
 #include <string>
 #include <unistd.h>
-#include <utils/Log.h>
+#include <log/log.h>
 
 #include "PosixAsyncIO.h"