Bug 1074593 - Add AddEntryAndNotify and RemoveEntryAndNotify for file/folder change when MTP in use. r=dhylands
--- a/dom/system/gonk/MozMtpDatabase.cpp
+++ b/dom/system/gonk/MozMtpDatabase.cpp
@@ -108,16 +108,23 @@ MozMtpDatabase::AddEntry(DbEntry *entry)
MOZ_ASSERT(mDb.Length() == entry->mHandle);
mDb.AppendElement(entry);
MTP_DBG("Handle: 0x%08x Parent: 0x%08x Path:'%s'",
entry->mHandle, entry->mParent, entry->mPath.get());
}
void
+MozMtpDatabase::AddEntryAndNotify(DbEntry* entry, RefCountedMtpServer* aMtpServer)
+{
+ AddEntry(entry);
+ aMtpServer->sendObjectAdded(entry->mHandle);
+}
+
+void
MozMtpDatabase::DumpEntries(const char* aLabel)
{
MutexAutoLock lock(mMutex);
ProtectedDbArray::size_type numEntries = mDb.Length();
MTP_LOG("%s: numEntries = %d", aLabel, numEntries);
ProtectedDbArray::index_type entryIndex;
for (entryIndex = 1; entryIndex < numEntries; entryIndex++) {
@@ -165,16 +172,23 @@ MozMtpDatabase::RemoveEntry(MtpObjectHan
{
MutexAutoLock lock(mMutex);
if (aHandle > 0 && aHandle < mDb.Length()) {
mDb[aHandle] = nullptr;
}
}
+void
+MozMtpDatabase::RemoveEntryAndNotify(MtpObjectHandle aHandle, RefCountedMtpServer* aMtpServer)
+{
+ RemoveEntry(aHandle);
+ aMtpServer->sendObjectRemoved(aHandle);
+}
+
class FileWatcherNotifyRunnable MOZ_FINAL : public nsRunnable
{
public:
FileWatcherNotifyRunnable(nsACString& aStorageName,
nsACString& aPath,
const char* aEventType)
: mStorageName(aStorageName),
mPath(aPath),
@@ -267,37 +281,31 @@ MozMtpDatabase::FileWatcherUpdate(RefCou
MtpObjectHandle entryHandle = FindEntryByPath(filePath);
if (aEventType.EqualsLiteral("modified")) {
// To update the file information to the newest, we remove the entry for
// the existing file, then re-add the entry for the file.
if (entryHandle != 0) {
MTP_LOG("About to call sendObjectRemoved Handle 0x%08x file %s", entryHandle, filePath.get());
- aMtpServer->sendObjectRemoved(entryHandle);
- RemoveEntry(entryHandle);
+ RemoveEntryAndNotify(entryHandle, aMtpServer);
}
- entryHandle = CreateEntryForFile(filePath, aFile);
- if (entryHandle == 0) {
- // creating entry for the file failed, don't tell MTP
- return;
- }
- MTP_LOG("About to call sendObjectAdded Handle 0x%08x file %s", entryHandle, filePath.get());
- aMtpServer->sendObjectAdded(entryHandle);
+
+ // create entry for the file and tell MTP.
+ CreateEntryForFileAndNotify(filePath, aFile, aMtpServer);
return;
}
if (aEventType.EqualsLiteral("deleted")) {
if (entryHandle == 0) {
// The entry has already been removed. We can't tell MTP.
return;
}
MTP_LOG("About to call sendObjectRemoved Handle 0x%08x file %s", entryHandle, filePath.get());
- aMtpServer->sendObjectRemoved(entryHandle);
- RemoveEntry(entryHandle);
+ RemoveEntryAndNotify(entryHandle, aMtpServer);
return;
}
}
nsCString
MozMtpDatabase::BaseName(const nsCString& path)
{
nsCOMPtr<nsIFile> file;
@@ -321,37 +329,39 @@ GetPathWithoutFileName(const nsCString&
path = StringHead(aFullPath, offset + 1);
}
MTP_LOG("returning '%s'", path.get());
return path;
}
-MtpObjectHandle
-MozMtpDatabase::CreateEntryForFile(const nsACString& aPath, DeviceStorageFile* aFile)
+void
+MozMtpDatabase::CreateEntryForFileAndNotify(const nsACString& aPath,
+ DeviceStorageFile* aFile,
+ RefCountedMtpServer* aMtpServer)
{
// Find the StorageID that this path corresponds to.
nsCString remainder;
MtpStorageID storageID = FindStorageIDFor(aPath, remainder);
if (storageID == 0) {
// The path in question isn't for a storage area we're monitoring.
nsCString path(aPath);
- return 0;
+ return;
}
bool exists = false;
aFile->mFile->Exists(&exists);
if (!exists) {
// File doesn't exist, no sense telling MTP about it.
// This could happen if Device Storage created and deleted a file right
// away. Since the notifications wind up being async, the file might
// not exist any more.
- return 0;
+ return;
}
// Now walk the remaining directories, finding or creating as required.
MtpObjectHandle parent = MTP_PARENT_ROOT;
bool doFind = true;
int32_t offset = aPath.Length() - remainder.Length();
int32_t slash;
@@ -401,22 +411,24 @@ MozMtpDatabase::CreateEntryForFile(const
} else {
// Found a slash, this makes this a directory component
entry->mObjectFormat = MTP_FORMAT_ASSOCIATION;
entry->mObjectSize = 0;
entry->mDateCreated = PR_Now();
}
entry->mDateModified = entry->mDateCreated;
- AddEntry(entry);
+ AddEntryAndNotify(entry, aMtpServer);
+ MTP_LOG("About to call sendObjectAdded Handle 0x%08x file %s", entry->mHandle, entry->mPath.get());
+
parent = entry->mHandle;
offset = slash + 1;
} while (slash != kNotFound);
- return parent; // parent will be entry->mHandle
+ return;
}
void
MozMtpDatabase::AddDirectory(MtpStorageID aStorageID,
const char* aPath,
MtpObjectHandle aParent)
{
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
--- a/dom/system/gonk/MozMtpDatabase.h
+++ b/dom/system/gonk/MozMtpDatabase.h
@@ -222,34 +222,38 @@ private:
MatchHandle,
MatchParent,
MatchFormat,
MatchHandleFormat,
MatchParentFormat,
};
void AddEntry(DbEntry* aEntry);
+ void AddEntryAndNotify(DbEntry* aEntr, RefCountedMtpServer* aMtpServer);
void DumpEntries(const char* aLabel);
MtpObjectHandle FindEntryByPath(const nsACString& aPath);
mozilla::TemporaryRef<DbEntry> GetEntry(MtpObjectHandle aHandle);
void RemoveEntry(MtpObjectHandle aHandle);
+ void RemoveEntryAndNotify(MtpObjectHandle aHandle, RefCountedMtpServer* aMtpServer);
void QueryEntries(MatchType aMatchType, uint32_t aMatchField1,
uint32_t aMatchField2, UnprotectedDbArray& aResult);
nsCString BaseName(const nsCString& aPath);
MtpObjectHandle GetNextHandle()
{
return mDb.Length();
}
void AddDirectory(MtpStorageID aStorageID, const char *aPath, MtpObjectHandle aParent);
- MtpObjectHandle CreateEntryForFile(const nsACString& aPath, DeviceStorageFile* aFile);
+ void CreateEntryForFileAndNotify(const nsACString& aPath,
+ DeviceStorageFile* aFile,
+ RefCountedMtpServer* aMtpServer);
StorageArray::index_type FindStorage(MtpStorageID aStorageID);
MtpStorageID FindStorageIDFor(const nsACString& aPath, nsCSubstring& aRemainder);
void FileWatcherNotify(DbEntry* aEntry, const char* aEventType);
// We need a mutex to protext mDb and mStorage. The MTP server runs on a
// dedicated thread, and it updates/accesses mDb. When files are updated
// through DeviceStorage, we need to update/access mDb and mStorage as well