diff options
Diffstat (limited to 'dom/system/gonk/MozMtpDatabase.h')
-rw-r--r-- | dom/system/gonk/MozMtpDatabase.h | 288 |
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__ |