Bug 1361330 - Part 4: Core implementation; r=asuth

This commit is contained in:
Jan Varga 2018-08-20 14:33:03 +02:00
parent 8486a0d568
commit 5733cbbbd3
27 changed files with 3578 additions and 2 deletions

View File

@ -101,6 +101,7 @@ DIRS += [
'payments',
'websocket',
'serviceworkers',
'simpledb',
]
if CONFIG['OS_ARCH'] == 'WINNT':

View File

@ -36,6 +36,7 @@
#include "mozilla/dom/quota/PQuotaParent.h"
#include "mozilla/dom/quota/PQuotaRequestParent.h"
#include "mozilla/dom/quota/PQuotaUsageRequestParent.h"
#include "mozilla/dom/simpledb/ActorsParent.h"
#include "mozilla/dom/StorageActivityService.h"
#include "mozilla/ipc/BackgroundParent.h"
#include "mozilla/ipc/BackgroundUtils.h"
@ -3600,8 +3601,12 @@ QuotaManager::Init(const nsAString& aBasePath)
return NS_ERROR_FAILURE;
}
static_assert(Client::IDB == 0 && Client::ASMJS == 1 && Client::DOMCACHE == 2 &&
Client::TYPE_MAX == 3, "Fix the registration!");
static_assert(Client::IDB == 0 &&
Client::ASMJS == 1 &&
Client::DOMCACHE == 2 &&
Client::SDB == 3 &&
Client::TYPE_MAX == 4,
"Fix the registration!");
MOZ_ASSERT(mClients.Capacity() == Client::TYPE_MAX,
"Should be using an auto array with correct capacity!");
@ -3610,6 +3615,7 @@ QuotaManager::Init(const nsAString& aBasePath)
mClients.AppendElement(indexedDB::CreateQuotaClient());
mClients.AppendElement(asmjscache::CreateClient());
mClients.AppendElement(cache::CreateQuotaClient());
mClients.AppendElement(simpledb::CreateQuotaClient());
return NS_OK;
}

View File

@ -19,6 +19,7 @@ class nsIRunnable;
#define IDB_DIRECTORY_NAME "idb"
#define ASMJSCACHE_DIRECTORY_NAME "asmjs"
#define DOMCACHE_DIRECTORY_NAME "cache"
#define SDB_DIRECTORY_NAME "sdb"
#define LS_DIRECTORY_NAME "ls"
BEGIN_QUOTA_NAMESPACE
@ -42,6 +43,7 @@ public:
//APPCACHE,
ASMJS,
DOMCACHE,
SDB,
TYPE_MAX
};
@ -64,6 +66,10 @@ public:
aText.AssignLiteral(DOMCACHE_DIRECTORY_NAME);
break;
case SDB:
aText.AssignLiteral(SDB_DIRECTORY_NAME);
break;
case TYPE_MAX:
default:
MOZ_ASSERT_UNREACHABLE("Bad id value!");
@ -85,6 +91,9 @@ public:
else if (aText.EqualsLiteral(DOMCACHE_DIRECTORY_NAME)) {
aType = DOMCACHE;
}
else if (aText.EqualsLiteral(SDB_DIRECTORY_NAME)) {
aType = SDB;
}
else {
return NS_ERROR_FAILURE;
}

View File

@ -0,0 +1,243 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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/. */
#include "ActorsChild.h"
#include "nsVariant.h"
#include "SDBConnection.h"
#include "SDBRequest.h"
#include "SDBResults.h"
namespace mozilla {
namespace dom {
/*******************************************************************************
* SDBConnectionChild
******************************************************************************/
SDBConnectionChild::SDBConnectionChild(SDBConnection* aConnection)
: mConnection(aConnection)
{
AssertIsOnOwningThread();
MOZ_ASSERT(aConnection);
MOZ_COUNT_CTOR(SDBConnectionChild);
}
SDBConnectionChild::~SDBConnectionChild()
{
AssertIsOnOwningThread();
MOZ_COUNT_DTOR(SDBConnectionChild);
}
void
SDBConnectionChild::SendDeleteMeInternal()
{
AssertIsOnOwningThread();
if (mConnection) {
mConnection->ClearBackgroundActor();
mConnection = nullptr;
MOZ_ALWAYS_TRUE(PBackgroundSDBConnectionChild::SendDeleteMe());
}
}
void
SDBConnectionChild::ActorDestroy(ActorDestroyReason aWhy)
{
AssertIsOnOwningThread();
if (mConnection) {
mConnection->ClearBackgroundActor();
#ifdef DEBUG
mConnection = nullptr;
#endif
}
}
PBackgroundSDBRequestChild*
SDBConnectionChild::AllocPBackgroundSDBRequestChild(
const SDBRequestParams& aParams)
{
AssertIsOnOwningThread();
MOZ_CRASH("PBackgroundSDBRequestChild actors should be manually "
"constructed!");
}
bool
SDBConnectionChild::DeallocPBackgroundSDBRequestChild(
PBackgroundSDBRequestChild* aActor)
{
AssertIsOnOwningThread();
MOZ_ASSERT(aActor);
delete static_cast<SDBRequestChild*>(aActor);
return true;
}
mozilla::ipc::IPCResult
SDBConnectionChild::RecvAllowToClose()
{
AssertIsOnOwningThread();
if (mConnection) {
mConnection->AllowToClose();
}
return IPC_OK();
}
mozilla::ipc::IPCResult
SDBConnectionChild::RecvClosed()
{
AssertIsOnOwningThread();
if (mConnection) {
mConnection->OnClose(/* aAbnormal */ true);
}
return IPC_OK();
}
/*******************************************************************************
* SDBRequestChild
******************************************************************************/
SDBRequestChild::SDBRequestChild(SDBRequest* aRequest)
: mConnection(aRequest->GetConnection())
, mRequest(aRequest)
{
AssertIsOnOwningThread();
MOZ_ASSERT(aRequest);
MOZ_COUNT_CTOR(SDBRequestChild);
}
SDBRequestChild::~SDBRequestChild()
{
AssertIsOnOwningThread();
MOZ_COUNT_DTOR(SDBRequestChild);
}
#ifdef DEBUG
void
SDBRequestChild::AssertIsOnOwningThread() const
{
MOZ_ASSERT(mRequest);
mRequest->AssertIsOnOwningThread();
}
#endif // DEBUG
void
SDBRequestChild::HandleResponse(nsresult aResponse)
{
AssertIsOnOwningThread();
MOZ_ASSERT(NS_FAILED(aResponse));
MOZ_ASSERT(mRequest);
mRequest->SetError(aResponse);
}
void
SDBRequestChild::HandleResponse()
{
AssertIsOnOwningThread();
MOZ_ASSERT(mRequest);
RefPtr<nsVariant> variant = new nsVariant();
variant->SetAsVoid();
mRequest->SetResult(variant);
}
void
SDBRequestChild::HandleResponse(const nsCString& aResponse)
{
AssertIsOnOwningThread();
MOZ_ASSERT(mRequest);
RefPtr<SDBResult> result = new SDBResult(aResponse);
RefPtr<nsVariant> variant = new nsVariant();
variant->SetAsInterface(NS_GET_IID(nsISDBResult), result);
mRequest->SetResult(variant);
}
void
SDBRequestChild::ActorDestroy(ActorDestroyReason aWhy)
{
AssertIsOnOwningThread();
if (mConnection) {
mConnection->AssertIsOnOwningThread();
mConnection->OnRequestFinished();
#ifdef DEBUG
mConnection = nullptr;
#endif
}
}
mozilla::ipc::IPCResult
SDBRequestChild::Recv__delete__(const SDBRequestResponse& aResponse)
{
AssertIsOnOwningThread();
MOZ_ASSERT(mRequest);
MOZ_ASSERT(mConnection);
switch (aResponse.type()) {
case SDBRequestResponse::Tnsresult:
HandleResponse(aResponse.get_nsresult());
break;
case SDBRequestResponse::TSDBRequestOpenResponse:
HandleResponse();
mConnection->OnOpen();
break;
case SDBRequestResponse::TSDBRequestSeekResponse:
HandleResponse();
break;
case SDBRequestResponse::TSDBRequestReadResponse:
HandleResponse(aResponse.get_SDBRequestReadResponse().data());
break;
case SDBRequestResponse::TSDBRequestWriteResponse:
HandleResponse();
break;
case SDBRequestResponse::TSDBRequestCloseResponse:
HandleResponse();
mConnection->OnClose(/* aAbnormal */ false);
break;
default:
MOZ_CRASH("Unknown response type!");
}
mConnection->OnRequestFinished();
// Null this out so that we don't try to call OnRequestFinished() again in
// ActorDestroy.
mConnection = nullptr;
return IPC_OK();
}
} // namespace dom
} // namespace mozilla

115
dom/simpledb/ActorsChild.h Normal file
View File

@ -0,0 +1,115 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_dom_simpledb_ActorsChild_h
#define mozilla_dom_simpledb_ActorsChild_h
#include "mozilla/dom/PBackgroundSDBConnectionChild.h"
#include "mozilla/dom/PBackgroundSDBRequestChild.h"
namespace mozilla {
namespace ipc {
class BackgroundChildImpl;
} // namespace ipc
namespace dom {
class SDBConnection;
class SDBRequest;
class SDBConnectionChild final
: public PBackgroundSDBConnectionChild
{
friend class mozilla::ipc::BackgroundChildImpl;
friend class SDBConnection;
SDBConnection* mConnection;
NS_DECL_OWNINGTHREAD
public:
void
AssertIsOnOwningThread() const
{
NS_ASSERT_OWNINGTHREAD(SDBConnectionChild);
}
private:
// Only created by SDBConnection.
explicit SDBConnectionChild(SDBConnection* aConnection);
// Only destroyed by mozilla::ipc::BackgroundChildImpl.
~SDBConnectionChild();
void
SendDeleteMeInternal();
// IPDL methods are only called by IPDL.
virtual void
ActorDestroy(ActorDestroyReason aWhy) override;
virtual PBackgroundSDBRequestChild*
AllocPBackgroundSDBRequestChild(const SDBRequestParams& aParams) override;
virtual bool
DeallocPBackgroundSDBRequestChild(PBackgroundSDBRequestChild* aActor)
override;
virtual mozilla::ipc::IPCResult
RecvAllowToClose() override;
virtual mozilla::ipc::IPCResult
RecvClosed() override;
};
class SDBRequestChild final
: public PBackgroundSDBRequestChild
{
friend class SDBConnectionChild;
friend class SDBConnection;
RefPtr<SDBConnection> mConnection;
RefPtr<SDBRequest> mRequest;
public:
void
AssertIsOnOwningThread() const
#ifdef DEBUG
;
#else
{ }
#endif
private:
// Only created by SDBConnection.
explicit SDBRequestChild(SDBRequest* aRequest);
// Only destroyed by SDBConnectionChild.
~SDBRequestChild();
void
HandleResponse(nsresult aResponse);
void
HandleResponse();
void
HandleResponse(const nsCString& aResponse);
// IPDL methods are only called by IPDL.
virtual void
ActorDestroy(ActorDestroyReason aWhy) override;
virtual mozilla::ipc::IPCResult
Recv__delete__(const SDBRequestResponse& aResponse) override;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_simpledb_ActorsChild_h

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,52 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_dom_simpledb_ActorsParent_h
#define mozilla_dom_simpledb_ActorsParent_h
template <class> struct already_AddRefed;
namespace mozilla {
namespace ipc {
class PrincipalInfo;
} // namespace ipc
namespace dom {
class PBackgroundSDBConnectionParent;
namespace quota {
class Client;
} // namespace quota
PBackgroundSDBConnectionParent*
AllocPBackgroundSDBConnectionParent(
const mozilla::ipc::PrincipalInfo& aPrincipalInfo);
bool
RecvPBackgroundSDBConnectionConstructor(
PBackgroundSDBConnectionParent* aActor,
const mozilla::ipc::PrincipalInfo& aPrincipalInfo);
bool
DeallocPBackgroundSDBConnectionParent(PBackgroundSDBConnectionParent* aActor);
namespace simpledb {
already_AddRefed<mozilla::dom::quota::Client>
CreateQuotaClient();
} // namespace simpledb
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_simpledb_ActorsParent_h

View File

@ -0,0 +1,64 @@
/* 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/. */
include protocol PBackground;
include protocol PBackgroundSDBRequest;
namespace mozilla {
namespace dom {
struct SDBRequestOpenParams
{
nsString name;
};
struct SDBRequestSeekParams
{
uint64_t offset;
};
struct SDBRequestReadParams
{
uint64_t size;
};
struct SDBRequestWriteParams
{
nsCString data;
};
struct SDBRequestCloseParams
{
};
union SDBRequestParams
{
SDBRequestOpenParams;
SDBRequestSeekParams;
SDBRequestReadParams;
SDBRequestWriteParams;
SDBRequestCloseParams;
};
protocol PBackgroundSDBConnection
{
manager PBackground;
manages PBackgroundSDBRequest;
parent:
async DeleteMe();
async PBackgroundSDBRequest(SDBRequestParams params);
child:
async __delete__();
async AllowToClose();
async Closed();
};
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,50 @@
/* 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/. */
include protocol PBackgroundSDBConnection;
namespace mozilla {
namespace dom {
struct SDBRequestOpenResponse
{
};
struct SDBRequestSeekResponse
{
};
struct SDBRequestReadResponse
{
nsCString data;
};
struct SDBRequestWriteResponse
{
};
struct SDBRequestCloseResponse
{
};
union SDBRequestResponse
{
nsresult;
SDBRequestOpenResponse;
SDBRequestSeekResponse;
SDBRequestReadResponse;
SDBRequestWriteResponse;
SDBRequestCloseResponse;
};
protocol PBackgroundSDBRequest
{
manager PBackgroundSDBConnection;
child:
async __delete__(SDBRequestResponse response);
};
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,403 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
#include "SDBConnection.h"
#include "ActorsChild.h"
#include "jsfriendapi.h"
#include "mozilla/ipc/BackgroundChild.h"
#include "mozilla/ipc/BackgroundParent.h"
#include "mozilla/ipc/BackgroundUtils.h"
#include "mozilla/ipc/PBackgroundChild.h"
#include "nsISDBCallbacks.h"
#include "SDBRequest.h"
namespace mozilla {
namespace dom {
using namespace mozilla::ipc;
namespace {
nsresult
GetWriteData(JSContext* aCx,
JS::Handle<JS::Value> aValue,
nsCString& aData)
{
if (aValue.isObject()) {
JS::Rooted<JSObject*> obj(aCx, &aValue.toObject());
bool isView = false;
if (JS_IsArrayBufferObject(obj) ||
(isView = JS_IsArrayBufferViewObject(obj))) {
uint8_t* data;
uint32_t length;
bool unused;
if (isView) {
JS_GetObjectAsArrayBufferView(obj, &length, &unused, &data);
} else {
JS_GetObjectAsArrayBuffer(obj, &length, &data);
}
if (NS_WARN_IF(!aData.Assign(reinterpret_cast<char*>(data),
length,
fallible_t()))) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
}
return NS_ERROR_NOT_IMPLEMENTED;
}
} // namespace
SDBConnection::SDBConnection()
: mBackgroundActor(nullptr)
, mRunningRequest(false)
, mOpen(false)
, mAllowedToClose(false)
{
AssertIsOnOwningThread();
}
SDBConnection::~SDBConnection()
{
AssertIsOnOwningThread();
if (mBackgroundActor) {
mBackgroundActor->SendDeleteMeInternal();
MOZ_ASSERT(!mBackgroundActor, "SendDeleteMeInternal should have cleared!");
}
}
void
SDBConnection::ClearBackgroundActor()
{
AssertIsOnOwningThread();
mBackgroundActor = nullptr;
}
void
SDBConnection::OnNewRequest()
{
AssertIsOnOwningThread();
MOZ_ASSERT(!mRunningRequest);
mRunningRequest = true;
}
void
SDBConnection::OnRequestFinished()
{
AssertIsOnOwningThread();
MOZ_ASSERT(mRunningRequest);
mRunningRequest = false;
}
void
SDBConnection::OnOpen()
{
AssertIsOnOwningThread();
MOZ_ASSERT(!mOpen);
mOpen = true;
}
void
SDBConnection::OnClose(bool aAbnormal)
{
AssertIsOnOwningThread();
MOZ_ASSERT(mOpen);
mOpen = false;
if (aAbnormal) {
MOZ_ASSERT(mAllowedToClose);
if (mCloseCallback) {
mCloseCallback->OnClose(this);
}
}
}
void
SDBConnection::AllowToClose()
{
AssertIsOnOwningThread();
mAllowedToClose = true;
}
nsresult
SDBConnection::CheckState()
{
AssertIsOnOwningThread();
if (mAllowedToClose) {
return NS_ERROR_ABORT;
}
if (mRunningRequest) {
return NS_ERROR_NOT_AVAILABLE;
}
return NS_OK;
}
nsresult
SDBConnection::EnsureBackgroundActor()
{
AssertIsOnOwningThread();
if (mBackgroundActor) {
return NS_OK;
}
PBackgroundChild* backgroundActor =
BackgroundChild::GetOrCreateForCurrentThread();
if (NS_WARN_IF(!backgroundActor)) {
return NS_ERROR_FAILURE;
}
SDBConnectionChild* actor = new SDBConnectionChild(this);
mBackgroundActor =
static_cast<SDBConnectionChild*>(
backgroundActor->SendPBackgroundSDBConnectionConstructor(
actor,
*mPrincipalInfo));
if (NS_WARN_IF(!mBackgroundActor)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult
SDBConnection::InitiateRequest(SDBRequest* aRequest,
const SDBRequestParams& aParams)
{
AssertIsOnOwningThread();
MOZ_ASSERT(aRequest);
MOZ_ASSERT(mBackgroundActor);
auto actor = new SDBRequestChild(aRequest);
if (!mBackgroundActor->SendPBackgroundSDBRequestConstructor(actor, aParams)) {
return NS_ERROR_FAILURE;
}
// Balanced in SDBRequestChild::Recv__delete__().
OnNewRequest();
return NS_OK;
}
NS_IMPL_ISUPPORTS(SDBConnection, nsISDBConnection)
NS_IMETHODIMP
SDBConnection::Init(nsIPrincipal *aPrincipal)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aPrincipal);
nsAutoPtr<PrincipalInfo> principalInfo(new PrincipalInfo());
nsresult rv = PrincipalToPrincipalInfo(aPrincipal, principalInfo);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (principalInfo->type() != PrincipalInfo::TContentPrincipalInfo &&
principalInfo->type() != PrincipalInfo::TSystemPrincipalInfo) {
NS_WARNING("Simpledb not allowed for this principal!");
return NS_ERROR_INVALID_ARG;
}
mPrincipalInfo = std::move(principalInfo);
return NS_OK;
}
NS_IMETHODIMP
SDBConnection::Open(const nsAString& aName, nsISDBRequest** _retval)
{
AssertIsOnOwningThread();
nsresult rv = CheckState();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (mOpen) {
return NS_ERROR_ALREADY_INITIALIZED;
}
SDBRequestOpenParams params;
params.name() = aName;
RefPtr<SDBRequest> request = new SDBRequest(this);
rv = EnsureBackgroundActor();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = InitiateRequest(request, params);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
request.forget(_retval);
return NS_OK;
}
NS_IMETHODIMP
SDBConnection::Seek(uint64_t aOffset, nsISDBRequest** _retval)
{
AssertIsOnOwningThread();
nsresult rv = CheckState();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (!mOpen) {
return NS_BASE_STREAM_CLOSED;
}
SDBRequestSeekParams params;
params.offset() = aOffset;
RefPtr<SDBRequest> request = new SDBRequest(this);
rv = InitiateRequest(request, params);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
request.forget(_retval);
return NS_OK;
}
NS_IMETHODIMP
SDBConnection::Read(uint64_t aSize, nsISDBRequest** _retval)
{
AssertIsOnOwningThread();
nsresult rv = CheckState();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (!mOpen) {
return NS_BASE_STREAM_CLOSED;
}
SDBRequestReadParams params;
params.size() = aSize;
RefPtr<SDBRequest> request = new SDBRequest(this);
rv = InitiateRequest(request, params);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
request.forget(_retval);
return NS_OK;
}
NS_IMETHODIMP
SDBConnection::Write(JS::HandleValue aValue,
JSContext* aCx,
nsISDBRequest** _retval)
{
AssertIsOnOwningThread();
nsresult rv = CheckState();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (!mOpen) {
return NS_BASE_STREAM_CLOSED;
}
JS::Rooted<JS::Value> value(aCx, aValue);
nsCString data;
rv = GetWriteData(aCx, value, data);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
SDBRequestWriteParams params;
params.data() = data;
RefPtr<SDBRequest> request = new SDBRequest(this);
rv = InitiateRequest(request, params);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
request.forget(_retval);
return NS_OK;
}
NS_IMETHODIMP
SDBConnection::Close(nsISDBRequest** _retval)
{
AssertIsOnOwningThread();
nsresult rv = CheckState();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (!mOpen) {
return NS_BASE_STREAM_CLOSED;
}
SDBRequestCloseParams params;
RefPtr<SDBRequest> request = new SDBRequest(this);
rv = InitiateRequest(request, params);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
request.forget(_retval);
return NS_OK;
}
NS_IMETHODIMP
SDBConnection::GetCloseCallback(nsISDBCloseCallback** aCloseCallback)
{
AssertIsOnOwningThread();
MOZ_ASSERT(aCloseCallback);
NS_IF_ADDREF(*aCloseCallback = mCloseCallback);
return NS_OK;
}
NS_IMETHODIMP
SDBConnection::SetCloseCallback(nsISDBCloseCallback* aCloseCallback)
{
AssertIsOnOwningThread();
mCloseCallback = aCloseCallback;
return NS_OK;
}
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,97 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_dom_simpledb_SDBConnection_h
#define mozilla_dom_simpledb_SDBConnection_h
#include "nsAutoPtr.h"
#include "nsISDBConnection.h"
#include "nsTArray.h"
#define NS_SDBCONNECTION_CONTRACTID \
"@mozilla.org/dom/sdb-connection;1"
class nsISDBCloseCallback;
namespace mozilla {
namespace ipc {
class PBackgroundChild;
class PrincipalInfo;
} // namespace ipc
namespace dom {
class SDBConnectionChild;
class SDBRequest;
class SDBRequestParams;
class SDBConnection final
: public nsISDBConnection
{
typedef mozilla::ipc::PBackgroundChild PBackgroundChild;
typedef mozilla::ipc::PrincipalInfo PrincipalInfo;
nsCOMPtr<nsISDBCloseCallback> mCloseCallback;
nsAutoPtr<PrincipalInfo> mPrincipalInfo;
SDBConnectionChild* mBackgroundActor;
bool mRunningRequest;
bool mOpen;
bool mAllowedToClose;
public:
SDBConnection();
void
AssertIsOnOwningThread() const
{
NS_ASSERT_OWNINGTHREAD(SDBConnection);
}
void
ClearBackgroundActor();
void
OnNewRequest();
void
OnRequestFinished();
void
OnOpen();
void
OnClose(bool aAbnormal);
void
AllowToClose();
private:
~SDBConnection();
nsresult
CheckState();
nsresult
EnsureBackgroundActor();
nsresult
InitiateRequest(SDBRequest* aRequest,
const SDBRequestParams& aParams);
NS_DECL_ISUPPORTS
NS_DECL_NSISDBCONNECTION
};
} // namespace dom
} // namespace mozilla
#endif /* mozilla_dom_simpledb_SDBConnection_h */

134
dom/simpledb/SDBRequest.cpp Normal file
View File

@ -0,0 +1,134 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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/. */
#include "SDBRequest.h"
#include "nsISDBCallbacks.h"
#include "nsThreadUtils.h"
#include "SDBConnection.h"
namespace mozilla {
namespace dom {
SDBRequest::SDBRequest(SDBConnection* aConnection)
: mConnection(aConnection)
, mResultCode(NS_OK)
, mHaveResultOrErrorCode(false)
{
AssertIsOnOwningThread();
MOZ_ASSERT(aConnection);
}
SDBRequest::~SDBRequest()
{
AssertIsOnOwningThread();
}
void
SDBRequest::SetResult(nsIVariant* aResult)
{
AssertIsOnOwningThread();
MOZ_ASSERT(aResult);
MOZ_ASSERT(mConnection);
MOZ_ASSERT(!mHaveResultOrErrorCode);
mResult = aResult;
mHaveResultOrErrorCode = true;
FireCallback();
}
void
SDBRequest::SetError(nsresult aRv)
{
AssertIsOnOwningThread();
MOZ_ASSERT(mConnection);
MOZ_ASSERT(mResultCode == NS_OK);
MOZ_ASSERT(!mHaveResultOrErrorCode);
mResultCode = aRv;
mHaveResultOrErrorCode = true;
FireCallback();
}
void
SDBRequest::FireCallback()
{
AssertIsOnOwningThread();
if (mCallback) {
nsCOMPtr<nsISDBCallback> callback;
callback.swap(mCallback);
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToCurrentThread(
NewRunnableMethod<RefPtr<SDBRequest>>(
"nsISDBCallback::OnComplete",
callback,
&nsISDBCallback::OnComplete,
this)));
}
}
NS_IMPL_CYCLE_COLLECTING_ADDREF(SDBRequest)
NS_IMPL_CYCLE_COLLECTING_RELEASE(SDBRequest)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SDBRequest)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY(nsISDBRequest)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION(SDBRequest, mCallback, mResult)
NS_IMETHODIMP
SDBRequest::GetResult(nsIVariant** aResult)
{
AssertIsOnOwningThread();
MOZ_ASSERT(aResult);
if (!mHaveResultOrErrorCode) {
return NS_ERROR_NOT_AVAILABLE;
}
NS_IF_ADDREF(*aResult = mResult);
return NS_OK;
}
NS_IMETHODIMP
SDBRequest::GetResultCode(nsresult* aResultCode)
{
AssertIsOnOwningThread();
MOZ_ASSERT(aResultCode);
if (!mHaveResultOrErrorCode) {
return NS_ERROR_NOT_AVAILABLE;
}
*aResultCode = mResultCode;
return NS_OK;
}
NS_IMETHODIMP
SDBRequest::GetCallback(nsISDBCallback** aCallback)
{
AssertIsOnOwningThread();
MOZ_ASSERT(aCallback);
NS_IF_ADDREF(*aCallback = mCallback);
return NS_OK;
}
NS_IMETHODIMP
SDBRequest::SetCallback(nsISDBCallback* aCallback)
{
AssertIsOnOwningThread();
mCallback = aCallback;
return NS_OK;
}
} // namespace dom
} // namespace mozilla

70
dom/simpledb/SDBRequest.h Normal file
View File

@ -0,0 +1,70 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_dom_simpledb_SDBRequest_h
#define mozilla_dom_simpledb_SDBRequest_h
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsISDBRequest.h"
#include "nsIVariant.h"
class nsISDBCallback;
namespace mozilla {
namespace dom {
class SDBConnection;
class SDBRequest final
: public nsISDBRequest
{
RefPtr<SDBConnection> mConnection;
nsCOMPtr<nsIVariant> mResult;
nsCOMPtr<nsISDBCallback> mCallback;
nsresult mResultCode;
bool mHaveResultOrErrorCode;
public:
explicit SDBRequest(SDBConnection* aConnection);
void
AssertIsOnOwningThread() const
{
NS_ASSERT_OWNINGTHREAD(SDBRequest);
}
SDBConnection*
GetConnection() const
{
AssertIsOnOwningThread();
return mConnection;
}
void
SetResult(nsIVariant* aResult);
void
SetError(nsresult aRv);
private:
~SDBRequest();
void
FireCallback();
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_NSISDBREQUEST
NS_DECL_CYCLE_COLLECTION_CLASS(SDBRequest)
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_simpledb_SDBRequest_h

View File

@ -0,0 +1,63 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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/. */
#include "SDBResults.h"
#include "nsContentUtils.h"
namespace mozilla {
namespace dom {
SDBResult::SDBResult(const nsACString& aData)
: mData(aData)
{
}
NS_IMPL_ISUPPORTS(SDBResult,
nsISDBResult)
NS_IMETHODIMP
SDBResult::GetAsArray(uint32_t* aDataLen, uint8_t** aData)
{
MOZ_ASSERT(aDataLen);
MOZ_ASSERT(aData);
if (mData.IsEmpty()) {
*aDataLen = 0;
*aData = nullptr;
return NS_OK;
}
uint32_t length = mData.Length();
uint8_t* data = static_cast<uint8_t*>(moz_xmalloc(length * sizeof(uint8_t)));
if (!data) {
return NS_ERROR_OUT_OF_MEMORY;
}
memcpy(data, mData.BeginReading(), length * sizeof(uint8_t));
*aDataLen = length;
*aData = data;
return NS_OK;
}
NS_IMETHODIMP
SDBResult::GetAsArrayBuffer(JSContext* aCx, JS::MutableHandleValue _retval)
{
JS::Rooted<JSObject*> arrayBuffer(aCx);
nsresult rv =
nsContentUtils::CreateArrayBuffer(aCx, mData, arrayBuffer.address());
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
_retval.setObject(*arrayBuffer);
return NS_OK;
}
} // namespace dom
} // namespace mozilla

35
dom/simpledb/SDBResults.h Normal file
View File

@ -0,0 +1,35 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_dom_simpledb_SDBResults_h
#define mozilla_dom_simpledb_SDBResults_h
#include "nsISDBResults.h"
#include "nsString.h"
namespace mozilla {
namespace dom {
class SDBResult
: public nsISDBResult
{
nsCString mData;
public:
explicit SDBResult(const nsACString& aData);
private:
virtual ~SDBResult()
{ }
NS_DECL_ISUPPORTS
NS_DECL_NSISDBRESULT
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_simpledb_SDBResults_h

42
dom/simpledb/moz.build Normal file
View File

@ -0,0 +1,42 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
XPIDL_SOURCES += [
'nsISDBCallbacks.idl',
'nsISDBConnection.idl',
'nsISDBRequest.idl',
'nsISDBResults.idl',
]
XPIDL_MODULE = 'dom_simpledb'
EXPORTS.mozilla.dom.simpledb += [
'ActorsParent.h',
]
EXPORTS.mozilla.dom += [
'SDBConnection.h',
]
UNIFIED_SOURCES += [
'ActorsChild.cpp',
'ActorsParent.cpp',
'SDBConnection.cpp',
'SDBRequest.cpp',
'SDBResults.cpp',
]
IPDL_SOURCES += [
'PBackgroundSDBConnection.ipdl',
'PBackgroundSDBRequest.ipdl',
]
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wno-error=shadow']

View File

@ -0,0 +1,22 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
#include "nsISupports.idl"
interface nsISDBConnection;
interface nsISDBRequest;
[scriptable, function, uuid(8cbd576c-c6bf-42fd-96ee-3b824dafe1d4)]
interface nsISDBCallback : nsISupports
{
void onComplete(in nsISDBRequest aRequest);
};
[scriptable, function, uuid(e0821d43-62b9-40fe-99f8-ff9ab3184cbf)]
interface nsISDBCloseCallback : nsISupports
{
void onClose(in nsISDBConnection aConnection);
};

View File

@ -0,0 +1,35 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
#include "nsISupports.idl"
interface nsIPrincipal;
interface nsISDBCloseCallback;
interface nsISDBRequest;
[scriptable, builtinclass, uuid(ea420fdd-548f-44f9-9286-59aad6a40f01)]
interface nsISDBConnection : nsISupports
{
[must_use] void
init(in nsIPrincipal aPrincipal);
[must_use] nsISDBRequest
open(in AString aName);
[must_use] nsISDBRequest
seek(in unsigned long long offset);
[must_use] nsISDBRequest
read(in unsigned long long size);
[must_use, implicit_jscontext] nsISDBRequest
write(in jsval value);
[must_use] nsISDBRequest
close();
attribute nsISDBCloseCallback closeCallback;
};

View File

@ -0,0 +1,20 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
#include "nsISupports.idl"
interface nsISDBCallback;
interface nsIVariant;
[scriptable, uuid(13f05bcf-715c-427e-aac8-df9b2c1ec1e3)]
interface nsISDBRequest : nsISupports
{
[must_use] readonly attribute nsIVariant result;
[must_use] readonly attribute nsresult resultCode;
attribute nsISDBCallback callback;
};

View File

@ -0,0 +1,18 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
#include "nsISupports.idl"
[scriptable, uuid(bca19e01-b34e-4a48-8875-2f4cb871febf)]
interface nsISDBResult : nsISupports
{
[must_use] void
getAsArray([optional] out uint32_t dataLen,
[array, retval, size_is(dataLen)] out uint8_t data);
[must_use, implicit_jscontext] jsval
getAsArrayBuffer();
};

View File

@ -16,6 +16,7 @@
#include "mozilla/Assertions.h"
#include "mozilla/SchedulerGroup.h"
#include "mozilla/dom/ClientManagerActors.h"
#include "mozilla/dom/PBackgroundSDBConnectionChild.h"
#include "mozilla/dom/PFileSystemRequestChild.h"
#include "mozilla/dom/FileSystemTaskBase.h"
#include "mozilla/dom/asmjscache/AsmJSCache.h"
@ -239,6 +240,24 @@ BackgroundChildImpl::DeallocPBackgroundLocalStorageCacheChild(
return true;
}
BackgroundChildImpl::PBackgroundSDBConnectionChild*
BackgroundChildImpl::AllocPBackgroundSDBConnectionChild(
const PrincipalInfo& aPrincipalInfo)
{
MOZ_CRASH("PBackgroundSDBConnectionChild actor should be manually "
"constructed!");
}
bool
BackgroundChildImpl::DeallocPBackgroundSDBConnectionChild(
PBackgroundSDBConnectionChild* aActor)
{
MOZ_ASSERT(aActor);
delete aActor;
return true;
}
BackgroundChildImpl::PBackgroundStorageChild*
BackgroundChildImpl::AllocPBackgroundStorageChild(const nsString& aProfilePath)
{

View File

@ -70,6 +70,14 @@ protected:
DeallocPBackgroundIndexedDBUtilsChild(PBackgroundIndexedDBUtilsChild* aActor)
override;
virtual PBackgroundSDBConnectionChild*
AllocPBackgroundSDBConnectionChild(const PrincipalInfo& aPrincipalInfo)
override;
virtual bool
DeallocPBackgroundSDBConnectionChild(PBackgroundSDBConnectionChild* aActor)
override;
virtual PBackgroundLocalStorageCacheChild*
AllocPBackgroundLocalStorageCacheChild(const PrincipalInfo& aPrincipalInfo,
const nsCString& aOriginKey,

View File

@ -34,6 +34,7 @@
#include "mozilla/dom/ipc/PendingIPCBlobParent.h"
#include "mozilla/dom/ipc/TemporaryIPCBlobParent.h"
#include "mozilla/dom/quota/ActorsParent.h"
#include "mozilla/dom/simpledb/ActorsParent.h"
#include "mozilla/dom/StorageIPC.h"
#include "mozilla/dom/MIDIManagerParent.h"
#include "mozilla/dom/MIDIPortParent.h"
@ -252,6 +253,43 @@ BackgroundParentImpl::RecvFlushPendingFileDeletions()
return IPC_OK();
}
BackgroundParentImpl::PBackgroundSDBConnectionParent*
BackgroundParentImpl::AllocPBackgroundSDBConnectionParent(
const PrincipalInfo& aPrincipalInfo)
{
AssertIsInMainProcess();
AssertIsOnBackgroundThread();
return mozilla::dom::AllocPBackgroundSDBConnectionParent(aPrincipalInfo);
}
mozilla::ipc::IPCResult
BackgroundParentImpl::RecvPBackgroundSDBConnectionConstructor(
PBackgroundSDBConnectionParent* aActor,
const PrincipalInfo& aPrincipalInfo)
{
AssertIsInMainProcess();
AssertIsOnBackgroundThread();
MOZ_ASSERT(aActor);
if (!mozilla::dom::RecvPBackgroundSDBConnectionConstructor(aActor,
aPrincipalInfo)) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
}
bool
BackgroundParentImpl::DeallocPBackgroundSDBConnectionParent(
PBackgroundSDBConnectionParent* aActor)
{
AssertIsInMainProcess();
AssertIsOnBackgroundThread();
MOZ_ASSERT(aActor);
return mozilla::dom::DeallocPBackgroundSDBConnectionParent(aActor);
}
BackgroundParentImpl::PBackgroundLocalStorageCacheParent*
BackgroundParentImpl::AllocPBackgroundLocalStorageCacheParent(
const PrincipalInfo& aPrincipalInfo,

View File

@ -63,6 +63,20 @@ protected:
virtual mozilla::ipc::IPCResult
RecvFlushPendingFileDeletions() override;
virtual PBackgroundSDBConnectionParent*
AllocPBackgroundSDBConnectionParent(const PrincipalInfo& aPrincipalInfo)
override;
virtual mozilla::ipc::IPCResult
RecvPBackgroundSDBConnectionConstructor(
PBackgroundSDBConnectionParent* aActor,
const PrincipalInfo& aPrincipalInfo)
override;
virtual bool
DeallocPBackgroundSDBConnectionParent(PBackgroundSDBConnectionParent* aActor)
override;
virtual PBackgroundLocalStorageCacheParent*
AllocPBackgroundLocalStorageCacheParent(const PrincipalInfo& aPrincipalInfo,
const nsCString& aOriginKey,

View File

@ -5,6 +5,7 @@
include protocol PAsmJSCacheEntry;
include protocol PBackgroundIDBFactory;
include protocol PBackgroundIndexedDBUtils;
include protocol PBackgroundSDBConnection;
include protocol PBackgroundLocalStorageCache;
include protocol PBackgroundStorage;
include protocol PBackgroundTest;
@ -66,6 +67,7 @@ sync protocol PBackground
manages PAsmJSCacheEntry;
manages PBackgroundIDBFactory;
manages PBackgroundIndexedDBUtils;
manages PBackgroundSDBConnection;
manages PBackgroundLocalStorageCache;
manages PBackgroundStorage;
manages PBackgroundTest;
@ -108,6 +110,8 @@ parent:
// Use only for testing!
async FlushPendingFileDeletions();
async PBackgroundSDBConnection(PrincipalInfo principalInfo);
async PBackgroundLocalStorageCache(PrincipalInfo principalInfo,
nsCString originKey,
uint32_t privateBrowsingId);

View File

@ -31,6 +31,10 @@
#define NS_CANVASRENDERINGCONTEXTWEBGL_CID \
{ 0x2fe88332, 0x31c6, 0x4829, { 0xb2, 0x47, 0xa0, 0x7d, 0x8a, 0x7e, 0xe8, 0x0fe } }
// {ae2793c0-2ba3-4adb-9c5e-c23525812c64}
#define NS_SDBCONNECTION_CID \
{ 0xae2793c0, 0x2ba3, 0x4adb, { 0x9c, 0x5e, 0xc2, 0x35, 0x25, 0x81, 0x2c, 0x64 } }
// {A746DECD-AE74-4d86-8E75-4FDA81A9BE90}
#define NS_DOMSESSIONSTORAGEMANAGER_CID \
{ 0xa746decd, 0xae74, 0x4d86, { 0x8e, 0x75, 0x4f, 0xda, 0x81, 0xa9, 0xbe, 0x90 } }

View File

@ -66,6 +66,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/dom/BlobURL.h"
#include "mozilla/dom/DOMRequest.h"
#include "mozilla/dom/SDBConnection.h"
#include "mozilla/dom/LocalStorageManager.h"
#include "mozilla/dom/network/UDPSocketChild.h"
#include "mozilla/dom/quota/QuotaManagerService.h"
@ -197,6 +198,7 @@ already_AddRefed<nsIPresentationService> NS_CreatePresentationService();
// Factory Constructor
typedef mozilla::dom::BlobURL::Mutator BlobURLMutator;
NS_GENERIC_FACTORY_CONSTRUCTOR(BlobURLMutator)
NS_GENERIC_FACTORY_CONSTRUCTOR(SDBConnection)
NS_GENERIC_FACTORY_CONSTRUCTOR(LocalStorageManager)
NS_GENERIC_FACTORY_CONSTRUCTOR(SessionStorageManager)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(DOMRequestService,
@ -534,6 +536,7 @@ NS_DEFINE_NAMED_CID(NS_VIDEODOCUMENT_CID);
NS_DEFINE_NAMED_CID(NS_STYLESHEETSERVICE_CID);
NS_DEFINE_NAMED_CID(NS_HOSTOBJECTURI_CID);
NS_DEFINE_NAMED_CID(NS_HOSTOBJECTURIMUTATOR_CID);
NS_DEFINE_NAMED_CID(NS_SDBCONNECTION_CID);
NS_DEFINE_NAMED_CID(NS_DOMSESSIONSTORAGEMANAGER_CID);
NS_DEFINE_NAMED_CID(NS_DOMLOCALSTORAGEMANAGER_CID);
NS_DEFINE_NAMED_CID(NS_TEXTEDITOR_CID);
@ -771,6 +774,7 @@ static const mozilla::Module::CIDEntry kLayoutCIDs[] = {
{ &kNS_STYLESHEETSERVICE_CID, false, nullptr, nsStyleSheetServiceConstructor },
{ &kNS_HOSTOBJECTURI_CID, false, nullptr, BlobURLMutatorConstructor }, // do_CreateInstance returns mutator
{ &kNS_HOSTOBJECTURIMUTATOR_CID, false, nullptr, BlobURLMutatorConstructor },
{ &kNS_SDBCONNECTION_CID, false, nullptr, SDBConnectionConstructor },
{ &kNS_DOMSESSIONSTORAGEMANAGER_CID, false, nullptr, SessionStorageManagerConstructor },
{ &kNS_DOMLOCALSTORAGEMANAGER_CID, false, nullptr, LocalStorageManagerConstructor },
{ &kNS_TEXTEDITOR_CID, false, nullptr, TextEditorConstructor },
@ -871,6 +875,7 @@ static const mozilla::Module::ContractIDEntry kLayoutContracts[] = {
{ NS_WINDOWCONTROLLER_CONTRACTID, &kNS_WINDOWCONTROLLER_CID },
{ PLUGIN_DLF_CONTRACTID, &kNS_PLUGINDOCLOADERFACTORY_CID },
{ NS_STYLESHEETSERVICE_CONTRACTID, &kNS_STYLESHEETSERVICE_CID },
{ NS_SDBCONNECTION_CONTRACTID, &kNS_SDBCONNECTION_CID },
{ "@mozilla.org/dom/localStorage-manager;1", &kNS_DOMLOCALSTORAGEMANAGER_CID },
// Keeping the old ContractID for backward compatibility
{ "@mozilla.org/dom/storagemanager;1", &kNS_DOMLOCALSTORAGEMANAGER_CID },