diff -r 000000000000 -r 6474c204b198 dom/indexedDB/ipc/IndexedDBParent.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dom/indexedDB/ipc/IndexedDBParent.h Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,878 @@ +/* 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_dom_indexeddb_ipc_indexeddbparent_h__ +#define mozilla_dom_indexeddb_ipc_indexeddbparent_h__ + +#include "mozilla/Attributes.h" +#include "mozilla/DebugOnly.h" + +#include "mozilla/dom/indexedDB/IndexedDatabase.h" + +#include "mozilla/dom/indexedDB/PIndexedDBParent.h" +#include "mozilla/dom/indexedDB/PIndexedDBCursorParent.h" +#include "mozilla/dom/indexedDB/PIndexedDBDatabaseParent.h" +#include "mozilla/dom/indexedDB/PIndexedDBDeleteDatabaseRequestParent.h" +#include "mozilla/dom/indexedDB/PIndexedDBIndexParent.h" +#include "mozilla/dom/indexedDB/PIndexedDBObjectStoreParent.h" +#include "mozilla/dom/indexedDB/PIndexedDBRequestParent.h" +#include "mozilla/dom/indexedDB/PIndexedDBTransactionParent.h" + +#include "nsIDOMEventListener.h" + +namespace mozilla { +namespace dom { +class ContentParent; +class PBlobParent; +class TabParent; +} +} + +class nsIDOMBlob; +class nsIDOMEvent; + +BEGIN_INDEXEDDB_NAMESPACE + +class IDBCursor; +class IDBDatabase; +class IDBFactory; +class IDBIndex; +class IDBObjectStore; +class IDBOpenDBRequest; +class IDBTransaction; + +class IndexedDBCursorParent; +class IndexedDBDatabaseParent; +class IndexedDBDeleteDatabaseRequestParent; +class IndexedDBIndexParent; +class IndexedDBObjectStoreParent; +class IndexedDBTransactionParent; +class IndexedDBVersionChangeTransactionParent; +class IndexedDBVersionChangeObjectStoreParent; + +/******************************************************************************* + * AutoSetCurrentTransaction + ******************************************************************************/ + +class AutoSetCurrentTransaction +{ +public: + AutoSetCurrentTransaction(IDBTransaction* aTransaction); + ~AutoSetCurrentTransaction(); +}; + +/******************************************************************************* + * WeakEventListener + ******************************************************************************/ + +class WeakEventListenerBase : public nsIDOMEventListener +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIDOMEVENTLISTENER + +protected: + WeakEventListenerBase() + { } + + virtual ~WeakEventListenerBase() + { } +}; + +template +class WeakEventListener : public WeakEventListenerBase +{ + T* mActor; + +public: + WeakEventListener(T* aActor) + : mActor(aActor) + { } + + void + NoteDyingActor() + { + mActor = nullptr; + } + + NS_IMETHOD + HandleEvent(nsIDOMEvent* aEvent) MOZ_OVERRIDE + { + return mActor ? mActor->HandleEvent(aEvent) : NS_OK; + } + +protected: + virtual ~WeakEventListener() + { } +}; + +template +class AutoWeakEventListener +{ + nsRefPtr > mEventListener; + +public: + AutoWeakEventListener(T* aActor) + { + mEventListener = new WeakEventListener(aActor); + } + + ~AutoWeakEventListener() + { + mEventListener->NoteDyingActor(); + } + + template + operator U*() + { + return mEventListener; + } + + T* + operator ->() + { + return mEventListener; + } +}; + +/******************************************************************************* + * IndexedDBParent + ******************************************************************************/ + +class IndexedDBParent : private PIndexedDBParent +{ + friend class mozilla::dom::ContentParent; + friend class mozilla::dom::TabParent; + friend class IndexedDBDatabaseParent; + friend class IndexedDBDeleteDatabaseRequestParent; + + nsRefPtr mFactory; + nsCString mASCIIOrigin; + + ContentParent* mManagerContent; + TabParent* mManagerTab; + + bool mDisconnected; + +public: + IndexedDBParent(ContentParent* aContentParent); + IndexedDBParent(TabParent* aTabParent); + + virtual ~IndexedDBParent(); + + const nsCString& + GetASCIIOrigin() const + { + return mASCIIOrigin; + } + + void + Disconnect(); + + bool + IsDisconnected() const + { + return mDisconnected; + } + + ContentParent* + GetManagerContent() const + { + return mManagerContent; + } + + TabParent* + GetManagerTab() const + { + return mManagerTab; + } + + bool + CheckReadPermission(const nsAString& aDatabaseName); + + bool + CheckWritePermission(const nsAString& aDatabaseName); + + mozilla::ipc::IProtocol* + CloneProtocol(Channel* aChannel, + mozilla::ipc::ProtocolCloneContext* aCtx) MOZ_OVERRIDE; + +protected: + bool + CheckPermissionInternal(const nsAString& aDatabaseName, + const nsACString& aPermission); + + virtual void + ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE; + + virtual bool + RecvPIndexedDBDatabaseConstructor(PIndexedDBDatabaseParent* aActor, + const nsString& aName, + const uint64_t& aVersion, + const PersistenceType& aPersistenceType) + MOZ_OVERRIDE; + + virtual bool + RecvPIndexedDBDeleteDatabaseRequestConstructor( + PIndexedDBDeleteDatabaseRequestParent* aActor, + const nsString& aName, + const PersistenceType& aPersistenceType) + MOZ_OVERRIDE; + + virtual PIndexedDBDatabaseParent* + AllocPIndexedDBDatabaseParent(const nsString& aName, const uint64_t& aVersion, + const PersistenceType& aPersistenceType) + MOZ_OVERRIDE; + + virtual bool + DeallocPIndexedDBDatabaseParent(PIndexedDBDatabaseParent* aActor) MOZ_OVERRIDE; + + virtual PIndexedDBDeleteDatabaseRequestParent* + AllocPIndexedDBDeleteDatabaseRequestParent( + const nsString& aName, + const PersistenceType& aPersistenceType) + MOZ_OVERRIDE; + + virtual bool + DeallocPIndexedDBDeleteDatabaseRequestParent( + PIndexedDBDeleteDatabaseRequestParent* aActor) + MOZ_OVERRIDE; +}; + +/******************************************************************************* + * IndexedDBDatabaseParent + ******************************************************************************/ + +class IndexedDBDatabaseParent : private PIndexedDBDatabaseParent +{ + friend class IndexedDBParent; + friend class IndexedDBTransactionParent; + friend class IndexedDBVersionChangeTransactionParent; + + AutoWeakEventListener mEventListener; + + nsRefPtr mOpenRequest; + nsRefPtr mDatabase; + +public: + IndexedDBDatabaseParent(); + virtual ~IndexedDBDatabaseParent(); + + nsresult + SetOpenRequest(IDBOpenDBRequest* aRequest); + + nsresult + HandleEvent(nsIDOMEvent* aEvent); + + void + Disconnect(); + + bool + IsDisconnected() const + { + return static_cast(Manager())->IsDisconnected(); + } + + bool + CheckWritePermission(const nsAString& aDatabaseName); + + void + Invalidate(); + +protected: + nsresult + HandleRequestEvent(nsIDOMEvent* aEvent, const nsAString& aType); + + nsresult + HandleDatabaseEvent(nsIDOMEvent* aEvent, const nsAString& aType); + + virtual void + ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE; + + virtual bool + RecvClose(const bool& aUnlinked) MOZ_OVERRIDE; + + virtual bool + RecvPIndexedDBTransactionConstructor(PIndexedDBTransactionParent* aActor, + const TransactionParams& aParams) + MOZ_OVERRIDE; + + virtual PIndexedDBTransactionParent* + AllocPIndexedDBTransactionParent(const TransactionParams& aParams) MOZ_OVERRIDE; + + virtual bool + DeallocPIndexedDBTransactionParent(PIndexedDBTransactionParent* aActor) + MOZ_OVERRIDE; +}; + +/******************************************************************************* + * IndexedDBTransactionParent + ******************************************************************************/ + +class IndexedDBTransactionParent : protected PIndexedDBTransactionParent +{ + friend class IndexedDBCursorParent; + friend class IndexedDBDatabaseParent; + friend class IndexedDBObjectStoreParent; + +protected: + AutoWeakEventListener mEventListener; + + nsRefPtr mTransaction; + + bool mArtificialRequestCount; + +public: + IndexedDBTransactionParent(); + virtual ~IndexedDBTransactionParent(); + + bool + IsDisconnected() const + { + return static_cast(Manager())->IsDisconnected(); + } + + nsresult + SetTransaction(IDBTransaction* aTransaction); + + IDBTransaction* + GetTransaction() const + { + return mTransaction; + } + + nsresult + HandleEvent(nsIDOMEvent* aEvent); + +protected: + virtual void + ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE; + + virtual bool + RecvAbort(const nsresult& aAbortCode) MOZ_OVERRIDE; + + virtual bool + RecvAllRequestsFinished() MOZ_OVERRIDE; + + virtual bool + RecvDeleteObjectStore(const nsString& aName) MOZ_OVERRIDE; + + virtual bool + RecvPIndexedDBObjectStoreConstructor( + PIndexedDBObjectStoreParent* aActor, + const ObjectStoreConstructorParams& aParams) + MOZ_OVERRIDE; + + virtual PIndexedDBObjectStoreParent* + AllocPIndexedDBObjectStoreParent(const ObjectStoreConstructorParams& aParams) + MOZ_OVERRIDE; + + virtual bool + DeallocPIndexedDBObjectStoreParent(PIndexedDBObjectStoreParent* aActor) + MOZ_OVERRIDE; +}; + +/******************************************************************************* + * IndexedDBVersionChangeTransactionParent + ******************************************************************************/ + +class IndexedDBVersionChangeTransactionParent : + public IndexedDBTransactionParent +{ + friend class IndexedDBVersionChangeObjectStoreParent; + +public: + IndexedDBVersionChangeTransactionParent(); + virtual ~IndexedDBVersionChangeTransactionParent(); + + bool + IsDisconnected() const + { + return static_cast(Manager())->IsDisconnected(); + } + +protected: + virtual bool + RecvDeleteObjectStore(const nsString& aName) MOZ_OVERRIDE; + + virtual bool + RecvPIndexedDBObjectStoreConstructor( + PIndexedDBObjectStoreParent* aActor, + const ObjectStoreConstructorParams& aParams) + MOZ_OVERRIDE; + + virtual PIndexedDBObjectStoreParent* + AllocPIndexedDBObjectStoreParent(const ObjectStoreConstructorParams& aParams) + MOZ_OVERRIDE; +}; + +/******************************************************************************* + * IndexedDBCursorParent + ******************************************************************************/ + +class IndexedDBCursorParent : private PIndexedDBCursorParent +{ + friend class IndexedDBIndexParent; + friend class IndexedDBObjectStoreParent; + + nsRefPtr mCursor; + +public: + IDBCursor* + GetCursor() const + { + return mCursor; + } + + bool + IsDisconnected() const; + +protected: + IndexedDBCursorParent(IDBCursor* aCursor); + virtual ~IndexedDBCursorParent(); + + virtual void + ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE; + + virtual bool + RecvPIndexedDBRequestConstructor(PIndexedDBRequestParent* aActor, + const CursorRequestParams& aParams) + MOZ_OVERRIDE; + + virtual PIndexedDBRequestParent* + AllocPIndexedDBRequestParent(const CursorRequestParams& aParams) MOZ_OVERRIDE; + + virtual bool + DeallocPIndexedDBRequestParent(PIndexedDBRequestParent* aActor) MOZ_OVERRIDE; +}; + +/******************************************************************************* + * IndexedDBObjectStoreParent + ******************************************************************************/ + +class IndexedDBObjectStoreParent : protected PIndexedDBObjectStoreParent +{ + friend class IndexedDBIndexParent; + friend class IndexedDBTransactionParent; + friend class IndexedDBVersionChangeTransactionParent; + + typedef mozilla::dom::indexedDB::ipc::OpenCursorResponse OpenCursorResponse; + +protected: + nsRefPtr mObjectStore; + +public: + IndexedDBObjectStoreParent(); + virtual ~IndexedDBObjectStoreParent(); + + void + SetObjectStore(IDBObjectStore* aObjectStore); + + IDBObjectStore* + GetObjectStore() const + { + return mObjectStore; + } + + bool + IsDisconnected() const + { + IndexedDBTransactionParent* manager = + static_cast(Manager()); + return manager->IsDisconnected(); + } + + // Ordinarily callers could just do this manually using + // PIndexedDBObjectStoreParent::SendPIndexedDBCursorConstructor but we're + // inheriting the abstract protocol class privately to prevent outside code + // from sending messages without checking the disconnected state. Therefore + // we need a helper method. + bool + OpenCursor(IDBCursor* aCursor, + const ObjectStoreCursorConstructorParams& aParams, + OpenCursorResponse& aResponse) NS_WARN_UNUSED_RESULT + { + if (IsDisconnected()) { + return true; + } + + IndexedDBCursorParent* cursorActor = new IndexedDBCursorParent(aCursor); + + if (!SendPIndexedDBCursorConstructor(cursorActor, aParams)) { + return false; + } + + aResponse = cursorActor; + return true; + } + +protected: + virtual void + ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE; + + virtual bool + RecvDeleteIndex(const nsString& aName) MOZ_OVERRIDE; + + virtual bool + RecvPIndexedDBRequestConstructor(PIndexedDBRequestParent* aActor, + const ObjectStoreRequestParams& aParams) + MOZ_OVERRIDE; + + virtual bool + RecvPIndexedDBIndexConstructor(PIndexedDBIndexParent* aActor, + const IndexConstructorParams& aParams) + MOZ_OVERRIDE; + + virtual PIndexedDBRequestParent* + AllocPIndexedDBRequestParent(const ObjectStoreRequestParams& aParams) MOZ_OVERRIDE; + + virtual bool + DeallocPIndexedDBRequestParent(PIndexedDBRequestParent* aActor) MOZ_OVERRIDE; + + virtual PIndexedDBIndexParent* + AllocPIndexedDBIndexParent(const IndexConstructorParams& aParams) MOZ_OVERRIDE; + + virtual bool + DeallocPIndexedDBIndexParent(PIndexedDBIndexParent* aActor) MOZ_OVERRIDE; + + virtual PIndexedDBCursorParent* + AllocPIndexedDBCursorParent(const ObjectStoreCursorConstructorParams& aParams) + MOZ_OVERRIDE; + + virtual bool + DeallocPIndexedDBCursorParent(PIndexedDBCursorParent* aActor) MOZ_OVERRIDE; +}; + +/******************************************************************************* + * IndexedDBVersionChangeObjectStoreParent + ******************************************************************************/ + +class IndexedDBVersionChangeObjectStoreParent : + public IndexedDBObjectStoreParent +{ + friend class IndexedDBVersionChangeTransactionParent; + +public: + IndexedDBVersionChangeObjectStoreParent(); + virtual ~IndexedDBVersionChangeObjectStoreParent(); + +protected: + bool + IsDisconnected() const + { + IndexedDBVersionChangeTransactionParent* manager = + static_cast(Manager()); + return manager->IsDisconnected(); + } + + virtual bool + RecvDeleteIndex(const nsString& aName) MOZ_OVERRIDE; + + virtual bool + RecvPIndexedDBIndexConstructor(PIndexedDBIndexParent* aActor, + const IndexConstructorParams& aParams) + MOZ_OVERRIDE; +}; + +/******************************************************************************* + * IndexedDBIndexParent + ******************************************************************************/ + +class IndexedDBIndexParent : private PIndexedDBIndexParent +{ + friend class IndexedDBObjectStoreParent; + friend class IndexedDBVersionChangeObjectStoreParent; + + typedef mozilla::dom::indexedDB::ipc::OpenCursorResponse OpenCursorResponse; + + nsRefPtr mIndex; + +public: + IndexedDBIndexParent(); + virtual ~IndexedDBIndexParent(); + + void + SetIndex(IDBIndex* aObjectStore); + + IDBIndex* + GetIndex() const + { + return mIndex; + } + + // Ordinarily callers could just do this manually using + // PIndexedDBIndexParent::SendPIndexedDBCursorConstructor but we're + // inheriting the abstract protocol class privately to prevent outside code + // from sending messages without checking the disconnected state. Therefore + // we need a helper method. + bool + OpenCursor(IDBCursor* aCursor, const IndexCursorConstructorParams& aParams, + OpenCursorResponse& aResponse) NS_WARN_UNUSED_RESULT + { + if (IsDisconnected()) { + return true; + } + + IndexedDBCursorParent* cursorActor = new IndexedDBCursorParent(aCursor); + + if (!SendPIndexedDBCursorConstructor(cursorActor, aParams)) { + return false; + } + + aResponse = cursorActor; + return true; + } + + bool + IsDisconnected() const + { + IndexedDBObjectStoreParent* manager = + static_cast(Manager()); + return manager->IsDisconnected(); + } + +protected: + virtual void + ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE; + + virtual bool + RecvPIndexedDBRequestConstructor(PIndexedDBRequestParent* aActor, + const IndexRequestParams& aParams) + MOZ_OVERRIDE; + + virtual PIndexedDBRequestParent* + AllocPIndexedDBRequestParent(const IndexRequestParams& aParams) MOZ_OVERRIDE; + + virtual bool + DeallocPIndexedDBRequestParent(PIndexedDBRequestParent* aActor) MOZ_OVERRIDE; + + virtual PIndexedDBCursorParent* + AllocPIndexedDBCursorParent(const IndexCursorConstructorParams& aParams) + MOZ_OVERRIDE; + + virtual bool + DeallocPIndexedDBCursorParent(PIndexedDBCursorParent* aActor) MOZ_OVERRIDE; +}; + +/******************************************************************************* + * IndexedDBRequestParentBase + ******************************************************************************/ + +class IndexedDBRequestParentBase : public PIndexedDBRequestParent +{ +public: + bool + SendResponse(const ResponseValue& aResponse) NS_WARN_UNUSED_RESULT + { + if (IsDisconnected()) { + return true; + } + + return Send__delete__(this, aResponse); + } + +protected: + // Don't let anyone call this directly, instead go through SendResponse. + using PIndexedDBRequestParent::Send__delete__; + + typedef ipc::ResponseValue ResponseValue; + typedef PIndexedDBRequestParent::PBlobParent PBlobParent; + + nsRefPtr mRequest; + + IndexedDBRequestParentBase(); + virtual ~IndexedDBRequestParentBase(); + + virtual void + ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE; + + virtual bool + IsDisconnected() = 0; +}; + +/******************************************************************************* + * IndexedDBObjectStoreRequestParent + ******************************************************************************/ + +class IndexedDBObjectStoreRequestParent : public IndexedDBRequestParentBase +{ + friend class IndexedDBObjectStoreParent; + + nsRefPtr mObjectStore; + + typedef ipc::ObjectStoreRequestParams ParamsUnionType; + typedef ParamsUnionType::Type RequestType; + DebugOnly mRequestType; + + typedef ipc::AddParams AddParams; + typedef ipc::PutParams PutParams; + typedef ipc::ClearParams ClearParams; + typedef ipc::DeleteParams DeleteParams; + typedef ipc::GetParams GetParams; + typedef ipc::GetAllParams GetAllParams; + typedef ipc::GetAllKeysParams GetAllKeysParams; + typedef ipc::CountParams CountParams; + typedef ipc::OpenCursorParams OpenCursorParams; + typedef ipc::OpenKeyCursorParams OpenKeyCursorParams; + +public: + IndexedDBObjectStoreRequestParent(IDBObjectStore* aObjectStore, + RequestType aRequestType); + virtual ~IndexedDBObjectStoreRequestParent(); + + bool + Get(const GetParams& aParams); + + bool + GetAll(const GetAllParams& aParams); + + bool + GetAllKeys(const GetAllKeysParams& aParams); + + bool + Add(const AddParams& aParams); + + bool + Put(const PutParams& aParams); + + bool + Delete(const DeleteParams& aParams); + + bool + Clear(const ClearParams& aParams); + + bool + Count(const CountParams& aParams); + + bool + OpenCursor(const OpenCursorParams& aParams); + + bool + OpenKeyCursor(const OpenKeyCursorParams& aParams); + +protected: + void + ConvertBlobActors(const InfallibleTArray& aActors, + nsTArray >& aBlobs); + +private: + virtual bool + IsDisconnected() MOZ_OVERRIDE; +}; + +/******************************************************************************* + * IndexedDBIndexRequestParent + ******************************************************************************/ + +class IndexedDBIndexRequestParent : public IndexedDBRequestParentBase +{ + friend class IndexedDBIndexParent; + + nsRefPtr mIndex; + + typedef ipc::IndexRequestParams ParamsUnionType; + typedef ParamsUnionType::Type RequestType; + DebugOnly mRequestType; + + typedef ipc::GetKeyParams GetKeyParams; + typedef ipc::GetAllKeysParams GetAllKeysParams; + typedef ipc::OpenKeyCursorParams OpenKeyCursorParams; + typedef ipc::GetParams GetParams; + typedef ipc::GetAllParams GetAllParams; + typedef ipc::CountParams CountParams; + typedef ipc::OpenCursorParams OpenCursorParams; + +public: + IndexedDBIndexRequestParent(IDBIndex* aIndex, RequestType aRequestType); + virtual ~IndexedDBIndexRequestParent(); + + bool + Get(const GetParams& aParams); + + bool + GetKey(const GetKeyParams& aParams); + + bool + GetAll(const GetAllParams& aParams); + + bool + GetAllKeys(const GetAllKeysParams& aParams); + + bool + Count(const CountParams& aParams); + + bool + OpenCursor(const OpenCursorParams& aParams); + + bool + OpenKeyCursor(const OpenKeyCursorParams& aParams); + +private: + virtual bool + IsDisconnected() MOZ_OVERRIDE; +}; + +/******************************************************************************* + * IndexedDBCursorRequestParent + ******************************************************************************/ + +class IndexedDBCursorRequestParent : public IndexedDBRequestParentBase +{ + friend class IndexedDBCursorParent; + + nsRefPtr mCursor; + + typedef ipc::CursorRequestParams ParamsUnionType; + typedef ParamsUnionType::Type RequestType; + DebugOnly mRequestType; + + typedef ipc::ContinueParams ContinueParams; + +public: + IndexedDBCursorRequestParent(IDBCursor* aCursor, RequestType aRequestType); + virtual ~IndexedDBCursorRequestParent(); + + bool + Continue(const ContinueParams& aParams); + +private: + virtual bool + IsDisconnected() MOZ_OVERRIDE; +}; + +/******************************************************************************* + * IndexedDBDeleteDatabaseRequestParent + ******************************************************************************/ + +class IndexedDBDeleteDatabaseRequestParent : + private PIndexedDBDeleteDatabaseRequestParent +{ + friend class IndexedDBParent; + + AutoWeakEventListener mEventListener; + + nsRefPtr mFactory; + nsRefPtr mOpenRequest; + +public: + nsresult + HandleEvent(nsIDOMEvent* aEvent); + +protected: + IndexedDBDeleteDatabaseRequestParent(IDBFactory* aFactory); + virtual ~IndexedDBDeleteDatabaseRequestParent(); + + nsresult + SetOpenRequest(IDBOpenDBRequest* aOpenRequest); + + bool + IsDisconnected() const + { + return static_cast(Manager())->IsDisconnected(); + } +}; + +END_INDEXEDDB_NAMESPACE + +#endif // mozilla_dom_indexeddb_ipc_indexeddbparent_h__