import changes from `dev' branch of rmottola/Arctic-Fox:

- Bug 1261009 - Remove the Data Store API, r=fabrice (b22e580107)
- Bug 1268393 - Some compilation issues in ServiceWorker code, r=ehsan (d9c2f2554b)
- Bug 1209095 - Accept opaqueredirection fetch results if the request redirection type is manual. r=bkelly (6fe92d1368)
- Bug 1267733 P2 Pass ServiceWorkerRegistrationInfo down to CancelChannelRunnable. r=jdm (0ec51f09ef)
- Bug 1267733 P3 Trigger service worker update after failed interception. r=jdm (f89a7998d4)
- Bug 1267733 P4 Add a wpt test that verifies a service worker update can recover from a broken navigation interception. r=jdm (9dc0ce97bd)
- Bug 1267691: Assert on failed attempts to shutdown a thread from itself r=froyd (0cbd1e458c)
- Bug 1180533 - Disable BackgroundHangMonitor on gonk (a2d666e741)
- Bug 1121216 - disable BackgroundHangMonitor for TSan builds; r=jchen (ef15d1016f)
- Bug 1265621 - Use StaticRefPtr in Omnijar.cpp; r=froydnj (81bc32836e)
- Bug 1265621 - Expose outer zip readers in Omnijar::GetReader; r=froydnj (ce3f82929e)
- Bug 1267021 - Use fallible allocation and move semantics for Push events. r=wchen (3a1ae23d8d)
- Bug 1222899 - Handle geolocation-device-events callback. r=kchen (a33bcf4297)
- Bug 1237831 - Update GonkGPSGeolocationProvider.cpp to use B2G-style. r=jst (d389eedf47)
- Bug 1245033 - Build break in dom/system/gonk/GonkGPSGeolocationProvider.cpp:541:126: error: format '%d' expects argument of type 'int', but argument 5 has type 'nsresult'. r=fabrice (ecde789edf)
- Bug 1264287: Convert Wifi to use |UniquePtr|, r=nfroyd (9bad7792bf)
- Bug 1267577 - Move nsRunnable to mozilla::Runnable. r=gsvelto (f58e2161f2)
- Bug 1210370 - Close wpa_supplicant before we shutdown nsIWifiProxyService. r=mrbkap (5cd4dce58f)
- Bug 1218629 - Save audio volume for each device to setting db r=alwu (2f1847dd6f)
- Bug 1249437 - Remove workaround of volume control r=alwu (13cd144a89)
- Bug 1268432: Replace |Task| with |Runnable| in B2G code r=fabrice (bcc768e9cb)
- Bug 1226483 - Add ASSERT check to AudioManager::SelectDeviceFromDevices() r=alwu (446e8f634e)
- Bug 1229234 - Enable audio_is_output_device() on ICS r=alwu (84aae07f23)
- Bug 1267369 - Only generate typelib data for scriptable interfaces; r=khuey (e49b44c9ce)
- Bug 1155969 - Make runtests.py flake8 compliant. r=ted (1de456b206)
- Bug 1266569 - Avoid including the ChromeUtils binding in Base64.h. r=froydnj (7ba39a7687)
This commit is contained in:
2024-08-28 23:55:40 +08:00
parent 10f5941b9c
commit c2bcdec5c9
199 changed files with 1344 additions and 7774 deletions
-7
View File
@@ -910,13 +910,6 @@ pref("network.sntp.pools", // Servers separated by ';'.
pref("network.sntp.port", 123);
pref("network.sntp.timeout", 30); // In seconds.
// Enable dataStore
pref("dom.datastore.enabled", true);
// When an entry is changed, use two timers to fire system messages in a more
// moderate pattern.
pref("dom.datastore.sysMsgOnChangeShortTimeoutSec", 10);
pref("dom.datastore.sysMsgOnChangeLongTimeoutSec", 60);
// DOM Inter-App Communication API.
pref("dom.inter-app-communication-api.enabled", true);
+32 -6
View File
@@ -7,7 +7,6 @@
window.performance.mark('gecko-shell-loadstart');
Cu.import('resource://gre/modules/ContactService.jsm');
Cu.import('resource://gre/modules/DataStoreChangeNotifier.jsm');
Cu.import('resource://gre/modules/AlarmService.jsm');
Cu.import('resource://gre/modules/ActivitiesService.jsm');
Cu.import('resource://gre/modules/NotificationDB.jsm');
@@ -1064,22 +1063,49 @@ window.addEventListener('ContentStart', function update_onContentStart() {
updatePrompt.wrappedJSObject.handleContentStart(shell);
#endif
});
/* The "GPSChipOn" is to indicate that GPS engine is turned ON by the modem.
During this GPS engine is turned ON by the modem, we make the location tracking icon visible to user.
Once GPS engine is turned OFF, the location icon will disappear.
If GPS engine is not turned ON by the modem or GPS location service is triggered,
we let GPS service take over the control of showing the location tracking icon.
The regular sequence of the geolocation-device-events is: starting-> GPSStarting-> shutdown-> GPSShutdown
*/
(function geolocationStatusTracker() {
let gGeolocationActive = false;
let GPSChipOn = false;
Services.obs.addObserver(function(aSubject, aTopic, aData) {
let oldState = gGeolocationActive;
if (aData == "starting") {
gGeolocationActive = true;
} else if (aData == "shutdown") {
gGeolocationActive = false;
let promptWarning = false;
switch (aData) {
case "GPSStarting":
if (!gGeolocationActive) {
gGeolocationActive = true;
GPSChipOn = true;
promptWarning = true;
}
break;
case "GPSShutdown":
if (GPSChipOn) {
gGeolocationActive = false;
GPSChipOn = false;
}
break;
case "starting":
gGeolocationActive = true;
GPSChipOn = false;
break;
case "shutdown":
gGeolocationActive = false;
break;
}
if (gGeolocationActive != oldState) {
shell.sendChromeEvent({
type: 'geolocation-status',
active: gGeolocationActive
active: gGeolocationActive,
prompt: promptWarning
});
}
}, "geolocation-device-events", false);
-4
View File
@@ -938,10 +938,6 @@ bin/libfreebl_32int64_3.so
@RESPATH@/components/FxAccountsUIGlue.js
@RESPATH@/components/services_fxaccounts.xpt
@RESPATH@/components/DataStore.manifest
@RESPATH@/components/DataStoreImpl.js
@RESPATH@/components/dom_datastore.xpt
@RESPATH@/components/MobileIdentity.manifest
@RESPATH@/components/MobileIdentity.js
@RESPATH@/components/dom_mobileidentity.xpt
-4
View File
@@ -815,10 +815,6 @@ bin/libfreebl_32int64_3.so
#endif
#endif
@RESPATH@/components/DataStore.manifest
@RESPATH@/components/DataStoreImpl.js
@RESPATH@/components/dom_datastore.xpt
@RESPATH@/components/dom_audiochannel.xpt
; Shutdown Terminator
-4
View File
@@ -170,10 +170,6 @@ AppsService.prototype = {
return UserCustomizations.isFromExtension(aURI);
},
updateDataStoreEntriesFromLocalId: function(aLocalId) {
return DOMApplicationRegistry.updateDataStoreEntriesFromLocalId(aLocalId);
},
classID : APPS_SERVICE_CID,
QueryInterface : XPCOMUtils.generateQI([Ci.nsIAppsService])
}
-4
View File
@@ -419,10 +419,6 @@ this.DOMApplicationRegistry = {
getAppInfo: function getAppInfo(aAppId) {
return AppsUtils.getAppInfo(this.webapps, aAppId);
},
updateDataStoreEntriesFromLocalId: function(aLocalId) {
debug("updateDataStoreEntriesFromLocalId() not yet supported on child!");
}
}
-76
View File
@@ -149,10 +149,6 @@ XPCOMUtils.defineLazyGetter(this, "interAppCommService", function() {
.getService(Ci.nsIInterAppCommService);
});
XPCOMUtils.defineLazyServiceGetter(this, "dataStoreService",
"@mozilla.org/datastore-service;1",
"nsIDataStoreService");
XPCOMUtils.defineLazyServiceGetter(this, "appsService",
"@mozilla.org/AppsService;1",
"nsIAppsService");
@@ -452,18 +448,6 @@ this.DOMApplicationRegistry = {
}
}),
updateDataStoreForApp: Task.async(function*(aId) {
if (!this.webapps[aId]) {
return;
}
// Create or Update the DataStore for this app
let results = yield this._readManifests([{ id: aId }]);
let app = this.webapps[aId];
this.updateDataStore(app.localId, app.origin, app.manifestURL,
results[0].manifest, app.appStatus);
}),
appKind: function(aApp, aManifest) {
if (aApp.origin.startsWith("android://")) {
return this.kAndroid;
@@ -815,52 +799,10 @@ this.DOMApplicationRegistry = {
Services.prefs.setBoolPref("dom.apps.reset-permissions", true);
}
// DataStores must be initialized at startup.
for (let id in this.webapps) {
yield this.updateDataStoreForApp(id);
}
yield this.registerAppsHandlers(runUpdate);
}.bind(this)).then(null, Cu.reportError);
},
updateDataStore: function(aId, aOrigin, aManifestURL, aManifest) {
if (!aManifest) {
debug("updateDataStore: no manifest for " + aOrigin);
return;
}
let uri = Services.io.newURI(aOrigin, null, null);
let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(Ci.nsIScriptSecurityManager);
let principal = secMan.createCodebasePrincipal(uri, {appId: aId});
if (!dataStoreService.checkPermission(principal)) {
return;
}
if ('datastores-owned' in aManifest) {
for (let name in aManifest['datastores-owned']) {
let readonly = "access" in aManifest['datastores-owned'][name]
? aManifest['datastores-owned'][name].access == 'readonly'
: false;
dataStoreService.installDataStore(aId, name, aOrigin, aManifestURL,
readonly);
}
}
if ('datastores-access' in aManifest) {
for (let name in aManifest['datastores-access']) {
let readonly = ("readonly" in aManifest['datastores-access'][name]) &&
!aManifest['datastores-access'][name].readonly
? false : true;
dataStoreService.installAccessDataStore(aId, name, aOrigin,
aManifestURL, readonly);
}
}
},
// |aEntryPoint| is either the entry_point name or the null in which case we
// use the root of the manifest.
//
@@ -1927,8 +1869,6 @@ this.DOMApplicationRegistry = {
kind: app.kind },
true);
}
this.updateDataStore(this.webapps[id].localId, app.origin,
app.manifestURL, newManifest);
MessageBroadcaster.broadcastMessage("Webapps:UpdateState", {
app: app,
manifest: newManifest,
@@ -2373,9 +2313,6 @@ this.DOMApplicationRegistry = {
}, true);
}
this.updateDataStore(this.webapps[aId].localId, aApp.origin,
aApp.manifestURL, aApp.manifest);
aApp.name = aNewManifest.name;
aApp.csp = manifest.csp || "";
aApp.updateTime = Date.now();
@@ -3015,9 +2952,6 @@ this.DOMApplicationRegistry = {
this.doUninstall.bind(this, aData, aData.mm)
);
}
this.updateDataStore(this.webapps[id].localId, this.webapps[id].origin,
this.webapps[id].manifestURL, jsonManifest);
}
for (let prop of ["installState", "downloadAvailable", "downloading",
@@ -3162,9 +3096,6 @@ this.DOMApplicationRegistry = {
}, true);
}
this.updateDataStore(this.webapps[aId].localId, aNewApp.origin,
aNewApp.manifestURL, aManifest);
if (aInstallSuccessCallback) {
try {
yield aInstallSuccessCallback(aNewApp, aManifest, zipFile.path);
@@ -4676,13 +4607,6 @@ this.DOMApplicationRegistry = {
return AppsUtils.areAnyAppsInstalled(this.webapps);
},
updateDataStoreEntriesFromLocalId: function(aLocalId) {
let app = appsService.getAppByLocalId(aLocalId);
if (app) {
this.updateDataStoreForApp(app.id);
}
},
_isLaunchable: function(aApp) {
return true;
},
+1 -1
View File
@@ -2,7 +2,7 @@
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - basic operation on a readonly db</title>
<title>?!?</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="file_test_widget.js"></script>
<script type="application/javascript" src="common.js"></script>
+22 -2
View File
@@ -74,7 +74,9 @@ ThreadSafeChromeUtils::Base64URLEncode(GlobalObject& aGlobal,
MOZ_CRASH("Uninitialized union: expected buffer or view");
}
nsresult rv = mozilla::Base64URLEncode(length, data, aOptions, aResult);
auto paddingPolicy = aOptions.mPad ? Base64URLEncodePaddingPolicy::Include :
Base64URLEncodePaddingPolicy::Omit;
nsresult rv = mozilla::Base64URLEncode(length, data, paddingPolicy, aResult);
if (NS_WARN_IF(NS_FAILED(rv))) {
aResult.Truncate();
aRv.Throw(rv);
@@ -88,8 +90,26 @@ ThreadSafeChromeUtils::Base64URLDecode(GlobalObject& aGlobal,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv)
{
Base64URLDecodePaddingPolicy paddingPolicy;
switch (aOptions.mPadding) {
case Base64URLDecodePadding::Require:
paddingPolicy = Base64URLDecodePaddingPolicy::Require;
break;
case Base64URLDecodePadding::Ignore:
paddingPolicy = Base64URLDecodePaddingPolicy::Ignore;
break;
case Base64URLDecodePadding::Reject:
paddingPolicy = Base64URLDecodePaddingPolicy::Reject;
break;
default:
aRv.Throw(NS_ERROR_INVALID_ARG);
return;
}
FallibleTArray<uint8_t> data;
nsresult rv = mozilla::Base64URLDecode(aString, aOptions, data);
nsresult rv = mozilla::Base64URLDecode(aString, paddingPolicy, data);
if (NS_WARN_IF(NS_FAILED(rv))) {
aRv.Throw(rv);
return;
-102
View File
@@ -95,7 +95,6 @@
#endif
#include "nsIDOMGlobalPropertyInitializer.h"
#include "mozilla/dom/DataStoreService.h"
#include "nsJSUtils.h"
#include "nsScriptNameSpaceManager.h"
@@ -1503,38 +1502,6 @@ Navigator::GetDeprecatedBattery(ErrorResult& aRv)
return mBatteryManager;
}
/* static */ already_AddRefed<Promise>
Navigator::GetDataStores(nsPIDOMWindow* aWindow,
const nsAString& aName,
const nsAString& aOwner,
ErrorResult& aRv)
{
if (!aWindow || !aWindow->GetDocShell()) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
RefPtr<DataStoreService> service = DataStoreService::GetOrCreate();
if (!service) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsCOMPtr<nsISupports> promise;
aRv = service->GetDataStores(aWindow, aName, aOwner, getter_AddRefs(promise));
RefPtr<Promise> p = static_cast<Promise*>(promise.get());
return p.forget();
}
already_AddRefed<Promise>
Navigator::GetDataStores(const nsAString& aName,
const nsAString& aOwner,
ErrorResult& aRv)
{
return GetDataStores(mWindow, aName, aOwner, aRv);
}
already_AddRefed<Promise>
Navigator::GetFeature(const nsAString& aName, ErrorResult& aRv)
{
@@ -2294,75 +2261,6 @@ Navigator::HasUserMediaSupport(JSContext* /* unused */,
Preferences::GetBool("media.peerconnection.enabled", false);
}
/* static */
bool
Navigator::HasDataStoreSupport(nsIPrincipal* aPrincipal)
{
workers::AssertIsOnMainThread();
return DataStoreService::CheckPermission(aPrincipal);
}
// A WorkerMainThreadRunnable to synchronously dispatch the call of
// HasDataStoreSupport() from the worker thread to the main thread.
class HasDataStoreSupportRunnable final
: public workers::WorkerCheckAPIExposureOnMainThreadRunnable
{
public:
bool mResult;
explicit HasDataStoreSupportRunnable(workers::WorkerPrivate* aWorkerPrivate)
: workers::WorkerCheckAPIExposureOnMainThreadRunnable(aWorkerPrivate)
, mResult(false)
{
MOZ_ASSERT(aWorkerPrivate);
aWorkerPrivate->AssertIsOnWorkerThread();
}
protected:
virtual bool
MainThreadRun() override
{
workers::AssertIsOnMainThread();
mResult = Navigator::HasDataStoreSupport(mWorkerPrivate->GetPrincipal());
return true;
}
};
/* static */
bool
Navigator::HasDataStoreSupport(JSContext* aCx, JSObject* aGlobal)
{
// If the caller is on the worker thread, dispatch this to the main thread.
if (!NS_IsMainThread()) {
workers::WorkerPrivate* workerPrivate =
workers::GetWorkerPrivateFromContext(aCx);
workerPrivate->AssertIsOnWorkerThread();
RefPtr<HasDataStoreSupportRunnable> runnable =
new HasDataStoreSupportRunnable(workerPrivate);
return runnable->Dispatch() && runnable->mResult;
}
workers::AssertIsOnMainThread();
JS::Rooted<JSObject*> global(aCx, aGlobal);
nsCOMPtr<nsPIDOMWindow> win = GetWindowFromGlobal(global);
if (!win) {
return false;
}
nsIDocument* doc = win->GetExtantDoc();
if (!doc || !doc->NodePrincipal()) {
return false;
}
return HasDataStoreSupport(doc->NodePrincipal());
}
#ifdef MOZ_B2G
/* static */
bool
-13
View File
@@ -164,11 +164,6 @@ public:
Promise* GetBattery(ErrorResult& aRv);
battery::BatteryManager* GetDeprecatedBattery(ErrorResult& aRv);
static already_AddRefed<Promise> GetDataStores(nsPIDOMWindow* aWindow,
const nsAString& aName,
const nsAString& aOwner,
ErrorResult& aRv);
static void AppName(nsAString& aAppName, bool aUsePrefOverriddenValue);
static nsresult GetPlatform(nsAString& aPlatform,
@@ -186,10 +181,6 @@ public:
// NavigatorBinding::ClearCachedUserAgentValue(this);
void ClearUserAgentCache();
already_AddRefed<Promise> GetDataStores(const nsAString& aName,
const nsAString& aOwner,
ErrorResult& aRv);
// Feature Detection API
already_AddRefed<Promise> GetFeature(const nsAString& aName,
ErrorResult& aRv);
@@ -326,10 +317,6 @@ public:
static bool HasUserMediaSupport(JSContext* /* unused */,
JSObject* /* unused */);
static bool HasDataStoreSupport(nsIPrincipal* aPrincipal);
static bool HasDataStoreSupport(JSContext* cx, JSObject* aGlobal);
#ifdef MOZ_B2G
static bool HasMobileIdSupport(JSContext* aCx, JSObject* aGlobal);
#endif
@@ -88,8 +88,10 @@ function testDecode(input, decoded) {
function test_base64URLDecode() {
throws(_ => ChromeUtils.base64URLDecode(""), /TypeError/,
"Should require decoding options");
throws(_ => ChromeUtils.base64URLEncode("", {}), /TypeError/,
throws(_ => ChromeUtils.base64URLDecode("", {}), /TypeError/,
"Decoding should require the padding option");
throws(_ => ChromeUtils.base64URLDecode("", { padding: "chocolate" }),
"Decoding should throw for invalid padding policy");
for (let {decoded, encoded} of binaryTests) {
testDecode(encoded, decoded);
-23
View File
@@ -362,25 +362,6 @@ DOMInterfaces = {
'nativeType': 'nsDOMDataChannel',
},
'DataStore': [{
'workers': False
}, {
'workers': True,
'nativeType': 'mozilla::dom::workers::WorkerDataStore',
'implicitJSContext': ['name', 'owner', 'readOnly', 'get', 'remove',
'clear', 'revisionId', 'getLength', 'sync']
}],
'DataStoreCursor': [{
'workers': False,
'wrapperCache': False
}, {
'workers': True,
'nativeType': 'mozilla::dom::workers::WorkerDataStoreCursor',
'wrapperCache': False,
'implicitJSContext': ['store', 'next', 'close']
}],
'DedicatedWorkerGlobalScope': {
'headerFile': 'mozilla/dom/WorkerScope.h',
'workers': True,
@@ -1611,10 +1592,6 @@ DOMInterfaces = {
},
},
'WorkerNavigator': {
'implicitJSContext': ['getDataStores'],
},
'XMLHttpRequest': [
{
'nativeType': 'nsXMLHttpRequest',
@@ -129,7 +129,7 @@ private:
};
class BluetoothA2dpManager::InitProfileResultHandlerRunnable final
: public nsRunnable
: public Runnable
{
public:
InitProfileResultHandlerRunnable(BluetoothProfileResultHandler* aRes,
@@ -171,7 +171,7 @@ BluetoothA2dpManager::InitA2dpInterface(BluetoothProfileResultHandler* aRes)
if (sBtA2dpInterface) {
BT_LOGR("Bluetooth A2DP interface is already initalized.");
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new InitProfileResultHandlerRunnable(aRes, NS_OK);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch A2DP Init runnable");
@@ -184,7 +184,7 @@ BluetoothA2dpManager::InitA2dpInterface(BluetoothProfileResultHandler* aRes)
if (NS_WARN_IF(!btInf)) {
// If there's no Bluetooth interface, we dispatch a runnable
// that calls the profile result handler.
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch A2DP OnError runnable");
@@ -197,7 +197,7 @@ BluetoothA2dpManager::InitA2dpInterface(BluetoothProfileResultHandler* aRes)
if (NS_WARN_IF(!setupInterface)) {
// If there's no Setup interface, we dispatch a runnable
// that calls the profile result handler.
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch A2DP OnError runnable");
@@ -210,7 +210,7 @@ BluetoothA2dpManager::InitA2dpInterface(BluetoothProfileResultHandler* aRes)
if (NS_WARN_IF(!a2dpInterface)) {
// If there's no A2DP interface, we dispatch a runnable
// that calls the profile result handler.
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch A2DP OnError runnable");
@@ -329,7 +329,7 @@ private:
};
class BluetoothA2dpManager::DeinitProfileResultHandlerRunnable final
: public nsRunnable
: public Runnable
{
public:
DeinitProfileResultHandlerRunnable(BluetoothProfileResultHandler* aRes,
@@ -365,7 +365,7 @@ BluetoothA2dpManager::DeinitA2dpInterface(BluetoothProfileResultHandler* aRes)
if (!sBtA2dpInterface) {
BT_LOGR("Bluetooth A2DP interface has not been initalized.");
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new DeinitProfileResultHandlerRunnable(aRes, NS_OK);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch A2DP Deinit runnable");
@@ -378,7 +378,7 @@ BluetoothA2dpManager::DeinitA2dpInterface(BluetoothProfileResultHandler* aRes)
if (NS_WARN_IF(!btInf)) {
// If there's no backend interface, we dispatch a runnable
// that calls the profile result handler.
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new DeinitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch A2DP OnError runnable");
@@ -391,7 +391,7 @@ BluetoothA2dpManager::DeinitA2dpInterface(BluetoothProfileResultHandler* aRes)
if (NS_WARN_IF(!setupInterface)) {
// If there's no Setup interface, we dispatch a runnable
// that calls the profile result handler.
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new DeinitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch A2DP OnError runnable");
@@ -172,7 +172,7 @@ private:
};
class BluetoothAvrcpManager::InitProfileResultHandlerRunnable final
: public nsRunnable
: public Runnable
{
public:
InitProfileResultHandlerRunnable(BluetoothProfileResultHandler* aRes,
@@ -211,7 +211,7 @@ BluetoothAvrcpManager::InitAvrcpInterface(BluetoothProfileResultHandler* aRes)
if (sBtAvrcpInterface) {
BT_LOGR("Bluetooth AVRCP interface is already initalized.");
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new InitProfileResultHandlerRunnable(aRes, NS_OK);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch AVRCP Init runnable");
@@ -224,7 +224,7 @@ BluetoothAvrcpManager::InitAvrcpInterface(BluetoothProfileResultHandler* aRes)
if (NS_WARN_IF(!btInf)) {
// If there's no Bluetooth interface, we dispatch a runnable
// that calls the profile result handler.
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch AVRCP OnError runnable");
@@ -237,7 +237,7 @@ BluetoothAvrcpManager::InitAvrcpInterface(BluetoothProfileResultHandler* aRes)
if (NS_WARN_IF(!setupInterface)) {
// If there's no Setup interface, we dispatch a runnable
// that calls the profile result handler.
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch AVRCP OnError runnable");
@@ -250,7 +250,7 @@ BluetoothAvrcpManager::InitAvrcpInterface(BluetoothProfileResultHandler* aRes)
if (NS_WARN_IF(!avrcpInterface)) {
// If there's no AVRCP interface, we dispatch a runnable
// that calls the profile result handler.
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch AVRCP OnError runnable");
@@ -350,7 +350,7 @@ private:
};
class BluetoothAvrcpManager::DeinitProfileResultHandlerRunnable final
: public nsRunnable
: public Runnable
{
public:
DeinitProfileResultHandlerRunnable(BluetoothProfileResultHandler* aRes,
@@ -386,7 +386,7 @@ BluetoothAvrcpManager::DeinitAvrcpInterface(BluetoothProfileResultHandler* aRes)
if (!sBtAvrcpInterface) {
BT_LOGR("Bluetooth AVRCP interface has not been initalized.");
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new DeinitProfileResultHandlerRunnable(aRes, NS_OK);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch AVRCP Deinit runnable");
@@ -399,7 +399,7 @@ BluetoothAvrcpManager::DeinitAvrcpInterface(BluetoothProfileResultHandler* aRes)
if (NS_WARN_IF(!btInf)) {
// If there's no backend interface, we dispatch a runnable
// that calls the profile result handler.
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new DeinitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch AVRCP OnError runnable");
@@ -412,7 +412,7 @@ BluetoothAvrcpManager::DeinitAvrcpInterface(BluetoothProfileResultHandler* aRes)
if (NS_WARN_IF(!setupInterface)) {
// If there's no Setup interface, we dispatch a runnable
// that calls the profile result handler.
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new DeinitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch AVRCP OnError runnable");
@@ -434,7 +434,7 @@ BluetoothAvrcpManager::HandleShutdown()
sBluetoothAvrcpManager = nullptr;
}
class BluetoothAvrcpManager::ConnectRunnable final : public nsRunnable
class BluetoothAvrcpManager::ConnectRunnable final : public Runnable
{
public:
ConnectRunnable(BluetoothAvrcpManager* aManager)
@@ -467,7 +467,7 @@ BluetoothAvrcpManager::Connect(const BluetoothAddress& aDeviceAddress,
NS_DispatchToMainThread(new ConnectRunnable(this));
}
class BluetoothAvrcpManager::DisconnectRunnable final : public nsRunnable
class BluetoothAvrcpManager::DisconnectRunnable final : public Runnable
{
public:
DisconnectRunnable(BluetoothAvrcpManager* aManager)
@@ -88,16 +88,17 @@ BluetoothDaemonSocketModule::ConnectCmd(const BluetoothAddress& aBdAddr,
/* |DeleteTask| deletes a class instance on the I/O thread
*/
template <typename T>
class DeleteTask final : public Task
class DeleteTask final : public Runnable
{
public:
DeleteTask(T* aPtr)
: mPtr(aPtr)
{ }
void Run() override
NS_IMETHOD Run() override
{
mPtr = nullptr;
return NS_OK;
}
private:
@@ -134,7 +135,7 @@ public:
}
MessageLoopForIO::current()->PostTask(
FROM_HERE, new DeleteTask<AcceptWatcher>(this));
MakeAndAddRef<DeleteTask<AcceptWatcher>>(this));
}
};
@@ -145,8 +146,8 @@ BluetoothDaemonSocketModule::AcceptCmd(int aFd,
MOZ_ASSERT(NS_IsMainThread());
/* receive Bluedroid's socket-setup messages and client fd */
Task* t = new SocketMessageWatcherTask(new AcceptWatcher(aFd, aRes));
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t);
XRE_GetIOMessageLoop()->PostTask(
MakeAndAddRef<SocketMessageWatcherTask>(new AcceptWatcher(aFd, aRes)));
return NS_OK;
}
@@ -157,8 +158,8 @@ BluetoothDaemonSocketModule::CloseCmd(BluetoothSocketResultHandler* aRes)
MOZ_ASSERT(NS_IsMainThread());
/* stop the watcher corresponding to |aRes| */
Task* t = new DeleteSocketMessageWatcherTask(aRes);
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t);
XRE_GetIOMessageLoop()->PostTask(
MakeAndAddRef<DeleteSocketMessageWatcherTask>(aRes));
return NS_OK;
}
@@ -273,7 +274,7 @@ public:
}
MessageLoopForIO::current()->PostTask(
FROM_HERE, new DeleteTask<ConnectWatcher>(this));
MakeAndAddRef<DeleteTask<ConnectWatcher>>(this));
}
};
@@ -298,8 +299,8 @@ BluetoothDaemonSocketModule::ConnectRsp(const DaemonSocketPDUHeader& aHeader,
}
/* receive Bluedroid's socket-setup messages */
Task* t = new SocketMessageWatcherTask(new ConnectWatcher(fd, aRes));
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t);
XRE_GetIOMessageLoop()->PostTask(
MakeAndAddRef<SocketMessageWatcherTask>(new ConnectWatcher(fd, aRes)));
}
//
@@ -465,7 +465,7 @@ private:
};
class BluetoothGattManager::InitProfileResultHandlerRunnable final
: public nsRunnable
: public Runnable
{
public:
InitProfileResultHandlerRunnable(BluetoothProfileResultHandler* aRes,
@@ -501,7 +501,7 @@ BluetoothGattManager::InitGattInterface(BluetoothProfileResultHandler* aRes)
if (sBluetoothGattInterface) {
BT_LOGR("Bluetooth GATT interface is already initalized.");
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new InitProfileResultHandlerRunnable(aRes, NS_OK);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch GATT Init runnable");
@@ -514,7 +514,7 @@ BluetoothGattManager::InitGattInterface(BluetoothProfileResultHandler* aRes)
if (NS_WARN_IF(!btInf)) {
// If there's no Bluetooth interface, we dispatch a runnable
// that calls the profile result handler.
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch GATT OnError runnable");
@@ -527,7 +527,7 @@ BluetoothGattManager::InitGattInterface(BluetoothProfileResultHandler* aRes)
if (NS_WARN_IF(!setupInterface)) {
// If there's no Setup interface, we dispatch a runnable
// that calls the profile result handler.
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch GATT OnError runnable");
@@ -540,7 +540,7 @@ BluetoothGattManager::InitGattInterface(BluetoothProfileResultHandler* aRes)
if (NS_WARN_IF(!gattInterface)) {
// If there's no GATT interface, we dispatch a runnable
// that calls the profile result handler.
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch GATT OnError runnable");
@@ -615,7 +615,7 @@ private:
};
class BluetoothGattManager::DeinitProfileResultHandlerRunnable final
: public nsRunnable
: public Runnable
{
public:
DeinitProfileResultHandlerRunnable(BluetoothProfileResultHandler* aRes,
@@ -651,7 +651,7 @@ BluetoothGattManager::DeinitGattInterface(BluetoothProfileResultHandler* aRes)
if (!sBluetoothGattInterface) {
BT_LOGR("Bluetooth GATT interface has not been initalized.");
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new DeinitProfileResultHandlerRunnable(aRes, NS_OK);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch GATT Deinit runnable");
@@ -664,7 +664,7 @@ BluetoothGattManager::DeinitGattInterface(BluetoothProfileResultHandler* aRes)
if (NS_WARN_IF(!btInf)) {
// If there's no backend interface, we dispatch a runnable
// that calls the profile result handler.
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new DeinitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch GATT OnError runnable");
@@ -677,7 +677,7 @@ BluetoothGattManager::DeinitGattInterface(BluetoothProfileResultHandler* aRes)
if (NS_WARN_IF(!setupInterface)) {
// If there's no Setup interface, we dispatch a runnable
// that calls the profile result handler.
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new DeinitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch GATT OnError runnable");
@@ -78,7 +78,7 @@ private:
};
class BluetoothHidManager::InitProfileResultHandlerRunnable final
: public nsRunnable
: public Runnable
{
public:
InitProfileResultHandlerRunnable(BluetoothProfileResultHandler* aRes,
@@ -114,7 +114,7 @@ BluetoothHidManager::InitHidInterface(BluetoothProfileResultHandler* aRes)
if (sBluetoothHidInterface) {
BT_LOGR("Bluetooth HID interface is already initialized.");
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new InitProfileResultHandlerRunnable(aRes, NS_OK);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch HID Init runnable");
@@ -127,7 +127,7 @@ BluetoothHidManager::InitHidInterface(BluetoothProfileResultHandler* aRes)
if (NS_WARN_IF(!btInf)) {
// If there's no backend interface, we dispatch a runnable
// that calls the profile result handler.
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch HID OnError runnable");
@@ -140,7 +140,7 @@ BluetoothHidManager::InitHidInterface(BluetoothProfileResultHandler* aRes)
if (NS_WARN_IF(!setupInterface)) {
// If there's no Setup interface, we dispatch a runnable
// that calls the profile result handler.
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch HID OnError runnable");
@@ -153,7 +153,7 @@ BluetoothHidManager::InitHidInterface(BluetoothProfileResultHandler* aRes)
if (NS_WARN_IF(!hidinterface)) {
// If there's no HID interface, we dispatch a runnable
// that calls the profile result handler.
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch HID OnError runnable");
@@ -230,7 +230,7 @@ private:
};
class BluetoothHidManager::DeinitProfileResultHandlerRunnable final
: public nsRunnable
: public Runnable
{
public:
DeinitProfileResultHandlerRunnable(BluetoothProfileResultHandler* aRes,
@@ -266,7 +266,7 @@ BluetoothHidManager::DeinitHidInterface(BluetoothProfileResultHandler* aRes)
if (!sBluetoothHidInterface) {
BT_LOGR("Bluetooth Hid interface has not been initialized.");
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new DeinitProfileResultHandlerRunnable(aRes, NS_OK);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch HID Deinit runnable");
@@ -279,7 +279,7 @@ BluetoothHidManager::DeinitHidInterface(BluetoothProfileResultHandler* aRes)
if (NS_WARN_IF(!btInf)) {
// If there's no backend interface, we dispatch a runnable
// that calls the profile result handler.
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new DeinitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch HID OnError runnable");
@@ -292,7 +292,7 @@ BluetoothHidManager::DeinitHidInterface(BluetoothProfileResultHandler* aRes)
if (NS_WARN_IF(!setupInterface)) {
// If there's no Setup interface, we dispatch a runnable
// that calls the profile result handler.
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new DeinitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch HID OnError runnable");
@@ -102,7 +102,7 @@ BluetoothOppManager::Observe(nsISupports* aSubject,
return NS_ERROR_UNEXPECTED;
}
class BluetoothOppManager::SendSocketDataTask final : public nsRunnable
class BluetoothOppManager::SendSocketDataTask final : public Runnable
{
public:
SendSocketDataTask(UniquePtr<uint8_t[]> aStream, uint32_t aSize)
@@ -126,7 +126,7 @@ private:
uint32_t mSize;
};
class BluetoothOppManager::ReadFileTask final : public nsRunnable
class BluetoothOppManager::ReadFileTask final : public Runnable
{
public:
ReadFileTask(nsIInputStream* aInputStream,
@@ -172,7 +172,7 @@ private:
uint32_t mAvailablePacketSize;
};
class BluetoothOppManager::CloseSocketTask final : public Task
class BluetoothOppManager::CloseSocketTask final : public Runnable
{
public:
CloseSocketTask(BluetoothSocket* aSocket) : mSocket(aSocket)
@@ -180,10 +180,11 @@ public:
MOZ_ASSERT(aSocket);
}
void Run() override
NS_IMETHOD Run() override
{
MOZ_ASSERT(NS_IsMainThread());
mSocket->Close();
return NS_OK;
}
private:
@@ -1138,8 +1139,8 @@ BluetoothOppManager::ClientDataHandler(UnixSocketBuffer* aMessage)
// Disconnect request, so we make a delay here. If the socket hasn't been
// disconnected, we will close it.
if (mSocket) {
MessageLoop::current()->
PostDelayedTask(FROM_HERE, new CloseSocketTask(mSocket), 1000);
MessageLoop::current()->PostDelayedTask(
MakeAndAddRef<CloseSocketTask>(mSocket), 1000);
}
} else if (mLastCommand == ObexRequestCode::Connect) {
MOZ_ASSERT(!mFileName.IsEmpty());
+32 -20
View File
@@ -200,12 +200,14 @@ public:
, mFd(aFd)
{ }
void Run() override
NS_IMETHOD Run() override
{
MOZ_ASSERT(!GetIO()->IsConsumerThread());
MOZ_ASSERT(!IsCanceled());
GetIO()->Connect(mFd);
return NS_OK;
}
private:
@@ -220,13 +222,14 @@ public:
, mFd(aFd)
{ }
void Run() override
NS_IMETHOD Run() override
{
MOZ_ASSERT(!GetIO()->IsConsumerThread());
if (!IsCanceled()) {
GetIO()->Listen(mFd);
}
return NS_OK;
}
private:
@@ -240,11 +243,13 @@ class SocketConnectClientFdTask final
: SocketIOTask<DroidSocketImpl>(aImpl)
{ }
void Run() override
NS_IMETHOD Run() override
{
MOZ_ASSERT(!GetIO()->IsConsumerThread());
GetIO()->ConnectClientFd();
return NS_OK;
}
};
@@ -303,7 +308,7 @@ DroidSocketImpl::Accept(int aFd)
mConnectionStatus = SOCKET_IS_CONNECTED;
GetConsumerThread()->PostTask(
FROM_HERE, new SocketEventTask(this, SocketEventTask::CONNECT_SUCCESS));
MakeAndAddRef<SocketEventTask>(this, SocketEventTask::CONNECT_SUCCESS));
AddWatchers(READ_WATCHER, true);
if (HasPendingData()) {
@@ -347,12 +352,14 @@ public:
, mFd(aFd)
{ }
void Run() override
NS_IMETHOD Run() override
{
MOZ_ASSERT(!GetIO()->IsConsumerThread());
MOZ_ASSERT(!IsCanceled());
GetIO()->Accept(mFd);
return NS_OK;
}
private:
@@ -386,8 +393,8 @@ public:
}
mImpl->mConsumer->SetAddress(aBdAddress);
mImpl->GetIOLoop()->PostTask(FROM_HERE,
new AcceptTask(mImpl, fd.forget()));
mImpl->GetIOLoop()->PostTask(
mozilla::MakeAndAddRef<AcceptTask>(mImpl, fd.forget()));
}
void OnError(BluetoothStatus aStatus) override
@@ -416,11 +423,13 @@ public:
, mListenFd(aListenFd)
{ }
void Run() override
NS_IMETHOD Run() override
{
MOZ_ASSERT(GetIO()->IsConsumerThread());
GetIO()->mConsumer->Accept(mListenFd, new AcceptResultHandler(GetIO()));
return NS_OK;
}
private:
@@ -438,7 +447,7 @@ DroidSocketImpl::OnSocketCanAcceptWithoutBlocking(int aFd)
*/
RemoveWatchers(READ_WATCHER);
GetConsumerThread()->PostTask(FROM_HERE, new InvokeAcceptTask(this, aFd));
GetConsumerThread()->PostTask(MakeAndAddRef<InvokeAcceptTask>(this, aFd));
}
void
@@ -483,7 +492,7 @@ DroidSocketImpl::OnSocketCanConnectWithoutBlocking(int aFd)
mConnectionStatus = SOCKET_IS_CONNECTED;
GetConsumerThread()->PostTask(
FROM_HERE, new SocketEventTask(this, SocketEventTask::CONNECT_SUCCESS));
MakeAndAddRef<SocketEventTask>(this, SocketEventTask::CONNECT_SUCCESS));
AddWatchers(READ_WATCHER, true);
if (HasPendingData()) {
@@ -519,7 +528,7 @@ public:
, mBuffer(aBuffer)
{ }
void Run() override
NS_IMETHOD Run() override
{
DroidSocketImpl* io = SocketTask<DroidSocketImpl>::GetIO();
@@ -528,13 +537,15 @@ public:
if (NS_WARN_IF(io->IsShutdownOnConsumerThread())) {
// Since we've already explicitly closed and the close
// happened before this, this isn't really an error.
return;
return NS_OK;
}
BluetoothSocket* bluetoothSocket = io->GetBluetoothSocket();
MOZ_ASSERT(bluetoothSocket);
bluetoothSocket->ReceiveSocketData(mBuffer);
return NS_OK;
}
private:
@@ -544,8 +555,8 @@ private:
void
DroidSocketImpl::ConsumeBuffer()
{
GetConsumerThread()->PostTask(FROM_HERE,
new ReceiveTask(this, mBuffer.release()));
GetConsumerThread()->PostTask(
MakeAndAddRef<ReceiveTask>(this, mBuffer.release()));
}
void
@@ -605,8 +616,8 @@ public:
}
mImpl->mConsumer->SetAddress(aBdAddress);
mImpl->GetIOLoop()->PostTask(FROM_HERE,
new SocketConnectTask(mImpl, aFd));
mImpl->GetIOLoop()->PostTask(
mozilla::MakeAndAddRef<SocketConnectTask>(mImpl, aFd));
}
void OnError(BluetoothStatus aStatus) override
@@ -682,7 +693,8 @@ public:
{
MOZ_ASSERT(mImpl->IsConsumerThread());
mImpl->GetIOLoop()->PostTask(FROM_HERE, new SocketListenTask(mImpl, aFd));
mImpl->GetIOLoop()->PostTask(
mozilla::MakeAndAddRef<SocketListenTask>(mImpl, aFd));
}
void OnError(BluetoothStatus aStatus) override
@@ -776,8 +788,8 @@ BluetoothSocket::SendSocketData(UnixSocketIOBuffer* aBuffer)
MOZ_ASSERT(!mImpl->IsShutdownOnConsumerThread());
mImpl->GetIOLoop()->PostTask(
FROM_HERE,
new SocketIOSendTask<DroidSocketImpl, UnixSocketIOBuffer>(mImpl, aBuffer));
MakeAndAddRef<SocketIOSendTask<DroidSocketImpl, UnixSocketIOBuffer>>(
mImpl, aBuffer));
}
// |SocketBase|
@@ -860,7 +872,7 @@ BluetoothSocket::Cleanup()
// sever the relationship here so any future calls to listen
// or connect will create a new implementation.
mImpl->ShutdownOnConsumerThread();
mImpl->GetIOLoop()->PostTask(FROM_HERE, new SocketIOShutdownTask(mImpl));
mImpl->GetIOLoop()->PostTask(MakeAndAddRef<SocketIOShutdownTask>(mImpl));
mImpl = nullptr;
mSocketInterface = nullptr;
@@ -277,10 +277,11 @@ SocketMessageWatcherTask::SocketMessageWatcherTask(
MOZ_ASSERT(mWatcher);
}
void
NS_IMETHODIMP
SocketMessageWatcherTask::Run()
{
mWatcher->Watch();
return NS_OK;
}
//
@@ -294,19 +295,20 @@ DeleteSocketMessageWatcherTask::DeleteSocketMessageWatcherTask(
MOZ_ASSERT(mRes);
}
void
NS_IMETHODIMP
DeleteSocketMessageWatcherTask::Run()
{
// look up hash table for the watcher corresponding to |mRes|
SocketMessageWatcherWrapper* wrapper = sWatcherHashtable.Get(mRes);
if (!wrapper) {
return;
return NS_OK;
}
// stop the watcher if it exists
SocketMessageWatcher* watcher = wrapper->GetSocketMessageWatcher();
watcher->StopWatching();
watcher->Proceed(STATUS_DONE);
return NS_OK;
}
END_BLUETOOTH_NAMESPACE
@@ -84,12 +84,12 @@ private:
/* |SocketMessageWatcherTask| starts a SocketMessageWatcher
* on the I/O task
*/
class SocketMessageWatcherTask final : public Task
class SocketMessageWatcherTask final : public Runnable
{
public:
SocketMessageWatcherTask(SocketMessageWatcher* aWatcher);
void Run() override;
NS_IMETHOD Run() override;
private:
SocketMessageWatcher* mWatcher;
@@ -98,12 +98,12 @@ private:
/* |DeleteSocketMessageWatcherTask| deletes a watching SocketMessageWatcher
* on the I/O task
*/
class DeleteSocketMessageWatcherTask final : public Task
class DeleteSocketMessageWatcherTask final : public Runnable
{
public:
DeleteSocketMessageWatcherTask(BluetoothSocketResultHandler* aRes);
void Run() override;
NS_IMETHOD Run() override;
private:
BluetoothSocketResultHandler* mRes;
@@ -108,17 +108,18 @@ protected:
~GetVolumeTask() { }
};
class BluetoothHfpManager::CloseScoTask : public Task
class BluetoothHfpManager::CloseScoTask : public Runnable
{
private:
void Run() override
NS_IMETHOD Run() override
{
MOZ_ASSERT(sBluetoothHfpManager);
sBluetoothHfpManager->DisconnectSco();
return NS_OK;
}
};
class BluetoothHfpManager::CloseScoRunnable : public nsRunnable
class BluetoothHfpManager::CloseScoRunnable : public Runnable
{
public:
NS_IMETHOD Run() override
@@ -126,16 +127,16 @@ public:
MOZ_ASSERT(NS_IsMainThread());
MessageLoop::current()->PostDelayedTask(
FROM_HERE, new CloseScoTask(), sBusyToneInterval);
MakeAndAddRef<CloseScoTask>(), sBusyToneInterval);
return NS_OK;
}
};
class BluetoothHfpManager::RespondToBLDNTask : public Task
class BluetoothHfpManager::RespondToBLDNTask : public Runnable
{
private:
void Run() override
NS_IMETHOD Run() override
{
MOZ_ASSERT(sBluetoothHfpManager);
@@ -143,6 +144,7 @@ private:
sBluetoothHfpManager->mDialingRequestProcessed = true;
sBluetoothHfpManager->SendResponse(HFP_AT_RESPONSE_ERROR);
}
return NS_OK;
}
};
@@ -319,7 +321,7 @@ private:
};
class BluetoothHfpManager::InitProfileResultHandlerRunnable final
: public nsRunnable
: public Runnable
{
public:
InitProfileResultHandlerRunnable(BluetoothProfileResultHandler* aRes,
@@ -355,7 +357,7 @@ BluetoothHfpManager::InitHfpInterface(BluetoothProfileResultHandler* aRes)
if (sBluetoothHfpInterface) {
BT_LOGR("Bluetooth Handsfree interface is already initalized.");
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new InitProfileResultHandlerRunnable(aRes, NS_OK);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch HFP Init runnable");
@@ -368,7 +370,7 @@ BluetoothHfpManager::InitHfpInterface(BluetoothProfileResultHandler* aRes)
if (NS_WARN_IF(!btInf)) {
// If there's no backend interface, we dispatch a runnable
// that calls the profile result handler.
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch HFP OnError runnable");
@@ -381,7 +383,7 @@ BluetoothHfpManager::InitHfpInterface(BluetoothProfileResultHandler* aRes)
if (NS_WARN_IF(!setupInterface)) {
// If there's no Setup interface, we dispatch a runnable
// that calls the profile result handler.
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch HFP OnError runnable");
@@ -394,7 +396,7 @@ BluetoothHfpManager::InitHfpInterface(BluetoothProfileResultHandler* aRes)
if (NS_WARN_IF(!interface)) {
// If there's no HFP interface, we dispatch a runnable
// that calls the profile result handler.
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch HFP OnError runnable");
@@ -471,7 +473,7 @@ private:
};
class BluetoothHfpManager::DeinitProfileResultHandlerRunnable final
: public nsRunnable
: public Runnable
{
public:
DeinitProfileResultHandlerRunnable(BluetoothProfileResultHandler* aRes,
@@ -507,7 +509,7 @@ BluetoothHfpManager::DeinitHfpInterface(BluetoothProfileResultHandler* aRes)
if (!sBluetoothHfpInterface) {
BT_LOGR("Bluetooth Handsfree interface has not been initialized.");
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new DeinitProfileResultHandlerRunnable(aRes, NS_OK);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch HFP Deinit runnable");
@@ -520,7 +522,7 @@ BluetoothHfpManager::DeinitHfpInterface(BluetoothProfileResultHandler* aRes)
if (NS_WARN_IF(!btInf)) {
// If there's no backend interface, we dispatch a runnable
// that calls the profile result handler.
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new DeinitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch HFP OnError runnable");
@@ -533,7 +535,7 @@ BluetoothHfpManager::DeinitHfpInterface(BluetoothProfileResultHandler* aRes)
if (NS_WARN_IF(!setupInterface)) {
// If there's no Setup interface, we dispatch a runnable
// that calls the profile result handler.
RefPtr<nsRunnable> r =
RefPtr<Runnable> r =
new DeinitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch HFP OnError runnable");
@@ -1597,8 +1599,7 @@ void BluetoothHfpManager::DialCallNotification(const nsAString& aNumber,
mDialingRequestProcessed = false;
NotifyDialer(NS_LITERAL_STRING("BLDN"));
MessageLoop::current()->PostDelayedTask(FROM_HERE,
new RespondToBLDNTask(),
MessageLoop::current()->PostDelayedTask(MakeAndAddRef<RespondToBLDNTask>(),
sWaitingForDialingInterval);
} else if (message[0] == '>') {
mDialingRequestProcessed = false;
@@ -1607,8 +1608,7 @@ void BluetoothHfpManager::DialCallNotification(const nsAString& aNumber,
newMsg += StringHead(message, message.Length() - 1);
NotifyDialer(NS_ConvertUTF8toUTF16(newMsg));
MessageLoop::current()->PostDelayedTask(FROM_HERE,
new RespondToBLDNTask(),
MessageLoop::current()->PostDelayedTask(MakeAndAddRef<RespondToBLDNTask>(),
sWaitingForDialingInterval);
} else {
SendResponse(HFP_AT_RESPONSE_OK);
@@ -1766,8 +1766,7 @@ BluetoothHfpManager::KeyPressedNotification(const BluetoothAddress& aBdAddress)
NotifyDialer(NS_LITERAL_STRING("BLDN"));
MessageLoop::current()->PostDelayedTask(FROM_HERE,
new RespondToBLDNTask(),
MessageLoop::current()->PostDelayedTask(MakeAndAddRef<RespondToBLDNTask>(),
sWaitingForDialingInterval);
}
}
File diff suppressed because it is too large Load Diff
+20 -19
View File
@@ -242,10 +242,10 @@ BluetoothHfpManager::Notify(const hal::BatteryInformation& aBatteryInfo)
}
#ifdef MOZ_B2G_RIL
class BluetoothHfpManager::RespondToBLDNTask : public Task
class BluetoothHfpManager::RespondToBLDNTask : public Runnable
{
private:
void Run() override
NS_IMETHOD Run() override
{
MOZ_ASSERT(sBluetoothHfpManager);
@@ -253,10 +253,11 @@ private:
sBluetoothHfpManager->mDialingRequestProcessed = true;
sBluetoothHfpManager->SendLine("ERROR");
}
return NS_OK;
}
};
class BluetoothHfpManager::SendRingIndicatorTask : public Task
class BluetoothHfpManager::SendRingIndicatorTask : public Runnable
{
public:
SendRingIndicatorTask(const nsAString& aNumber, int aType)
@@ -266,18 +267,18 @@ public:
MOZ_ASSERT(NS_IsMainThread());
}
void Run() override
NS_IMETHOD Run() override
{
MOZ_ASSERT(NS_IsMainThread());
// Stop sending RING indicator
if (sStopSendingRingFlag) {
return;
return NS_OK;
}
if (!sBluetoothHfpManager) {
BT_WARNING("BluetoothHfpManager no longer exists, cannot send ring!");
return;
return NS_OK;
}
nsAutoCString ringMsg("RING");
@@ -291,10 +292,10 @@ public:
sBluetoothHfpManager->SendLine(clipMsg.get());
}
MessageLoop::current()->
PostDelayedTask(FROM_HERE,
new SendRingIndicatorTask(mNumber, mType),
sRingInterval);
MessageLoop::current()->PostDelayedTask(
MakeAndAddRef<SendRingIndicatorTask>(mNumber, mType), sRingInterval);
return NS_OK;
}
private:
@@ -303,14 +304,16 @@ private:
};
#endif // MOZ_B2G_RIL
class BluetoothHfpManager::CloseScoTask : public Task
class BluetoothHfpManager::CloseScoTask : public Runnable
{
private:
void Run() override
NS_IMETHOD Run() override
{
MOZ_ASSERT(sBluetoothHfpManager);
sBluetoothHfpManager->DisconnectSco();
return NS_OK;
}
};
@@ -985,7 +988,7 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
}
MessageLoop::current()->
PostDelayedTask(FROM_HERE, new RespondToBLDNTask(),
PostDelayedTask(MakeAndAddRef<RespondToBLDNTask>(),
sWaitingForDialingInterval);
// Don't send response 'OK' here because we'll respond later in either
@@ -1490,7 +1493,7 @@ BluetoothHfpManager::HandleCallStateChanged(uint32_t aCallIndex,
}
mCurrentCallArray[aCallIndex].mNumber = aNumber;
RefPtr<nsRunnable> sendRingTask;
RefPtr<Runnable> sendRingTask;
nsString address;
switch (aCallState) {
@@ -1576,9 +1579,8 @@ BluetoothHfpManager::HandleCallStateChanged(uint32_t aCallIndex,
}
MessageLoop::current()->PostDelayedTask(
FROM_HERE,
new SendRingIndicatorTask(number,
mCurrentCallArray[aCallIndex].mType),
MakeAndAddRef<SendRingIndicatorTask>(
number, mCurrentCallArray[aCallIndex].mType),
sRingInterval);
}
break;
@@ -1686,8 +1688,7 @@ BluetoothHfpManager::HandleCallStateChanged(uint32_t aCallIndex,
DisconnectSco();
} else {
// Close Sco later since Dialer is still playing busy tone via HF.
MessageLoop::current()->PostDelayedTask(FROM_HERE,
new CloseScoTask(),
MessageLoop::current()->PostDelayedTask(MakeAndAddRef<CloseScoTask>(),
sBusyToneInterval);
}
+6 -5
View File
@@ -97,7 +97,7 @@ BluetoothOppManager::Observe(nsISupports* aSubject,
return NS_ERROR_UNEXPECTED;
}
class SendSocketDataTask : public nsRunnable
class SendSocketDataTask : public Runnable
{
public:
SendSocketDataTask(UniquePtr<uint8_t[]> aStream, uint32_t aSize)
@@ -121,7 +121,7 @@ private:
uint32_t mSize;
};
class ReadFileTask : public nsRunnable
class ReadFileTask : public Runnable
{
public:
ReadFileTask(nsIInputStream* aInputStream,
@@ -167,7 +167,7 @@ private:
uint32_t mAvailablePacketSize;
};
class CloseSocketTask : public Task
class CloseSocketTask : public Runnable
{
public:
CloseSocketTask(BluetoothSocket* aSocket) : mSocket(aSocket)
@@ -175,7 +175,7 @@ public:
MOZ_ASSERT(aSocket);
}
void Run() override
NS_IMETHOD Run() override
{
MOZ_ASSERT(NS_IsMainThread());
@@ -183,6 +183,7 @@ public:
SocketConnectionStatus::SOCKET_CONNECTED) {
mSocket->Close();
}
return NS_OK;
}
private:
@@ -1076,7 +1077,7 @@ BluetoothOppManager::ClientDataHandler(UnixSocketBuffer* aMessage)
// disconnected, we will close it.
if (mSocket) {
MessageLoop::current()->
PostDelayedTask(FROM_HERE, new CloseSocketTask(mSocket), 1000);
PostDelayedTask(MakeAndAddRef<CloseSocketTask>(mSocket), 1000);
}
} else if (mLastCommand == ObexRequestCode::Connect) {
MOZ_ASSERT(!mFileName.IsEmpty());
+30 -23
View File
@@ -43,7 +43,7 @@ public:
// Delayed-task handling
//
void SetDelayedConnectTask(CancelableTask* aTask);
void SetDelayedConnectTask(CancelableRunnable* aTask);
void ClearDelayedConnectTask();
void CancelDelayedConnectTask();
@@ -126,7 +126,7 @@ private:
* Task member for delayed connect task. Should only be access on consumer
* thread.
*/
CancelableTask* mDelayedConnectTask;
CancelableRunnable* mDelayedConnectTask;
/**
* I/O buffer for received data
@@ -193,7 +193,7 @@ BluetoothSocket::BluetoothSocketIO::GetDataSocket()
}
void
BluetoothSocket::BluetoothSocketIO::SetDelayedConnectTask(CancelableTask* aTask)
BluetoothSocket::BluetoothSocketIO::SetDelayedConnectTask(CancelableRunnable* aTask)
{
MOZ_ASSERT(IsConsumerThread());
@@ -285,7 +285,7 @@ BluetoothSocket::BluetoothSocketIO::OnConnected()
MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTED);
GetConsumerThread()->PostTask(
FROM_HERE, new SocketEventTask(this, SocketEventTask::CONNECT_SUCCESS));
MakeAndAddRef<SocketEventTask>(this, SocketEventTask::CONNECT_SUCCESS));
AddWatchers(READ_WATCHER, true);
if (HasPendingData()) {
@@ -334,7 +334,7 @@ BluetoothSocket::BluetoothSocketIO::OnSocketCanAcceptWithoutBlocking()
SetSocket(fd, SOCKET_IS_CONNECTED);
GetConsumerThread()->PostTask(
FROM_HERE, new SocketEventTask(this, SocketEventTask::CONNECT_SUCCESS));
MakeAndAddRef<SocketEventTask>(this, SocketEventTask::CONNECT_SUCCESS));
AddWatchers(READ_WATCHER, true);
if (HasPendingData()) {
@@ -384,7 +384,7 @@ BluetoothSocket::BluetoothSocketIO::FireSocketError()
// Tell the consumer thread we've errored
GetConsumerThread()->PostTask(
FROM_HERE, new SocketEventTask(this, SocketEventTask::CONNECT_ERROR));
MakeAndAddRef<SocketEventTask>(this, SocketEventTask::CONNECT_ERROR));
}
// |DataSocketIO|
@@ -416,7 +416,7 @@ public:
, mBuffer(aBuffer)
{ }
void Run() override
NS_IMETHOD Run() override
{
BluetoothSocketIO* io = SocketTask<BluetoothSocketIO>::GetIO();
@@ -425,13 +425,15 @@ public:
if (NS_WARN_IF(io->IsShutdownOnConsumerThread())) {
// Since we've already explicitly closed and the close
// happened before this, this isn't really an error.
return;
return NS_OK;
}
BluetoothSocket* bluetoothSocket = io->GetBluetoothSocket();
MOZ_ASSERT(bluetoothSocket);
bluetoothSocket->ReceiveSocketData(mBuffer);
return NS_OK;
}
private:
@@ -441,8 +443,8 @@ private:
void
BluetoothSocket::BluetoothSocketIO::ConsumeBuffer()
{
GetConsumerThread()->PostTask(FROM_HERE,
new ReceiveTask(this, mBuffer.release()));
GetConsumerThread()->PostTask(
MakeAndAddRef<ReceiveTask>(this, mBuffer.release()));
}
void
@@ -505,13 +507,14 @@ public:
: SocketIOTask<BluetoothSocketIO>(aIO)
{ }
void Run() override
NS_IMETHOD Run() override
{
MOZ_ASSERT(!GetIO()->IsConsumerThread());
if (!IsCanceled()) {
GetIO()->Listen();
}
return NS_OK;
}
};
@@ -523,12 +526,14 @@ public:
: SocketIOTask<BluetoothSocketIO>(aIO)
{ }
void Run() override
NS_IMETHOD Run() override
{
MOZ_ASSERT(!GetIO()->IsConsumerThread());
MOZ_ASSERT(!IsCanceled());
GetIO()->Connect();
return NS_OK;
}
};
@@ -540,21 +545,23 @@ public:
: SocketIOTask<BluetoothSocketIO>(aIO)
{ }
void Run() override
NS_IMETHOD Run() override
{
MOZ_ASSERT(GetIO()->IsConsumerThread());
if (IsCanceled()) {
return;
return NS_OK;
}
BluetoothSocketIO* io = GetIO();
if (io->IsShutdownOnConsumerThread()) {
return;
return NS_OK;
}
io->ClearDelayedConnectTask();
io->GetIOLoop()->PostTask(FROM_HERE, new ConnectTask(io));
io->GetIOLoop()->PostTask(MakeAndAddRef<ConnectTask>(io));
return NS_OK;
}
};
@@ -670,11 +677,12 @@ BluetoothSocket::Connect(BluetoothUnixSocketConnector* aConnector,
SetConnectionStatus(SOCKET_CONNECTING);
if (aDelayMs > 0) {
DelayedConnectTask* connectTask = new DelayedConnectTask(mIO);
RefPtr<DelayedConnectTask> connectTask =
MakeAndAddRef<DelayedConnectTask>(mIO);
mIO->SetDelayedConnectTask(connectTask);
MessageLoop::current()->PostDelayedTask(FROM_HERE, connectTask, aDelayMs);
MessageLoop::current()->PostDelayedTask(connectTask.forget(), aDelayMs);
} else {
aIOLoop->PostTask(FROM_HERE, new ConnectTask(mIO));
aIOLoop->PostTask(MakeAndAddRef<ConnectTask>(mIO));
}
return NS_OK;
@@ -700,7 +708,7 @@ BluetoothSocket::Listen(BluetoothUnixSocketConnector* aConnector,
mIO = new BluetoothSocketIO(aConsumerLoop, aIOLoop, this, aConnector);
SetConnectionStatus(SOCKET_LISTENING);
aIOLoop->PostTask(FROM_HERE, new ListenTask(mIO));
aIOLoop->PostTask(MakeAndAddRef<ListenTask>(mIO));
return NS_OK;
}
@@ -733,8 +741,7 @@ BluetoothSocket::SendSocketData(UnixSocketIOBuffer* aBuffer)
MOZ_ASSERT(!mIO->IsShutdownOnConsumerThread());
mIO->GetIOLoop()->PostTask(
FROM_HERE,
new SocketIOSendTask<BluetoothSocketIO, UnixSocketIOBuffer>(mIO, aBuffer));
MakeAndAddRef<SocketIOSendTask<BluetoothSocketIO, UnixSocketIOBuffer>>(mIO, aBuffer));
}
// |SocketBase|
@@ -754,7 +761,7 @@ BluetoothSocket::Close()
// We sever the relationship here so any future calls to listen or connect
// will create a new implementation.
mIO->ShutdownOnConsumerThread();
mIO->GetIOLoop()->PostTask(FROM_HERE, new SocketIOShutdownTask(mIO));
mIO->GetIOLoop()->PostTask(MakeAndAddRef<SocketIOShutdownTask>(mIO));
mIO = nullptr;
NotifyDisconnect();
@@ -25,7 +25,7 @@ BEGIN_BLUETOOTH_NAMESPACE
class BluetoothReply;
class BluetoothReplyRunnable : public nsRunnable
class BluetoothReplyRunnable : public Runnable
{
public:
NS_DECL_NSIRUNNABLE
@@ -96,7 +96,7 @@ protected:
}
};
class BluetoothReplyTaskQueue : public nsRunnable
class BluetoothReplyTaskQueue : public Runnable
{
public:
NS_DECL_NSIRUNNABLE
+2 -2
View File
@@ -434,7 +434,7 @@ BluetoothService::StartBluetooth(bool aIsStartup,
}
} else {
BT_WARNING("Bluetooth has already been enabled before.");
RefPtr<nsRunnable> runnable = new BluetoothService::ToggleBtAck(true);
RefPtr<Runnable> runnable = new BluetoothService::ToggleBtAck(true);
if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
BT_WARNING("Failed to dispatch to main thread!");
}
@@ -465,7 +465,7 @@ BluetoothService::StopBluetooth(bool aIsStartup,
}
} else {
BT_WARNING("Bluetooth has already been enabled/disabled before.");
RefPtr<nsRunnable> runnable = new BluetoothService::ToggleBtAck(false);
RefPtr<Runnable> runnable = new BluetoothService::ToggleBtAck(false);
if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
BT_WARNING("Failed to dispatch to main thread!");
}
+1 -1
View File
@@ -41,7 +41,7 @@ class BluetoothService : public nsIObserver
friend class StartupTask;
public:
class ToggleBtAck : public nsRunnable
class ToggleBtAck : public Runnable
{
public:
ToggleBtAck(bool aEnabled);
@@ -897,9 +897,9 @@ private:
{
mService->AssignAppUuid(mServer->mAppUuid);
RefPtr<nsRunnable> runnable = new AddServiceTaskQueue(mServer,
mService,
mPromise);
RefPtr<Runnable> runnable = new AddServiceTaskQueue(mServer,
mService,
mPromise);
nsresult rv = NS_DispatchToMainThread(runnable.forget());
if (NS_WARN_IF(NS_FAILED(rv))) {
+2 -2
View File
@@ -153,7 +153,7 @@ TestGonkCameraHardwareListener::HandleEvent(nsIDOMEvent* aEvent)
OnTakePictureError(mTarget);
} else if (errorType.EqualsLiteral("system")) {
if (!NS_WARN_IF(!mCameraThread)) {
class DeferredSystemFailure : public nsRunnable
class DeferredSystemFailure : public Runnable
{
public:
DeferredSystemFailure(nsGonkCameraControl* aTarget)
@@ -228,7 +228,7 @@ TestGonkCameraHardwareListener::HandleEvent(nsIDOMEvent* aEvent)
NS_IMPL_ISUPPORTS(TestGonkCameraHardwareListener, nsIDOMEventListener)
class TestGonkCameraHardware::ControlMessage : public nsRunnable
class TestGonkCameraHardware::ControlMessage : public Runnable
{
public:
ControlMessage(TestGonkCameraHardware* aTestHw)
+4 -6
View File
@@ -115,10 +115,9 @@ CryptoBuffer::FromJwkBase64(const nsString& aBase64)
NS_ConvertUTF16toUTF8 temp(aBase64);
temp.StripWhitespace();
Base64URLDecodeOptions options;
// JWK prohibits padding per RFC 7515, section 2.
options.mPadding = Base64URLDecodePadding::Reject;
nsresult rv = Base64URLDecode(temp, options, *this);
nsresult rv = Base64URLDecode(temp, Base64URLDecodePaddingPolicy::Reject,
*this);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
@@ -134,9 +133,8 @@ CryptoBuffer::ToJwkBase64(nsString& aBase64)
}
nsAutoCString base64;
Base64URLEncodeOptions options;
options.mPad = false;
nsresult rv = Base64URLEncode(Length(), Elements(), options, base64);
nsresult rv = Base64URLEncode(Length(), Elements(),
Base64URLEncodePaddingPolicy::Omit, base64);
NS_ENSURE_SUCCESS(rv, rv);
CopyASCIItoUTF16(base64, aBase64);
-2
View File
@@ -1,2 +0,0 @@
component {db5c9602-030f-4bff-a3de-881a8de370f2} DataStoreImpl.js
contract @mozilla.org/dom/datastore;1 {db5c9602-030f-4bff-a3de-881a8de370f2}
-54
View File
@@ -1,54 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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;
enum RunStatus {
Success,
CreatedSchema,
Error
};
virtual void Run(DataStoreDB* aDb, RunStatus aStatus) = 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()
{
}
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_DataStoreCallbacks_h
-223
View File
@@ -1,223 +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 = ["DataStoreChangeNotifier"];
function debug(s) {
//dump('DEBUG DataStoreChangeNotifier: ' + 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");
XPCOMUtils.defineLazyServiceGetter(this, "systemMessenger",
"@mozilla.org/system-message-internal;1",
"nsISystemMessagesInternal");
var kSysMsgOnChangeShortTimeoutSec =
Services.prefs.getIntPref("dom.datastore.sysMsgOnChangeShortTimeoutSec");
var kSysMsgOnChangeLongTimeoutSec =
Services.prefs.getIntPref("dom.datastore.sysMsgOnChangeLongTimeoutSec");
this.DataStoreChangeNotifier = {
children: [],
messages: [ "DataStore:Changed", "DataStore:RegisterForMessages",
"DataStore:UnregisterForMessages",
"child-process-shutdown" ],
// These hashes are used for storing the mapping between the datastore
// identifiers (name | owner manifest URL) and their correspondent timers.
// The object literal is defined as below:
//
// {
// "datastore name 1|owner manifest URL 1": timer1,
// "datastore name 2|owner manifest URL 2": timer2,
// ...
// }
sysMsgOnChangeShortTimers: {},
sysMsgOnChangeLongTimers: {},
init: function() {
debug("init");
this.messages.forEach((function(msgName) {
ppmm.addMessageListener(msgName, this);
}).bind(this));
Services.obs.addObserver(this, 'xpcom-shutdown', false);
},
observe: function(aSubject, aTopic, aData) {
debug("observe");
switch (aTopic) {
case 'xpcom-shutdown':
this.messages.forEach((function(msgName) {
ppmm.removeMessageListener(msgName, this);
}).bind(this));
Services.obs.removeObserver(this, 'xpcom-shutdown');
ppmm = null;
break;
default:
debug("Wrong observer topic: " + aTopic);
break;
}
},
broadcastMessage: function broadcastMessage(aData) {
debug("broadcast");
this.children.forEach(function(obj) {
if (obj.store == aData.store && obj.owner == aData.owner) {
obj.mm.sendAsyncMessage("DataStore:Changed:Return:OK", aData);
}
});
},
broadcastSystemMessage: function(aStore, aOwner) {
debug("broadcastSystemMessage");
// Clear relevant timers.
var storeKey = aStore + "|" + aOwner;
var shortTimer = this.sysMsgOnChangeShortTimers[storeKey];
if (shortTimer) {
shortTimer.cancel();
delete this.sysMsgOnChangeShortTimers[storeKey];
}
var longTimer = this.sysMsgOnChangeLongTimers[storeKey];
if (longTimer) {
longTimer.cancel();
delete this.sysMsgOnChangeLongTimers[storeKey];
}
systemMessenger.broadcastMessage("datastore-update-" + aStore,
{ owner: aOwner });
},
// Use the following logic to broadcast system messages in a moderate pattern.
// 1. When an entry is changed, start a short timer and a long timer.
// 2. If an entry is changed while the short timer is running, reset it.
// Do not reset the long timer.
// 3. Once either fires, broadcast the system message and cancel both timers.
setSystemMessageTimeout: function(aStore, aOwner) {
debug("setSystemMessageTimeout");
var storeKey = aStore + "|" + aOwner;
// Reset the short timer.
var shortTimer = this.sysMsgOnChangeShortTimers[storeKey];
if (!shortTimer) {
shortTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
this.sysMsgOnChangeShortTimers[storeKey] = shortTimer;
} else {
shortTimer.cancel();
}
shortTimer.initWithCallback({ notify: this.broadcastSystemMessage.bind(this, aStore, aOwner) },
kSysMsgOnChangeShortTimeoutSec * 1000,
Ci.nsITimer.TYPE_ONE_SHOT);
// Set the long timer if necessary.
if (!this.sysMsgOnChangeLongTimers[storeKey]) {
var longTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
this.sysMsgOnChangeLongTimers[storeKey] = longTimer;
longTimer.initWithCallback({ notify: this.broadcastSystemMessage.bind(this, aStore, aOwner) },
kSysMsgOnChangeLongTimeoutSec * 1000,
Ci.nsITimer.TYPE_ONE_SHOT);
}
},
receiveMessage: function(aMessage) {
debug("receiveMessage ");
// No check has to be done when the message is 'child-process-shutdown'.
if (aMessage.name != "child-process-shutdown") {
let principal = aMessage.principal;
if (!principal || !dataStoreService.checkPermission(principal)) {
return;
}
}
switch (aMessage.name) {
case "DataStore:Changed":
this.broadcastMessage(aMessage.data);
if (Services.prefs.getBoolPref("dom.sysmsg.enabled")) {
this.setSystemMessageTimeout(aMessage.data.store, aMessage.data.owner);
}
break;
case "DataStore:RegisterForMessages":
debug("Register!");
for (let i = 0; i < this.children.length; ++i) {
if (this.children[i].mm == aMessage.target &&
this.children[i].store == aMessage.data.store &&
this.children[i].owner == aMessage.data.owner) {
debug("Register on existing index: " + i);
this.children[i].windows.push(aMessage.data.innerWindowID);
return;
}
}
this.children.push({ mm: aMessage.target,
store: aMessage.data.store,
owner: aMessage.data.owner,
windows: [ aMessage.data.innerWindowID ]});
break;
case "DataStore:UnregisterForMessages":
debug("Unregister");
for (let i = 0; i < this.children.length; ++i) {
if (this.children[i].mm == aMessage.target) {
debug("Unregister index: " + i);
var pos = this.children[i].windows.indexOf(aMessage.data.innerWindowID);
if (pos != -1) {
this.children[i].windows.splice(pos, 1);
}
if (this.children[i].windows.length) {
continue;
}
debug("Unregister delete index: " + i);
this.children.splice(i, 1);
--i;
}
}
break;
case "child-process-shutdown":
debug("Child process shutdown");
for (let i = 0; i < this.children.length; ++i) {
if (this.children[i].mm == aMessage.target) {
debug("Unregister index: " + i);
this.children.splice(i, 1);
--i;
}
}
break;
default:
debug("Wrong message: " + aMessage.name);
}
}
}
DataStoreChangeNotifier.init();
-79
View File
@@ -1,79 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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 "mozilla/dom/DataStore.h"
#include "mozilla/dom/DataStoreCursor.h"
#include "mozilla/dom/DataStoreBinding.h"
#include "mozilla/dom/DataStoreImplBinding.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/ErrorResult.h"
#include "nsPIDOMWindow.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTING_ADDREF(DataStoreCursor)
NS_IMPL_CYCLE_COLLECTING_RELEASE(DataStoreCursor)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DataStoreCursor)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION(DataStoreCursor, mCursor)
already_AddRefed<DataStoreCursor>
DataStoreCursor::Constructor(GlobalObject& aGlobal, ErrorResult& aRv)
{
RefPtr<DataStoreCursor> cursor = new DataStoreCursor();
return cursor.forget();
}
bool
DataStoreCursor::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto,
JS::MutableHandle<JSObject*> aReflector)
{
return DataStoreCursorBinding::Wrap(aCx, this, aGivenProto, aReflector);
}
already_AddRefed<DataStore>
DataStoreCursor::GetStore(ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mCursor);
return mCursor->GetStore(aRv);
}
already_AddRefed<Promise>
DataStoreCursor::Next(ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mCursor);
return mCursor->Next(aRv);
}
void
DataStoreCursor::Close(ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mCursor);
mCursor->Close(aRv);
}
void
DataStoreCursor::SetDataStoreCursorImpl(DataStoreCursorImpl& aCursor)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!mCursor);
mCursor = &aCursor;
}
} //namespace dom
} //namespace mozilla
-59
View File
@@ -1,59 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_DataStoreCursor_h
#define mozilla_dom_DataStoreCursor_h
#include "nsAutoPtr.h"
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
namespace mozilla {
class ErrorResult;
namespace dom {
class Promise;
class DataStore;
class GlobalObject;
class DataStoreCursorImpl;
class DataStoreCursor final : public nsISupports
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(DataStoreCursor)
// WebIDL (internal functions)
static already_AddRefed<DataStoreCursor> Constructor(GlobalObject& aGlobal,
ErrorResult& aRv);
bool WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector);
// WebIDL (public APIs)
already_AddRefed<DataStore> GetStore(ErrorResult& aRv);
already_AddRefed<Promise> Next(ErrorResult& aRv);
void Close(ErrorResult& aRv);
// This internal function (ChromeOnly) is aimed to make the DataStoreCursor
// keep a reference to the DataStoreCursorImpl which really implements the
// API's logic in JS.
void SetDataStoreCursorImpl(DataStoreCursorImpl& aCursor);
private:
~DataStoreCursor() {}
RefPtr<DataStoreCursorImpl> mCursor;
};
} //namespace dom
} //namespace mozilla
#endif
-444
View File
@@ -1,444 +0,0 @@
/* -*- js-indent-level: 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 = ['DataStoreCursor'];
function debug(s) {
//dump('DEBUG DataStoreCursor: ' + s + '\n');
}
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
const STATE_INIT = 0;
const STATE_REVISION_INIT = 1;
const STATE_REVISION_CHECK = 2;
const STATE_SEND_ALL = 3;
const STATE_REVISION_SEND = 4;
const STATE_DONE = 5;
const REVISION_ADDED = 'added';
const REVISION_UPDATED = 'updated';
const REVISION_REMOVED = 'removed';
const REVISION_VOID = 'void';
const REVISION_SKIP = 'skip'
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
/**
* legend:
* - RID = revision ID
* - R = revision object (with the internalRevisionId that is a number)
* - X = current object ID.
* - L = the list of revisions that we have to send
*
* State: init: do you have RID ?
* YES: state->initRevision; loop
* NO: get R; X=0; state->sendAll; send a 'clear'
*
* State: initRevision. Get R from RID. Done?
* YES: state->revisionCheck; loop
* NO: RID = null; state->init; loop
*
* State: revisionCheck: get all the revisions between R and NOW. Done?
* YES and R == NOW: state->done; loop
* YES and R != NOW: Store this revisions in L; state->revisionSend; loop
* NO: R = NOW; X=0; state->sendAll; send a 'clear'
*
* State: sendAll: is R still the last revision?
* YES get the first object with id > X. Done?
* YES: X = object.id; send 'add'
* NO: state->revisionCheck; loop
* NO: R = NOW; X=0; send a 'clear'
*
* State: revisionSend: do you have something from L to send?
* YES and L[0] == 'removed': R=L[0]; send 'remove' with ID
* YES and L[0] == 'added': R=L[0]; get the object; found?
* NO: loop
* YES: send 'add' with ID and object
* YES and L[0] == 'updated': R=L[0]; get the object; found?
* NO: loop
* YES and object.R > R: continue
* YES and object.R <= R: send 'update' with ID and object
* YES L[0] == 'void': R=L[0]; state->init; loop
* NO: state->revisionCheck; loop
*
* State: done: send a 'done' with R
*/
/* Helper functions */
function createDOMError(aWindow, aEvent) {
return new aWindow.DOMError(aEvent);
}
/* DataStoreCursor object */
this.DataStoreCursor = function(aWindow, aDataStore, aRevisionId) {
debug("DataStoreCursor created");
this.init(aWindow, aDataStore, aRevisionId);
}
this.DataStoreCursor.prototype = {
classDescription: 'DataStoreCursor XPCOM Component',
classID: Components.ID('{b6d14349-1eab-46b8-8513-584a7328a26b}'),
contractID: '@mozilla.org/dom/datastore-cursor-impl;1',
QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsISupports]),
_shuttingdown: false,
_window: null,
_dataStore: null,
_revisionId: null,
_revision: null,
_revisionsList: null,
_objectId: 0,
_state: STATE_INIT,
init: function(aWindow, aDataStore, aRevisionId) {
debug('DataStoreCursor init');
this._window = aWindow;
this._dataStore = aDataStore;
this._revisionId = aRevisionId;
Services.obs.addObserver(this, "inner-window-destroyed", false);
let util = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
this._innerWindowID = util.currentInnerWindowID;
},
observe: function(aSubject, aTopic, aData) {
let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data;
if (wId == this._innerWindowID) {
Services.obs.removeObserver(this, "inner-window-destroyed");
this._shuttingdown = true;
}
},
// This is the implementation of the state machine.
// Read the comments at the top of this file in order to follow what it does.
stateMachine: function(aStore, aRevisionStore, aResolve, aReject) {
debug('StateMachine: ' + this._state);
// If the window has been destroyed we cannot create the Promise object.
if (this._shuttingdown) {
return;
}
switch (this._state) {
case STATE_INIT:
this.stateMachineInit(aStore, aRevisionStore, aResolve, aReject);
break;
case STATE_REVISION_INIT:
this.stateMachineRevisionInit(aStore, aRevisionStore, aResolve, aReject);
break;
case STATE_REVISION_CHECK:
this.stateMachineRevisionCheck(aStore, aRevisionStore, aResolve, aReject);
break;
case STATE_SEND_ALL:
this.stateMachineSendAll(aStore, aRevisionStore, aResolve, aReject);
break;
case STATE_REVISION_SEND:
this.stateMachineRevisionSend(aStore, aRevisionStore, aResolve, aReject);
break;
case STATE_DONE:
this.stateMachineDone(aStore, aRevisionStore, aResolve, aReject);
break;
}
},
stateMachineInit: function(aStore, aRevisionStore, aResolve, aReject) {
debug('StateMachineInit');
if (this._revisionId) {
this._state = STATE_REVISION_INIT;
this.stateMachine(aStore, aRevisionStore, aResolve, aReject);
return;
}
let self = this;
let request = aRevisionStore.openCursor(null, 'prev');
request.onsuccess = function(aEvent) {
if (aEvent.target.result === undefined) {
aReject(self._window.DOMError("InvalidRevision",
"The DataStore is corrupted"));
return;
}
self._revision = aEvent.target.result.value;
self._objectId = 0;
self._state = STATE_SEND_ALL;
aResolve(self.createTask('clear', null, '', null));
}
},
stateMachineRevisionInit: function(aStore, aRevisionStore, aResolve, aReject) {
debug('StateMachineRevisionInit');
let self = this;
let request = this._dataStore._db.getInternalRevisionId(
self._revisionId,
aRevisionStore,
function(aInternalRevisionId) {
// This revision doesn't exist.
if (aInternalRevisionId == undefined) {
self._revisionId = null;
self._objectId = 0;
self._state = STATE_INIT;
self.stateMachine(aStore, aRevisionStore, aResolve, aReject);
return;
}
self._revision = { revisionId: self._revisionId,
internalRevisionId: aInternalRevisionId };
self._state = STATE_REVISION_CHECK;
self.stateMachine(aStore, aRevisionStore, aResolve, aReject);
}
);
},
stateMachineRevisionCheck: function(aStore, aRevisionStore, aResolve, aReject) {
debug('StateMachineRevisionCheck');
let changes = {
addedIds: {},
updatedIds: {},
removedIds: {}
};
let self = this;
let request = aRevisionStore.mozGetAll(
self._window.IDBKeyRange.lowerBound(this._revision.internalRevisionId, true));
request.onsuccess = function(aEvent) {
// Optimize the operations.
for (let i = 0; i < aEvent.target.result.length; ++i) {
let data = aEvent.target.result[i];
switch (data.operation) {
case REVISION_ADDED:
changes.addedIds[data.objectId] = data.internalRevisionId;
break;
case REVISION_UPDATED:
// We don't consider an update if this object has been added
// or if it has been already modified by a previous
// operation.
if (!(data.objectId in changes.addedIds) &&
!(data.objectId in changes.updatedIds)) {
changes.updatedIds[data.objectId] = data.internalRevisionId;
}
break;
case REVISION_REMOVED:
let id = data.objectId;
// If the object has been added in this range of revisions
// we can ignore it and remove it from the list.
if (id in changes.addedIds) {
delete changes.addedIds[id];
} else {
changes.removedIds[id] = data.internalRevisionId;
}
if (id in changes.updatedIds) {
delete changes.updatedIds[id];
}
break;
case REVISION_VOID:
if (i != 0) {
dump('Internal error: Revision "' + REVISION_VOID + '" should not be found!!!\n');
return;
}
self._revisionId = null;
self._objectId = 0;
self._state = STATE_INIT;
self.stateMachine(aStore, aRevisionStore, aResolve, aReject);
return;
}
}
// From changes to a map of internalRevisionId.
let revisions = {};
function addRevisions(obj) {
for (let key in obj) {
revisions[obj[key]] = true;
}
}
addRevisions(changes.addedIds);
addRevisions(changes.updatedIds);
addRevisions(changes.removedIds);
// Create the list of revisions.
let list = [];
for (let i = 0; i < aEvent.target.result.length; ++i) {
let data = aEvent.target.result[i];
// If this revision doesn't contain useful data, we still need to keep
// it in the list because we need to update the internal revision ID.
if (!(data.internalRevisionId in revisions)) {
data.operation = REVISION_SKIP;
}
list.push(data);
}
if (list.length == 0) {
self._state = STATE_DONE;
self.stateMachine(aStore, aRevisionStore, aResolve, aReject);
return;
}
// Some revision has to be sent.
self._revisionsList = list;
self._state = STATE_REVISION_SEND;
self.stateMachine(aStore, aRevisionStore, aResolve, aReject);
};
},
stateMachineSendAll: function(aStore, aRevisionStore, aResolve, aReject) {
debug('StateMachineSendAll');
let self = this;
let request = aRevisionStore.openCursor(null, 'prev');
request.onsuccess = function(aEvent) {
if (self._revision.revisionId != aEvent.target.result.value.revisionId) {
self._revision = aEvent.target.result.value;
self._objectId = 0;
aResolve(self.createTask('clear', null, '', null));
return;
}
let request = aStore.openCursor(self._window.IDBKeyRange.lowerBound(self._objectId, true));
request.onsuccess = function(aEvent) {
let cursor = aEvent.target.result;
if (!cursor) {
self._state = STATE_REVISION_CHECK;
self.stateMachine(aStore, aRevisionStore, aResolve, aReject);
return;
}
self._objectId = cursor.key;
aResolve(self.createTask('add', self._objectId, '', cursor.value));
};
};
},
stateMachineRevisionSend: function(aStore, aRevisionStore, aResolve, aReject) {
debug('StateMachineRevisionSend');
if (!this._revisionsList.length) {
this._state = STATE_REVISION_CHECK;
this.stateMachine(aStore, aRevisionStore, aResolve, aReject);
return;
}
this._revision = this._revisionsList.shift();
switch (this._revision.operation) {
case REVISION_REMOVED:
aResolve(this.createTask('remove', this._revision.objectId, '', null));
break;
case REVISION_ADDED: {
let request = aStore.get(this._revision.objectId);
let self = this;
request.onsuccess = function(aEvent) {
if (aEvent.target.result == undefined) {
self.stateMachine(aStore, aRevisionStore, aResolve, aReject);
return;
}
aResolve(self.createTask('add', self._revision.objectId, '',
aEvent.target.result));
}
break;
}
case REVISION_UPDATED: {
let request = aStore.get(this._revision.objectId);
let self = this;
request.onsuccess = function(aEvent) {
if (aEvent.target.result == undefined) {
self.stateMachine(aStore, aRevisionStore, aResolve, aReject);
return;
}
if (aEvent.target.result.revisionId > self._revision.internalRevisionId) {
self.stateMachine(aStore, aRevisionStore, aResolve, aReject);
return;
}
aResolve(self.createTask('update', self._revision.objectId, '',
aEvent.target.result));
}
break;
}
case REVISION_VOID:
// Internal error!
dump('Internal error: Revision "' + REVISION_VOID + '" should not be found!!!\n');
break;
case REVISION_SKIP:
// This revision contains data that has already been sent by another one.
this.stateMachine(aStore, aRevisionStore, aResolve, aReject);
break;
}
},
stateMachineDone: function(aStore, aRevisionStore, aResolve, aReject) {
this.close();
aResolve(this.createTask('done', null, this._revision.revisionId, null));
},
// public interface
get store() {
return this._dataStore.exposedObject;
},
next: function() {
debug('Next');
// If the window has been destroyed we cannot create the Promise object.
if (this._shuttingdown) {
throw Cr.NS_ERROR_FAILURE;
}
let self = this;
return new this._window.Promise(function(aResolve, aReject) {
self._dataStore._db.cursorTxn(
function(aTxn, aStore, aRevisionStore) {
self.stateMachine(aStore, aRevisionStore, aResolve, aReject);
},
function(aEvent) {
aReject(createDOMError(self._window, aEvent));
}
);
});
},
close: function() {
this._dataStore.syncTerminated(this);
},
createTask: function(aOperation, aId, aRevisionId, aData) {
return Cu.cloneInto({ operation: aOperation, id: aId,
revisionId: aRevisionId, data: aData }, this._window);
}
};
-80
View File
@@ -1,80 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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 {
class DataStoreDBCallback;
class IDBDatabase;
class IDBFactory;
class IDBOpenDBRequest;
class IDBTransaction;
class DataStoreDB final : public nsIDOMEventListener
{
public:
NS_DECL_ISUPPORTS
DataStoreDB(const nsAString& aManifestURL, const nsAString& aName);
nsresult Open(IDBTransactionMode aMode, const Sequence<nsString>& aDb,
DataStoreDBCallback* aCallback);
nsresult Delete();
IDBTransaction* Transaction() const;
// nsIDOMEventListener
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) override;
private:
~DataStoreDB();
nsresult CreateFactoryIfNeeded();
nsresult UpgradeSchema(nsIDOMEvent* aEvent);
nsresult DatabaseOpened();
nsresult AddEventListeners();
nsresult RemoveEventListeners();
nsString mDatabaseName;
RefPtr<IDBFactory> mFactory;
RefPtr<IDBOpenDBRequest> mRequest;
RefPtr<IDBDatabase> mDatabase;
RefPtr<IDBTransaction> mTransaction;
RefPtr<DataStoreDBCallback> mCallback;
// Internal state to avoid strange use of this class.
enum StateType {
Inactive,
Active
} mState;
IDBTransactionMode mTransactionMode;
Sequence<nsString> mObjectStores;
bool mCreatedSchema;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_DataStoreDB_h
-118
View File
@@ -1,118 +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 = ['DataStoreDB'];
function debug(s) {
//dump('DEBUG DataStoreDB: ' + s + '\n');
}
const DATASTOREDB_VERSION = 1;
const DATASTOREDB_OBJECTSTORE_NAME = 'DataStoreDB';
const DATASTOREDB_REVISION = 'revision';
const DATASTOREDB_REVISION_INDEX = 'revisionIndex';
Cu.import('resource://gre/modules/IndexedDBHelper.jsm');
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.importGlobalProperties(["indexedDB"]);
XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
"@mozilla.org/uuid-generator;1",
"nsIUUIDGenerator");
this.DataStoreDB = function DataStoreDB() {}
DataStoreDB.prototype = {
__proto__: IndexedDBHelper.prototype,
upgradeSchema: function(aTransaction, aDb, aOldVersion, aNewVersion) {
debug('updateSchema');
aDb.createObjectStore(DATASTOREDB_OBJECTSTORE_NAME, { autoIncrement: true });
let store = aDb.createObjectStore(DATASTOREDB_REVISION,
{ autoIncrement: true,
keyPath: 'internalRevisionId' });
store.createIndex(DATASTOREDB_REVISION_INDEX, 'revisionId', { unique: true });
},
init: function(aOwner, aName) {
let dbName = aName + '|' + aOwner;
this.initDBHelper(dbName, DATASTOREDB_VERSION,
[DATASTOREDB_OBJECTSTORE_NAME, DATASTOREDB_REVISION]);
},
txn: function(aType, aCallback, aErrorCb) {
debug('Transaction request');
this.newTxn(
aType,
aType == 'readonly'
? [ DATASTOREDB_OBJECTSTORE_NAME ] : [ DATASTOREDB_OBJECTSTORE_NAME, DATASTOREDB_REVISION ],
function(aTxn, aStores) {
aType == 'readonly' ? aCallback(aTxn, aStores[0], null) : aCallback(aTxn, aStores[0], aStores[1]);
},
function() {},
aErrorCb
);
},
cursorTxn: function(aCallback, aErrorCb) {
debug('Cursor transaction request');
this.newTxn(
'readonly',
[ DATASTOREDB_OBJECTSTORE_NAME, DATASTOREDB_REVISION ],
function(aTxn, aStores) {
aCallback(aTxn, aStores[0], aStores[1]);
},
function() {},
aErrorCb
);
},
revisionTxn: function(aType, aCallback, aErrorCb) {
debug("Transaction request");
this.newTxn(
aType,
DATASTOREDB_REVISION,
aCallback,
function() {},
aErrorCb
);
},
addRevision: function(aStore, aKey, aType, aSuccessCb) {
debug("AddRevision: " + aKey + " - " + aType);
let revisionId = uuidgen.generateUUID().toString();
let request = aStore.put({ revisionId: revisionId, objectId: aKey, operation: aType });
request.onsuccess = function() {
aSuccessCb(revisionId);
}
},
getInternalRevisionId: function(aRevisionId, aStore, aSuccessCb) {
debug('GetInternalRevisionId');
let request = aStore.index(DATASTOREDB_REVISION_INDEX).getKey(aRevisionId);
request.onsuccess = function(aEvent) {
aSuccessCb(aEvent.target.result);
}
},
clearRevisions: function(aStore, aSuccessCb) {
debug("ClearRevisions");
let request = aStore.clear();
request.onsuccess = function() {
aSuccessCb();
}
},
delete: function() {
debug('delete');
this.close();
indexedDB.deleteDatabase(this.dbName);
debug('database deleted');
}
}
-549
View File
@@ -1,549 +0,0 @@
/* -*- js-indent-level: 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'
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";
const REVISION_REMOVED = "removed";
const REVISION_VOID = "void";
// This value has to be tuned a bit. Currently it's just a guess
// and yet we don't know if it's too low or too high.
const MAX_REQUESTS = 25;
Cu.import("resource://gre/modules/DataStoreCursorImpl.jsm");
Cu.import("resource://gre/modules/DataStoreDB.jsm");
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
Cu.importGlobalProperties(["indexedDB"]);
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
"@mozilla.org/childprocessmessagemanager;1",
"nsIMessageSender");
/* Helper functions */
function createDOMError(aWindow, aEvent) {
return new aWindow.DOMError(aEvent);
}
function throwInvalidArg(aWindow) {
return aWindow.Promise.reject(
new aWindow.DOMError("SyntaxError", "Non-numeric or invalid id"));
}
function throwReadOnly(aWindow) {
return aWindow.Promise.reject(
new aWindow.DOMError("ReadOnlyError", "DataStore in readonly mode"));
}
function validateId(aId) {
// If string, it cannot be empty.
if (typeof(aId) == 'string') {
return aId.length;
}
aId = parseInt(aId);
return (!isNaN(aId) && aId > 0);
}
/* DataStore object */
function DataStore() {
debug("DataStore created");
}
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]),
callbacks: [],
_window: null,
_name: null,
_owner: null,
_readOnly: null,
_revisionId: null,
_exposedObject: null,
_cursor: null,
_shuttingdown: false,
_eventTarget: null,
init: function(aWindow, aName, aOwner, aReadOnly) {
debug("DataStore init");
this._window = aWindow;
this._name = aName;
this._owner = aOwner;
this._readOnly = aReadOnly;
this._db = new DataStoreDB();
this._db.init(aOwner, aName);
Services.obs.addObserver(this, "inner-window-destroyed", false);
let util = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
this._innerWindowID = util.currentInnerWindowID;
cpmm.addMessageListener("DataStore:Changed:Return:OK", this);
cpmm.sendAsyncMessage("DataStore:RegisterForMessages",
{ store: this._name, owner: this._owner,
innerWindowID: this._innerWindowID },
null,
this._window.document.nodePrincipal);
},
observe: function(aSubject, aTopic, aData) {
let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data;
if (wId == this._innerWindowID) {
Services.obs.removeObserver(this, "inner-window-destroyed");
cpmm.removeMessageListener("DataStore:Changed:Return:OK", this);
cpmm.sendAsyncMessage("DataStore:UnregisterForMessages",
{ innerWindowID: this._innerWindowID },
null,
this._window.document.nodePrincipal);
this._shuttingdown = true;
this._db.close();
}
},
setEventTarget: function(aEventTarget) {
this._eventTarget = aEventTarget;
},
newDBPromise: function(aTxnType, aFunction) {
let self = this;
return new this._window.Promise(function(aResolve, aReject) {
debug("DBPromise started");
self._db.txn(
aTxnType,
function(aTxn, aStore, aRevisionStore) {
debug("DBPromise success");
aFunction(aResolve, aReject, aTxn, aStore, aRevisionStore);
},
function(aEvent) {
debug("DBPromise error");
aReject(createDOMError(self._window, aEvent));
}
);
});
},
checkRevision: function(aReject, aRevisionStore, aRevisionId, aCallback) {
if (!aRevisionId) {
aCallback();
return;
}
let self = this;
let request = aRevisionStore.openCursor(null, 'prev');
request.onsuccess = function(aEvent) {
let cursor = aEvent.target.result;
if (!cursor) {
dump("This cannot really happen.");
return;
}
if (cursor.value.revisionId != aRevisionId) {
aReject(new self._window.DOMError("ConstraintError",
"RevisionId is not up-to-date"));
return;
}
aCallback();
}
},
getInternal: function(aStore, aIds, aCallback) {
debug("GetInternal: " + aIds.toSource());
// Creation of the results array.
let results = new this._window.Array(aIds.length);
// We're going to create this amount of requests.
let pendingIds = aIds.length;
let indexPos = 0;
let self = this;
function getInternalSuccess(aEvent, aPos) {
debug("GetInternal success. Record: " + aEvent.target.result);
results[aPos] = Cu.cloneInto(aEvent.target.result, self._window);
if (!--pendingIds) {
aCallback(results);
return;
}
if (indexPos < aIds.length) {
// Just MAX_REQUESTS requests at the same time.
let count = 0;
while (indexPos < aIds.length && ++count < MAX_REQUESTS) {
getInternalRequest();
}
}
}
function getInternalRequest() {
let currentPos = indexPos++;
let request = aStore.get(aIds[currentPos]);
request.onsuccess = function(aEvent) {
getInternalSuccess(aEvent, currentPos);
}
}
getInternalRequest();
},
putInternal: function(aResolve, aStore, aRevisionStore, aObj, aId) {
debug("putInternal " + aId);
let self = this;
let request = aStore.put(aObj, aId);
request.onsuccess = function(aEvent) {
debug("putInternal success");
self.addRevision(aRevisionStore, aId, REVISION_UPDATED,
function() {
debug("putInternal - revisionId increased");
// No wrap here because the result is always a int.
aResolve(aEvent.target.result);
}
);
};
},
addInternal: function(aResolve, aStore, aRevisionStore, aObj, aId) {
debug("AddInternal");
let self = this;
let request = aStore.add(aObj, aId);
request.onsuccess = function(aEvent) {
debug("Request successful. Id: " + aEvent.target.result);
self.addRevision(aRevisionStore, aEvent.target.result, REVISION_ADDED,
function() {
debug("AddInternal - revisionId increased");
// No wrap here because the result is always a int.
aResolve(aEvent.target.result);
}
);
};
},
removeInternal: function(aResolve, aStore, aRevisionStore, aId) {
debug("RemoveInternal");
let self = this;
let request = aStore.get(aId);
request.onsuccess = function(aEvent) {
debug("RemoveInternal success. Record: " + aEvent.target.result);
if (aEvent.target.result === undefined) {
aResolve(false);
return;
}
let deleteRequest = aStore.delete(aId);
deleteRequest.onsuccess = function() {
debug("RemoveInternal success");
self.addRevision(aRevisionStore, aId, REVISION_REMOVED,
function() {
aResolve(true);
}
);
};
};
},
clearInternal: function(aResolve, aStore, aRevisionStore) {
debug("ClearInternal");
let self = this;
let request = aStore.clear();
request.onsuccess = function() {
debug("ClearInternal success");
self._db.clearRevisions(aRevisionStore,
function() {
debug("Revisions cleared");
self.addRevision(aRevisionStore, null, REVISION_VOID,
function() {
debug("ClearInternal - revisionId increased");
aResolve();
}
);
}
);
};
},
getLengthInternal: function(aResolve, aStore) {
debug("GetLengthInternal");
let request = aStore.count();
request.onsuccess = function(aEvent) {
debug("GetLengthInternal success: " + aEvent.target.result);
// No wrap here because the result is always a int.
aResolve(aEvent.target.result);
};
},
addRevision: function(aRevisionStore, aId, aType, aSuccessCb) {
let self = this;
this._db.addRevision(aRevisionStore, aId, aType,
function(aRevisionId) {
self._revisionId = aRevisionId;
self.sendNotification(aId, aType, aRevisionId);
aSuccessCb();
}
);
},
retrieveRevisionId: function(aSuccessCb) {
let self = this;
this._db.revisionTxn(
'readonly',
function(aTxn, aRevisionStore) {
debug("RetrieveRevisionId transaction success");
let request = aRevisionStore.openCursor(null, 'prev');
request.onsuccess = function(aEvent) {
let cursor = aEvent.target.result;
if (cursor) {
self._revisionId = cursor.value.revisionId;
}
aSuccessCb(self._revisionId);
};
}
);
},
sendNotification: function(aId, aOperation, aRevisionId) {
debug("SendNotification");
if (aOperation == REVISION_VOID) {
aOperation = "cleared";
}
cpmm.sendAsyncMessage("DataStore:Changed",
{ store: this.name, owner: this._owner,
message: { revisionId: aRevisionId, id: aId,
operation: aOperation, owner: this._owner } },
null,
this._window.document.nodePrincipal);
},
receiveMessage: function(aMessage) {
debug("receiveMessage");
if (aMessage.name != "DataStore:Changed:Return:OK") {
debug("Wrong message: " + aMessage.name);
return;
}
// If this message is not for this DataStore, let's ignore it.
if (aMessage.data.owner != this._owner ||
aMessage.data.store != this._name) {
return;
}
let self = this;
this.retrieveRevisionId(
function() {
// If the window has been destroyed we don't emit the events.
if (self._shuttingdown) {
return;
}
// If we have an active cursor we don't emit events.
if (self._cursor) {
return;
}
let event = new self._window.DataStoreChangeEvent('change',
aMessage.data.message);
self._eventTarget.dispatchEvent(event);
}
);
},
get exposedObject() {
debug("get exposedObject");
return this._exposedObject;
},
set exposedObject(aObject) {
debug("set exposedObject");
this._exposedObject = aObject;
},
syncTerminated: function(aCursor) {
// This checks is to avoid that an invalid cursor stops a sync.
if (this._cursor == aCursor) {
this._cursor = null;
}
},
// Public interface :
get name() {
return this._name;
},
get owner() {
return this._owner;
},
get readOnly() {
return this._readOnly;
},
get: function() {
let ids = Array.prototype.slice.call(arguments);
for (let i = 0; i < ids.length; ++i) {
if (!validateId(ids[i])) {
return throwInvalidArg(this._window);
}
}
if (ids.length == 0) {
return this._window.Promise.resolve(new this._window.Array());
}
let self = this;
// Promise<Object>
return this.newDBPromise("readonly",
function(aResolve, aReject, aTxn, aStore, aRevisionStore) {
self.getInternal(aStore, ids,
function(aResults) {
aResolve(ids.length > 1 ? aResults : aResults[0]);
});
}
);
},
put: function(aObj, aId, aRevisionId) {
if (!validateId(aId)) {
return throwInvalidArg(this._window);
}
if (this._readOnly) {
return throwReadOnly(this._window);
}
let self = this;
// Promise<void>
return this.newDBPromise("readwrite",
function(aResolve, aReject, aTxn, aStore, aRevisionStore) {
self.checkRevision(aReject, aRevisionStore, aRevisionId, function() {
self.putInternal(aResolve, aStore, aRevisionStore, aObj, aId);
});
}
);
},
add: function(aObj, aId, aRevisionId) {
if (aId) {
if (!validateId(aId)) {
return throwInvalidArg(this._window);
}
}
if (this._readOnly) {
return throwReadOnly(this._window);
}
let self = this;
// Promise<int>
return this.newDBPromise("readwrite",
function(aResolve, aReject, aTxn, aStore, aRevisionStore) {
self.checkRevision(aReject, aRevisionStore, aRevisionId, function() {
self.addInternal(aResolve, aStore, aRevisionStore, aObj, aId);
});
}
);
},
remove: function(aId, aRevisionId) {
if (!validateId(aId)) {
return throwInvalidArg(this._window);
}
if (this._readOnly) {
return throwReadOnly(this._window);
}
let self = this;
// Promise<void>
return this.newDBPromise("readwrite",
function(aResolve, aReject, aTxn, aStore, aRevisionStore) {
self.checkRevision(aReject, aRevisionStore, aRevisionId, function() {
self.removeInternal(aResolve, aStore, aRevisionStore, aId);
});
}
);
},
clear: function(aRevisionId) {
if (this._readOnly) {
return throwReadOnly(this._window);
}
let self = this;
// Promise<void>
return this.newDBPromise("readwrite",
function(aResolve, aReject, aTxn, aStore, aRevisionStore) {
self.checkRevision(aReject, aRevisionStore, aRevisionId, function() {
self.clearInternal(aResolve, aStore, aRevisionStore);
});
}
);
},
get revisionId() {
return this._revisionId;
},
getLength: function() {
let self = this;
// Promise<int>
return this.newDBPromise("readonly",
function(aResolve, aReject, aTxn, aStore, aRevisionStore) {
self.getLengthInternal(aResolve, aStore);
}
);
},
sync: function(aRevisionId) {
debug("Sync");
this._cursor = new DataStoreCursor(this._window, this, aRevisionId);
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]);
-100
View File
@@ -1,100 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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/IDBObjectStore.h"
#include "mozilla/dom/IDBRequest.h"
#include "mozilla/dom/ToJSValue.h"
#include "nsIDOMEvent.h"
namespace mozilla {
namespace dom {
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);
RefPtr<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_CRASH("This should not happen");
}
JS::Rooted<JS::Value> value(aCx);
if (!ToJSValue(aCx, data, &value)) {
return NS_ERROR_FAILURE;
}
ErrorResult error;
mRequest = aStore->Put(aCx, value, JS::UndefinedHandleValue, error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
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_CRASH("This should not happen");
}
mRequest->RemoveEventListener(NS_LITERAL_STRING("success"), this, false);
mRequest = nullptr;
mCallback->Run(mRevisionID);
return NS_OK;
}
} // namespace dom
} // namespace mozilla
-50
View File
@@ -1,50 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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 {
class DataStoreRevisionCallback;
class IDBObjectStore;
class IDBRequest;
class DataStoreRevision final : public nsIDOMEventListener
{
public:
NS_DECL_ISUPPORTS
enum RevisionType {
RevisionVoid
};
nsresult AddRevision(JSContext* aCx,
IDBObjectStore* aStore,
uint32_t aObjectId,
RevisionType aRevisionType,
DataStoreRevisionCallback* aCallback);
// nsIDOMEventListener
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) override;
private:
~DataStoreRevision() {}
RefPtr<DataStoreRevisionCallback> mCallback;
RefPtr<IDBRequest> mRequest;
nsString mRevisionID;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_DataStoreRevision_h
-50
View File
@@ -1,50 +0,0 @@
# -*- 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',
]
UNIFIED_SOURCES += [
'DataStore.cpp',
'DataStoreCursor.cpp',
'DataStoreDB.cpp',
'DataStoreRevision.cpp',
'DataStoreService.cpp',
]
LOCAL_INCLUDES += [
'/js/xpconnect/wrappers',
]
EXTRA_COMPONENTS += [
'DataStore.manifest',
'DataStoreImpl.js',
]
EXTRA_JS_MODULES += [
'DataStoreChangeNotifier.jsm',
'DataStoreCursorImpl.jsm',
'DataStoreDB.jsm',
]
MOCHITEST_MANIFESTS += ['tests/mochitest.ini']
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']
-55
View File
@@ -1,55 +0,0 @@
var gBasePath = "tests/dom/datastore/tests/";
function handleRequest(request, response) {
var query = getQuery(request);
var testToken = '';
if ('testToken' in query) {
testToken = query.testToken;
}
var template = 'file_app.template.webapp';
if ('template' in query) {
template = query.template;
}
var template = gBasePath + template;
response.setHeader("Content-Type", "application/x-web-app-manifest+json", false);
response.write(readTemplate(template).replace(/TESTTOKEN/g, testToken));
}
// Copy-pasted incantations. There ought to be a better way to synchronously read
// a file into a string, but I guess we're trying to discourage that.
function readTemplate(path) {
var file = Components.classes["@mozilla.org/file/directory_service;1"].
getService(Components.interfaces.nsIProperties).
get("CurWorkD", Components.interfaces.nsILocalFile);
var fis = Components.classes['@mozilla.org/network/file-input-stream;1'].
createInstance(Components.interfaces.nsIFileInputStream);
var cis = Components.classes["@mozilla.org/intl/converter-input-stream;1"].
createInstance(Components.interfaces.nsIConverterInputStream);
var split = path.split("/");
for(var i = 0; i < split.length; ++i) {
file.append(split[i]);
}
fis.init(file, -1, -1, false);
cis.init(fis, "UTF-8", 0, 0);
var data = "";
let str = {};
let read = 0;
do {
read = cis.readString(0xffffffff, str); // read as much as we can and put it in str.value
data += str.value;
} while (read != 0);
cis.close();
return data;
}
function getQuery(request) {
var query = {};
request.queryString.split('&').forEach(function (val) {
var [name, value] = val.split('=');
query[name] = unescape(value);
});
return query;
}
@@ -1,10 +0,0 @@
{
"name": "Really Rapid Release (hosted)",
"description": "Updated even faster than <a href='http://mozilla.org'>Firefox</a>, just to annoy slashdotters.",
"launch_path": "/tests/dom/datastore/tests/TESTTOKEN",
"icons": { "128": "default_icon" },
"datastores-owned" : {
"foo" : { "access": "readwrite", "description" : "This store is called foo" },
"bar" : { "access": "readonly", "description" : "This store is called bar" }
}
}
@@ -1,10 +0,0 @@
{
"name": "Really Rapid Release (hosted) - app 2",
"description": "Updated even faster than <a href='http://mozilla.org'>Firefox</a>, just to annoy slashdotters.",
"launch_path": "/tests/dom/datastore/tests/TESTTOKEN",
"icons": { "128": "default_icon" },
"datastores-access" : {
"foo" : { "readonly": false, "description" : "This store is called foo" },
"bar" : { "readonly": true, "description" : "This store is called bar" }
}
}
-91
View File
@@ -1,91 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - install/uninstall apps</title>
<body>
<script type="application/javascript;version=1.7">
var gHostedManifestURL = 'http://test/tests/dom/datastore/tests/file_app.sjs?testToken=file_app_install.html';
function is(a, b, msg) {
alert((a === b ? 'OK' : 'KO') + ' ' + msg)
}
function ok(a, msg) {
alert((a ? 'OK' : 'KO')+ ' ' + msg)
}
function cbError() {
alert('KO error');
}
function finish() {
alert('DONE');
}
var tests = [
// Get datastore with name 'foo'
function() {
navigator.getDataStores('foo').then(function(stores) {
is(stores.length, 1, "getDataStores('foo') returns 1 element");
is(stores[0].name, 'foo', 'The dataStore.name is foo');
ok(stores[0].owner, 'The dataStore.owner exists');
is(stores[0].readOnly, false, 'The dataStore foo is not in readonly');
runTest();
}, cbError);
},
// Get datastore with name 'bar'
function() {
navigator.getDataStores('bar').then(function(stores) {
is(stores.length, 1, "getDataStores('bar') returns 1 element");
is(stores[0].name, 'bar', 'The dataStore.name is bar');
ok(stores[0].owner, 'The dataStore.owner exists');
is(stores[0].readOnly, false, 'The dataStore bar is in readonly');
runTest();
}, cbError);
},
// Get datastore with name 'foo' and a specified owner
function() {
navigator.getDataStores('foo', gHostedManifestURL).then(function(stores) {
is(stores.length, 1, "getDataStores('foo','" + gHostedManifestURL +
"') returns 1 element");
is(stores[0].name, 'foo', 'The dataStore.name is foo');
ok(stores[0].owner, 'The dataStore.owner exists');
is(stores[0].readOnly, false, 'The dataStore foo is not in readonly');
runTest();
}, cbError);
},
// Get datastore with name 'foo' and an arbitrary non-existent owner
function() {
navigator.getDataStores('foo', 'non-existent').then(function(stores) {
is(stores.length, 0, "getDataStores('foo','non-existent') returns 0 element");
runTest();
}, cbError);
},
// Get datastore with an arbitrary non-existent name
function() {
navigator.getDataStores('non-existent').then(function(stores) {
is(stores.length, 0, "getDataStores('non-existent') returns 0 element");
runTest();
}, cbError);
},
];
function runTest() {
if (!tests.length) {
finish();
return;
}
var test = tests.shift();
test();
}
runTest();
</script>
</html>
-110
View File
@@ -1,110 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - add([array]) remove([array])</title>
</head>
<body>
<div id="container"></div>
<script type="application/javascript;version=1.7">
var gStore;
function is(a, b, msg) {
alert((a === b ? 'OK' : 'KO') + ' ' + msg)
}
function ok(a, msg) {
alert((a ? 'OK' : 'KO')+ ' ' + msg)
}
function cbError() {
alert('KO error');
}
function finish() {
alert('DONE');
}
function testGetDataStores() {
navigator.getDataStores('foo').then(function(stores) {
is(stores.length, 1, "getDataStores('foo') returns 1 element");
is(stores[0].name, 'foo', 'The dataStore.name is foo');
is(stores[0].readOnly, false, 'The dataStore foo is not in readonly');
var store = stores[0];
ok("get" in store, "store.get exists");
ok("put" in store, "store.put exists");
ok("add" in store, "store.add exists");
ok("remove" in store, "store.remove exists");
ok("clear" in store, "store.clear exists");
gStore = stores[0];
runTest();
}, cbError);
}
var itemNumber = 60;
function testStoreAdd() {
var objects = [];
for (var i = 0; i < itemNumber; ++i) {
objects.push(i);
}
function testStoreAddInternal() {
if (!objects.length) {
ok(true, "We inserted " + itemNumber + " items");
runTest();
return;
}
var obj = objects.shift();
gStore.add(obj).then(function() {
ok(true, "We inserted a new item!");
testStoreAddInternal();
}, cbError);
}
testStoreAddInternal();
}
function testStoreGet() {
var objects = [];
for (var i = 1; i <= itemNumber; ++i) {
objects.push(i);
}
gStore.get.apply(gStore, objects).then(function(data) {
is(data.length, objects.length, "Get - Data matches");
for (var i = 0; i < data.length; ++i) {
is(data[i], objects[i] - 1, "Get - Data matches: " + i + " " + data[i] + " == " + objects[i]);
}
runTest();
}, cbError);
}
var tests = [
// Test for GetDataStore
testGetDataStores,
// Add many items
function() { testStoreAdd() },
function() { testStoreGet() },
];
function runTest() {
if (!tests.length) {
finish();
return;
}
var test = tests.shift();
test();
}
runTest();
</script>
</body>
</html>
-31
View File
@@ -1,31 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - basic operation on a readonly db</title>
<script type="text/javascript" src="file_basic_common.js"></script>
</head>
<body>
<div id="container"></div>
<script type="application/javascript;version=1.7">
function is(a, b, msg) {
alert((a === b ? 'OK' : 'KO') + ' ' + msg)
}
function ok(a, msg) {
alert((a ? 'OK' : 'KO')+ ' ' + msg)
}
function cbError() {
alert('KO error');
}
function finish() {
alert('DONE');
}
runTest();
</script>
</body>
</html>
-119
View File
@@ -1,119 +0,0 @@
var gStore;
function testGetDataStores() {
navigator.getDataStores('foo').then(function(stores) {
is(stores.length, 1, "getDataStores('foo') returns 1 element");
is(stores[0].name, 'foo', 'The dataStore.name is foo');
is(stores[0].readOnly, false, 'The dataStore foo is not in readonly');
var store = stores[0];
ok("get" in store, "store.get exists");
ok("put" in store, "store.put exists");
ok("add" in store, "store.add exists");
ok("remove" in store, "store.remove exists");
ok("clear" in store, "store.clear exists");
ok("revisionId" in store, "store.revisionId exists");
ok("getLength" in store, "store.getLength exists");
ok("sync" in store, "store.sync exists");
gStore = stores[0];
runTest();
}, cbError);
}
function testStoreGet(id, value) {
gStore.get(id).then(function(what) {
ok(true, "store.get() retrieves data");
is(what, value, "store.get(" + id + ") returns " + value);
}, function() {
ok(false, "store.get(" + id + ") retrieves data");
}).then(runTest, cbError);
}
function testStoreAdd(value) {
return gStore.add(value).then(function(what) {
ok(true, "store.add() is called");
ok(what > 0, "store.add() returns something");
return what;
}, cbError);
}
function testStorePut(value, id) {
return gStore.put(value, id).then(function() {
ok(true, "store.put() is called");
}, cbError);
}
function testStoreGetLength(number) {
return gStore.getLength().then(function(n) {
is(number, n, "store.getLength() returns the right number");
}, cbError);
}
function testStoreRemove(id) {
return gStore.remove(id).then(function() {
ok(true, "store.remove() is called");
}, cbError);
}
function testStoreClear() {
return gStore.clear().then(function() {
ok(true, "store.clear() is called");
}, cbError);
}
var tests = [
// Test for GetDataStore
testGetDataStores,
// Unknown ID
function() { testStoreGet(42, undefined); },
function() { testStoreGet(42, undefined); }, // twice
// Add + Get - number
function() { testStoreAdd(42).then(function(id) {
gId = id; runTest(); }, cbError); },
function() { testStoreGet(gId, 42); },
// Add + Get - boolean
function() { testStoreAdd(true).then(function(id) {
gId = id; runTest(); }, cbError); },
function() { testStoreGet(gId, true); },
// Add + Get - string
function() { testStoreAdd("hello world").then(function(id) {
gId = id; runTest(); }, cbError); },
function() { testStoreGet(gId, "hello world"); },
// Put + Get - string
function() { testStorePut("hello world 2", gId).then(function() {
runTest(); }, cbError); },
function() { testStoreGet(gId, "hello world 2"); },
// getLength
function() { testStoreGetLength(3).then(function() { runTest(); }, cbError); },
// Remove
function() { testStoreRemove(gId).then(function(what) {
runTest(); }, cbError); },
function() { testStoreGet(gId, undefined); },
// Remove - wrong ID
function() { testStoreRemove(gId).then(function(what) {
runTest(); }, cbError); },
// Clear
function() { testStoreClear().then(function(what) {
runTest(); }, cbError); },
];
function runTest() {
if (!tests.length) {
finish();
return;
}
var test = tests.shift();
test();
}
@@ -1,30 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - basic operation on a readonly db</title>
</head>
<body>
<div id="container"></div>
<script type="application/javascript;version=1.7">
var messages = [];
var worker = new Worker("file_basic_worker.js");
worker.onmessage = function(event) {
messages.push(event.data)
if (event.data == 'DONE') {
// Free the worker when all the tests are done.
worker.terminate();
// Fire message to the test_basic_worker.html.
for (var i = 0; i < messages.length; i++) {
alert(messages[i]);
}
}
}
</script>
</body>
</html>
-19
View File
@@ -1,19 +0,0 @@
function is(a, b, msg) {
postMessage((a === b ? 'OK' : 'KO') + ' ' + msg)
}
function ok(a, msg) {
postMessage((a ? 'OK' : 'KO')+ ' ' + msg)
}
function cbError() {
postMessage('KO error');
}
function finish() {
postMessage('DONE');
}
importScripts("file_basic_common.js");
runTest();
-46
View File
@@ -1,46 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - bug 1008044</title>
</head>
<body>
<div id="container"></div>
<script type="application/javascript;version=1.7">
function ok(a, msg) {
alert((!!a ? 'OK' : 'KO') + ' ' + msg)
}
function cbError() {
alert('KO error');
}
function finish() {
alert('DONE');
}
navigator.getDataStores('foo').then(function(stores) {
if (stores[0].name != 'foo') {
ok(false, "Wrong name is received! Expected 'foo'");
}
runTest();
});
navigator.getDataStores('bar').then(function(stores) {
if (stores[0].name != 'bar') {
ok(false, "Wrong name is received! Expected 'bar'");
}
runTest();
});
var pending = 2;
function runTest() {
if (--pending == 0) {
ok(true, "Test passed!");
finish();
}
}
</script>
</body>
</html>
-40
View File
@@ -1,40 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - basic operation on a readonly db</title>
<script type="text/javascript" src="file_basic_common.js"></script>
</head>
<body>
<div id="container"></div>
<script type="application/javascript;version=1.7">
function is(a, b, msg) {
ok(a === b, msg);
}
function ok(a, msg) {
alert((a ? 'OK' : 'KO') + ' ' + msg)
}
function finish() {
alert('DONE');
}
navigator.getDataStores('foo').then(function(stores) {
is(stores.length, 1, "getDataStores('foo') returns 1 element");
is(stores[0].name, 'foo', 'The dataStore.name is foo');
is(stores[0].readOnly, false, 'The dataStore foo is not in readonly');
var store = stores[0];
store.get.apply(store, []).then(function(a) {
ok(Array.isArray(a), "bug 1058108");
is(a.length, 0, "bug 1058108");
finish();
});
});
</script>
</body>
</html>
-77
View File
@@ -1,77 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for bug 924104</title>
</head>
<body>
<div id="container"></div>
<script type="application/javascript;version=1.7">
var gStore;
function is(a, b, msg) {
alert((a === b ? 'OK' : 'KO') + ' ' + msg)
}
function ok(a, msg) {
alert((a ? 'OK' : 'KO')+ ' ' + msg)
}
function cbError() {
alert('KO error');
}
function finish() {
alert('DONE');
}
function testGetDataStores() {
navigator.getDataStores('foo').then(function(stores) {
gStore = stores[0];
runTest();
}, cbError);
}
function testBug924104() {
gStore
.add({})
.then(
function(index) {
ok(index, "store.add() created item" + index);
return gStore.get(index);
},
cbError)
.then(
function(obj) {
ok(true, "store.get() works");
var status = false;
try {
obj['foobar'] = 42;
status = true;
} catch(e) {}
ok(status, "Object is editable");
runTest();
},
cbError);
}
var tests = [
testGetDataStores,
testBug924104
];
function runTest() {
if (!tests.length) {
finish();
return;
}
var test = tests.shift();
test();
}
runTest();
</script>
</body>
</html>
-34
View File
@@ -1,34 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - bug 1008044</title>
</head>
<body>
<div id="container"></div>
<script type="application/javascript;version=1.7">
function is(a, b, msg) {
alert((a == b ? 'OK' : 'KO') + ' ' + msg)
}
function cbError() {
alert('KO error');
}
function finish() {
alert('DONE');
}
navigator.getDataStores('foo').then(function(stores) {
is (stores.length, 1, "Correct number of Stores");
is (stores[0].name, 'foo', "Correct name is received!");
stores[0].get(42).then(function(something) {
is (something, null, "Correct value");
finish();
}, cbError);
}, cbError);
</script>
</body>
</html>
-88
View File
@@ -1,88 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - bug 976311 app1</title>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript;version=1.7">
var gStores = [];
var expectedWhere;
function is(a, b, msg) {
ok(a === b, msg);
}
function ok(a, msg) {
alert((a ? 'OK' : 'KO')+ ' ' + msg)
}
function cbError() {
alert('KO error');
}
function finish() {
alert('DONE');
}
function checkEvent(id) {
is(expectedWhere, id, "Message on the correct DS: " + id + " " + expectedWhere);
runTest();
}
function testGetDataStores() {
navigator.getDataStores('foo').then(function(stores) {
is(stores.length, 2, "getDataStores('foo') returns 1 element");
is(stores[0].name, 'foo', 'The dataStore.name is foo');
is(stores[0].readOnly, false, 'The dataStore foo is not in readonly');
stores[0].onchange = function(evt) { checkEvent(0); }
gStores.push(stores[0]);
is(stores[1].name, 'foo', 'The dataStore.name is foo');
is(stores[1].readOnly, false, 'The dataStore foo is not in readonly');
stores[1].onchange = function(evt) { checkEvent(1); }
gStores.push(stores[1]);
runTest();
}, cbError);
}
function testStoreAdd(where, value) {
expectedWhere = where;
dump("ADD TO: " + gStores[where].owner + "\n");
gStores[where].add({ a: value });
}
var tests = [
// Test for GetDataStore
testGetDataStores,
function() { testStoreAdd(0, 1); },
function() { testStoreAdd(1, 2); },
function() { testStoreAdd(0, 3); },
function() { testStoreAdd(1, 4); }
];
function runTest() {
if (!tests.length) {
finish();
return;
}
var test = tests.shift();
test();
}
runTest();
</script>
</pre>
</body>
</html>
@@ -1,12 +0,0 @@
{
"name": "Really Rapid Release (hosted)",
"description": "Updated even faster than <a href='http://mozilla.org'>Firefox</a>, just to annoy slashdotters.",
"launch_path": "/tests/dom/datastore/tests/TESTTOKEN",
"icons": { "128": "default_icon" },
"datastores-owned" : {
"foo" : { "access": "readwrite", "description" : "This store is called foo" }
},
"datastores-access" : {
"foo" : { "readonly": false, "description" : "This store is called foo" }
}
}
-26
View File
@@ -1,26 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - bug 986056 app</title>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript;version=1.7">
function cbError() {
alert('KO error');
}
navigator.getDataStores('foo').then(function(stores) {
alert("OK " + stores.length);
}, cbError);
</script>
</pre>
</body>
</html>
@@ -1,12 +0,0 @@
{
"name": "Really Rapid Release (hosted)",
"description": "Updated even faster than <a href='http://mozilla.org'>Firefox</a>, just to annoy slashdotters.",
"launch_path": "/tests/dom/datastore/tests/TESTTOKEN",
"icons": { "128": "default_icon" },
"datastores-owned" : {
"foo" : { "access": "readwrite", "description" : "This store is called foo" }
},
"datastores-access" : {
"foo" : { "readonly": false, "description" : "This store is called foo" }
}
}
@@ -1,25 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore just for certified Apps</title>
</head>
<body>
<div id="container"></div>
<script type="application/javascript;version=1.7">
function ok(a, msg) {
alert((a ? 'OK' : 'KO')+ ' ' + msg)
}
function finish() {
alert('DONE');
}
ok(!("DataStore" in window), "DataStore is not an available interface");
ok(!("DataStoreChangeEvent" in window), "DataStore is not an available interface");
ok(!("getDataStores" in navigator), "DataStore not available");
finish();
</script>
</body>
</html>
-148
View File
@@ -1,148 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - basic operation on a readonly db</title>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript;version=1.7">
var gStore;
var gChangeId = null;
var gChangeOperation = null;
function is(a, b, msg) {
alert((a === b ? 'OK' : 'KO') + ' ' + msg)
}
function ok(a, msg) {
alert((a ? 'OK' : 'KO')+ ' ' + msg)
}
function cbError() {
alert('KO error');
}
function finish() {
alert('DONE');
}
function testGetDataStores() {
navigator.getDataStores('foo').then(function(stores) {
is(stores.length, 1, "getDataStores('foo') returns 1 element");
is(stores[0].name, 'foo', 'The dataStore.name is foo');
is(stores[0].readOnly, false, 'The dataStore foo is not in readonly');
gStore = stores[0];
runTest();
}, cbError);
}
function testStoreAdd(value, expectedId) {
gStore.add(value).then(function(id) {
is(id, expectedId, "store.add() is called");
}, cbError);
}
function testStorePut(value, id) {
gStore.put(value, id).then(function(retId) {
is(id, retId, "store.put() is called with the right id");
}, cbError);
}
function testStoreRemove(id, expectedSuccess) {
gStore.remove(id).then(function(success) {
is(success, expectedSuccess, "store.remove() returns the right value");
}, cbError);
}
function testStoreClear() {
gStore.clear().catch(cbError);
}
function eventListener(evt) {
ok(evt instanceof DataStoreChangeEvent, "DataStoreChangeEvent has been received");
ok(evt, "OnChangeListener is called with data");
is(/[0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12}/.test(evt.revisionId), true, "event.revisionId returns something");
is(evt.id, gChangeId, "OnChangeListener is called with the right ID: " + evt.id);
is(evt.operation, gChangeOperation, "OnChangeListener is called with the right operation:" + evt.operation + " " + gChangeOperation);
runTest();
}
var tests = [
// Test for GetDataStore
testGetDataStores,
// Add onchange = function
function() {
gStore.onchange = eventListener;
is(gStore.onchange, eventListener, "onChange is set");
runTest();
},
// Add
function() { gChangeId = 1; gChangeOperation = 'added';
testStoreAdd({ number: 42 }, 1); },
// Put
function() { gChangeId = 1; gChangeOperation = 'updated';
testStorePut({ number: 43 }, 1); },
// Remove
function() { gChangeId = 1; gChangeOperation = 'removed';
testStoreRemove(1, true); },
// Clear
function() { gChangeId = null; gChangeOperation = 'cleared';
testStoreClear(); },
// Remove onchange function and replace it with addEventListener
function() {
gStore.onchange = null;
gStore.addEventListener('change', eventListener);
runTest();
},
// Add
function() { gChangeId = 2; gChangeOperation = 'added';
testStoreAdd({ number: 42 }, 2); },
// Put
function() { gChangeId = 2; gChangeOperation = 'updated';
testStorePut({ number: 43 }, 2); },
// Remove
function() { gChangeId = 2; gChangeOperation = 'removed';
testStoreRemove(2, true); },
// Clear
function() { gChangeId = null; gChangeOperation = 'cleared';
testStoreClear(); },
// Remove event listener
function() {
gStore.removeEventListener('change', eventListener);
runTest();
},
];
function runTest() {
if (!tests.length) {
finish();
return;
}
var test = tests.shift();
test();
}
runTest();
</script>
</pre>
</body>
</html>
-51
View File
@@ -1,51 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - basic operation on a readonly db</title>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript;version=1.7">
function is(a, b, msg) {
alert((a === b ? 'OK' : 'KO') + ' ' + msg)
}
function ok(a, msg) {
alert((a ? 'OK' : 'KO')+ ' ' + msg)
}
function cbError() {
alert('KO error');
}
function finish() {
alert('DONE');
}
function eventListener(obj) {
ok(obj, "OnChangeListener is called with data");
ok("revisionId" in obj, "the event contains a revisionId");
ok("id" in obj, "the event contains a id");
ok("operation" in obj, "the event contains a operation");
ok("owner" in obj, "the event contains a owner");
is(obj.owner, 'http://test/tests/dom/datastore/tests/file_app.sjs?testToken=file_changes.html', 'Owner matches');
finish();
}
navigator.getDataStores('foo').then(function(stores) {
is(stores.length, 1, "getDataStores('foo') returns 1 element");
is(stores[0].name, 'foo', 'The dataStore.name is foo');
stores[0].onchange = eventListener;
alert('READY');
});
</script>
</pre>
</body>
</html>
-75
View File
@@ -1,75 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - duplicate keys</title>
</head>
<body>
<div id="container"></div>
<script type="application/javascript;version=1.7">
var gStore;
var gEvent;
var gChangeId;
function ok(a, msg) {
alert((a ? 'OK' : 'KO')+ ' ' + msg)
}
function is(a, b, msg) {
ok(a === b, msg);
}
function cbError() {
alert('KO error');
}
function finish() {
alert('DONE');
}
function testGetDataStores() {
navigator.getDataStores('foo').then(function(stores) {
gStore = stores[0];
runTest();
}, cbError);
}
function testAdd(success) {
gStore.add({ a: 42 }, 'test').then(function() {
is(success, true, "Record added");
runTest();
}, function(e) {
is(success, false, "Record failed");
ok(e instanceof DOMError, "DOMError received");
is(e.name, 'ConstraintError', 'e.name: ConstraintError');
is(e.message, '', 'e.message');
runTest();
});
}
var tests = [
// Test for GetDataStore
testGetDataStores,
// add
function() { testAdd(true); },
// add duplicate
function() { testAdd(false); }
];
function runTest() {
if (!tests.length) {
finish();
return;
}
var test = tests.shift();
test();
}
runTest();
</script>
</body>
</html>
-32
View File
@@ -1,32 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - event maker</title>
</head>
<body>
<script type="application/javascript;version=1.7">
function is(a, b, msg) {
alert((a === b ? 'OK' : 'KO') + ' ' + msg)
}
function cbError() {
alert('KO error');
}
function finish() {
alert('DONE');
}
navigator.getDataStores('foo').then(function(stores) {
is(stores.length, 1, "getDataStores('foo') returns 1 element");
is(stores[0].name, 'foo', 'The dataStore.name is foo');
is(stores[0].readOnly, false, 'The dataStore foo is not in readonly');
stores[0].add({a: 42}).then(finish, cbError);
});
</script>
</body>
</html>
@@ -1,45 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - event receiver</title>
</head>
<body>
<script type="application/javascript;version=1.7">
function ok(a, msg) {
alert((a ? 'OK' : 'KO') + ' ' + msg)
}
function is(a, b, msg) {
ok(a === b, msg);
}
function cbError() {
alert('KO error');
}
function finish() {
alert('DONE');
}
function eventListener(evt) {
ok(evt, "OnChangeListener is called with data");
finish();
}
navigator.getDataStores('foo').then(function(stores) {
is(stores.length, 1, "getDataStores('foo') returns 1 element");
is(stores[0].name, 'foo', 'The dataStore.name is foo');
is(stores[0].readOnly, false, 'The dataStore foo is not in readonly');
var store = stores[0];
store.onchange = eventListener;
alert("READY");
});
</script>
</body>
</html>
-161
View File
@@ -1,161 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - string or unsigned long keys</title>
</head>
<body>
<div id="container"></div>
<script type="application/javascript;version=1.7">
var gStore;
var gEvent;
var gChangeId;
function is(a, b, msg) {
alert((a === b ? 'OK' : 'KO') + ' ' + msg)
}
function ok(a, msg) {
alert((a ? 'OK' : 'KO')+ ' ' + msg)
}
function cbError() {
alert('KO error');
}
function finish() {
alert('DONE');
}
function testGetDataStores() {
navigator.getDataStores('foo').then(function(stores) {
gStore = stores[0];
runTest();
}, cbError);
}
function testAdd_noKey(key) {
gEvent = 'added';
gChangeId = key;
gStore.add({ a: 42 }).then(function(id) {
is(id, key, "Id must be " + key + " received: " + id);
});
}
function testAdd_withKey(key) {
gEvent = 'added';
gChangeId = key;
gStore.add({ a: 42 }, key).then(function(id) {
is(id, key, "Id must be " + key + " received: " + id);
});
}
function testPut(key) {
gEvent = 'updated';
gChangeId = key;
gStore.put({ a: 42 }, key).then(function(id) {
is(id, key, "Id must be " + key + " received: " + id);
});
}
function testGet(key) {
gStore.get(key).then(function(value) {
ok(value, "Object received!");
is(value.a, 42, "Object received with right value!");
runTest();
});
}
function testArrayGet(key) {
gStore.get.apply(gStore, key).then(function(values) {
is(values.length, key.length, "Object received!");
for (var i = 0; i < values.length; ++i) {
is(values[i].a, 42, "Object received with right value!");
}
runTest();
});
}
function testRemove(key, success) {
gEvent = 'removed';
gChangeId = key;
gStore.remove(key).then(function(value) {
is(value, success, "Status must be " + success + " received: " + value);
if (value == false) {
runTest();
return;
}
});
}
function eventListener() {
gStore.onchange = function(e) {
is(e.operation, gEvent, "Operation matches: " + e.operation + " " + gEvent);
ok(e.id === gChangeId, "Operation id matches");
runTest();
};
runTest();
}
var tests = [
// Test for GetDataStore
testGetDataStores,
// Event listener
eventListener,
// add
function() { testAdd_noKey(1); },
function() { testAdd_withKey(123); },
function() { testAdd_noKey(124); },
function() { testAdd_withKey('foobar'); },
function() { testAdd_noKey(125); },
function() { testAdd_withKey('125'); },
function() { testAdd_withKey('126'); },
function() { testAdd_noKey(126); },
// put
function() { testPut(42); },
function() { testPut('42'); },
// get
function() { testGet('42'); },
function() { testGet(42); },
function() { testGet(1); },
function() { testGet(123); },
function() { testGet(124); },
function() { testGet('foobar'); },
function() { testGet(125); },
function() { testGet('125'); },
function() { testGet('126'); },
function() { testGet(126); },
function() { testArrayGet(['42', 42, 1, 123, 124, 'foobar', 125, '125', '126', 126]); },
// remove
function() { testRemove(42, true); },
function() { testRemove('42', true); },
function() { testRemove('43', false); },
function() { testRemove(43, false); },
];
function runTest() {
if (!tests.length) {
finish();
return;
}
var test = tests.shift();
test();
}
runTest();
</script>
</body>
</html>
@@ -1,120 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - notify updates with system messages</title>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript;version=1.7">
var gStore;
var gChangeId = null;
var gChangeOperation = null;
var gIsSystemMessageFired = false;
function is(a, b, msg) {
alert((a === b ? 'OK' : 'KO') + ' ' + msg)
}
function ok(a, msg) {
alert((a ? 'OK' : 'KO')+ ' ' + msg)
}
function cbError() {
alert('KO error');
}
function finish() {
alert('DONE');
}
function testGetDataStores() {
navigator.getDataStores('foo').then(function(stores) {
is(stores.length, 1, "getDataStores('foo') returns 1 element");
is(stores[0].name, 'foo', 'The dataStore.name is foo');
is(stores[0].readOnly, false, 'The dataStore foo is not in readonly');
gStore = stores[0];
runTest();
}, cbError);
}
function testStoreAdd(value, expectedId) {
gStore.add(value).then(function(id) {
is(id, expectedId, "store.add() is called");
}, cbError);
}
function eventListener(evt) {
ok(evt instanceof DataStoreChangeEvent, "DataStoreChangeEvent has been received");
ok(evt, "OnChangeListener is called with data");
is(/[0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12}/.test(evt.revisionId), true, "event.revisionId returns something");
is(evt.id, gChangeId, "OnChangeListener is called with the right ID: " + evt.id);
is(evt.operation, gChangeOperation, "OnChangeListener is called with the right operation:" + evt.operation + " " + gChangeOperation);
runTest();
}
function onDatastoreUpdateFoo(message) {
gIsSystemMessageFired = true;
ok(true, "System message 'datastore-update-foo' has been received");
runTest();
}
var tests = [
// Test for GetDataStore.
testGetDataStores,
// Add onchange = function.
function() {
gStore.onchange = eventListener;
is(gStore.onchange, eventListener, "onChange is set");
runTest();
},
// Set system message handler.
function() {
navigator.mozSetMessageHandler('datastore-update-foo', onDatastoreUpdateFoo);
runTest();
},
// Add.
function() { gChangeId = 1; gChangeOperation = 'added';
testStoreAdd({ number: 42 }, 1); },
// Remove event listener.
function() {
gStore.removeEventListener('change', eventListener);
runTest();
},
// Ensure the system message has fired and no more pending ones.
function() {
// Periodically check whether the system message has fired.
var timer = setInterval(function() {
if (gIsSystemMessageFired) {
clearInterval(timer);
ok(true, "The system message has fired");
ok(!navigator.mozHasPendingMessage('datastore-update-foo'), "No more pending system message");
finish();
}
}, 1000);
}
];
function runTest() {
if (tests.length) {
var test = tests.shift();
test();
}
}
runTest();
</script>
</pre>
</body>
</html>
-72
View File
@@ -1,72 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - basic operation on a readonly db</title>
</head>
<body>
<div id="container"></div>
<script type="application/javascript;version=1.7">
function is(a, b, msg) {
dump((a === b ? 'OK' : 'KO') + ' ' + msg + "\n")
alert((a === b ? 'OK' : 'KO') + ' ' + msg)
}
function ok(a, msg) {
alert((a ? 'OK' : 'KO')+ ' ' + msg)
}
function cbError() {
alert('KO error');
}
function finish() {
alert('DONE');
}
function runTest() {
navigator.getDataStores('bar').then(function(stores) {
is(stores.length, 1, "getDataStores('bar') returns 1 element");
is(stores[0].name, 'bar', 'The dataStore.name is bar');
is(stores[0].readOnly, true, 'The dataStore bar is eadonly');
var store = stores[0];
ok("get" in store, "store.get exists");
ok("put" in store, "store.put exists");
ok("add" in store, "store.add exists");
ok("remove" in store, "store.remove exists");
ok("clear" in store, "store.clear exists");
var f = store.clear();
f = f.then(cbError, function() {
ok(true, "store.clear() fails because the db is readonly");
return store.remove(123);
});
f = f.then(cbError, function() {
ok(true, "store.remove() fails because the db is readonly");
return store.add(123, true);
});
f = f.then(cbError, function() {
ok(true, "store.add() fails because the db is readonly");
return store.put({}, 123);
})
f = f.then(cbError, function() {
ok(true, "store.put() fails because the db is readonly");
})
f.then(function() {
// All done.
ok(true, "All done");
finish();
});
}, cbError);
}
runTest();
</script>
</body>
</html>
-31
View File
@@ -1,31 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - sync</title>
<script type="text/javascript" src="file_sync_common.js"></script>
</head>
<body>
<div id="container"></div>
<script type="application/javascript;version=1.7">
function is(a, b, msg) {
alert((a === b ? 'OK' : 'KO') + ' ' + msg)
}
function ok(a, msg) {
alert((a ? 'OK' : 'KO')+ ' ' + msg)
}
function cbError() {
alert('KO error');
}
function finish() {
alert('DONE');
}
runTest();
</script>
</body>
</html>
-461
View File
@@ -1,461 +0,0 @@
var gStore;
var gRevisions = [];
var gCursor;
var gExpectedEvents = true;
function testGetDataStores() {
navigator.getDataStores('foo').then(function(stores) {
is(stores.length, 1, "getDataStores('foo') returns 1 element");
gStore = stores[0];
gRevisions.push(gStore.revisionId);
gStore.onchange = function(aEvent) {
ok(gExpectedEvents, "Events received!");
runTest();
}
runTest();
}, cbError);
}
function testBasicInterface() {
var cursor = gStore.sync();
ok(cursor, "Cursor is created");
is(cursor.store, gStore, "Cursor.store is the store");
ok("next" in cursor, "Cursor.next exists");
ok("close" in cursor, "Cursor.close exists");
cursor.close();
runTest();
}
function testCursor(cursor, steps) {
if (!steps.length) {
runTest();
return;
}
var step = steps.shift();
cursor.next().then(function(data) {
ok(!!data, "Cursor.next returns data");
is(data.operation, step.operation, "Waiting for operation: '" + step.operation + "' received '" + data.operation + "'");
switch (data.operation) {
case 'clear':
is (data.id, null, "'clear' operation wants a null id");
break;
case 'done':
is(/[0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12}/.test(data.revisionId), true, "done has a valid revisionId");
is (data.revisionId, gRevisions[gRevisions.length-1], "Last revision matches");
is (data.id, null, "'done' operation wants a null id");
break;
case 'add':
case 'update':
if ('id' in step) {
is(data.id, step.id, "next() add: id matches: " + data.id + " " + step.id);
}
if ('data' in step) {
is(data.data, step.data, "next() add: data matches: " + data.data + " " + step.data);
}
break;
case 'remove':
if ('id' in step) {
is(data.id, step.id, "next() add: id matches: " + data.id + " " + step.id);
}
break;
}
testCursor(cursor, steps);
});
}
var tests = [
// Test for GetDataStore
testGetDataStores,
// interface test
testBasicInterface,
// empty DataStore
function() {
var cursor = gStore.sync();
var steps = [ { operation: 'clear' },
{ operation: 'done' },
{ operation: 'done' }];
testCursor(cursor, steps);
},
function() {
gExpectedEvents = false;
var cursor = gStore.sync('wrong revision ID');
var steps = [ { operation: 'clear' },
{ operation: 'done' },
{ operation: 'done' }];
testCursor(cursor, steps);
},
function() {
var cursor = gStore.sync(gRevisions[0]);
var steps = [ { operation: 'done' },
{ operation: 'done' }];
testCursor(cursor, steps);
},
// Test add from scratch
function() {
gExpectedEvents = true;
gStore.add(1).then(function(id) {
gRevisions.push(gStore.revisionId);
ok(true, "Item: " + id + " added");
});
},
function() {
gStore.add(2,"foobar").then(function(id) {
gRevisions.push(gStore.revisionId);
ok(true, "Item: " + id + " added");
});
},
function() {
gStore.add(3,3).then(function(id) {
gRevisions.push(gStore.revisionId);
ok(true, "Item: " + id + " added");
});
},
function() {
gExpectedEvents = false;
var cursor = gStore.sync();
var steps = [ { operation: 'clear', },
{ operation: 'add', id: 1, data: 1 },
{ operation: 'add', id: 3, data: 3 },
{ operation: 'add', id: 'foobar', data: 2 },
{ operation: 'done' }];
testCursor(cursor, steps);
},
function() {
var cursor = gStore.sync('wrong revision ID');
var steps = [ { operation: 'clear', },
{ operation: 'add', id: 1, data: 1 },
{ operation: 'add', id: 3, data: 3 },
{ operation: 'add', id: 'foobar', data: 2 },
{ operation: 'done' }];
testCursor(cursor, steps);
},
function() {
var cursor = gStore.sync(gRevisions[0]);
var steps = [ { operation: 'add', id: 1, data: 1 },
{ operation: 'add', id: 'foobar', data: 2 },
{ operation: 'add', id: 3, data: 3 },
{ operation: 'done' }];
testCursor(cursor, steps);
},
function() {
var cursor = gStore.sync(gRevisions[1]);
var steps = [ { operation: 'add', id: 'foobar', data: 2 },
{ operation: 'add', id: 3, data: 3 },
{ operation: 'done' }];
testCursor(cursor, steps);
},
function() {
var cursor = gStore.sync(gRevisions[2]);
var steps = [ { operation: 'add', id: 3, data: 3 },
{ operation: 'done' }];
testCursor(cursor, steps);
},
function() {
var cursor = gStore.sync(gRevisions[3]);
var steps = [ { operation: 'done' }];
testCursor(cursor, steps);
},
// Test after an update
function() {
gExpectedEvents = true;
gStore.put(123, 1).then(function() {
gRevisions.push(gStore.revisionId);
});
},
function() {
gExpectedEvents = false;
var cursor = gStore.sync();
var steps = [ { operation: 'clear', },
{ operation: 'add', id: 1, data: 123 },
{ operation: 'add', id: 3, data: 3 },
{ operation: 'add', id: 'foobar', data: 2 },
{ operation: 'done' }];
testCursor(cursor, steps);
},
function() {
var cursor = gStore.sync('wrong revision ID');
var steps = [ { operation: 'clear', },
{ operation: 'add', id: 1, data: 123 },
{ operation: 'add', id: 3, data: 3 },
{ operation: 'add', id: 'foobar', data: 2 },
{ operation: 'done' }];
testCursor(cursor, steps);
},
function() {
var cursor = gStore.sync(gRevisions[0]);
var steps = [ { operation: 'add', id: 1, data: 123 },
{ operation: 'add', id: 'foobar', data: 2 },
{ operation: 'add', id: 3, data: 3 },
{ operation: 'done' }];
testCursor(cursor, steps);
},
function() {
var cursor = gStore.sync(gRevisions[1]);
var steps = [ { operation: 'add', id: 'foobar', data: 2 },
{ operation: 'add', id: 3, data: 3 },
{ operation: 'update', id: 1, data: 123 },
{ operation: 'done' }];
testCursor(cursor, steps);
},
function() {
var cursor = gStore.sync(gRevisions[2]);
var steps = [ { operation: 'add', id: 3, data: 3 },
{ operation: 'update', id: 1, data: 123 },
{ operation: 'done' }];
testCursor(cursor, steps);
},
function() {
var cursor = gStore.sync(gRevisions[3]);
var steps = [ { operation: 'update', id: 1, data: 123 },
{ operation: 'done' }];
testCursor(cursor, steps);
},
function() {
var cursor = gStore.sync(gRevisions[4]);
var steps = [ { operation: 'done' }];
testCursor(cursor, steps);
},
// Test after a remove
function() {
gExpectedEvents = true;
gStore.remove(3).then(function() {
gRevisions.push(gStore.revisionId);
});
},
function() {
gExpectedEvents = false;
var cursor = gStore.sync();
var steps = [ { operation: 'clear', },
{ operation: 'add', id: 1, data: 123 },
{ operation: 'add', id: 'foobar', data: 2 },
{ operation: 'done' }];
testCursor(cursor, steps);
},
function() {
var cursor = gStore.sync('wrong revision ID');
var steps = [ { operation: 'clear', },
{ operation: 'add', id: 1, data: 123 },
{ operation: 'add', id: 'foobar', data: 2 },
{ operation: 'done' }];
testCursor(cursor, steps);
},
function() {
var cursor = gStore.sync(gRevisions[0]);
var steps = [ { operation: 'add', id: 1, data: 123 },
{ operation: 'add', id: 'foobar', data: 2 },
{ operation: 'done' }];
testCursor(cursor, steps);
},
function() {
var cursor = gStore.sync(gRevisions[1]);
var steps = [ { operation: 'add', id: 'foobar', data: 2 },
{ operation: 'update', id: 1, data: 123 },
{ operation: 'done' }];
testCursor(cursor, steps);
},
function() {
var cursor = gStore.sync(gRevisions[2]);
var steps = [ { operation: 'update', id: 1, data: 123 },
{ operation: 'done' }];
testCursor(cursor, steps);
},
function() {
var cursor = gStore.sync(gRevisions[3]);
var steps = [ { operation: 'update', id: 1, data: 123 },
{ operation: 'remove', id: 3 },
{ operation: 'done' }];
testCursor(cursor, steps);
},
function() {
var cursor = gStore.sync(gRevisions[4]);
var steps = [ { operation: 'remove', id: 3 },
{ operation: 'done' }];
testCursor(cursor, steps);
},
function() {
var cursor = gStore.sync(gRevisions[5]);
var steps = [ { operation: 'done' }];
testCursor(cursor, steps);
},
// New events when the cursor is active
function() {
gCursor = gStore.sync();
var steps = [ { operation: 'clear', },
{ operation: 'add', id: 1, data: 123 },
{ operation: 'add', id: 'foobar', data: 2 } ];
testCursor(gCursor, steps);
},
function() {
gStore.add(42, 2).then(function(id) {
ok(true, "Item: " + id + " added");
gRevisions.push(gStore.revisionId);
runTest();
});
},
function() {
var steps = [ { operation: 'clear', },
{ operation: 'add', id: 1, data: 123 },
{ operation: 'add', id: 2, data: 42 },
{ operation: 'add', id: 'foobar', data: 2 } ]
testCursor(gCursor, steps);
},
function() {
gStore.put(43, 2).then(function(id) {
gRevisions.push(gStore.revisionId);
runTest();
});
},
function() {
var steps = [ { operation: 'clear', },
{ operation: 'add', id: 1, data: 123 },
{ operation: 'add', id: 2, data: 43 },
{ operation: 'add', id: 'foobar', data: 2 } ]
testCursor(gCursor, steps);
},
function() {
gStore.remove(2).then(function(id) {
gRevisions.push(gStore.revisionId);
runTest();
});
},
function() {
var steps = [ { operation: 'clear', },
{ operation: 'add', id: 1, data: 123 },
{ operation: 'add', id: 'foobar', data: 2 } ]
testCursor(gCursor, steps);
},
function() {
gStore.add(42).then(function(id) {
ok(true, "Item: " + id + " added");
gRevisions.push(gStore.revisionId);
runTest();
});
},
function() {
var steps = [ { operation: 'clear', },
{ operation: 'add', id: 1, data: 123 },
{ operation: 'add', id: 4, data: 42 },
{ operation: 'add', id: 'foobar', data: 2 } ]
testCursor(gCursor, steps);
},
function() {
gStore.clear().then(function() {
gRevisions.push(gStore.revisionId);
runTest();
});
},
function() {
var steps = [ { operation: 'clear' } ];
testCursor(gCursor, steps);
},
function() {
gStore.add(42).then(function(id) {
ok(true, "Item: " + id + " added");
gRevisions.push(gStore.revisionId);
runTest();
});
},
function() {
var steps = [ { operation: 'clear', },
{ operation: 'add', id: 5, data: 42 } ];
testCursor(gCursor, steps);
},
function() {
gStore.clear().then(function() {
gRevisions.push(gStore.revisionId);
runTest();
});
},
function() {
gStore.add(42).then(function(id) {
ok(true, "Item: " + id + " added");
gRevisions.push(gStore.revisionId);
runTest();
});
},
function() {
var steps = [ { operation: 'clear' },
{ operation: 'add', id: 6, data: 42 },
{ operation: 'done'} ];
testCursor(gCursor, steps);
},
function() {
gExpectedEvents = true;
gStore.add(42).then(function(id) {
});
}
];
function runTest() {
if (!tests.length) {
finish();
return;
}
var test = tests.shift();
test();
}
-30
View File
@@ -1,30 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - sync</title>
</head>
<body>
<div id="container"></div>
<script type="application/javascript;version=1.7">
var messages = [];
var worker = new Worker("file_sync_worker.js");
worker.onmessage = function(event) {
messages.push(event.data)
if (event.data == 'DONE') {
// Free the worker when all the tests are done.
worker.terminate();
// Fire message to the test_sync_worker.html.
for (var i = 0; i < messages.length; i++) {
alert(messages[i]);
}
}
}
</script>
</body>
</html>
-19
View File
@@ -1,19 +0,0 @@
function is(a, b, msg) {
postMessage((a === b ? 'OK' : 'KO') + ' ' + msg)
}
function ok(a, msg) {
postMessage((a ? 'OK' : 'KO')+ ' ' + msg)
}
function cbError() {
postMessage('KO error');
}
function finish() {
postMessage('DONE');
}
importScripts("file_sync_common.js");
runTest();
-129
View File
@@ -1,129 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - transactional semantics</title>
</head>
<body>
<div id="container"></div>
<script type="application/javascript;version=1.7">
var gStore;
function is(a, b, msg) {
alert((a === b ? 'OK' : 'KO') + ' ' + msg)
}
function ok(a, msg) {
alert((a ? 'OK' : 'KO')+ ' ' + msg)
}
function cbError() {
alert('KO error');
}
function finish() {
alert('DONE');
}
function testGetDataStores() {
navigator.getDataStores('foo').then(function(stores) {
is(stores.length, 1, "getDataStores('foo') returns 1 element");
is(stores[0].name, 'foo', 'The dataStore.name is foo');
is(stores[0].readOnly, false, 'The dataStore foo is not in readonly');
gStore = stores[0];
runTest();
}, cbError);
}
function checkError(e) {
ok(e instanceof DOMError, "Expecting a DOMError");
is(e.name, "ConstraintError", "DOMError.name must be ConstraintError");
}
var tests = [
// Test for GetDataStore
testGetDataStores,
// Add
function() { gStore.add("data", null, 'foobar').catch(function(e) {
ok(true, "Add rejects when the revision is wrong");
checkError(e); runTest(); }); },
function() { gStore.add("data").then(function() {
ok(true, "Add succeeded without revisionId");
runTest(); }, cbError); },
function() { gStore.add("data", null, gStore.revisionId).then(function() {
ok(true, "Add succeeded with the correct revisionId");
runTest(); }, cbError); },
function() { gStore.add("data", 42, 'foobar').catch(function(e) {
ok(true, "Add rejects when the revision is wrong");
checkError(e); runTest(); }); },
function() { gStore.add("data", 42).then(function() {
ok(true, "Add succeeded without revisionId");
runTest(); }, cbError); },
function() { gStore.add("data", 43, gStore.revisionId).then(function() {
ok(true, "Add succeeded with the correct revisionId");
runTest(); }, cbError); },
// Put
function() { gStore.put("data", 42, 'foobar').catch(function(e) {
ok(true, "Put rejects when the revision is wrong");
checkError(e); runTest(); }); },
function() { gStore.put("data", 42).then(function() {
ok(true, "Put succeeded without revisionId");
runTest(); }, cbError); },
function() { gStore.put("data", 42, gStore.revisionId).then(function() {
ok(true, "Put succeeded with the correct revisionId");
runTest(); }, cbError); },
// Remove
function() { gStore.remove(42, 'foobar').catch(function(e) {
ok(true, "Remove rejects when the revision is wrong");
checkError(e); runTest(); }); },
function() { gStore.remove(42).then(function() {
ok(true, "Remove succeeded without revisionId");
runTest(); }, cbError); },
function() { gStore.remove(42, gStore.revisionId).then(function() {
ok(true, "Remove succeeded with the correct revisionId");
runTest(); }, cbError); },
// Clear
function() { gStore.clear('foobar').catch(function(e) {
ok(true, "Clear rejects when the revision is wrong");
checkError(e); runTest(); }); },
function() { gStore.clear().then(function() {
ok(true, "Clear succeeded without revisionId");
runTest(); }, cbError); },
function() { gStore.clear(gStore.revisionId).then(function() {
ok(true, "Clear succeeded with the correct revisionId");
runTest(); }, cbError); },
];
function runTest() {
if (!tests.length) {
finish();
return;
}
var test = tests.shift();
test();
}
runTest();
</script>
</body>
</html>
@@ -1,29 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore</title>
</head>
<body>
<div id="container"></div>
<script type="application/javascript;version=1.7">
var messages = [];
var worker = new Worker("file_worker_close.js");
worker.onmessage = function(event) {
messages.push(event.data)
if (event.data == 'DONE') {
worker.terminate();
// Fire message to the test_basic_worker.html.
for (var i = 0; i < messages.length; i++) {
alert(messages[i]);
}
}
}
</script>
</body>
</html>
-18
View File
@@ -1,18 +0,0 @@
function is(a, b, msg) {
postMessage((a == b ? 'OK' : 'KO')+ ' ' + msg)
}
var store;
navigator.getDataStores('foo').then(function(stores) {
is(stores.length, 1, "getDataStores('foo') returns 1 element");
is(stores[0].name, 'foo', 'The dataStore.name is foo');
is(stores[0].readOnly, false, 'The dataStore foo is not in readonly');
store = stores[0];
postMessage('DONE');
});
onclose = function() {
for (var i = 0; i < 100; ++i) {
store.get(123);
}
}
-64
View File
@@ -1,64 +0,0 @@
[DEFAULT]
skip-if = (buildapp != 'b2g' && buildapp != 'mulet')
support-files =
file_app_install.html
file_readonly.html
file_basic.html
file_basic_worker.html
file_basic_worker.js
file_changes.html
file_changes2.html
file_app.sjs
file_app.template.webapp
file_app2.template.webapp
file_arrays.html
file_sync.html
file_sync_worker.html
file_sync_worker.js
file_bug924104.html
file_certifiedApp.html
file_keys.html
file_duplicate.html
file_bug976311.html
file_bug976311.template.webapp
file_bug986056.html
file_bug986056.template.webapp
file_bug1058108.html
file_event_maker.html
file_event_receiver.html
file_transactions.html
file_basic_common.js
file_sync_common.js
file_bug1008044.html
file_bug957086.html
file_notify_system_message.html
file_worker_close.html
file_worker_close.js
[test_app_install.html]
skip-if = toolkit == 'gonk' # embed-apps doesn't work in the mochitest app
[test_readonly.html]
skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 936226
[test_basic.html]
[test_basic_worker.html]
[test_changes.html]
[test_arrays.html]
[test_oop.html]
skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 936226
[test_sync.html]
skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 936226
[test_sync_worker.html]
[test_bug924104.html]
[test_certifiedApp.html]
[test_keys.html]
[test_duplicate.html]
[test_bug976311.html]
[test_bug986056.html]
[test_oop_events.html]
[test_transactions.html]
[test_bug1008044.html]
[test_bug957086.html]
[test_bug1058108.html]
[test_notify_system_message.html]
skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' || toolkit == 'win' #bug 1053662 - Timeout prone
[test_worker_close.html]
-128
View File
@@ -1,128 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - sync</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<div id="container"></div>
<script type="application/javascript;version=1.7">
var gHostedManifestURL = 'http://test/tests/dom/datastore/tests/file_app.sjs?testToken=file_sync.html';
var gApp;
function cbError() {
ok(false, "Error callback invoked");
finish();
}
function installApp() {
var request = navigator.mozApps.install(gHostedManifestURL);
request.onerror = cbError;
request.onsuccess = function() {
gApp = request.result;
runTest();
}
}
function uninstallApp() {
// Uninstall the app.
var request = navigator.mozApps.mgmt.uninstall(gApp);
request.onerror = cbError;
request.onsuccess = function() {
// All done.
info("All done");
runTest();
}
}
function testApp() {
var ifr = document.createElement('iframe');
ifr.setAttribute('mozbrowser', 'true');
ifr.setAttribute('mozapp', gApp.manifestURL);
ifr.setAttribute('src', gApp.manifest.launch_path);
var domParent = document.getElementById('container');
// Set us up to listen for messages from the app.
var listener = function(e) {
var message = e.detail.message;
if (/^OK/.exec(message)) {
ok(true, "Message from app: " + message);
} else if (/KO/.exec(message)) {
ok(false, "Message from app: " + message);
} else if (/DONE/.exec(message)) {
ok(true, "Messaging from app complete");
ifr.removeEventListener('mozbrowsershowmodalprompt', listener);
domParent.removeChild(ifr);
runTest();
}
}
// This event is triggered when the app calls "alert".
ifr.addEventListener('mozbrowsershowmodalprompt', listener, false);
domParent.appendChild(ifr);
}
var tests = [
// Permissions
function() {
SpecialPowers.pushPermissions(
[{ "type": "browser", "allow": 1, "context": document },
{ "type": "embed-apps", "allow": 1, "context": document },
{ "type": "webapps-manage", "allow": 1, "context": document }], runTest);
},
// Preferences
function() {
SpecialPowers.pushPrefEnv({"set": [["dom.datastore.enabled", true],
["dom.datastore.sysMsgOnChangeShortTimeoutSec", 1],
["dom.datastore.sysMsgOnChangeLongTimeoutSec", 3],
["dom.testing.ignore_ipc_principal", true],
["dom.testing.datastore_enabled_for_hosted_apps", true]]}, runTest);
},
function() {
if (SpecialPowers.isMainProcess()) {
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
}
SpecialPowers.pushPrefEnv({"set":[["dom.mozBrowserFramesEnabled", true]]}, runTest);
},
// No confirmation needed when an app is installed
function() {
SpecialPowers.autoConfirmAppInstall(() =>
SpecialPowers.autoConfirmAppUninstall(runTest));
},
// Installing the app
installApp,
// Run tests in app
testApp,
// Uninstall the app
uninstallApp
];
function runTest() {
if (!tests.length) {
finish();
return;
}
var test = tests.shift();
test();
}
function finish() {
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
runTest();
</script>
</body>
</html>
-128
View File
@@ -1,128 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for DataStore - sync</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<div id="container"></div>
<script type="application/javascript;version=1.7">
var gHostedManifestURL = 'http://test/tests/dom/datastore/tests/file_app.sjs?testToken=file_sync_worker.html';
var gApp;
function cbError() {
ok(false, "Error callback invoked");
finish();
}
function installApp() {
var request = navigator.mozApps.install(gHostedManifestURL);
request.onerror = cbError;
request.onsuccess = function() {
gApp = request.result;
runTest();
}
}
function uninstallApp() {
// Uninstall the app.
var request = navigator.mozApps.mgmt.uninstall(gApp);
request.onerror = cbError;
request.onsuccess = function() {
// All done.
info("All done");
runTest();
}
}
function testApp() {
var ifr = document.createElement('iframe');
ifr.setAttribute('mozbrowser', 'true');
ifr.setAttribute('mozapp', gApp.manifestURL);
ifr.setAttribute('src', gApp.manifest.launch_path);
var domParent = document.getElementById('container');
// Set us up to listen for messages from the app.
var listener = function(e) {
var message = e.detail.message;
if (/^OK/.exec(message)) {
ok(true, "Message from app: " + message);
} else if (/KO/.exec(message)) {
ok(false, "Message from app: " + message);
} else if (/DONE/.exec(message)) {
ok(true, "Messaging from app complete");
ifr.removeEventListener('mozbrowsershowmodalprompt', listener);
domParent.removeChild(ifr);
runTest();
}
}
// This event is triggered when the app calls "alert".
ifr.addEventListener('mozbrowsershowmodalprompt', listener, false);
domParent.appendChild(ifr);
}
var tests = [
// Permissions
function() {
SpecialPowers.pushPermissions(
[{ "type": "browser", "allow": 1, "context": document },
{ "type": "embed-apps", "allow": 1, "context": document },
{ "type": "webapps-manage", "allow": 1, "context": document }], runTest);
},
// Preferences
function() {
SpecialPowers.pushPrefEnv({"set": [["dom.datastore.enabled", true],
["dom.datastore.sysMsgOnChangeShortTimeoutSec", 1],
["dom.datastore.sysMsgOnChangeLongTimeoutSec", 3],
["dom.testing.ignore_ipc_principal", true],
["dom.testing.datastore_enabled_for_hosted_apps", true]]}, runTest);
},
function() {
if (SpecialPowers.isMainProcess()) {
SpecialPowers.Cu.import("resource://gre/modules/DataStoreChangeNotifier.jsm");
}
SpecialPowers.pushPrefEnv({"set":[["dom.mozBrowserFramesEnabled", true]]}, runTest)
},
// No confirmation needed when an app is installed
function() {
SpecialPowers.autoConfirmAppInstall(() =>
SpecialPowers.autoConfirmAppUninstall(runTest));
},
// Installing the app
installApp,
// Run tests in app
testApp,
// Uninstall the app
uninstallApp
];
function runTest() {
if (!tests.length) {
finish();
return;
}
var test = tests.shift();
test();
}
function finish() {
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
runTest();
</script>
</body>
</html>
@@ -188,10 +188,6 @@ const kEventConstructors = {
return e;
},
},
DataStoreChangeEvent: { create: function (aName, aProps) {
return new DataStoreChangeEvent(aProps);
},
},
DeviceLightEvent: { create: function (aName, aProps) {
return new DeviceLightEvent(aName, aProps);
},
+1 -1
View File
@@ -20,7 +20,7 @@
BEGIN_FMRADIO_NAMESPACE
class FMRadioReplyRunnable : public nsRunnable
class FMRadioReplyRunnable : public Runnable
{
public:
FMRadioReplyRunnable() : mResponseType(SuccessResponse()) {}
-25
View File
@@ -208,31 +208,6 @@ IDBFactory::CreateForMainThreadJS(JSContext* aCx,
return NS_OK;
}
// static
nsresult
IDBFactory::CreateForDatastore(JSContext* aCx,
JS::Handle<JSObject*> aOwningObject,
IDBFactory** aFactory)
{
MOZ_ASSERT(NS_IsMainThread());
// There should be a null principal pushed here, but it's still chrome...
MOZ_ASSERT(!nsContentUtils::IsCallerChrome());
nsAutoPtr<PrincipalInfo> principalInfo(
new PrincipalInfo(SystemPrincipalInfo()));
nsresult rv =
CreateForMainThreadJSInternal(aCx, aOwningObject, principalInfo, aFactory);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
MOZ_ASSERT(!principalInfo);
return NS_OK;
}
// static
nsresult
IDBFactory::CreateForWorker(JSContext* aCx,
-5
View File
@@ -90,11 +90,6 @@ public:
JS::Handle<JSObject*> aOwningObject,
IDBFactory** aFactory);
static nsresult
CreateForDatastore(JSContext* aCx,
JS::Handle<JSObject*> aOwningObject,
IDBFactory** aFactory);
static nsresult
CreateForWorker(JSContext* aCx,
JS::Handle<JSObject*> aOwningObject,
-5
View File
@@ -95,9 +95,4 @@ interface nsIAppsService : nsISupports
* Available only in the parent process.
*/
bool isExtensionResource(in nsIURI uri);
/**
* Reads the manifest file for this app and update the DataStore map
*/
void updateDataStoreEntriesFromLocalId(in unsigned long localId);
};
-19
View File
@@ -191,7 +191,6 @@
#include "nsIPrincipal.h"
#include "nsDeviceStorage.h"
#include "DomainPolicy.h"
#include "mozilla/dom/DataStoreService.h"
#include "mozilla/dom/ipc/StructuredCloneData.h"
#include "mozilla/dom/telephony/PTelephonyChild.h"
#include "mozilla/dom/time/DateCacheCleaner.h"
@@ -1187,24 +1186,6 @@ NS_IMETHODIMP MemoryReportRequestChild::Run()
finished, nullptr);
}
bool
ContentChild::RecvDataStoreNotify(const uint32_t& aAppId,
const nsString& aName,
const nsString& aManifestURL)
{
RefPtr<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)
{
-4
View File
@@ -250,10 +250,6 @@ public:
const FileDescriptor& aGCLog,
const FileDescriptor& aCCLog) override;
virtual bool
RecvDataStoreNotify(const uint32_t& aAppId, const nsString& aName,
const nsString& aManifestURL) override;
virtual PTestShellChild* AllocPTestShellChild() override;
virtual bool DeallocPTestShellChild(PTestShellChild*) override;
-23
View File
@@ -41,7 +41,6 @@
#include "mozilla/DataStorage.h"
#include "mozilla/devtools/HeapSnapshotTempFileHelperParent.h"
#include "mozilla/docshell/OfflineCacheUpdateParent.h"
#include "mozilla/dom/DataStoreService.h"
#include "mozilla/dom/DataTransfer.h"
#include "mozilla/dom/DOMStorageIPC.h"
#include "mozilla/dom/Element.h"
@@ -2290,7 +2289,6 @@ ContentParent::InitializeMembers()
mIsAlive = true;
mMetamorphosed = false;
mSendPermissionUpdates = false;
mSendDataStoreInfos = false;
mCalledClose = false;
mCalledCloseWithError = false;
mCalledKillHard = false;
@@ -2945,27 +2943,6 @@ ContentParent::RecvAudioChannelServiceStatus(
return true;
}
bool
ContentParent::RecvDataStoreGetStores(
const nsString& aName,
const nsString& aOwner,
const IPC::Principal& aPrincipal,
InfallibleTArray<DataStoreSetting>* aValue)
{
RefPtr<DataStoreService> service = DataStoreService::GetOrCreate();
if (NS_WARN_IF(!service)) {
return false;
}
nsresult rv = service->GetDataStoresFromIPC(aName, aOwner, aPrincipal, aValue);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
mSendDataStoreInfos = true;
return true;
}
void
ContentParent::ForkNewProcess(bool aBlocking)
{
-12
View File
@@ -328,11 +328,6 @@ public:
return mSendPermissionUpdates;
}
bool NeedsDataStoreInfos() const
{
return mSendDataStoreInfos;
}
/**
* Kill our subprocess and make sure it dies. Should only be used
* in emergency situations since it bypasses the normal shutdown
@@ -980,12 +975,6 @@ private:
virtual bool RecvGetLookAndFeelCache(nsTArray<LookAndFeelInt>* aLookAndFeelIntCache) override;
virtual bool RecvDataStoreGetStores(
const nsString& aName,
const nsString& aOwner,
const IPC::Principal& aPrincipal,
InfallibleTArray<DataStoreSetting>* aValue) override;
virtual bool RecvSpeakerManagerGetSpeakerStatus(bool* aValue) override;
virtual bool RecvSpeakerManagerForceSpeaker(const bool& aEnable) override;
@@ -1147,7 +1136,6 @@ private:
bool mMetamorphosed;
bool mSendPermissionUpdates;
bool mSendDataStoreInfos;
bool mIsForBrowser;
bool mIsNuwaProcess;
bool mHasGamepadListener;
+3 -3
View File
@@ -35,7 +35,7 @@ namespace dom {
namespace {
class CallNuwaSpawn: public nsRunnable
class CallNuwaSpawn: public Runnable
{
public:
NS_IMETHOD Run()
@@ -94,7 +94,7 @@ NuwaFork()
sNuwaForking = true;
MessageLoop* ioloop = XRE_GetIOMessageLoop();
ioloop->PostTask(FROM_HERE, NewRunnableFunction(RunNuwaFork));
ioloop->PostTask(NewRunnableFunction(RunNuwaFork));
}
} // Anonymous namespace.
@@ -185,7 +185,7 @@ GetProtoFdInfos(NuwaProtoFdInfo* aInfoList,
*aInfoSize = i;
}
class RunAddNewIPCProcess : public nsRunnable
class RunAddNewIPCProcess : public mozilla::Runnable
{
public:
RunAddNewIPCProcess(pid_t aPid,
-14
View File
@@ -290,14 +290,6 @@ struct DataStorageItem {
DataStorageType type;
};
struct DataStoreSetting {
nsString name;
nsString originURL;
nsString manifestURL;
bool readOnly;
bool enabled;
};
// Note: Any changes to this structure should also be changed in
// FileSystemUpdate below.
struct VolumeInfo {
@@ -491,9 +483,6 @@ child:
*/
async BidiKeyboardNotify(bool isLangRTL);
async DataStoreNotify(uint32_t aAppId, nsString aName,
nsString aManifestURL);
/**
* Dump this process's GC and CC logs to the provided files.
*
@@ -946,9 +935,6 @@ parent:
async AudioChannelChangeDefVolChannel(int32_t aChannel, bool aHidden);
sync DataStoreGetStores(nsString aName, nsString aOwner, Principal aPrincipal)
returns (DataStoreSetting[] dataStores);
async FilePathUpdateNotify(nsString aType,
nsString aStorageName,
nsString aFilepath,
+2 -2
View File
@@ -68,7 +68,7 @@ private:
void NuwaFork();
// initialization off the critical path of app startup.
CancelableTask* mPreallocateAppProcessTask;
CancelableRunnable* mPreallocateAppProcessTask;
// The array containing the preallocated processes. 4 as the inline storage size
// should be enough so we don't need to grow the AutoTArray.
@@ -243,7 +243,7 @@ PreallocatedProcessManagerImpl::ScheduleDelayedNuwaFork()
return;
}
RefPtr<CancelableTask> task = NewRunnableMethod(
RefPtr<CancelableRunnable> task = NewRunnableMethod(
this, &PreallocatedProcessManagerImpl::DelayedNuwaFork);
mPreallocateAppProcessTask = task;
MessageLoop::current()->PostDelayedTask(task.forget(),
@@ -14,10 +14,6 @@ Cu.import("resource://gre/modules/PermissionsInstaller.jsm");
Cu.import("resource://gre/modules/PermissionsTable.jsm");
Cu.import("resource://gre/modules/PermissionSettings.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "dataStoreService",
"@mozilla.org/datastore-service;1",
"nsIDataStoreService");
this.EXPORTED_SYMBOLS = ["SystemMessagePermissionsChecker",
"SystemMessagePermissionsTable"];
@@ -185,34 +181,6 @@ this.SystemMessagePermissionsChecker = {
return object
},
/**
* Check if the message is a datastore-update message
* @param string aSysMsgName
* The system messsage name.
*/
isDataStoreSystemMessage: function(aSysMsgName) {
return aSysMsgName.indexOf('datastore-update-') === 0;
},
/**
* Check if this manifest can deliver this particular datastore message.
*/
canDeliverDataStoreSystemMessage: function(aSysMsgName, aManifestURL) {
let store = aSysMsgName.substr('datastore-update-'.length);
// Get all the manifest URLs of the apps which can access the datastore.
let manifestURLs = dataStoreService.getAppManifestURLsForDataStore(store);
let enumerate = manifestURLs.enumerate();
while (enumerate.hasMoreElements()) {
let manifestURL = enumerate.getNext().QueryInterface(Ci.nsISupportsString);
if (manifestURL == aManifestURL) {
return true;
}
}
return false;
},
/**
* Check if the system message is permitted to be registered for the given
* app at start-up based on the permissions claimed in the app's manifest.
@@ -258,11 +226,6 @@ this.SystemMessagePermissionsChecker = {
"aPageURL: " + aPageURL + ", " +
"aManifestURL: " + aManifestURL);
if (this.isDataStoreSystemMessage(aSysMsgName) &&
this.canDeliverDataStoreSystemMessage(aSysMsgName, aManifestURL)) {
return true;
}
let permNames = this.getSystemMessagePermissions(aSysMsgName);
if (permNames === null) {
return false;
-1
View File
@@ -55,7 +55,6 @@ DIRS += [
'crypto',
'phonenumberutils',
'alarm',
'datastore',
'devicestorage',
'encoding',
'events',
+6 -6
View File
@@ -169,7 +169,7 @@ NfcConsumer::Send(const CommandOptions& aOptions)
}
// Runnable used dispatch the NfcEventOptions on the main thread.
class NfcConsumer::DispatchNfcEventRunnable final : public nsRunnable
class NfcConsumer::DispatchNfcEventRunnable final : public Runnable
{
public:
DispatchNfcEventRunnable(NfcService* aNfcService, const EventOptions& aEvent)
@@ -391,7 +391,7 @@ NfcConsumer::OnConnectSuccess(int aIndex)
}
}
class NfcConsumer::ShutdownServiceRunnable final : public nsRunnable
class NfcConsumer::ShutdownServiceRunnable final : public Runnable
{
public:
ShutdownServiceRunnable(NfcService* aNfcService)
@@ -463,7 +463,7 @@ NfcService::FactoryCreate()
/**
* |StartConsumerRunnable| calls |NfcConsumer::Start| on the NFC thread.
*/
class NfcService::StartConsumerRunnable final : public nsRunnable
class NfcService::StartConsumerRunnable final : public Runnable
{
public:
StartConsumerRunnable(NfcConsumer* aNfcConsumer)
@@ -516,7 +516,7 @@ NfcService::Start(nsINfcGonkEventListener* aListener)
* thread on the main thread. This has to be down after shutting
* down the NFC consumer on the NFC thread.
*/
class NfcService::CleanupRunnable final : public nsRunnable
class NfcService::CleanupRunnable final : public Runnable
{
public:
CleanupRunnable(NfcConsumer* aNfcConsumer,
@@ -550,7 +550,7 @@ private:
* NFC thread. Optionally, it can dispatch a |CleanupRunnable| to
* the main thread for cleaning up the NFC resources.
*/
class NfcService::ShutdownConsumerRunnable final : public nsRunnable
class NfcService::ShutdownConsumerRunnable final : public Runnable
{
public:
ShutdownConsumerRunnable(NfcConsumer* aNfcConsumer, bool aCleanUp)
@@ -601,7 +601,7 @@ NfcService::Shutdown()
/**
* |SendRunnable| calls |NfcConsumer::Send| on the NFC thread.
*/
class NfcService::SendRunnable final : public nsRunnable
class NfcService::SendRunnable final : public Runnable
{
public:
SendRunnable(NfcConsumer* aNfcConsumer, const CommandOptions& aOptions)
+2 -2
View File
@@ -98,8 +98,8 @@ CopySubscriptionKeyToArray(nsIPushSubscription* aSubscription,
if (NS_FAILED(rv)) {
return rv;
}
if (!aKey.SetLength(keyLen, fallible) ||
!aKey.ReplaceElementsAt(0, keyLen, keyBuffer, keyLen, fallible)) {
if (!aKey.SetCapacity(keyLen, fallible) ||
!aKey.InsertElementsAt(0, keyBuffer, keyLen, fallible)) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
+3 -5
View File
@@ -341,13 +341,10 @@ PushSubscription::ToJSON(PushSubscriptionJSON& aJSON, ErrorResult& aRv)
aJSON.mEndpoint.Construct();
aJSON.mEndpoint.Value() = mEndpoint;
Base64URLEncodeOptions encodeOptions;
encodeOptions.mPad = false;
aJSON.mKeys.mP256dh.Construct();
nsresult rv = Base64URLEncode(mRawP256dhKey.Length(),
mRawP256dhKey.Elements(),
encodeOptions,
Base64URLEncodePaddingPolicy::Omit,
aJSON.mKeys.mP256dh.Value());
if (NS_WARN_IF(NS_FAILED(rv))) {
aRv.Throw(rv);
@@ -356,7 +353,8 @@ PushSubscription::ToJSON(PushSubscriptionJSON& aJSON, ErrorResult& aRv)
aJSON.mKeys.mAuth.Construct();
rv = Base64URLEncode(mAuthSecret.Length(), mAuthSecret.Elements(),
encodeOptions, aJSON.mKeys.mAuth.Value());
Base64URLEncodePaddingPolicy::Omit,
aJSON.mKeys.mAuth.Value());
if (NS_WARN_IF(NS_FAILED(rv))) {
aRv.Throw(rv);
return;
+14 -8
View File
@@ -11,10 +11,20 @@ namespace dom {
PushUtil::CopyArrayBufferToArray(const ArrayBuffer& aBuffer,
nsTArray<uint8_t>& aArray)
{
MOZ_ASSERT(aArray.IsEmpty());
aBuffer.ComputeLengthAndData();
return aArray.SetLength(aBuffer.Length(), fallible) &&
aArray.ReplaceElementsAt(0, aBuffer.Length(), aBuffer.Data(),
aBuffer.Length(), fallible);
return aArray.SetCapacity(aBuffer.Length(), fallible) &&
aArray.InsertElementsAt(0, aBuffer.Data(), aBuffer.Length(), fallible);
}
/* static */ bool
PushUtil::CopyArrayBufferViewToArray(const ArrayBufferView& aView,
nsTArray<uint8_t>& aArray)
{
MOZ_ASSERT(aArray.IsEmpty());
aView.ComputeLengthAndData();
return aArray.SetCapacity(aView.Length(), fallible) &&
aArray.InsertElementsAt(0, aView.Data(), aView.Length(), fallible);
}
/* static */ bool
@@ -25,11 +35,7 @@ PushUtil::CopyBufferSourceToArray(
return CopyArrayBufferToArray(aSource.GetAsArrayBuffer(), aArray);
}
if (aSource.IsArrayBufferView()) {
const ArrayBufferView& view = aSource.GetAsArrayBufferView();
view.ComputeLengthAndData();
return aArray.SetLength(view.Length(), fallible) &&
aArray.ReplaceElementsAt(0, view.Length(), view.Data(),
view.Length(), fallible);
return CopyArrayBufferViewToArray(aSource.GetAsArrayBufferView(), aArray);
}
MOZ_CRASH("Uninitialized union: expected buffer or view");
}
+8
View File
@@ -5,6 +5,10 @@
#ifndef mozilla_dom_PushUtil_h
#define mozilla_dom_PushUtil_h
#include "nsTArray.h"
#include "mozilla/dom/TypedArray.h"
namespace mozilla {
namespace dom {
@@ -20,6 +24,10 @@ public:
CopyArrayBufferToArray(const ArrayBuffer& aBuffer,
nsTArray<uint8_t>& aArray);
static bool
CopyArrayBufferViewToArray(const ArrayBufferView& aView,
nsTArray<uint8_t>& aArray);
static bool
CopyBufferSourceToArray(const OwningArrayBufferViewOrArrayBuffer& aSource,
nsTArray<uint8_t>& aArray);

Some files were not shown because too many files have changed in this diff Show More