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"