Skip to content

Commit

Permalink
Bug 871445 - patch 1 - DataStoreService and getDataStores(), r=mounir…
Browse files Browse the repository at this point in the history
…, r=fabrice, r=ehsan

--HG--
rename : dom/apps/tests/file_app.sjs => dom/datastore/tests/file_app.sjs
rename : dom/apps/tests/file_hosted_app.template.webapp => dom/datastore/tests/file_app.template.webapp
  • Loading branch information
bakulf committed Oct 2, 2013
1 parent 00e08db commit e09904f
Show file tree
Hide file tree
Showing 20 changed files with 501 additions and 1 deletion.
2 changes: 2 additions & 0 deletions b2g/app/b2g.js
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,8 @@ pref("network.sntp.timeout", 30); // In seconds.
// Enable promise
pref("dom.promise.enabled", false);

pref("dom.datastore.enabled", true);

// DOM Inter-App Communication API.
#ifdef MOZ_WIDGET_GONK
// Enable this only for gonk-specific build but not for desktop build.
Expand Down
4 changes: 4 additions & 0 deletions b2g/installer/package-manifest.in
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,10 @@ bin/components/@DLL_PREFIX@nkgnomevfs@DLL_SUFFIX@
@BINPATH@/components/B2GAboutRedirector.js
@BINPATH@/components/FilePicker.js

@BINPATH@/components/DataStore.manifest
@BINPATH@/components/DataStoreService.js
@BINPATH@/components/dom_datastore.xpt

#ifdef MOZ_WEBSPEECH
@BINPATH@/components/dom_webspeechsynth.xpt
#endif
Expand Down
5 changes: 5 additions & 0 deletions browser/installer/package-manifest.in
Original file line number Diff line number Diff line change
Expand Up @@ -816,6 +816,11 @@ bin/libfreebl_32int64_3.so
@BINPATH@/metro/modules
#endif

@BINPATH@/components/DataStore.manifest
@BINPATH@/components/DataStoreService.js
@BINPATH@/components/dom_datastore.xpt


#ifdef MOZ_ASAN
@BINPATH@/llvm-symbolizer
#endif
43 changes: 42 additions & 1 deletion dom/apps/src/Webapps.jsm
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ XPCOMUtils.defineLazyGetter(this, "interAppCommService", function() {
.getService(Ci.nsIInterAppCommService);
});

XPCOMUtils.defineLazyServiceGetter(this, "dataStoreService",
"@mozilla.org/datastore-service;1",
"nsIDataStoreService");

XPCOMUtils.defineLazyGetter(this, "msgmgr", function() {
return Cc["@mozilla.org/system-message-internal;1"]
.getService(Ci.nsISystemMessagesInternal);
Expand Down Expand Up @@ -272,6 +276,19 @@ this.DOMApplicationRegistry = {
}
},

updateDataStoreForApp: function(aId) {
if (!this.webapps[aId]) {
return;
}

// Create or Update the DataStore for this app
this._readManifests([{ id: aId }], (function(aResult) {
this.updateDataStore(this.webapps[aId].localId,
this.webapps[aId].manifestURL,
aResult[0].manifest);
}).bind(this));
},

updatePermissionsForApp: function updatePermissionsForApp(aId) {
if (!this.webapps[aId]) {
return;
Expand Down Expand Up @@ -513,6 +530,7 @@ this.DOMApplicationRegistry = {
}
this.updateOfflineCacheForApp(id);
this.updatePermissionsForApp(id);
this.updateDataStoreForApp(id);
}
// Need to update the persisted list of apps since
// installPreinstalledApp() removes the ones failing to install.
Expand All @@ -534,6 +552,20 @@ this.DOMApplicationRegistry = {
}).bind(this));
},

updateDataStore: function(aId, aManifestURL, aManifest) {
if (!("datastores" in aManifest)) {
return;
}

for (let name in aManifest.datastores) {
let readonly = ("readonly" in aManifest.datastores[name]) &&
!aManifest.datastores[name].readonly
? false : true;

dataStoreService.installDataStore(aId, name, aManifestURL, readonly);
}
},

// |aEntryPoint| is either the entry_point name or the null in which case we
// use the root of the manifest.
//
Expand Down Expand Up @@ -1392,7 +1424,7 @@ this.DOMApplicationRegistry = {
manifestURL: app.manifestURL },
true);
}

this.updateDataStore(this.webapps[id].localId, app.manifestURL, aData);
this.broadcastMessage("Webapps:PackageEvent",
{ type: "applied",
manifestURL: app.manifestURL,
Expand Down Expand Up @@ -1598,6 +1630,8 @@ this.DOMApplicationRegistry = {
}, true);
}

this.updateDataStore(this.webapps[id].localId, app.manifestURL, app.manifest);

app.name = manifest.name;
app.csp = manifest.csp || "";
app.role = manifest.role || "";
Expand Down Expand Up @@ -2097,6 +2131,10 @@ this.DOMApplicationRegistry = {
manifestURL: appObject.manifestURL },
true);
}

this.updateDataStore(this.webapps[aId].localId, appObject.manifestURL,
aManifest);

debug("About to fire Webapps:PackageEvent 'installed'");
this.broadcastMessage("Webapps:PackageEvent",
{ type: "installed",
Expand Down Expand Up @@ -2199,6 +2237,9 @@ this.DOMApplicationRegistry = {
this.uninstall(aData, aData.mm);
}).bind(this));
}

this.updateDataStore(this.webapps[id].localId, this.webapps[id].manifestURL,
jsonManifest);
}

["installState", "downloadAvailable",
Expand Down
24 changes: 24 additions & 0 deletions dom/base/Navigator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,13 @@
#endif

#include "nsIDOMGlobalPropertyInitializer.h"
#include "nsIDataStoreService.h"
#include "nsJSUtils.h"

#include "nsScriptNameSpaceManager.h"

#include "mozilla/dom/NavigatorBinding.h"
#include "mozilla/dom/Promise.h"

namespace mozilla {
namespace dom {
Expand Down Expand Up @@ -1095,6 +1097,28 @@ Navigator::GetBattery(ErrorResult& aRv)
return mBatteryManager;
}

already_AddRefed<Promise>
Navigator::GetDataStores(const nsAString& aName, ErrorResult& aRv)
{
if (!mWindow || !mWindow->GetDocShell()) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}

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(mWindow, aName, getter_AddRefs(promise));

nsRefPtr<Promise> p = static_cast<Promise*>(promise.get());
return p.forget();
}

PowerManager*
Navigator::GetMozPower(ErrorResult& aRv)
{
Expand Down
4 changes: 4 additions & 0 deletions dom/base/Navigator.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ class BatteryManager;
class FMRadio;
#endif

class Promise;

class DesktopNotificationCenter;
class MobileMessageManager;
class MozIdleObserver;
Expand Down Expand Up @@ -175,6 +177,8 @@ class Navigator : public nsIDOMNavigator
// The XPCOM GetDoNotTrack is ok
Geolocation* GetGeolocation(ErrorResult& aRv);
battery::BatteryManager* GetBattery(ErrorResult& aRv);
already_AddRefed<Promise> GetDataStores(const nsAString &aName,
ErrorResult& aRv);
bool Vibrate(uint32_t aDuration);
bool Vibrate(const nsTArray<uint32_t>& aDuration);
void GetAppCodeName(nsString& aAppCodeName, ErrorResult& aRv)
Expand Down
63 changes: 63 additions & 0 deletions dom/datastore/DataStore.jsm
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/* -*- 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'

var EXPORTED_SYMBOLS = ["DataStore"];

/* DataStore object */

function DataStore(aAppId, aName, aOwner, aReadOnly) {
this.appId = aAppId;
this.name = aName;
this.owner = aOwner;
this.readOnly = aReadOnly;
}

DataStore.prototype = {
appId: null,
name: null,
owner: null,
readOnly: null,

exposeObject: function(aWindow) {
let self = this;
let chromeObject = {
get name() {
return self.name;
},

get owner() {
return self.owner;
},

get readOnly() {
return self.readOnly;
},

/* TODO:
Promise<Object> get(unsigned long id);
Promise<void> update(unsigned long id, any obj);
Promise<int> add(any obj)
Promise<boolean> remove(unsigned long id)
Promise<void> clear();
readonly attribute DOMString revisionId
attribute EventHandler onchange;
Promise<DataStoreChanges> getChanges(DOMString revisionId)
getAll(), getLength()
*/

__exposedProps__: {
name: 'r',
owner: 'r',
readOnly: 'r'
}
};

return chromeObject;
}
};
2 changes: 2 additions & 0 deletions dom/datastore/DataStore.manifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
component {d193d0e2-c677-4a7b-bb0a-19155b470f2e} DataStoreService.js
contract @mozilla.org/datastore-service;1 {d193d0e2-c677-4a7b-bb0a-19155b470f2e}
115 changes: 115 additions & 0 deletions dom/datastore/DataStoreService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/* -*- 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 */

let DEBUG = 0;
let debug;
if (DEBUG)
debug = function (s) { dump('DEBUG DataStore: ' + s + '\n'); }
else
debug = function (s) {}

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/DataStore.jsm');

/* DataStoreService */

const DATASTORESERVICE_CID = Components.ID('{d193d0e2-c677-4a7b-bb0a-19155b470f2e}');

function DataStoreService() {
debug('DataStoreService Constructor');

let obs = Services.obs;
if (!obs) {
debug("DataStore Error: observer-service is null!");
return;
}

obs.addObserver(this, 'webapps-clear-data', false);
}

DataStoreService.prototype = {
// Hash of DataStores
stores: {},

installDataStore: function(aAppId, aName, aOwner, aReadOnly) {
debug('installDataStore - appId: ' + aAppId + ', aName: ' + aName +
', aOwner:' + aOwner + ', aReadOnly: ' + aReadOnly);

if (aName in this.stores && aAppId in this.stores[aName]) {
debug('This should not happen');
return;
}

let store = new DataStore(aAppId, aName, aOwner, aReadOnly);

if (!(aName in this.stores)) {
this.stores[aName] = {};
}

this.stores[aName][aAppId] = store;
},

getDataStores: function(aWindow, aName) {
debug('getDataStores - aName: ' + aName);
let self = this;
return new aWindow.Promise(function(resolve, reject) {
let results = [];

if (aName in self.stores) {
for (let appId in self.stores[aName]) {
let obj = self.stores[aName][appId].exposeObject(aWindow);
results.push(obj);
}
}

resolve(results);
});
},

observe: function observe(aSubject, aTopic, aData) {
debug('getDataStores - 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;
}

for (let key in this.stores) {
if (params.appId in this.stores[key]) {
delete this.stores[key][params.appId];
}

if (!this.stores[key].length) {
delete this.stores[key];
}
}
},

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
})
};

this.NSGetFactory = XPCOMUtils.generateNSGetFactory([DataStoreService]);
24 changes: 24 additions & 0 deletions dom/datastore/moz.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# -*- 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/.

TEST_DIRS += ['tests']

XPIDL_SOURCES += [
'nsIDataStoreService.idl',
]

XPIDL_MODULE = 'dom_datastore'

MODULE = 'dom'

EXTRA_COMPONENTS += [
'DataStore.manifest',
'DataStoreService.js',
]

EXTRA_JS_MODULES += [
'DataStore.jsm',
]
Loading

0 comments on commit e09904f

Please sign in to comment.