Backed out changesets 083b9fb75e9a, 4cbc8cf0b619, and ef379607cff7 (bug 957086) for Win7/Win8 debug mochitest crashes.
authorRyan VanderMeulen <ryanvm@gmail.com>
Thu, 29 May 2014 13:22:57 -0400
changeset 205949 ea7edac9664adc9bdb819cfa1a50353b8348a200
parent 205948 c9f8e59a7e0db764407fed215b88d9c933bfb911
child 205950 29ca8bc78484630eb38ed9e159552b73e34b9bf5
push id494
push userraliiev@mozilla.com
push dateMon, 25 Aug 2014 18:42:16 +0000
treeherdermozilla-release@a3cc3e46b571 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs957086
milestone32.0a1
backs out083b9fb75e9a8fff9eab3dddfed568a88d4a2bcf
4cbc8cf0b6199852d1a303acbcb55a9992e0a89c
ef379607cff7b4c6abcd63cee9f366454fa7616b
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changesets 083b9fb75e9a, 4cbc8cf0b619, and ef379607cff7 (bug 957086) for Win7/Win8 debug mochitest crashes.
b2g/installer/package-manifest.in
browser/installer/package-manifest.in
dom/base/Navigator.cpp
dom/datastore/DataStore.manifest
dom/datastore/DataStoreCallbacks.h
dom/datastore/DataStoreChangeNotifier.jsm
dom/datastore/DataStoreDB.cpp
dom/datastore/DataStoreDB.h
dom/datastore/DataStoreImpl.js
dom/datastore/DataStoreImpl.jsm
dom/datastore/DataStoreRevision.cpp
dom/datastore/DataStoreRevision.h
dom/datastore/DataStoreService.cpp
dom/datastore/DataStoreService.h
dom/datastore/DataStoreService.js
dom/datastore/DataStoreServiceInternal.jsm
dom/datastore/moz.build
dom/datastore/nsIDataStore.idl
dom/datastore/nsIDataStoreService.idl
dom/indexedDB/IDBFactory.cpp
dom/indexedDB/IDBFactory.h
dom/indexedDB/IDBRequest.cpp
dom/indexedDB/IDBRequest.h
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PContent.ipdl
dom/webidl/DataStore.webidl
layout/build/nsLayoutModule.cpp
layout/build/nsLayoutStatics.cpp
mobile/android/installer/package-manifest.in
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -803,17 +803,17 @@ bin/components/@DLL_PREFIX@nkgnomevfs@DL
 #endif
 
 #ifdef MOZ_SERVICES_FXACCOUNTS
 @BINPATH@/components/FxAccountsUIGlue.js
 @BINPATH@/components/services_fxaccounts.xpt
 #endif
 
 @BINPATH@/components/DataStore.manifest
-@BINPATH@/components/DataStoreImpl.js
+@BINPATH@/components/DataStoreService.js
 @BINPATH@/components/dom_datastore.xpt
 
 #ifdef MOZ_WEBSPEECH
 @BINPATH@/components/dom_webspeechsynth.xpt
 #endif
 
 #ifdef XP_MACOSX
 @BINPATH@/@DLL_PREFIX@plugin_child_interpose@DLL_SUFFIX@
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -856,17 +856,17 @@ bin/libfreebl_32int64_3.so
 @BINPATH@/metro/chrome/pdfjs/*
 #endif
 @BINPATH@/metro/components
 @BINPATH@/metro/defaults
 @BINPATH@/metro/modules
 #endif
 
 @BINPATH@/components/DataStore.manifest
-@BINPATH@/components/DataStoreImpl.js
+@BINPATH@/components/DataStoreService.js
 @BINPATH@/components/dom_datastore.xpt
 
 
 #ifdef MOZ_ASAN
 #ifdef CLANG_CXX
 @BINPATH@/llvm-symbolizer
 #endif
 #endif
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -77,17 +77,17 @@
 #include "AudioChannelManager.h"
 #endif
 
 #ifdef MOZ_B2G_FM
 #include "mozilla/dom/FMRadio.h"
 #endif
 
 #include "nsIDOMGlobalPropertyInitializer.h"
-#include "mozilla/dom/DataStoreService.h"
+#include "nsIDataStoreService.h"
 #include "nsJSUtils.h"
 
 #include "nsScriptNameSpaceManager.h"
 
 #include "mozilla/dom/NavigatorBinding.h"
 #include "mozilla/dom/Promise.h"
 
 #include "nsIUploadChannel2.h"
@@ -1461,17 +1461,18 @@ Navigator::GetDataStores(nsPIDOMWindow* 
                          const nsAString& aName,
                          ErrorResult& aRv)
 {
   if (!aWindow || !aWindow->GetDocShell()) {
     aRv.Throw(NS_ERROR_UNEXPECTED);
     return nullptr;
   }
 
-  nsRefPtr<DataStoreService> service = DataStoreService::GetOrCreate();
+  nsCOMPtr<nsIDataStoreService> service =
+    do_GetService("@mozilla.org/datastore-service;1");
   if (!service) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   nsCOMPtr<nsISupports> promise;
   aRv = service->GetDataStores(aWindow, aName, getter_AddRefs(promise));
 
--- a/dom/datastore/DataStore.manifest
+++ b/dom/datastore/DataStore.manifest
@@ -1,2 +1,2 @@
-component {db5c9602-030f-4bff-a3de-881a8de370f2} DataStoreImpl.js
-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}
deleted file mode 100644
--- a/dom/datastore/DataStoreCallbacks.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* -*- 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
--- a/dom/datastore/DataStoreChangeNotifier.jsm
+++ b/dom/datastore/DataStoreChangeNotifier.jsm
@@ -7,16 +7,19 @@
 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 this.EXPORTED_SYMBOLS = ["DataStoreChangeNotifier"];
 
 function debug(s) {
   //dump('DEBUG DataStoreChangeNotifier: ' + s + '\n');
 }
 
+// DataStoreServiceInternal should not be converted into a lazy getter as it
+// runs code during initialization.
+Cu.import('resource://gre/modules/DataStoreServiceInternal.jsm');
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
                                    "@mozilla.org/parentprocessmessagemanager;1",
                                    "nsIMessageBroadcaster");
 
 this.DataStoreChangeNotifier = {
deleted file mode 100644
--- a/dom/datastore/DataStoreDB.cpp
+++ /dev/null
@@ -1,319 +0,0 @@
-/* -*- 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;
-  }
-
-  {
-    RootedDictionary<IDBObjectStoreParameters> params(cx);
-    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;
-
-  {
-    RootedDictionary<IDBObjectStoreParameters> params(cx);
-    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();
-    }
-  }
-
-  {
-    RootedDictionary<IDBIndexParameters> params(cx);
-    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
deleted file mode 100644
--- a/dom/datastore/DataStoreDB.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/* -*- 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
rename from dom/datastore/DataStoreImpl.js
rename to dom/datastore/DataStoreImpl.jsm
--- a/dom/datastore/DataStoreImpl.js
+++ b/dom/datastore/DataStoreImpl.jsm
@@ -1,16 +1,18 @@
 /* -*- 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'
 
+this.EXPORTED_SYMBOLS = ["DataStore"];
+
 function debug(s) {
   //dump('DEBUG DataStore: ' + s + '\n');
 }
 
 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 const REVISION_ADDED = "added";
 const REVISION_UPDATED = "updated";
@@ -52,26 +54,27 @@ function validateId(aId) {
     return aId.length;
   }
 
   aId = parseInt(aId);
   return (!isNaN(aId) && aId > 0);
 }
 
 /* DataStore object */
-function DataStore() {
+this.DataStore = function(aWindow, aName, aOwner, aReadOnly) {
   debug("DataStore created");
+  this.init(aWindow, aName, aOwner, aReadOnly);
 }
 
-DataStore.prototype = {
+this.DataStore.prototype = {
   classDescription: "DataStore XPCOM Component",
   classID: Components.ID("{db5c9602-030f-4bff-a3de-881a8de370f2}"),
   contractID: "@mozilla.org/dom/datastore-impl;1",
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIDataStore, Ci.nsISupports,
-                                         Ci.nsIObserver]),
+  QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsISupports,
+                                         Components.interfaces.nsIObserver]),
 
   callbacks: [],
 
   _window: null,
   _name: null,
   _owner: null,
   _readOnly: null,
   _revisionId: null,
@@ -528,10 +531,8 @@ DataStore.prototype = {
     let cursorImpl = this._window.DataStoreCursorImpl.
                                   _create(this._window, this._cursor);
 
     let exposedCursor = new this._window.DataStoreCursor();
     exposedCursor.setDataStoreCursorImpl(cursorImpl);
     return exposedCursor;
   }
 };
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([DataStore]);
deleted file mode 100644
--- a/dom/datastore/DataStoreRevision.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/* -*- 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
deleted file mode 100644
--- a/dom/datastore/DataStoreRevision.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* -*- 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 "jsapi.h"
-#include "nsAutoPtr.h"
-#include "nsIDOMEventListener.h"
-#include "nsString.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
deleted file mode 100644
--- a/dom/datastore/DataStoreService.cpp
+++ /dev/null
@@ -1,1348 +0,0 @@
-/* -*- 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 "DataStoreService.h"
-
-#include "DataStoreCallbacks.h"
-#include "DataStoreDB.h"
-#include "DataStoreRevision.h"
-#include "mozilla/dom/DataStore.h"
-#include "mozilla/dom/DataStoreBinding.h"
-#include "mozilla/dom/DataStoreImplBinding.h"
-#include "nsIDataStore.h"
-
-#include "mozilla/Preferences.h"
-#include "mozilla/Services.h"
-#include "mozilla/StaticPtr.h"
-#include "mozilla/dom/ContentChild.h"
-#include "mozilla/dom/ContentParent.h"
-#include "mozilla/dom/DOMError.h"
-#include "mozilla/dom/indexedDB/IDBCursor.h"
-#include "mozilla/dom/indexedDB/IDBObjectStore.h"
-#include "mozilla/dom/PermissionMessageUtils.h"
-#include "mozilla/dom/Promise.h"
-#include "mozilla/unused.h"
-
-#include "mozIApplication.h"
-#include "mozIApplicationClearPrivateDataParams.h"
-#include "nsIAppsService.h"
-#include "nsIDOMEvent.h"
-#include "nsIDocument.h"
-#include "nsIDOMGlobalPropertyInitializer.h"
-#include "nsIIOService.h"
-#include "nsIObserverService.h"
-#include "nsIPermissionManager.h"
-#include "nsIScriptSecurityManager.h"
-#include "nsIUUIDGenerator.h"
-#include "nsPIDOMWindow.h"
-#include "nsIURI.h"
-
-#include "nsContentUtils.h"
-#include "nsNetCID.h"
-#include "nsServiceManagerUtils.h"
-#include "nsThreadUtils.h"
-#include "nsXULAppAPI.h"
-
-#define ASSERT_PARENT_PROCESS()                                             \
-  AssertIsInMainProcess();                                                  \
-  if (NS_WARN_IF(!IsMainProcess())) {                                       \
-    return NS_ERROR_FAILURE;                                                \
-  }
-
-namespace mozilla {
-namespace dom {
-
-using namespace indexedDB;
-
-// This class contains all the information about a DataStore.
-class DataStoreInfo
-{
-public:
-  DataStoreInfo()
-    : mReadOnly(true)
-    , mEnabled(false)
-  {}
-
-  DataStoreInfo(const nsAString& aName,
-                const nsAString& aOriginURL,
-                const nsAString& aManifestURL,
-                bool aReadOnly,
-                bool aEnabled)
-  {
-    Init(aName, aOriginURL, aManifestURL, aReadOnly, aEnabled);
-  }
-
-  void Init(const nsAString& aName,
-            const nsAString& aOriginURL,
-            const nsAString& aManifestURL,
-            bool aReadOnly,
-            bool aEnabled)
-  {
-    mName = aName;
-    mOriginURL = aOriginURL;
-    mManifestURL = aManifestURL;
-    mReadOnly = aReadOnly;
-    mEnabled = aEnabled;
-  }
-
-  void Update(const nsAString& aName,
-              const nsAString& aOriginURL,
-              const nsAString& aManifestURL,
-              bool aReadOnly)
-  {
-    mName = aName;
-    mOriginURL = aOriginURL;
-    mManifestURL = aManifestURL;
-    mReadOnly = aReadOnly;
-  }
-
-  void Enable()
-  {
-    mEnabled = true;
-  }
-
-  nsString mName;
-  nsString mOriginURL;
-  nsString mManifestURL;
-  bool mReadOnly;
-
-  // A DataStore is enabled when it has its first revision.
-  bool mEnabled;
-};
-
-namespace {
-
-// Singleton for DataStoreService.
-StaticRefPtr<DataStoreService> gDataStoreService;
-static uint64_t gCounterID = 0;
-
-typedef nsClassHashtable<nsUint32HashKey, DataStoreInfo> HashApp;
-
-bool
-IsMainProcess()
-{
-  static const bool isMainProcess =
-    XRE_GetProcessType() == GeckoProcessType_Default;
-  return isMainProcess;
-}
-
-void
-AssertIsInMainProcess()
-{
-  MOZ_ASSERT(IsMainProcess());
-}
-
-void
-RejectPromise(nsPIDOMWindow* aWindow, Promise* aPromise, nsresult aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(NS_FAILED(aRv));
-
-  nsRefPtr<DOMError> error;
-  if (aRv == NS_ERROR_DOM_SECURITY_ERR) {
-    error = new DOMError(aWindow, NS_LITERAL_STRING("SecurityError"),
-                         NS_LITERAL_STRING("Access denied"));
-  } else {
-    error = new DOMError(aWindow, NS_LITERAL_STRING("InternalError"),
-                         NS_LITERAL_STRING("An error occurred"));
-  }
-
-  aPromise->MaybeReject(error);
-}
-
-void
-DeleteDatabase(const nsAString& aName,
-               const nsAString& aManifestURL)
-{
-  AssertIsInMainProcess();
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsRefPtr<DataStoreDB> db = new DataStoreDB(aManifestURL, aName);
-  db->Delete();
-}
-
-PLDHashOperator
-DeleteDataStoresAppEnumerator(
-                             const uint32_t& aAppId,
-                             nsAutoPtr<DataStoreInfo>& aInfo,
-                             void* aUserData)
-{
-  AssertIsInMainProcess();
-  MOZ_ASSERT(NS_IsMainThread());
-
-  auto* appId = static_cast<uint32_t*>(aUserData);
-  if (*appId != aAppId) {
-    return PL_DHASH_NEXT;
-  }
-
-  DeleteDatabase(aInfo->mName, aInfo->mManifestURL);
-  return PL_DHASH_REMOVE;
-}
-
-PLDHashOperator
-DeleteDataStoresEnumerator(const nsAString& aName,
-                           nsAutoPtr<HashApp>& aApps,
-                           void* aUserData)
-{
-  AssertIsInMainProcess();
-  MOZ_ASSERT(NS_IsMainThread());
-
-  aApps->Enumerate(DeleteDataStoresAppEnumerator, aUserData);
-  return aApps->Count() ? PL_DHASH_NEXT : PL_DHASH_REMOVE;
-}
-
-void
-GeneratePermissionName(nsAString& aPermission,
-                       const nsAString& aName,
-                       const nsAString& aManifestURL)
-{
-  aPermission.AssignASCII("indexedDB-chrome-");
-  aPermission.Append(aName);
-  aPermission.AppendASCII("|");
-  aPermission.Append(aManifestURL);
-}
-
-nsresult
-ResetPermission(uint32_t aAppId, const nsAString& aOriginURL,
-                const nsAString& aManifestURL,
-                const nsAString& aPermission,
-                bool aReadOnly)
-{
-  AssertIsInMainProcess();
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsresult rv;
-  nsCOMPtr<nsIIOService> ioService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  nsCOMPtr<nsIURI> uri;
-  rv = ioService->NewURI(NS_ConvertUTF16toUTF8(aOriginURL), nullptr, nullptr,
-                         getter_AddRefs(uri));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
-  if (!ssm) {
-    return NS_ERROR_FAILURE;
-  }
-
-  nsCOMPtr<nsIPrincipal> principal;
-  rv = ssm->GetAppCodebasePrincipal(uri, aAppId, false,
-                                    getter_AddRefs(principal));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  nsCOMPtr<nsIPermissionManager> pm =
-    do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
-  if (!pm) {
-    return NS_ERROR_FAILURE;
-  }
-
-  nsCString basePermission;
-  basePermission.Append(NS_ConvertUTF16toUTF8(aPermission));
-
-  // Write permission
-  {
-    nsCString permission;
-    permission.Append(basePermission);
-    permission.AppendASCII("-write");
-
-    uint32_t perm = nsIPermissionManager::UNKNOWN_ACTION;
-    rv = pm->TestExactPermissionFromPrincipal(principal, permission.get(),
-                                              &perm);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-
-    if (aReadOnly && perm == nsIPermissionManager::ALLOW_ACTION) {
-      rv = pm->RemoveFromPrincipal(principal, permission.get());
-    }
-    else if (!aReadOnly && perm != nsIPermissionManager::ALLOW_ACTION) {
-      rv = pm->AddFromPrincipal(principal, permission.get(),
-                                nsIPermissionManager::ALLOW_ACTION,
-                                nsIPermissionManager::EXPIRE_NEVER, 0);
-    }
-
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-  }
-
-  // Read permission
-  {
-    nsCString permission;
-    permission.Append(basePermission);
-    permission.AppendASCII("-read");
-
-    uint32_t perm = nsIPermissionManager::UNKNOWN_ACTION;
-    rv = pm->TestExactPermissionFromPrincipal(principal, permission.get(),
-                                              &perm);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-
-    if (perm != nsIPermissionManager::ALLOW_ACTION) {
-      rv = pm->AddFromPrincipal(principal, permission.get(),
-                                nsIPermissionManager::ALLOW_ACTION,
-                                nsIPermissionManager::EXPIRE_NEVER, 0);
-      if (NS_WARN_IF(NS_FAILED(rv))) {
-        return rv;
-      }
-    }
-  }
-
-  // Generic permission
-  uint32_t perm = nsIPermissionManager::UNKNOWN_ACTION;
-  rv = pm->TestExactPermissionFromPrincipal(principal, basePermission.get(),
-                                            &perm);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  if (perm != nsIPermissionManager::ALLOW_ACTION) {
-    rv = pm->AddFromPrincipal(principal, basePermission.get(),
-                              nsIPermissionManager::ALLOW_ACTION,
-                              nsIPermissionManager::EXPIRE_NEVER, 0);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-  }
-
-  return NS_OK;
-}
-
-class MOZ_STACK_CLASS GetDataStoreInfosData
-{
-public:
-  GetDataStoreInfosData(nsClassHashtable<nsStringHashKey, HashApp>& aAccessStores,
-                        const nsAString& aName, uint32_t aAppId,
-                        nsTArray<DataStoreInfo>& aStores)
-    : mAccessStores(aAccessStores)
-    , mName(aName)
-    , mAppId(aAppId)
-    , mStores(aStores)
-  {}
-
-  nsClassHashtable<nsStringHashKey, HashApp>& mAccessStores;
-  nsString mName;
-  uint32_t mAppId;
-  nsTArray<DataStoreInfo>& mStores;
-};
-
-PLDHashOperator
-GetDataStoreInfosEnumerator(const uint32_t& aAppId,
-                            DataStoreInfo* aInfo,
-                            void* aUserData)
-{
-  AssertIsInMainProcess();
-  MOZ_ASSERT(NS_IsMainThread());
-
-  auto* data = static_cast<GetDataStoreInfosData*>(aUserData);
-  if (aAppId == data->mAppId) {
-    return PL_DHASH_NEXT;
-  }
-
-  HashApp* apps;
-  if (!data->mAccessStores.Get(data->mName, &apps)) {
-    return PL_DHASH_NEXT;
-  }
-
-  DataStoreInfo* accessInfo = nullptr;
-  if (!apps->Get(data->mAppId, &accessInfo)) {
-    return PL_DHASH_NEXT;
-  }
-
-  bool readOnly = aInfo->mReadOnly || accessInfo->mReadOnly;
-  DataStoreInfo* accessStore = data->mStores.AppendElement();
-  accessStore->Init(aInfo->mName, aInfo->mOriginURL,
-                    aInfo->mManifestURL, readOnly,
-                    aInfo->mEnabled);
-
-  return PL_DHASH_NEXT;
-}
-
-// This class is useful to enumerate the add permissions for each app.
-class MOZ_STACK_CLASS AddPermissionsData
-{
-public:
-  AddPermissionsData(const nsAString& aPermission, bool aReadOnly)
-    : mPermission(aPermission)
-    , mReadOnly(aReadOnly)
-    , mResult(NS_OK)
-  {}
-
-  nsString mPermission;
-  bool mReadOnly;
-  nsresult mResult;
-};
-
-PLDHashOperator
-AddPermissionsEnumerator(const uint32_t& aAppId,
-                         DataStoreInfo* aInfo,
-                         void* userData)
-{
-  AssertIsInMainProcess();
-  MOZ_ASSERT(NS_IsMainThread());
-
-  auto* data = static_cast<AddPermissionsData*>(userData);
-
-  // ReadOnly is decided by the owner first.
-  bool readOnly = data->mReadOnly || aInfo->mReadOnly;
-
-  data->mResult = ResetPermission(aAppId, aInfo->mOriginURL,
-                                  aInfo->mManifestURL,
-                                  data->mPermission,
-                                  readOnly);
-  return NS_FAILED(data->mResult) ? PL_DHASH_STOP : PL_DHASH_NEXT;
-}
-
-// This class is useful to enumerate the add permissions for each app.
-class MOZ_STACK_CLASS AddAccessPermissionsData
-{
-public:
-  AddAccessPermissionsData(const nsAString& aName, bool aReadOnly)
-    : mName(aName)
-    , mReadOnly(aReadOnly)
-    , mResult(NS_OK)
-  {}
-
-  nsString mName;
-  bool mReadOnly;
-  nsresult mResult;
-};
-
-PLDHashOperator
-AddAccessPermissionsEnumerator(const uint32_t& aAppId,
-                               DataStoreInfo* aInfo,
-                               void* userData)
-{
-  AssertIsInMainProcess();
-  MOZ_ASSERT(NS_IsMainThread());
-
-  auto* data = static_cast<AddAccessPermissionsData*>(userData);
-
-  nsString permission;
-  GeneratePermissionName(permission, data->mName, aInfo->mManifestURL);
-
-  // ReadOnly is decided by the owner first.
-  bool readOnly = aInfo->mReadOnly || data->mReadOnly;
-
-  data->mResult = ResetPermission(aAppId, aInfo->mOriginURL,
-                                  aInfo->mManifestURL,
-                                  permission, readOnly);
-  return NS_FAILED(data->mResult) ? PL_DHASH_STOP : PL_DHASH_NEXT;
-}
-
-} /* anonymous namespace */
-
-// A PendingRequest is created when a content code wants a list of DataStores
-// but some of them are not enabled yet.
-class PendingRequest
-{
-public:
-  void Init(nsPIDOMWindow* aWindow, Promise* aPromise,
-            const nsTArray<DataStoreInfo>& aStores,
-            const nsTArray<nsString>& aPendingDataStores)
-  {
-    mWindow = aWindow;
-    mPromise = aPromise;
-    mStores = aStores;
-    mPendingDataStores = aPendingDataStores;
-  }
-
-  nsCOMPtr<nsPIDOMWindow> mWindow;
-  nsRefPtr<Promise> mPromise;
-  nsTArray<DataStoreInfo> mStores;
-
-  // This array contains the list of manifestURLs of the DataStores that are
-  // not enabled yet.
-  nsTArray<nsString> mPendingDataStores;
-};
-
-// This callback is used to enable a DataStore when its first revisionID is
-// created.
-class RevisionAddedEnableStoreCallback MOZ_FINAL :
-  public DataStoreRevisionCallback
-{
-public:
-  NS_INLINE_DECL_REFCOUNTING(RevisionAddedEnableStoreCallback);
-
-  RevisionAddedEnableStoreCallback(uint32_t aAppId,
-                                   const nsAString& aName,
-                                   const nsAString& aManifestURL)
-    : mAppId(aAppId)
-    , mName(aName)
-    , mManifestURL(aManifestURL)
-  {
-    AssertIsInMainProcess();
-    MOZ_ASSERT(NS_IsMainThread());
-  }
-
-  void
-  Run(const nsAString& aRevisionId)
-  {
-    AssertIsInMainProcess();
-    MOZ_ASSERT(NS_IsMainThread());
-
-    nsRefPtr<DataStoreService> service = DataStoreService::Get();
-    MOZ_ASSERT(service);
-
-    service->EnableDataStore(mAppId, mName, mManifestURL);
-  }
-
-private:
-  uint32_t mAppId;
-  nsString mName;
-  nsString mManifestURL;
-};
-
-// This DataStoreDBCallback is called when DataStoreDB opens the DataStore DB.
-// Then the first revision will be created if it doesn't exist yet.
-class FirstRevisionIdCallback MOZ_FINAL : public DataStoreDBCallback
-                                        , public nsIDOMEventListener
-{
-public:
-  NS_DECL_ISUPPORTS
-
-  FirstRevisionIdCallback(uint32_t aAppId, const nsAString& aName,
-                          const nsAString& aManifestURL)
-    : mAppId(aAppId)
-    , mName(aName)
-    , mManifestURL(aManifestURL)
-  {
-    AssertIsInMainProcess();
-    MOZ_ASSERT(NS_IsMainThread());
-  }
-
-  void
-  Run(DataStoreDB* aDb, bool aSuccess)
-  {
-    AssertIsInMainProcess();
-    MOZ_ASSERT(NS_IsMainThread());
-    MOZ_ASSERT(aDb);
-
-    if (!aSuccess) {
-      NS_WARNING("Failed to create the first revision.");
-      return;
-    }
-
-    mTxn = aDb->Transaction();
-
-    ErrorResult rv;
-    nsRefPtr<IDBObjectStore> store =
-      mTxn->ObjectStore(NS_LITERAL_STRING(DATASTOREDB_REVISION), rv);
-    if (NS_WARN_IF(rv.Failed())) {
-      return;
-    }
-
-    // a Null JSContext is ok because OpenCursor ignores it if the range is
-    // undefined.
-    mRequest = store->OpenCursor(nullptr, JS::UndefinedHandleValue,
-                                 IDBCursorDirection::Prev, rv);
-    if (NS_WARN_IF(rv.Failed())) {
-      return;
-    }
-
-    nsresult res;
-    res = mRequest->EventTarget::AddEventListener(NS_LITERAL_STRING("success"),
-                                                  this, false);
-    if (NS_WARN_IF(NS_FAILED(res))) {
-      return;
-    }
-  }
-
-  // nsIDOMEventListener
-  NS_IMETHOD
-  HandleEvent(nsIDOMEvent* aEvent)
-  {
-    AssertIsInMainProcess();
-    MOZ_ASSERT(NS_IsMainThread());
-
-    nsString type;
-    nsresult rv = aEvent->GetType(type);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-
-    if (!type.EqualsASCII("success")) {
-      return NS_ERROR_FAILURE;
-    }
-
-    mRequest->RemoveEventListener(NS_LITERAL_STRING("success"), this, false);
-
-    // Note: this cx is only used for rooting and AddRevision, neither of which
-    // actually care which compartment we're in.
-    AutoSafeJSContext cx;
-
-    ErrorResult error;
-    JS::Rooted<JS::Value> result(cx, mRequest->GetResult(error));
-    if (NS_WARN_IF(error.Failed())) {
-      return error.ErrorCode();
-    }
-
-    // This means that the content is a IDBCursor, so the first revision already
-    // exists.
-    if (result.isObject()) {
-      nsRefPtr<DataStoreService> service = DataStoreService::Get();
-      MOZ_ASSERT(service);
-
-      return service->EnableDataStore(mAppId, mName, mManifestURL);
-    }
-
-    MOZ_ASSERT(mTxn);
-    nsRefPtr<IDBObjectStore> store =
-      mTxn->ObjectStore(NS_LITERAL_STRING(DATASTOREDB_REVISION), error);
-    if (NS_WARN_IF(error.Failed())) {
-      return error.ErrorCode();
-    }
-    MOZ_ASSERT(store);
-
-    nsRefPtr<RevisionAddedEnableStoreCallback> callback =
-      new RevisionAddedEnableStoreCallback(mAppId, mName, mManifestURL);
-
-    // If the revision doesn't exist, let's create it.
-    nsRefPtr<DataStoreRevision> mRevision = new DataStoreRevision();
-    return mRevision->AddRevision(cx, store, 0, DataStoreRevision::RevisionVoid,
-                                  callback);
-  }
-
-private:
-  nsRefPtr<IDBRequest> mRequest;
-
-  nsRefPtr<IDBTransaction> mTxn;
-  nsRefPtr<DataStoreRevision> mRevision;
-
-  uint32_t mAppId;
-  nsString mName;
-  nsString mManifestURL;
-};
-
-NS_IMPL_ISUPPORTS(FirstRevisionIdCallback, nsIDOMEventListener)
-
-// This class calls the 'retrieveRevisionId' method of the DataStore object for
-// any DataStore in the 'mResults' array. When all of them are called, the
-// promise is resolved with 'mResults'.
-// The reson why this has to be done is because DataStore are object that can be
-// created in any thread and in any process. The first revision has been
-// created, but they don't know its value yet.
-class RetrieveRevisionsCounter
-{
-public:
-  NS_INLINE_DECL_REFCOUNTING(RetrieveRevisionsCounter);
-
-  RetrieveRevisionsCounter(uint32_t aId, Promise* aPromise, uint32_t aCount)
-    : mPromise(aPromise)
-    , mId(aId)
-    , mCount(aCount)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-  }
-
-  void
-  AppendDataStore(JSContext* aCx, DataStore* aDataStore,
-                  nsIDataStore* aDataStoreIf)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    mResults.AppendElement(aDataStore);
-
-    // DataStore will run this callback when the revisionID is retrieved.
-    JSFunction* func = js::NewFunctionWithReserved(aCx, JSCallback,
-                                                   0 /* nargs */, 0 /* flags */,
-                                                   nullptr, nullptr);
-    if (!func) {
-      return;
-    }
-
-    JS::Rooted<JSObject*> obj(aCx, JS_GetFunctionObject(func));
-    if (!obj) {
-      return;
-    }
-
-    // We use the ID to know which counter is this. The service keeps all of
-    // these counters alive with their own IDs in an hashtable.
-    js::SetFunctionNativeReserved(obj, 0, JS::Int32Value(mId));
-
-    JS::Rooted<JS::Value> value(aCx, JS::ObjectValue(*obj));
-    nsresult rv = aDataStoreIf->RetrieveRevisionId(value);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return;
-    }
-  }
-
-private:
-  static bool
-  JSCallback(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    JS::CallArgs args = CallArgsFromVp(aArgc, aVp);
-
-    JS::Rooted<JS::Value> value(aCx,
-                                js::GetFunctionNativeReserved(&args.callee(), 0));
-    uint32_t id = value.toInt32();
-
-    nsRefPtr<DataStoreService> service = DataStoreService::Get();
-    MOZ_ASSERT(service);
-
-    nsRefPtr<RetrieveRevisionsCounter> counter = service->GetCounter(id);
-    MOZ_ASSERT(counter);
-
-    // When all the callbacks are called, we can resolve the promise and remove
-    // the counter from the service.
-    --counter->mCount;
-    if (!counter->mCount) {
-      service->RemoveCounter(id);
-      counter->mPromise->MaybeResolve(counter->mResults);
-    }
-
-    return true;
-  }
-
-  nsRefPtr<Promise> mPromise;
-  nsTArray<nsRefPtr<DataStore>> mResults;
-
-  uint32_t mId;
-  uint32_t mCount;
-};
-
-/* static */ already_AddRefed<DataStoreService>
-DataStoreService::GetOrCreate()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (!gDataStoreService) {
-    nsRefPtr<DataStoreService> service = new DataStoreService();
-    if (NS_WARN_IF(NS_FAILED(service->Init()))) {
-      return nullptr;
-    }
-
-    gDataStoreService = service;
-  }
-
-  nsRefPtr<DataStoreService> service = gDataStoreService.get();
-  return service.forget();
-}
-
-/* static */ already_AddRefed<DataStoreService>
-DataStoreService::Get()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsRefPtr<DataStoreService> service = gDataStoreService.get();
-  return service.forget();
-}
-
-/* static */ void
-DataStoreService::Shutdown()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (gDataStoreService) {
-    if (IsMainProcess()) {
-      nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
-      if (obs) {
-        obs->RemoveObserver(gDataStoreService, "webapps-clear-data");
-      }
-    }
-
-    gDataStoreService = nullptr;
-  }
-}
-
-NS_INTERFACE_MAP_BEGIN(DataStoreService)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDataStoreService)
-  NS_INTERFACE_MAP_ENTRY(nsIDataStoreService)
-  NS_INTERFACE_MAP_ENTRY(nsIObserver)
-NS_INTERFACE_MAP_END
-
-NS_IMPL_ADDREF(DataStoreService)
-NS_IMPL_RELEASE(DataStoreService)
-
-DataStoreService::DataStoreService()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-}
-
-DataStoreService::~DataStoreService()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-}
-
-nsresult
-DataStoreService::Init()
-{
-  if (!IsMainProcess()) {
-    return NS_OK;
-  }
-
-  nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
-  if (!obs) {
-    return NS_ERROR_FAILURE;
-  }
-
-  nsresult rv = obs->AddObserver(this, "webapps-clear-data", false);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-DataStoreService::InstallDataStore(uint32_t aAppId,
-                                   const nsAString& aName,
-                                   const nsAString& aOriginURL,
-                                   const nsAString& aManifestURL,
-                                   bool aReadOnly)
-{
-  ASSERT_PARENT_PROCESS()
-  MOZ_ASSERT(NS_IsMainThread());
-
-  HashApp* apps = nullptr;
-  if (!mStores.Get(aName, &apps)) {
-    apps = new HashApp();
-    mStores.Put(aName, apps);
-  }
-
-  DataStoreInfo* info = nullptr;
-  if (!apps->Get(aAppId, &info)) {
-    info = new DataStoreInfo(aName, aOriginURL, aManifestURL, aReadOnly, false);
-    apps->Put(aAppId, info);
-  } else {
-    info->Update(aName, aOriginURL, aManifestURL, aReadOnly);
-  }
-
-  nsresult rv = AddPermissions(aAppId, aName, aOriginURL, aManifestURL,
-                               aReadOnly);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  // Immediately create the first revision.
-  return CreateFirstRevisionId(aAppId, aName, aManifestURL);
-}
-
-NS_IMETHODIMP
-DataStoreService::InstallAccessDataStore(uint32_t aAppId,
-                                         const nsAString& aName,
-                                         const nsAString& aOriginURL,
-                                         const nsAString& aManifestURL,
-                                         bool aReadOnly)
-{
-  ASSERT_PARENT_PROCESS()
-  MOZ_ASSERT(NS_IsMainThread());
-
-  HashApp* apps = nullptr;
-  if (!mAccessStores.Get(aName, &apps)) {
-    apps = new HashApp();
-    mAccessStores.Put(aName, apps);
-  }
-
-  DataStoreInfo* info = nullptr;
-  if (!apps->Get(aAppId, &info)) {
-    info = new DataStoreInfo(aName, aOriginURL, aManifestURL, aReadOnly, false);
-    apps->Put(aAppId, info);
-  } else {
-    info->Update(aName, aOriginURL, aManifestURL, aReadOnly);
-  }
-
-  return AddAccessPermissions(aAppId, aName, aOriginURL, aManifestURL,
-                              aReadOnly);
-}
-
-NS_IMETHODIMP
-DataStoreService::GetDataStores(nsIDOMWindow* aWindow,
-                                const nsAString& aName,
-                                nsISupports** aDataStores)
-{
-  // FIXME This will be a thread-safe method.
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aWindow);
-  if (!window) {
-    return NS_ERROR_FAILURE;
-  }
-
-  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(window);
-  nsRefPtr<Promise> promise = new Promise(global);
-
-  nsCOMPtr<nsIDocument> document = window->GetDoc();
-  MOZ_ASSERT(document);
-
-  nsCOMPtr<nsIPrincipal> principal = document->NodePrincipal();
-  MOZ_ASSERT(principal);
-
-  nsTArray<DataStoreInfo> stores;
-
-  // If this request comes from the main process, we have access to the
-  // window, so we can skip the ipc communication.
-  if (IsMainProcess()) {
-    uint32_t appId;
-    nsresult rv = principal->GetAppId(&appId);
-    if (NS_FAILED(rv)) {
-      RejectPromise(window, promise, rv);
-      promise.forget(aDataStores);
-      return NS_OK;
-    }
-
-    rv = GetDataStoreInfos(aName, appId, stores);
-    if (NS_FAILED(rv)) {
-      RejectPromise(window, promise, rv);
-      promise.forget(aDataStores);
-      return NS_OK;
-    }
-  }
-
-  else {
-    // This method can be called in the child so we need to send a request
-    // to the parent and create DataStore object here.
-    ContentChild* contentChild = ContentChild::GetSingleton();
-
-    nsTArray<DataStoreSetting> array;
-    if (!contentChild->SendDataStoreGetStores(nsAutoString(aName),
-                                              IPC::Principal(principal),
-                                              &array)) {
-      RejectPromise(window, promise, NS_ERROR_FAILURE);
-      promise.forget(aDataStores);
-      return NS_OK;
-    }
-
-    for (uint32_t i = 0; i < array.Length(); ++i) {
-      DataStoreInfo* info = stores.AppendElement();
-      info->Init(array[i].name(), array[i].originURL(),
-                 array[i].manifestURL(), array[i].readOnly(),
-                 array[i].enabled());
-    }
-  }
-
-  GetDataStoresCreate(window, promise, stores);
-  promise.forget(aDataStores);
-  return NS_OK;
-}
-
-void
-DataStoreService::GetDataStoresCreate(nsPIDOMWindow* aWindow, Promise* aPromise,
-                                      const nsTArray<DataStoreInfo>& aStores)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (!aStores.Length()) {
-    GetDataStoresResolve(aWindow, aPromise, aStores);
-    return;
-  }
-
-  nsTArray<nsString> pendingDataStores;
-  for (uint32_t i = 0; i < aStores.Length(); ++i) {
-    if (!aStores[i].mEnabled) {
-      pendingDataStores.AppendElement(aStores[i].mManifestURL);
-    }
-  }
-
-  if (!pendingDataStores.Length()) {
-    GetDataStoresResolve(aWindow, aPromise, aStores);
-    return;
-  }
-
-  PendingRequests* requests;
-  if (!mPendingRequests.Get(aStores[0].mName, &requests)) {
-    requests = new PendingRequests();
-    mPendingRequests.Put(aStores[0].mName, requests);
-  }
-
-  PendingRequest* request = requests->AppendElement();
-  request->Init(aWindow, aPromise, aStores, pendingDataStores);
-}
-
-void
-DataStoreService::GetDataStoresResolve(nsPIDOMWindow* aWindow,
-                                       Promise* aPromise,
-                                       const nsTArray<DataStoreInfo>& aStores)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (!aStores.Length()) {
-    nsTArray<nsRefPtr<DataStore>> results;
-    aPromise->MaybeResolve(results);
-    return;
-  }
-
-  AutoSafeJSContext cx;
-
-  // The counter will finish this task once all the DataStores will know their
-  // first revision Ids.
-  nsRefPtr<RetrieveRevisionsCounter> counter =
-    new RetrieveRevisionsCounter(++gCounterID, aPromise, aStores.Length());
-  mPendingCounters.Put(gCounterID, counter);
-
-  for (uint32_t i = 0; i < aStores.Length(); ++i) {
-    nsCOMPtr<nsIDataStore> dataStore =
-      do_CreateInstance("@mozilla.org/dom/datastore;1");
-    if (NS_WARN_IF(!dataStore)) {
-      return;
-    }
-
-    nsresult rv = dataStore->Init(aWindow, aStores[i].mName,
-                                  aStores[i].mManifestURL,
-                                  aStores[i].mReadOnly);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return;
-    }
-
-    nsCOMPtr<nsIXPConnectWrappedJS> xpcwrappedjs = do_QueryInterface(dataStore);
-    if (NS_WARN_IF(!xpcwrappedjs)) {
-      return;
-    }
-
-    JS::Rooted<JSObject*> dataStoreJS(cx, xpcwrappedjs->GetJSObject());
-    if (NS_WARN_IF(!dataStoreJS)) {
-      return;
-    }
-
-    JSAutoCompartment ac(cx, dataStoreJS);
-    nsRefPtr<DataStoreImpl> dataStoreObj = new DataStoreImpl(dataStoreJS,
-                                                             aWindow);
-
-    nsRefPtr<DataStore> exposedStore = new DataStore(aWindow);
-
-    ErrorResult error;
-    exposedStore->SetDataStoreImpl(*dataStoreObj, error);
-    if (error.Failed()) {
-      return;
-    }
-
-    JS::Rooted<JSObject*> obj(cx, exposedStore->WrapObject(cx));
-    MOZ_ASSERT(obj);
-
-    JS::Rooted<JS::Value> exposedObject(cx, JS::ObjectValue(*obj));
-    dataStore->SetExposedObject(exposedObject);
-
-    counter->AppendDataStore(cx, exposedStore, dataStore);
-  }
-}
-
-// Thie method populates 'aStores' with the list of DataStores with 'aName' as
-// name and available for this 'aAppId'.
-nsresult
-DataStoreService::GetDataStoreInfos(const nsAString& aName,
-                                    uint32_t aAppId,
-                                    nsTArray<DataStoreInfo>& aStores)
-{
-  AssertIsInMainProcess();
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsCOMPtr<nsIAppsService> appsService =
-    do_GetService("@mozilla.org/AppsService;1");
-  if (NS_WARN_IF(!appsService)) {
-    return NS_ERROR_FAILURE;
-  }
-
-  nsCOMPtr<mozIApplication> app;
-  nsresult rv = appsService->GetAppByLocalId(aAppId, getter_AddRefs(app));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  if (!app) {
-    return NS_ERROR_DOM_SECURITY_ERR;
-  }
-
-  uint16_t status;
-  rv = app->GetAppStatus(&status);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  if (status != nsIPrincipal::APP_STATUS_CERTIFIED &&
-      !Preferences::GetBool("dom.testing.datastore_enabled_for_hosted_apps",
-                            false)) {
-    return NS_ERROR_DOM_SECURITY_ERR;
-  }
-
-  aStores.Clear();
-
-  HashApp* apps = nullptr;
-  if (!mStores.Get(aName, &apps)) {
-    return NS_OK;
-  }
-
-  DataStoreInfo* info = nullptr;
-  if (apps->Get(aAppId, &info)) {
-    DataStoreInfo* owned = aStores.AppendElement();
-    owned->Init(info->mName, info->mOriginURL, info->mManifestURL, false,
-                info->mEnabled);
-  }
-
-  GetDataStoreInfosData data(mAccessStores, aName, aAppId, aStores);
-  apps->EnumerateRead(GetDataStoreInfosEnumerator, &data);
-  return NS_OK;
-}
-
-// This method is called when an app with DataStores is deleted.
-void
-DataStoreService::DeleteDataStores(uint32_t aAppId)
-{
-  AssertIsInMainProcess();
-  MOZ_ASSERT(NS_IsMainThread());
-
-  mStores.Enumerate(DeleteDataStoresEnumerator, &aAppId);
-  mAccessStores.Enumerate(DeleteDataStoresEnumerator, &aAppId);
-}
-
-NS_IMETHODIMP
-DataStoreService::Observe(nsISupports* aSubject,
-                          const char* aTopic,
-                          const char16_t* aData)
-{
-  AssertIsInMainProcess();
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (strcmp(aTopic, "webapps-clear-data")) {
-    return NS_OK;
-  }
-
-  nsCOMPtr<mozIApplicationClearPrivateDataParams> params =
-    do_QueryInterface(aSubject);
-  MOZ_ASSERT(params);
-
-  // DataStore is explosed to apps, not browser content.
-  bool browserOnly;
-  nsresult rv = params->GetBrowserOnly(&browserOnly);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  if (browserOnly) {
-    return NS_OK;
-  }
-
-  uint32_t appId;
-  rv = params->GetAppId(&appId);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  DeleteDataStores(appId);
-
-  return NS_OK;
-}
-
-nsresult
-DataStoreService::AddPermissions(uint32_t aAppId,
-                                 const nsAString& aName,
-                                 const nsAString& aOriginURL,
-                                 const nsAString& aManifestURL,
-                                 bool aReadOnly)
-{
-  AssertIsInMainProcess();
-  MOZ_ASSERT(NS_IsMainThread());
-
-  // This is the permission name.
-  nsString permission;
-  GeneratePermissionName(permission, aName, aManifestURL);
-
-  // When a new DataStore is installed, the permissions must be set for the
-  // owner app.
-  nsresult rv = ResetPermission(aAppId, aOriginURL, aManifestURL, permission,
-                                aReadOnly);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  // For any app that wants to have access to this DataStore we add the
-  // permissions.
-  HashApp* apps;
-  if (!mAccessStores.Get(aName, &apps)) {
-    return NS_OK;
-  }
-
-  AddPermissionsData data(permission, aReadOnly);
-  apps->EnumerateRead(AddPermissionsEnumerator, &data);
-  return data.mResult;
-}
-
-nsresult
-DataStoreService::AddAccessPermissions(uint32_t aAppId, const nsAString& aName,
-                                       const nsAString& aOriginURL,
-                                       const nsAString& aManifestURL,
-                                       bool aReadOnly)
-{
-  AssertIsInMainProcess();
-  MOZ_ASSERT(NS_IsMainThread());
-
-  // When an app wants to have access to a DataStore, the permissions must be
-  // set.
-  HashApp* apps = nullptr;
-  if (!mStores.Get(aName, &apps)) {
-    return NS_OK;
-  }
-
-  AddAccessPermissionsData data(aName, aReadOnly);
-  apps->EnumerateRead(AddAccessPermissionsEnumerator, &data);
-  return data.mResult;
-}
-
-// This method starts the operation to create the first revision for a DataStore
-// if needed.
-nsresult
-DataStoreService::CreateFirstRevisionId(uint32_t aAppId,
-                                        const nsAString& aName,
-                                        const nsAString& aManifestURL)
-{
-  AssertIsInMainProcess();
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsRefPtr<DataStoreDB> db = new DataStoreDB(aManifestURL, aName);
-
-  nsRefPtr<FirstRevisionIdCallback> callback =
-    new FirstRevisionIdCallback(aAppId, aName, aManifestURL);
-
-  Sequence<nsString> dbs;
-  dbs.AppendElement(NS_LITERAL_STRING(DATASTOREDB_REVISION));
-
-  return db->Open(IDBTransactionMode::Readwrite, dbs, callback);
-}
-
-nsresult
-DataStoreService::EnableDataStore(uint32_t aAppId, const nsAString& aName,
-                                  const nsAString& aManifestURL)
-{
-  AssertIsInMainProcess();
-  MOZ_ASSERT(NS_IsMainThread());
-
-  {
-    HashApp* apps = nullptr;
-    DataStoreInfo* info = nullptr;
-    if (mStores.Get(aName, &apps) && apps->Get(aAppId, &info)) {
-      info->Enable();
-    }
-  }
-
-  // Notify the child processes.
-  if (IsMainProcess()) {
-    nsTArray<ContentParent*> children;
-    ContentParent::GetAll(children);
-    for (uint32_t i = 0; i < children.Length(); i++) {
-      if (children[i]->NeedsDataStoreInfos()) {
-        unused << children[i]->SendDataStoreNotify(aAppId, nsAutoString(aName),
-                                                   nsAutoString(aManifestURL));
-      }
-    }
-  }
-
-  // Maybe we have some pending request waiting for this DataStore.
-  PendingRequests* requests;
-  if (!mPendingRequests.Get(aName, &requests)) {
-    return NS_OK;
-  }
-
-  for (uint32_t i = 0; i < requests->Length();) {
-    PendingRequest& request = requests->ElementAt(i);
-    nsTArray<nsString>::index_type pos =
-      request.mPendingDataStores.IndexOf(aManifestURL);
-    if (pos != request.mPendingDataStores.NoIndex) {
-      request.mPendingDataStores.RemoveElementAt(pos);
-
-      // No other pending dataStores.
-      if (request.mPendingDataStores.IsEmpty()) {
-        GetDataStoresResolve(request.mWindow, request.mPromise,
-                             request.mStores);
-        requests->RemoveElementAt(i);
-        continue;
-      }
-    }
-
-    ++i;
-  }
-
-  // No other pending requests for this name.
-  if (requests->IsEmpty()) {
-    mPendingRequests.Remove(aName);
-  }
-
-  return NS_OK;
-}
-
-already_AddRefed<RetrieveRevisionsCounter>
-DataStoreService::GetCounter(uint32_t aId) const
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsRefPtr<RetrieveRevisionsCounter> counter;
-  return mPendingCounters.Get(aId, getter_AddRefs(counter))
-           ? counter.forget() : nullptr;
-}
-
-void
-DataStoreService::RemoveCounter(uint32_t aId)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  mPendingCounters.Remove(aId);
-}
-
-nsresult
-DataStoreService::GetDataStoresFromIPC(const nsAString& aName,
-                                       nsIPrincipal* aPrincipal,
-                                       nsTArray<DataStoreSetting>* aValue)
-{
-  MOZ_ASSERT(IsMainProcess());
-  MOZ_ASSERT(NS_IsMainThread());
-
-  uint32_t appId;
-  nsresult rv = aPrincipal->GetAppId(&appId);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  nsTArray<DataStoreInfo> stores;
-  rv = GetDataStoreInfos(aName, appId, stores);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  for (uint32_t i = 0; i < stores.Length(); ++i) {
-    DataStoreSetting* data = aValue->AppendElement();
-    data->name() = stores[i].mName;
-    data->originURL() = stores[i].mOriginURL;
-    data->manifestURL() = stores[i].mManifestURL;
-    data->readOnly() = stores[i].mReadOnly;
-    data->enabled() = stores[i].mEnabled;
-  }
-
-  return NS_OK;
-}
-
-nsresult
-DataStoreService::GenerateUUID(nsAString& aID)
-{
-  nsresult rv;
-
-  if (!mUUIDGenerator) {
-    mUUIDGenerator = do_GetService("@mozilla.org/uuid-generator;1", &rv);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-  }
-
-  nsID id;
-  rv = mUUIDGenerator->GenerateUUIDInPlace(&id);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  char chars[NSID_LENGTH];
-  id.ToProvidedString(chars);
-  CopyASCIItoUTF16(chars, aID);
-
-  return NS_OK;
-}
-
-} // namespace dom
-} // namespace mozilla
deleted file mode 100644
--- a/dom/datastore/DataStoreService.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/* -*- 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 "mozilla/dom/PContent.h"
-#include "nsClassHashtable.h"
-#include "nsIDataStoreService.h"
-#include "nsIObserver.h"
-#include "nsRefPtrHashtable.h"
-
-class nsIPrincipal;
-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 ContentChild;
-  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);
-
-  nsresult GetDataStoresFromIPC(const nsAString& aName,
-                                nsIPrincipal* aPrincipal,
-                                nsTArray<DataStoreSetting>* aValue);
-
-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
new file mode 100644
--- /dev/null
+++ b/dom/datastore/DataStoreService.js
@@ -0,0 +1,522 @@
+/* -*- 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/DataStoreImpl.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 = new DataStore(aWindow, aStores[i].name,
+                              aStores[i].owner, aStores[i].readOnly);
+
+      let storeImpl = aWindow.DataStoreImpl._create(aWindow, obj);
+
+      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]);
new file mode 100644
--- /dev/null
+++ b/dom/datastore/DataStoreServiceInternal.jsm
@@ -0,0 +1,68 @@
+/* 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"
+
+const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+
+this.EXPORTED_SYMBOLS = ["DataStoreServiceInternal"];
+
+function debug(s) {
+  //dump('DEBUG DataStoreServiceInternal: ' + s + '\n');
+}
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+
+XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
+                                   "@mozilla.org/parentprocessmessagemanager;1",
+                                   "nsIMessageBroadcaster");
+
+XPCOMUtils.defineLazyServiceGetter(this, "dataStoreService",
+                                   "@mozilla.org/datastore-service;1",
+                                   "nsIDataStoreService");
+
+this.DataStoreServiceInternal = {
+  init: function() {
+    debug("init");
+
+    let inParent = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime)
+                      .processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
+    if (inParent) {
+      ppmm.addMessageListener("DataStore:Get", this);
+    }
+  },
+
+  receiveMessage: function(aMessage) {
+    debug("receiveMessage");
+
+    if (aMessage.name != 'DataStore:Get') {
+      return;
+    }
+
+    let prefName = 'dom.testing.datastore_enabled_for_hosted_apps';
+    if ((Services.prefs.getPrefType(prefName) == Services.prefs.PREF_INVALID ||
+         !Services.prefs.getBoolPref(prefName)) &&
+        !aMessage.target.assertAppHasStatus(Ci.nsIPrincipal.APP_STATUS_CERTIFIED)) {
+      return;
+    }
+
+    let msg = aMessage.data;
+
+    if (!aMessage.principal ||
+        aMessage.principal.appId == Ci.nsIScriptSecurityManager.UNKNOWN_APP_ID) {
+      aMessage.target.sendAsyncMessage("DataStore:Get:Return:KO");
+      return;
+    }
+
+    msg.stores = dataStoreService.getDataStoresInfo(msg.name, aMessage.principal.appId);
+    if (msg.stores === null) {
+      aMessage.target.sendAsyncMessage("DataStore:Get:Return:KO");
+      return;
+    }
+    aMessage.target.sendAsyncMessage("DataStore:Get:Return:OK", msg);
+  }
+}
+
+DataStoreServiceInternal.init();
--- a/dom/datastore/moz.build
+++ b/dom/datastore/moz.build
@@ -1,48 +1,42 @@
 # -*- Mode: python; c-basic-offset: 4; 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 += [
-    'nsIDataStore.idl',
     'nsIDataStoreService.idl',
 ]
 
 XPIDL_MODULE = 'dom_datastore'
 
 EXPORTS.mozilla.dom += [
     'DataStore.h',
     'DataStoreCursor.h',
-    'DataStoreService.h',
 ]
 
 SOURCES += [
     'DataStore.cpp',
     'DataStoreCursor.cpp',
-    'DataStoreDB.cpp',
-    'DataStoreRevision.cpp',
-    'DataStoreService.cpp',
 ]
 
 LOCAL_INCLUDES += [
     '/js/xpconnect/wrappers',
 ]
 
 EXTRA_COMPONENTS += [
     'DataStore.manifest',
-    'DataStoreImpl.js',
+    'DataStoreService.js',
 ]
 
 EXTRA_JS_MODULES += [
     'DataStoreChangeNotifier.jsm',
     'DataStoreCursorImpl.jsm',
     'DataStoreDB.jsm',
+    'DataStoreImpl.jsm',
+    'DataStoreServiceInternal.jsm',
 ]
 
 MOCHITEST_MANIFESTS += ['tests/mochitest.ini']
 
-include('/ipc/chromium/chromium-config.mozbuild')
-
 FINAL_LIBRARY = 'xul'
-FAIL_ON_WARNINGS = True
deleted file mode 100644
--- a/dom/datastore/nsIDataStore.idl
+++ /dev/null
@@ -1,23 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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 nsIDOMWindow;
-
-// NOTE: This is a temporary interface.
-// It will be removed in the next patches for rewriting DataStore in C++.
-[scriptable, uuid(0b41fef5-14ba-48b0-923c-3d8fb64692ae)]
-interface nsIDataStore : nsISupports
-{
-  void init(in nsIDOMWindow window,
-            in DOMString name,
-            in DOMString manifestURL,
-            in boolean readOnly);
-
-  attribute jsval exposedObject;
-
-  void retrieveRevisionId(in jsval cb);
-};
--- a/dom/datastore/nsIDataStoreService.idl
+++ b/dom/datastore/nsIDataStoreService.idl
@@ -2,26 +2,34 @@
 /* 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 nsIDOMWindow;
 
-[scriptable, uuid(0a050c4f-d292-4a14-8712-09bc1019840a)]
+[scriptable, uuid(bd02d09c-41ab-47b7-9319-57aa8e5059b0)]
 interface nsIDataStoreService : nsISupports
 {
   void installDataStore(in unsigned long appId,
                         in DOMString name,
                         in DOMString originURL,
                         in DOMString manifestURL,
                         in boolean readOnly);
 
   void installAccessDataStore(in unsigned long appId,
                               in DOMString name,
                               in DOMString originURL,
                               in DOMString manifestURL,
                               in boolean readOnly);
 
   nsISupports getDataStores(in nsIDOMWindow window,
                             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);
 };
--- a/dom/indexedDB/IDBFactory.cpp
+++ b/dom/indexedDB/IDBFactory.cpp
@@ -230,16 +230,19 @@ IDBFactory::Create(JSContext* aCx,
 // static
 nsresult
 IDBFactory::Create(ContentParent* aContentParent,
                    IDBFactory** aFactory)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
   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
   // IsCallerChrome() assertion in quota manager.
   nsCString group;
   nsCString origin;
   StoragePrivilege privilege;
   PersistenceType defaultPersistenceType;
   QuotaManager::GetInfoForChrome(&group, &origin, &privilege,
--- a/dom/indexedDB/IDBFactory.h
+++ b/dom/indexedDB/IDBFactory.h
@@ -70,17 +70,17 @@ public:
   // Called when using IndexedDB from a JS component or a JSM in the current
   // process.
   static nsresult Create(JSContext* aCx,
                          JS::Handle<JSObject*> aOwningObject,
                          ContentParent* aContentParent,
                          IDBFactory** aFactory);
 
   // Called when using IndexedDB from a JS component or a JSM in a different
-  // process or from a C++ component.
+  // process.
   static nsresult Create(ContentParent* aContentParent,
                          IDBFactory** aFactory);
 
   static already_AddRefed<nsIFileURL>
   GetDatabaseFileURL(nsIFile* aDatabaseFile,
                      PersistenceType aPersistenceType,
                      const nsACString& aGroup,
                      const nsACString& aOrigin);
--- a/dom/indexedDB/IDBRequest.cpp
+++ b/dom/indexedDB/IDBRequest.cpp
@@ -322,17 +322,17 @@ IDBRequest::ReadyState() const
 
 JSObject*
 IDBRequest::WrapObject(JSContext* aCx)
 {
   return IDBRequestBinding::Wrap(aCx, this);
 }
 
 JS::Value
-IDBRequest::GetResult(mozilla::ErrorResult& aRv) const
+IDBRequest::GetResult(JSContext* aCx, mozilla::ErrorResult& aRv) const
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (!mHaveResultOrErrorCode) {
     // XXX Need a real error code here.
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
   }
 
--- a/dom/indexedDB/IDBRequest.h
+++ b/dom/indexedDB/IDBRequest.h
@@ -127,23 +127,17 @@ public:
   // WebIDL
   nsPIDOMWindow*
   GetParentObject() const
   {
     return GetOwner();
   }
 
   JS::Value
-  GetResult(ErrorResult& aRv) const;
-
-  JS::Value
-  GetResult(JSContext* aCx, ErrorResult& aRv) const
-  {
-    return GetResult(aRv);
-  }
+  GetResult(JSContext* aCx, ErrorResult& aRv) const;
 
   IDBTransaction*
   GetTransaction() const
   {
     NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
     return mTransaction;
   }
 
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -137,17 +137,16 @@
 #include "ProcessUtils.h"
 #include "StructuredCloneUtils.h"
 #include "URIUtils.h"
 #include "nsContentUtils.h"
 #include "nsIPrincipal.h"
 #include "nsDeviceStorage.h"
 #include "AudioChannelService.h"
 #include "JavaScriptChild.h"
-#include "mozilla/dom/DataStoreService.h"
 #include "mozilla/dom/telephony/PTelephonyChild.h"
 #include "mozilla/dom/time/DateCacheCleaner.h"
 #include "mozilla/net/NeckoMessageUtils.h"
 
 using namespace base;
 using namespace mozilla;
 using namespace mozilla::docshell;
 using namespace mozilla::dom::bluetooth;
@@ -765,34 +764,16 @@ ContentChild::RecvAudioChannelNotify()
         AudioChannelService::GetAudioChannelService();
     if (service) {
         service->Notify();
     }
     return true;
 }
 
 bool
-ContentChild::RecvDataStoreNotify(const uint32_t& aAppId,
-                                  const nsString& aName,
-                                  const nsString& aManifestURL)
-{
-  nsRefPtr<DataStoreService> service = DataStoreService::GetOrCreate();
-  if (NS_WARN_IF(!service)) {
-    return false;
-  }
-
-  nsresult rv = service->EnableDataStore(aAppId, aName, aManifestURL);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return false;
-  }
-
-  return true;
-}
-
-bool
 ContentChild::DeallocPMemoryReportRequestChild(PMemoryReportRequestChild* actor)
 {
     static_cast<MemoryReportRequestChild*>(actor)->Release();
     return true;
 }
 
 PCycleCollectWithLogsChild*
 ContentChild::AllocPCycleCollectWithLogsChild(const bool& aDumpAllTraces,
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -152,20 +152,16 @@ public:
     RecvPCycleCollectWithLogsConstructor(PCycleCollectWithLogsChild* aChild,
                                          const bool& aDumpAllTraces,
                                          const FileDescriptor& aGCLog,
                                          const FileDescriptor& aCCLog) MOZ_OVERRIDE;
 
     virtual bool
     RecvAudioChannelNotify() MOZ_OVERRIDE;
 
-    virtual bool
-    RecvDataStoreNotify(const uint32_t& aAppId, const nsString& aName,
-                        const nsString& aManifestURL) MOZ_OVERRIDE;
-
     virtual PTestShellChild* AllocPTestShellChild() MOZ_OVERRIDE;
     virtual bool DeallocPTestShellChild(PTestShellChild*) MOZ_OVERRIDE;
     virtual bool RecvPTestShellConstructor(PTestShellChild*) MOZ_OVERRIDE;
     jsipc::JavaScriptChild *GetCPOWManager();
 
     virtual PNeckoChild* AllocPNeckoChild() MOZ_OVERRIDE;
     virtual bool DeallocPNeckoChild(PNeckoChild*) MOZ_OVERRIDE;
 
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -28,17 +28,16 @@
 #include "IHistory.h"
 #include "IDBFactory.h"
 #include "IndexedDBParent.h"
 #include "IndexedDatabaseManager.h"
 #include "mozIApplication.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/dom/asmjscache/AsmJSCache.h"
 #include "mozilla/dom/Element.h"
-#include "mozilla/dom/DataStoreService.h"
 #include "mozilla/dom/ExternalHelperAppParent.h"
 #include "mozilla/dom/PFileDescriptorSetParent.h"
 #include "mozilla/dom/PCycleCollectWithLogsParent.h"
 #include "mozilla/dom/PMemoryReportRequestParent.h"
 #include "mozilla/dom/power/PowerManagerService.h"
 #include "mozilla/dom/DOMStorageIPC.h"
 #include "mozilla/dom/bluetooth/PBluetoothParent.h"
 #include "mozilla/dom/PFMRadioParent.h"
@@ -1491,17 +1490,16 @@ ContentParent::InitializeMembers()
 {
     mSubprocess = nullptr;
     mChildID = gContentChildID++;
     mGeolocationWatchID = -1;
     mForceKillTask = nullptr;
     mNumDestroyingTabs = 0;
     mIsAlive = true;
     mSendPermissionUpdates = false;
-    mSendDataStoreInfos = false;
     mCalledClose = false;
     mCalledCloseWithError = false;
     mCalledKillHard = false;
 }
 
 ContentParent::ContentParent(mozIApplication* aApp,
                              bool aIsForBrowser,
                              bool aIsForPreallocated,
@@ -2074,36 +2072,16 @@ ContentParent::RecvAudioChannelChangeDef
     if (service) {
        service->SetDefaultVolumeControlChannelInternal(aChannel,
                                                        aHidden, mChildID);
     }
     return true;
 }
 
 bool
-ContentParent::RecvDataStoreGetStores(
-                                    const nsString& aName,
-                                    const IPC::Principal& aPrincipal,
-                                    InfallibleTArray<DataStoreSetting>* aValue)
-{
-  nsRefPtr<DataStoreService> service = DataStoreService::GetOrCreate();
-  if (NS_WARN_IF(!service)) {
-    return false;
-  }
-
-  nsresult rv = service->GetDataStoresFromIPC(aName, aPrincipal, aValue);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return false;
-  }
-
-  mSendDataStoreInfos = true;
-  return true;
-}
-
-bool
 ContentParent::RecvBroadcastVolume(const nsString& aVolumeName)
 {
 #ifdef MOZ_WIDGET_GONK
     nsresult rv;
     nsCOMPtr<nsIVolumeService> vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID, &rv);
     if (vs) {
         vs->BroadcastVolume(aVolumeName);
     }
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -155,24 +155,20 @@ public:
 #endif
 
     GeckoChildProcessHost* Process() {
         return mSubprocess;
     }
 
     int32_t Pid();
 
-    bool NeedsPermissionsUpdate() const {
+    bool NeedsPermissionsUpdate() {
         return mSendPermissionUpdates;
     }
 
-    bool NeedsDataStoreInfos() const {
-        return mSendDataStoreInfos;
-    }
-
     BlobParent* GetOrCreateActorForBlob(nsIDOMBlob* aBlob);
 
     /**
      * Kill our subprocess and make sure it dies.  Should only be used
      * in emergency situations since it bypasses the normal shutdown
      * process.
      */
     void KillHard();
@@ -525,21 +521,16 @@ private:
 
     virtual bool RecvAudioChannelChangedNotification() MOZ_OVERRIDE;
 
     virtual bool RecvAudioChannelChangeDefVolChannel(const int32_t& aChannel,
                                                      const bool& aHidden) MOZ_OVERRIDE;
     virtual bool RecvGetSystemMemory(const uint64_t& getterId) MOZ_OVERRIDE;
     virtual bool RecvBroadcastVolume(const nsString& aVolumeName) MOZ_OVERRIDE;
 
-    virtual bool RecvDataStoreGetStores(
-                       const nsString& aName,
-                       const IPC::Principal& aPrincipal,
-                       InfallibleTArray<DataStoreSetting>* aValue) MOZ_OVERRIDE;
-
     virtual bool RecvSpeakerManagerGetSpeakerStatus(bool* aValue) MOZ_OVERRIDE;
 
     virtual bool RecvSpeakerManagerForceSpeaker(const bool& aEnable) MOZ_OVERRIDE;
 
     virtual bool RecvSystemMessageHandled() MOZ_OVERRIDE;
 
     virtual bool RecvNuwaReady() MOZ_OVERRIDE;
 
@@ -604,17 +595,16 @@ private:
     int32_t mNumDestroyingTabs;
     // True only while this is ready to be used to host remote tabs.
     // This must not be used for new purposes after mIsAlive goes to
     // false, but some previously scheduled IPC traffic may still pass
     // through.
     bool mIsAlive;
 
     bool mSendPermissionUpdates;
-    bool mSendDataStoreInfos;
     bool mIsForBrowser;
     bool mIsNuwaProcess;
 
     // These variables track whether we've called Close(), CloseWithError()
     // and KillHard() on our channel.
     bool mCalledClose;
     bool mCalledCloseWithError;
     bool mCalledKillHard;
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -257,24 +257,16 @@ union MaybePrefValue {
 };
 
 struct PrefSetting {
   nsCString name;
   MaybePrefValue defaultValue;
   MaybePrefValue userValue;
 };
 
-struct DataStoreSetting {
-  nsString name;
-  nsString originURL;
-  nsString manifestURL;
-  bool readOnly;
-  bool enabled;
-};
-
 intr protocol PContent
 {
     parent opens PCompositor;
     parent opens PSharedBufferManager;
     parent opens PImageBridge;
     child opens PBackground;
 
     manages PAsmJSCacheEntry;
@@ -341,19 +333,16 @@ child:
 
     /**
      * Notify the AudioChannelService in the child processes.
      */
     async AudioChannelNotify();
 
     async SpeakerManagerNotify();
 
-    async DataStoreNotify(uint32_t aAppId, nsString aName,
-                          nsString aManifestURL);
-
     /**
      * Dump this process's GC and CC logs to the provided files.
      *
      * For documentation on the other args, see dumpGCAndCCLogsToFile in
      * nsIMemoryInfoDumper.idl
      */
     PCycleCollectWithLogs(bool dumpAllTraces,
                           FileDescriptor gcLog,
@@ -556,19 +545,16 @@ parent:
     sync AudioChannelRegisterType(AudioChannel aChannel, bool aWithVideo);
     sync AudioChannelUnregisterType(AudioChannel aChannel,
                                     bool aElementHidden,
                                     bool aWithVideo);
 
     async AudioChannelChangedNotification();
     async AudioChannelChangeDefVolChannel(int32_t aChannel, bool aHidden);
 
-    sync DataStoreGetStores(nsString aName, Principal aPrincipal)
-        returns (DataStoreSetting[] dataStores);
-
     async FilePathUpdateNotify(nsString aType,
                                nsString aStorageName,
                                nsString aFilepath,
                                nsCString aReason);
     // get nsIVolumeService to broadcast volume information
     async BroadcastVolume(nsString volumeName);
 
     // Notify the parent that the child has finished handling a system message.
--- a/dom/webidl/DataStore.webidl
+++ b/dom/webidl/DataStore.webidl
@@ -103,15 +103,8 @@ dictionary DataStoreTask {
   DOMString revisionId;
 
   DataStoreOperation operation;
 
   // When |operation| is "clear" or "done", this must return null.
   DataStoreKey? id;
   any data;
 };
-
-// For internal use.
-dictionary DataStoreRevisionData {
-  DOMString revisionId = "";
-  unsigned long objectId = 0;
-  DOMString operation = "";
-};
--- a/layout/build/nsLayoutModule.cpp
+++ b/layout/build/nsLayoutModule.cpp
@@ -224,18 +224,16 @@ static void Shutdown();
 #include "mozilla/dom/mobilemessage/SmsServicesFactory.h"
 #include "nsIPowerManagerService.h"
 #include "nsIAlarmHalService.h"
 #include "nsIMediaManager.h"
 #include "nsMixedContentBlocker.h"
 
 #include "AudioChannelService.h"
 
-#include "mozilla/dom/DataStoreService.h"
-
 #include "mozilla/dom/power/PowerManagerService.h"
 #include "mozilla/dom/alarm/AlarmHalService.h"
 #include "mozilla/dom/time/TimeService.h"
 #include "StreamingProtocolService.h"
 
 #include "mozilla/dom/telephony/TelephonyFactory.h"
 #include "nsITelephonyProvider.h"
 
@@ -581,25 +579,20 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsDOMScri
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(Geolocation, Init)
 
 #define NS_GEOLOCATION_SERVICE_CID \
   { 0x404d02a, 0x1CA, 0xAAAB, { 0x47, 0x62, 0x94, 0x4b, 0x1b, 0xf2, 0xf7, 0xb5 } }
 
 #define NS_AUDIOCHANNEL_SERVICE_CID \
   { 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(AudioChannelService, AudioChannelService::GetAudioChannelService)
 
-NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(DataStoreService, DataStoreService::GetOrCreate)
-
 #ifdef MOZ_WEBSPEECH
 NS_GENERIC_FACTORY_CONSTRUCTOR(FakeSpeechRecognitionService)
 #endif
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsCSPContext)
 NS_GENERIC_FACTORY_CONSTRUCTOR(CSPService)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsMixedContentBlocker)
 
@@ -739,17 +732,16 @@ NS_DEFINE_NAMED_CID(NS_HTMLEDITOR_CID);
 NS_DEFINE_NAMED_CID(NS_EDITORCONTROLLER_CID);
 NS_DEFINE_NAMED_CID(NS_EDITINGCONTROLLER_CID);
 NS_DEFINE_NAMED_CID(NS_EDITORCOMMANDTABLE_CID);
 NS_DEFINE_NAMED_CID(NS_EDITINGCOMMANDTABLE_CID);
 NS_DEFINE_NAMED_CID(NS_TEXTSERVICESDOCUMENT_CID);
 NS_DEFINE_NAMED_CID(NS_GEOLOCATION_SERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_GEOLOCATION_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(CSPSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_CSPCONTEXT_CID);
 NS_DEFINE_NAMED_CID(NS_MIXEDCONTENTBLOCKER_CID);
 NS_DEFINE_NAMED_CID(NS_EVENTLISTENERSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_GLOBALMESSAGEMANAGER_CID);
 NS_DEFINE_NAMED_CID(NS_PARENTPROCESSMESSAGEMANAGER_CID);
 NS_DEFINE_NAMED_CID(NS_CHILDPROCESSMESSAGEMANAGER_CID);
@@ -1028,17 +1020,16 @@ static const mozilla::Module::CIDEntry k
   { &kNS_EDITORCONTROLLER_CID, false, nullptr, nsEditorControllerConstructor },
   { &kNS_EDITINGCONTROLLER_CID, false, nullptr, nsEditingControllerConstructor },
   { &kNS_EDITORCOMMANDTABLE_CID, false, nullptr, nsEditorCommandTableConstructor },
   { &kNS_EDITINGCOMMANDTABLE_CID, false, nullptr, nsEditingCommandTableConstructor },
   { &kNS_TEXTSERVICESDOCUMENT_CID, false, nullptr, nsTextServicesDocumentConstructor },
   { &kNS_GEOLOCATION_SERVICE_CID, false, nullptr, nsGeolocationServiceConstructor },
   { &kNS_GEOLOCATION_CID, false, nullptr, GeolocationConstructor },
   { &kNS_AUDIOCHANNEL_SERVICE_CID, false, nullptr, AudioChannelServiceConstructor },
-  { &kNS_DATASTORE_SERVICE_CID, false, nullptr, DataStoreServiceConstructor },
   { &kNS_FOCUSMANAGER_CID, false, nullptr, CreateFocusManager },
 #ifdef MOZ_WEBSPEECH
   { &kNS_FAKE_SPEECH_RECOGNITION_SERVICE_CID, false, nullptr, FakeSpeechRecognitionServiceConstructor },
   { &kNS_SYNTHVOICEREGISTRY_CID, true, nullptr, nsSynthVoiceRegistryConstructor },
 #endif
   { &kCSPSERVICE_CID, false, nullptr, CSPServiceConstructor },
   { &kNS_CSPCONTEXT_CID, false, nullptr, nsCSPContextConstructor },
   { &kNS_MIXEDCONTENTBLOCKER_CID, false, nullptr, nsMixedContentBlockerConstructor },
@@ -1184,17 +1175,16 @@ static const mozilla::Module::ContractID
   { NS_AUDIOCHANNELAGENT_CONTRACTID, &kNS_AUDIOCHANNELAGENT_CID },
   { "@mozilla.org/editor/htmleditor;1", &kNS_HTMLEDITOR_CID },
   { "@mozilla.org/editor/editorcontroller;1", &kNS_EDITORCONTROLLER_CID },
   { "@mozilla.org/editor/editingcontroller;1", &kNS_EDITINGCONTROLLER_CID },
   { "@mozilla.org/textservices/textservicesdocument;1", &kNS_TEXTSERVICESDOCUMENT_CID },
   { "@mozilla.org/geolocation/service;1", &kNS_GEOLOCATION_SERVICE_CID },
   { "@mozilla.org/geolocation;1", &kNS_GEOLOCATION_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 },
 #ifdef MOZ_WEBSPEECH
   { NS_SPEECH_RECOGNITION_SERVICE_CONTRACTID_PREFIX "fake", &kNS_FAKE_SPEECH_RECOGNITION_SERVICE_CID },
   { NS_SYNTHVOICEREGISTRY_CONTRACTID, &kNS_SYNTHVOICEREGISTRY_CID },
 #endif
   { CSPSERVICE_CONTRACTID, &kCSPSERVICE_CID },
   { NS_CSPCONTEXT_CONTRACTID, &kNS_CSPCONTEXT_CID },
   { NS_MIXEDCONTENTBLOCKER_CONTRACTID, &kNS_MIXEDCONTENTBLOCKER_CID },
--- a/layout/build/nsLayoutStatics.cpp
+++ b/layout/build/nsLayoutStatics.cpp
@@ -60,17 +60,16 @@
 #include "nsMathMLOperators.h"
 #include "Navigator.h"
 #include "DOMStorageObserver.h"
 #include "CacheObserver.h"
 #include "DisplayItemClip.h"
 #include "ActiveLayerTracker.h"
 
 #include "AudioChannelService.h"
-#include "mozilla/dom/DataStoreService.h"
 
 #ifdef MOZ_XUL
 #include "nsXULPopupManager.h"
 #include "nsXULContentUtils.h"
 #include "nsXULPrototypeCache.h"
 #include "nsXULTooltipListener.h"
 
 #include "inDOMView.h"
@@ -407,18 +406,16 @@ nsLayoutStatics::Shutdown()
 
   nsLayoutUtils::Shutdown();
 
   nsHyphenationManager::Shutdown();
   nsDOMMutationObserver::Shutdown();
 
   AudioChannelService::Shutdown();
 
-  DataStoreService::Shutdown();
-
   ContentParent::ShutDown();
 
   nsRefreshDriver::Shutdown();
 
   DisplayItemClip::Shutdown();
 
   nsDocument::XPCOMShutdown();
 
--- a/mobile/android/installer/package-manifest.in
+++ b/mobile/android/installer/package-manifest.in
@@ -619,10 +619,10 @@ bin/components/@DLL_PREFIX@nkgnomevfs@DL
 @BINPATH@/components/marionettecomponent.js
 #endif
 
 #ifdef MOZ_ANDROID_SYNTHAPKS
 @BINPATH@/components/WebappsUpdateTimer.js
 #endif
 
 @BINPATH@/components/DataStore.manifest
-@BINPATH@/components/DataStoreImpl.js
+@BINPATH@/components/DataStoreService.js
 @BINPATH@/components/dom_datastore.xpt