Bug 957086 - patch 2 - DataStoreService in C++, r=ehsan, r=bz, r=janv
This commit is contained in:
@@ -806,7 +806,6 @@ bin/components/@DLL_PREFIX@nkgnomevfs@DLL_SUFFIX@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
@BINPATH@/components/DataStore.manifest
|
@BINPATH@/components/DataStore.manifest
|
||||||
@BINPATH@/components/DataStoreService.js
|
|
||||||
@BINPATH@/components/DataStoreImpl.js
|
@BINPATH@/components/DataStoreImpl.js
|
||||||
@BINPATH@/components/dom_datastore.xpt
|
@BINPATH@/components/dom_datastore.xpt
|
||||||
|
|
||||||
|
|||||||
@@ -853,7 +853,6 @@ bin/libfreebl_32int64_3.so
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
@BINPATH@/components/DataStore.manifest
|
@BINPATH@/components/DataStore.manifest
|
||||||
@BINPATH@/components/DataStoreService.js
|
|
||||||
@BINPATH@/components/DataStoreImpl.js
|
@BINPATH@/components/DataStoreImpl.js
|
||||||
@BINPATH@/components/dom_datastore.xpt
|
@BINPATH@/components/dom_datastore.xpt
|
||||||
|
|
||||||
|
|||||||
@@ -82,7 +82,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "nsIDOMGlobalPropertyInitializer.h"
|
#include "nsIDOMGlobalPropertyInitializer.h"
|
||||||
#include "nsIDataStoreService.h"
|
#include "mozilla/dom/DataStoreService.h"
|
||||||
#include "nsJSUtils.h"
|
#include "nsJSUtils.h"
|
||||||
|
|
||||||
#include "nsScriptNameSpaceManager.h"
|
#include "nsScriptNameSpaceManager.h"
|
||||||
@@ -1466,8 +1466,7 @@ Navigator::GetDataStores(nsPIDOMWindow* aWindow,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIDataStoreService> service =
|
nsRefPtr<DataStoreService> service = DataStoreService::GetOrCreate();
|
||||||
do_GetService("@mozilla.org/datastore-service;1");
|
|
||||||
if (!service) {
|
if (!service) {
|
||||||
aRv.Throw(NS_ERROR_FAILURE);
|
aRv.Throw(NS_ERROR_FAILURE);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|||||||
@@ -1,4 +1,2 @@
|
|||||||
component {db5c9602-030f-4bff-a3de-881a8de370f2} DataStoreImpl.js
|
component {db5c9602-030f-4bff-a3de-881a8de370f2} DataStoreImpl.js
|
||||||
contract @mozilla.org/dom/datastore;1 {db5c9602-030f-4bff-a3de-881a8de370f2}
|
contract @mozilla.org/dom/datastore;1 {db5c9602-030f-4bff-a3de-881a8de370f2}
|
||||||
component {d193d0e2-c677-4a7b-bb0a-19155b470f2e} DataStoreService.js
|
|
||||||
contract @mozilla.org/datastore-service;1 {d193d0e2-c677-4a7b-bb0a-19155b470f2e}
|
|
||||||
|
|||||||
48
dom/datastore/DataStoreCallbacks.h
Normal file
48
dom/datastore/DataStoreCallbacks.h
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/* -*- 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_dom_DataStoreCallbacks_h
|
||||||
|
#define mozilla_dom_DataStoreCallbacks_h
|
||||||
|
|
||||||
|
#include "nsISupports.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
class DataStoreDB;
|
||||||
|
|
||||||
|
class DataStoreDBCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_IMETHOD_(MozExternalRefCountType) AddRef(void) = 0;
|
||||||
|
NS_IMETHOD_(MozExternalRefCountType) Release(void) = 0;
|
||||||
|
|
||||||
|
virtual void Run(DataStoreDB* aDb, bool aSuccess) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual ~DataStoreDBCallback()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class DataStoreRevisionCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_IMETHOD_(MozExternalRefCountType) AddRef(void) = 0;
|
||||||
|
NS_IMETHOD_(MozExternalRefCountType) Release(void) = 0;
|
||||||
|
|
||||||
|
virtual void Run(const nsAString& aRevisionID) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual ~DataStoreRevisionCallback()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // dom namespace
|
||||||
|
} // mozilla namespace
|
||||||
|
|
||||||
|
#endif // mozilla_dom_DataStoreCallbacks_h
|
||||||
319
dom/datastore/DataStoreDB.cpp
Normal file
319
dom/datastore/DataStoreDB.cpp
Normal file
@@ -0,0 +1,319 @@
|
|||||||
|
/* -*- 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/. */
|
||||||
|
|
||||||
|
#include "DataStoreDB.h"
|
||||||
|
|
||||||
|
#include "DataStoreCallbacks.h"
|
||||||
|
#include "mozilla/dom/IDBDatabaseBinding.h"
|
||||||
|
#include "mozilla/dom/IDBFactoryBinding.h"
|
||||||
|
#include "mozilla/dom/indexedDB/IDBDatabase.h"
|
||||||
|
#include "mozilla/dom/indexedDB/IDBFactory.h"
|
||||||
|
#include "mozilla/dom/indexedDB/IDBIndex.h"
|
||||||
|
#include "mozilla/dom/indexedDB/IDBObjectStore.h"
|
||||||
|
#include "mozilla/dom/indexedDB/IDBRequest.h"
|
||||||
|
#include "nsIDOMEvent.h"
|
||||||
|
|
||||||
|
#define DATASTOREDB_VERSION 1
|
||||||
|
#define DATASTOREDB_NAME "DataStoreDB"
|
||||||
|
#define DATASTOREDB_REVISION_INDEX "revisionIndex"
|
||||||
|
|
||||||
|
using namespace mozilla::dom::indexedDB;
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS(DataStoreDB, nsIDOMEventListener)
|
||||||
|
|
||||||
|
DataStoreDB::DataStoreDB(const nsAString& aManifestURL, const nsAString& aName)
|
||||||
|
: mState(Inactive)
|
||||||
|
{
|
||||||
|
mDatabaseName.Assign(aName);
|
||||||
|
mDatabaseName.AppendASCII("|");
|
||||||
|
mDatabaseName.Append(aManifestURL);
|
||||||
|
}
|
||||||
|
|
||||||
|
DataStoreDB::~DataStoreDB()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
DataStoreDB::CreateFactoryIfNeeded()
|
||||||
|
{
|
||||||
|
if (!mFactory) {
|
||||||
|
nsresult rv = IDBFactory::Create(nullptr, getter_AddRefs(mFactory));
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
DataStoreDB::Open(IDBTransactionMode aMode, const Sequence<nsString>& aDbs,
|
||||||
|
DataStoreDBCallback* aCallback)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mState == Inactive);
|
||||||
|
|
||||||
|
nsresult rv = CreateFactoryIfNeeded();
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorResult error;
|
||||||
|
mRequest = mFactory->Open(mDatabaseName, DATASTOREDB_VERSION, error);
|
||||||
|
if (NS_WARN_IF(error.Failed())) {
|
||||||
|
return error.ErrorCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = AddEventListeners();
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
mState = Active;
|
||||||
|
mTransactionMode = aMode;
|
||||||
|
mObjectStores = aDbs;
|
||||||
|
mCallback = aCallback;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
DataStoreDB::HandleEvent(nsIDOMEvent* aEvent)
|
||||||
|
{
|
||||||
|
nsString type;
|
||||||
|
nsresult rv = aEvent->GetType(type);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type.EqualsASCII("success")) {
|
||||||
|
RemoveEventListeners();
|
||||||
|
mState = Inactive;
|
||||||
|
|
||||||
|
rv = DatabaseOpened();
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
mCallback->Run(this, false);
|
||||||
|
} else {
|
||||||
|
mCallback->Run(this, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
mRequest = nullptr;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type.EqualsASCII("upgradeneeded")) {
|
||||||
|
return UpgradeSchema();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type.EqualsASCII("error") || type.EqualsASCII("blocked")) {
|
||||||
|
RemoveEventListeners();
|
||||||
|
mState = Inactive;
|
||||||
|
mCallback->Run(this, false);
|
||||||
|
mRequest = nullptr;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSUME_UNREACHABLE("This should not happen");
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
DataStoreDB::UpgradeSchema()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
AutoSafeJSContext cx;
|
||||||
|
|
||||||
|
ErrorResult error;
|
||||||
|
JS::Rooted<JS::Value> result(cx, mRequest->GetResult(error));
|
||||||
|
if (NS_WARN_IF(error.Failed())) {
|
||||||
|
return error.ErrorCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(result.isObject());
|
||||||
|
|
||||||
|
IDBDatabase* database = nullptr;
|
||||||
|
nsresult rv = UNWRAP_OBJECT(IDBDatabase, &result.toObject(), database);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
NS_WARNING("Didn't get the object we expected!");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
IDBObjectStoreParameters params;
|
||||||
|
params.Init(NS_LITERAL_STRING("{ \"autoIncrement\": true }"));
|
||||||
|
nsRefPtr<IDBObjectStore> store =
|
||||||
|
database->CreateObjectStore(cx, NS_LITERAL_STRING(DATASTOREDB_NAME),
|
||||||
|
params, error);
|
||||||
|
if (NS_WARN_IF(error.Failed())) {
|
||||||
|
return error.ErrorCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<IDBObjectStore> store;
|
||||||
|
|
||||||
|
{
|
||||||
|
IDBObjectStoreParameters params;
|
||||||
|
params.Init(NS_LITERAL_STRING("{ \"autoIncrement\": true, \"keyPath\": \"internalRevisionId\" }"));
|
||||||
|
|
||||||
|
store =
|
||||||
|
database->CreateObjectStore(cx, NS_LITERAL_STRING(DATASTOREDB_REVISION),
|
||||||
|
params, error);
|
||||||
|
if (NS_WARN_IF(error.Failed())) {
|
||||||
|
return error.ErrorCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
IDBIndexParameters params;
|
||||||
|
params.Init(NS_LITERAL_STRING("{ \"unique\": true }"));
|
||||||
|
nsRefPtr<IDBIndex> index =
|
||||||
|
store->CreateIndex(cx, NS_LITERAL_STRING(DATASTOREDB_REVISION_INDEX),
|
||||||
|
NS_LITERAL_STRING("revisionId"), params, error);
|
||||||
|
if (NS_WARN_IF(error.Failed())) {
|
||||||
|
return error.ErrorCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
DataStoreDB::DatabaseOpened()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
AutoSafeJSContext cx;
|
||||||
|
|
||||||
|
ErrorResult error;
|
||||||
|
JS::Rooted<JS::Value> result(cx, mRequest->GetResult(error));
|
||||||
|
if (NS_WARN_IF(error.Failed())) {
|
||||||
|
return error.ErrorCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(result.isObject());
|
||||||
|
|
||||||
|
nsresult rv = UNWRAP_OBJECT(IDBDatabase, &result.toObject(), mDatabase);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
NS_WARNING("Didn't get the object we expected!");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<IDBTransaction> txn = mDatabase->Transaction(mObjectStores,
|
||||||
|
mTransactionMode,
|
||||||
|
error);
|
||||||
|
if (NS_WARN_IF(error.Failed())) {
|
||||||
|
return error.ErrorCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
mTransaction = txn.forget();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
DataStoreDB::Delete()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mState == Inactive);
|
||||||
|
|
||||||
|
nsresult rv = CreateFactoryIfNeeded();
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
mTransaction = nullptr;
|
||||||
|
|
||||||
|
if (mDatabase) {
|
||||||
|
rv = mDatabase->Close();
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDatabase = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorResult error;
|
||||||
|
nsRefPtr<IDBOpenDBRequest> request =
|
||||||
|
mFactory->DeleteDatabase(mDatabaseName, IDBOpenDBOptions(), error);
|
||||||
|
if (NS_WARN_IF(error.Failed())) {
|
||||||
|
return error.ErrorCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
indexedDB::IDBTransaction*
|
||||||
|
DataStoreDB::Transaction() const
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mTransaction);
|
||||||
|
MOZ_ASSERT(mTransaction->IsOpen());
|
||||||
|
return mTransaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
DataStoreDB::AddEventListeners()
|
||||||
|
{
|
||||||
|
nsresult rv;
|
||||||
|
rv = mRequest->EventTarget::AddEventListener(NS_LITERAL_STRING("success"),
|
||||||
|
this, false);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = mRequest->EventTarget::AddEventListener(NS_LITERAL_STRING("upgradeneeded"),
|
||||||
|
this, false);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = mRequest->EventTarget::AddEventListener(NS_LITERAL_STRING("error"),
|
||||||
|
this, false);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = mRequest->EventTarget::AddEventListener(NS_LITERAL_STRING("blocked"),
|
||||||
|
this, false);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
DataStoreDB::RemoveEventListeners()
|
||||||
|
{
|
||||||
|
nsresult rv;
|
||||||
|
rv = mRequest->RemoveEventListener(NS_LITERAL_STRING("success"),
|
||||||
|
this, false);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = mRequest->RemoveEventListener(NS_LITERAL_STRING("upgradeneeded"),
|
||||||
|
this, false);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = mRequest->RemoveEventListener(NS_LITERAL_STRING("error"),
|
||||||
|
this, false);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = mRequest->RemoveEventListener(NS_LITERAL_STRING("blocked"),
|
||||||
|
this, false);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
82
dom/datastore/DataStoreDB.h
Normal file
82
dom/datastore/DataStoreDB.h
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
/* -*- 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_dom_DataStoreDB_h
|
||||||
|
#define mozilla_dom_DataStoreDB_h
|
||||||
|
|
||||||
|
#include "mozilla/dom/IDBTransactionBinding.h"
|
||||||
|
#include "nsAutoPtr.h"
|
||||||
|
#include "nsIDOMEventListener.h"
|
||||||
|
#include "nsISupportsImpl.h"
|
||||||
|
#include "nsString.h"
|
||||||
|
|
||||||
|
#define DATASTOREDB_REVISION "revision"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
namespace indexedDB {
|
||||||
|
class IDBDatabase;
|
||||||
|
class IDBFactory;
|
||||||
|
class IDBObjectStore;
|
||||||
|
class IDBOpenDBRequest;
|
||||||
|
class IDBTransaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
class DataStoreDBCallback;
|
||||||
|
|
||||||
|
class DataStoreDB MOZ_FINAL : public nsIDOMEventListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
|
DataStoreDB(const nsAString& aManifestURL, const nsAString& aName);
|
||||||
|
~DataStoreDB();
|
||||||
|
|
||||||
|
nsresult Open(IDBTransactionMode aMode, const Sequence<nsString>& aDb,
|
||||||
|
DataStoreDBCallback* aCallback);
|
||||||
|
|
||||||
|
nsresult Delete();
|
||||||
|
|
||||||
|
indexedDB::IDBTransaction* Transaction() const;
|
||||||
|
|
||||||
|
// nsIDOMEventListener
|
||||||
|
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
|
||||||
|
|
||||||
|
private:
|
||||||
|
nsresult CreateFactoryIfNeeded();
|
||||||
|
|
||||||
|
nsresult UpgradeSchema();
|
||||||
|
|
||||||
|
nsresult DatabaseOpened();
|
||||||
|
|
||||||
|
nsresult AddEventListeners();
|
||||||
|
|
||||||
|
nsresult RemoveEventListeners();
|
||||||
|
|
||||||
|
nsString mDatabaseName;
|
||||||
|
|
||||||
|
nsRefPtr<indexedDB::IDBFactory> mFactory;
|
||||||
|
nsRefPtr<indexedDB::IDBOpenDBRequest> mRequest;
|
||||||
|
nsRefPtr<indexedDB::IDBDatabase> mDatabase;
|
||||||
|
nsRefPtr<indexedDB::IDBTransaction> mTransaction;
|
||||||
|
|
||||||
|
nsRefPtr<DataStoreDBCallback> mCallback;
|
||||||
|
|
||||||
|
// Internal state to avoid strange use of this class.
|
||||||
|
enum StateType {
|
||||||
|
Inactive,
|
||||||
|
Active
|
||||||
|
} mState;
|
||||||
|
|
||||||
|
IDBTransactionMode mTransactionMode;
|
||||||
|
Sequence<nsString> mObjectStores;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif // mozilla_dom_DataStoreDB_h
|
||||||
@@ -59,7 +59,6 @@ function validateId(aId) {
|
|||||||
/* DataStore object */
|
/* DataStore object */
|
||||||
function DataStore() {
|
function DataStore() {
|
||||||
debug("DataStore created");
|
debug("DataStore created");
|
||||||
this.wrappedJSObject = this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DataStore.prototype = {
|
DataStore.prototype = {
|
||||||
|
|||||||
102
dom/datastore/DataStoreRevision.cpp
Normal file
102
dom/datastore/DataStoreRevision.cpp
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
/* -*- 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/. */
|
||||||
|
|
||||||
|
#include "DataStoreRevision.h"
|
||||||
|
|
||||||
|
#include "DataStoreCallbacks.h"
|
||||||
|
#include "DataStoreService.h"
|
||||||
|
#include "mozilla/dom/DataStoreBinding.h"
|
||||||
|
#include "mozilla/dom/indexedDB/IDBObjectStore.h"
|
||||||
|
#include "nsIDOMEvent.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
using namespace indexedDB;
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS(DataStoreRevision, nsIDOMEventListener)
|
||||||
|
|
||||||
|
// Note: this code in it must not assume anything about the compartment cx is
|
||||||
|
// in.
|
||||||
|
nsresult
|
||||||
|
DataStoreRevision::AddRevision(JSContext* aCx,
|
||||||
|
IDBObjectStore* aStore,
|
||||||
|
uint32_t aObjectId,
|
||||||
|
RevisionType aRevisionType,
|
||||||
|
DataStoreRevisionCallback* aCallback)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aStore);
|
||||||
|
MOZ_ASSERT(aCallback);
|
||||||
|
|
||||||
|
nsRefPtr<DataStoreService> service = DataStoreService::Get();
|
||||||
|
if (!service) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsString id;
|
||||||
|
nsresult rv = service->GenerateUUID(mRevisionID);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataStoreRevisionData data;
|
||||||
|
data.mRevisionId = mRevisionID;
|
||||||
|
data.mObjectId = aObjectId;
|
||||||
|
|
||||||
|
switch (aRevisionType) {
|
||||||
|
case RevisionVoid:
|
||||||
|
data.mOperation = NS_LITERAL_STRING("void");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
MOZ_ASSUME_UNREACHABLE("This should not happen");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
JS::Rooted<JS::Value> value(aCx);
|
||||||
|
if (!data.ToObject(aCx, &value)) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorResult error;
|
||||||
|
mRequest = aStore->Put(aCx, value, JS::UndefinedHandleValue, error);
|
||||||
|
if (NS_WARN_IF(error.Failed())) {
|
||||||
|
return error.ErrorCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = mRequest->EventTarget::AddEventListener(NS_LITERAL_STRING("success"),
|
||||||
|
this, false);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
mCallback = aCallback;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
DataStoreRevision::HandleEvent(nsIDOMEvent* aEvent)
|
||||||
|
{
|
||||||
|
nsString type;
|
||||||
|
nsresult rv = aEvent->GetType(type);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!type.EqualsASCII("success")) {
|
||||||
|
MOZ_ASSUME_UNREACHABLE("This should not happen");
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
mRequest->RemoveEventListener(NS_LITERAL_STRING("success"), this, false);
|
||||||
|
mRequest = nullptr;
|
||||||
|
|
||||||
|
mCallback->Run(mRevisionID);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // dom namespace
|
||||||
|
} // mozilla namespace
|
||||||
52
dom/datastore/DataStoreRevision.h
Normal file
52
dom/datastore/DataStoreRevision.h
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/* -*- 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_dom_DataStoreRevision_h
|
||||||
|
#define mozilla_dom_DataStoreRevision_h
|
||||||
|
|
||||||
|
#include "nsIDOMEventListener.h"
|
||||||
|
#include "nsAutoPtr.h"
|
||||||
|
#include "nsString.h"
|
||||||
|
#include "jsapi.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
namespace indexedDB {
|
||||||
|
class IDBObjectStore;
|
||||||
|
class IDBRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
class DataStoreRevisionCallback;
|
||||||
|
|
||||||
|
class DataStoreRevision MOZ_FINAL : public nsIDOMEventListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
|
enum RevisionType {
|
||||||
|
RevisionVoid
|
||||||
|
};
|
||||||
|
|
||||||
|
nsresult AddRevision(JSContext* aCx,
|
||||||
|
indexedDB::IDBObjectStore* aStore,
|
||||||
|
uint32_t aObjectId,
|
||||||
|
RevisionType aRevisionType,
|
||||||
|
DataStoreRevisionCallback* aCallback);
|
||||||
|
|
||||||
|
// nsIDOMEventListener
|
||||||
|
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
|
||||||
|
|
||||||
|
private:
|
||||||
|
nsRefPtr<DataStoreRevisionCallback> mCallback;
|
||||||
|
nsRefPtr<indexedDB::IDBRequest> mRequest;
|
||||||
|
nsString mRevisionID;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif // mozilla_dom_DataStoreRevision_h
|
||||||
1277
dom/datastore/DataStoreService.cpp
Normal file
1277
dom/datastore/DataStoreService.cpp
Normal file
File diff suppressed because it is too large
Load Diff
103
dom/datastore/DataStoreService.h
Normal file
103
dom/datastore/DataStoreService.h
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
/* -*- 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_dom_DataStoreService_h
|
||||||
|
#define mozilla_dom_DataStoreService_h
|
||||||
|
|
||||||
|
#include "nsClassHashtable.h"
|
||||||
|
#include "nsIDataStoreService.h"
|
||||||
|
#include "nsIObserver.h"
|
||||||
|
#include "nsRefPtrHashtable.h"
|
||||||
|
|
||||||
|
class nsIUUIDGenerator;
|
||||||
|
class nsPIDOMWindow;
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
class DataStoreInfo;
|
||||||
|
class FirstRevisionIdCallback;
|
||||||
|
class PendingRequest;
|
||||||
|
class Promise;
|
||||||
|
class RetrieveRevisionsCounter;
|
||||||
|
class RevisionAddedEnableStoreCallback;
|
||||||
|
|
||||||
|
class DataStoreService MOZ_FINAL : public nsIDataStoreService
|
||||||
|
, public nsIObserver
|
||||||
|
{
|
||||||
|
friend class FirstRevisionIdCallback;
|
||||||
|
friend class RetrieveRevisionsCounter;
|
||||||
|
friend class RevisionAddedEnableStoreCallback;
|
||||||
|
|
||||||
|
public:
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
NS_DECL_NSIOBSERVER
|
||||||
|
NS_DECL_NSIDATASTORESERVICE
|
||||||
|
|
||||||
|
// Returns the DataStoreService singleton. Only to be called from main
|
||||||
|
// thread.
|
||||||
|
static already_AddRefed<DataStoreService> GetOrCreate();
|
||||||
|
|
||||||
|
static already_AddRefed<DataStoreService> Get();
|
||||||
|
|
||||||
|
static void Shutdown();
|
||||||
|
|
||||||
|
nsresult GenerateUUID(nsAString& aID);
|
||||||
|
|
||||||
|
private:
|
||||||
|
DataStoreService();
|
||||||
|
~DataStoreService();
|
||||||
|
|
||||||
|
nsresult Init();
|
||||||
|
|
||||||
|
typedef nsClassHashtable<nsUint32HashKey, DataStoreInfo> HashApp;
|
||||||
|
|
||||||
|
nsresult AddPermissions(uint32_t aAppId, const nsAString& aName,
|
||||||
|
const nsAString& aOriginURL,
|
||||||
|
const nsAString& aManifestURL,
|
||||||
|
bool aReadOnly);
|
||||||
|
|
||||||
|
nsresult AddAccessPermissions(uint32_t aAppId, const nsAString& aName,
|
||||||
|
const nsAString& aOriginURL,
|
||||||
|
const nsAString& aManifestURL,
|
||||||
|
bool aReadOnly);
|
||||||
|
|
||||||
|
nsresult CreateFirstRevisionId(uint32_t aAppId, const nsAString& aName,
|
||||||
|
const nsAString& aManifestURL);
|
||||||
|
|
||||||
|
void GetDataStoresCreate(nsPIDOMWindow* aWindow, Promise* aPromise,
|
||||||
|
const nsTArray<DataStoreInfo>& aStores);
|
||||||
|
|
||||||
|
void GetDataStoresResolve(nsPIDOMWindow* aWindow, Promise* aPromise,
|
||||||
|
const nsTArray<DataStoreInfo>& aStores);
|
||||||
|
|
||||||
|
nsresult GetDataStoreInfos(const nsAString& aName, uint32_t aAppId,
|
||||||
|
nsTArray<DataStoreInfo>& aStores);
|
||||||
|
|
||||||
|
void DeleteDataStores(uint32_t aAppId);
|
||||||
|
|
||||||
|
nsresult EnableDataStore(uint32_t aAppId, const nsAString& aName,
|
||||||
|
const nsAString& aManifestURL);
|
||||||
|
|
||||||
|
already_AddRefed<RetrieveRevisionsCounter> GetCounter(uint32_t aId) const;
|
||||||
|
|
||||||
|
void RemoveCounter(uint32_t aId);
|
||||||
|
|
||||||
|
nsClassHashtable<nsStringHashKey, HashApp> mStores;
|
||||||
|
nsClassHashtable<nsStringHashKey, HashApp> mAccessStores;
|
||||||
|
|
||||||
|
typedef nsTArray<PendingRequest> PendingRequests;
|
||||||
|
nsClassHashtable<nsStringHashKey, PendingRequests> mPendingRequests;
|
||||||
|
|
||||||
|
nsRefPtrHashtable<nsUint32HashKey, RetrieveRevisionsCounter> mPendingCounters;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIUUIDGenerator> mUUIDGenerator;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif // mozilla_dom_DataStoreService_h
|
||||||
@@ -1,527 +0,0 @@
|
|||||||
/* -*- Mode: js2; js2-basic-offset: 2; indent-tabs-mode: nil; -*- */
|
|
||||||
/* vim: set ft=javascript 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/. */
|
|
||||||
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
/* static functions */
|
|
||||||
|
|
||||||
function debug(s) {
|
|
||||||
//dump('DEBUG DataStoreService: ' + s + '\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
|
||||||
|
|
||||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
|
||||||
Cu.import('resource://gre/modules/Services.jsm');
|
|
||||||
Cu.import("resource://gre/modules/DataStoreDB.jsm");
|
|
||||||
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
|
|
||||||
|
|
||||||
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
|
|
||||||
"@mozilla.org/childprocessmessagemanager;1",
|
|
||||||
"nsIMessageSender");
|
|
||||||
|
|
||||||
XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
|
|
||||||
"@mozilla.org/parentprocessmessagemanager;1",
|
|
||||||
"nsIMessageBroadcaster");
|
|
||||||
|
|
||||||
XPCOMUtils.defineLazyServiceGetter(this, "permissionManager",
|
|
||||||
"@mozilla.org/permissionmanager;1",
|
|
||||||
"nsIPermissionManager");
|
|
||||||
|
|
||||||
XPCOMUtils.defineLazyServiceGetter(this, "secMan",
|
|
||||||
"@mozilla.org/scriptsecuritymanager;1",
|
|
||||||
"nsIScriptSecurityManager");
|
|
||||||
|
|
||||||
/* DataStoreService */
|
|
||||||
|
|
||||||
const DATASTORESERVICE_CID = Components.ID('{d193d0e2-c677-4a7b-bb0a-19155b470f2e}');
|
|
||||||
const REVISION_VOID = "void";
|
|
||||||
|
|
||||||
function DataStoreService() {
|
|
||||||
debug('DataStoreService Constructor');
|
|
||||||
|
|
||||||
this.inParent = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime)
|
|
||||||
.processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
|
|
||||||
|
|
||||||
if (this.inParent) {
|
|
||||||
let obs = Services.obs;
|
|
||||||
if (!obs) {
|
|
||||||
debug("DataStore Error: observer-service is null!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
obs.addObserver(this, 'webapps-clear-data', false);
|
|
||||||
}
|
|
||||||
|
|
||||||
let self = this;
|
|
||||||
cpmm.addMessageListener("datastore-first-revision-created",
|
|
||||||
function(aMsg) { self.receiveMessage(aMsg); });
|
|
||||||
}
|
|
||||||
|
|
||||||
DataStoreService.prototype = {
|
|
||||||
inParent: false,
|
|
||||||
|
|
||||||
// Hash of DataStores
|
|
||||||
stores: {},
|
|
||||||
accessStores: {},
|
|
||||||
pendingRequests: {},
|
|
||||||
|
|
||||||
installDataStore: function(aAppId, aName, aOrigin, aOwner, aReadOnly) {
|
|
||||||
debug('installDataStore - appId: ' + aAppId + ', aName: ' +
|
|
||||||
aName + ', aOrigin: ' + aOrigin + ', aOwner:' + aOwner +
|
|
||||||
', aReadOnly: ' + aReadOnly);
|
|
||||||
|
|
||||||
this.checkIfInParent();
|
|
||||||
|
|
||||||
if (aName in this.stores && aAppId in this.stores[aName]) {
|
|
||||||
debug('This should not happen');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(aName in this.stores)) {
|
|
||||||
this.stores[aName] = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
// A DataStore is enabled when it has a first valid revision.
|
|
||||||
this.stores[aName][aAppId] = { origin: aOrigin, owner: aOwner,
|
|
||||||
readOnly: aReadOnly, enabled: false };
|
|
||||||
|
|
||||||
this.addPermissions(aAppId, aName, aOrigin, aOwner, aReadOnly);
|
|
||||||
|
|
||||||
this.createFirstRevisionId(aAppId, aName, aOwner);
|
|
||||||
},
|
|
||||||
|
|
||||||
installAccessDataStore: function(aAppId, aName, aOrigin, aOwner, aReadOnly) {
|
|
||||||
debug('installAccessDataStore - appId: ' + aAppId + ', aName: ' +
|
|
||||||
aName + ', aOrigin: ' + aOrigin + ', aOwner:' + aOwner +
|
|
||||||
', aReadOnly: ' + aReadOnly);
|
|
||||||
|
|
||||||
this.checkIfInParent();
|
|
||||||
|
|
||||||
if (aName in this.accessStores && aAppId in this.accessStores[aName]) {
|
|
||||||
debug('This should not happen');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(aName in this.accessStores)) {
|
|
||||||
this.accessStores[aName] = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
this.accessStores[aName][aAppId] = { origin: aOrigin, owner: aOwner,
|
|
||||||
readOnly: aReadOnly };
|
|
||||||
this.addAccessPermissions(aAppId, aName, aOrigin, aOwner, aReadOnly);
|
|
||||||
},
|
|
||||||
|
|
||||||
checkIfInParent: function() {
|
|
||||||
if (!this.inParent) {
|
|
||||||
throw "DataStore can execute this operation just in the parent process";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
createFirstRevisionId: function(aAppId, aName, aOwner) {
|
|
||||||
debug("createFirstRevisionId database: " + aName);
|
|
||||||
|
|
||||||
let self = this;
|
|
||||||
let db = new DataStoreDB();
|
|
||||||
db.init(aOwner, aName);
|
|
||||||
db.revisionTxn(
|
|
||||||
'readwrite',
|
|
||||||
function(aTxn, aRevisionStore) {
|
|
||||||
debug("createFirstRevisionId - transaction success");
|
|
||||||
|
|
||||||
let request = aRevisionStore.openCursor(null, 'prev');
|
|
||||||
request.onsuccess = function(aEvent) {
|
|
||||||
let cursor = aEvent.target.result;
|
|
||||||
if (cursor) {
|
|
||||||
debug("First revision already created.");
|
|
||||||
self.enableDataStore(aAppId, aName, aOwner);
|
|
||||||
} else {
|
|
||||||
// If the revision doesn't exist, let's create the first one.
|
|
||||||
db.addRevision(aRevisionStore, 0, REVISION_VOID, function() {
|
|
||||||
debug("First revision created.");
|
|
||||||
self.enableDataStore(aAppId, aName, aOwner);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
enableDataStore: function(aAppId, aName, aOwner) {
|
|
||||||
if (aName in this.stores && aAppId in this.stores[aName]) {
|
|
||||||
this.stores[aName][aAppId].enabled = true;
|
|
||||||
ppmm.broadcastAsyncMessage('datastore-first-revision-created',
|
|
||||||
{ name: aName, owner: aOwner });
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
addPermissions: function(aAppId, aName, aOrigin, aOwner, aReadOnly) {
|
|
||||||
// When a new DataStore is installed, the permissions must be set for the
|
|
||||||
// owner app.
|
|
||||||
let permission = "indexedDB-chrome-" + aName + '|' + aOwner;
|
|
||||||
this.resetPermissions(aAppId, aOrigin, aOwner, permission, aReadOnly);
|
|
||||||
|
|
||||||
// For any app that wants to have access to this DataStore we add the
|
|
||||||
// permissions.
|
|
||||||
if (aName in this.accessStores) {
|
|
||||||
for (let appId in this.accessStores[aName]) {
|
|
||||||
// ReadOnly is decided by the owner first.
|
|
||||||
let readOnly = aReadOnly || this.accessStores[aName][appId].readOnly;
|
|
||||||
this.resetPermissions(appId, this.accessStores[aName][appId].origin,
|
|
||||||
this.accessStores[aName][appId].owner,
|
|
||||||
permission, readOnly);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
addAccessPermissions: function(aAppId, aName, aOrigin, aOwner, aReadOnly) {
|
|
||||||
// When an app wants to have access to a DataStore, the permissions must be
|
|
||||||
// set.
|
|
||||||
if (!(aName in this.stores)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let appId in this.stores[aName]) {
|
|
||||||
let permission = "indexedDB-chrome-" + aName + '|' + this.stores[aName][appId].owner;
|
|
||||||
// The ReadOnly is decied by the owenr first.
|
|
||||||
let readOnly = this.stores[aName][appId].readOnly || aReadOnly;
|
|
||||||
this.resetPermissions(aAppId, aOrigin, aOwner, permission, readOnly);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
resetPermissions: function(aAppId, aOrigin, aOwner, aPermission, aReadOnly) {
|
|
||||||
debug("ResetPermissions - appId: " + aAppId + " - origin: " + aOrigin +
|
|
||||||
" - owner: " + aOwner + " - permissions: " + aPermission +
|
|
||||||
" - readOnly: " + aReadOnly);
|
|
||||||
|
|
||||||
let uri = Services.io.newURI(aOrigin, null, null);
|
|
||||||
let principal = secMan.getAppCodebasePrincipal(uri, aAppId, false);
|
|
||||||
|
|
||||||
let result = permissionManager.testExactPermissionFromPrincipal(principal,
|
|
||||||
aPermission + '-write');
|
|
||||||
|
|
||||||
if (aReadOnly && result == Ci.nsIPermissionManager.ALLOW_ACTION) {
|
|
||||||
debug("Write permission removed");
|
|
||||||
permissionManager.removeFromPrincipal(principal, aPermission + '-write');
|
|
||||||
} else if (!aReadOnly && result != Ci.nsIPermissionManager.ALLOW_ACTION) {
|
|
||||||
debug("Write permission added");
|
|
||||||
permissionManager.addFromPrincipal(principal, aPermission + '-write',
|
|
||||||
Ci.nsIPermissionManager.ALLOW_ACTION);
|
|
||||||
}
|
|
||||||
|
|
||||||
result = permissionManager.testExactPermissionFromPrincipal(principal,
|
|
||||||
aPermission + '-read');
|
|
||||||
if (result != Ci.nsIPermissionManager.ALLOW_ACTION) {
|
|
||||||
debug("Read permission added");
|
|
||||||
permissionManager.addFromPrincipal(principal, aPermission + '-read',
|
|
||||||
Ci.nsIPermissionManager.ALLOW_ACTION);
|
|
||||||
}
|
|
||||||
|
|
||||||
result = permissionManager.testExactPermissionFromPrincipal(principal, aPermission);
|
|
||||||
if (result != Ci.nsIPermissionManager.ALLOW_ACTION) {
|
|
||||||
debug("Generic permission added");
|
|
||||||
permissionManager.addFromPrincipal(principal, aPermission,
|
|
||||||
Ci.nsIPermissionManager.ALLOW_ACTION);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
getDataStores: function(aWindow, aName) {
|
|
||||||
debug('getDataStores - aName: ' + aName);
|
|
||||||
|
|
||||||
let self = this;
|
|
||||||
return new aWindow.Promise(function(resolve, reject) {
|
|
||||||
// If this request comes from the main process, we have access to the
|
|
||||||
// window, so we can skip the ipc communication.
|
|
||||||
if (self.inParent) {
|
|
||||||
let stores = self.getDataStoresInfo(aName, aWindow.document.nodePrincipal.appId);
|
|
||||||
if (stores === null) {
|
|
||||||
reject(new aWindow.DOMError("SecurityError", "Access denied"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
self.getDataStoreCreate(aWindow, resolve, stores);
|
|
||||||
} else {
|
|
||||||
// This method can be called in the child so we need to send a request
|
|
||||||
// to the parent and create DataStore object here.
|
|
||||||
new DataStoreServiceChild(aWindow, aName, function(aStores) {
|
|
||||||
debug("DataStoreServiceChild success callback!");
|
|
||||||
self.getDataStoreCreate(aWindow, resolve, aStores);
|
|
||||||
}, function() {
|
|
||||||
debug("DataStoreServiceChild error callback!");
|
|
||||||
reject(new aWindow.DOMError("SecurityError", "Access denied"));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
getDataStoresInfo: function(aName, aAppId) {
|
|
||||||
debug('GetDataStoresInfo');
|
|
||||||
|
|
||||||
let appsService = Cc["@mozilla.org/AppsService;1"]
|
|
||||||
.getService(Ci.nsIAppsService);
|
|
||||||
let app = appsService.getAppByLocalId(aAppId);
|
|
||||||
if (!app) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let prefName = "dom.testing.datastore_enabled_for_hosted_apps";
|
|
||||||
if (app.appStatus != Ci.nsIPrincipal.APP_STATUS_CERTIFIED &&
|
|
||||||
(Services.prefs.getPrefType(prefName) == Services.prefs.PREF_INVALID ||
|
|
||||||
!Services.prefs.getBoolPref(prefName))) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let results = [];
|
|
||||||
|
|
||||||
if (aName in this.stores) {
|
|
||||||
if (aAppId in this.stores[aName]) {
|
|
||||||
results.push({ name: aName,
|
|
||||||
owner: this.stores[aName][aAppId].owner,
|
|
||||||
readOnly: false,
|
|
||||||
enabled: this.stores[aName][aAppId].enabled });
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i in this.stores[aName]) {
|
|
||||||
if (i == aAppId) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let access = this.getDataStoreAccess(aName, aAppId);
|
|
||||||
if (!access) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let readOnly = this.stores[aName][i].readOnly || access.readOnly;
|
|
||||||
results.push({ name: aName,
|
|
||||||
owner: this.stores[aName][i].owner,
|
|
||||||
readOnly: readOnly,
|
|
||||||
enabled: this.stores[aName][i].enabled });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return results;
|
|
||||||
},
|
|
||||||
|
|
||||||
getDataStoreCreate: function(aWindow, aResolve, aStores) {
|
|
||||||
debug("GetDataStoreCreate");
|
|
||||||
|
|
||||||
let results = new aWindow.Array();
|
|
||||||
|
|
||||||
if (!aStores.length) {
|
|
||||||
aResolve(results);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let pendingDataStores = [];
|
|
||||||
|
|
||||||
for (let i = 0; i < aStores.length; ++i) {
|
|
||||||
if (!aStores[i].enabled) {
|
|
||||||
pendingDataStores.push(aStores[i].owner);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pendingDataStores.length) {
|
|
||||||
this.getDataStoreResolve(aWindow, aResolve, aStores);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(aStores[0].name in this.pendingRequests)) {
|
|
||||||
this.pendingRequests[aStores[0].name] = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
this.pendingRequests[aStores[0].name].push({ window: aWindow,
|
|
||||||
resolve: aResolve,
|
|
||||||
stores: aStores,
|
|
||||||
pendingDataStores: pendingDataStores });
|
|
||||||
},
|
|
||||||
|
|
||||||
getDataStoreResolve: function(aWindow, aResolve, aStores) {
|
|
||||||
debug("GetDataStoreResolve");
|
|
||||||
|
|
||||||
let callbackPending = aStores.length;
|
|
||||||
let results = new aWindow.Array();
|
|
||||||
|
|
||||||
if (!callbackPending) {
|
|
||||||
aResolve(results);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < aStores.length; ++i) {
|
|
||||||
let obj = Cc["@mozilla.org/dom/datastore;1"]
|
|
||||||
.createInstance(Ci.nsIDataStore);
|
|
||||||
if (!obj || !obj.wrappedJSObject) {
|
|
||||||
dump("Failed to create a DataStore object.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
obj.init(aWindow, aStores[i].name, aStores[i].owner, aStores[i].readOnly);
|
|
||||||
|
|
||||||
let storeImpl = aWindow.DataStoreImpl._create(aWindow, obj.wrappedJSObject);
|
|
||||||
|
|
||||||
let exposedStore = new aWindow.DataStore();
|
|
||||||
exposedStore.setDataStoreImpl(storeImpl);
|
|
||||||
|
|
||||||
obj.exposedObject = exposedStore;
|
|
||||||
|
|
||||||
results.push(exposedStore);
|
|
||||||
|
|
||||||
obj.retrieveRevisionId(
|
|
||||||
function() {
|
|
||||||
--callbackPending;
|
|
||||||
if (!callbackPending) {
|
|
||||||
aResolve(results);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
getDataStoreAccess: function(aName, aAppId) {
|
|
||||||
if (!(aName in this.accessStores) ||
|
|
||||||
!(aAppId in this.accessStores[aName])) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.accessStores[aName][aAppId];
|
|
||||||
},
|
|
||||||
|
|
||||||
observe: function observe(aSubject, aTopic, aData) {
|
|
||||||
debug('observe - aTopic: ' + aTopic);
|
|
||||||
if (aTopic != 'webapps-clear-data') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let params =
|
|
||||||
aSubject.QueryInterface(Ci.mozIApplicationClearPrivateDataParams);
|
|
||||||
|
|
||||||
// DataStore is explosed to apps, not browser content.
|
|
||||||
if (params.browserOnly) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
function isEmpty(aMap) {
|
|
||||||
for (var key in aMap) {
|
|
||||||
if (aMap.hasOwnProperty(key)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let key in this.stores) {
|
|
||||||
if (params.appId in this.stores[key]) {
|
|
||||||
this.deleteDatabase(key, this.stores[key][params.appId].owner);
|
|
||||||
delete this.stores[key][params.appId];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isEmpty(this.stores[key])) {
|
|
||||||
delete this.stores[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let key in this.accessStores) {
|
|
||||||
if (params.appId in this.accessStores[key]) {
|
|
||||||
delete this.accessStores[key][params.appId];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isEmpty(this.accessStores[key])) {
|
|
||||||
delete this.accessStores[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
deleteDatabase: function(aName, aOwner) {
|
|
||||||
debug("delete database: " + aName);
|
|
||||||
|
|
||||||
let db = new DataStoreDB();
|
|
||||||
db.init(aOwner, aName);
|
|
||||||
db.delete();
|
|
||||||
},
|
|
||||||
|
|
||||||
receiveMessage: function(aMsg) {
|
|
||||||
debug("receiveMessage");
|
|
||||||
let data = aMsg.json;
|
|
||||||
|
|
||||||
if (!(data.name in this.pendingRequests)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < this.pendingRequests[data.name].length;) {
|
|
||||||
let pos = this.pendingRequests[data.name][i].pendingDataStores.indexOf(data.owner);
|
|
||||||
if (pos != -1) {
|
|
||||||
this.pendingRequests[data.name][i].pendingDataStores.splice(pos, 1);
|
|
||||||
if (!this.pendingRequests[data.name][i].pendingDataStores.length) {
|
|
||||||
this.getDataStoreResolve(this.pendingRequests[data.name][i].window,
|
|
||||||
this.pendingRequests[data.name][i].resolve,
|
|
||||||
this.pendingRequests[data.name][i].stores);
|
|
||||||
this.pendingRequests[data.name].splice(i, 1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.pendingRequests[data.name].length) {
|
|
||||||
delete this.pendingRequests[data.name];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
classID : DATASTORESERVICE_CID,
|
|
||||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDataStoreService,
|
|
||||||
Ci.nsIObserver]),
|
|
||||||
classInfo: XPCOMUtils.generateCI({
|
|
||||||
classID: DATASTORESERVICE_CID,
|
|
||||||
contractID: '@mozilla.org/datastore-service;1',
|
|
||||||
interfaces: [Ci.nsIDataStoreService, Ci.nsIObserver],
|
|
||||||
flags: Ci.nsIClassInfo.SINGLETON
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
/* DataStoreServiceChild */
|
|
||||||
|
|
||||||
function DataStoreServiceChild(aWindow, aName, aSuccessCb, aErrorCb) {
|
|
||||||
debug("DataStoreServiceChild created");
|
|
||||||
this.init(aWindow, aName, aSuccessCb, aErrorCb);
|
|
||||||
}
|
|
||||||
|
|
||||||
DataStoreServiceChild.prototype = {
|
|
||||||
__proto__: DOMRequestIpcHelper.prototype,
|
|
||||||
|
|
||||||
init: function(aWindow, aName, aSuccessCb, aErrorCb) {
|
|
||||||
debug("DataStoreServiceChild init");
|
|
||||||
this._successCb = aSuccessCb;
|
|
||||||
this._errorCb = aErrorCb;
|
|
||||||
this._name = aName;
|
|
||||||
|
|
||||||
this.initDOMRequestHelper(aWindow, [ "DataStore:Get:Return:OK",
|
|
||||||
"DataStore:Get:Return:KO" ]);
|
|
||||||
|
|
||||||
cpmm.sendAsyncMessage("DataStore:Get",
|
|
||||||
{ name: aName }, null, aWindow.document.nodePrincipal );
|
|
||||||
},
|
|
||||||
|
|
||||||
receiveMessage: function(aMessage) {
|
|
||||||
debug("DataStoreServiceChild receiveMessage");
|
|
||||||
|
|
||||||
if (aMessage.data.name != this._name) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (aMessage.name) {
|
|
||||||
case 'DataStore:Get:Return:OK':
|
|
||||||
this.destroyDOMRequestHelper();
|
|
||||||
this._successCb(aMessage.data.stores);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'DataStore:Get:Return:KO':
|
|
||||||
this.destroyDOMRequestHelper();
|
|
||||||
this._errorCb();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([DataStoreService]);
|
|
||||||
@@ -14,11 +14,15 @@ XPIDL_MODULE = 'dom_datastore'
|
|||||||
EXPORTS.mozilla.dom += [
|
EXPORTS.mozilla.dom += [
|
||||||
'DataStore.h',
|
'DataStore.h',
|
||||||
'DataStoreCursor.h',
|
'DataStoreCursor.h',
|
||||||
|
'DataStoreService.h',
|
||||||
]
|
]
|
||||||
|
|
||||||
SOURCES += [
|
SOURCES += [
|
||||||
'DataStore.cpp',
|
'DataStore.cpp',
|
||||||
'DataStoreCursor.cpp',
|
'DataStoreCursor.cpp',
|
||||||
|
'DataStoreDB.cpp',
|
||||||
|
'DataStoreRevision.cpp',
|
||||||
|
'DataStoreService.cpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
LOCAL_INCLUDES += [
|
LOCAL_INCLUDES += [
|
||||||
@@ -28,7 +32,6 @@ LOCAL_INCLUDES += [
|
|||||||
EXTRA_COMPONENTS += [
|
EXTRA_COMPONENTS += [
|
||||||
'DataStore.manifest',
|
'DataStore.manifest',
|
||||||
'DataStoreImpl.js',
|
'DataStoreImpl.js',
|
||||||
'DataStoreService.js',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
EXTRA_JS_MODULES += [
|
EXTRA_JS_MODULES += [
|
||||||
@@ -40,4 +43,7 @@ EXTRA_JS_MODULES += [
|
|||||||
|
|
||||||
MOCHITEST_MANIFESTS += ['tests/mochitest.ini']
|
MOCHITEST_MANIFESTS += ['tests/mochitest.ini']
|
||||||
|
|
||||||
|
include('/ipc/chromium/chromium-config.mozbuild')
|
||||||
|
|
||||||
FINAL_LIBRARY = 'xul'
|
FINAL_LIBRARY = 'xul'
|
||||||
|
FAIL_ON_WARNINGS = True
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
interface nsIDOMWindow;
|
interface nsIDOMWindow;
|
||||||
|
|
||||||
[scriptable, uuid(bd02d09c-41ab-47b7-9319-57aa8e5059b0)]
|
[scriptable, uuid(0a050c4f-d292-4a14-8712-09bc1019840a)]
|
||||||
interface nsIDataStoreService : nsISupports
|
interface nsIDataStoreService : nsISupports
|
||||||
{
|
{
|
||||||
void installDataStore(in unsigned long appId,
|
void installDataStore(in unsigned long appId,
|
||||||
@@ -24,12 +24,4 @@ interface nsIDataStoreService : nsISupports
|
|||||||
|
|
||||||
nsISupports getDataStores(in nsIDOMWindow window,
|
nsISupports getDataStores(in nsIDOMWindow window,
|
||||||
in DOMString name);
|
in DOMString name);
|
||||||
|
|
||||||
// This is an array of objects composed by:
|
|
||||||
// - readOnly: boolean
|
|
||||||
// - name: DOMString
|
|
||||||
// - owner: DOMString
|
|
||||||
// - enabled: true/false - true if this dataStore is ready to be used.
|
|
||||||
jsval getDataStoresInfo(in DOMString name,
|
|
||||||
in unsigned long appId);
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -235,9 +235,6 @@ IDBFactory::Create(ContentParent* aContentParent,
|
|||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
|
NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
|
||||||
NS_ASSERTION(nsContentUtils::IsCallerChrome(), "Only for chrome!");
|
NS_ASSERTION(nsContentUtils::IsCallerChrome(), "Only for chrome!");
|
||||||
NS_ASSERTION(aContentParent, "Null ContentParent!");
|
|
||||||
|
|
||||||
NS_ASSERTION(!nsContentUtils::GetCurrentJSContext(), "Should be called from C++");
|
|
||||||
|
|
||||||
// We need to get this information before we push a null principal to avoid
|
// We need to get this information before we push a null principal to avoid
|
||||||
// IsCallerChrome() assertion in quota manager.
|
// IsCallerChrome() assertion in quota manager.
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ public:
|
|||||||
IDBFactory** aFactory);
|
IDBFactory** aFactory);
|
||||||
|
|
||||||
// Called when using IndexedDB from a JS component or a JSM in a different
|
// Called when using IndexedDB from a JS component or a JSM in a different
|
||||||
// process.
|
// process or from a C++ component.
|
||||||
static nsresult Create(ContentParent* aContentParent,
|
static nsresult Create(ContentParent* aContentParent,
|
||||||
IDBFactory** aFactory);
|
IDBFactory** aFactory);
|
||||||
|
|
||||||
|
|||||||
@@ -327,7 +327,7 @@ IDBRequest::WrapObject(JSContext* aCx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
JS::Value
|
JS::Value
|
||||||
IDBRequest::GetResult(JSContext* aCx, mozilla::ErrorResult& aRv) const
|
IDBRequest::GetResult(mozilla::ErrorResult& aRv) const
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
|||||||
@@ -132,7 +132,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
JS::Value
|
JS::Value
|
||||||
GetResult(JSContext* aCx, ErrorResult& aRv) const;
|
GetResult(ErrorResult& aRv) const;
|
||||||
|
|
||||||
|
JS::Value
|
||||||
|
GetResult(JSContext* aCx, ErrorResult& aRv) const
|
||||||
|
{
|
||||||
|
return GetResult(aRv);
|
||||||
|
}
|
||||||
|
|
||||||
IDBTransaction*
|
IDBTransaction*
|
||||||
GetTransaction() const
|
GetTransaction() const
|
||||||
|
|||||||
@@ -108,3 +108,10 @@ dictionary DataStoreTask {
|
|||||||
DataStoreKey? id;
|
DataStoreKey? id;
|
||||||
any data;
|
any data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// For internal use.
|
||||||
|
dictionary DataStoreRevisionData {
|
||||||
|
DOMString revisionId = "";
|
||||||
|
unsigned long objectId = 0;
|
||||||
|
DOMString operation = "";
|
||||||
|
};
|
||||||
|
|||||||
@@ -229,6 +229,8 @@ static void Shutdown();
|
|||||||
|
|
||||||
#include "AudioChannelService.h"
|
#include "AudioChannelService.h"
|
||||||
|
|
||||||
|
#include "mozilla/dom/DataStoreService.h"
|
||||||
|
|
||||||
#include "mozilla/dom/power/PowerManagerService.h"
|
#include "mozilla/dom/power/PowerManagerService.h"
|
||||||
#include "mozilla/dom/alarm/AlarmHalService.h"
|
#include "mozilla/dom/alarm/AlarmHalService.h"
|
||||||
#include "mozilla/dom/time/TimeService.h"
|
#include "mozilla/dom/time/TimeService.h"
|
||||||
@@ -584,10 +586,15 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(Geolocation, Init)
|
|||||||
#define NS_AUDIOCHANNEL_SERVICE_CID \
|
#define NS_AUDIOCHANNEL_SERVICE_CID \
|
||||||
{ 0xf712e983, 0x048a, 0x443f, { 0x88, 0x02, 0xfc, 0xc3, 0xd9, 0x27, 0xce, 0xac }}
|
{ 0xf712e983, 0x048a, 0x443f, { 0x88, 0x02, 0xfc, 0xc3, 0xd9, 0x27, 0xce, 0xac }}
|
||||||
|
|
||||||
|
#define NS_DATASTORE_SERVICE_CID \
|
||||||
|
{ 0x0d4285fe, 0xf1b3, 0x49fa, { 0xbc, 0x51, 0xa4, 0xa8, 0x3f, 0x0a, 0xaf, 0x85 }}
|
||||||
|
|
||||||
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsGeolocationService, nsGeolocationService::GetGeolocationService)
|
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsGeolocationService, nsGeolocationService::GetGeolocationService)
|
||||||
|
|
||||||
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(AudioChannelService, AudioChannelService::GetAudioChannelService)
|
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(AudioChannelService, AudioChannelService::GetAudioChannelService)
|
||||||
|
|
||||||
|
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(DataStoreService, DataStoreService::GetOrCreate)
|
||||||
|
|
||||||
#ifdef MOZ_WEBSPEECH
|
#ifdef MOZ_WEBSPEECH
|
||||||
NS_GENERIC_FACTORY_CONSTRUCTOR(FakeSpeechRecognitionService)
|
NS_GENERIC_FACTORY_CONSTRUCTOR(FakeSpeechRecognitionService)
|
||||||
#endif
|
#endif
|
||||||
@@ -737,6 +744,7 @@ NS_DEFINE_NAMED_CID(NS_TEXTSERVICESDOCUMENT_CID);
|
|||||||
NS_DEFINE_NAMED_CID(NS_GEOLOCATION_SERVICE_CID);
|
NS_DEFINE_NAMED_CID(NS_GEOLOCATION_SERVICE_CID);
|
||||||
NS_DEFINE_NAMED_CID(NS_GEOLOCATION_CID);
|
NS_DEFINE_NAMED_CID(NS_GEOLOCATION_CID);
|
||||||
NS_DEFINE_NAMED_CID(NS_AUDIOCHANNEL_SERVICE_CID);
|
NS_DEFINE_NAMED_CID(NS_AUDIOCHANNEL_SERVICE_CID);
|
||||||
|
NS_DEFINE_NAMED_CID(NS_DATASTORE_SERVICE_CID);
|
||||||
NS_DEFINE_NAMED_CID(NS_FOCUSMANAGER_CID);
|
NS_DEFINE_NAMED_CID(NS_FOCUSMANAGER_CID);
|
||||||
NS_DEFINE_NAMED_CID(CSPSERVICE_CID);
|
NS_DEFINE_NAMED_CID(CSPSERVICE_CID);
|
||||||
NS_DEFINE_NAMED_CID(NS_CSPCONTEXT_CID);
|
NS_DEFINE_NAMED_CID(NS_CSPCONTEXT_CID);
|
||||||
@@ -1025,6 +1033,7 @@ static const mozilla::Module::CIDEntry kLayoutCIDs[] = {
|
|||||||
{ &kNS_GEOLOCATION_SERVICE_CID, false, nullptr, nsGeolocationServiceConstructor },
|
{ &kNS_GEOLOCATION_SERVICE_CID, false, nullptr, nsGeolocationServiceConstructor },
|
||||||
{ &kNS_GEOLOCATION_CID, false, nullptr, GeolocationConstructor },
|
{ &kNS_GEOLOCATION_CID, false, nullptr, GeolocationConstructor },
|
||||||
{ &kNS_AUDIOCHANNEL_SERVICE_CID, false, nullptr, AudioChannelServiceConstructor },
|
{ &kNS_AUDIOCHANNEL_SERVICE_CID, false, nullptr, AudioChannelServiceConstructor },
|
||||||
|
{ &kNS_DATASTORE_SERVICE_CID, false, nullptr, DataStoreServiceConstructor },
|
||||||
{ &kNS_FOCUSMANAGER_CID, false, nullptr, CreateFocusManager },
|
{ &kNS_FOCUSMANAGER_CID, false, nullptr, CreateFocusManager },
|
||||||
#ifdef MOZ_WEBSPEECH
|
#ifdef MOZ_WEBSPEECH
|
||||||
{ &kNS_FAKE_SPEECH_RECOGNITION_SERVICE_CID, false, nullptr, FakeSpeechRecognitionServiceConstructor },
|
{ &kNS_FAKE_SPEECH_RECOGNITION_SERVICE_CID, false, nullptr, FakeSpeechRecognitionServiceConstructor },
|
||||||
@@ -1180,6 +1189,7 @@ static const mozilla::Module::ContractIDEntry kLayoutContracts[] = {
|
|||||||
{ "@mozilla.org/geolocation/service;1", &kNS_GEOLOCATION_SERVICE_CID },
|
{ "@mozilla.org/geolocation/service;1", &kNS_GEOLOCATION_SERVICE_CID },
|
||||||
{ "@mozilla.org/geolocation;1", &kNS_GEOLOCATION_CID },
|
{ "@mozilla.org/geolocation;1", &kNS_GEOLOCATION_CID },
|
||||||
{ "@mozilla.org/audiochannel/service;1", &kNS_AUDIOCHANNEL_SERVICE_CID },
|
{ "@mozilla.org/audiochannel/service;1", &kNS_AUDIOCHANNEL_SERVICE_CID },
|
||||||
|
{ "@mozilla.org/datastore-service;1", &kNS_DATASTORE_SERVICE_CID },
|
||||||
{ "@mozilla.org/focus-manager;1", &kNS_FOCUSMANAGER_CID },
|
{ "@mozilla.org/focus-manager;1", &kNS_FOCUSMANAGER_CID },
|
||||||
#ifdef MOZ_WEBSPEECH
|
#ifdef MOZ_WEBSPEECH
|
||||||
{ NS_SPEECH_RECOGNITION_SERVICE_CONTRACTID_PREFIX "fake", &kNS_FAKE_SPEECH_RECOGNITION_SERVICE_CID },
|
{ NS_SPEECH_RECOGNITION_SERVICE_CONTRACTID_PREFIX "fake", &kNS_FAKE_SPEECH_RECOGNITION_SERVICE_CID },
|
||||||
|
|||||||
@@ -65,6 +65,7 @@
|
|||||||
#include "ActiveLayerTracker.h"
|
#include "ActiveLayerTracker.h"
|
||||||
|
|
||||||
#include "AudioChannelService.h"
|
#include "AudioChannelService.h"
|
||||||
|
#include "mozilla/dom/DataStoreService.h"
|
||||||
|
|
||||||
#ifdef MOZ_XUL
|
#ifdef MOZ_XUL
|
||||||
#include "nsXULPopupManager.h"
|
#include "nsXULPopupManager.h"
|
||||||
@@ -411,6 +412,8 @@ nsLayoutStatics::Shutdown()
|
|||||||
|
|
||||||
AudioChannelService::Shutdown();
|
AudioChannelService::Shutdown();
|
||||||
|
|
||||||
|
DataStoreService::Shutdown();
|
||||||
|
|
||||||
ContentParent::ShutDown();
|
ContentParent::ShutDown();
|
||||||
|
|
||||||
nsRefreshDriver::Shutdown();
|
nsRefreshDriver::Shutdown();
|
||||||
|
|||||||
@@ -624,6 +624,5 @@ bin/components/@DLL_PREFIX@nkgnomevfs@DLL_SUFFIX@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
@BINPATH@/components/DataStore.manifest
|
@BINPATH@/components/DataStore.manifest
|
||||||
@BINPATH@/components/DataStoreService.js
|
|
||||||
@BINPATH@/components/DataStoreImpl.js
|
@BINPATH@/components/DataStoreImpl.js
|
||||||
@BINPATH@/components/dom_datastore.xpt
|
@BINPATH@/components/dom_datastore.xpt
|
||||||
|
|||||||
Reference in New Issue
Block a user