Backed out 3 changesets (bug 957086) for causing bug 1018406
authorEhsan Akhgari <ehsan@mozilla.com>
Mon, 02 Jun 2014 10:19:19 -0400
changeset 205310 6a984e21c2ca17cc65aac6077e45cf0c99ea51fe
parent 205309 56f9b7162d7c21891b27bb9fdb627474903a3dda
child 205317 49c1bc3e92364e388e506761b33b4bddfd43a877
child 205350 c6c1b82b2383a84b443c778386efe210100fc6cb
child 205387 c4370f7c4472138aa792072ba398be538f3e720e
push id3741
push userasasaki@mozilla.com
push dateMon, 21 Jul 2014 20:25:18 +0000
treeherdermozilla-beta@4d6f46f5af68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs957086, 1018406
milestone32.0a1
backs outf8b6dab2f985fc235ea07807e190c5fa208f8a79
b69bcaa24ab50e6d671b6215b0ab19bd80237052
3b45335d46948dbb6007d21b4837fc841b72dacf
first release with
nightly linux32
6a984e21c2ca / 32.0a1 / 20140602072051 / files
nightly linux64
6a984e21c2ca / 32.0a1 / 20140602072051 / files
nightly mac
6a984e21c2ca / 32.0a1 / 20140602072051 / files
nightly win32
6a984e21c2ca / 32.0a1 / 20140602072051 / files
nightly win64
6a984e21c2ca / 32.0a1 / 20140602072051 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out 3 changesets (bug 957086) for causing bug 1018406 Backed out changeset f8b6dab2f985 (bug 957086) Backed out changeset b69bcaa24ab5 (bug 957086) Backed out changeset 3b45335d4694 (bug 957086)
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
@@ -805,17 +805,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
@@ -852,17 +852,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,1347 +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)
-{
-  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"
@@ -1500,17 +1499,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,
@@ -2083,36 +2081,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
@@ -157,24 +157,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();
@@ -531,21 +527,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;
 
@@ -610,17 +601,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
@@ -225,18 +225,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"
 
@@ -586,25 +584,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)
 
@@ -744,17 +737,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);
@@ -1033,17 +1025,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 },
@@ -1189,17 +1180,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