summaryrefslogtreecommitdiffstats
path: root/dom/system/gonk/MozMtpDatabase.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/system/gonk/MozMtpDatabase.h')
-rw-r--r--dom/system/gonk/MozMtpDatabase.h288
1 files changed, 288 insertions, 0 deletions
diff --git a/dom/system/gonk/MozMtpDatabase.h b/dom/system/gonk/MozMtpDatabase.h
new file mode 100644
index 000000000..8b308762e
--- /dev/null
+++ b/dom/system/gonk/MozMtpDatabase.h
@@ -0,0 +1,288 @@
+/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_system_mozmtpdatabase_h__
+#define mozilla_system_mozmtpdatabase_h__
+
+#include "MozMtpCommon.h"
+
+#include "mozilla/Mutex.h"
+#include "mozilla/RefPtr.h"
+#include "nsCOMPtr.h"
+#include "nsString.h"
+#include "nsIThread.h"
+#include "nsTArray.h"
+
+class DeviceStorageFile;
+
+BEGIN_MTP_NAMESPACE // mozilla::system::mtp
+
+class RefCountedMtpServer;
+
+using namespace android;
+
+class MozMtpDatabase final : public MtpDatabase
+{
+public:
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MozMtpDatabase)
+
+ MozMtpDatabase();
+
+ // called from SendObjectInfo to reserve a database entry for the incoming file
+ virtual MtpObjectHandle beginSendObject(const char* aPath,
+ MtpObjectFormat aFormat,
+ MtpObjectHandle aParent,
+ MtpStorageID aStorageID,
+ uint64_t aSize,
+ time_t aModified);
+
+ // called to report success or failure of the SendObject file transfer
+ // success should signal a notification of the new object's creation,
+ // failure should remove the database entry created in beginSendObject
+ virtual void endSendObject(const char* aPath,
+ MtpObjectHandle aHandle,
+ MtpObjectFormat aFormat,
+ bool aSucceeded);
+
+ virtual MtpObjectHandleList* getObjectList(MtpStorageID aStorageID,
+ MtpObjectFormat aFormat,
+ MtpObjectHandle aParent);
+
+ virtual int getNumObjects(MtpStorageID aStorageID,
+ MtpObjectFormat aFormat,
+ MtpObjectHandle aParent);
+
+ virtual MtpObjectFormatList* getSupportedPlaybackFormats();
+
+ virtual MtpObjectFormatList* getSupportedCaptureFormats();
+
+ virtual MtpObjectPropertyList* getSupportedObjectProperties(MtpObjectFormat aFormat);
+
+ virtual MtpDevicePropertyList* getSupportedDeviceProperties();
+
+ virtual MtpResponseCode getObjectPropertyValue(MtpObjectHandle aHandle,
+ MtpObjectProperty aProperty,
+ MtpDataPacket& aPacket);
+
+ virtual MtpResponseCode setObjectPropertyValue(MtpObjectHandle aHandle,
+ MtpObjectProperty aProperty,
+ MtpDataPacket& aPacket);
+
+ virtual MtpResponseCode getDevicePropertyValue(MtpDeviceProperty aProperty,
+ MtpDataPacket& aPacket);
+
+ virtual MtpResponseCode setDevicePropertyValue(MtpDeviceProperty aProperty,
+ MtpDataPacket& aPacket);
+
+ virtual MtpResponseCode resetDeviceProperty(MtpDeviceProperty aProperty);
+
+ virtual MtpResponseCode getObjectPropertyList(MtpObjectHandle aHandle,
+ uint32_t aFormat,
+ uint32_t aProperty,
+ int aGroupCode,
+ int aDepth,
+ MtpDataPacket& aPacket);
+
+ virtual MtpResponseCode getObjectInfo(MtpObjectHandle aHandle,
+ MtpObjectInfo& aInfo);
+
+ virtual void* getThumbnail(MtpObjectHandle aHandle, size_t& aOutThumbSize);
+
+ virtual MtpResponseCode getObjectFilePath(MtpObjectHandle aHandle,
+ MtpString& aOutFilePath,
+ int64_t& aOutFileLength,
+ MtpObjectFormat& aOutFormat);
+
+ virtual MtpResponseCode deleteFile(MtpObjectHandle aHandle);
+
+ virtual MtpObjectHandleList* getObjectReferences(MtpObjectHandle aHandle);
+
+ virtual MtpResponseCode setObjectReferences(MtpObjectHandle aHandle,
+ MtpObjectHandleList* aReferences);
+
+ virtual MtpProperty* getObjectPropertyDesc(MtpObjectProperty aProperty,
+ MtpObjectFormat aFormat);
+
+ virtual MtpProperty* getDevicePropertyDesc(MtpDeviceProperty aProperty);
+
+ virtual void sessionStarted();
+
+ virtual void sessionEnded();
+
+ void AddStorage(MtpStorageID aStorageID, const char* aPath, const char *aName);
+ void RemoveStorage(MtpStorageID aStorageID);
+
+ void MtpWatcherUpdate(RefCountedMtpServer* aMtpServer,
+ DeviceStorageFile* aFile,
+ const nsACString& aEventType);
+
+protected:
+ virtual ~MozMtpDatabase();
+
+private:
+
+ struct DbEntry final
+ {
+ DbEntry()
+ : mHandle(0),
+ mStorageID(0),
+ mObjectFormat(MTP_FORMAT_DEFINED),
+ mParent(0),
+ mObjectSize(0),
+ mDateCreated(0),
+ mDateModified(0),
+ mDateAdded(0) {}
+
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DbEntry)
+
+ MtpObjectHandle mHandle; // uint32_t
+ MtpStorageID mStorageID; // uint32_t
+ nsCString mObjectName;
+ MtpObjectFormat mObjectFormat; // uint16_t
+ MtpObjectHandle mParent; // uint32_t
+ uint64_t mObjectSize;
+ nsCString mDisplayName;
+ nsCString mPath;
+ time_t mDateCreated;
+ time_t mDateModified;
+ time_t mDateAdded;
+
+ protected:
+ ~DbEntry() {}
+ };
+
+ template<class T>
+ class ProtectedTArray : private nsTArray<T>
+ {
+ public:
+ typedef T elem_type;
+ typedef typename nsTArray<T>::size_type size_type;
+ typedef typename nsTArray<T>::index_type index_type;
+ typedef nsTArray<T> base_type;
+
+ static const index_type NoIndex = base_type::NoIndex;
+
+ ProtectedTArray(mozilla::Mutex& aMutex)
+ : mMutex(aMutex)
+ {}
+
+ size_type Length() const
+ {
+ // GRR - This assert prints to stderr and won't show up in logcat.
+ mMutex.AssertCurrentThreadOwns();
+ return base_type::Length();
+ }
+
+ template <class Item>
+ elem_type* AppendElement(const Item& aItem)
+ {
+ mMutex.AssertCurrentThreadOwns();
+ return base_type::AppendElement(aItem);
+ }
+
+ void Clear()
+ {
+ mMutex.AssertCurrentThreadOwns();
+ base_type::Clear();
+ }
+
+ void RemoveElementAt(index_type aIndex)
+ {
+ mMutex.AssertCurrentThreadOwns();
+ base_type::RemoveElementAt(aIndex);
+ }
+
+ elem_type& operator[](index_type aIndex)
+ {
+ mMutex.AssertCurrentThreadOwns();
+ return base_type::ElementAt(aIndex);
+ }
+
+ const elem_type& operator[](index_type aIndex) const
+ {
+ mMutex.AssertCurrentThreadOwns();
+ return base_type::ElementAt(aIndex);
+ }
+
+ private:
+ mozilla::Mutex& mMutex;
+ };
+ typedef nsTArray<RefPtr<DbEntry> > UnprotectedDbArray;
+ typedef ProtectedTArray<RefPtr<DbEntry> > ProtectedDbArray;
+
+ struct StorageEntry final
+ {
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(StorageEntry)
+
+ MtpStorageID mStorageID;
+ nsCString mStoragePath;
+ nsCString mStorageName;
+
+ protected:
+ ~StorageEntry() {}
+ };
+ typedef ProtectedTArray<RefPtr<StorageEntry> > StorageArray;
+
+ enum MatchType
+ {
+ MatchAll,
+ MatchHandle,
+ MatchParent,
+ MatchFormat,
+ MatchHandleFormat,
+ MatchParentFormat,
+ };
+
+ bool IsValidHandle(MtpObjectHandle aHandle)
+ {
+ return aHandle > 0 && aHandle < mDb.Length();
+ }
+
+ void AddEntry(DbEntry* aEntry);
+ void AddEntryAndNotify(DbEntry* aEntr, RefCountedMtpServer* aMtpServer);
+ void DumpEntries(const char* aLabel);
+ MtpObjectHandle FindEntryByPath(const nsACString& aPath);
+ already_AddRefed<DbEntry> GetEntry(MtpObjectHandle aHandle);
+ void RemoveEntry(MtpObjectHandle aHandle);
+ void RemoveEntryAndNotify(MtpObjectHandle aHandle, RefCountedMtpServer* aMtpServer);
+ void UpdateEntry(MtpObjectHandle aHandle, DeviceStorageFile* aFile);
+ void UpdateEntryAndNotify(MtpObjectHandle aHandle, DeviceStorageFile* aFile,
+ 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);
+
+ void CreateEntryForFileAndNotify(const nsACString& aPath,
+ DeviceStorageFile* aFile,
+ RefCountedMtpServer* aMtpServer);
+
+ StorageArray::index_type FindStorage(MtpStorageID aStorageID);
+ MtpStorageID FindStorageIDFor(const nsACString& aPath, nsCSubstring& aRemainder);
+ void MtpWatcherNotify(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
+ // (from a non-MTP server thread).
+ mozilla::Mutex mMutex;
+ ProtectedDbArray mDb;
+ StorageArray mStorage;
+
+ bool mBeginSendObjectCalled;
+};
+
+END_MTP_NAMESPACE
+
+#endif // mozilla_system_mozmtpdatabase_h__