Bug 957086 - patch 3 - DataStoreService in C++ OOP, r=janv

This commit is contained in:
Andrea Marchesini 2014-05-29 16:35:03 +01:00
Родитель 28ba788770
Коммит cc10beffc2
12 изменённых файлов: 198 добавлений и 123 удалений

Просмотреть файл

@ -12,9 +12,6 @@ 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");

Просмотреть файл

@ -144,7 +144,7 @@ DataStoreDB::UpgradeSchema()
}
{
IDBObjectStoreParameters params;
RootedDictionary<IDBObjectStoreParameters> params(cx);
params.Init(NS_LITERAL_STRING("{ \"autoIncrement\": true }"));
nsRefPtr<IDBObjectStore> store =
database->CreateObjectStore(cx, NS_LITERAL_STRING(DATASTOREDB_NAME),
@ -157,7 +157,7 @@ DataStoreDB::UpgradeSchema()
nsRefPtr<IDBObjectStore> store;
{
IDBObjectStoreParameters params;
RootedDictionary<IDBObjectStoreParameters> params(cx);
params.Init(NS_LITERAL_STRING("{ \"autoIncrement\": true, \"keyPath\": \"internalRevisionId\" }"));
store =
@ -169,7 +169,7 @@ DataStoreDB::UpgradeSchema()
}
{
IDBIndexParameters params;
RootedDictionary<IDBIndexParameters> params(cx);
params.Init(NS_LITERAL_STRING("{ \"unique\": true }"));
nsRefPtr<IDBIndex> index =
store->CreateIndex(cx, NS_LITERAL_STRING(DATASTOREDB_REVISION_INDEX),

Просмотреть файл

@ -7,10 +7,10 @@
#ifndef mozilla_dom_DataStoreRevision_h
#define mozilla_dom_DataStoreRevision_h
#include "nsIDOMEventListener.h"
#include "nsAutoPtr.h"
#include "nsString.h"
#include "jsapi.h"
#include "nsAutoPtr.h"
#include "nsIDOMEventListener.h"
#include "nsString.h"
namespace mozilla {
namespace dom {

Просмотреть файл

@ -10,17 +10,21 @@
#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/Promise.h"
#include "mozilla/dom/indexedDB/IDBCursor.h"
#include "mozilla/dom/indexedDB/IDBObjectStore.h"
#include "mozilla/dom/DataStoreBinding.h"
#include "mozilla/dom/DataStoreImplBinding.h"
#include "mozilla/dom/PermissionMessageUtils.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/unused.h"
#include "mozIApplication.h"
#include "mozIApplicationClearPrivateDataParams.h"
@ -44,7 +48,7 @@
#define ASSERT_PARENT_PROCESS() \
AssertIsInMainProcess(); \
if (NS_WARN_IF(XRE_GetProcessType() != GeckoProcessType_Default)) { \
if (NS_WARN_IF(!IsMainProcess())) { \
return NS_ERROR_FAILURE; \
}
@ -57,17 +61,32 @@ using namespace indexedDB;
class DataStoreInfo
{
public:
DataStoreInfo()
: mReadOnly(true)
, mEnabled(false)
{}
DataStoreInfo(const nsAString& aName,
const nsAString& aOriginURL,
const nsAString& aManifestURL,
bool aReadOnly,
bool aEnabled)
: mName(aName)
, mOriginURL(aOriginURL)
, mManifestURL(aManifestURL)
, mReadOnly(aReadOnly)
, mEnabled(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,
@ -341,10 +360,10 @@ GetDataStoreInfosEnumerator(const uint32_t& aAppId,
}
bool readOnly = aInfo->mReadOnly || accessInfo->mReadOnly;
DataStoreInfo accessStore(aInfo->mName, aInfo->mOriginURL,
aInfo->mManifestURL, readOnly,
aInfo->mEnabled);
data->mStores.AppendElement(accessStore);
DataStoreInfo* accessStore = data->mStores.AppendElement();
accessStore->Init(aInfo->mName, aInfo->mOriginURL,
aInfo->mManifestURL, readOnly,
aInfo->mEnabled);
return PL_DHASH_NEXT;
}
@ -428,15 +447,14 @@ AddAccessPermissionsEnumerator(const uint32_t& aAppId,
class PendingRequest
{
public:
PendingRequest(nsPIDOMWindow* aWindow,
Promise* aPromise,
const nsTArray<DataStoreInfo>& aStores,
const nsTArray<nsString>& aPendingDataStores)
: mWindow(aWindow)
, mPromise(aPromise)
, mStores(aStores)
, mPendingDataStores(aPendingDataStores)
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;
@ -856,15 +874,17 @@ DataStoreService::GetDataStores(nsIDOMWindow* aWindow,
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()) {
nsCOMPtr<nsIDocument> document = window->GetDoc();
MOZ_ASSERT(document);
nsCOMPtr<nsIPrincipal> principal = document->NodePrincipal();
MOZ_ASSERT(principal);
uint32_t appId;
nsresult rv = principal->GetAppId(&appId);
if (NS_FAILED(rv)) {
@ -873,25 +893,37 @@ DataStoreService::GetDataStores(nsIDOMWindow* aWindow,
return NS_OK;
}
nsTArray<DataStoreInfo> stores;
rv = GetDataStoreInfos(aName, appId, stores);
if (NS_FAILED(rv)) {
RejectPromise(window, promise, rv);
promise.forget(aDataStores);
return NS_OK;
}
GetDataStoresCreate(window, promise, stores);
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.
// TODO
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;
}
@ -900,7 +932,6 @@ void
DataStoreService::GetDataStoresCreate(nsPIDOMWindow* aWindow, Promise* aPromise,
const nsTArray<DataStoreInfo>& aStores)
{
AssertIsInMainProcess();
MOZ_ASSERT(NS_IsMainThread());
if (!aStores.Length()) {
@ -926,8 +957,8 @@ DataStoreService::GetDataStoresCreate(nsPIDOMWindow* aWindow, Promise* aPromise,
mPendingRequests.Put(aStores[0].mName, requests);
}
PendingRequest request(aWindow, aPromise, aStores, pendingDataStores);
requests->AppendElement(request);
PendingRequest* request = requests->AppendElement();
request->Init(aWindow, aPromise, aStores, pendingDataStores);
}
void
@ -935,7 +966,6 @@ DataStoreService::GetDataStoresResolve(nsPIDOMWindow* aWindow,
Promise* aPromise,
const nsTArray<DataStoreInfo>& aStores)
{
AssertIsInMainProcess();
MOZ_ASSERT(NS_IsMainThread());
if (!aStores.Length()) {
@ -1045,9 +1075,9 @@ DataStoreService::GetDataStoreInfos(const nsAString& aName,
DataStoreInfo* info = nullptr;
if (apps->Get(aAppId, &info)) {
DataStoreInfo owned(info->mName, info->mOriginURL, info->mManifestURL,
false, info->mEnabled);
aStores.AppendElement(owned);
DataStoreInfo* owned = aStores.AppendElement();
owned->Init(info->mName, info->mOriginURL, info->mManifestURL, false,
info->mEnabled);
}
GetDataStoreInfosData data(mAccessStores, aName, aAppId, aStores);
@ -1195,6 +1225,18 @@ DataStoreService::EnableDataStore(uint32_t aAppId, const nsAString& aName,
}
}
// 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)) {
@ -1231,7 +1273,6 @@ DataStoreService::EnableDataStore(uint32_t aAppId, const nsAString& aName,
already_AddRefed<RetrieveRevisionsCounter>
DataStoreService::GetCounter(uint32_t aId) const
{
AssertIsInMainProcess();
MOZ_ASSERT(NS_IsMainThread());
nsRefPtr<RetrieveRevisionsCounter> counter;
@ -1242,10 +1283,40 @@ DataStoreService::GetCounter(uint32_t aId) const
void
DataStoreService::RemoveCounter(uint32_t aId)
{
AssertIsInMainProcess();
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());
mPendingCounters.Remove(aId);
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

Просмотреть файл

@ -7,11 +7,13 @@
#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;
@ -28,6 +30,7 @@ class RevisionAddedEnableStoreCallback;
class DataStoreService MOZ_FINAL : public nsIDataStoreService
, public nsIObserver
{
friend class ContentChild;
friend class FirstRevisionIdCallback;
friend class RetrieveRevisionsCounter;
friend class RevisionAddedEnableStoreCallback;
@ -47,6 +50,10 @@ public:
nsresult GenerateUUID(nsAString& aID);
nsresult GetDataStoresFromIPC(const nsAString& aName,
nsIPrincipal* aPrincipal,
nsTArray<DataStoreSetting>* aValue);
private:
DataStoreService();
~DataStoreService();

Просмотреть файл

@ -1,68 +0,0 @@
/* 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();

Просмотреть файл

@ -38,7 +38,6 @@ EXTRA_JS_MODULES += [
'DataStoreChangeNotifier.jsm',
'DataStoreCursorImpl.jsm',
'DataStoreDB.jsm',
'DataStoreServiceInternal.jsm',
]
MOCHITEST_MANIFESTS += ['tests/mochitest.ini']

Просмотреть файл

@ -142,6 +142,7 @@
#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"
@ -768,6 +769,24 @@ ContentChild::RecvAudioChannelNotify()
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)
{

Просмотреть файл

@ -157,6 +157,10 @@ public:
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;

Просмотреть файл

@ -33,6 +33,7 @@
#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"
@ -1495,6 +1496,7 @@ ContentParent::InitializeMembers()
mNumDestroyingTabs = 0;
mIsAlive = true;
mSendPermissionUpdates = false;
mSendDataStoreInfos = false;
mCalledClose = false;
mCalledCloseWithError = false;
mCalledKillHard = false;
@ -2076,6 +2078,26 @@ ContentParent::RecvAudioChannelChangeDefVolChannel(const int32_t& aChannel,
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)
{

Просмотреть файл

@ -160,10 +160,14 @@ public:
int32_t Pid();
bool NeedsPermissionsUpdate() {
bool NeedsPermissionsUpdate() const {
return mSendPermissionUpdates;
}
bool NeedsDataStoreInfos() const {
return mSendDataStoreInfos;
}
BlobParent* GetOrCreateActorForBlob(nsIDOMBlob* aBlob);
/**
@ -526,6 +530,11 @@ private:
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;
@ -600,6 +609,7 @@ private:
bool mIsAlive;
bool mSendPermissionUpdates;
bool mSendDataStoreInfos;
bool mIsForBrowser;
bool mIsNuwaProcess;

Просмотреть файл

@ -262,6 +262,14 @@ struct PrefSetting {
MaybePrefValue userValue;
};
struct DataStoreSetting {
nsString name;
nsString originURL;
nsString manifestURL;
bool readOnly;
bool enabled;
};
intr protocol PContent
{
parent opens PCompositor;
@ -338,6 +346,9 @@ child:
async SpeakerManagerNotify();
async DataStoreNotify(uint32_t aAppId, nsString aName,
nsString aManifestURL);
/**
* Dump this process's GC and CC logs to the provided files.
*
@ -550,6 +561,9 @@ parent:
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,