summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Mike Lockwood <lockwood@android.com> 2011-02-26 13:21:23 -0800
committer Android Git Automerger <android-git-automerger@android.com> 2011-02-26 13:21:23 -0800
commitfbd67fec87e425cfbbd80926cec8cd345d134b4c (patch)
treeaaae80808d0a63554d370bdb241ed6f45a7643f3
parent1b8956398be6aeacf0383d8e0931771dbd3a6d2b (diff)
parent0600fff9149df3af01e90d4996b70dbc1ee7c135 (diff)
am 0600fff9: DO NOT MERGE: MTP: Add support for dynamically adding and removing storage units
* commit '0600fff9149df3af01e90d4996b70dbc1ee7c135': DO NOT MERGE: MTP: Add support for dynamically adding and removing storage units
-rw-r--r--media/jni/android_mtp_MtpServer.cpp18
-rw-r--r--media/mtp/MtpServer.cpp91
-rw-r--r--media/mtp/MtpServer.h18
-rw-r--r--media/mtp/MtpStorage.cpp4
-rw-r--r--media/mtp/MtpStorage.h5
-rw-r--r--media/mtp/mtp.h2
6 files changed, 106 insertions, 32 deletions
diff --git a/media/jni/android_mtp_MtpServer.cpp b/media/jni/android_mtp_MtpServer.cpp
index 3883fb2dcd7a..b27441fb681c 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 be004d2dd786..469fb0470b4c 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;
@@ -438,6 +468,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;
@@ -454,6 +487,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;
@@ -470,7 +505,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);
@@ -486,7 +523,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;
@@ -494,6 +534,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,
@@ -503,6 +545,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,
@@ -536,6 +580,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
@@ -551,11 +597,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;
@@ -591,6 +641,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);
@@ -687,6 +739,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) {
@@ -718,6 +771,8 @@ MtpResponseCode MtpServer::doSendObjectInfo() {
}
MtpResponseCode MtpServer::doSendObject() {
+ if (!hasStorage())
+ return MTP_RESPONSE_GENERAL_ERROR;
MtpResponseCode result = MTP_RESPONSE_OK;
mode_t mask;
int ret;
@@ -834,6 +889,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 605d5a2e0d4d..1efa7158baa6 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 2fbbc512d1e2..6cb88b33551f 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 ace720b9f511..858c9d38a3f6 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 8bc2e22c31d8..6fedc161b9c1 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