зеркало из https://github.com/mozilla/gecko-dev.git
289 строки
9.4 KiB
C++
289 строки
9.4 KiB
C++
/* -*- 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__
|