Merge "Fix Unicode string handling" into pi-dev

am: 47f61f07ca

Change-Id: I99a31b6aa291b49861f9158b11260c30aac88b88
gugelfrei
Jerry Zhang 6 years ago committed by android-build-merger
commit d60bb0bc80

@ -49,7 +49,6 @@ cc_library_shared {
shared_libs: [
"libasyncio",
"libbase",
"libutils",
"liblog",
"libusbhost",
],

@ -24,6 +24,7 @@ namespace android {
class MtpDataPacket;
class MtpProperty;
class MtpObjectInfo;
class MtpStringBuffer;
class IMtpDatabase {
public:
@ -86,7 +87,7 @@ public:
virtual void* getThumbnail(MtpObjectHandle handle, size_t& outThumbSize) = 0;
virtual MtpResponseCode getObjectFilePath(MtpObjectHandle handle,
MtpString& outFilePath,
MtpStringBuffer& outFilePath,
int64_t& outFileLength,
MtpObjectFormat& outFormat) = 0;

@ -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 @@ Int8List* MtpDataPacket::getAInt8() {
delete result;
return NULL;
}
result->push(value);
result->push_back(value);
}
return result;
}
@ -145,7 +146,7 @@ UInt8List* MtpDataPacket::getAUInt8() {
delete result;
return NULL;
}
result->push(value);
result->push_back(value);
}
return result;
}
@ -161,7 +162,7 @@ Int16List* MtpDataPacket::getAInt16() {
delete result;
return NULL;
}
result->push(value);
result->push_back(value);
}
return result;
}
@ -177,7 +178,7 @@ UInt16List* MtpDataPacket::getAUInt16() {
delete result;
return NULL;
}
result->push(value);
result->push_back(value);
}
return result;
}
@ -193,7 +194,7 @@ Int32List* MtpDataPacket::getAInt32() {
delete result;
return NULL;
}
result->push(value);
result->push_back(value);
}
return result;
}
@ -209,7 +210,7 @@ UInt32List* MtpDataPacket::getAUInt32() {
delete result;
return NULL;
}
result->push(value);
result->push_back(value);
}
return result;
}
@ -225,7 +226,7 @@ Int64List* MtpDataPacket::getAInt64() {
delete result;
return NULL;
}
result->push(value);
result->push_back(value);
}
return result;
}
@ -241,7 +242,7 @@ UInt64List* MtpDataPacket::getAUInt64() {
delete result;
return NULL;
}
result->push(value);
result->push_back(value);
}
return result;
}

@ -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 {

@ -262,7 +262,7 @@ void MtpDevice::initialize() {
MtpDeviceProperty propCode = (*mDeviceInfo->mDeviceProperties)[i];
MtpProperty* property = getDevicePropDesc(propCode);
if (property)
mDeviceProperties.push(property);
mDeviceProperties.push_back(property);
}
}
}
@ -327,7 +327,7 @@ const char* MtpDevice::getDeviceName() {
}
bool MtpDevice::openSession() {
Mutex::Autolock autoLock(mMutex);
std::lock_guard<std::mutex> lg(mMutex);
mSessionID = 0;
mTransactionID = 0;
@ -353,7 +353,7 @@ bool MtpDevice::closeSession() {
}
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 @@ MtpDeviceInfo* MtpDevice::getDeviceInfo() {
}
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 @@ MtpStorageIDList* MtpDevice::getStorageIDs() {
}
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 @@ MtpStorageInfo* MtpDevice::getStorageInfo(MtpStorageID storageID) {
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 @@ MtpObjectHandleList* MtpDevice::getObjectHandles(MtpStorageID storageID,
}
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 @@ MtpObjectInfo* MtpDevice::getObjectInfo(MtpObjectHandle handle) {
}
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 @@ void* MtpDevice::getThumbnail(MtpObjectHandle handle, int& outLength) {
}
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 @@ MtpObjectHandle MtpDevice::sendObjectInfo(MtpObjectInfo* info) {
}
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::sendObject(MtpObjectHandle handle, int size, int srcFD) {
}
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 @@ MtpObjectHandle MtpDevice::getStorageID(MtpObjectHandle handle) {
}
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 @@ MtpObjectPropertyList* MtpDevice::getObjectPropsSupported(MtpObjectFormat format
}
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::getDevicePropDesc(MtpDeviceProperty code) {
}
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 @@ bool MtpDevice::getObjectPropValue(MtpObjectHandle handle, MtpProperty* property
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 @@ bool MtpDevice::readObjectInternal(MtpObjectHandle handle,
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 @@ bool MtpDevice::readPartialObject(MtpObjectHandle handle,
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 @@ bool MtpDevice::readPartialObject64(MtpObjectHandle handle,
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 @@ MtpResponseCode MtpDevice::readResponse() {
}
int MtpDevice::submitEventRequest() {
if (mEventMutex.tryLock()) {
if (!mEventMutex.try_lock()) {
// An event is being reaped on another thread.
return -1;
}
@ -916,7 +916,7 @@ int MtpDevice::submitEventRequest() {
// 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::submitEventRequest() {
}
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 @@ int MtpDevice::reapEventRequest(int handle, uint32_t (*parameters)[3]) {
}
void MtpDevice::discardEventRequest(int handle) {
Mutex::Autolock autoLock(mEventMutexForInterrupt);
std::lock_guard<std::mutex> lg(mEventMutexForInterrupt);
if (mCurrentEventHandle != handle) {
return;
}

@ -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 @@ private:
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;

@ -20,6 +20,8 @@
#include "MtpPacket.h"
#include "mtp.h"
#include <errno.h>
class IMtpHandle;
namespace android {

@ -19,6 +19,7 @@
#include <android-base/macros.h>
#include "MtpDebug.h"
#include "MtpTypes.h"
struct usb_device;

@ -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::setFormDateTime() {
}
void MtpProperty::print() {
MtpString buffer;
std::string buffer;
bool deviceProp = isDeviceProperty();
if (deviceProp)
ALOGI(" %s (%04X)", MtpDebug::getDevicePropCodeName(mCode), mCode);
@ -346,11 +350,11 @@ void MtpProperty::print() {
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 @@ void MtpProperty::print() {
buffer += ", ";
print(mStepSize, buffer);
buffer += ")";
ALOGI("%s", (const char *)buffer);
ALOGI("%s", buffer.c_str());
break;
case kFormEnum:
buffer = " Enum { ";
@ -372,7 +376,7 @@ void MtpProperty::print() {
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() {
}
}
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");

@ -19,6 +19,8 @@
#include "MtpTypes.h"
#include <string>
namespace android {
class MtpDataPacket;
@ -97,7 +99,6 @@ public:
void setFormDateTime();
void print();
void print(MtpPropertyValue& value, MtpString& buffer);
inline bool isDeviceProperty() const {
return ( ((mCode & 0xF000) == 0x5000)
@ -110,6 +111,7 @@ private:
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

@ -102,10 +102,10 @@ static const MtpEventCode kSupportedEventCodes[] = {
};
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 @@ MtpServer::~MtpServer() {
}
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::sendEvent(MtpEventCode code, uint32_t param1) {
}
}
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 @@ void MtpServer::removeEditObject(MtpObjectHandle handle) {
ObjectEdit* edit = mObjectEditList[i];
if (edit->mHandle == handle) {
delete edit;
mObjectEditList.removeAt(i);
mObjectEditList.erase(mObjectEditList.begin() + i);
return;
}
}
@ -318,7 +318,7 @@ void MtpServer::commitEdit(ObjectEdit* edit) {
bool MtpServer::handleRequest() {
Mutex::Autolock autoLock(mMutex);
std::lock_guard<std::mutex> lg(mMutex);
MtpOperationCode operation = mRequest.getOperationCode();
MtpResponseCode response;
@ -769,7 +769,7 @@ MtpResponseCode MtpServer::doGetObject() {
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 @@ MtpResponseCode MtpServer::doGetPartialObject(MtpOperationCode operation) {
// 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::doGetPartialObject(MtpOperationCode operation) {
}
MtpResponseCode MtpServer::doSendObjectInfo() {
MtpString path;
MtpStringBuffer path;
uint16_t temp16;
uint32_t temp32;
@ -906,7 +906,7 @@ MtpResponseCode MtpServer::doSendObjectInfo() {
// 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 @@ MtpResponseCode MtpServer::doSendObjectInfo() {
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 @@ MtpResponseCode MtpServer::doSendObjectInfo() {
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 @@ MtpResponseCode MtpServer::doMoveObject() {
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 @@ MtpResponseCode MtpServer::doMoveObject() {
// special case the root
if (parent == 0) {
path = storage->getPath();
path.set(storage->getPath());
} else {
int64_t parentLength;
MtpObjectFormat parentFormat;
@ -1034,8 +1034,8 @@ MtpResponseCode MtpServer::doMoveObject() {
}
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 @@ MtpResponseCode MtpServer::doCopyObject() {
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 @@ MtpResponseCode MtpServer::doCopyObject() {
// special case the root
if (parent == 0) {
path = storage->getPath();
path.set(storage->getPath());
} else {
int64_t parentLength;
MtpObjectFormat parentFormat;
@ -1116,8 +1116,8 @@ MtpResponseCode MtpServer::doCopyObject() {
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 @@ MtpResponseCode MtpServer::doDeleteObject() {
// 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 @@ MtpResponseCode MtpServer::doBeginEditObject() {
return MTP_RESPONSE_GENERAL_ERROR;
}
MtpString path;
MtpStringBuffer path;
int64_t fileLength;
MtpObjectFormat format;
int result = mDatabase->getObjectFilePath(handle, path, fileLength, format);

@ -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 @@ private:
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 @@ private:
// 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 @@ private:
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 @@ private:
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);

@ -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 @@ class MtpStorage {
private:
MtpStorageID mStorageID;
MtpString mFilePath;
MtpString mDescription;
MtpStringBuffer mFilePath;
MtpStringBuffer mDescription;
uint64_t mMaxCapacity;
uint64_t mMaxFileSize;
bool mRemovable;

@ -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

@ -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 MtpDataPacket;
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

@ -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 MtpStorage;
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 UInt32List MtpObjectHandleList;
typedef UInt16List MtpObjectPropertyList;
typedef UInt32List MtpStorageIDList;
typedef String8 MtpString;
enum UrbPacketDivisionMode {
// First packet only contains a header.
FIRST_PACKET_ONLY_HEADER,

@ -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"

@ -20,7 +20,7 @@
#include <gtest/gtest.h>
#include <string>
#include <unistd.h>
#include <utils/Log.h>
#include <log/log.h>
#include "PosixAsyncIO.h"

Loading…
Cancel
Save