diff options
author | Mike Lockwood <lockwood@android.com> | 2011-02-18 09:07:14 -0500 |
---|---|---|
committer | Mike Lockwood <lockwood@android.com> | 2011-02-22 13:57:23 -0800 |
commit | 467ca0de6d7fd55787a37de9dfd7e5325e1c3c6f (patch) | |
tree | b2f83ecf23e9bc3b86eb5e79a78811a12d4dd274 /media | |
parent | 0c4650b4d566f65aa6faa9be45e7f1e29148e1a9 (diff) | |
download | frameworks_base-467ca0de6d7fd55787a37de9dfd7e5325e1c3c6f.zip frameworks_base-467ca0de6d7fd55787a37de9dfd7e5325e1c3c6f.tar.gz frameworks_base-467ca0de6d7fd55787a37de9dfd7e5325e1c3c6f.tar.bz2 |
MTP: Add support for dynamically adding and removing storage units
BUG: 3402847
Change-Id: I7da266061d949abcb6bb11c6faaa47b5e4a2a977
Diffstat (limited to 'media')
-rw-r--r-- | media/jni/android_mtp_MtpServer.cpp | 18 | ||||
-rw-r--r-- | media/mtp/MtpServer.cpp | 91 | ||||
-rw-r--r-- | media/mtp/MtpServer.h | 18 | ||||
-rw-r--r-- | media/mtp/MtpStorage.cpp | 4 | ||||
-rw-r--r-- | media/mtp/MtpStorage.h | 5 | ||||
-rw-r--r-- | media/mtp/mtp.h | 2 |
6 files changed, 106 insertions, 32 deletions
diff --git a/media/jni/android_mtp_MtpServer.cpp b/media/jni/android_mtp_MtpServer.cpp index 3883fb2..b27441f 100644 --- a/media/jni/android_mtp_MtpServer.cpp +++ b/media/jni/android_mtp_MtpServer.cpp @@ -35,6 +35,7 @@ #include "private/android_filesystem_config.h" #include "MtpServer.h" +#include "MtpStorage.h" using namespace android; @@ -56,22 +57,24 @@ class MtpThread : public Thread { private: MtpDatabase* mDatabase; MtpServer* mServer; - String8 mStoragePath; - uint64_t mReserveSpace; + MtpStorage* mStorage; Mutex mMutex; bool mUsePtp; int mFd; public: - MtpThread(MtpDatabase* database, const char* storagePath, uint64_t reserveSpace) + MtpThread(MtpDatabase* database, MtpStorage* storage) : mDatabase(database), mServer(NULL), - mStoragePath(storagePath), - mReserveSpace(reserveSpace), + mStorage(storage), mFd(-1) { } + virtual ~MtpThread() { + delete mStorage; + } + void setPtpMode(bool usePtp) { mMutex.lock(); mUsePtp = usePtp; @@ -86,7 +89,7 @@ public: (mUsePtp ? MTP_INTERFACE_MODE_PTP : MTP_INTERFACE_MODE_MTP)); mServer = new MtpServer(mFd, mDatabase, AID_MEDIA_RW, 0664, 0775); - mServer->addStorage(mStoragePath, mReserveSpace); + mServer->addStorage(mStorage); mMutex.unlock(); mServer->run(); @@ -137,7 +140,8 @@ android_mtp_MtpServer_setup(JNIEnv *env, jobject thiz, jobject javaDatabase, const char *storagePathStr = env->GetStringUTFChars(storagePath, NULL); // create the thread and assign it to the smart pointer - sThread = new MtpThread(database, storagePathStr, reserveSpace); + MtpStorage* storage = new MtpStorage(MTP_FIRST_STORAGE_ID, storagePathStr, reserveSpace); + sThread = new MtpThread(database, storage); env->ReleaseStringUTFChars(storagePath, storagePathStr); #endif diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp index 853a5af..37e02a3 100644 --- a/media/mtp/MtpServer.cpp +++ b/media/mtp/MtpServer.cpp @@ -84,6 +84,8 @@ static const MtpOperationCode kSupportedOperationCodes[] = { static const MtpEventCode kSupportedEventCodes[] = { MTP_EVENT_OBJECT_ADDED, MTP_EVENT_OBJECT_REMOVED, + MTP_EVENT_STORE_ADDED, + MTP_EVENT_STORE_REMOVED, }; MtpServer::MtpServer(int fd, MtpDatabase* database, @@ -104,11 +106,23 @@ MtpServer::MtpServer(int fd, MtpDatabase* database, MtpServer::~MtpServer() { } -void MtpServer::addStorage(const char* filePath, uint64_t reserveSpace) { - int index = mStorages.size() + 1; - index |= index << 16; // set high and low part to our index - MtpStorage* storage = new MtpStorage(index, filePath, reserveSpace); - addStorage(storage); +void MtpServer::addStorage(MtpStorage* storage) { + Mutex::Autolock autoLock(mMutex); + + mStorages.push(storage); + sendStoreAdded(storage->getStorageID()); +} + +void MtpServer::removeStorage(MtpStorage* storage) { + Mutex::Autolock autoLock(mMutex); + + for (int i = 0; i < mStorages.size(); i++) { + if (mStorages[i] == storage) { + mStorages.removeAt(i); + sendStoreRemoved(storage->getStorageID()); + break; + } + } } MtpStorage* MtpServer::getStorage(MtpStorageID id) { @@ -122,6 +136,12 @@ MtpStorage* MtpServer::getStorage(MtpStorageID id) { return NULL; } +bool MtpServer::hasStorage(MtpStorageID id) { + if (id == 0 || id == 0xFFFFFFFF) + return mStorages.size() > 0; + return (getStorage(id) != NULL); +} + void MtpServer::run() { int fd = mFD; @@ -203,28 +223,38 @@ void MtpServer::run() { } void MtpServer::sendObjectAdded(MtpObjectHandle handle) { - if (mSessionOpen) { - LOGV("sendObjectAdded %d\n", handle); - mEvent.setEventCode(MTP_EVENT_OBJECT_ADDED); - mEvent.setTransactionID(mRequest.getTransactionID()); - mEvent.setParameter(1, handle); - int ret = mEvent.write(mFD); - LOGV("mEvent.write returned %d\n", ret); - } + LOGV("sendObjectAdded %d\n", handle); + sendEvent(MTP_EVENT_OBJECT_ADDED, handle); } void MtpServer::sendObjectRemoved(MtpObjectHandle handle) { + LOGV("sendObjectRemoved %d\n", handle); + sendEvent(MTP_EVENT_OBJECT_REMOVED, handle); +} + +void MtpServer::sendStoreAdded(MtpStorageID id) { + LOGV("sendStoreAdded %08X\n", id); + sendEvent(MTP_EVENT_STORE_ADDED, id); +} + +void MtpServer::sendStoreRemoved(MtpStorageID id) { + LOGV("sendStoreRemoved %08X\n", id); + sendEvent(MTP_EVENT_STORE_REMOVED, id); +} + +void MtpServer::sendEvent(MtpEventCode code, uint32_t param1) { if (mSessionOpen) { - LOGV("sendObjectRemoved %d\n", handle); - mEvent.setEventCode(MTP_EVENT_OBJECT_REMOVED); + mEvent.setEventCode(code); mEvent.setTransactionID(mRequest.getTransactionID()); - mEvent.setParameter(1, handle); + mEvent.setParameter(1, param1); int ret = mEvent.write(mFD); LOGV("mEvent.write returned %d\n", ret); } } bool MtpServer::handleRequest() { + Mutex::Autolock autoLock(mMutex); + MtpOperationCode operation = mRequest.getOperationCode(); MtpResponseCode response; @@ -439,6 +469,9 @@ MtpResponseCode MtpServer::doGetObjectHandles() { MtpObjectFormat format = mRequest.getParameter(2); // 0 for all formats MtpObjectHandle parent = mRequest.getParameter(3); // 0xFFFFFFFF for objects with no parent // 0x00000000 for all objects? + + if (!hasStorage(storageID)) + return MTP_RESPONSE_INVALID_STORAGE_ID; if (parent == 0xFFFFFFFF) parent = 0; @@ -455,6 +488,8 @@ MtpResponseCode MtpServer::doGetNumObjects() { MtpObjectFormat format = mRequest.getParameter(2); // 0 for all formats MtpObjectHandle parent = mRequest.getParameter(3); // 0xFFFFFFFF for objects with no parent // 0x00000000 for all objects? + if (!hasStorage(storageID)) + return MTP_RESPONSE_INVALID_STORAGE_ID; if (parent == 0xFFFFFFFF) parent = 0; @@ -471,7 +506,9 @@ MtpResponseCode MtpServer::doGetNumObjects() { MtpResponseCode MtpServer::doGetObjectReferences() { if (!mSessionOpen) return MTP_RESPONSE_SESSION_NOT_OPEN; - MtpStorageID handle = mRequest.getParameter(1); + if (!hasStorage()) + return MTP_RESPONSE_INVALID_OBJECT_HANDLE; + MtpObjectHandle handle = mRequest.getParameter(1); // FIXME - check for invalid object handle MtpObjectHandleList* handles = mDatabase->getObjectReferences(handle); @@ -487,7 +524,10 @@ MtpResponseCode MtpServer::doGetObjectReferences() { MtpResponseCode MtpServer::doSetObjectReferences() { if (!mSessionOpen) return MTP_RESPONSE_SESSION_NOT_OPEN; + if (!hasStorage()) + return MTP_RESPONSE_INVALID_OBJECT_HANDLE; MtpStorageID handle = mRequest.getParameter(1); + MtpObjectHandleList* references = mData.getAUInt32(); MtpResponseCode result = mDatabase->setObjectReferences(handle, references); delete references; @@ -495,6 +535,8 @@ MtpResponseCode MtpServer::doSetObjectReferences() { } MtpResponseCode MtpServer::doGetObjectPropValue() { + if (!hasStorage()) + return MTP_RESPONSE_INVALID_OBJECT_HANDLE; MtpObjectHandle handle = mRequest.getParameter(1); MtpObjectProperty property = mRequest.getParameter(2); LOGV("GetObjectPropValue %d %s\n", handle, @@ -504,6 +546,8 @@ MtpResponseCode MtpServer::doGetObjectPropValue() { } MtpResponseCode MtpServer::doSetObjectPropValue() { + if (!hasStorage()) + return MTP_RESPONSE_INVALID_OBJECT_HANDLE; MtpObjectHandle handle = mRequest.getParameter(1); MtpObjectProperty property = mRequest.getParameter(2); LOGV("SetObjectPropValue %d %s\n", handle, @@ -537,6 +581,8 @@ MtpResponseCode MtpServer::doResetDevicePropValue() { } MtpResponseCode MtpServer::doGetObjectPropList() { + if (!hasStorage()) + return MTP_RESPONSE_INVALID_OBJECT_HANDLE; MtpObjectHandle handle = mRequest.getParameter(1); // use uint32_t so we can support 0xFFFFFFFF @@ -552,11 +598,15 @@ MtpResponseCode MtpServer::doGetObjectPropList() { } MtpResponseCode MtpServer::doGetObjectInfo() { + if (!hasStorage()) + return MTP_RESPONSE_INVALID_OBJECT_HANDLE; MtpObjectHandle handle = mRequest.getParameter(1); return mDatabase->getObjectInfo(handle, mData); } MtpResponseCode MtpServer::doGetObject() { + if (!hasStorage()) + return MTP_RESPONSE_INVALID_OBJECT_HANDLE; MtpObjectHandle handle = mRequest.getParameter(1); MtpString pathBuf; int64_t fileLength; @@ -592,6 +642,8 @@ MtpResponseCode MtpServer::doGetObject() { } MtpResponseCode MtpServer::doGetPartialObject() { + if (!hasStorage()) + return MTP_RESPONSE_INVALID_OBJECT_HANDLE; MtpObjectHandle handle = mRequest.getParameter(1); uint32_t offset = mRequest.getParameter(2); uint32_t length = mRequest.getParameter(3); @@ -688,6 +740,7 @@ MtpResponseCode MtpServer::doSendObjectInfo() { if (mSendObjectFileSize > storage->getFreeSpace()) return MTP_RESPONSE_STORAGE_FULL; +LOGD("path: %s parent: %d storageID: %08X", (const char*)path, parent, storageID); MtpObjectHandle handle = mDatabase->beginSendObject((const char*)path, format, parent, storageID, mSendObjectFileSize, modifiedTime); if (handle == kInvalidObjectHandle) { @@ -719,6 +772,8 @@ MtpResponseCode MtpServer::doSendObjectInfo() { } MtpResponseCode MtpServer::doSendObject() { + if (!hasStorage()) + return MTP_RESPONSE_GENERAL_ERROR; MtpResponseCode result = MTP_RESPONSE_OK; mode_t mask; int ret; @@ -835,6 +890,8 @@ static void deletePath(const char* path) { } MtpResponseCode MtpServer::doDeleteObject() { + if (!hasStorage()) + return MTP_RESPONSE_INVALID_OBJECT_HANDLE; MtpObjectHandle handle = mRequest.getParameter(1); MtpObjectFormat format = mRequest.getParameter(2); // FIXME - support deleting all objects if handle is 0xFFFFFFFF diff --git a/media/mtp/MtpServer.h b/media/mtp/MtpServer.h index 605d5a2..1efa715 100644 --- a/media/mtp/MtpServer.h +++ b/media/mtp/MtpServer.h @@ -22,9 +22,10 @@ #include "MtpResponsePacket.h" #include "MtpEventPacket.h" #include "mtp.h" - #include "MtpUtils.h" +#include <utils/threads.h> + namespace android { class MtpDatabase; @@ -62,20 +63,29 @@ private: MtpString mSendObjectFilePath; size_t mSendObjectFileSize; + Mutex mMutex; + public: MtpServer(int fd, MtpDatabase* database, int fileGroup, int filePerm, int directoryPerm); virtual ~MtpServer(); - void addStorage(const char* filePath, uint64_t reserveSpace); - inline void addStorage(MtpStorage* storage) { mStorages.push(storage); } - MtpStorage* getStorage(MtpStorageID id); + void addStorage(MtpStorage* storage); + void removeStorage(MtpStorage* storage); + void run(); void sendObjectAdded(MtpObjectHandle handle); void sendObjectRemoved(MtpObjectHandle handle); private: + MtpStorage* getStorage(MtpStorageID id); + inline bool hasStorage() { return mStorages.size() > 0; } + bool hasStorage(MtpStorageID id); + void sendStoreAdded(MtpStorageID id); + void sendStoreRemoved(MtpStorageID id); + void sendEvent(MtpEventCode code, uint32_t param1); + bool handleRequest(); MtpResponseCode doGetDeviceInfo(); diff --git a/media/mtp/MtpStorage.cpp b/media/mtp/MtpStorage.cpp index 2fbbc51..6cb88b3 100644 --- a/media/mtp/MtpStorage.cpp +++ b/media/mtp/MtpStorage.cpp @@ -59,7 +59,7 @@ int MtpStorage::getAccessCapability() const { uint64_t MtpStorage::getMaxCapacity() { if (mMaxCapacity == 0) { struct statfs stat; - if (statfs(mFilePath, &stat)) + if (statfs(getPath(), &stat)) return -1; mMaxCapacity = (uint64_t)stat.f_blocks * (uint64_t)stat.f_bsize; } @@ -68,7 +68,7 @@ uint64_t MtpStorage::getMaxCapacity() { uint64_t MtpStorage::getFreeSpace() { struct statfs stat; - if (statfs(mFilePath, &stat)) + if (statfs(getPath(), &stat)) return -1; uint64_t freeSpace = (uint64_t)stat.f_bavail * (uint64_t)stat.f_bsize; return (freeSpace > mReserveSpace ? freeSpace - mReserveSpace : 0); diff --git a/media/mtp/MtpStorage.h b/media/mtp/MtpStorage.h index ace720b..858c9d3 100644 --- a/media/mtp/MtpStorage.h +++ b/media/mtp/MtpStorage.h @@ -17,6 +17,7 @@ #ifndef _MTP_STORAGE_H #define _MTP_STORAGE_H +#include "MtpTypes.h" #include "mtp.h" namespace android { @@ -27,7 +28,7 @@ class MtpStorage { private: MtpStorageID mStorageID; - const char* mFilePath; + MtpString mFilePath; uint64_t mMaxCapacity; // amount of free space to leave unallocated uint64_t mReserveSpace; @@ -44,7 +45,7 @@ public: uint64_t getMaxCapacity(); uint64_t getFreeSpace(); const char* getDescription() const; - inline const char* getPath() const { return mFilePath; } + inline const char* getPath() const { return (const char *)mFilePath; } }; }; // namespace android diff --git a/media/mtp/mtp.h b/media/mtp/mtp.h index 8bc2e22..6fedc16 100644 --- a/media/mtp/mtp.h +++ b/media/mtp/mtp.h @@ -22,6 +22,8 @@ #define MTP_STANDARD_VERSION 100 +#define MTP_FIRST_STORAGE_ID 0x00010001 + // Container Types #define MTP_CONTAINER_TYPE_UNDEFINED 0 #define MTP_CONTAINER_TYPE_COMMAND 1 |