MtpServer changes for MtpStorageManager
MoveObject and DeleteObject require
begin() and end() methods in order to
maintain database consistency. delete() now
has to return errors.
Allow sendObject after sendObjectInfo since
the spec allows this.
Test: See tests for main MtpStorageManager change
Bug: 63143623
Change-Id: Ied105e884cafd36e861521dcc59740e23b330f5f
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index bb0414d..cfda0a6 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <algorithm>
#include <android-base/logging.h>
#include <android-base/properties.h>
#include <chrono>
@@ -31,7 +32,7 @@
#define LOG_TAG "MtpServer"
#include "MtpDebug.h"
-#include "MtpDatabase.h"
+#include "IMtpDatabase.h"
#include "MtpDevHandle.h"
#include "MtpFfsCompatHandle.h"
#include "MtpFfsHandle.h"
@@ -99,7 +100,7 @@
MTP_EVENT_DEVICE_PROP_CHANGED,
};
-MtpServer::MtpServer(MtpDatabase* database, bool ptp,
+MtpServer::MtpServer(IMtpDatabase* database, bool ptp,
const MtpString& deviceInfoManufacturer,
const MtpString& deviceInfoModel,
const MtpString& deviceInfoDeviceVersion,
@@ -150,21 +151,17 @@
void MtpServer::removeStorage(MtpStorage* storage) {
Mutex::Autolock autoLock(mMutex);
-
- for (size_t i = 0; i < mStorages.size(); i++) {
- if (mStorages[i] == storage) {
- mStorages.removeAt(i);
- sendStoreRemoved(storage->getStorageID());
- break;
- }
+ auto iter = std::find(mStorages.begin(), mStorages.end(), storage);
+ if (iter != mStorages.end()) {
+ sendStoreRemoved(storage->getStorageID());
+ mStorages.erase(iter);
}
}
MtpStorage* MtpServer::getStorage(MtpStorageID id) {
if (id == 0)
return mStorages[0];
- for (size_t i = 0; i < mStorages.size(); i++) {
- MtpStorage* storage = mStorages[i];
+ for (MtpStorage *storage : mStorages) {
if (storage->getStorageID() == id)
return storage;
}
@@ -265,9 +262,6 @@
}
mObjectEditList.clear();
- if (mSessionOpen)
- mDatabase->sessionEnded();
-
sHandle->close();
}
@@ -335,7 +329,7 @@
}
void MtpServer::commitEdit(ObjectEdit* edit) {
- mDatabase->endSendObject((const char *)edit->mPath, edit->mHandle, edit->mFormat, true);
+ mDatabase->rescanFile((const char *)edit->mPath, edit->mHandle, edit->mFormat);
}
@@ -348,9 +342,9 @@
mResponse.reset();
if (mSendObjectHandle != kInvalidObjectHandle && operation != MTP_OPERATION_SEND_OBJECT) {
- // FIXME - need to delete mSendObjectHandle from the database
- ALOGE("expected SendObject after SendObjectInfo");
mSendObjectHandle = kInvalidObjectHandle;
+ mSendObjectFormat = 0;
+ mSendObjectModifiedTime = 0;
}
int containertype = mRequest.getContainerType();
@@ -526,8 +520,6 @@
mSessionID = mRequest.getParameter(1);
mSessionOpen = true;
- mDatabase->sessionStarted();
-
return MTP_RESPONSE_OK;
}
@@ -536,7 +528,6 @@
return MTP_RESPONSE_SESSION_NOT_OPEN;
mSessionID = 0;
mSessionOpen = false;
- mDatabase->sessionEnded();
return MTP_RESPONSE_OK;
}
@@ -604,6 +595,8 @@
return MTP_RESPONSE_INVALID_STORAGE_ID;
MtpObjectHandleList* handles = mDatabase->getObjectList(storageID, format, parent);
+ if (handles == NULL)
+ return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
mData.putAUInt32(handles);
delete handles;
return MTP_RESPONSE_OK;
@@ -991,26 +984,25 @@
}
ALOGD("path: %s parent: %d storageID: %08X", (const char*)path, parent, storageID);
- MtpObjectHandle handle = mDatabase->beginSendObject((const char*)path,
- format, parent, storageID, mSendObjectFileSize, modifiedTime);
+ MtpObjectHandle handle = mDatabase->beginSendObject((const char*)path, format,
+ parent, storageID);
if (handle == kInvalidObjectHandle) {
return MTP_RESPONSE_GENERAL_ERROR;
}
- if (format == MTP_FORMAT_ASSOCIATION) {
+ if (format == MTP_FORMAT_ASSOCIATION) {
int ret = makeFolder((const char *)path);
if (ret)
return MTP_RESPONSE_GENERAL_ERROR;
// SendObject does not get sent for directories, so call endSendObject here instead
- mDatabase->endSendObject(path, handle, MTP_FORMAT_ASSOCIATION, MTP_RESPONSE_OK);
- } else {
- mSendObjectFilePath = path;
- // save the handle for the SendObject call, which should follow
- mSendObjectHandle = handle;
- mSendObjectFormat = format;
- mSendObjectModifiedTime = modifiedTime;
+ mDatabase->endSendObject(handle, MTP_RESPONSE_OK);
}
+ mSendObjectFilePath = path;
+ // save the handle for the SendObject call, which should follow
+ mSendObjectHandle = handle;
+ mSendObjectFormat = format;
+ mSendObjectModifiedTime = modifiedTime;
mResponse.setParameter(1, storageID);
mResponse.setParameter(2, parent);
@@ -1061,6 +1053,10 @@
path += "/";
path += info.mName;
+ result = mDatabase->beginMoveObject(objectHandle, parent, storageID);
+ if (result != MTP_RESPONSE_OK)
+ return result;
+
if (info.mStorageID == storageID) {
ALOGV("Moving file from %s to %s", (const char*)fromPath, (const char*)path);
if (rename(fromPath, path)) {
@@ -1087,8 +1083,8 @@
}
// If the move failed, undo the database change
- if (result == MTP_RESPONSE_OK)
- result = mDatabase->moveObject(objectHandle, parent, storageID, path);
+ mDatabase->endMoveObject(info.mParent, parent, info.mStorageID, storageID, objectHandle,
+ result == MTP_RESPONSE_OK);
return result;
}
@@ -1139,8 +1135,7 @@
path += "/";
path += info.mName;
- MtpObjectHandle handle = mDatabase->beginSendObject((const char*)path,
- format, parent, storageID, fileLength, info.mDateModified);
+ MtpObjectHandle handle = mDatabase->beginCopyObject(objectHandle, parent, storageID);
if (handle == kInvalidObjectHandle) {
return MTP_RESPONSE_GENERAL_ERROR;
}
@@ -1158,9 +1153,7 @@
}
}
- mDatabase->endSendObject(path, handle, format, result);
- if (format == MTP_FORMAT_ASSOCIATION)
- mDatabase->doScanDirectory(path);
+ mDatabase->endCopyObject(handle, result);
mResponse.setParameter(1, handle);
return result;
}
@@ -1190,6 +1183,15 @@
}
initialData = ret - MTP_CONTAINER_HEADER_SIZE;
+ if (mSendObjectFormat == MTP_FORMAT_ASSOCIATION) {
+ if (initialData != 0)
+ ALOGE("Expected folder size to be 0!");
+ mSendObjectHandle = kInvalidObjectHandle;
+ mSendObjectFormat = 0;
+ mSendObjectModifiedTime = 0;
+ return result;
+ }
+
mtp_file_range mfr;
mfr.fd = open(mSendObjectFilePath, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
if (mfr.fd < 0) {
@@ -1255,8 +1257,7 @@
// reset so we don't attempt to send the data back
mData.reset();
- mDatabase->endSendObject(mSendObjectFilePath, mSendObjectHandle, mSendObjectFormat,
- result == MTP_RESPONSE_OK);
+ mDatabase->endSendObject(mSendObjectHandle, result == MTP_RESPONSE_OK);
mSendObjectHandle = kInvalidObjectHandle;
mSendObjectFormat = 0;
mSendObjectModifiedTime = 0;
@@ -1282,16 +1283,18 @@
MtpString filePath;
int64_t fileLength;
int result = mDatabase->getObjectFilePath(handle, filePath, fileLength, format);
- if (result == MTP_RESPONSE_OK) {
- ALOGV("deleting %s", (const char *)filePath);
- result = mDatabase->deleteFile(handle);
- // Don't delete the actual files unless the database deletion is allowed
- if (result == MTP_RESPONSE_OK) {
- deletePath((const char *)filePath);
- }
- }
+ if (result != MTP_RESPONSE_OK)
+ return result;
- return result;
+ // Don't delete the actual files unless the database deletion is allowed
+ result = mDatabase->beginDeleteObject(handle);
+ if (result != MTP_RESPONSE_OK)
+ return result;
+
+ bool success = deletePath((const char *)filePath);
+
+ mDatabase->endDeleteObject(handle, success);
+ return success ? result : MTP_RESPONSE_PARTIAL_DELETION;
}
MtpResponseCode MtpServer::doGetObjectPropDesc() {