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

- Bug 1216751 part 1. Restrict value iterators to interfaces that have indexed properties and pair iterators to interfaces that do not have indexed properties. r=qdot (6519f3f8c5)
- Bug 1216751 part 2. For value iterators, "entries", "keys", and "values" must just come from Array.prototype. r=qdot (c0859f945c)
- Bug 1216751 part 3. For pair iterators, @@iterator should be an alias for "entries". Similarly for maplikes and "entries" and setlikes and "values". r=qdot (bbe7c04782)
- Bug 1216751 part 4. Implement forEach for iterable interfaces. r=qdot (8fdba677a4)
- Bug 1216751 part 5. Remove the now-unnecessary value iterator infrastructure, since it's entirely handled via the %ArrayPrototype% methods now. r=qdot (88d3911694)
- Bug 1231333 - part 1, JS engine: only allow futexWait in workers. r=luke (28e16fd2f9)
- Bug 1231333 - part 2, DOM: only allow futexWait in workers. r=khuey (6c4dc98037)
- Bug 1148990 - Don't ship bagheeraclient.js or tokenserverclient.js on Android. r=gps (aa9b22699a)
- Bug 1216749 - Land the Firefox Kinto.js client (r=rnewman) (ea8c74e2ea)
- Bug 1230221 - Convert JS callsites to use asyncOpen2 within services/ (r=sicking) (07ac8751f1)
- Bug 1242965 - Make services/common eslintable. r=rnewman (0c84562750)
- Bug 1055616 - Skip addons addons without a sourceURI or from a non-secure domain rather than treating them as errors. r=rnewman (7b8b738be0)
- Bug 1229986 - get Sync tps tests starting again. r=whimboo (8cd0bf4f7f)
- Bug 1003204: Removed CommonUtils.exceptionStr() in services/sync r=makh r=gfritzsche (830c106a29)
- Bug 1003204: Removed CommonUtils.exceptionStr() in services/common/ r=gfritzsche (2c7bd4f8b5)
- Bug 1234734 - Replace CommonUtils.stackTrace() with Log.stackTrace(). r=markh (3f0e88f192)
- Bug 1241715 - get Sync TPS tests working locally by tweaking observers listened for and the authentication setup. r=whimboo (529b2f3d44)
- Bug 1203736 - Convert H264::DecodeSPS assert to error return. r=jya (41c8c34c42)
- Bug 1186716: Error if SPS NAL parsing failed. r=rillian (6c158be51e)
- Bug 1187076 - Warn at end of SPS buffers. r=jya (2a49671261)
- fix broken files (a090aad200)
- Bug 1218217: avoid buffersize overflow even if codec is unbounded in dimensions r=pkerr (356140c947)
- Bug 1218217: bustage fix for static assert r=bustage (e86dc5bf3a)
- Bug 1041882 - Remove Froyo-specific support from libcubeb. r=snorp, r=padenot (e1f2d5283f)
- Bug 1073319 - Enable AVX2 for libvpx on linux (update.py). r=rillian (934fd0a896)
- Bug 1245027 - Move LOCAL_INCLUDES to moz.build in media/libvpx. r=mshal (7e56797d0e)
- parts of Bug 1151175 - Update libvpx update.py for 1.4.0. (0e3f4a470f)
- bits of 1178215 (bab7592703)
- Bug 1218124 - Add vpx_once patch to update script. r=gerald (7b72a43382)
- Bug 1225221 - vpx: Allow 8k video in update.sh. r=kinetik (9ec59f7737)
- Bug 1224363 - Upstream update patch - r=rillian (4772921a5f)
- Bug 1224361 - Upstream update patch - r=rillian (36ad6f1de4)
- Bug 1233983 - Make libvpx build with clang-cl; r=rillian (5d98a8d888)
- Bug 1224371 - Upstream update patch. r=jya (25164ba856)
- Bug 1237848 - Updated update.py patch - r=rillian (69646eb6dc)
- Bug 1184226 - Suppressing received packets when disabled, r=ekr (c8dfdb1a56)
- Bug 1184226 - Disabling write on shutdown, r=ekr (d5a810dbe5)
- Bug 1184226 - Updating transportlayerdtls logging levels, r=ekr (f3bc4a9889)
- Bug 1137932: Unwind the stack before starting the DTLS handshake. r=mt (69dce8243a)
- Bug 1214269 - read multiple DTLS packets from NSS if present. r=mt rjesup (e57b1628f5)
- Bug 1235235 - Fix -Wimplicit-fallthrough warning in media/mtransport/. r=ekr (d56c9d1244)
- Bug 1115483 - Accept a match on any a=fingerprint value. r=ekr (4a58378c09)
- Bug 1167274 - Do the right thing when accessing the proxyinfo fails for some reason. r=mt (3ea23173ea)
- Bug 1125292 - Sending ALPN header field for WebRTC calls, r=bwc (16fda60c39)
- Bug 1167443 - Fix verification of end-of-candidates in mochitests. r=mt (8d74546e68)
- Bug 1192813 - update the default candidate as new candidates arrive.  r=bwc (490ac80af2)
- Bug 1206981 - prevent ICE TCP from being turned off under e10s. r=jesup (a38afd56b8)
- Bug 1234578 - Assert if PCM is destroyed improperly. r=rjesup (f1aa0d7cbc)
- Bug 1164564 - WorkerDebugger.initialize should not return failure when called more than once;r=khuey (c316c83af7)
- Bug 1211903 - WorkerDebugger should live on the main thread;r=khuey (5586888e77)
- Bug 1164581 - Adding an overload for NS_ProxyRelease that accepts already_AddRefed, and removing all the others. r=bobbyholley (bc70230689)
- Bug 1186750 part 1 - Inlinize trivial constructors and destructors of events in DeviceStorageRequestParent. r=dhylands (0fc6b594b1)
- Bug 1186750 part 2 - Remove some unused member fields in events in DeviceStorageRequestParent. r=dhylands (d4be7e7031)
- Bug 1186750 part 3 - Abstract CancelableFileEvent in DeviceStorageReqeustParent and use already_AddRefed&& for passing DeviceStorageFile parameter. r=dhylands (cea4df4465)
- Bug 1186750 part 4 - Clear runnable list in DeviceStorageRequestParent when being destroyed. r=dhylands (a4d6018ce6)
- Bug 1196315 - Ensure MIME service is only accessed on the main thread. r=dhylands (20c07f4baf)
- Bug 1186750 part 5 - Convert nsDOMDeviceStorage::CheckPermission to take already_AddRefed&&. r=dhylands (7b2d0b415e)
- Bug 1186750 part 6 - Remove unused and unimplemented method nsDOMDeviceStorage::StorePermission. r=dhylands (e6772e7b51)
- Bug 1186750 part 7 - Convert DispatchToOwningThread and DispatchOrAbandon to take already_AddRefed&&. r=dhylands (5925568a22)
- Bug 1186750 part 8 - Convert DeviceStorageUsedSpaceCache::Dispatch to use already_AddRef&&. r=dhylands (660b44eec7)
- Bug 1186750 part 9 - Use already_AddRefed&& to initialize mFile of device storage requests. r=dhylands (c94464f412)
- Bug 1186750 part 10 - Simplify code in DeviceStorageRequestParent::Dispatch. r=dhylands (debcc219ca)
- Bug 1186750 part 11 - Convert all usage of Dispatch/NS_DispatchToMainThread in dom/devicestorage to pass in either already_AddRefed or raw pointer. r=dhylands (753694d0b5)
- Bug 1059469: Part 1 - Add a log module for dump() calls. r=bent (d94c677e49)
- Bug 1059469: Part 2 - When rescheduling the interval timer, cancel it first, and refactor things so that actually does something. r=bent (1edc485b0f)
- Bug 1243881 - patch 1 - unship performance.translateTime, r=bz (5a4afeea67)
- Bug 1243881 - patch 2 - unship performance.translateTime, r=bz (5bf9557cd4)
- Bug 1165722 - Replace JS_GetPropertyDescriptor usage in Xray code. r=bholley (e277cbcc78)
- Bug 1243824. Add support for static functions and attributes on JSXrays. r=bholley (498d6c6034)
- Bug 1228456 - SharedWorker should close the MessagePort in case the connecting runnable is not dispatched, r=smaug (c14a3e212f)
- Bug 779707 - Add crashtest. (e86caca48e)
- Bug 1228456 - add 'override' to the Cancel() method of a nsICancelableRunnable, rs=me (48db3b97e9)
- Bug 1131323 - Enable SharedWorker loads to be intercepted through service workers; r=nsm (b2d972c5e3)
- Bug 1173002 - Set worker system principal flag correctly when created from chrome, r=bz, a=kwierso. (ac9fc2980d)
- bits of 1113429 backout (a862f16bb7)
- bug 1206312 - add IndexedDatabaseManager include to IDBKeyRange. r=bz (bd6663f976)
- Bug 1247117: De-namespace much of IndexedDB. r=baku (a996e3b443)
- Bug 1196841: Update getAll/getAllKeys to match the spec and expose them. r=baku (7365769e04)
- Bug 1196840: Make IDBTransaction::ObjectStoreNames const. r=baku (e7af2b0510)
- Bug 1176165 - Fix the exception codes returned from functions that modify the IndexedDB schema, r=janv. (efa4e818d0)
- Bug 935753 - Firefox displays the "This is a secure Firefox page" indicator on pages served by addons. r=MattN (77dced27ad)
- Bug 925681 - Show identity block and reload icon in awesomebar in Australis' customization mode. ui-r=shorlander, r=Gijs (ffd1b2f6a4)
- Bug 970382 - Add about:accounts to the list of chrome UIs with a special identity mode r=gavin (6d2817d087)
- Bug 1051847 - Add trusted identity block to about:license and about:rights. r=dao (aa8dfe4d1d)
- Bug 1094947 - The trusted identity block is not displayed for the about:downloads page. r=jaws (1c51faa077)
- Bug 686281 - Implement CSS mask style; r=dbaron. (2f823c4a49)
- Bug 686281 - Mask CSS parsing and Mask DOM API. r=dbaron (f9cc291131)
- Bug 686281 - Mask CSS rendering; r=mstange (b26ba7ba7e)
- Bug 686281 - Mask CSS animation; r=dbaron. (4ce1ba671e)
- Bug 686281 - Mask CSS webkit-alias; r=dbaron. (c27f4023d6)
- Bug 686281 - Mask mochitest; r=dbaron. (010fcdfd04)
- Bug 686281 - Expands will-change of a shorthand prop to longhand ones; r=dbaron. (f8e4a6dcfd)
- Bug 686281 - A static assertion to keep value correctness of NS_RULE_NODE_IS_ANIMATION_RULE; r=dbaron. (5ae87b576b)
- Bug 686281 - Remove nsStyleSVGReset::mMask; r=dbaron (1e7a0dfb45)
- Bug 686281 - mask-composite reftests; r=dbaron (7f769e196a)
- Bug 686281 - Rename nsStyleSVGReset::mLayers to nsStyleSVGReset::mMask; Rename nsStyleBackground::mLayers to nsStyleBackground::mImage. r=dbaron (3bd4fc6e3b)
- Bug 1241275 - Change the way -moz-window-dragging works. r=heycam,roc (5691f2dbf5)
- Bug 1246892 - pass aCTF as a reference instead of value. r=roc (98b0e45063)
- Bug 1234800 - Reinstate code that adjusts dirty rects for fixed-position frames in display ports. r=tn (44e55ebacb)
- Bug 1234800 - Move this line to the right place. r=tn (1a86a7fc72)
- Bug 1216832 - Handle preserve-3d visible regions during display list building by always transforming from the preserve-3d root each time. r=roc (1887af1172)
- Bug 1231243 - In nsDisplayBackgroundImage::GetBoundsInternal(), take the union of the image bounds and the viewport bounds if APZ is enabled. r=mstange (87a1fa0ab4)
- Bug 1246622 - Handle nested preserve-3d contexts when hit testing. r=roc (6eed51c734)
- Bug 1235945 - Fix assertion error in some cases when running szip when debug flags are enabled for host tools. r=froydnj (3a0aa4f728)
- Bug 1224798: Do not produce a clip mask if our context is entirely clipped out anyway. r=jrmuizel (3926a4ef7d)
- Bug 1223604 - Disentangle nsSVGClipPathFrame::ApplyClipOrPaintClipMask and make the code easier to understand. r=Bas (c8c19a1b0d)
- Bug 1204405: Don't access prefs off main thread in testing ProcessLink::Open(). r=khuey (301aa7259d)
- Bug 1248896 - don't conditional compile on config ENABLE_TESTS in Nuwa. r=khuey (4f2fd275fd)
- Bug 1232458 - use UniquePtr<T[]> instead of nsAutoArrayPtr<T> in WindowsDllBlocklist.cpp; r=aklotz (292071bdb5)
- Bug 1247741 - Additional checks for pointer validity in LdrLoadDLL detour. r=aklotz (8ee48e8cf3)
- Bug 1113930 - Move __libc_stack_end related code block from StackWalk.cpp in a non-OSX section. r=froydnj (4f0f9e2e66)
- Bug 1113930 - Use the actual stack end address on x86 OSX and Android for the stack walker. r=froydnj (7371d9a508)
- missing bit of Bug 1216681 (fdf69e362f)
- Bug 1193593 - Test fingerprinting resistance for media queries in picture elements. r=heycam (6155b73c26)
- Bug 1232829 - Detach obsolete DocumentTimeline from refresh driver when the document is reset; r=smaug (564680e2a0)
- Bug 1075457, part 1 - Implement rendering for |clip-path:polygon()|. r=mstange, r=jwatt (76056caacd)
- Bug 1075457, part 2 - Implement circle() and ellipse() for the |clip-path| property. r=mstange, r=jwatt (4b8b39c682)
- Bug 1094571 - add unicode-range load tests. r=heycam (3358555411)
- Bug 1216695 - Remove the Request.context specific bits from fetch-request-resources.https.html; r=bkelly (2315e50b97)
- Bug 1193133 - Disable broken service worker wpt tests. r=bkelly (8f0205d5e7)
- Bug 1199831: Fix a bunch of mixed-content violations in imported ServiceWorker WPTs. r=jdm (33f261ce91)
- bit of Bug 603201 (325170577f)
- Bug 1184798 - same origin, cors and no-cors load tests. r=bkelly (f8549dd0bb)
- Bug 1210581: Test controlled worker loads (XHR, fetch, importScripts). r=ehsan (41a436df47)
- Bug 1215196 - Fix web-platform-tests iframe scripts to avoid pulling in testharness.js in them; r=bkelly (a2edb0784c)
- Bug 1242798 - Don't OSR into Ion on debuggee frames. (r=jandem) (21e17bdd9d)
- Bug 1238658 - Allow setElem-accessor optimizations only for native baseHolder objects; r=efaust (12c9766a53)
- Bug 1144630 - Follup: Fix review nit. (rs=evilpie) (67b5cc2c7f)
- Bug 1182866 - Fix Baseline GETNAME stubs to check for uninitialized lexicals. (r=jandem) (dd47d2025a)
- Bug 1189536 - Make fetch-request-xhr.https.html pass; r=bkelly (ce177226bf)
- Bug 1188822 - Make service-workers/service-worker/fetch-request-resources.https.html pass. r=bkelly (3a5f3a6660)
This commit is contained in:
2023-11-14 15:08:43 +08:00
parent c0c677f5cf
commit e4c3e62beb
430 changed files with 13118 additions and 7404 deletions
-1
View File
@@ -145,7 +145,6 @@ toolbar[printpreview="true"] {
visibility: collapse;
}
#wrapper-urlbar-container #urlbar-container > #urlbar > toolbarbutton,
#urlbar-container:not([combined]) > #urlbar > toolbarbutton,
#urlbar-container[combined] + #reload-button + #stop-button,
#urlbar-container[combined] + #reload-button,
+6 -3
View File
@@ -6404,14 +6404,17 @@ var gIdentityHandler = {
let nsIWebProgressListener = Ci.nsIWebProgressListener;
// For some URIs like data: we can't get a host and so can't do
// anything useful here. Chrome URIs however get special treatment.
// anything useful here.
let unknown = false;
try {
uri.host;
} catch (e) { unknown = true; }
if ((uri.scheme == "chrome" || uri.scheme == "about") &&
uri.spec !== "about:blank") {
// Chrome URIs however get special treatment. Some chrome URIs are
// whitelisted to provide a positive security signal to the user.
let whitelist = /^about:(accounts|addons|app-manager|config|crashes|customizing|downloads|healthreport|home|license|newaddon|permissions|preferences|privatebrowsing|rights|sessionrestore|support|welcomeback)/i;
let isChromeUI = uri.schemeIs("about") && whitelist.test(uri.spec);
if (isChromeUI) {
this.setMode(this.IDENTITY_MODE_CHROMEUI);
} else if (unknown) {
this.setMode(this.IDENTITY_MODE_UNKNOWN);
@@ -0,0 +1,138 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
const DUMMY = "browser/browser/base/content/test/general/dummy_page.html";
function loadNewTab(aURL, aCallback) {
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.loadURI(aURL);
gBrowser.selectedBrowser.addEventListener("load", function() {
if (gBrowser.selectedBrowser.currentURI.spec != aURL)
return;
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
aCallback(gBrowser.selectedTab);
}, true);
}
function getIdentityMode() {
return document.getElementById("identity-box").className;
}
var TESTS = [
function test_webpage() {
let oldTab = gBrowser.selectedTab;
loadNewTab("http://example.com/" + DUMMY, function(aNewTab) {
is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
gBrowser.selectedTab = oldTab;
is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
gBrowser.selectedTab = aNewTab;
is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
gBrowser.removeTab(aNewTab);
runNextTest();
});
},
function test_blank() {
let oldTab = gBrowser.selectedTab;
loadNewTab("about:blank", function(aNewTab) {
is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
gBrowser.selectedTab = oldTab;
is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
gBrowser.selectedTab = aNewTab;
is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
gBrowser.removeTab(aNewTab);
runNextTest();
});
},
function test_chrome() {
let oldTab = gBrowser.selectedTab;
// Since users aren't likely to type in full chrome URLs, we won't show
// the positive security indicator on it, but we will show it on about:addons.
loadNewTab("chrome://mozapps/content/extensions/extensions.xul", function(aNewTab) {
is(getIdentityMode(), "unknownIdentity", "Identity should be chrome");
gBrowser.selectedTab = oldTab;
is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
gBrowser.selectedTab = aNewTab;
is(getIdentityMode(), "unknownIdentity", "Identity should be chrome");
gBrowser.removeTab(aNewTab);
runNextTest();
});
},
function test_https() {
let oldTab = gBrowser.selectedTab;
loadNewTab("https://example.com/" + DUMMY, function(aNewTab) {
is(getIdentityMode(), "verifiedDomain", "Identity should be verified");
gBrowser.selectedTab = oldTab;
is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
gBrowser.selectedTab = aNewTab;
is(getIdentityMode(), "verifiedDomain", "Identity should be verified");
gBrowser.removeTab(aNewTab);
runNextTest();
});
},
function test_addons() {
let oldTab = gBrowser.selectedTab;
loadNewTab("about:addons", function(aNewTab) {
is(getIdentityMode(), "chromeUI", "Identity should be chrome");
gBrowser.selectedTab = oldTab;
is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
gBrowser.selectedTab = aNewTab;
is(getIdentityMode(), "chromeUI", "Identity should be chrome");
gBrowser.removeTab(aNewTab);
runNextTest();
});
}
];
var gTestStart = null;
function runNextTest() {
if (gTestStart)
info("Test part took " + (Date.now() - gTestStart) + "ms");
if (TESTS.length == 0) {
finish();
return;
}
info("Running " + TESTS[0].name);
gTestStart = Date.now();
TESTS.shift()();
};
function test() {
waitForExplicitFinish();
runNextTest();
}
+8 -3
View File
@@ -110,6 +110,8 @@ void
DocumentTimeline::WillRefresh(mozilla::TimeStamp aTime)
{
MOZ_ASSERT(mIsObservingRefreshDriver);
MOZ_ASSERT(GetRefreshDriver(),
"Should be able to reach refresh driver from within WillRefresh");
bool needsTicks = false;
nsTArray<Animation*> animationsToRemove(mAnimations.Count());
@@ -143,10 +145,13 @@ DocumentTimeline::WillRefresh(mozilla::TimeStamp aTime)
}
if (!needsTicks) {
// If another refresh driver observer destroys the nsPresContext,
// nsRefreshDriver will detect it and we won't be called.
// We already assert that GetRefreshDriver() is non-null at the beginning
// of this function but we check it again here to be sure that ticking
// animations does not have any side effects that cause us to lose the
// connection with the refresh driver, such as triggering the destruction
// of mDocument's PresShell.
MOZ_ASSERT(GetRefreshDriver(),
"Refresh driver should still be valid inside WillRefresh");
"Refresh driver should still be valid at end of WillRefresh");
GetRefreshDriver()->RemoveRefreshObserver(this, Flush_Style);
mIsObservingRefreshDriver = false;
}
+1 -11
View File
@@ -49,17 +49,7 @@ ArchiveReaderEvent::ArchiveReaderEvent(ArchiveReader* aArchiveReader)
ArchiveReaderEvent::~ArchiveReaderEvent()
{
if (!NS_IsMainThread()) {
nsIMIMEService* mimeService;
mMimeService.forget(&mimeService);
if (mimeService) {
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
NS_WARN_IF_FALSE(mainThread, "Couldn't get the main thread! Leaking!");
if (mainThread) {
NS_ProxyRelease(mainThread, mimeService);
}
}
NS_ReleaseOnMainThread(mMimeService.forget());
}
MOZ_COUNT_DTOR(ArchiveReaderEvent);
+2 -2
View File
@@ -778,11 +778,11 @@ Console::~Console()
if (!NS_IsMainThread()) {
if (mStorage) {
NS_ReleaseOnMainThread(mStorage);
NS_ReleaseOnMainThread(mStorage.forget());
}
if (mSandbox) {
NS_ReleaseOnMainThread(mSandbox);
NS_ReleaseOnMainThread(mSandbox.forget());
}
}
+2 -2
View File
@@ -636,8 +636,8 @@ WebSocketImpl::Disconnect()
// until the end of the method.
RefPtr<WebSocketImpl> kungfuDeathGrip = this;
NS_ReleaseOnMainThread(mChannel);
NS_ReleaseOnMainThread(static_cast<nsIWebSocketEventService*>(mService.forget().take()));
NS_ReleaseOnMainThread(mChannel.forget());
NS_ReleaseOnMainThread(mService.forget());
mWebSocket->DontKeepAliveAnyMore();
mWebSocket->mImpl = nullptr;
+8
View File
@@ -289,6 +289,8 @@ bool nsContentUtils::sFragmentParsingActive = false;
bool nsContentUtils::sDOMWindowDumpEnabled;
#endif
mozilla::LazyLogModule nsContentUtils::sDOMDumpLog("Dump");
// Subset of http://www.whatwg.org/specs/web-apps/current-work/#autofill-field-name
enum AutocompleteFieldName
{
@@ -7161,6 +7163,12 @@ nsContentUtils::DOMWindowDumpEnabled()
#endif
}
mozilla::LogModule*
nsContentUtils::DOMDumpLog()
{
return sDOMDumpLog;
}
bool
nsContentUtils::GetNodeTextContent(nsINode* aNode, bool aDeep, nsAString& aResult,
const fallible_t& aFallible)
+10 -1
View File
@@ -31,6 +31,7 @@
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/FloatingPoint.h"
#include "mozilla/net/ReferrerPolicy.h"
#include "mozilla/Logging.h"
#include "nsIContentPolicy.h"
#if defined(XP_WIN)
@@ -2380,10 +2381,17 @@ public:
const nsAString& aVersion);
/**
* Return true if the browser.dom.window.dump.enabled pref is set.
* Returns true if the browser.dom.window.dump.enabled pref is set.
*/
static bool DOMWindowDumpEnabled();
/**
* Returns a LogModule that dump calls from content script are logged to.
* This can be enabled with the 'Dump' module, and is useful for synchronizing
* content JS to other logging modules.
*/
static mozilla::LogModule* DOMDumpLog();
/**
* Returns whether a content is an insertion point for XBL
* bindings or web components ShadowRoot. In web components,
@@ -2733,6 +2741,7 @@ private:
#if !(defined(DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
static bool sDOMWindowDumpEnabled;
#endif
static mozilla::LazyLogModule sDOMDumpLog;
};
class MOZ_RAII nsAutoScriptBlocker {
+4 -7
View File
@@ -77,8 +77,8 @@
#include "mozilla/dom/TabChild.h"
#include "mozilla/dom/IDBFactoryBinding.h"
#include "mozilla/dom/IDBMutableFileBinding.h"
#include "mozilla/dom/indexedDB/IDBMutableFile.h"
#include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
#include "mozilla/dom/IDBMutableFile.h"
#include "mozilla/dom/IndexedDatabaseManager.h"
#include "mozilla/dom/PermissionMessageUtils.h"
#include "mozilla/dom/quota/PersistenceType.h"
#include "mozilla/dom/quota/QuotaManager.h"
@@ -2989,7 +2989,7 @@ nsDOMWindowUtils::GetFileId(JS::Handle<JS::Value> aFile, JSContext* aCx,
JSObject* obj = aFile.toObjectOrNull();
indexedDB::IDBMutableFile* mutableFile = nullptr;
IDBMutableFile* mutableFile = nullptr;
if (NS_SUCCEEDED(UNWRAP_OBJECT(IDBMutableFile, obj, mutableFile))) {
*_retval = mutableFile->GetFileId();
return NS_OK;
@@ -3061,8 +3061,7 @@ nsDOMWindowUtils::GetFileReferences(const nsAString& aDatabaseName, int64_t aId,
quota::PersistenceType persistenceType =
quota::PersistenceTypeFromStorage(options.mStorage);
RefPtr<indexedDB::IndexedDatabaseManager> mgr =
indexedDB::IndexedDatabaseManager::Get();
RefPtr<IndexedDatabaseManager> mgr = IndexedDatabaseManager::Get();
if (mgr) {
rv = mgr->BlockAndGetFileReferences(persistenceType, origin, aDatabaseName,
@@ -3083,8 +3082,6 @@ nsDOMWindowUtils::FlushPendingFileDeletions()
{
MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
using mozilla::dom::indexedDB::IndexedDatabaseManager;
RefPtr<IndexedDatabaseManager> mgr = IndexedDatabaseManager::Get();
if (mgr) {
nsresult rv = mgr->FlushPendingFileDeletions();
+9 -1
View File
@@ -2133,7 +2133,15 @@ nsDocument::Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup)
// Note that, since mTiming does not change during a reset, the
// navigationStart time remains unchanged and therefore any future new
// timeline will have the same global clock time as the old one.
mDocumentTimeline = nullptr;
if (mDocumentTimeline) {
nsRefreshDriver* rd = mPresShell && mPresShell->GetPresContext() ?
mPresShell->GetPresContext()->RefreshDriver() :
nullptr;
if (rd) {
mDocumentTimeline->NotifyRefreshDriverDestroying(rd);
}
mDocumentTimeline = nullptr;
}
nsCOMPtr<nsIPropertyBag2> bag = do_QueryInterface(aChannel);
if (bag) {
+2 -2
View File
@@ -183,8 +183,8 @@
#include "prenv.h"
#include "prprf.h"
#include "mozilla/dom/IDBFactory.h"
#include "mozilla/dom/MessageChannel.h"
#include "mozilla/dom/indexedDB/IDBFactory.h"
#include "mozilla/dom/Promise.h"
#ifdef MOZ_GAMEPAD
@@ -266,7 +266,6 @@ using mozilla::OriginAttributes;
using mozilla::TimeStamp;
using mozilla::TimeDuration;
using mozilla::dom::cache::CacheStorage;
using mozilla::dom::indexedDB::IDBFactory;
static LazyLogModule gDOMLeakPRLog("DOMLeak");
@@ -6481,6 +6480,7 @@ nsGlobalWindow::Dump(const nsAString& aStr)
#endif
if (cstr) {
MOZ_LOG(nsContentUtils::DOMDumpLog(), LogLevel::Debug, ("[Window.Dump] %s", cstr));
#ifdef XP_WIN
PrintToDebugger(cstr);
#endif
+2 -4
View File
@@ -124,9 +124,7 @@ class WindowOrientationObserver;
namespace cache {
class CacheStorage;
} // namespace cache
namespace indexedDB {
class IDBFactory;
} // namespace indexedDB
} // namespace dom
namespace gfx {
class VRDeviceProxy;
@@ -953,7 +951,7 @@ public:
mozilla::dom::DOMStorage* GetLocalStorage(mozilla::ErrorResult& aError);
mozilla::dom::Selection* GetSelectionOuter();
mozilla::dom::Selection* GetSelection(mozilla::ErrorResult& aError);
mozilla::dom::indexedDB::IDBFactory* GetIndexedDB(mozilla::ErrorResult& aError);
mozilla::dom::IDBFactory* GetIndexedDB(mozilla::ErrorResult& aError);
already_AddRefed<nsICSSDeclaration>
GetComputedStyle(mozilla::dom::Element& aElt, const nsAString& aPseudoElt,
mozilla::ErrorResult& aError);
@@ -1789,7 +1787,7 @@ protected:
// unsuspending it.
nsCOMPtr<nsIDocument> mSuspendedDoc;
RefPtr<mozilla::dom::indexedDB::IDBFactory> mIndexedDB;
RefPtr<mozilla::dom::IDBFactory> mIndexedDB;
// This counts the number of windows that have been opened in rapid succession
// (i.e. within dom.successive_dialog_time_limit of each other). It is reset
-34
View File
@@ -11,7 +11,6 @@
#include "nsDOMNavigationTiming.h"
#include "nsContentUtils.h"
#include "nsIScriptSecurityManager.h"
#include "nsGlobalWindow.h"
#include "nsIDOMWindow.h"
#include "nsILoadInfo.h"
#include "nsIURI.h"
@@ -30,8 +29,6 @@
#include "mozilla/Preferences.h"
#include "mozilla/IntegerPrintfMacros.h"
#include "mozilla/TimeStamp.h"
#include "SharedWorker.h"
#include "ServiceWorker.h"
#include "js/HeapAPI.h"
#include "GeckoProfiler.h"
#include "WorkerPrivate.h"
@@ -923,37 +920,6 @@ PerformanceBase::ClearResourceTimings()
mResourceEntries.Clear();
}
DOMHighResTimeStamp
PerformanceBase::TranslateTime(DOMHighResTimeStamp aTime,
const WindowOrWorkerOrSharedWorkerOrServiceWorker& aTimeSource,
ErrorResult& aRv)
{
TimeStamp otherCreationTimeStamp;
if (aTimeSource.IsWindow()) {
RefPtr<nsPerformance> performance = aTimeSource.GetAsWindow().GetPerformance();
if (NS_WARN_IF(!performance)) {
aRv.Throw(NS_ERROR_FAILURE);
}
otherCreationTimeStamp = performance->CreationTimeStamp();
} else if (aTimeSource.IsWorker()) {
otherCreationTimeStamp = aTimeSource.GetAsWorker().CreationTimeStamp();
} else if (aTimeSource.IsSharedWorker()) {
SharedWorker& sharedWorker = aTimeSource.GetAsSharedWorker();
WorkerPrivate* workerPrivate = sharedWorker.GetWorkerPrivate();
otherCreationTimeStamp = workerPrivate->CreationTimeStamp();
} else if (aTimeSource.IsServiceWorker()) {
ServiceWorker& serviceWorker = aTimeSource.GetAsServiceWorker();
WorkerPrivate* workerPrivate = serviceWorker.GetWorkerPrivate();
otherCreationTimeStamp = workerPrivate->CreationTimeStamp();
} else {
MOZ_CRASH("This should not be possible.");
}
return RoundTime(
aTime + (otherCreationTimeStamp - CreationTimeStamp()).ToMilliseconds());
}
DOMHighResTimeStamp
PerformanceBase::RoundTime(double aTime) const
{
-6
View File
@@ -30,7 +30,6 @@ namespace dom {
class PerformanceEntry;
class PerformanceObserver;
class WindowOrWorkerOrSharedWorkerOrServiceWorker;
} // namespace dom
} // namespace mozilla
@@ -318,11 +317,6 @@ public:
virtual DOMHighResTimeStamp Now() const = 0;
DOMHighResTimeStamp
TranslateTime(DOMHighResTimeStamp aTime,
const mozilla::dom::WindowOrWorkerOrSharedWorkerOrServiceWorker& aTimeSource,
mozilla::ErrorResult& aRv);
void Mark(const nsAString& aName, mozilla::ErrorResult& aRv);
void ClearMarks(const mozilla::dom::Optional<nsAString>& aName);
void Measure(const nsAString& aName,
+5 -12
View File
@@ -297,7 +297,9 @@ nsScriptLoader::StartLoad(nsScriptLoadRequest *aRequest, const nsAString &aType,
aRequest->mCORSMode == CORS_NONE
? nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL
: nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS;
if (aRequest->mCORSMode == CORS_USE_CREDENTIALS) {
if (aRequest->mCORSMode == CORS_ANONYMOUS) {
securityFlags |= nsILoadInfo::SEC_COOKIES_SAME_ORIGIN;
} else if (aRequest->mCORSMode == CORS_USE_CREDENTIALS) {
securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
}
securityFlags |= nsILoadInfo::SEC_ALLOW_CHROME;
@@ -803,17 +805,8 @@ nsScriptLoader::ProcessOffThreadRequest(nsScriptLoadRequest* aRequest)
NotifyOffThreadScriptLoadCompletedRunnable::~NotifyOffThreadScriptLoadCompletedRunnable()
{
if (MOZ_UNLIKELY(mRequest || mLoader) && !NS_IsMainThread()) {
nsCOMPtr<nsIThread> mainThread;
NS_GetMainThread(getter_AddRefs(mainThread));
if (mainThread) {
NS_ProxyRelease(mainThread, mRequest);
NS_ProxyRelease(mainThread, mLoader);
} else {
MOZ_ASSERT(false, "We really shouldn't leak!");
// Better to leak than crash.
Unused << mRequest.forget();
Unused << mLoader.forget();
}
NS_ReleaseOnMainThread(mRequest.forget());
NS_ReleaseOnMainThread(mLoader.forget());
}
}
-1
View File
@@ -1 +0,0 @@
/* nothing here */
-2
View File
@@ -256,7 +256,6 @@ support-files =
file_explicit_user_agent.sjs
referrer_change_server.sjs
file_change_policy_redirect.html
empty_worker.js
file_bug1198095.js
[test_anonymousContent_api.html]
@@ -847,6 +846,5 @@ skip-if = e10s || os != 'linux' || buildapp != 'browser'
[test_change_policy.html]
skip-if = buildapp == 'b2g' #no ssl support
[test_document.all_iteration.html]
[test_performance_translate.html]
[test_bug1198095.html]
[test_bug1187157.html]
@@ -1,75 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for performance.translate()</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="test_performance_user_timing.js"></script>
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
function testBasic() {
ok("translateTime" in performance, "Performance.translateTime exists.");
try {
performance.translateTime(0, null);
ok(false, "Wrong use of performance.translateTime.");
} catch(e) {
ok(true, "Wrong use of performance.translateTime.");
}
next();
}
function testWindow() {
is(performance.translateTime(42, this), 42, "translating time with the same window.");
var now = performance.now();
var ifr = document.createElement('iframe');
ifr.src = 'file_empty.html';
document.body.appendChild(ifr);
ifr.onload = function() {
var a = performance.translateTime(0, ifr.contentWindow);
ok (a >= now, "Time has been translated from a window that started loading later than we did");
next();
}
}
function testWorker() {
var now = performance.now();
var w = new Worker('empty_worker.js');
var a = performance.translateTime(0, w);
// bug 1226147
ok (a >= now, "Time has been translated from a Worker that started loading later than we did");
next();
}
function testSharedWorker() {
var now = performance.now();
var w = new SharedWorker('empty_worker.js');
var a = performance.translateTime(0, w);
ok (a >= now, "Time has been translated from a SharedWorker that started loading later than we did");
next();
}
var tests = [ testBasic, testWindow, testWorker, testSharedWorker ];
function next() {
if (!tests.length) {
SimpleTest.finish();
return;
}
var test = tests.shift();
test();
}
SimpleTest.waitForExplicitFinish();
addLoadEvent(next);
</script>
</pre>
</body>
</html>
+2 -38
View File
@@ -612,7 +612,6 @@ DOMInterfaces = {
},
'IDBCursor': {
'nativeType': 'mozilla::dom::indexedDB::IDBCursor',
'implicitJSContext': [ 'delete' ],
'binaryNames': {
'direction': 'getDirection'
@@ -620,27 +619,10 @@ DOMInterfaces = {
},
'IDBCursorWithValue': {
'nativeType': 'mozilla::dom::indexedDB::IDBCursor',
},
'IDBDatabase': {
'nativeType': 'mozilla::dom::indexedDB::IDBDatabase',
},
'IDBFactory': {
'nativeType': 'mozilla::dom::indexedDB::IDBFactory',
},
'IDBFileHandle': {
'nativeType': 'mozilla::dom::indexedDB::IDBFileHandle',
},
'IDBFileRequest': {
'nativeType': 'mozilla::dom::indexedDB::IDBFileRequest',
'nativeType': 'mozilla::dom::IDBCursor',
},
'IDBIndex': {
'nativeType': 'mozilla::dom::indexedDB::IDBIndex',
'binaryNames': {
'mozGetAll': 'getAll',
'mozGetAllKeys': 'getAllKeys',
@@ -648,43 +630,25 @@ DOMInterfaces = {
},
'IDBKeyRange': {
'nativeType': 'mozilla::dom::indexedDB::IDBKeyRange',
'headerFile': 'mozilla/dom/indexedDB/IDBKeyRange.h',
'wrapperCache': False,
},
'IDBLocaleAwareKeyRange': {
'nativeType': 'mozilla::dom::indexedDB::IDBLocaleAwareKeyRange',
'headerFile': 'mozilla/dom/indexedDB/IDBKeyRange.h',
'headerFile': 'IDBKeyRange.h',
'wrapperCache': False,
},
'IDBMutableFile': {
'nativeType': 'mozilla::dom::indexedDB::IDBMutableFile',
},
'IDBObjectStore': {
'nativeType': 'mozilla::dom::indexedDB::IDBObjectStore',
'binaryNames': {
'mozGetAll': 'getAll'
}
},
'IDBOpenDBRequest': {
'nativeType': 'mozilla::dom::indexedDB::IDBOpenDBRequest',
'headerFile': 'IDBRequest.h'
},
'IDBRequest': {
'nativeType': 'mozilla::dom::indexedDB::IDBRequest',
},
'IDBTransaction': {
'nativeType': 'mozilla::dom::indexedDB::IDBTransaction',
},
'IDBVersionChangeEvent': {
'nativeType': 'mozilla::dom::indexedDB::IDBVersionChangeEvent',
'headerFile': 'IDBEvents.h',
},
+78 -35
View File
@@ -1138,11 +1138,13 @@ class CGHeaders(CGWrapper):
if desc.interface.maplikeOrSetlikeOrIterable:
# We need ToJSValue.h for maplike/setlike type conversions
bindingHeaders.add("mozilla/dom/ToJSValue.h")
# Add headers for the key and value types of the maplike, since
# they'll be needed for convenience functions
addHeadersForType((desc.interface.maplikeOrSetlikeOrIterable.keyType,
desc, None))
if desc.interface.maplikeOrSetlikeOrIterable.valueType:
# Add headers for the key and value types of the
# maplike/setlike/iterable, since they'll be needed for
# convenience functions
if desc.interface.maplikeOrSetlikeOrIterable.hasKeyType():
addHeadersForType((desc.interface.maplikeOrSetlikeOrIterable.keyType,
desc, None))
if desc.interface.maplikeOrSetlikeOrIterable.hasValueType():
addHeadersForType((desc.interface.maplikeOrSetlikeOrIterable.valueType,
desc, None))
@@ -2271,34 +2273,49 @@ class MethodDefiner(PropertyDefiner):
"condition": MemberCondition()
})
# Generate the maplike/setlike iterator, if one wasn't already
# generated by a method. If we already have an @@iterator symbol, fail.
if descriptor.interface.maplikeOrSetlikeOrIterable:
if hasIterator(methods, self.regular):
raise TypeError("Cannot have maplike/setlike/iterable interface with "
"other members that generate @@iterator "
"on interface %s, such as indexed getters "
"or aliased functions." %
self.descriptor.interface.identifier.name)
for m in methods:
if (m.isMaplikeOrSetlikeOrIterableMethod() and
(((m.maplikeOrSetlikeOrIterable.isMaplike() or
(m.maplikeOrSetlikeOrIterable.isIterable() and
m.maplikeOrSetlikeOrIterable.hasValueType())) and
m.identifier.name == "entries") or
(((m.maplikeOrSetlikeOrIterable.isSetlike() or
(m.maplikeOrSetlikeOrIterable.isIterable() and
not m.maplikeOrSetlikeOrIterable.hasValueType()))) and
m.identifier.name == "values"))):
self.regular.append({
"name": "@@iterator",
"methodName": m.identifier.name,
"length": methodLength(m),
"flags": "0",
"condition": PropertyDefiner.getControllingCondition(m,
descriptor),
})
break
# Generate the keys/values/entries aliases for value iterables.
maplikeOrSetlikeOrIterable = descriptor.interface.maplikeOrSetlikeOrIterable
if (not static and
maplikeOrSetlikeOrIterable and
maplikeOrSetlikeOrIterable.isIterable() and
maplikeOrSetlikeOrIterable.isValueIterator()):
# Add our keys/values/entries/forEach
self.regular.append({
"name": "keys",
"methodInfo": False,
"selfHostedName": "ArrayKeys",
"length": 0,
"flags": "JSPROP_ENUMERATE",
"condition": PropertyDefiner.getControllingCondition(m,
descriptor)
})
self.regular.append({
"name": "values",
"methodInfo": False,
"selfHostedName": "ArrayValues",
"length": 0,
"flags": "JSPROP_ENUMERATE",
"condition": PropertyDefiner.getControllingCondition(m,
descriptor)
})
self.regular.append({
"name": "entries",
"methodInfo": False,
"selfHostedName": "ArrayEntries",
"length": 0,
"flags": "JSPROP_ENUMERATE",
"condition": PropertyDefiner.getControllingCondition(m,
descriptor)
})
self.regular.append({
"name": "forEach",
"methodInfo": False,
"selfHostedName": "ArrayForEach",
"length": 0,
"flags": "JSPROP_ENUMERATE",
"condition": PropertyDefiner.getControllingCondition(m,
descriptor)
})
if not static:
stringifier = descriptor.operations['Stringifier']
@@ -13079,8 +13096,9 @@ class CGForwardDeclarations(CGWrapper):
# arguments to helper functions, and they'll need to be forward
# declared in the header.
if d.interface.maplikeOrSetlikeOrIterable:
builder.forwardDeclareForType(d.interface.maplikeOrSetlikeOrIterable.keyType,
config)
if d.interface.maplikeOrSetlikeOrIterable.hasKeyType():
builder.forwardDeclareForType(d.interface.maplikeOrSetlikeOrIterable.keyType,
config)
if d.interface.maplikeOrSetlikeOrIterable.hasValueType():
builder.forwardDeclareForType(d.interface.maplikeOrSetlikeOrIterable.valueType,
config)
@@ -15808,6 +15826,31 @@ class CGIterableMethodGenerator(CGGeneric):
using CGCallGenerator.
"""
def __init__(self, descriptor, iterable, methodName):
if methodName == "forEach":
CGGeneric.__init__(self, fill(
"""
if (!JS::IsCallable(arg0)) {
ThrowErrorMessage(cx, MSG_NOT_CALLABLE, "Argument 1 of ${ifaceName}.forEach");
return false;
}
JS::AutoValueArray<3> callArgs(cx);
callArgs[2].setObject(*obj);
JS::Rooted<JS::Value> ignoredReturnVal(cx);
for (size_t i = 0; i < self->GetIterableLength(); ++i) {
if (!ToJSValue(cx, self->GetValueAtIndex(i), callArgs[0])) {
return false;
}
if (!ToJSValue(cx, self->GetKeyAtIndex(i), callArgs[1])) {
return false;
}
if (!JS::Call(cx, arg1, arg0, JS::HandleValueArray(callArgs),
&ignoredReturnVal)) {
return false;
}
}
""",
ifaceName=descriptor.interface.identifier.name))
return
CGGeneric.__init__(self, fill(
"""
typedef ${iterClass} itrType;
+2 -5
View File
@@ -900,8 +900,5 @@ def getAllTypes(descriptors, dictionaries, callbacks):
def iteratorNativeType(descriptor):
assert descriptor.interface.isIterable()
iterableDecl = descriptor.interface.maplikeOrSetlikeOrIterable
if iterableDecl.valueType is None:
iterClass = "OneTypeIterableIterator"
else:
iterClass = "TwoTypeIterableIterator"
return "mozilla::dom::%s<%s>" % (iterClass, descriptor.nativeType)
assert iterableDecl.isPairIterator()
return "mozilla::dom::IterableIterator<%s>" % descriptor.nativeType
+71 -164
View File
@@ -6,19 +6,17 @@
/**
* The IterableIterator class is used for WebIDL interfaces that have a
* iterable<> member defined. It handles the ES6 Iterator-like functions that
* are generated for the iterable interface.
* iterable<> member defined with two types (so a pair iterator). It handles
* the ES6 Iterator-like functions that are generated for the iterable
* interface.
*
* For iterable interfaces, the implementation class will need to
* implement these two functions:
* For iterable interfaces with a pair iterator, the implementation class will
* need to implement these two functions:
*
* - size_t GetIterableLength()
* - Returns the number of elements available to iterate over
* - [type] GetValueAtIndex(size_t index)
* - Returns the value at the requested index.
*
* If this is a two-type iterator, then the implementation class will also need to implement:
*
* - [type] GetKeyAtIndex(size_t index)
* - Returns the key at the requested index
*
@@ -60,13 +58,77 @@ protected:
};
template <typename T>
class IterableIterator : public IterableIteratorBase
class IterableIterator final : public IterableIteratorBase
{
public:
explicit IterableIterator(T* aIterableObj)
typedef bool (*WrapFunc)(JSContext* aCx,
IterableIterator<T>* aObject,
JS::Handle<JSObject*> aGivenProto,
JS::MutableHandle<JSObject*> aReflector);
explicit IterableIterator(T* aIterableObj,
IterableIteratorType aIteratorType,
WrapFunc aWrapFunc)
: mIterableObj(aIterableObj)
, mIteratorType(aIteratorType)
, mWrapFunc(aWrapFunc)
, mIndex(0)
{
MOZ_ASSERT(mIterableObj);
MOZ_ASSERT(mWrapFunc);
}
void
Next(JSContext* aCx, JS::MutableHandle<JSObject*> aResult, ErrorResult& aRv)
{
JS::Rooted<JS::Value> value(aCx, JS::UndefinedValue());
if (mIndex >= this->mIterableObj->GetIterableLength()) {
DictReturn(aCx, aResult, true, value, aRv);
return;
}
switch (mIteratorType) {
case IterableIteratorType::Keys:
{
if (!ToJSValue(aCx, this->mIterableObj->GetKeyAtIndex(mIndex), &value)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
DictReturn(aCx, aResult, false, value, aRv);
break;
}
case IterableIteratorType::Values:
{
if (!ToJSValue(aCx, this->mIterableObj->GetValueAtIndex(mIndex), &value)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
DictReturn(aCx, aResult, false, value, aRv);
break;
}
case IterableIteratorType::Entries:
{
JS::Rooted<JS::Value> key(aCx);
if (!ToJSValue(aCx, this->mIterableObj->GetKeyAtIndex(mIndex), &key)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
if (!ToJSValue(aCx, this->mIterableObj->GetValueAtIndex(mIndex), &value)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
KeyAndValueReturn(aCx, key, value, aResult, aRv);
break;
}
default:
MOZ_CRASH("Invalid iterator type!");
}
++mIndex;
}
bool
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aObj)
{
return (*mWrapFunc)(aCx, this, aGivenProto, aObj);
}
protected:
@@ -128,161 +190,6 @@ protected:
// Binding Implementation object that we're iterating over.
RefPtr<T> mIterableObj;
};
template<typename T>
class OneTypeIterableIterator final : public IterableIterator<T>
{
public:
typedef typename IterableIterator<T>::IterableIteratorType IterableIteratorType;
using IterableIterator<T>::DictReturn;
using IterableIterator<T>::KeyAndValueReturn;
typedef bool (*WrapFunc)(JSContext* aCx,
OneTypeIterableIterator<T>* aObject,
JS::Handle<JSObject*> aGivenProto,
JS::MutableHandle<JSObject*> aReflector);
OneTypeIterableIterator(T* aIterableObj,
IterableIteratorType aIteratorType,
WrapFunc aWrapFunc)
: IterableIterator<T>(aIterableObj)
, mIteratorType(aIteratorType)
, mWrapFunc(aWrapFunc)
, mIndex(0)
{
MOZ_ASSERT(mWrapFunc);
}
void
Next(JSContext* aCx, JS::MutableHandle<JSObject*> aResult, ErrorResult& aRv)
{
JS::Rooted<JS::Value> value(aCx, JS::UndefinedValue());
if (mIndex >= this->mIterableObj->GetIterableLength()) {
DictReturn(aCx, aResult, true, value, aRv);
return;
}
switch (mIteratorType) {
case IterableIteratorType::Keys:
case IterableIteratorType::Values:
{
if (!ToJSValue(aCx, this->mIterableObj->GetValueAtIndex(mIndex), &value)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
DictReturn(aCx, aResult, false, value, aRv);
break;
}
case IterableIteratorType::Entries:
{
if (!ToJSValue(aCx, this->mIterableObj->GetValueAtIndex(mIndex), &value)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
KeyAndValueReturn(aCx, value, value, aResult, aRv);
break;
}
default:
MOZ_CRASH("Invalid iterator type!");
}
++mIndex;
}
bool
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aObj)
{
return (*mWrapFunc)(aCx, this, aGivenProto, aObj);
}
protected:
virtual ~OneTypeIterableIterator() {}
// Tells whether this is a key, value, or entries iterator.
IterableIteratorType mIteratorType;
// Function pointer to binding-type-specific Wrap() call for this iterator.
WrapFunc mWrapFunc;
// Current index of iteration.
uint32_t mIndex;
};
template<typename T>
class TwoTypeIterableIterator final : public IterableIterator<T>
{
public:
typedef typename IterableIterator<T>::IterableIteratorType IterableIteratorType;
using IterableIterator<T>::DictReturn;
using IterableIterator<T>::KeyAndValueReturn;
typedef bool (*WrapFunc)(JSContext* aCx,
TwoTypeIterableIterator<T>* aObject,
JS::Handle<JSObject*> aGivenProto,
JS::MutableHandle<JSObject*> aReflector);
TwoTypeIterableIterator(T* aIterableObj, IterableIteratorType aIteratorType,
WrapFunc aWrapFunc)
: IterableIterator<T>(aIterableObj)
, mIteratorType(aIteratorType)
, mWrapFunc(aWrapFunc)
, mIndex(0)
{
MOZ_ASSERT(mWrapFunc);
}
void
Next(JSContext* aCx, JS::MutableHandle<JSObject*> aResult, ErrorResult& aRv)
{
JS::Rooted<JS::Value> value(aCx, JS::UndefinedValue());
if (mIndex >= this->mIterableObj->GetIterableLength()) {
DictReturn(aCx, aResult, true, value, aRv);
return;
}
switch (mIteratorType) {
case IterableIteratorType::Keys:
{
if (!ToJSValue(aCx, this->mIterableObj->GetKeyAtIndex(mIndex), &value)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
DictReturn(aCx, aResult, false, value, aRv);
break;
}
case IterableIteratorType::Values:
{
if (!ToJSValue(aCx, this->mIterableObj->GetValueAtIndex(mIndex), &value)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
DictReturn(aCx, aResult, false, value, aRv);
break;
}
case IterableIteratorType::Entries:
{
JS::Rooted<JS::Value> key(aCx);
if (!ToJSValue(aCx, this->mIterableObj->GetKeyAtIndex(mIndex), &key)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
if (!ToJSValue(aCx, this->mIterableObj->GetValueAtIndex(mIndex), &value)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
KeyAndValueReturn(aCx, key, value, aResult, aRv);
break;
}
default:
MOZ_CRASH("Invalid iterator type!");
}
++mIndex;
}
bool
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aObj)
{
return (*mWrapFunc)(aCx, this, aGivenProto, aObj);
}
protected:
virtual ~TwoTypeIterableIterator() {}
// Tells whether this is a key, value, or entries iterator.
IterableIteratorType mIteratorType;
// Function pointer to binding-type-specific Wrap() call for this iterator.
+100 -25
View File
@@ -1092,7 +1092,7 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
def validate(self):
# We don't support consequential unforgeable interfaces. Need to check
# this here, becaue in finish() an interface might not know yet that
# this here, because in finish() an interface might not know yet that
# it's consequential.
if self.getExtendedAttribute("Unforgeable") and self.isConsequential():
raise WebIDLError(
@@ -1111,6 +1111,8 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
self.identifier.name,
locations)
indexedGetter = None
hasLengthAttribute = False
for member in self.members:
member.validate()
@@ -1121,8 +1123,13 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
[self.location, member.location])
# Check that PutForwards refers to another attribute and that no
# cycles exist in forwarded assignments.
# cycles exist in forwarded assignments. Also check for a
# integer-typed "length" attribute.
if member.isAttr():
if (member.identifier.name == "length" and
member.type.isInteger()):
hasLengthAttribute = True
iface = self
attr = member
putForwards = attr.getExtendedAttribute("PutForwards")
@@ -1160,8 +1167,11 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
putForwards = attr.getExtendedAttribute("PutForwards")
# Check that the name of an [Alias] doesn't conflict with an
# interface member.
# interface member and whether we support indexed properties.
if member.isMethod():
if member.isGetter() and member.isIndexed():
indexedGetter = member
for alias in member.aliases:
if self.isOnGlobalProtoChain():
raise WebIDLError("[Alias] must not be used on a "
@@ -1222,6 +1232,35 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
"exposed conditionally",
[self.location])
# Value iterators are only allowed on interfaces with indexed getters,
# and pair iterators are only allowed on interfaces without indexed
# getters.
if self.isIterable():
iterableDecl = self.maplikeOrSetlikeOrIterable
if iterableDecl.isValueIterator():
if not indexedGetter:
raise WebIDLError("Interface with value iterator does not "
"support indexed properties",
[self.location])
if iterableDecl.valueType != indexedGetter.signatures()[0][0]:
raise WebIDLError("Iterable type does not match indexed "
"getter type",
[iterableDecl.location,
indexedGetter.location])
if not hasLengthAttribute:
raise WebIDLError('Interface with value iterator does not '
'have an integer-typed "length" attribute',
[self.location])
else:
assert iterableDecl.isPairIterator()
if indexedGetter:
raise WebIDLError("Interface with pair iterator supports "
"indexed properties",
[self.location, iterableDecl.location,
indexedGetter.location])
def isInterface(self):
return True
@@ -3420,7 +3459,10 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
def __init__(self, location, identifier, ifaceType, keyType, valueType, ifaceKind):
IDLInterfaceMember.__init__(self, location, identifier, ifaceKind)
assert isinstance(keyType, IDLType)
if keyType is not None:
assert isinstance(keyType, IDLType)
else:
assert valueType is not None
assert ifaceType in ['maplike', 'setlike', 'iterable']
if valueType is not None:
assert isinstance(valueType, IDLType)
@@ -3439,6 +3481,9 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
def isIterable(self):
return self.maplikeOrSetlikeOrIterableType == "iterable"
def hasKeyType(self):
return self.keyType is not None
def hasValueType(self):
return self.valueType is not None
@@ -3463,7 +3508,8 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
[self.location, member.location])
def addMethod(self, name, members, allowExistingOperations, returnType, args=[],
chromeOnly=False, isPure=False, affectsNothing=False, newObject=False):
chromeOnly=False, isPure=False, affectsNothing=False, newObject=False,
isIteratorAlias=False):
"""
Create an IDLMethod based on the parameters passed in.
@@ -3523,16 +3569,20 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
if newObject:
method.addExtendedAttributes(
[IDLExtendedAttribute(self.location, ("NewObject",))])
if isIteratorAlias:
method.addExtendedAttributes(
[IDLExtendedAttribute(self.location, ("Alias", "@@iterator"))])
members.append(method)
def resolve(self, parentScope):
self.keyType.resolveType(parentScope)
if self.keyType:
self.keyType.resolveType(parentScope)
if self.valueType:
self.valueType.resolveType(parentScope)
def finish(self, scope):
IDLInterfaceMember.finish(self, scope)
if not self.keyType.isComplete():
if self.keyType and not self.keyType.isComplete():
t = self.keyType.complete(scope)
assert not isinstance(t, IDLUnresolvedType)
@@ -3554,9 +3604,23 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
IDLInterfaceMember.handleExtendedAttribute(self, attr)
def _getDependentObjects(self):
deps = set()
if self.keyType:
deps.add(self.keyType)
if self.valueType:
return set([self.keyType, self.valueType])
return set([self.keyType])
deps.add(self.valueType)
return deps
def getForEachArguments(self):
return [IDLArgument(self.location,
IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"),
"callback"),
BuiltinTypes[IDLBuiltinType.Types.object]),
IDLArgument(self.location,
IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"),
"thisArg"),
BuiltinTypes[IDLBuiltinType.Types.any],
optional=True)]
# Iterable adds ES6 iterator style functions and traits
# (keys/values/entries/@@iterator) to an interface.
@@ -3577,9 +3641,15 @@ class IDLIterable(IDLMaplikeOrSetlikeOrIterableBase):
we generate our functions as if they were part of the interface
specification during parsing.
"""
# We only need to add entries/keys/values here if we're a pair iterator.
# Value iterators just copy these from %ArrayPrototype% instead.
if not self.isPairIterator():
return
# object entries()
self.addMethod("entries", members, False, self.iteratorType,
affectsNothing=True, newObject=True)
affectsNothing=True, newObject=True,
isIteratorAlias=True)
# object keys()
self.addMethod("keys", members, False, self.iteratorType,
affectsNothing=True, newObject=True)
@@ -3587,6 +3657,17 @@ class IDLIterable(IDLMaplikeOrSetlikeOrIterableBase):
self.addMethod("values", members, False, self.iteratorType,
affectsNothing=True, newObject=True)
# void forEach(callback(valueType, keyType), optional any thisArg)
self.addMethod("forEach", members, False,
BuiltinTypes[IDLBuiltinType.Types.void],
self.getForEachArguments())
def isValueIterator(self):
return not self.isPairIterator()
def isPairIterator(self):
return self.hasKeyType()
# MaplikeOrSetlike adds ES6 map-or-set-like traits to an interface.
class IDLMaplikeOrSetlike(IDLMaplikeOrSetlikeOrIterableBase):
@@ -3623,26 +3704,17 @@ class IDLMaplikeOrSetlike(IDLMaplikeOrSetlikeOrIterableBase):
# object entries()
self.addMethod("entries", members, False, BuiltinTypes[IDLBuiltinType.Types.object],
affectsNothing=True)
affectsNothing=True, isIteratorAlias=self.isMaplike())
# object keys()
self.addMethod("keys", members, False, BuiltinTypes[IDLBuiltinType.Types.object],
affectsNothing=True)
# object values()
self.addMethod("values", members, False, BuiltinTypes[IDLBuiltinType.Types.object],
affectsNothing=True)
affectsNothing=True, isIteratorAlias=self.isSetlike())
# void forEach(callback(valueType, keyType), thisVal)
foreachArguments = [IDLArgument(self.location,
IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"),
"callback"),
BuiltinTypes[IDLBuiltinType.Types.object]),
IDLArgument(self.location,
IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"),
"thisArg"),
BuiltinTypes[IDLBuiltinType.Types.any],
optional=True)]
self.addMethod("forEach", members, False, BuiltinTypes[IDLBuiltinType.Types.void],
foreachArguments)
self.getForEachArguments())
def getKeyArg():
return IDLArgument(self.location,
@@ -5448,10 +5520,13 @@ class Parser(Tokenizer):
location = self.getLocation(p, 2)
identifier = IDLUnresolvedIdentifier(location, "__iterable",
allowDoubleUnderscore=True)
keyType = p[3]
valueType = None
if (len(p) > 6):
keyType = p[3]
valueType = p[5]
else:
keyType = None
valueType = p[3]
p[0] = IDLIterable(location, identifier, keyType, valueType, self.globalScope())
def p_Setlike(self, p):
@@ -6521,7 +6596,7 @@ class Parser(Tokenizer):
if isinstance(m, IDLIterable):
iterable = m
break
if iterable:
if iterable and iterable.isPairIterator():
def simpleExtendedAttr(str):
return IDLExtendedAttribute(iface.location, (str, ))
nextMethod = IDLMethod(
@@ -45,8 +45,8 @@ def WebIDLTest(parser, harness):
prefix + " - Interface failed but not as a WebIDLError exception: %s" % e)
iterableMembers = [(x, WebIDL.IDLMethod) for x in ["entries", "keys",
"values"]]
setROMembers = ([(x, WebIDL.IDLMethod) for x in ["has", "forEach"]] +
"values", "forEach"]]
setROMembers = ([(x, WebIDL.IDLMethod) for x in ["has"]] +
[("__setlike", WebIDL.IDLMaplikeOrSetlike)] +
iterableMembers)
setROMembers.extend([("size", WebIDL.IDLAttribute)])
@@ -62,7 +62,7 @@ def WebIDLTest(parser, harness):
"__clear",
"__delete"]] +
setRWMembers)
mapROMembers = ([(x, WebIDL.IDLMethod) for x in ["get", "has", "forEach"]] +
mapROMembers = ([(x, WebIDL.IDLMethod) for x in ["get", "has"]] +
[("__maplike", WebIDL.IDLMaplikeOrSetlike)] +
iterableMembers)
mapROMembers.extend([("size", WebIDL.IDLAttribute)])
@@ -78,6 +78,10 @@ def WebIDLTest(parser, harness):
# __iterable to it for the iterable<> case.
iterableMembers.append(("__iterable", WebIDL.IDLIterable))
valueIterableMembers = [("__iterable", WebIDL.IDLIterable)]
valueIterableMembers.append(("__indexedgetter", WebIDL.IDLMethod))
valueIterableMembers.append(("length", WebIDL.IDLAttribute))
disallowedIterableNames = ["keys", "entries", "values"]
disallowedMemberNames = ["forEach", "has", "size"] + disallowedIterableNames
mapDisallowedMemberNames = ["get"] + disallowedMemberNames
@@ -93,10 +97,10 @@ def WebIDLTest(parser, harness):
"""
interface Foo1 {
iterable<long>;
readonly attribute unsigned long length;
getter long(unsigned long index);
};
""", iterableMembers,
# numProductions == 2 because of the generated iterator iface,
numProductions=2)
""", valueIterableMembers)
shouldPass("Iterable (key and value)",
"""
@@ -23,7 +23,7 @@ NS_INTERFACE_MAP_END
TestInterfaceIterableSingle::TestInterfaceIterableSingle(nsPIDOMWindow* aParent)
: mParent(aParent)
{
for(int i = 0; i < 3; ++i) {
for (int i = 0; i < 3; ++i) {
mValues.AppendElement(i);
}
}
@@ -55,17 +55,22 @@ TestInterfaceIterableSingle::GetParentObject() const
return mParent;
}
size_t
TestInterfaceIterableSingle::GetIterableLength() const
uint32_t
TestInterfaceIterableSingle::Length() const
{
return mValues.Length();
}
uint32_t
TestInterfaceIterableSingle::GetValueAtIndex(uint32_t index) const
int32_t
TestInterfaceIterableSingle::IndexedGetter(uint32_t aIndex, bool& aFound) const
{
MOZ_ASSERT(index < mValues.Length());
return mValues.ElementAt(index);
if (aIndex >= mValues.Length()) {
aFound = false;
return 0;
}
aFound = true;
return mValues[aIndex];
}
} // namespace dom
@@ -36,12 +36,12 @@ public:
static already_AddRefed<TestInterfaceIterableSingle>
Constructor(const GlobalObject& aGlobal, ErrorResult& rv);
size_t GetIterableLength() const;
uint32_t GetValueAtIndex(uint32_t aIndex) const;
uint32_t Length() const;
int32_t IndexedGetter(uint32_t aIndex, bool& aFound) const;
private:
virtual ~TestInterfaceIterableSingle() {}
nsCOMPtr<nsPIDOMWindow> mParent;
nsTArray<uint32_t> mValues;
nsTArray<int32_t> mValues;
};
} // namespace dom
@@ -93,7 +93,8 @@
is(e[1], 1, "SimpleMap: iterable second array element should be value");
}
is(m[Symbol.iterator].length, 0, "SimpleMap: @@iterator symbol is correct length");
is(m[Symbol.iterator].name, "[Symbol.iterator]", "SimpleMap: @@iterator symbol has correct name");
is(m[Symbol.iterator].name, "entries", "SimpleMap: @@iterator symbol has correct name");
is(m[Symbol.iterator], m.entries, 'SimpleMap: @@iterator is an alias for "entries"');
ok(iterable, "SimpleMap: @@iterator symbol resolved correctly");
for (var k of m.keys()) {
is(k, "test", "SimpleMap: first keys element should be 'test'");
@@ -139,7 +140,8 @@
is(e, "test", "SimpleSet: iterable first array element should be key");
}
is(m[Symbol.iterator].length, 0, "SimpleSet: @@iterator symbol is correct length");
is(m[Symbol.iterator].name, "[Symbol.iterator]", "SimpleSet: @@iterator symbol has correct name");
is(m[Symbol.iterator].name, "values", "SimpleSet: @@iterator symbol has correct name");
is(m[Symbol.iterator], m.values, 'SimpleSet: @@iterator is an alias for "values"');
ok(iterable, "SimpleSet: @@iterator symbol resolved correctly");
for (var k of m.keys()) {
is(k, "test", "SimpleSet: first keys element should be 'test'");
+49 -2
View File
@@ -14,7 +14,8 @@
base_properties = [["entries", "function", 0],
["keys", "function", 0],
["values", "function", 0]]
["values", "function", 0],
["forEach", "function", 1]]
var testExistence = function testExistence(prefix, obj, properties) {
for (var [name, type, args] of properties) {
// Properties are somewhere up the proto chain, hasOwnProperty won't work
@@ -50,6 +51,16 @@
info("IterableSingle: Testing simple iterable creation and functionality");
itr = new TestInterfaceIterableSingle();
testExistence("IterableSingle: ", itr, base_properties);
is(itr[Symbol.iterator], Array.prototype[Symbol.iterator],
"IterableSingle: Should be using %ArrayIterator% for @@iterator");
is(itr.keys, Array.prototype.keys,
"IterableSingle: Should be using %ArrayIterator% for 'keys'");
is(itr.entries, Array.prototype.entries,
"IterableSingle: Should be using %ArrayIterator% for 'entries'");
is(itr.values, itr[Symbol.iterator],
"IterableSingle: Should be using @@iterator for 'values'");
is(itr.forEach, Array.prototype.forEach,
"IterableSingle: Should be using %ArrayIterator% for 'forEach'");
var keys = [...itr.keys()];
var values = [...itr.values()];
var entries = [...itr.entries()];
@@ -73,6 +84,23 @@
is(entry.value[1], entries[i][1],
"IterableSingle: Entry iterator value 1 should match destructuring " + i);
}
var callsToForEachCallback = 0;
var thisArg = {};
itr.forEach(function(value, index, obj) {
is(index, callsToForEachCallback,
`IterableSingle: Should have the right index at ${callsToForEachCallback} calls to forEach callback`);
is(value, values[index],
`IterableSingle: Should have the right value at ${callsToForEachCallback} calls to forEach callback`);
is(this, thisArg,
"IterableSingle: Should have the right this value for forEach callback");
is(obj, itr,
"IterableSingle: Should have the right third arg for forEach callback");
++callsToForEachCallback;
}, thisArg);
is(callsToForEachCallback, 3,
"IterableSingle: Should have right total number of calls to forEach callback");
var key = key_itr.next();
var value = value_itr.next();
var entry = entries_itr.next();
@@ -83,13 +111,15 @@
is(entry.value, undefined, "IterableDouble: Entry iterator value should be undefined");
is(entry.done, true, "IterableSingle: Entry iterator done should be true");
is(Object.prototype.toString.call(Object.getPrototypeOf(key_itr)),
"[object TestInterfaceIterableSingleIteratorPrototype]",
"[object Array Iterator]",
"iterator prototype should have the right brand");
// Simple dual type iterable creation and functionality test
info("IterableDouble: Testing simple iterable creation and functionality");
itr = new TestInterfaceIterableDouble();
testExistence("IterableDouble: ", itr, base_properties);
is(itr.entries, itr[Symbol.iterator],
"IterableDouble: Should be using @@iterator for 'entries'");
var elements = [["a", "b"], ["c", "d"], ["e", "f"]]
var keys = [...itr.keys()];
var values = [...itr.values()];
@@ -114,6 +144,23 @@
is(entry.value[1], entries[i][1],
"IterableDouble: Entry iterator value 1 should match destructuring " + i);
}
callsToForEachCallback = 0;
thisArg = {};
itr.forEach(function(value, key, obj) {
is(key, keys[callsToForEachCallback],
`IterableDouble: Should have the right key at ${callsToForEachCallback} calls to forEach callback`);
is(value, values[callsToForEachCallback],
`IterableDouble: Should have the right value at ${callsToForEachCallback} calls to forEach callback`);
is(this, thisArg,
"IterableDouble: Should have the right this value for forEach callback");
is(obj, itr,
"IterableSingle: Should have the right third arg for forEach callback");
++callsToForEachCallback;
}, thisArg);
is(callsToForEachCallback, 3,
"IterableDouble: Should have right total number of calls to forEach callback");
var key = key_itr.next();
var value = value_itr.next();
var entry = entries_itr.next()
+1 -4
View File
@@ -73,10 +73,7 @@ ManagerId::~ManagerId()
// The PBackground worker thread shouldn't be running after the main thread
// is stopped. So main thread is guaranteed to exist here.
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
MOZ_ASSERT(mainThread);
NS_ProxyRelease(mainThread, mPrincipal.forget().take());
NS_ReleaseOnMainThread(mPrincipal.forget());
}
} // namespace cache
+8 -8
View File
@@ -9,15 +9,15 @@
#include "DataStoreCallbacks.h"
#include "jsapi.h"
#include "mozilla/dom/IDBDatabaseBinding.h"
#include "mozilla/dom/IDBDatabase.h"
#include "mozilla/dom/IDBEvents.h"
#include "mozilla/dom/IDBFactory.h"
#include "mozilla/dom/IDBFactoryBinding.h"
#include "mozilla/dom/IDBIndex.h"
#include "mozilla/dom/IDBObjectStore.h"
#include "mozilla/dom/IDBObjectStoreBinding.h"
#include "mozilla/dom/indexedDB/IDBDatabase.h"
#include "mozilla/dom/indexedDB/IDBEvents.h"
#include "mozilla/dom/indexedDB/IDBFactory.h"
#include "mozilla/dom/indexedDB/IDBIndex.h"
#include "mozilla/dom/indexedDB/IDBObjectStore.h"
#include "mozilla/dom/indexedDB/IDBRequest.h"
#include "mozilla/dom/indexedDB/IDBTransaction.h"
#include "mozilla/dom/IDBRequest.h"
#include "mozilla/dom/IDBTransaction.h"
#include "nsComponentManagerUtils.h"
#include "nsContentUtils.h"
#include "nsIDOMEvent.h"
@@ -354,7 +354,7 @@ DataStoreDB::Delete()
return NS_OK;
}
indexedDB::IDBTransaction*
IDBTransaction*
DataStoreDB::Transaction() const
{
MOZ_ASSERT(mTransaction);
+6 -9
View File
@@ -18,14 +18,11 @@
namespace mozilla {
namespace dom {
namespace indexedDB {
class DataStoreDBCallback;
class IDBDatabase;
class IDBFactory;
class IDBOpenDBRequest;
class IDBTransaction;
} // namespace indexedDB
class DataStoreDBCallback;
class DataStoreDB final : public nsIDOMEventListener
{
@@ -39,7 +36,7 @@ public:
nsresult Delete();
indexedDB::IDBTransaction* Transaction() const;
IDBTransaction* Transaction() const;
// nsIDOMEventListener
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) override;
@@ -59,10 +56,10 @@ private:
nsString mDatabaseName;
RefPtr<indexedDB::IDBFactory> mFactory;
RefPtr<indexedDB::IDBOpenDBRequest> mRequest;
RefPtr<indexedDB::IDBDatabase> mDatabase;
RefPtr<indexedDB::IDBTransaction> mTransaction;
RefPtr<IDBFactory> mFactory;
RefPtr<IDBOpenDBRequest> mRequest;
RefPtr<IDBDatabase> mDatabase;
RefPtr<IDBTransaction> mTransaction;
RefPtr<DataStoreDBCallback> mCallback;
+2 -4
View File
@@ -9,16 +9,14 @@
#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 "mozilla/dom/indexedDB/IDBObjectStore.h"
#include "mozilla/dom/indexedDB/IDBRequest.h"
#include "nsIDOMEvent.h"
namespace mozilla {
namespace dom {
using namespace indexedDB;
NS_IMPL_ISUPPORTS(DataStoreRevision, nsIDOMEventListener)
// Note: this code in it must not assume anything about the compartment cx is
+3 -6
View File
@@ -15,12 +15,9 @@
namespace mozilla {
namespace dom {
namespace indexedDB {
class DataStoreRevisionCallback;
class IDBObjectStore;
class IDBRequest;
} // namespace indexedDB
class DataStoreRevisionCallback;
class DataStoreRevision final : public nsIDOMEventListener
{
@@ -32,7 +29,7 @@ public:
};
nsresult AddRevision(JSContext* aCx,
indexedDB::IDBObjectStore* aStore,
IDBObjectStore* aStore,
uint32_t aObjectId,
RevisionType aRevisionType,
DataStoreRevisionCallback* aCallback);
@@ -43,7 +40,7 @@ public:
private:
~DataStoreRevision() {}
RefPtr<DataStoreRevisionCallback> mCallback;
RefPtr<indexedDB::IDBRequest> mRequest;
RefPtr<IDBRequest> mRequest;
nsString mRevisionID;
};
+4 -6
View File
@@ -21,10 +21,10 @@
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/DOMError.h"
#include "mozilla/dom/indexedDB/IDBCursor.h"
#include "mozilla/dom/indexedDB/IDBObjectStore.h"
#include "mozilla/dom/indexedDB/IDBRequest.h"
#include "mozilla/dom/indexedDB/IDBTransaction.h"
#include "mozilla/dom/IDBCursor.h"
#include "mozilla/dom/IDBObjectStore.h"
#include "mozilla/dom/IDBRequest.h"
#include "mozilla/dom/IDBTransaction.h"
#include "mozilla/dom/PermissionMessageUtils.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/unused.h"
@@ -63,8 +63,6 @@ using mozilla::OriginAttributes;
namespace mozilla {
namespace dom {
using namespace indexedDB;
// This class contains all the information about a DataStore.
class DataStoreInfo
{
+9 -3
View File
@@ -87,6 +87,13 @@ public:
uint32_t aFileType,
uint32_t aFileAttributes);
static already_AddRefed<DeviceStorageFile>
CreateUnique(const nsAString& aStorageType,
const nsAString& aStorageName,
nsAString& aFileName,
uint32_t aFileType,
uint32_t aFileAttributes);
NS_DECL_THREADSAFE_ISUPPORTS
bool IsAvailable();
@@ -300,11 +307,10 @@ public:
already_AddRefed<DOMRequest> CreateAndRejectDOMRequest(const char *aReason,
ErrorResult& aRv);
nsresult CheckPermission(DeviceStorageRequest* aRequest);
void StorePermission(DeviceStorageRequest* aRequest, bool aAllow);
nsresult CheckPermission(already_AddRefed<DeviceStorageRequest>&& aRequest);
bool IsOwningThread();
nsresult DispatchToOwningThread(nsIRunnable* aRunnable);
nsresult DispatchToOwningThread(already_AddRefed<nsIRunnable>&& aRunnable);
private:
~nsDOMDeviceStorage();
+81 -314
View File
@@ -36,6 +36,7 @@ DeviceStorageRequestParent::DeviceStorageRequestParent(
void
DeviceStorageRequestParent::Dispatch()
{
RefPtr<CancelableRunnable> r;
switch (mParams.type()) {
case DeviceStorageParams::TDeviceStorageAddParams:
{
@@ -52,13 +53,8 @@ DeviceStorageRequestParent::Dispatch()
blobImpl->GetInternalStream(getter_AddRefs(stream), rv);
MOZ_ASSERT(!rv.Failed());
RefPtr<CancelableRunnable> r = new WriteFileEvent(this, dsf, stream,
DEVICE_STORAGE_REQUEST_CREATE);
nsCOMPtr<nsIEventTarget> target
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
MOZ_ASSERT(target);
target->Dispatch(r, NS_DISPATCH_NORMAL);
r = new WriteFileEvent(this, dsf.forget(), stream,
DEVICE_STORAGE_REQUEST_CREATE);
break;
}
@@ -77,13 +73,8 @@ DeviceStorageRequestParent::Dispatch()
blobImpl->GetInternalStream(getter_AddRefs(stream), rv);
MOZ_ASSERT(!rv.Failed());
RefPtr<CancelableRunnable> r = new WriteFileEvent(this, dsf, stream,
DEVICE_STORAGE_REQUEST_APPEND);
nsCOMPtr<nsIEventTarget> target
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
MOZ_ASSERT(target);
target->Dispatch(r, NS_DISPATCH_NORMAL);
r = new WriteFileEvent(this, dsf.forget(), stream,
DEVICE_STORAGE_REQUEST_APPEND);
break;
}
@@ -94,12 +85,7 @@ DeviceStorageRequestParent::Dispatch()
RefPtr<DeviceStorageFile> dsf =
new DeviceStorageFile(p.type(), p.storageName(), p.relpath());
RefPtr<CancelableRunnable> r = new CreateFdEvent(this, dsf);
nsCOMPtr<nsIEventTarget> target
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
MOZ_ASSERT(target);
target->Dispatch(r, NS_DISPATCH_NORMAL);
r = new CreateFdEvent(this, dsf.forget());
break;
}
@@ -109,12 +95,7 @@ DeviceStorageRequestParent::Dispatch()
RefPtr<DeviceStorageFile> dsf =
new DeviceStorageFile(p.type(), p.storageName(),
p.rootDir(), p.relpath());
RefPtr<CancelableRunnable> r = new ReadFileEvent(this, dsf);
nsCOMPtr<nsIEventTarget> target
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
MOZ_ASSERT(target);
target->Dispatch(r, NS_DISPATCH_NORMAL);
r = new ReadFileEvent(this, dsf.forget());
break;
}
@@ -124,12 +105,7 @@ DeviceStorageRequestParent::Dispatch()
RefPtr<DeviceStorageFile> dsf =
new DeviceStorageFile(p.type(), p.storageName(), p.relpath());
RefPtr<CancelableRunnable> r = new DeleteFileEvent(this, dsf);
nsCOMPtr<nsIEventTarget> target
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
MOZ_ASSERT(target);
target->Dispatch(r, NS_DISPATCH_NORMAL);
r = new DeleteFileEvent(this, dsf.forget());
break;
}
@@ -139,12 +115,7 @@ DeviceStorageRequestParent::Dispatch()
RefPtr<DeviceStorageFile> dsf =
new DeviceStorageFile(p.type(), p.storageName());
RefPtr<FreeSpaceFileEvent> r = new FreeSpaceFileEvent(this, dsf);
nsCOMPtr<nsIEventTarget> target
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
MOZ_ASSERT(target);
target->Dispatch(r, NS_DISPATCH_NORMAL);
r = new FreeSpaceFileEvent(this, dsf.forget());
break;
}
@@ -158,10 +129,9 @@ DeviceStorageRequestParent::Dispatch()
RefPtr<DeviceStorageFile> dsf =
new DeviceStorageFile(p.type(), p.storageName());
RefPtr<UsedSpaceFileEvent> r = new UsedSpaceFileEvent(this, dsf);
usedSpaceCache->Dispatch(r);
break;
usedSpaceCache->Dispatch(
MakeAndAddRef<UsedSpaceFileEvent>(this, dsf.forget()));
return;
}
case DeviceStorageParams::TDeviceStorageFormatParams:
@@ -170,11 +140,10 @@ DeviceStorageRequestParent::Dispatch()
RefPtr<DeviceStorageFile> dsf =
new DeviceStorageFile(p.type(), p.storageName());
RefPtr<PostFormatResultEvent> r
= new PostFormatResultEvent(this, dsf);
DebugOnly<nsresult> rv = NS_DispatchToMainThread(r);
DebugOnly<nsresult> rv = NS_DispatchToMainThread(
new PostFormatResultEvent(this, dsf.forget()));
MOZ_ASSERT(NS_SUCCEEDED(rv));
break;
return;
}
case DeviceStorageParams::TDeviceStorageMountParams:
@@ -183,11 +152,10 @@ DeviceStorageRequestParent::Dispatch()
RefPtr<DeviceStorageFile> dsf =
new DeviceStorageFile(p.type(), p.storageName());
RefPtr<PostMountResultEvent> r
= new PostMountResultEvent(this, dsf);
DebugOnly<nsresult> rv = NS_DispatchToMainThread(r);
DebugOnly<nsresult> rv = NS_DispatchToMainThread(
new PostMountResultEvent(this, dsf.forget()));
MOZ_ASSERT(NS_SUCCEEDED(rv));
break;
return;
}
case DeviceStorageParams::TDeviceStorageUnmountParams:
@@ -196,11 +164,10 @@ DeviceStorageRequestParent::Dispatch()
RefPtr<DeviceStorageFile> dsf =
new DeviceStorageFile(p.type(), p.storageName());
RefPtr<PostUnmountResultEvent> r
= new PostUnmountResultEvent(this, dsf);
DebugOnly<nsresult> rv = NS_DispatchToMainThread(r);
DebugOnly<nsresult> rv = NS_DispatchToMainThread(
new PostUnmountResultEvent(this, dsf.forget()));
MOZ_ASSERT(NS_SUCCEEDED(rv));
break;
return;
}
case DeviceStorageParams::TDeviceStorageEnumerationParams:
@@ -209,21 +176,22 @@ DeviceStorageRequestParent::Dispatch()
RefPtr<DeviceStorageFile> dsf
= new DeviceStorageFile(p.type(), p.storageName(),
p.rootdir(), NS_LITERAL_STRING(""));
RefPtr<CancelableRunnable> r
= new EnumerateFileEvent(this, dsf, p.since());
nsCOMPtr<nsIEventTarget> target
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
MOZ_ASSERT(target);
target->Dispatch(r, NS_DISPATCH_NORMAL);
r = new EnumerateFileEvent(this, dsf.forget(), p.since());
break;
}
default:
{
NS_RUNTIMEABORT("not reached");
break;
return;
}
}
if (r) {
nsCOMPtr<nsIEventTarget> target =
do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
MOZ_ASSERT(target);
target->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
}
}
bool
@@ -393,10 +361,15 @@ DeviceStorageRequestParent::ActorDestroy(ActorDestroyReason)
{
MutexAutoLock lock(mMutex);
mActorDestroyed = true;
int32_t count = mRunnables.Length();
for (int32_t index = 0; index < count; index++) {
mRunnables[index]->Cancel();
for (auto& runnable : mRunnables) {
runnable->Cancel();
}
// Ensure we clear all references to the runnables so that there won't
// be leak due to cyclic reference. Note that it is safe to release
// the references here, since if a runnable is not cancelled yet, the
// corresponding thread should still hold a reference to it, and thus
// the runnable will end up being released in that thread, not here.
mRunnables.Clear();
}
DeviceStorageRequestParent::PostFreeSpaceResultEvent::PostFreeSpaceResultEvent(
@@ -419,19 +392,6 @@ DeviceStorageRequestParent::PostFreeSpaceResultEvent::CancelableRun() {
return NS_OK;
}
DeviceStorageRequestParent::PostUsedSpaceResultEvent::
PostUsedSpaceResultEvent(DeviceStorageRequestParent* aParent,
const nsAString& aType,
uint64_t aUsedSpace)
: CancelableRunnable(aParent)
, mType(aType)
, mUsedSpace(aUsedSpace)
{
}
DeviceStorageRequestParent::PostUsedSpaceResultEvent::
~PostUsedSpaceResultEvent() {}
nsresult
DeviceStorageRequestParent::PostUsedSpaceResultEvent::CancelableRun() {
MOZ_ASSERT(NS_IsMainThread());
@@ -448,8 +408,6 @@ DeviceStorageRequestParent::PostErrorEvent::
CopyASCIItoUTF16(aError, mError);
}
DeviceStorageRequestParent::PostErrorEvent::~PostErrorEvent() {}
nsresult
DeviceStorageRequestParent::PostErrorEvent::CancelableRun() {
MOZ_ASSERT(NS_IsMainThread());
@@ -459,14 +417,6 @@ DeviceStorageRequestParent::PostErrorEvent::CancelableRun() {
return NS_OK;
}
DeviceStorageRequestParent::PostSuccessEvent::
PostSuccessEvent(DeviceStorageRequestParent* aParent)
: CancelableRunnable(aParent)
{
}
DeviceStorageRequestParent::PostSuccessEvent::~PostSuccessEvent() {}
nsresult
DeviceStorageRequestParent::PostSuccessEvent::CancelableRun() {
MOZ_ASSERT(NS_IsMainThread());
@@ -476,22 +426,6 @@ DeviceStorageRequestParent::PostSuccessEvent::CancelableRun() {
return NS_OK;
}
DeviceStorageRequestParent::PostBlobSuccessEvent::
PostBlobSuccessEvent(DeviceStorageRequestParent* aParent,
DeviceStorageFile* aFile,
uint32_t aLength,
nsACString& aMimeType,
uint64_t aLastModifiedDate)
: CancelableRunnable(aParent)
, mLength(aLength)
, mLastModificationDate(aLastModifiedDate)
, mFile(aFile)
, mMimeType(aMimeType)
{
}
DeviceStorageRequestParent::PostBlobSuccessEvent::~PostBlobSuccessEvent() {}
nsresult
DeviceStorageRequestParent::PostBlobSuccessEvent::CancelableRun() {
MOZ_ASSERT(NS_IsMainThread());
@@ -520,21 +454,6 @@ DeviceStorageRequestParent::PostBlobSuccessEvent::CancelableRun() {
return NS_OK;
}
DeviceStorageRequestParent::PostEnumerationSuccessEvent::
PostEnumerationSuccessEvent(DeviceStorageRequestParent* aParent,
const nsAString& aStorageType,
const nsAString& aRelPath,
InfallibleTArray<DeviceStorageFileValue>& aPaths)
: CancelableRunnable(aParent)
, mStorageType(aStorageType)
, mRelPath(aRelPath)
, mPaths(aPaths)
{
}
DeviceStorageRequestParent::PostEnumerationSuccessEvent::
~PostEnumerationSuccessEvent() {}
nsresult
DeviceStorageRequestParent::PostEnumerationSuccessEvent::CancelableRun() {
MOZ_ASSERT(NS_IsMainThread());
@@ -544,36 +463,23 @@ DeviceStorageRequestParent::PostEnumerationSuccessEvent::CancelableRun() {
return NS_OK;
}
DeviceStorageRequestParent::CreateFdEvent::
CreateFdEvent(DeviceStorageRequestParent* aParent,
DeviceStorageFile* aFile)
: CancelableRunnable(aParent)
, mFile(aFile)
{
}
DeviceStorageRequestParent::CreateFdEvent::~CreateFdEvent()
{
}
nsresult
DeviceStorageRequestParent::CreateFdEvent::CancelableRun()
{
MOZ_ASSERT(!NS_IsMainThread());
nsCOMPtr<nsIRunnable> r;
if (!mFile->mFile) {
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
return NS_DispatchToMainThread(r);
return NS_DispatchToMainThread(
new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN));
}
bool check = false;
mFile->mFile->Exists(&check);
if (check) {
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_EXISTS);
return NS_DispatchToMainThread(r);
return NS_DispatchToMainThread(
new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_EXISTS));
}
nsCOMPtr<nsIRunnable> r;
FileDescriptor fileDescriptor;
nsresult rv = mFile->CreateFileDescriptor(fileDescriptor);
if (NS_FAILED(rv)) {
@@ -585,23 +491,7 @@ DeviceStorageRequestParent::CreateFdEvent::CancelableRun()
r = new PostFileDescriptorResultEvent(mParent, fileDescriptor);
}
return NS_DispatchToMainThread(r);
}
DeviceStorageRequestParent::WriteFileEvent::
WriteFileEvent(DeviceStorageRequestParent* aParent,
DeviceStorageFile* aFile,
nsIInputStream* aInputStream,
int32_t aRequestType)
: CancelableRunnable(aParent)
, mFile(aFile)
, mInputStream(aInputStream)
, mRequestType(aRequestType)
{
}
DeviceStorageRequestParent::WriteFileEvent::~WriteFileEvent()
{
return NS_DispatchToMainThread(r.forget());
}
nsresult
@@ -609,11 +499,9 @@ DeviceStorageRequestParent::WriteFileEvent::CancelableRun()
{
MOZ_ASSERT(!NS_IsMainThread());
nsCOMPtr<nsIRunnable> r;
if (!mInputStream || !mFile->mFile) {
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
return NS_DispatchToMainThread(r);
return NS_DispatchToMainThread(
new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN));
}
bool check = false;
@@ -622,21 +510,22 @@ DeviceStorageRequestParent::WriteFileEvent::CancelableRun()
if (mRequestType == DEVICE_STORAGE_REQUEST_CREATE) {
if (check) {
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_EXISTS);
return NS_DispatchToMainThread(r);
return NS_DispatchToMainThread(
new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_EXISTS));
}
rv = mFile->Write(mInputStream);
} else if (mRequestType == DEVICE_STORAGE_REQUEST_APPEND) {
if (!check) {
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST);
return NS_DispatchToMainThread(r);
return NS_DispatchToMainThread(
new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST));
}
rv = mFile->Append(mInputStream);
} else {
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
return NS_DispatchToMainThread(r);
return NS_DispatchToMainThread(
new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN));
}
nsCOMPtr<nsIRunnable> r;
if (NS_FAILED(rv)) {
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
}
@@ -644,18 +533,7 @@ DeviceStorageRequestParent::WriteFileEvent::CancelableRun()
r = new PostPathResultEvent(mParent, mFile->mPath);
}
return NS_DispatchToMainThread(r);
}
DeviceStorageRequestParent::DeleteFileEvent::
DeleteFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile)
: CancelableRunnable(aParent)
, mFile(aFile)
{
}
DeviceStorageRequestParent::DeleteFileEvent::~DeleteFileEvent()
{
return NS_DispatchToMainThread(r.forget());
}
nsresult
@@ -665,12 +543,11 @@ DeviceStorageRequestParent::DeleteFileEvent::CancelableRun()
mFile->Remove();
nsCOMPtr<nsIRunnable> r;
if (!mFile->mFile) {
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
return NS_DispatchToMainThread(r);
return NS_DispatchToMainThread(
new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN));
}
nsCOMPtr<nsIRunnable> r;
bool check = false;
mFile->mFile->Exists(&check);
if (check) {
@@ -680,19 +557,7 @@ DeviceStorageRequestParent::DeleteFileEvent::CancelableRun()
r = new PostPathResultEvent(mParent, mFile->mPath);
}
return NS_DispatchToMainThread(r);
}
DeviceStorageRequestParent::FreeSpaceFileEvent::
FreeSpaceFileEvent(DeviceStorageRequestParent* aParent,
DeviceStorageFile* aFile)
: CancelableRunnable(aParent)
, mFile(aFile)
{
}
DeviceStorageRequestParent::FreeSpaceFileEvent::~FreeSpaceFileEvent()
{
return NS_DispatchToMainThread(r.forget());
}
nsresult
@@ -705,21 +570,8 @@ DeviceStorageRequestParent::FreeSpaceFileEvent::CancelableRun()
mFile->GetStorageFreeSpace(&freeSpace);
}
nsCOMPtr<nsIRunnable> r;
r = new PostFreeSpaceResultEvent(mParent, static_cast<uint64_t>(freeSpace));
return NS_DispatchToMainThread(r);
}
DeviceStorageRequestParent::UsedSpaceFileEvent::
UsedSpaceFileEvent(DeviceStorageRequestParent* aParent,
DeviceStorageFile* aFile)
: CancelableRunnable(aParent)
, mFile(aFile)
{
}
DeviceStorageRequestParent::UsedSpaceFileEvent::~UsedSpaceFileEvent()
{
return NS_DispatchToMainThread(
new PostFreeSpaceResultEvent(mParent, static_cast<uint64_t>(freeSpace)));
}
nsresult
@@ -743,13 +595,13 @@ DeviceStorageRequestParent::UsedSpaceFileEvent::CancelableRun()
} else {
r = new PostUsedSpaceResultEvent(mParent, mFile->mStorageType, totalUsage);
}
return NS_DispatchToMainThread(r);
return NS_DispatchToMainThread(r.forget());
}
DeviceStorageRequestParent::ReadFileEvent::
ReadFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile)
: CancelableRunnable(aParent)
, mFile(aFile)
ReadFileEvent(DeviceStorageRequestParent* aParent,
already_AddRefed<DeviceStorageFile>&& aFile)
: CancelableFileEvent(aParent, Move(aFile))
{
nsCOMPtr<nsIMIMEService> mimeService
= do_GetService(NS_MIMESERVICE_CONTRACTID);
@@ -761,60 +613,41 @@ DeviceStorageRequestParent::ReadFileEvent::
}
}
DeviceStorageRequestParent::ReadFileEvent::~ReadFileEvent()
{
}
nsresult
DeviceStorageRequestParent::ReadFileEvent::CancelableRun()
{
MOZ_ASSERT(!NS_IsMainThread());
nsCOMPtr<nsIRunnable> r;
if (!mFile->mFile) {
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
return NS_DispatchToMainThread(r);
return NS_DispatchToMainThread(
new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN));
}
bool check = false;
mFile->mFile->Exists(&check);
if (!check) {
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST);
return NS_DispatchToMainThread(r);
return NS_DispatchToMainThread(
new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST));
}
int64_t fileSize;
nsresult rv = mFile->mFile->GetFileSize(&fileSize);
if (NS_FAILED(rv)) {
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
return NS_DispatchToMainThread(r);
return NS_DispatchToMainThread(
new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN));
}
PRTime modDate;
rv = mFile->mFile->GetLastModifiedTime(&modDate);
if (NS_FAILED(rv)) {
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
return NS_DispatchToMainThread(r);
return NS_DispatchToMainThread(
new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN));
}
r = new PostBlobSuccessEvent(mParent, mFile, static_cast<uint64_t>(fileSize),
mMimeType, modDate);
return NS_DispatchToMainThread(r);
}
DeviceStorageRequestParent::EnumerateFileEvent::
EnumerateFileEvent(DeviceStorageRequestParent* aParent,
DeviceStorageFile* aFile,
uint64_t aSince)
: CancelableRunnable(aParent)
, mFile(aFile)
, mSince(aSince)
{
}
DeviceStorageRequestParent::EnumerateFileEvent::~EnumerateFileEvent()
{
return NS_DispatchToMainThread(
new PostBlobSuccessEvent(mParent, mFile.forget(),
static_cast<uint64_t>(fileSize),
mMimeType, modDate));
}
nsresult
@@ -822,13 +655,12 @@ DeviceStorageRequestParent::EnumerateFileEvent::CancelableRun()
{
MOZ_ASSERT(!NS_IsMainThread());
nsCOMPtr<nsIRunnable> r;
if (mFile->mFile) {
bool check = false;
mFile->mFile->Exists(&check);
if (!check) {
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST);
return NS_DispatchToMainThread(r);
return NS_DispatchToMainThread(
new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST));
}
}
@@ -843,22 +675,9 @@ DeviceStorageRequestParent::EnumerateFileEvent::CancelableRun()
values.AppendElement(dsvf);
}
r = new PostEnumerationSuccessEvent(mParent, mFile->mStorageType,
mFile->mRootDir, values);
return NS_DispatchToMainThread(r);
}
DeviceStorageRequestParent::PostPathResultEvent::
PostPathResultEvent(DeviceStorageRequestParent* aParent,
const nsAString& aPath)
: CancelableRunnable(aParent)
, mPath(aPath)
{
}
DeviceStorageRequestParent::PostPathResultEvent::~PostPathResultEvent()
{
return NS_DispatchToMainThread(
new PostEnumerationSuccessEvent(mParent, mFile->mStorageType,
mFile->mRootDir, values));
}
nsresult
@@ -871,19 +690,6 @@ DeviceStorageRequestParent::PostPathResultEvent::CancelableRun()
return NS_OK;
}
DeviceStorageRequestParent::PostFileDescriptorResultEvent::
PostFileDescriptorResultEvent(DeviceStorageRequestParent* aParent,
const FileDescriptor& aFileDescriptor)
: CancelableRunnable(aParent)
, mFileDescriptor(aFileDescriptor)
{
}
DeviceStorageRequestParent::PostFileDescriptorResultEvent::
~PostFileDescriptorResultEvent()
{
}
nsresult
DeviceStorageRequestParent::PostFileDescriptorResultEvent::CancelableRun()
{
@@ -894,19 +700,6 @@ DeviceStorageRequestParent::PostFileDescriptorResultEvent::CancelableRun()
return NS_OK;
}
DeviceStorageRequestParent::PostFormatResultEvent::
PostFormatResultEvent(DeviceStorageRequestParent* aParent,
DeviceStorageFile* aFile)
: CancelableRunnable(aParent)
, mFile(aFile)
{
}
DeviceStorageRequestParent::PostFormatResultEvent::
~PostFormatResultEvent()
{
}
nsresult
DeviceStorageRequestParent::PostFormatResultEvent::CancelableRun()
{
@@ -922,19 +715,6 @@ DeviceStorageRequestParent::PostFormatResultEvent::CancelableRun()
return NS_OK;
}
DeviceStorageRequestParent::PostMountResultEvent::
PostMountResultEvent(DeviceStorageRequestParent* aParent,
DeviceStorageFile* aFile)
: CancelableRunnable(aParent)
, mFile(aFile)
{
}
DeviceStorageRequestParent::PostMountResultEvent::
~PostMountResultEvent()
{
}
nsresult
DeviceStorageRequestParent::PostMountResultEvent::CancelableRun()
{
@@ -950,19 +730,6 @@ DeviceStorageRequestParent::PostMountResultEvent::CancelableRun()
return NS_OK;
}
DeviceStorageRequestParent::PostUnmountResultEvent::
PostUnmountResultEvent(DeviceStorageRequestParent* aParent,
DeviceStorageFile* aFile)
: CancelableRunnable(aParent)
, mFile(aFile)
{
}
DeviceStorageRequestParent::PostUnmountResultEvent::
~PostUnmountResultEvent()
{
}
nsresult
DeviceStorageRequestParent::PostUnmountResultEvent::CancelableRun()
{
+114 -80
View File
@@ -74,11 +74,22 @@ private:
bool mCanceled;
};
class CancelableFileEvent : public CancelableRunnable
{
protected:
CancelableFileEvent(DeviceStorageRequestParent* aParent,
already_AddRefed<DeviceStorageFile>&& aFile)
: CancelableRunnable(aParent)
, mFile(Move(aFile)) {}
RefPtr<DeviceStorageFile> mFile;
};
class PostErrorEvent : public CancelableRunnable
{
public:
PostErrorEvent(DeviceStorageRequestParent* aParent, const char* aError);
virtual ~PostErrorEvent();
virtual ~PostErrorEvent() {}
virtual nsresult CancelableRun();
private:
nsString mError;
@@ -87,21 +98,28 @@ private:
class PostSuccessEvent : public CancelableRunnable
{
public:
explicit PostSuccessEvent(DeviceStorageRequestParent* aParent);
virtual ~PostSuccessEvent();
explicit PostSuccessEvent(DeviceStorageRequestParent* aParent)
: CancelableRunnable(aParent) {}
virtual ~PostSuccessEvent() {}
virtual nsresult CancelableRun();
};
class PostBlobSuccessEvent : public CancelableRunnable
class PostBlobSuccessEvent : public CancelableFileEvent
{
public:
PostBlobSuccessEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile, uint32_t aLength, nsACString& aMimeType, uint64_t aLastModifiedDate);
virtual ~PostBlobSuccessEvent();
PostBlobSuccessEvent(DeviceStorageRequestParent* aParent,
already_AddRefed<DeviceStorageFile>&& aFile,
uint32_t aLength, nsACString& aMimeType,
uint64_t aLastModifiedDate)
: CancelableFileEvent(aParent, Move(aFile))
, mLength(aLength)
, mLastModificationDate(aLastModifiedDate)
, mMimeType(aMimeType) {}
virtual ~PostBlobSuccessEvent() {}
virtual nsresult CancelableRun();
private:
uint32_t mLength;
uint64_t mLastModificationDate;
RefPtr<DeviceStorageFile> mFile;
nsCString mMimeType;
};
@@ -111,8 +129,12 @@ private:
PostEnumerationSuccessEvent(DeviceStorageRequestParent* aParent,
const nsAString& aStorageType,
const nsAString& aRelPath,
InfallibleTArray<DeviceStorageFileValue>& aPaths);
virtual ~PostEnumerationSuccessEvent();
InfallibleTArray<DeviceStorageFileValue>& aPaths)
: CancelableRunnable(aParent)
, mStorageType(aStorageType)
, mRelPath(aRelPath)
, mPaths(aPaths) {}
virtual ~PostEnumerationSuccessEvent() {}
virtual nsresult CancelableRun();
private:
const nsString mStorageType;
@@ -120,89 +142,97 @@ private:
InfallibleTArray<DeviceStorageFileValue> mPaths;
};
class CreateFdEvent : public CancelableRunnable
class CreateFdEvent : public CancelableFileEvent
{
public:
CreateFdEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile);
virtual ~CreateFdEvent();
CreateFdEvent(DeviceStorageRequestParent* aParent,
already_AddRefed<DeviceStorageFile>&& aFile)
: CancelableFileEvent(aParent, Move(aFile)) {}
virtual ~CreateFdEvent() {}
virtual nsresult CancelableRun();
private:
RefPtr<DeviceStorageFile> mFile;
};
class WriteFileEvent : public CancelableRunnable
class WriteFileEvent : public CancelableFileEvent
{
public:
WriteFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile,
nsIInputStream* aInputStream, int32_t aRequestType);
virtual ~WriteFileEvent();
WriteFileEvent(DeviceStorageRequestParent* aParent,
already_AddRefed<DeviceStorageFile>&& aFile,
nsIInputStream* aInputStream, int32_t aRequestType)
: CancelableFileEvent(aParent, Move(aFile))
, mInputStream(aInputStream)
, mRequestType(aRequestType) {}
virtual ~WriteFileEvent() {}
virtual nsresult CancelableRun();
private:
RefPtr<DeviceStorageFile> mFile;
nsCOMPtr<nsIInputStream> mInputStream;
int32_t mRequestType;
};
class DeleteFileEvent : public CancelableRunnable
class DeleteFileEvent : public CancelableFileEvent
{
public:
DeleteFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile);
virtual ~DeleteFileEvent();
DeleteFileEvent(DeviceStorageRequestParent* aParent,
already_AddRefed<DeviceStorageFile>&& aFile)
: CancelableFileEvent(aParent, Move(aFile)) {}
virtual ~DeleteFileEvent() {}
virtual nsresult CancelableRun();
};
class FreeSpaceFileEvent : public CancelableFileEvent
{
public:
FreeSpaceFileEvent(DeviceStorageRequestParent* aParent,
already_AddRefed<DeviceStorageFile>&& aFile)
: CancelableFileEvent(aParent, Move(aFile)) {}
virtual ~FreeSpaceFileEvent() {}
virtual nsresult CancelableRun();
};
class UsedSpaceFileEvent : public CancelableFileEvent
{
public:
UsedSpaceFileEvent(DeviceStorageRequestParent* aParent,
already_AddRefed<DeviceStorageFile>&& aFile)
: CancelableFileEvent(aParent, Move(aFile)) {}
virtual ~UsedSpaceFileEvent() {}
virtual nsresult CancelableRun();
};
class ReadFileEvent : public CancelableFileEvent
{
public:
ReadFileEvent(DeviceStorageRequestParent* aParent,
already_AddRefed<DeviceStorageFile>&& aFile);
virtual ~ReadFileEvent() {}
virtual nsresult CancelableRun();
private:
RefPtr<DeviceStorageFile> mFile;
};
class FreeSpaceFileEvent : public CancelableRunnable
{
public:
FreeSpaceFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile);
virtual ~FreeSpaceFileEvent();
virtual nsresult CancelableRun();
private:
RefPtr<DeviceStorageFile> mFile;
};
class UsedSpaceFileEvent : public CancelableRunnable
{
public:
UsedSpaceFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile);
virtual ~UsedSpaceFileEvent();
virtual nsresult CancelableRun();
private:
RefPtr<DeviceStorageFile> mFile;
};
class ReadFileEvent : public CancelableRunnable
{
public:
ReadFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile);
virtual ~ReadFileEvent();
virtual nsresult CancelableRun();
private:
RefPtr<DeviceStorageFile> mFile;
nsCString mMimeType;
};
class EnumerateFileEvent : public CancelableRunnable
class EnumerateFileEvent : public CancelableFileEvent
{
public:
EnumerateFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile, uint64_t aSince);
virtual ~EnumerateFileEvent();
EnumerateFileEvent(DeviceStorageRequestParent* aParent,
already_AddRefed<DeviceStorageFile>&& aFile,
uint64_t aSince)
: CancelableFileEvent(aParent, Move(aFile))
, mSince(aSince) {}
virtual ~EnumerateFileEvent() {}
virtual nsresult CancelableRun();
private:
RefPtr<DeviceStorageFile> mFile;
uint64_t mSince;
};
class PostPathResultEvent : public CancelableRunnable
{
public:
PostPathResultEvent(DeviceStorageRequestParent* aParent, const nsAString& aPath);
virtual ~PostPathResultEvent();
PostPathResultEvent(DeviceStorageRequestParent* aParent,
const nsAString& aPath)
: CancelableRunnable(aParent)
, mPath(aPath) {}
virtual ~PostPathResultEvent() {}
virtual nsresult CancelableRun();
private:
RefPtr<DeviceStorageFile> mFile;
nsString mPath;
};
@@ -210,11 +240,12 @@ private:
{
public:
PostFileDescriptorResultEvent(DeviceStorageRequestParent* aParent,
const FileDescriptor& aFileDescriptor);
virtual ~PostFileDescriptorResultEvent();
const FileDescriptor& aFileDescriptor)
: CancelableRunnable(aParent)
, mFileDescriptor(aFileDescriptor) {}
virtual ~PostFileDescriptorResultEvent() {}
virtual nsresult CancelableRun();
private:
RefPtr<DeviceStorageFile> mFile;
FileDescriptor mFileDescriptor;
};
@@ -234,42 +265,45 @@ private:
public:
PostUsedSpaceResultEvent(DeviceStorageRequestParent* aParent,
const nsAString& aType,
uint64_t aUsedSpace);
virtual ~PostUsedSpaceResultEvent();
uint64_t aUsedSpace)
: CancelableRunnable(aParent)
, mType(aType)
, mUsedSpace(aUsedSpace) {}
virtual ~PostUsedSpaceResultEvent() {}
virtual nsresult CancelableRun();
private:
nsString mType;
uint64_t mUsedSpace;
};
class PostFormatResultEvent : public CancelableRunnable
class PostFormatResultEvent : public CancelableFileEvent
{
public:
PostFormatResultEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile);
virtual ~PostFormatResultEvent();
PostFormatResultEvent(DeviceStorageRequestParent* aParent,
already_AddRefed<DeviceStorageFile>&& aFile)
: CancelableFileEvent(aParent, Move(aFile)) {}
virtual ~PostFormatResultEvent() {}
virtual nsresult CancelableRun();
private:
RefPtr<DeviceStorageFile> mFile;
};
class PostMountResultEvent : public CancelableRunnable
class PostMountResultEvent : public CancelableFileEvent
{
public:
PostMountResultEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile);
virtual ~PostMountResultEvent();
PostMountResultEvent(DeviceStorageRequestParent* aParent,
already_AddRefed<DeviceStorageFile>&& aFile)
: CancelableFileEvent(aParent, Move(aFile)) {}
virtual ~PostMountResultEvent() {}
virtual nsresult CancelableRun();
private:
RefPtr<DeviceStorageFile> mFile;
};
class PostUnmountResultEvent : public CancelableRunnable
class PostUnmountResultEvent : public CancelableFileEvent
{
public:
PostUnmountResultEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile);
virtual ~PostUnmountResultEvent();
PostUnmountResultEvent(DeviceStorageRequestParent* aParent,
already_AddRefed<DeviceStorageFile>&& aFile)
: CancelableFileEvent(aParent, Move(aFile)) {}
virtual ~PostUnmountResultEvent() {}
virtual nsresult CancelableRun();
private:
RefPtr<DeviceStorageFile> mFile;
};
protected:
+5 -5
View File
@@ -825,7 +825,7 @@ DeviceStorageStatics::ListenerWrapper::ListenerWrapper(nsDOMDeviceStorage* aList
DeviceStorageStatics::ListenerWrapper::~ListenerWrapper()
{
// Even weak pointers are not thread safe
NS_ProxyRelease(mOwningThread, mListener);
NS_ProxyRelease(mOwningThread, mListener.forget());
}
bool
@@ -854,7 +854,7 @@ DeviceStorageStatics::ListenerWrapper::OnFileWatcherUpdate(const nsCString& aDat
listener->OnFileWatcherUpdate(data, file);
}
});
mOwningThread->Dispatch(r, NS_DISPATCH_NORMAL);
mOwningThread->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
}
void
@@ -867,7 +867,7 @@ DeviceStorageStatics::ListenerWrapper::OnDiskSpaceWatcher(bool aLowDiskSpace)
listener->OnDiskSpaceWatcher(aLowDiskSpace);
}
});
mOwningThread->Dispatch(r, NS_DISPATCH_NORMAL);
mOwningThread->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
}
void
@@ -880,7 +880,7 @@ DeviceStorageStatics::ListenerWrapper::OnWritableNameChanged()
listener->OnWritableNameChanged();
}
});
mOwningThread->Dispatch(r, NS_DISPATCH_NORMAL);
mOwningThread->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
}
#ifdef MOZ_WIDGET_GONK
@@ -895,7 +895,7 @@ DeviceStorageStatics::ListenerWrapper::OnVolumeStateChanged(nsIVolume* aVolume)
listener->OnVolumeStateChanged(volume);
}
});
mOwningThread->Dispatch(r, NS_DISPATCH_NORMAL);
mOwningThread->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
}
#endif
+206 -146
View File
@@ -693,8 +693,20 @@ DeviceStorageFile::CreateUnique(nsAString& aFileName,
if (storageName.IsEmpty()) {
nsDOMDeviceStorage::GetDefaultStorageName(storageType, storageName);
}
return CreateUnique(storageType, storageName, storagePath,
aFileType, aFileAttributes);
}
//static
already_AddRefed<DeviceStorageFile>
DeviceStorageFile::CreateUnique(const nsAString& aStorageType,
const nsAString& aStorageName,
nsAString& aFileName,
uint32_t aFileType,
uint32_t aFileAttributes)
{
RefPtr<DeviceStorageFile> dsf =
new DeviceStorageFile(storageType, storageName, storagePath);
new DeviceStorageFile(aStorageType, aStorageName, aFileName);
if (!dsf->mFile) {
return nullptr;
}
@@ -824,8 +836,7 @@ DeviceStorageFile::Write(nsIInputStream* aInputStream)
return rv;
}
nsCOMPtr<nsIRunnable> iocomplete = new IOEventComplete(this, "created");
rv = NS_DispatchToMainThread(iocomplete);
rv = NS_DispatchToMainThread(new IOEventComplete(this, "created"));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -852,8 +863,7 @@ DeviceStorageFile::Write(InfallibleTArray<uint8_t>& aBits)
return rv;
}
nsCOMPtr<nsIRunnable> iocomplete = new IOEventComplete(this, "created");
rv = NS_DispatchToMainThread(iocomplete);
rv = NS_DispatchToMainThread(new IOEventComplete(this, "created"));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -869,8 +879,7 @@ DeviceStorageFile::Write(InfallibleTArray<uint8_t>& aBits)
outputStream->Write((char*) aBits.Elements(), aBits.Length(), &wrote);
outputStream->Close();
iocomplete = new IOEventComplete(this, "modified");
rv = NS_DispatchToMainThread(iocomplete);
rv = NS_DispatchToMainThread(new IOEventComplete(this, "modified"));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -923,8 +932,7 @@ DeviceStorageFile::Append(nsIInputStream* aInputStream, nsIOutputStream* aOutput
bufSize -= wrote;
}
nsCOMPtr<nsIRunnable> iocomplete = new IOEventComplete(this, "modified");
rv = NS_DispatchToMainThread(iocomplete);
rv = NS_DispatchToMainThread(new IOEventComplete(this, "modified"));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -961,8 +969,7 @@ DeviceStorageFile::Remove()
return rv;
}
nsCOMPtr<nsIRunnable> iocomplete = new IOEventComplete(this, "deleted");
return NS_DispatchToMainThread(iocomplete);
return NS_DispatchToMainThread(new IOEventComplete(this, "deleted"));
}
nsresult
@@ -1499,6 +1506,7 @@ DeviceStorageRequest::DeviceStorageRequest()
: mId(DeviceStorageRequestManager::INVALID_ID)
, mAccess(DEVICE_STORAGE_ACCESS_UNDEFINED)
, mSendToParent(true)
, mUseMainThread(false)
, mUseStreamTransport(false)
, mCheckFile(false)
, mCheckBlob(false)
@@ -1521,7 +1529,7 @@ DeviceStorageRequest::~DeviceStorageRequest()
void
DeviceStorageRequest::Initialize(DeviceStorageRequestManager* aManager,
DeviceStorageFile* aFile,
already_AddRefed<DeviceStorageFile>&& aFile,
uint32_t aId)
{
DS_LOG_DEBUG("%p manages %p", aManager, this);
@@ -1535,11 +1543,11 @@ DeviceStorageRequest::Initialize(DeviceStorageRequestManager* aManager,
void
DeviceStorageRequest::Initialize(DeviceStorageRequestManager* aManager,
DeviceStorageFile* aFile,
already_AddRefed<DeviceStorageFile>&& aFile,
uint32_t aRequest,
BlobImpl* aBlob)
{
Initialize(aManager, aFile, aRequest);
Initialize(aManager, Move(aFile), aRequest);
mBlob = aBlob;
mCheckBlob = true;
mCheckFile = true;
@@ -1548,11 +1556,11 @@ DeviceStorageRequest::Initialize(DeviceStorageRequestManager* aManager,
void
DeviceStorageRequest::Initialize(DeviceStorageRequestManager* aManager,
DeviceStorageFile* aFile,
already_AddRefed<DeviceStorageFile>&& aFile,
uint32_t aRequest,
DeviceStorageFileDescriptor* aDSFileDescriptor)
{
Initialize(aManager, aFile, aRequest);
Initialize(aManager, Move(aFile), aRequest);
mDSFileDescriptor = aDSFileDescriptor;
MOZ_ASSERT(mDSFileDescriptor);
}
@@ -1578,11 +1586,30 @@ DeviceStorageRequest::Cancel()
nsresult
DeviceStorageRequest::Allow()
{
if (mUseMainThread && !NS_IsMainThread()) {
RefPtr<DeviceStorageRequest> self = this;
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([self] () -> void
{
self->Allow();
});
return NS_DispatchToMainThread(r.forget());
}
nsresult rv = AllowInternal();
if (NS_WARN_IF(NS_FAILED(rv))) {
return Reject(rv == NS_ERROR_ILLEGAL_VALUE
? POST_ERROR_EVENT_ILLEGAL_TYPE
: POST_ERROR_EVENT_UNKNOWN);
const char *reason;
switch (rv) {
case NS_ERROR_ILLEGAL_VALUE:
reason = POST_ERROR_EVENT_ILLEGAL_TYPE;
break;
case NS_ERROR_DOM_SECURITY_ERR:
reason = POST_ERROR_EVENT_PERMISSION_DENIED;
break;
default:
reason = POST_ERROR_EVENT_UNKNOWN;
break;
}
return Reject(reason);
}
return rv;
}
@@ -1607,9 +1634,10 @@ DeviceStorageRequest::GetManager() const
return mManager;
}
void
nsresult
DeviceStorageRequest::Prepare()
{
return NS_OK;
}
nsresult
@@ -1623,7 +1651,11 @@ nsresult
DeviceStorageRequest::AllowInternal()
{
MOZ_ASSERT(mManager->IsOwningThread() || NS_IsMainThread());
Prepare();
nsresult rv = Prepare();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
DeviceStorageTypeChecker* typeChecker
= DeviceStorageTypeChecker::CreateOrGet();
@@ -1649,7 +1681,8 @@ DeviceStorageRequest::AllowInternal()
nsCOMPtr<nsIEventTarget> target
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
MOZ_ASSERT(target);
return target->Dispatch(this, NS_DISPATCH_NORMAL);
nsCOMPtr<nsIRunnable> self = this;
return target->Dispatch(self.forget(), NS_DISPATCH_NORMAL);
}
DS_LOG_INFO("run %u", mId);
@@ -1669,7 +1702,7 @@ DeviceStorageRequest::SendToParentProcess()
self->Reject(POST_ERROR_EVENT_UNKNOWN);
}
});
return NS_DispatchToMainThread(r);
return NS_DispatchToMainThread(r.forget());
}
MOZ_ASSERT(NS_IsMainThread());
@@ -1699,11 +1732,11 @@ DeviceStorageCursorRequest::DeviceStorageCursorRequest()
void
DeviceStorageCursorRequest::Initialize(DeviceStorageRequestManager* aManager,
DeviceStorageFile* aFile,
already_AddRefed<DeviceStorageFile>&& aFile,
uint32_t aRequest,
PRTime aSince)
{
Initialize(aManager, aFile, aRequest);
Initialize(aManager, Move(aFile), aRequest);
mStorageType = mFile->mStorageType;
mSince = aSince;
}
@@ -1729,7 +1762,7 @@ DeviceStorageCursorRequest::SendContinueToParentProcess()
{
self->SendContinueToParentProcess();
});
return NS_DispatchToMainThread(r);
return NS_DispatchToMainThread(r.forget());
}
MOZ_ASSERT(NS_IsMainThread());
@@ -1756,7 +1789,7 @@ DeviceStorageCursorRequest::Continue()
{
self->Continue();
});
nsresult rv = NS_DispatchToMainThread(r);
nsresult rv = NS_DispatchToMainThread(r.forget());
if (NS_WARN_IF(NS_FAILED(rv))) {
return Reject(POST_ERROR_EVENT_UNKNOWN);
}
@@ -1869,6 +1902,8 @@ class DeviceStorageCreateRequest final
: public DeviceStorageRequest
{
public:
using DeviceStorageRequest::Initialize;
DeviceStorageCreateRequest()
{
mAccess = DEVICE_STORAGE_ACCESS_CREATE;
@@ -1903,7 +1938,62 @@ public:
return Resolve(fullPath);
}
void Initialize(DeviceStorageRequestManager* aManager,
already_AddRefed<DeviceStorageFile>&& aFile,
uint32_t aRequest) override
{
DeviceStorageRequest::Initialize(aManager, Move(aFile), aRequest);
mUseMainThread = mFile->mPath.IsEmpty();
}
protected:
nsresult Prepare() override
{
if (!mFile->mPath.IsEmpty()) {
// Checks have already been performed when request was created
return NS_OK;
}
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIMIMEService> mimeSvc = do_GetService(NS_MIMESERVICE_CONTRACTID);
if (!mimeSvc) {
return NS_ERROR_FAILURE;
}
// if mimeType or extension are null, the request will be rejected
// in DeviceStorageRequest::AllowInternal when the type checker
// verifies the file path
nsString mimeType;
mBlob->GetType(mimeType);
nsCString extension;
mimeSvc->GetPrimaryExtension(NS_LossyConvertUTF16toASCII(mimeType),
EmptyCString(), extension);
char buffer[32];
NS_MakeRandomString(buffer, ArrayLength(buffer) - 1);
nsAutoString path;
path.AssignLiteral(buffer);
path.Append('.');
path.AppendASCII(extension.get());
RefPtr<DeviceStorageFile> file
= DeviceStorageFile::CreateUnique(mFile->mStorageType,
mFile->mStorageName, path,
nsIFile::NORMAL_FILE_TYPE, 00600);
if (!file) {
return NS_ERROR_FAILURE;
}
if (!file->IsSafePath()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
mFile = file.forget();
return NS_OK;
}
nsresult CreateSendParams(DeviceStorageParams& aParams) override
{
BlobChild* actor
@@ -1986,16 +2076,17 @@ public:
DeviceStorageOpenRequest()
{
mUseMainThread = true;
mUseStreamTransport = true;
mCheckFile = true;
DS_LOG_INFO("");
}
void Initialize(DeviceStorageRequestManager* aManager,
DeviceStorageFile* aFile,
already_AddRefed<DeviceStorageFile>&& aFile,
uint32_t aRequest) override
{
DeviceStorageRequest::Initialize(aManager, aFile, aRequest);
DeviceStorageRequest::Initialize(aManager, Move(aFile), aRequest);
mAccess = mFile->mEditable ? DEVICE_STORAGE_ACCESS_WRITE
: DEVICE_STORAGE_ACCESS_READ;
}
@@ -2019,10 +2110,11 @@ public:
}
protected:
void Prepare() override
nsresult Prepare() override
{
MOZ_ASSERT(NS_IsMainThread());
mFile->CalculateMimeType();
return NS_OK;
}
nsresult CreateSendParams(DeviceStorageParams& aParams) override
@@ -2121,7 +2213,8 @@ public:
DeviceStorageUsedSpaceCache* usedSpaceCache
= DeviceStorageUsedSpaceCache::CreateOrGet();
MOZ_ASSERT(usedSpaceCache);
usedSpaceCache->Dispatch(this);
nsCOMPtr<nsIRunnable> self = this;
usedSpaceCache->Dispatch(self.forget());
return NS_OK;
}
@@ -2306,10 +2399,10 @@ public:
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(DeviceStoragePermissionCheck,
nsIContentPermissionRequest)
DeviceStoragePermissionCheck(DeviceStorageRequest* aRequest,
uint64_t aWindowID,
const PrincipalInfo &aPrincipalInfo)
: mRequest(aRequest)
DeviceStoragePermissionCheck(
already_AddRefed<DeviceStorageRequest>&& aRequest,
uint64_t aWindowID, const PrincipalInfo &aPrincipalInfo)
: mRequest(Move(aRequest))
, mWindowID(aWindowID)
, mPrincipalInfo(aPrincipalInfo)
{
@@ -2461,37 +2554,31 @@ nsDOMDeviceStorage::nsDOMDeviceStorage(nsPIDOMWindow* aWindow)
}
nsresult
nsDOMDeviceStorage::CheckPermission(DeviceStorageRequest* aRequest)
nsDOMDeviceStorage::CheckPermission(
already_AddRefed<DeviceStorageRequest>&& aRequest)
{
MOZ_ASSERT(mManager);
uint32_t cache = mManager->CheckPermission(aRequest->GetAccess());
RefPtr<DeviceStorageRequest> request(aRequest);
uint32_t cache = mManager->CheckPermission(request->GetAccess());
switch (cache) {
case nsIPermissionManager::ALLOW_ACTION:
return aRequest->Allow();
return request->Allow();
case nsIPermissionManager::DENY_ACTION:
return aRequest->Cancel();
return request->Cancel();
case nsIPermissionManager::PROMPT_ACTION:
default:
{
nsCOMPtr<nsIThread> mainThread;
nsresult rv = NS_GetMainThread(getter_AddRefs(mainThread));
if (NS_WARN_IF(NS_FAILED(rv))) {
return aRequest->Reject(POST_ERROR_EVENT_UNKNOWN);
return request->Reject(POST_ERROR_EVENT_UNKNOWN);
}
/* We need to do a bit of a song and dance here to release the object
because while we can initially increment the ownership count (no one
else is using it), we cannot safely decrement after dispatching because
it uses cycle collection and requires the main thread to free it. */
nsCOMPtr<nsIRunnable> r
= new DeviceStoragePermissionCheck(aRequest, mInnerWindowID,
*mPrincipalInfo);
rv = mainThread->Dispatch(r, NS_DISPATCH_NORMAL);
if (NS_WARN_IF(NS_FAILED(rv))) {
rv = aRequest->Reject(POST_ERROR_EVENT_UNKNOWN);
}
NS_ProxyRelease(mainThread, r.forget().take());
return rv;
return mainThread->Dispatch(
MakeAndAddRef<DeviceStoragePermissionCheck>(request.forget(),
mInnerWindowID,
*mPrincipalInfo),
NS_DISPATCH_NORMAL);
}
}
}
@@ -2505,9 +2592,10 @@ nsDOMDeviceStorage::IsOwningThread()
}
nsresult
nsDOMDeviceStorage::DispatchToOwningThread(nsIRunnable* aRunnable)
nsDOMDeviceStorage::DispatchToOwningThread(
already_AddRefed<nsIRunnable>&& aRunnable)
{
return mOwningThread->Dispatch(aRunnable, NS_DISPATCH_NORMAL);
return mOwningThread->Dispatch(Move(aRunnable), NS_DISPATCH_NORMAL);
}
/* virtual */ JSObject*
@@ -2910,45 +2998,18 @@ nsDOMDeviceStorage::IsAvailable()
already_AddRefed<DOMRequest>
nsDOMDeviceStorage::Add(Blob* aBlob, ErrorResult& aRv)
{
if (!aBlob) {
return nullptr;
}
nsCOMPtr<nsIMIMEService> mimeSvc = do_GetService(NS_MIMESERVICE_CONTRACTID);
if (!mimeSvc) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
// if mimeType isn't set, we will not get a correct
// extension, and AddNamed() will fail. This will post an
// onerror to the requestee.
nsString mimeType;
aBlob->GetType(mimeType);
nsCString extension;
mimeSvc->GetPrimaryExtension(NS_LossyConvertUTF16toASCII(mimeType),
EmptyCString(), extension);
// if extension is null here, we will ignore it for now.
// AddNamed() will check the file path and fail. This
// will post an onerror to the requestee.
// possible race here w/ unique filename
char buffer[32];
NS_MakeRandomString(buffer, ArrayLength(buffer) - 1);
nsAutoCString path;
path.Assign(nsDependentCString(buffer));
path.Append('.');
path.Append(extension);
return AddNamed(aBlob, NS_ConvertASCIItoUTF16(path), aRv);
nsString path;
return AddOrAppendNamed(aBlob, path, true, aRv);
}
already_AddRefed<DOMRequest>
nsDOMDeviceStorage::AddNamed(Blob* aBlob, const nsAString& aPath,
ErrorResult& aRv)
{
if (aPath.IsEmpty()) {
aRv.Throw(NS_ERROR_ILLEGAL_VALUE);
return nullptr;
}
return AddOrAppendNamed(aBlob, aPath, true, aRv);
}
@@ -2956,6 +3017,10 @@ already_AddRefed<DOMRequest>
nsDOMDeviceStorage::AppendNamed(Blob* aBlob, const nsAString& aPath,
ErrorResult& aRv)
{
if (aPath.IsEmpty()) {
aRv.Throw(NS_ERROR_ILLEGAL_VALUE);
return nullptr;
}
return AddOrAppendNamed(aBlob, aPath, false, aRv);
}
@@ -3001,19 +3066,13 @@ nsDOMDeviceStorage::AddOrAppendNamed(Blob* aBlob, const nsAString& aPath,
bool aCreate, ErrorResult& aRv)
{
MOZ_ASSERT(IsOwningThread());
MOZ_ASSERT(aCreate || !aPath.IsEmpty());
// if the blob is null here, bail
if (!aBlob) {
return nullptr;
}
DeviceStorageTypeChecker* typeChecker
= DeviceStorageTypeChecker::CreateOrGet();
if (!typeChecker) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsCOMPtr<nsIRunnable> r;
if (IsFullPath(aPath)) {
@@ -3032,25 +3091,25 @@ nsDOMDeviceStorage::AddOrAppendNamed(Blob* aBlob, const nsAString& aPath,
return nullptr;
}
RefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType,
mStorageName,
aPath);
if (!dsf->IsSafePath()) {
aRv = mManager->Reject(id, POST_ERROR_EVENT_PERMISSION_DENIED);
} else if (!typeChecker->Check(mStorageType, dsf->mFile) ||
!typeChecker->Check(mStorageType, aBlob->Impl())) {
aRv = mManager->Reject(id, POST_ERROR_EVENT_ILLEGAL_TYPE);
RefPtr<DeviceStorageFile> dsf;
if (aPath.IsEmpty()) {
dsf = new DeviceStorageFile(mStorageType, mStorageName);
} else {
RefPtr<DeviceStorageRequest> request;
if (aCreate) {
request = new DeviceStorageCreateRequest();
} else {
request = new DeviceStorageAppendRequest();
dsf = new DeviceStorageFile(mStorageType, mStorageName, aPath);
if (!dsf->IsSafePath()) {
aRv = mManager->Reject(id, POST_ERROR_EVENT_PERMISSION_DENIED);
return domRequest.forget();
}
request->Initialize(mManager, dsf, id, aBlob->Impl());
aRv = CheckPermission(request);
}
RefPtr<DeviceStorageRequest> request;
if (aCreate) {
request = new DeviceStorageCreateRequest();
} else {
request = new DeviceStorageAppendRequest();
}
request->Initialize(mManager, dsf.forget(), id, aBlob->Impl());
aRv = CheckPermission(request.forget());
return domRequest.forget();
}
@@ -3084,9 +3143,9 @@ nsDOMDeviceStorage::GetInternal(const nsAString& aPath, bool aEditable,
}
RefPtr<DeviceStorageRequest> request = new DeviceStorageOpenRequest();
request->Initialize(mManager, dsf, id);
request->Initialize(mManager, dsf.forget(), id);
aRv = CheckPermission(request);
aRv = CheckPermission(request.forget());
return domRequest.forget();
}
@@ -3118,9 +3177,9 @@ nsDOMDeviceStorage::Delete(const nsAString& aPath, ErrorResult& aRv)
}
RefPtr<DeviceStorageRequest> request = new DeviceStorageDeleteRequest();
request->Initialize(mManager, dsf, id);
request->Initialize(mManager, dsf.forget(), id);
aRv = CheckPermission(request);
aRv = CheckPermission(request.forget());
return domRequest.forget();
}
@@ -3139,9 +3198,9 @@ nsDOMDeviceStorage::FreeSpace(ErrorResult& aRv)
}
RefPtr<DeviceStorageRequest> request = new DeviceStorageFreeSpaceRequest();
request->Initialize(mManager, dsf, id);
request->Initialize(mManager, dsf.forget(), id);
aRv = CheckPermission(request);
aRv = CheckPermission(request.forget());
return domRequest.forget();
}
@@ -3164,9 +3223,9 @@ nsDOMDeviceStorage::UsedSpace(ErrorResult& aRv)
}
RefPtr<DeviceStorageRequest> request = new DeviceStorageUsedSpaceRequest();
request->Initialize(mManager, dsf, id);
request->Initialize(mManager, dsf.forget(), id);
aRv = CheckPermission(request);
aRv = CheckPermission(request.forget());
return domRequest.forget();
}
@@ -3185,9 +3244,9 @@ nsDOMDeviceStorage::Available(ErrorResult& aRv)
}
RefPtr<DeviceStorageRequest> request = new DeviceStorageAvailableRequest();
request->Initialize(mManager, dsf, id);
request->Initialize(mManager, dsf.forget(), id);
aRv = CheckPermission(request);
aRv = CheckPermission(request.forget());
return domRequest.forget();
}
@@ -3206,9 +3265,9 @@ nsDOMDeviceStorage::StorageStatus(ErrorResult& aRv)
}
RefPtr<DeviceStorageRequest> request = new DeviceStorageStatusRequest();
request->Initialize(mManager, dsf, id);
request->Initialize(mManager, dsf.forget(), id);
aRv = CheckPermission(request);
aRv = CheckPermission(request.forget());
return domRequest.forget();
}
@@ -3227,9 +3286,9 @@ nsDOMDeviceStorage::Format(ErrorResult& aRv)
}
RefPtr<DeviceStorageRequest> request = new DeviceStorageFormatRequest();
request->Initialize(mManager, dsf, id);
request->Initialize(mManager, dsf.forget(), id);
aRv = CheckPermission(request);
aRv = CheckPermission(request.forget());
return domRequest.forget();
}
@@ -3248,9 +3307,9 @@ nsDOMDeviceStorage::Mount(ErrorResult& aRv)
}
RefPtr<DeviceStorageRequest> request = new DeviceStorageMountRequest();
request->Initialize(mManager, dsf, id);
request->Initialize(mManager, dsf.forget(), id);
aRv = CheckPermission(request);
aRv = CheckPermission(request.forget());
return domRequest.forget();
}
@@ -3270,9 +3329,9 @@ nsDOMDeviceStorage::Unmount(ErrorResult& aRv)
RefPtr<DeviceStorageRequest> request = new DeviceStorageUnmountRequest();
request->Initialize(mManager, dsf, id);
request->Initialize(mManager, dsf.forget(), id);
aRv = CheckPermission(request);
aRv = CheckPermission(request.forget());
return domRequest.forget();
}
@@ -3318,9 +3377,9 @@ nsDOMDeviceStorage::CreateFileDescriptor(const nsAString& aPath,
}
RefPtr<DeviceStorageRequest> request = new DeviceStorageCreateFdRequest();
request->Initialize(mManager, dsf, id, aDSFileDescriptor);
request->Initialize(mManager, dsf.forget(), id, aDSFileDescriptor);
aRv = CheckPermission(request);
aRv = CheckPermission(request.forget());
return domRequest.forget();
}
@@ -3425,8 +3484,8 @@ nsDOMDeviceStorage::EnumerateInternal(const nsAString& aPath,
if (!dsf->IsSafePath()) {
aRv = mManager->Reject(id, POST_ERROR_EVENT_PERMISSION_DENIED);
} else {
request->Initialize(mManager, dsf, id, since);
aRv = CheckPermission(request);
request->Initialize(mManager, dsf.forget(), id, since);
aRv = CheckPermission(request.forget());
}
return cursor.forget();
@@ -3628,8 +3687,8 @@ nsDOMDeviceStorage::EventListenerWasAdded(const nsAString& aType,
RefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType,
mStorageName);
RefPtr<DeviceStorageRequest> request = new DeviceStorageWatchRequest();
request->Initialize(mManager, dsf, id);
aRv = CheckPermission(request);
request->Initialize(mManager, dsf.forget(), id);
aRv = CheckPermission(request.forget());
}
Atomic<uint32_t> DeviceStorageRequestManager::sLastRequestId(0);
@@ -3655,8 +3714,7 @@ DeviceStorageRequestManager::~DeviceStorageRequestManager()
while (i > 0) {
--i;
DS_LOG_ERROR("terminate %u", mPending[i].mId);
NS_ProxyRelease(mOwningThread,
NS_ISUPPORTS_CAST(EventTarget*, mPending[i].mRequest.forget().take()));
NS_ProxyRelease(mOwningThread, mPending[i].mRequest.forget());
}
}
}
@@ -3693,14 +3751,15 @@ DeviceStorageRequestManager::IsOwningThread()
}
nsresult
DeviceStorageRequestManager::DispatchToOwningThread(nsIRunnable* aRunnable)
DeviceStorageRequestManager::DispatchToOwningThread(
already_AddRefed<nsIRunnable>&& aRunnable)
{
return mOwningThread->Dispatch(aRunnable, NS_DISPATCH_NORMAL);
return mOwningThread->Dispatch(Move(aRunnable), NS_DISPATCH_NORMAL);
}
nsresult
DeviceStorageRequestManager::DispatchOrAbandon(uint32_t aId,
nsIRunnable* aRunnable)
DeviceStorageRequestManager::DispatchOrAbandon(
uint32_t aId, already_AddRefed<nsIRunnable>&& aRunnable)
{
MutexAutoLock lock(mMutex);
if (mShutdown) {
@@ -3709,10 +3768,11 @@ DeviceStorageRequestManager::DispatchOrAbandon(uint32_t aId,
safe to be freed off the owner thread but the dispatch method
does not know that. */
DS_LOG_DEBUG("shutdown %u", aId);
nsCOMPtr<nsIRunnable> runnable(aRunnable);
return NS_ERROR_ILLEGAL_DURING_SHUTDOWN;
}
nsresult rv = DispatchToOwningThread(aRunnable);
nsresult rv = DispatchToOwningThread(Move(aRunnable));
if (NS_WARN_IF(NS_FAILED(rv))) {
DS_LOG_ERROR("abandon %u", aId);
}
@@ -3779,7 +3839,7 @@ DeviceStorageRequestManager::Resolve(uint32_t aId, bool aForceDispatch)
{
self->Resolve(aId, false);
});
return DispatchOrAbandon(aId, r);
return DispatchOrAbandon(aId, r.forget());
}
DS_LOG_INFO("posted %u", aId);
@@ -3811,7 +3871,7 @@ DeviceStorageRequestManager::Resolve(uint32_t aId, const nsString& aResult,
{
self->Resolve(aId, result, false);
});
return DispatchOrAbandon(aId, r);
return DispatchOrAbandon(aId, r.forget());
}
DS_LOG_INFO("posted %u w/ %s", aId,
@@ -3856,7 +3916,7 @@ DeviceStorageRequestManager::Resolve(uint32_t aId, uint64_t aValue,
{
self->Resolve(aId, aValue, false);
});
return DispatchOrAbandon(aId, r);
return DispatchOrAbandon(aId, r.forget());
}
DS_LOG_INFO("posted %u w/ %" PRIu64, aId, aValue);
@@ -3936,7 +3996,7 @@ DeviceStorageRequestManager::Resolve(uint32_t aId, BlobImpl* aBlobImpl,
{
self->Resolve(aId, blobImpl, false);
});
return DispatchOrAbandon(aId, r);
return DispatchOrAbandon(aId, r.forget());
}
DS_LOG_INFO("posted %u w/ %p", aId, aBlobImpl);
@@ -4064,7 +4124,7 @@ DeviceStorageRequestManager::Reject(uint32_t aId, const nsString& aReason)
self->RejectInternal(i, reason);
});
return DispatchOrAbandon(aId, r);
return DispatchOrAbandon(aId, r.forget());
}
nsresult
+13 -11
View File
@@ -130,16 +130,16 @@ public:
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mIOThread);
RefPtr<InvalidateRunnable> r = new InvalidateRunnable(this, aStorageName);
mIOThread->Dispatch(r, NS_DISPATCH_NORMAL);
mIOThread->Dispatch(new InvalidateRunnable(this, aStorageName),
NS_DISPATCH_NORMAL);
}
void Dispatch(nsIRunnable* aRunnable)
void Dispatch(already_AddRefed<nsIRunnable>&& aRunnable)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mIOThread);
mIOThread->Dispatch(aRunnable, NS_DISPATCH_NORMAL);
mIOThread->Dispatch(mozilla::Move(aRunnable), NS_DISPATCH_NORMAL);
}
nsresult AccumUsedSizes(const nsAString& aStorageName,
@@ -245,7 +245,7 @@ public:
DeviceStorageRequestManager();
bool IsOwningThread();
nsresult DispatchToOwningThread(nsIRunnable* aRunnable);
nsresult DispatchToOwningThread(already_AddRefed<nsIRunnable>&& aRunnable);
void StorePermission(size_t aAccess, bool aAllow);
uint32_t CheckPermission(size_t aAccess);
@@ -290,7 +290,8 @@ private:
uint32_t CreateInternal(mozilla::dom::DOMRequest* aRequest, bool aCursor);
nsresult ResolveInternal(ListIndex aIndex, JS::HandleValue aResult);
nsresult RejectInternal(ListIndex aIndex, const nsString& aReason);
nsresult DispatchOrAbandon(uint32_t aId, nsIRunnable* aRunnable);
nsresult DispatchOrAbandon(uint32_t aId,
already_AddRefed<nsIRunnable>&& aRunnable);
ListType::index_type Find(uint32_t aId);
nsCOMPtr<nsIThread> mOwningThread;
@@ -311,16 +312,16 @@ protected:
public:
virtual void Initialize(DeviceStorageRequestManager* aManager,
DeviceStorageFile* aFile,
already_AddRefed<DeviceStorageFile>&& aFile,
uint32_t aRequest);
virtual void Initialize(DeviceStorageRequestManager* aManager,
DeviceStorageFile* aFile,
already_AddRefed<DeviceStorageFile>&& aFile,
uint32_t aRequest,
mozilla::dom::BlobImpl* aBlob);
virtual void Initialize(DeviceStorageRequestManager* aManager,
DeviceStorageFile* aFile,
already_AddRefed<DeviceStorageFile>&& aFile,
uint32_t aRequest,
DeviceStorageFileDescriptor* aDSFileDescriptor);
@@ -378,7 +379,7 @@ protected:
}
virtual ~DeviceStorageRequest();
virtual void Prepare();
virtual nsresult Prepare();
virtual nsresult CreateSendParams(mozilla::dom::DeviceStorageParams& aParams);
nsresult AllowInternal();
nsresult SendToParentProcess();
@@ -390,6 +391,7 @@ protected:
RefPtr<DeviceStorageFileDescriptor> mDSFileDescriptor;
DeviceStorageAccessType mAccess;
bool mSendToParent;
bool mUseMainThread;
bool mUseStreamTransport;
bool mCheckFile;
bool mCheckBlob;
@@ -410,7 +412,7 @@ public:
using DeviceStorageRequest::Initialize;
virtual void Initialize(DeviceStorageRequestManager* aManager,
DeviceStorageFile* aFile,
already_AddRefed<DeviceStorageFile>&& aFile,
uint32_t aRequest,
PRTime aSince);
+1 -1
View File
@@ -1128,7 +1128,7 @@ Event::TimeStamp() const
MOZ_ASSERT(workerPrivate);
TimeDuration duration =
mEvent->timeStamp - workerPrivate->CreationTimeStamp();
mEvent->timeStamp - workerPrivate->NowBaseTimeStamp();
return duration.ToMilliseconds();
}
+2 -3
View File
@@ -74,9 +74,8 @@ function testWorkerEvents() {
var worker = new Worker(window.URL.createObjectURL(blob));
worker.onmessage = function(evt) {
var timeAfterEvent = window.performance.now();
var time = window.performance.translateTime(evt.data, worker);
ok(time >= timeBeforeEvent &&
time <= timeAfterEvent,
ok(evt.data > timeBeforeEvent &&
evt.data < timeAfterEvent,
"Event timestamp in dedicated worker (" + evt.data +
") is in expected range: (" +
timeBeforeEvent + ", " + timeAfterEvent + ")");
+45
View File
@@ -324,5 +324,50 @@ InternalRequest::MapChannelToRequestMode(nsIChannel* aChannel)
return static_cast<RequestMode>(corsMode);
}
// static
RequestCredentials
InternalRequest::MapChannelToRequestCredentials(nsIChannel* aChannel)
{
MOZ_ASSERT(aChannel);
nsCOMPtr<nsILoadInfo> loadInfo;
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(aChannel->GetLoadInfo(getter_AddRefs(loadInfo))));
uint32_t securityMode;
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(loadInfo->GetSecurityMode(&securityMode)));
// TODO: Remove following code after stylesheet and image support cookie policy
if (securityMode == nsILoadInfo::SEC_NORMAL) {
uint32_t loadFlags;
aChannel->GetLoadFlags(&loadFlags);
if (loadFlags & nsIRequest::LOAD_ANONYMOUS) {
return RequestCredentials::Omit;
} else {
bool includeCrossOrigin;
nsCOMPtr<nsIHttpChannelInternal> internalChannel = do_QueryInterface(aChannel);
internalChannel->GetCorsIncludeCredentials(&includeCrossOrigin);
if (includeCrossOrigin) {
return RequestCredentials::Include;
}
}
return RequestCredentials::Same_origin;
}
uint32_t cookiePolicy = loadInfo->GetCookiePolicy();
if (cookiePolicy == nsILoadInfo::SEC_COOKIES_INCLUDE) {
return RequestCredentials::Include;
} else if (cookiePolicy == nsILoadInfo::SEC_COOKIES_OMIT) {
return RequestCredentials::Omit;
} else if (cookiePolicy == nsILoadInfo::SEC_COOKIES_SAME_ORIGIN) {
return RequestCredentials::Same_origin;
}
MOZ_ASSERT_UNREACHABLE("Unexpected cookie policy!");
return RequestCredentials::Same_origin;
}
} // namespace dom
} // namespace mozilla
+3
View File
@@ -376,6 +376,9 @@ public:
static RequestMode
MapChannelToRequestMode(nsIChannel* aChannel);
static RequestCredentials
MapChannelToRequestCredentials(nsIChannel* aChannel);
private:
// Does not copy mBodyStream. Use fallible Clone() for complete copy.
explicit InternalRequest(const InternalRequest& aOther);
+10 -8
View File
@@ -36,7 +36,6 @@ class BackgroundChildImpl;
} // namespace ipc
namespace dom {
namespace indexedDB {
class IDBCursor;
class IDBDatabase;
@@ -44,6 +43,9 @@ class IDBFactory;
class IDBMutableFile;
class IDBOpenDBRequest;
class IDBRequest;
namespace indexedDB {
class Key;
class PermissionRequestChild;
class PermissionRequestParent;
@@ -52,7 +54,7 @@ class SerializedStructuredCloneReadInfo;
class ThreadLocal
{
friend class nsAutoPtr<ThreadLocal>;
friend class IDBFactory;
friend IDBFactory;
LoggingInfo mLoggingInfo;
IDBTransaction* mCurrentTransaction;
@@ -147,7 +149,7 @@ class BackgroundFactoryChild final
: public PBackgroundIDBFactoryChild
{
friend class mozilla::ipc::BackgroundChildImpl;
friend class IDBFactory;
friend IDBFactory;
IDBFactory* mFactory;
@@ -240,7 +242,7 @@ class BackgroundFactoryRequestChild final
{
typedef mozilla::dom::quota::PersistenceType PersistenceType;
friend class IDBFactory;
friend IDBFactory;
friend class BackgroundFactoryChild;
friend class BackgroundDatabaseChild;
friend class PermissionRequestChild;
@@ -292,7 +294,7 @@ class BackgroundDatabaseChild final
{
friend class BackgroundFactoryChild;
friend class BackgroundFactoryRequestChild;
friend class IDBDatabase;
friend IDBDatabase;
nsAutoPtr<DatabaseSpec> mSpec;
RefPtr<IDBDatabase> mTemporaryStrongDatabase;
@@ -424,7 +426,7 @@ class BackgroundDatabaseRequestChild final
, public PBackgroundIDBDatabaseRequestChild
{
friend class BackgroundDatabaseChild;
friend class IDBDatabase;
friend IDBDatabase;
RefPtr<IDBDatabase> mDatabase;
@@ -504,7 +506,7 @@ class BackgroundTransactionChild final
, public PBackgroundIDBTransactionChild
{
friend class BackgroundDatabaseChild;
friend class IDBDatabase;
friend IDBDatabase;
public:
#ifdef DEBUG
@@ -631,7 +633,7 @@ class BackgroundRequestChild final
{
friend class BackgroundTransactionChild;
friend class BackgroundVersionChangeTransactionChild;
friend class IDBTransaction;
friend IDBTransaction;
RefPtr<IDBTransaction> mTransaction;
+2 -1
View File
@@ -29,10 +29,11 @@ NS_DEFINE_STATIC_IID_ACCESSOR(PIBlobImplSnapshot, FILEIMPLSNAPSHOT_IID)
namespace mozilla {
namespace dom {
namespace indexedDB {
class IDBFileHandle;
namespace indexedDB {
class BlobImplSnapshot final
: public BlobImpl
, public PIBlobImplSnapshot
+2 -2
View File
@@ -24,7 +24,8 @@
namespace mozilla {
namespace dom {
namespace indexedDB {
using namespace indexedDB;
IDBCursor::IDBCursor(Type aType,
BackgroundCursorChild* aBackgroundActor,
@@ -896,6 +897,5 @@ IDBCursor::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
}
}
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
+17 -15
View File
@@ -4,8 +4,8 @@
* 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_indexeddb_idbcursor_h__
#define mozilla_dom_indexeddb_idbcursor_h__
#ifndef mozilla_dom_idbcursor_h__
#define mozilla_dom_idbcursor_h__
#include "IndexedDatabase.h"
#include "js/RootingAPI.h"
@@ -24,21 +24,24 @@ class ErrorResult;
namespace dom {
class OwningIDBObjectStoreOrIDBIndex;
namespace indexedDB {
class BackgroundCursorChild;
class IDBIndex;
class IDBObjectStore;
class IDBRequest;
class IDBTransaction;
class OwningIDBObjectStoreOrIDBIndex;
namespace indexedDB {
class BackgroundCursorChild;
}
class IDBCursor final
: public nsISupports
, public nsWrapperCache
{
public:
typedef indexedDB::Key Key;
typedef indexedDB::StructuredCloneReadInfo StructuredCloneReadInfo;
enum Direction
{
NEXT = 0,
@@ -59,7 +62,7 @@ private:
Type_IndexKey,
};
BackgroundCursorChild* mBackgroundActor;
indexedDB::BackgroundCursorChild* mBackgroundActor;
RefPtr<IDBRequest> mRequest;
RefPtr<IDBObjectStore> mSourceObjectStore;
@@ -92,23 +95,23 @@ private:
public:
static already_AddRefed<IDBCursor>
Create(BackgroundCursorChild* aBackgroundActor,
Create(indexedDB::BackgroundCursorChild* aBackgroundActor,
const Key& aKey,
StructuredCloneReadInfo&& aCloneInfo);
static already_AddRefed<IDBCursor>
Create(BackgroundCursorChild* aBackgroundActor,
Create(indexedDB::BackgroundCursorChild* aBackgroundActor,
const Key& aKey);
static already_AddRefed<IDBCursor>
Create(BackgroundCursorChild* aBackgroundActor,
Create(indexedDB::BackgroundCursorChild* aBackgroundActor,
const Key& aKey,
const Key& aSortKey,
const Key& aPrimaryKey,
StructuredCloneReadInfo&& aCloneInfo);
static already_AddRefed<IDBCursor>
Create(BackgroundCursorChild* aBackgroundActor,
Create(indexedDB::BackgroundCursorChild* aBackgroundActor,
const Key& aKey,
const Key& aSortKey,
const Key& aPrimaryKey);
@@ -194,7 +197,7 @@ public:
private:
IDBCursor(Type aType,
BackgroundCursorChild* aBackgroundActor,
indexedDB::BackgroundCursorChild* aBackgroundActor,
const Key& aKey);
~IDBCursor();
@@ -212,8 +215,7 @@ private:
IsSourceDeleted() const;
};
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_indexeddb_idbcursor_h__
#endif // mozilla_dom_idbcursor_h__
+8 -6
View File
@@ -56,7 +56,6 @@
namespace mozilla {
namespace dom {
namespace indexedDB {
using namespace mozilla::dom::quota;
using namespace mozilla::ipc;
@@ -469,7 +468,6 @@ IDBDatabase::CreateObjectStore(
AssertIsOnOwningThread();
IDBTransaction* transaction = IDBTransaction::GetCurrent();
if (!transaction ||
transaction->Database() != this ||
transaction->GetMode() != IDBTransaction::VERSION_CHANGE) {
@@ -477,7 +475,10 @@ IDBDatabase::CreateObjectStore(
return nullptr;
}
MOZ_ASSERT(transaction->IsOpen());
if (!transaction->IsOpen()) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
return nullptr;
}
KeyPath keyPath(0);
if (NS_FAILED(KeyPath::Parse(aOptionalParameters.mKeyPath, &keyPath))) {
@@ -545,7 +546,6 @@ IDBDatabase::DeleteObjectStore(const nsAString& aName, ErrorResult& aRv)
AssertIsOnOwningThread();
IDBTransaction* transaction = IDBTransaction::GetCurrent();
if (!transaction ||
transaction->Database() != this ||
transaction->GetMode() != IDBTransaction::VERSION_CHANGE) {
@@ -553,7 +553,10 @@ IDBDatabase::DeleteObjectStore(const nsAString& aName, ErrorResult& aRv)
return;
}
MOZ_ASSERT(transaction->IsOpen());
if (!transaction->IsOpen()) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
return;
}
nsTArray<ObjectStoreSpec>& specArray = mSpec->objectStores();
@@ -1482,6 +1485,5 @@ Observer::Observe(nsISupports* aSubject,
return NS_OK;
}
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
+18 -18
View File
@@ -4,13 +4,13 @@
* 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_indexeddb_idbdatabase_h__
#define mozilla_dom_indexeddb_idbdatabase_h__
#ifndef mozilla_dom_idbdatabase_h__
#define mozilla_dom_idbdatabase_h__
#include "mozilla/Attributes.h"
#include "mozilla/dom/IDBTransactionBinding.h"
#include "mozilla/dom/StorageTypeBinding.h"
#include "mozilla/dom/indexedDB/IDBWrapperCache.h"
#include "mozilla/dom/IDBWrapperCache.h"
#include "mozilla/dom/quota/PersistenceType.h"
#include "nsAutoPtr.h"
#include "nsDataHashtable.h"
@@ -30,25 +30,26 @@ namespace dom {
class Blob;
class DOMStringList;
class IDBFactory;
class IDBMutableFile;
class IDBObjectStore;
struct IDBObjectStoreParameters;
class IDBOpenDBRequest;
class IDBRequest;
class IDBTransaction;
template <class> class Optional;
class StringOrStringSequence;
namespace indexedDB {
class BackgroundDatabaseChild;
class DatabaseSpec;
class IDBFactory;
class IDBMutableFile;
class IDBObjectStore;
class IDBOpenDBRequest;
class IDBRequest;
class IDBTransaction;
class PBackgroundIDBDatabaseFileChild;
}
class IDBDatabase final
: public IDBWrapperCache
{
typedef mozilla::dom::indexedDB::DatabaseSpec DatabaseSpec;
typedef mozilla::dom::StorageType StorageType;
typedef mozilla::dom::quota::PersistenceType PersistenceType;
@@ -68,11 +69,11 @@ class IDBDatabase final
// Normally null except during a versionchange transaction.
nsAutoPtr<DatabaseSpec> mPreviousSpec;
BackgroundDatabaseChild* mBackgroundActor;
indexedDB::BackgroundDatabaseChild* mBackgroundActor;
nsTHashtable<nsPtrHashKey<IDBTransaction>> mTransactions;
nsDataHashtable<nsISupportsHashKey, PBackgroundIDBDatabaseFileChild*>
nsDataHashtable<nsISupportsHashKey, indexedDB::PBackgroundIDBDatabaseFileChild*>
mFileActors;
nsTHashtable<nsISupportsHashKey> mReceivedBlobs;
@@ -90,7 +91,7 @@ public:
static already_AddRefed<IDBDatabase>
Create(IDBOpenDBRequest* aRequest,
IDBFactory* aFactory,
BackgroundDatabaseChild* aActor,
indexedDB::BackgroundDatabaseChild* aActor,
DatabaseSpec* aSpec);
#ifdef DEBUG
@@ -179,11 +180,11 @@ public:
void
AbortTransactions(bool aShouldWarn);
PBackgroundIDBDatabaseFileChild*
indexedDB::PBackgroundIDBDatabaseFileChild*
GetOrCreateFileActorForBlob(Blob* aBlob);
void
NoteFinishedFileActor(PBackgroundIDBDatabaseFileChild* aFileActor);
NoteFinishedFileActor(indexedDB::PBackgroundIDBDatabaseFileChild* aFileActor);
void
NoteReceivedBlob(Blob* aBlob);
@@ -285,7 +286,7 @@ public:
private:
IDBDatabase(IDBOpenDBRequest* aRequest,
IDBFactory* aFactory,
BackgroundDatabaseChild* aActor,
indexedDB::BackgroundDatabaseChild* aActor,
DatabaseSpec* aSpec);
~IDBDatabase();
@@ -320,8 +321,7 @@ private:
uint32_t aColumnNumber);
};
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_indexeddb_idbdatabase_h__
#endif // mozilla_dom_idbdatabase_h__
+2 -1
View File
@@ -44,6 +44,8 @@ CreateGenericEvent(EventTarget* aOwner,
return event.forget();
}
} // namespace indexedDB
// static
already_AddRefed<IDBVersionChangeEvent>
IDBVersionChangeEvent::CreateInternal(EventTarget* aOwner,
@@ -91,6 +93,5 @@ IDBVersionChangeEvent::WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*>
return IDBVersionChangeEventBinding::Wrap(aCx, this, aGivenProto);
}
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
+5 -4
View File
@@ -4,8 +4,8 @@
* 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_indexeddb_idbevents_h__
#define mozilla_dom_indexeddb_idbevents_h__
#ifndef mozilla_dom_idbevents_h__
#define mozilla_dom_idbevents_h__
#include "js/RootingAPI.h"
#include "mozilla/dom/BindingDeclarations.h"
@@ -54,6 +54,8 @@ CreateGenericEvent(EventTarget* aOwner,
Bubbles aBubbles,
Cancelable aCancelable);
} // namespace indexedDB
class IDBVersionChangeEvent final : public Event
{
uint64_t mOldVersion;
@@ -125,8 +127,7 @@ private:
NS_DEFINE_STATIC_IID_ACCESSOR(IDBVersionChangeEvent, IDBVERSIONCHANGEEVENT_IID)
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_indexeddb_idbevents_h__
#endif // mozilla_dom_idbevents_h__
-2
View File
@@ -43,7 +43,6 @@
namespace mozilla {
namespace dom {
namespace indexedDB {
using namespace mozilla::dom::quota;
using namespace mozilla::ipc;
@@ -956,6 +955,5 @@ IDBFactory::BackgroundCreateCallback::ActorFailed()
factory->BackgroundActorFailed();
}
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
+8 -9
View File
@@ -4,8 +4,8 @@
* 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_indexeddb_idbfactory_h__
#define mozilla_dom_indexeddb_idbfactory_h__
#ifndef mozilla_dom_idbfactory_h__
#define mozilla_dom_idbfactory_h__
#include "mozilla/Attributes.h"
#include "mozilla/dom/StorageTypeBinding.h"
@@ -35,15 +35,15 @@ class PrincipalInfo;
namespace dom {
struct IDBOpenDBOptions;
class IDBOpenDBRequest;
template <typename> class Optional;
class TabChild;
namespace indexedDB {
class BackgroundFactoryChild;
class FactoryRequestParams;
class IDBOpenDBRequest;
class LoggingInfo;
}
class IDBFactory final
: public nsISupports
@@ -69,7 +69,7 @@ class IDBFactory final
nsTArray<nsAutoPtr<PendingRequestInfo>> mPendingRequests;
BackgroundFactoryChild* mBackgroundActor;
indexedDB::BackgroundFactoryChild* mBackgroundActor;
#ifdef DEBUG
PRThread* mOwningThread;
@@ -240,18 +240,17 @@ private:
nsresult
BackgroundActorCreated(PBackgroundChild* aBackgroundActor,
const LoggingInfo& aLoggingInfo);
const indexedDB::LoggingInfo& aLoggingInfo);
void
BackgroundActorFailed();
nsresult
InitiateRequest(IDBOpenDBRequest* aRequest,
const FactoryRequestParams& aParams);
const indexedDB::FactoryRequestParams& aParams);
};
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_indexeddb_idbfactory_h__
#endif // mozilla_dom_idbfactory_h__
+2 -2
View File
@@ -17,7 +17,8 @@
namespace mozilla {
namespace dom {
namespace indexedDB {
using namespace mozilla::dom::indexedDB;
IDBFileHandle::IDBFileHandle(FileMode aMode,
IDBMutableFile* aMutableFile)
@@ -194,6 +195,5 @@ IDBFileHandle::GenerateFileRequest()
/* aWrapAsDOMRequest */ false);
}
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
+3 -7
View File
@@ -4,8 +4,8 @@
* 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_indexeddb_idbfilehandle_h__
#define mozilla_dom_indexeddb_idbfilehandle_h__
#ifndef mozilla_dom_idbfilehandle_h__
#define mozilla_dom_idbfilehandle_h__
#include "IDBFileRequest.h"
#include "js/TypeDecls.h"
@@ -22,9 +22,6 @@ namespace mozilla {
namespace dom {
struct IDBFileMetadataParameters;
namespace indexedDB {
class IDBFileRequest;
class IDBMutableFile;
@@ -146,8 +143,7 @@ private:
GenerateFileRequest() override;
};
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_indexeddb_idbfilehandle_h__
#endif // mozilla_dom_idbfilehandle_h__
+2 -2
View File
@@ -21,7 +21,8 @@
namespace mozilla {
namespace dom {
namespace indexedDB {
using namespace mozilla::dom::indexedDB;
IDBFileRequest::IDBFileRequest(nsPIDOMWindow* aWindow,
IDBFileHandle* aFileHandle,
@@ -152,6 +153,5 @@ IDBFileRequest::FireProgressEvent(uint64_t aLoaded, uint64_t aTotal)
DispatchTrustedEvent(event);
}
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
+3 -5
View File
@@ -4,8 +4,8 @@
* 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_indexeddb_idbfilerequest_h__
#define mozilla_dom_indexeddb_idbfilerequest_h__
#ifndef mozilla_dom_idbfilerequest_h__
#define mozilla_dom_idbfilerequest_h__
#include "DOMRequest.h"
#include "js/TypeDecls.h"
@@ -22,7 +22,6 @@ namespace mozilla {
class EventChainPreVisitor;
namespace dom {
namespace indexedDB {
class IDBFileHandle;
@@ -90,8 +89,7 @@ private:
FireProgressEvent(uint64_t aLoaded, uint64_t aTotal);
};
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_indexeddb_idbfilerequest_h__
#endif // mozilla_dom_idbfilerequest_h__
+1 -3
View File
@@ -25,7 +25,6 @@
namespace mozilla {
namespace dom {
namespace indexedDB {
namespace {
@@ -177,7 +176,7 @@ IDBIndex::LocaleAware() const
return mMetadata->locale().IsEmpty();
}
const KeyPath&
const indexedDB::KeyPath&
IDBIndex::GetKeyPath() const
{
AssertIsOnOwningThread();
@@ -621,6 +620,5 @@ IDBIndex::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
return IDBIndexBinding::Wrap(aCx, this, aGivenProto);
}
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
+11 -13
View File
@@ -4,8 +4,8 @@
* 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_indexeddb_idbindex_h__
#define mozilla_dom_indexeddb_idbindex_h__
#ifndef mozilla_dom_idbindex_h__
#define mozilla_dom_idbindex_h__
#include "js/RootingAPI.h"
#include "mozilla/Attributes.h"
@@ -24,15 +24,14 @@ class ErrorResult;
namespace dom {
class IDBObjectStore;
class IDBRequest;
template <typename> class Sequence;
namespace indexedDB {
class IDBObjectStore;
class IDBRequest;
class IndexMetadata;
class Key;
class KeyPath;
} // namespace indexedDB
class IDBIndex final
: public nsISupports
@@ -46,8 +45,8 @@ class IDBIndex final
// object. However, if this index is part of a versionchange transaction and
// it gets deleted then the metadata is copied into mDeletedMetadata and
// mMetadata is set to point at mDeletedMetadata.
const IndexMetadata* mMetadata;
nsAutoPtr<IndexMetadata> mDeletedMetadata;
const indexedDB::IndexMetadata* mMetadata;
nsAutoPtr<indexedDB::IndexMetadata> mDeletedMetadata;
const int64_t mId;
bool mRooted;
@@ -57,7 +56,7 @@ public:
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IDBIndex)
static already_AddRefed<IDBIndex>
Create(IDBObjectStore* aObjectStore, const IndexMetadata& aMetadata);
Create(IDBObjectStore* aObjectStore, const indexedDB::IndexMetadata& aMetadata);
int64_t
Id() const
@@ -79,7 +78,7 @@ public:
bool
LocaleAware() const;
const KeyPath&
const indexedDB::KeyPath&
GetKeyPath() const;
void
@@ -201,7 +200,7 @@ public:
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
private:
IDBIndex(IDBObjectStore* aObjectStore, const IndexMetadata* aMetadata);
IDBIndex(IDBObjectStore* aObjectStore, const indexedDB::IndexMetadata* aMetadata);
~IDBIndex();
@@ -226,8 +225,7 @@ private:
ErrorResult& aRv);
};
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_indexeddb_idbindex_h__
#endif // mozilla_dom_idbindex_h__
+2 -2
View File
@@ -14,7 +14,8 @@
namespace mozilla {
namespace dom {
namespace indexedDB {
using namespace mozilla::dom::indexedDB;
namespace {
@@ -447,6 +448,5 @@ IDBLocaleAwareKeyRange::Bound(const GlobalObject& aGlobal,
return keyRange.forget();
}
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
+13 -13
View File
@@ -4,12 +4,13 @@
* 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_indexeddb_idbkeyrange_h__
#define mozilla_dom_indexeddb_idbkeyrange_h__
#ifndef mozilla_dom_idbkeyrange_h__
#define mozilla_dom_idbkeyrange_h__
#include "js/RootingAPI.h"
#include "js/Value.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/IndexedDatabaseManager.h"
#include "mozilla/dom/indexedDB/Key.h"
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
@@ -28,16 +29,16 @@ namespace dom {
class GlobalObject;
namespace indexedDB {
class SerializedKeyRange;
} // namespace indexedDB
class IDBKeyRange
: public nsISupports
{
protected:
nsCOMPtr<nsISupports> mGlobal;
Key mLower;
Key mUpper;
indexedDB::Key mLower;
indexedDB::Key mUpper;
JS::Heap<JS::Value> mCachedLowerVal;
JS::Heap<JS::Value> mCachedUpperVal;
@@ -62,7 +63,7 @@ public:
IDBKeyRange** aKeyRange);
static already_AddRefed<IDBKeyRange>
FromSerialized(const SerializedKeyRange& aKeyRange);
FromSerialized(const indexedDB::SerializedKeyRange& aKeyRange);
static already_AddRefed<IDBKeyRange>
Only(const GlobalObject& aGlobal,
@@ -98,27 +99,27 @@ public:
#endif
void
ToSerialized(SerializedKeyRange& aKeyRange) const;
ToSerialized(indexedDB::SerializedKeyRange& aKeyRange) const;
const Key&
const indexedDB::Key&
Lower() const
{
return mLower;
}
Key&
indexedDB::Key&
Lower()
{
return mLower;
}
const Key&
const indexedDB::Key&
Upper() const
{
return mIsOnly ? mLower : mUpper;
}
Key&
indexedDB::Key&
Upper()
{
return mIsOnly ? mLower : mUpper;
@@ -205,8 +206,7 @@ public:
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector);
};
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_indexeddb_idbkeyrange_h__
#endif // mozilla_dom_idbkeyrange_h__
+1 -2
View File
@@ -34,8 +34,8 @@
namespace mozilla {
namespace dom {
namespace indexedDB {
using namespace mozilla::dom::indexedDB;
using namespace mozilla::dom::quota;
IDBMutableFile::IDBMutableFile(IDBDatabase* aDatabase,
@@ -279,6 +279,5 @@ IDBMutableFile::CreateFileFor(BlobImpl* aBlobImpl,
return file.forget();
}
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
+8 -9
View File
@@ -4,8 +4,8 @@
* 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_indexeddb_idbmutablefile_h__
#define mozilla_dom_indexeddb_idbmutablefile_h__
#ifndef mozilla_dom_idbmutablefile_h__
#define mozilla_dom_idbmutablefile_h__
#include "js/TypeDecls.h"
#include "mozilla/Atomics.h"
@@ -29,13 +29,13 @@ namespace dom {
class DOMRequest;
class File;
namespace indexedDB {
class BackgroundMutableFileChild;
class IDBDatabase;
class IDBFileHandle;
namespace indexedDB {
class BackgroundMutableFileChild;
}
class IDBMutableFile final
: public DOMEventTargetHelper
, public MutableFileBase
@@ -51,7 +51,7 @@ class IDBMutableFile final
public:
IDBMutableFile(IDBDatabase* aDatabase,
BackgroundMutableFileChild* aActor,
indexedDB::BackgroundMutableFileChild* aActor,
const nsAString& aName,
const nsAString& aType);
@@ -134,8 +134,7 @@ private:
~IDBMutableFile();
};
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_indexeddb_idbmutablefile_h__
#endif // mozilla_dom_idbmutablefile_h__
+15 -13
View File
@@ -54,7 +54,6 @@
namespace mozilla {
namespace dom {
namespace indexedDB {
using namespace mozilla::dom::quota;
using namespace mozilla::dom::workers;
@@ -1865,16 +1864,18 @@ IDBObjectStore::CreateIndexInternal(
{
AssertIsOnOwningThread();
IDBTransaction* transaction = IDBTransaction::GetCurrent();
if (!transaction ||
transaction != mTransaction ||
mTransaction->GetMode() != IDBTransaction::VERSION_CHANGE ||
if (mTransaction->GetMode() != IDBTransaction::VERSION_CHANGE ||
mDeletedSpec) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
return nullptr;
}
IDBTransaction* transaction = IDBTransaction::GetCurrent();
if (!transaction || transaction != mTransaction) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
return nullptr;
}
MOZ_ASSERT(transaction->IsOpen());
auto& indexes = const_cast<nsTArray<IndexMetadata>&>(mSpec->indexes());
@@ -1960,16 +1961,18 @@ IDBObjectStore::DeleteIndex(const nsAString& aName, ErrorResult& aRv)
{
AssertIsOnOwningThread();
IDBTransaction* transaction = IDBTransaction::GetCurrent();
if (!transaction ||
transaction != mTransaction ||
mTransaction->GetMode() != IDBTransaction::VERSION_CHANGE ||
if (mTransaction->GetMode() != IDBTransaction::VERSION_CHANGE ||
mDeletedSpec) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
return;
}
IDBTransaction* transaction = IDBTransaction::GetCurrent();
if (!transaction || transaction != mTransaction) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
return;
}
MOZ_ASSERT(transaction->IsOpen());
auto& metadataArray = const_cast<nsTArray<IndexMetadata>&>(mSpec->indexes());
@@ -2275,7 +2278,7 @@ IDBObjectStore::AutoIncrement() const
return mSpec->metadata().autoIncrement();
}
const KeyPath&
const indexedDB::KeyPath&
IDBObjectStore::GetKeyPath() const
{
AssertIsOnOwningThread();
@@ -2293,6 +2296,5 @@ IDBObjectStore::HasValidKeyPath() const
return GetKeyPath().IsValid();
}
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
+15 -10
View File
@@ -4,8 +4,8 @@
* 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_indexeddb_idbobjectstore_h__
#define mozilla_dom_indexeddb_idbobjectstore_h__
#ifndef mozilla_dom_idbobjectstore_h__
#define mozilla_dom_idbobjectstore_h__
#include "js/RootingAPI.h"
#include "mozilla/dom/IDBCursorBinding.h"
@@ -27,25 +27,31 @@ class ErrorResult;
namespace dom {
class DOMStringList;
template <typename> class Sequence;
namespace indexedDB {
class IDBCursor;
class IDBRequest;
class IDBTransaction;
class IndexUpdateInfo;
template <typename> class Sequence;
namespace indexedDB {
class Key;
class KeyPath;
class IndexUpdateInfo;
class ObjectStoreSpec;
struct StructuredCloneReadInfo;
} // namespace indexedDB
class IDBObjectStore final
: public nsISupports
, public nsWrapperCache
{
typedef indexedDB::IndexUpdateInfo IndexUpdateInfo;
typedef indexedDB::Key Key;
typedef indexedDB::KeyPath KeyPath;
typedef indexedDB::ObjectStoreSpec ObjectStoreSpec;
typedef indexedDB::StructuredCloneReadInfo StructuredCloneReadInfo;
// For AddOrPut() and DeleteInternal().
friend class IDBCursor;
friend class IDBCursor;
static const JSClass sDummyPropJSClass;
@@ -339,8 +345,7 @@ private:
ErrorResult& aRv);
};
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_indexeddb_idbobjectstore_h__
#endif // mozilla_dom_idbobjectstore_h__
+1 -2
View File
@@ -38,8 +38,8 @@
namespace mozilla {
namespace dom {
namespace indexedDB {
using namespace mozilla::dom::indexedDB;
using namespace mozilla::dom::workers;
using namespace mozilla::ipc;
@@ -660,6 +660,5 @@ WorkerFeature::Notify(JSContext* aCx, Status aStatus)
return true;
}
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
+6 -10
View File
@@ -4,14 +4,14 @@
* 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_indexeddb_idbrequest_h__
#define mozilla_dom_indexeddb_idbrequest_h__
#ifndef mozilla_dom_idbrequest_h__
#define mozilla_dom_idbrequest_h__
#include "js/RootingAPI.h"
#include "mozilla/Attributes.h"
#include "mozilla/EventForwards.h"
#include "mozilla/dom/IDBRequestBinding.h"
#include "mozilla/dom/indexedDB/IDBWrapperCache.h"
#include "mozilla/dom/IDBWrapperCache.h"
#include "nsAutoPtr.h"
#include "nsCycleCollectionParticipant.h"
@@ -28,17 +28,14 @@ class ErrorResult;
namespace dom {
class DOMError;
template <typename> struct Nullable;
class OwningIDBObjectStoreOrIDBIndexOrIDBCursor;
namespace indexedDB {
class IDBCursor;
class IDBDatabase;
class IDBFactory;
class IDBIndex;
class IDBObjectStore;
class IDBTransaction;
template <typename> struct Nullable;
class OwningIDBObjectStoreOrIDBIndexOrIDBCursor;
class IDBRequest
: public IDBWrapperCache
@@ -285,8 +282,7 @@ private:
~IDBOpenDBRequest();
};
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_indexeddb_idbrequest_h__
#endif // mozilla_dom_idbrequest_h__
+4 -5
View File
@@ -29,8 +29,8 @@
namespace mozilla {
namespace dom {
namespace indexedDB {
using namespace mozilla::dom::indexedDB;
using namespace mozilla::dom::workers;
using namespace mozilla::ipc;
@@ -279,7 +279,7 @@ IDBTransaction::AssertIsOnOwningThread() const
#endif // DEBUG
void
IDBTransaction::SetBackgroundActor(BackgroundTransactionChild* aBackgroundActor)
IDBTransaction::SetBackgroundActor(indexedDB::BackgroundTransactionChild* aBackgroundActor)
{
AssertIsOnOwningThread();
MOZ_ASSERT(aBackgroundActor);
@@ -570,7 +570,7 @@ IDBTransaction::DeleteObjectStore(int64_t aObjectStoreId)
void
IDBTransaction::CreateIndex(IDBObjectStore* aObjectStore,
const IndexMetadata& aMetadata)
const indexedDB::IndexMetadata& aMetadata)
{
AssertIsOnOwningThread();
MOZ_ASSERT(aObjectStore);
@@ -859,7 +859,7 @@ IDBTransaction::GetError() const
}
already_AddRefed<DOMStringList>
IDBTransaction::ObjectStoreNames()
IDBTransaction::ObjectStoreNames() const
{
AssertIsOnOwningThread();
@@ -1012,6 +1012,5 @@ WorkerFeature::Notify(JSContext* aCx, Status aStatus)
return true;
}
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
+24 -25
View File
@@ -4,12 +4,12 @@
* 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_indexeddb_idbtransaction_h__
#define mozilla_dom_indexeddb_idbtransaction_h__
#ifndef mozilla_dom_idbtransaction_h__
#define mozilla_dom_idbtransaction_h__
#include "mozilla/Attributes.h"
#include "mozilla/dom/IDBTransactionBinding.h"
#include "mozilla/dom/indexedDB/IDBWrapperCache.h"
#include "mozilla/dom/IDBWrapperCache.h"
#include "nsAutoPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIRunnable.h"
@@ -27,28 +27,28 @@ namespace dom {
class DOMError;
class DOMStringList;
namespace indexedDB {
class BackgroundCursorChild;
class BackgroundRequestChild;
class BackgroundTransactionChild;
class BackgroundVersionChangeTransactionChild;
class IDBDatabase;
class IDBObjectStore;
class IDBOpenDBRequest;
class IDBRequest;
namespace indexedDB {
class BackgroundCursorChild;
class BackgroundRequestChild;
class BackgroundTransactionChild;
class BackgroundVersionChangeTransactionChild;
class IndexMetadata;
class ObjectStoreSpec;
class OpenCursorParams;
class RequestParams;
}
class IDBTransaction final
: public IDBWrapperCache
, public nsIRunnable
{
friend class BackgroundCursorChild;
friend class BackgroundRequestChild;
friend class indexedDB::BackgroundCursorChild;
friend class indexedDB::BackgroundRequestChild;
class WorkerFeature;
friend class WorkerFeature;
@@ -85,8 +85,8 @@ private:
// a BackgroundVersionChangeTransactionChild. Otherwise it will be a
// BackgroundTransactionChild.
union {
BackgroundTransactionChild* mNormalBackgroundActor;
BackgroundVersionChangeTransactionChild* mVersionChangeBackgroundActor;
indexedDB::BackgroundTransactionChild* mNormalBackgroundActor;
indexedDB::BackgroundVersionChangeTransactionChild* mVersionChangeBackgroundActor;
} mBackgroundActor;
const int64_t mLoggingSerialNumber;
@@ -117,7 +117,7 @@ private:
public:
static already_AddRefed<IDBTransaction>
CreateVersionChange(IDBDatabase* aDatabase,
BackgroundVersionChangeTransactionChild* aActor,
indexedDB::BackgroundVersionChangeTransactionChild* aActor,
IDBOpenDBRequest* aOpenRequest,
int64_t aNextObjectStoreId,
int64_t aNextIndexId);
@@ -139,7 +139,7 @@ public:
#endif
void
SetBackgroundActor(BackgroundTransactionChild* aBackgroundActor);
SetBackgroundActor(indexedDB::BackgroundTransactionChild* aBackgroundActor);
void
ClearBackgroundActor()
@@ -153,12 +153,12 @@ public:
}
}
BackgroundRequestChild*
StartRequest(IDBRequest* aRequest, const RequestParams& aParams);
indexedDB::BackgroundRequestChild*
StartRequest(IDBRequest* aRequest, const indexedDB::RequestParams& aParams);
void
OpenCursor(BackgroundCursorChild* aBackgroundActor,
const OpenCursorParams& aParams);
OpenCursor(indexedDB::BackgroundCursorChild* aBackgroundActor,
const indexedDB::OpenCursorParams& aParams);
void
RefreshSpec(bool aMayDelete);
@@ -238,13 +238,13 @@ public:
}
already_AddRefed<IDBObjectStore>
CreateObjectStore(const ObjectStoreSpec& aSpec);
CreateObjectStore(const indexedDB::ObjectStoreSpec& aSpec);
void
DeleteObjectStore(int64_t aObjectStoreId);
void
CreateIndex(IDBObjectStore* aObjectStore, const IndexMetadata& aMetadata);
CreateIndex(IDBObjectStore* aObjectStore, const indexedDB::IndexMetadata& aMetadata);
void
DeleteIndex(IDBObjectStore* aObjectStore, int64_t aIndexId);
@@ -283,7 +283,7 @@ public:
IMPL_EVENT_HANDLER(error)
already_AddRefed<DOMStringList>
ObjectStoreNames();
ObjectStoreNames() const;
void
FireCompleteOrAbortEvents(nsresult aResult);
@@ -330,8 +330,7 @@ private:
OnRequestFinished(bool aActorDestroyedNormally);
};
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_indexeddb_idbtransaction_h__
#endif // mozilla_dom_idbtransaction_h__
-2
View File
@@ -13,7 +13,6 @@
namespace mozilla {
namespace dom {
namespace indexedDB {
NS_IMPL_CYCLE_COLLECTION_CLASS(IDBWrapperCache)
@@ -77,6 +76,5 @@ IDBWrapperCache::AssertIsRooted() const
}
#endif
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
+3 -5
View File
@@ -4,8 +4,8 @@
* 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_indexeddb_idbwrappercache_h__
#define mozilla_dom_indexeddb_idbwrappercache_h__
#ifndef mozilla_dom_idbwrappercache_h__
#define mozilla_dom_idbwrappercache_h__
#include "js/RootingAPI.h"
#include "mozilla/DOMEventTargetHelper.h"
@@ -16,7 +16,6 @@ class nsPIDOMWindow;
namespace mozilla {
namespace dom {
namespace indexedDB {
class IDBWrapperCache : public DOMEventTargetHelper
{
@@ -50,8 +49,7 @@ protected:
virtual ~IDBWrapperCache();
};
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_indexeddb_idbwrappercache_h__
#endif // mozilla_dom_idbwrappercache_h__
+5 -5
View File
@@ -4,8 +4,8 @@
* 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_indexeddb_indexeddatabase_h__
#define mozilla_dom_indexeddb_indexeddatabase_h__
#ifndef mozilla_dom_indexeddatabase_h__
#define mozilla_dom_indexeddatabase_h__
#include "js/StructuredClone.h"
#include "nsAutoPtr.h"
@@ -16,12 +16,12 @@ namespace mozilla {
namespace dom {
class Blob;
class IDBDatabase;
class IDBMutableFile;
namespace indexedDB {
class FileInfo;
class IDBDatabase;
class IDBMutableFile;
class SerializedStructuredCloneReadInfo;
struct StructuredCloneFile
@@ -74,4 +74,4 @@ struct StructuredCloneReadInfo
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_indexeddb_indexeddatabase_h__
#endif // mozilla_dom_indexeddatabase_h__
+1 -1
View File
@@ -7,7 +7,7 @@
#ifndef IndexedDatabaseInlines_h
#define IndexedDatabaseInlines_h
#ifndef mozilla_dom_indexeddb_indexeddatabase_h__
#ifndef mozilla_dom_indexeddatabase_h__
#error Must include IndexedDatabase.h first
#endif
+4 -1
View File
@@ -118,6 +118,10 @@ private:
nsTArray<RefPtr<FileManager> > mDefaultStorageFileManagers;
};
} // namespace indexedDB
using namespace mozilla::dom::indexedDB;
namespace {
NS_DEFINE_IID(kIDBRequestIID, PRIVATE_IDBREQUEST_IID);
@@ -1422,6 +1426,5 @@ GetFileReferencesHelper::Run()
return NS_OK;
}
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
+9 -5
View File
@@ -4,8 +4,8 @@
* 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_indexeddb_indexeddatabasemanager_h__
#define mozilla_dom_indexeddb_indexeddatabasemanager_h__
#ifndef mozilla_dom_indexeddatabasemanager_h__
#define mozilla_dom_indexeddatabasemanager_h__
#include "nsIObserver.h"
@@ -24,17 +24,22 @@ class EventChainPostVisitor;
namespace dom {
class IDBFactory;
namespace indexedDB {
class FileManager;
class FileManagerInfo;
class IDBFactory;
} // namespace indexedDB
class IndexedDatabaseManager final
: public nsIObserver
, public nsITimerCallback
{
typedef mozilla::dom::quota::PersistenceType PersistenceType;
typedef mozilla::dom::indexedDB::FileManager FileManager;
typedef mozilla::dom::indexedDB::FileManagerInfo FileManagerInfo;
public:
enum LoggingMode
@@ -217,8 +222,7 @@ private:
static mozilla::Atomic<bool> sLowDiskSpaceMode;
};
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_indexeddb_indexeddatabasemanager_h__
#endif // mozilla_dom_indexeddatabasemanager_h__
+2 -2
View File
@@ -18,8 +18,8 @@ include "mozilla/dom/indexedDB/SerializationHelpers.h";
using struct mozilla::null_t
from "ipc/IPCMessageUtils.h";
using mozilla::dom::indexedDB::IDBTransaction::Mode
from "mozilla/dom/indexedDB/IDBTransaction.h";
using mozilla::dom::IDBTransaction::Mode
from "mozilla/dom/IDBTransaction.h";
namespace mozilla {
namespace dom {
@@ -17,8 +17,8 @@ using struct mozilla::null_t
using struct mozilla::void_t
from "ipc/IPCMessageUtils.h";
using mozilla::dom::indexedDB::IDBCursor::Direction
from "mozilla/dom/indexedDB/IDBCursor.h";
using mozilla::dom::IDBCursor::Direction
from "mozilla/dom/IDBCursor.h";
using class mozilla::dom::indexedDB::Key
from "mozilla/dom/indexedDB/Key.h";
+10 -10
View File
@@ -11,8 +11,8 @@
#include "mozilla/dom/indexedDB/Key.h"
#include "mozilla/dom/indexedDB/KeyPath.h"
#include "mozilla/dom/indexedDB/IDBCursor.h"
#include "mozilla/dom/indexedDB/IDBTransaction.h"
#include "mozilla/dom/IDBCursor.h"
#include "mozilla/dom/IDBTransaction.h"
namespace IPC {
@@ -68,19 +68,19 @@ struct ParamTraits<mozilla::dom::indexedDB::KeyPath>
};
template <>
struct ParamTraits<mozilla::dom::indexedDB::IDBCursor::Direction> :
struct ParamTraits<mozilla::dom::IDBCursor::Direction> :
public ContiguousEnumSerializer<
mozilla::dom::indexedDB::IDBCursor::Direction,
mozilla::dom::indexedDB::IDBCursor::NEXT,
mozilla::dom::indexedDB::IDBCursor::DIRECTION_INVALID>
mozilla::dom::IDBCursor::Direction,
mozilla::dom::IDBCursor::NEXT,
mozilla::dom::IDBCursor::DIRECTION_INVALID>
{ };
template <>
struct ParamTraits<mozilla::dom::indexedDB::IDBTransaction::Mode> :
struct ParamTraits<mozilla::dom::IDBTransaction::Mode> :
public ContiguousEnumSerializer<
mozilla::dom::indexedDB::IDBTransaction::Mode,
mozilla::dom::indexedDB::IDBTransaction::READ_ONLY,
mozilla::dom::indexedDB::IDBTransaction::MODE_INVALID>
mozilla::dom::IDBTransaction::Mode,
mozilla::dom::IDBTransaction::READ_ONLY,
mozilla::dom::IDBTransaction::MODE_INVALID>
{ };
} // namespace IPC
+6 -3
View File
@@ -20,9 +20,7 @@ XPCSHELL_TESTS_MANIFESTS += [
if CONFIG['ENABLE_INTL_API']:
MOCHITEST_MANIFESTS += ['test/mochitest-intl-api.ini']
EXPORTS.mozilla.dom.indexedDB += [
'ActorsParent.h',
'FileSnapshot.h',
EXPORTS.mozilla.dom += [
'IDBCursor.h',
'IDBDatabase.h',
'IDBEvents.h',
@@ -38,6 +36,11 @@ EXPORTS.mozilla.dom.indexedDB += [
'IDBWrapperCache.h',
'IndexedDatabase.h',
'IndexedDatabaseManager.h',
]
EXPORTS.mozilla.dom.indexedDB += [
'ActorsParent.h',
'FileSnapshot.h',
'Key.h',
'KeyPath.h',
'SerializationHelpers.h',
+1 -1
View File
@@ -24,7 +24,7 @@
#include "mozilla/dom/PBlobStreamChild.h"
#include "mozilla/dom/PBlobStreamParent.h"
#include "mozilla/dom/indexedDB/FileSnapshot.h"
#include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
#include "mozilla/dom/IndexedDatabaseManager.h"
#include "mozilla/ipc/InputStreamUtils.h"
#include "mozilla/ipc/PBackgroundChild.h"
#include "mozilla/ipc/PBackgroundParent.h"
+1 -1
View File
@@ -60,7 +60,7 @@
#include "mozilla/dom/cellbroadcast/CellBroadcastParent.h"
#include "mozilla/dom/devicestorage/DeviceStorageRequestParent.h"
#include "mozilla/dom/icc/IccParent.h"
#include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
#include "mozilla/dom/IndexedDatabaseManager.h"
#include "mozilla/dom/mobileconnection/MobileConnectionParent.h"
#include "mozilla/dom/mobilemessage/SmsParent.h"
#include "mozilla/dom/power/PowerManagerService.h"
+10 -3
View File
@@ -13,6 +13,7 @@ support-files =
NetworkPreparationChromeScript.js
blacksilence.js
turnConfig.js
sdpUtils.js
[test_dataChannel_basicAudio.html]
skip-if = toolkit == 'gonk' || buildapp == 'mulet' # Bug 962984 for debug, bug 963244 for opt
@@ -61,12 +62,18 @@ skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g(Bug 1021776, too --ing
[test_peerConnection_addIceCandidate.html]
[test_peerConnection_basicAudio.html]
skip-if = toolkit == 'gonk' # B2G emulator is too slow to handle a two-way audio call reliably
[test_peerConnection_basicAudioRequireEOC.html]
skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g (Bug 1059867)
[test_peerConnection_basicAudioVideo.html]
skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
skip-if = toolkit == 'gonk' || buildapp == 'mulet' || (android_version == '18' && debug) # b2g(Bug 960442, video support for WebRTC is disabled on b2g), android(Bug 1189784, timeouts on 4.3 emulator)
[test_peerConnection_basicAudioVideoCombined.html]
skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
skip-if = toolkit == 'gonk' || buildapp == 'mulet' || (android_version == '18' && debug) # b2g(Bug 960442, video support for WebRTC is disabled on b2g), android(Bug 1189784, timeouts on 4.3 emulator)
[test_peerConnection_basicAudioVideoNoBundle.html]
skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
skip-if = toolkit == 'gonk' || buildapp == 'mulet' || (android_version == '18' && debug) # b2g(Bug 960442, video support for WebRTC is disabled on b2g), android(Bug 1189784, timeouts on 4.3 emulator)
[test_peerConnection_basicAudioVideoNoBundleNoRtcpMux.html]
skip-if = toolkit == 'gonk' || buildapp == 'mulet' || android_version == '18' # b2g(Bug 960442, video support for WebRTC is disabled on b2g), android(Bug 1189784, timeouts on 4.3 emulator)
[test_peerConnection_basicAudioVideoNoRtcpMux.html]
skip-if = toolkit == 'gonk' || buildapp == 'mulet' || android_version == '18' # b2g(Bug 960442, video support for WebRTC is disabled on b2g), android(Bug 1189784, timeouts on 4.3 emulator)
[test_peerConnection_basicVideo.html]
skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
[test_peerConnection_basicScreenshare.html]
+93 -127
View File
@@ -99,19 +99,6 @@ MediaElementChecker.prototype = {
}
};
// Also remove mode 0 if it's offered
// Note, we don't bother removing the fmtp lines, which makes a good test
// for some SDP parsing issues.
function removeVP8(sdp) {
var updated_sdp = sdp.replace("a=rtpmap:120 VP8/90000\r\n","");
updated_sdp = updated_sdp.replace("RTP/SAVPF 120 126 97\r\n","RTP/SAVPF 126 97\r\n");
updated_sdp = updated_sdp.replace("RTP/SAVPF 120 126\r\n","RTP/SAVPF 126\r\n");
updated_sdp = updated_sdp.replace("a=rtcp-fb:120 nack\r\n","");
updated_sdp = updated_sdp.replace("a=rtcp-fb:120 nack pli\r\n","");
updated_sdp = updated_sdp.replace("a=rtcp-fb:120 ccm fir\r\n","");
return updated_sdp;
}
var makeDefaultCommands = () => {
return [].concat(commandsPeerConnectionInitial,
commandsGetUserMedia,
@@ -143,6 +130,10 @@ function PeerConnectionTest(options) {
options.is_local = "is_local" in options ? options.is_local : true;
options.is_remote = "is_remote" in options ? options.is_remote : true;
options.h264 = "h264" in options ? options.h264 : false;
options.bundle = "bundle" in options ? options.bundle : true;
options.rtcpmux = "rtcpmux" in options ? options.rtcpmux : true;
if (typeof turnServers !== "undefined") {
if ((!options.turn_disabled_local) && (turnServers.local)) {
if (!options.hasOwnProperty("config_local")) {
@@ -162,26 +153,24 @@ function PeerConnectionTest(options) {
}
}
if (options.is_local)
this.pcLocal = new PeerConnectionWrapper('pcLocal', options.config_local, options.h264);
else
if (options.is_local) {
this.pcLocal = new PeerConnectionWrapper('pcLocal', options.config_local);
} else {
this.pcLocal = null;
}
if (options.is_remote)
this.pcRemote = new PeerConnectionWrapper('pcRemote', options.config_remote || options.config_local, options.h264);
else
if (options.is_remote) {
this.pcRemote = new PeerConnectionWrapper('pcRemote', options.config_remote || options.config_local);
} else {
this.pcRemote = null;
}
this.steeplechase = this.pcLocal === null || this.pcRemote === null;
options.steeplechase = !options.is_local || !options.is_remote;
// Create command chain instance and assign default commands
this.chain = new CommandChain(this, options.commands);
if (!options.is_local) {
this.chain.filterOut(/^PC_LOCAL/);
}
if (!options.is_remote) {
this.chain.filterOut(/^PC_REMOTE/);
}
this.testOptions = options;
}
/** TODO: consider removing this dependency on timeouts */
@@ -406,6 +395,14 @@ function(peer, desc, stateExpected) {
peer.setLocalDescDate = new Date();
});
peer.endOfTrickleSdp = peer.endOfTrickleIce.then(() => {
if (this.testOptions.steeplechase) {
send_message({"type": "end_of_trickle_ice"});
}
return peer._pc.localDescription;
})
.catch(e => ok(false, "Sending EOC message failed: " + e));
return Promise.all([eventFired, stateChanged]);
};
@@ -470,10 +467,41 @@ function(peer, desc, stateExpected) {
return Promise.all([eventFired, stateChanged]);
};
/**
* Adds and removes steps to/from the execution chain based on the configured
* testOptions.
*/
PeerConnectionTest.prototype.updateChainSteps = function() {
if (this.testOptions.h264) {
this.chain.insertAfterEach(
'PC_LOCAL_CREATE_OFFER',
[PC_LOCAL_REMOVE_VP8_FROM_OFFER]);
}
if (!this.testOptions.bundle) {
this.chain.insertAfterEach(
'PC_LOCAL_CREATE_OFFER',
[PC_LOCAL_REMOVE_BUNDLE_FROM_OFFER]);
}
if (!this.testOptions.rtcpmux) {
this.chain.insertAfterEach(
'PC_LOCAL_CREATE_OFFER',
[PC_LOCAL_REMOVE_RTCPMUX_FROM_OFFER]);
}
if (!this.testOptions.is_local) {
this.chain.filterOut(/^PC_LOCAL/);
}
if (!this.testOptions.is_remote) {
this.chain.filterOut(/^PC_REMOTE/);
}
};
/**
* Start running the tests as assigned to the command chain.
*/
PeerConnectionTest.prototype.run = function() {
/* We have to modify the chain here to allow tests which modify the default
* test chain instantiating a PeerConnectionTest() */
this.updateChainSteps();
return this.chain.execute()
.then(() => this.close())
.then(() => {
@@ -725,7 +753,7 @@ DataChannelWrapper.prototype = {
* @param {object} configuration
* Configuration for the peer connection instance
*/
function PeerConnectionWrapper(label, configuration, h264) {
function PeerConnectionWrapper(label, configuration) {
this.configuration = configuration;
if (configuration && configuration.label_suffix) {
label = label + "_" + configuration.label_suffix;
@@ -754,8 +782,6 @@ function PeerConnectionWrapper(label, configuration, h264) {
this.iceCheckingRestartExpected = false;
this.h264 = typeof h264 !== "undefined" ? true : false;
info("Creating " + this);
this._pc = new RTCPeerConnection(this.configuration);
@@ -995,10 +1021,6 @@ PeerConnectionWrapper.prototype = {
info("Got offer: " + JSON.stringify(offer));
// note: this might get updated through ICE gathering
this._latest_offer = offer;
if (this.h264) {
isnot(offer.sdp.search("H264/90000"), -1, "H.264 should be present in the SDP offer");
offer.sdp = removeVP8(offer.sdp);
}
return offer;
});
},
@@ -1292,18 +1314,16 @@ PeerConnectionWrapper.prototype = {
this.endOfTrickleIce = new Promise(r => resolveEndOfTrickle = r);
this.holdIceCandidates = new Promise(r => this.releaseIceCandidates = r);
this.endOfTrickleIce.then(() => {
this._pc.onicecandidate = () =>
ok(false, this.label + " received ICE candidate after end of trickle");
var localSdp = this._pc.getLocalDescription();
ok(localSdp.includes("a=end-of-candidates"));
ok(localSdp.includes("a=rtcp:"));
ok(!localSdp.includes("c=IN IP4 0.0.0.0"));
});
this._pc.onicecandidate = anEvent => {
if (!anEvent.candidate) {
this._pc.onicecandidate = () =>
ok(false, this.label + " received ICE candidate after end of trickle");
info(this.label + ": received end of trickle ICE event");
/* Bug 1193731. Accroding to WebRTC spec 4.3.1 the ICE Agent first sets
* the gathering state to completed (step 3.) before sending out the
* null newCandidate in step 4. */
todo(this._pc.iceGatheringState === 'completed',
"ICE gathering state has reached completed");
resolveEndOfTrickle(this.label);
return;
}
@@ -1312,25 +1332,19 @@ PeerConnectionWrapper.prototype = {
ok(anEvent.candidate.candidate.length > 0, "ICE candidate contains candidate");
ok(anEvent.candidate.sdpMid.length > 0, "SDP mid not empty");
// only check the m-section for the updated default addr that corresponds
// with this candidate.
var mSections = this.localDescription.sdp.split("\r\nm=");
sdputils.checkSdpCLineNotDefault(
mSections[anEvent.candidate.sdpMLineIndex+1], this.label
);
ok(typeof anEvent.candidate.sdpMLineIndex === 'number', "SDP MLine Index needs to exist");
this._local_ice_candidates.push(anEvent.candidate);
candidateHandler(this.label, anEvent.candidate);
};
},
/**
* Counts the amount of audio tracks in a given media constraint.
*
* @param constraints
* The contraint to be examined.
*/
countTracksInConstraint : function(type, constraints) {
if (!Array.isArray(constraints)) {
return 0;
}
return constraints.reduce((sum, c) => sum + (c[type] ? 1 : 0), 0);
},
checkLocalMediaTracks : function() {
var observed = {};
info(this + " Checking local tracks " + JSON.stringify(this.expectedLocalTrackInfoById));
@@ -1379,66 +1393,6 @@ PeerConnectionWrapper.prototype = {
"remote");
},
verifySdp: function(desc, expectedType, offerConstraintsList, offerOptions, isLocal) {
info("Examining this SessionDescription: " + JSON.stringify(desc));
info("offerConstraintsList: " + JSON.stringify(offerConstraintsList));
info("offerOptions: " + JSON.stringify(offerOptions));
ok(desc, "SessionDescription is not null");
is(desc.type, expectedType, "SessionDescription type is " + expectedType);
ok(desc.sdp.length > 10, "SessionDescription body length is plausible");
ok(desc.sdp.includes("a=ice-ufrag"), "ICE username is present in SDP");
ok(desc.sdp.includes("a=ice-pwd"), "ICE password is present in SDP");
ok(desc.sdp.includes("a=fingerprint"), "ICE fingerprint is present in SDP");
//TODO: update this for loopback support bug 1027350
ok(!desc.sdp.includes(LOOPBACK_ADDR), "loopback interface is absent from SDP");
var requiresTrickleIce = !desc.sdp.includes("a=candidate");
if (requiresTrickleIce) {
info("at least one ICE candidate is present in SDP");
} else {
info("No ICE candidate in SDP -> requiring trickle ICE");
}
if (isLocal) {
this.localRequiresTrickleIce = requiresTrickleIce;
} else {
this.remoteRequiresTrickleIce = requiresTrickleIce;
}
//TODO: how can we check for absence/presence of m=application?
var audioTracks =
this.countTracksInConstraint('audio', offerConstraintsList) ||
((offerOptions && offerOptions.offerToReceiveAudio) ? 1 : 0);
info("expected audio tracks: " + audioTracks);
if (audioTracks == 0) {
ok(!desc.sdp.includes("m=audio"), "audio m-line is absent from SDP");
} else {
ok(desc.sdp.includes("m=audio"), "audio m-line is present in SDP");
ok(desc.sdp.includes("a=rtpmap:109 opus/48000/2"), "OPUS codec is present in SDP");
//TODO: ideally the rtcp-mux should be for the m=audio, and not just
// anywhere in the SDP (JS SDP parser bug 1045429)
ok(desc.sdp.includes("a=rtcp-mux"), "RTCP Mux is offered in SDP");
}
var videoTracks =
this.countTracksInConstraint('video', offerConstraintsList) ||
((offerOptions && offerOptions.offerToReceiveVideo) ? 1 : 0);
info("expected video tracks: " + videoTracks);
if (videoTracks == 0) {
ok(!desc.sdp.includes("m=video"), "video m-line is absent from SDP");
} else {
ok(desc.sdp.includes("m=video"), "video m-line is present in SDP");
if (this.h264) {
ok(desc.sdp.includes("a=rtpmap:126 H264/90000"), "H.264 codec is present in SDP");
} else {
ok(desc.sdp.includes("a=rtpmap:120 VP8/90000"), "VP8 codec is present in SDP");
}
ok(desc.sdp.includes("a=rtcp-mux"), "RTCP Mux is offered in SDP");
}
},
/**
* Check that media flow is present on the given media element by waiting for
* it to reach ready state HAVE_ENOUGH_DATA and progress time further than
@@ -1763,11 +1717,11 @@ PeerConnectionWrapper.prototype = {
* The stats to check for ICE candidate pairs
* @param {object} counters
* The counters for media and data tracks based on constraints
* @param {object} answer
* The SDP answer to check for SDP bundle support
* @param {object} testOptions
* The test options object from the PeerConnectionTest
*/
checkStatsIceConnections : function(stats,
offerConstraintsList, offerOptions, answer) {
offerConstraintsList, offerOptions, testOptions) {
var numIceConnections = 0;
Object.keys(stats).forEach(key => {
if ((stats[key].type === "candidatepair") && stats[key].selected) {
@@ -1775,24 +1729,35 @@ PeerConnectionWrapper.prototype = {
}
});
info("ICE connections according to stats: " + numIceConnections);
if (answer.sdp.includes('a=group:BUNDLE')) {
is(numIceConnections, 1, "stats reports exactly 1 ICE connection");
isnot(numIceConnections, 0, "Number of ICE connections according to stats is not zero");
if (testOptions.bundle) {
if (testOptions.rtcpmux) {
is(numIceConnections, 1, "stats reports exactly 1 ICE connection");
} else {
is(numIceConnections, 2, "stats report exactly 2 ICE connections for media and RTCP");
}
} else {
// This code assumes that no media sections have been rejected due to
// codec mismatch or other unrecoverable negotiation failures.
var numAudioTracks =
this.countTracksInConstraint('audio', offerConstraintsList) ||
sdputils.countTracksInConstraint('audio', offerConstraintsList) ||
((offerOptions && offerOptions.offerToReceiveAudio) ? 1 : 0);
var numVideoTracks =
this.countTracksInConstraint('video', offerConstraintsList) ||
sdputils.countTracksInConstraint('video', offerConstraintsList) ||
((offerOptions && offerOptions.offerToReceiveVideo) ? 1 : 0);
var numDataTracks = this.dataChannels.length;
var numExpectedTransports = numAudioTracks + numVideoTracks;
if (!testOptions.rtcpmux) {
numExpectedTransports *= 2;
}
var numAudioVideoDataTracks = numAudioTracks + numVideoTracks + numDataTracks;
info("expected audio + video + data tracks: " + numAudioVideoDataTracks);
is(numAudioVideoDataTracks, numIceConnections, "stats ICE connections matches expected A/V tracks");
if (this.dataChannels.length) {
++numExpectedTransports;
}
info("expected audio + video + data transports: " + numExpectedTransports);
is(numIceConnections, numExpectedTransports, "stats ICE connections matches expected A/V transports");
}
},
@@ -1860,7 +1825,8 @@ var scriptsReady = Promise.all([
"templates.js",
"turnConfig.js",
"dataChannel.js",
"network.js"
"network.js",
"sdpUtils.js"
].map(script => {
var el = document.createElement("script");
if (typeof scriptRelativePath === 'string' && script.charAt(0) !== '/') {
+118
View File
@@ -0,0 +1,118 @@
/* 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/. */
var sdputils = {
checkSdpAfterEndOfTrickle: function(sdp, testOptions, label) {
info("EOC-SDP: " + JSON.stringify(sdp));
ok(sdp.sdp.includes("a=end-of-candidates"), label + ": SDP contains end-of-candidates");
sdputils.checkSdpCLineNotDefault(sdp.sdp, label);
if (testOptions.rtcpmux) {
ok(sdp.sdp.includes("a=rtcp-mux"), label + ": SDP contains rtcp-mux");
} else {
ok(sdp.sdp.includes("a=rtcp:"), label + ": SDP contains rtcp port");
}
},
// takes sdp in string form (or possibly a fragment, say an m-section), and
// verifies that the default 0.0.0.0 addr is not present.
checkSdpCLineNotDefault: function(sdpStr, label) {
info("CLINE-NO-DEFAULT-ADDR-SDP: " + JSON.stringify(sdpStr));
ok(!sdpStr.includes("c=IN IP4 0.0.0.0"), label + ": SDP contains non-zero IP c line");
},
// Also remove mode 0 if it's offered
// Note, we don't bother removing the fmtp lines, which makes a good test
// for some SDP parsing issues.
removeVP8: function(sdp) {
var updated_sdp = sdp.replace("a=rtpmap:120 VP8/90000\r\n","");
updated_sdp = updated_sdp.replace("RTP/SAVPF 120 126 97\r\n","RTP/SAVPF 126 97\r\n");
updated_sdp = updated_sdp.replace("RTP/SAVPF 120 126\r\n","RTP/SAVPF 126\r\n");
updated_sdp = updated_sdp.replace("a=rtcp-fb:120 nack\r\n","");
updated_sdp = updated_sdp.replace("a=rtcp-fb:120 nack pli\r\n","");
updated_sdp = updated_sdp.replace("a=rtcp-fb:120 ccm fir\r\n","");
return updated_sdp;
},
removeRtcpMux: function(sdp) {
return sdp.replace(/a=rtcp-mux\r\n/g,"");
},
removeBundle: function(sdp) {
return sdp.replace(/a=group:BUNDLE .*\r\n/g, "");
},
verifySdp: function(desc, expectedType, offerConstraintsList, offerOptions,
testOptions) {
info("Examining this SessionDescription: " + JSON.stringify(desc));
info("offerConstraintsList: " + JSON.stringify(offerConstraintsList));
info("offerOptions: " + JSON.stringify(offerOptions));
ok(desc, "SessionDescription is not null");
is(desc.type, expectedType, "SessionDescription type is " + expectedType);
ok(desc.sdp.length > 10, "SessionDescription body length is plausible");
ok(desc.sdp.includes("a=ice-ufrag"), "ICE username is present in SDP");
ok(desc.sdp.includes("a=ice-pwd"), "ICE password is present in SDP");
ok(desc.sdp.includes("a=fingerprint"), "ICE fingerprint is present in SDP");
//TODO: update this for loopback support bug 1027350
ok(!desc.sdp.includes(LOOPBACK_ADDR), "loopback interface is absent from SDP");
var requiresTrickleIce = !desc.sdp.includes("a=candidate");
if (requiresTrickleIce) {
info("at least one ICE candidate is present in SDP");
} else {
info("No ICE candidate in SDP -> requiring trickle ICE");
}
//TODO: how can we check for absence/presence of m=application?
var audioTracks =
sdputils.countTracksInConstraint('audio', offerConstraintsList) ||
((offerOptions && offerOptions.offerToReceiveAudio) ? 1 : 0);
info("expected audio tracks: " + audioTracks);
if (audioTracks == 0) {
ok(!desc.sdp.includes("m=audio"), "audio m-line is absent from SDP");
} else {
ok(desc.sdp.includes("m=audio"), "audio m-line is present in SDP");
ok(desc.sdp.includes("a=rtpmap:109 opus/48000/2"), "OPUS codec is present in SDP");
//TODO: ideally the rtcp-mux should be for the m=audio, and not just
// anywhere in the SDP (JS SDP parser bug 1045429)
is(testOptions.rtcpmux, desc.sdp.includes("a=rtcp-mux"), "RTCP Mux is offered in SDP");
}
var videoTracks =
sdputils.countTracksInConstraint('video', offerConstraintsList) ||
((offerOptions && offerOptions.offerToReceiveVideo) ? 1 : 0);
info("expected video tracks: " + videoTracks);
if (videoTracks == 0) {
ok(!desc.sdp.includes("m=video"), "video m-line is absent from SDP");
} else {
ok(desc.sdp.includes("m=video"), "video m-line is present in SDP");
if (testOptions.h264) {
ok(desc.sdp.includes("a=rtpmap:126 H264/90000"), "H.264 codec is present in SDP");
} else {
ok(desc.sdp.includes("a=rtpmap:120 VP8/90000"), "VP8 codec is present in SDP");
}
is(testOptions.rtcpmux, desc.sdp.includes("a=rtcp-mux"), "RTCP Mux is offered in SDP");
}
return requiresTrickleIce;
},
/**
* Counts the amount of audio tracks in a given media constraint.
*
* @param constraints
* The contraint to be examined.
*/
countTracksInConstraint: function(type, constraints) {
if (!Array.isArray(constraints)) {
return 0;
}
return constraints.reduce((sum, c) => sum + (c[type] ? 1 : 0), 0);
},
};
+50 -72
View File
@@ -208,20 +208,10 @@ var commandsGetUserMedia = [
var commandsPeerConnectionOfferAnswer = [
function PC_LOCAL_SETUP_ICE_HANDLER(test) {
test.pcLocal.setupIceCandidateHandler(test);
if (test.steeplechase) {
test.pcLocal.endOfTrickleIce.then(() => {
send_message({"type": "end_of_trickle_ice"});
});
}
},
function PC_REMOTE_SETUP_ICE_HANDLER(test) {
test.pcRemote.setupIceCandidateHandler(test);
if (test.steeplechase) {
test.pcRemote.endOfTrickleIce.then(() => {
send_message({"type": "end_of_trickle_ice"});
});
}
},
function PC_LOCAL_STEEPLECHASE_SIGNAL_EXPECTED_LOCAL_TRACKS(test) {
@@ -316,15 +306,17 @@ var commandsPeerConnectionOfferAnswer = [
},
function PC_LOCAL_SANE_LOCAL_SDP(test) {
test.pcLocal.verifySdp(test._local_offer, "offer",
test._offer_constraints, test._offer_options,
true);
test.pcLocal.localRequiresTrickleIce =
sdputils.verifySdp(test._local_offer, "offer",
test._offer_constraints, test._offer_options,
test.testOptions);
},
function PC_REMOTE_SANE_REMOTE_SDP(test) {
test.pcRemote.verifySdp(test._local_offer, "offer",
test._offer_constraints, test._offer_options,
false);
test.pcRemote.remoteRequiresTrickleIce =
sdputils.verifySdp(test._local_offer, "offer",
test._offer_constraints, test._offer_options,
test.testOptions);
},
function PC_REMOTE_CREATE_ANSWER(test) {
@@ -342,46 +334,6 @@ var commandsPeerConnectionOfferAnswer = [
});
},
function PC_REMOTE_CHECK_FOR_DUPLICATED_PORTS_IN_SDP(test) {
var re = /a=candidate.* (UDP|TCP) [\d]+ ([\d\.]+) ([\d]+) typ host/g;
var _sdpCandidatesIntoArray = sdp => {
var regexArray = [];
var resultArray = [];
while ((regexArray = re.exec(sdp)) !== null) {
info("regexArray: " + regexArray);
if ((regexArray[1] === "TCP") && (regexArray[3] === "9")) {
// As both sides can advertise TCP active connection on port 9 lets
// ignore them all together
info("Ignoring TCP candidate on port 9");
continue;
}
var triple = regexArray[1] + ":" + regexArray[2] + ":" + regexArray[3];
info("triple: " + triple);
if (resultArray.indexOf(triple) !== -1) {
dump("SDP: " + sdp.replace(/[\r]/g, '') + "\n");
ok(false, "This Transport:IP:Port " + triple + " appears twice in the SDP above!");
}
resultArray.push(triple);
}
return resultArray;
};
var offerTriples = _sdpCandidatesIntoArray(test._local_offer.sdp);
info("Offer ICE host candidates: " + JSON.stringify(offerTriples));
var answerTriples = _sdpCandidatesIntoArray(test.originalAnswer.sdp);
info("Answer ICE host candidates: " + JSON.stringify(answerTriples));
offerTriples.forEach(o => {
if (answerTriples.indexOf(o) !== -1) {
dump("SDP offer: " + test._local_offer.sdp.replace(/[\r]/g, '') + "\n");
dump("SDP answer: " + test.originalAnswer.sdp.replace(/[\r]/g, '') + "\n");
ok(false, "This IP:Port " + o + " appears in SDP offer and answer!");
}
});
},
function PC_REMOTE_SET_LOCAL_DESCRIPTION(test) {
return test.setLocalDescription(test.pcRemote, test.originalAnswer, STABLE)
.then(() => {
@@ -412,14 +364,16 @@ var commandsPeerConnectionOfferAnswer = [
});
},
function PC_REMOTE_SANE_LOCAL_SDP(test) {
test.pcRemote.verifySdp(test._remote_answer, "answer",
test._offer_constraints, test._offer_options,
true);
test.pcRemote.localRequiresTrickleIce =
sdputils.verifySdp(test._remote_answer, "answer",
test._offer_constraints, test._offer_options,
test.testOptions);
},
function PC_LOCAL_SANE_REMOTE_SDP(test) {
test.pcLocal.verifySdp(test._remote_answer, "answer",
test._offer_constraints, test._offer_options,
false);
test.pcLocal.remoteRequiresTrickleIce =
sdputils.verifySdp(test._remote_answer, "answer",
test._offer_constraints, test._offer_options,
test.testOptions);
},
function PC_LOCAL_WAIT_FOR_ICE_CONNECTED(test) {
@@ -483,7 +437,7 @@ var commandsPeerConnectionOfferAnswer = [
test.pcLocal.checkStatsIceConnections(stats,
test._offer_constraints,
test._offer_options,
test._remote_answer);
test.testOptions);
});
},
@@ -492,7 +446,7 @@ var commandsPeerConnectionOfferAnswer = [
test.pcRemote.checkStatsIceConnections(stats,
test._offer_constraints,
test._offer_options,
test.originalAnswer);
test.testOptions);
});
},
@@ -509,22 +463,46 @@ var commandsPeerConnectionOfferAnswer = [
function PC_REMOTE_CHECK_STATS(test) {
return checkAllTrackStats(test.pcRemote);
},
function PC_LOCAL_WAIT_FOR_END_OF_TRICKLE(test) {
return test.pcLocal.endOfTrickleIce;
function PC_LOCAL_VERIFY_SDP_AFTER_END_OF_TRICKLE(test) {
/* In case the endOfTrickleSdp promise is resolved already it will win the
* race because it gets evaluated first. But if endOfTrickleSdp is still
* pending the rejection will win the race. */
return Promise.race([
test.pcLocal.endOfTrickleSdp,
Promise.reject("No SDP")
])
.then(sdp => sdputils.checkSdpAfterEndOfTrickle(sdp, test.testOptions, test.pcLocal.label),
() => info("pcLocal: Gathering is not complete yet, skipping post-gathering SDP check"));
},
function PC_REMOTE_WAIT_FOR_END_OF_TRICKLE(test) {
return test.pcRemote.endOfTrickleIce;
function PC_REMOTE_VERIFY_SDP_AFTER_END_OF_TRICKLE(test) {
/* In case the endOfTrickleSdp promise is resolved already it will win the
* race because it gets evaluated first. But if endOfTrickleSdp is still
* pending the rejection will win the race. */
return Promise.race([
test.pcRemote.endOfTrickleSdp,
Promise.reject("No SDP")
])
.then(sdp => sdputils.checkSdpAfterEndOfTrickle(sdp, test.testOptions, test.pcRemote.label),
() => info("pcRemote: Gathering is not complete yet, skipping post-gathering SDP check"));
}
];
function PC_LOCAL_REMOVE_VP8_FROM_OFFER(test) {
isnot(test.originalOffer.sdp.search("H264/90000"), -1, "H.264 should be present in the SDP offer");
test.originalOffer.sdp = sdputils.removeVP8(test.originalOffer.sdp);
info("Updated H264 only offer: " + JSON.stringify(test.originalOffer));
};
function PC_LOCAL_REMOVE_BUNDLE_FROM_OFFER(test) {
test.originalOffer.sdp = test.originalOffer.sdp.replace(
/a=group:BUNDLE .*\r\n/g,
""
);
test.originalOffer.sdp = sdputils.removeBundle(test.originalOffer.sdp);
info("Updated no bundle offer: " + JSON.stringify(test.originalOffer));
};
function PC_LOCAL_REMOVE_RTCPMUX_FROM_OFFER(test) {
test.originalOffer.sdp = sdputils.removeRtcpMux(test.originalOffer.sdp);
info("Updated no RTCP-Mux offer: " + JSON.stringify(test.originalOffer));
};
var addRenegotiation = (chain, commands, checks) => {
chain.append(commands);
chain.append(commandsPeerConnectionOfferAnswer);
@@ -12,17 +12,11 @@
});
var test;
runNetworkTest(function () {
test = new PeerConnectionTest();
runNetworkTest(function (options) {
options = options || { };
options.bundle = false;
test = new PeerConnectionTest(options);
addInitialDataChannel(test.chain);
test.chain.insertAfter("PC_LOCAL_CREATE_OFFER", [
function PC_LOCAL_REMOVE_BUNDLE_FROM_OFFER(test) {
// Just replace a=group:BUNDLE with something that will be ignored.
test.originalOffer.sdp = test.originalOffer.sdp.replace(
"a=group:BUNDLE",
"a=foo:");
}
]);
test.setMediaConstraints([{audio: true}, {video: true}],
[{audio: true}, {video: true}]);
test.run();
@@ -13,6 +13,8 @@
var test;
runNetworkTest(function (options) {
options = options || { };
options.bundle = false;
test = new PeerConnectionTest(options);
addRenegotiation(test.chain,
commandsCreateDataChannel.concat(
@@ -27,9 +29,6 @@
),
commandsCheckDataChannel);
test.chain.insertAfterEach('PC_LOCAL_CREATE_OFFER',
PC_LOCAL_REMOVE_BUNDLE_FROM_OFFER);
// Insert before the second PC_LOCAL_CHECK_MEDIA_TRACKS
test.chain.insertBefore('PC_LOCAL_CHECK_MEDIA_TRACKS',
commandsWaitForDataChannel,
@@ -13,6 +13,8 @@
var test;
runNetworkTest(function (options) {
options = options || { };
options.bundle = false;
test = new PeerConnectionTest(options);
addRenegotiation(test.chain,
[
@@ -30,9 +32,6 @@
]
);
test.chain.insertAfterEach('PC_LOCAL_CREATE_OFFER',
PC_LOCAL_REMOVE_BUNDLE_FROM_OFFER);
// TODO(bug 1093835): figure out how to verify if media flows through the new stream
test.setMediaConstraints([{audio: true}], [{audio: true}]);
test.run();
@@ -13,6 +13,8 @@
var test;
runNetworkTest(function (options) {
options = options || { };
options.bundle = false;
test = new PeerConnectionTest(options);
addRenegotiation(test.chain,
[
@@ -30,9 +32,6 @@
]
);
test.chain.insertAfterEach('PC_LOCAL_CREATE_OFFER',
PC_LOCAL_REMOVE_BUNDLE_FROM_OFFER);
// TODO(bug 1093835): figure out how to verify if media flows through the new stream
test.setMediaConstraints([{video: true}], [{video: true}]);
test.run();
@@ -0,0 +1,35 @@
<!DOCTYPE HTML>
<html>
<head>
<script type="application/javascript" src="pc.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "1167443",
title: "Basic audio-only peer connection which waits for end-of-candidates"
});
var test;
runNetworkTest(function (options) {
test = new PeerConnectionTest(options);
test.chain.replace("PC_LOCAL_VERIFY_SDP_AFTER_END_OF_TRICKLE", [
function PC_LOCAL_REQUIRE_SDP_AFTER_END_OF_TRICKLE(test) {
return test.pcLocal.endOfTrickleSdp.then(sdp =>
sdputils.checkSdpAfterEndOfTrickle(sdp, test.testOptions, test.pcLocal.label));
}
]);
test.chain.replace("PC_REMOTE_VERIFY_SDP_AFTER_END_OF_TRICKLE", [
function PC_REMOTE_REQUIRE_SDP_AFTER_END_OF_TRICKLE(test) {
return test.pcRemote.endOfTrickleSdp.then(sdp =>
sdputils.checkSdpAfterEndOfTrickle(sdp, test.testOptions, test.pcRemote.label));
}
]);
test.setMediaConstraints([{audio: true}], [{audio: true}]);
test.run();
});
</script>
</pre>
</body>
</html>
@@ -12,10 +12,9 @@
});
runNetworkTest(options => {
options = options || { };
options.bundle = false;
var test = new PeerConnectionTest(options);
test.chain.insertAfter(
'PC_LOCAL_CREATE_OFFER',
[PC_LOCAL_REMOVE_BUNDLE_FROM_OFFER]);
test.setMediaConstraints([{audio: true}, {video: true}],
[{audio: true}, {video: true}]);
test.run();
@@ -0,0 +1,39 @@
<!DOCTYPE HTML>
<html>
<head>
<script type="application/javascript" src="pc.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "1167443",
title: "Basic audio & video call with disabled bundle and disbaled RTCP-Mux"
});
var test;
runNetworkTest(function (options) {
options = options || { };
options.bundle = false;
options.rtcpmux = false;
test = new PeerConnectionTest(options);
test.chain.replace("PC_LOCAL_VERIFY_SDP_AFTER_END_OF_TRICKLE", [
function PC_LOCAL_REQUIRE_SDP_AFTER_END_OF_TRICKLE(test) {
return test.pcLocal.endOfTrickleSdp .then(sdp =>
sdputils.checkSdpAfterEndOfTrickle(sdp, test.testOptions, test.pcLocal.label));
}
]);
test.chain.replace("PC_REMOTE_VERIFY_SDP_AFTER_END_OF_TRICKLE", [
function PC_REMOTE_REQUIRE_SDP_AFTER_END_OF_TRICKLE(test) {
return test.pcRemote.endOfTrickleSdp .then(sdp =>
sdputils.checkSdpAfterEndOfTrickle(sdp, test.testOptions, test.pcRemote.label));
}
]);
test.setMediaConstraints([{audio: true}, {video: true}],
[{audio: true}, {video: true}]);
test.run();
});
</script>
</pre>
</body>
</html>
@@ -0,0 +1,38 @@
<!DOCTYPE HTML>
<html>
<head>
<script type="application/javascript" src="pc.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "1167443",
title: "Basic audio & video call with disabled RTCP-Mux"
});
var test;
runNetworkTest(function (options) {
options = options || { };
options.rtcpmux = false;
test = new PeerConnectionTest(options);
test.chain.replace("PC_LOCAL_VERIFY_SDP_AFTER_END_OF_TRICKLE", [
function PC_LOCAL_REQUIRE_SDP_AFTER_END_OF_TRICKLE(test) {
return test.pcLocal.endOfTrickleSdp .then(sdp =>
sdputils.checkSdpAfterEndOfTrickle(sdp, test.testOptions, test.pcLocal.label));
}
]);
test.chain.replace("PC_REMOTE_VERIFY_SDP_AFTER_END_OF_TRICKLE", [
function PC_REMOTE_REQUIRE_SDP_AFTER_END_OF_TRICKLE(test) {
return test.pcRemote.endOfTrickleSdp .then(sdp =>
sdputils.checkSdpAfterEndOfTrickle(sdp, test.testOptions, test.pcRemote.label));
}
]);
test.setMediaConstraints([{audio: true}, {video: true}],
[{audio: true}, {video: true}]);
test.run();
});
</script>
</pre>
</body>
</html>
@@ -22,10 +22,7 @@ SpeechStreamListener::~SpeechStreamListener()
nsCOMPtr<nsIThread> mainThread;
NS_GetMainThread(getter_AddRefs(mainThread));
SpeechRecognition* forgottenRecognition = nullptr;
mRecognition.swap(forgottenRecognition);
NS_ProxyRelease(mainThread,
static_cast<DOMEventTargetHelper*>(forgottenRecognition));
NS_ProxyRelease(mainThread, mRecognition.forget());
}
void
+1 -1
View File
@@ -35,7 +35,7 @@ interface IDBDatabase : EventTarget {
};
partial interface IDBDatabase {
[Func="mozilla::dom::indexedDB::IndexedDatabaseManager::ExperimentalFeaturesEnabled"]
[Func="mozilla::dom::IndexedDatabaseManager::ExperimentalFeaturesEnabled"]
readonly attribute StorageType storage;
[Exposed=Window, Throws]
+8 -10
View File
@@ -32,10 +32,10 @@ interface IDBIndex {
// <null>: Not locale-aware, uses normal JS sorting.
// <string>: Sorted based on the rules of the specified locale.
// Note: never returns "auto", only the current locale.
[Func="mozilla::dom::indexedDB::IndexedDatabaseManager::ExperimentalFeaturesEnabled"]
[Func="mozilla::dom::IndexedDatabaseManager::ExperimentalFeaturesEnabled"]
readonly attribute DOMString? locale;
[Func="mozilla::dom::indexedDB::IndexedDatabaseManager::ExperimentalFeaturesEnabled"]
[Func="mozilla::dom::IndexedDatabaseManager::ExperimentalFeaturesEnabled"]
readonly attribute boolean isAutoLocale;
[Throws]
@@ -56,16 +56,14 @@ interface IDBIndex {
partial interface IDBIndex {
[Throws]
IDBRequest mozGetAll (optional any key, optional unsigned long limit);
IDBRequest mozGetAll (optional any key, [EnforceRange] optional unsigned long limit);
[Throws]
IDBRequest mozGetAllKeys (optional any key, optional unsigned long limit);
IDBRequest mozGetAllKeys (optional any key, [EnforceRange] optional unsigned long limit);
[Throws,
Func="mozilla::dom::indexedDB::IndexedDatabaseManager::ExperimentalFeaturesEnabled"]
IDBRequest getAll (optional any key, optional unsigned long limit);
[Throws]
IDBRequest getAll (optional any key, [EnforceRange] optional unsigned long limit);
[Throws,
Func="mozilla::dom::indexedDB::IndexedDatabaseManager::ExperimentalFeaturesEnabled"]
IDBRequest getAllKeys (optional any key, optional unsigned long limit);
[Throws]
IDBRequest getAllKeys (optional any key, [EnforceRange] optional unsigned long limit);
};
+1 -1
View File
@@ -30,7 +30,7 @@ interface IDBKeyRange {
};
[Exposed=(Window,Worker),
Func="mozilla::dom::indexedDB::IndexedDatabaseManager::ExperimentalFeaturesEnabled"]
Func="mozilla::dom::IndexedDatabaseManager::ExperimentalFeaturesEnabled"]
interface IDBLocaleAwareKeyRange : IDBKeyRange {
[NewObject, Throws]
static IDBLocaleAwareKeyRange bound (any lower, any upper, optional boolean lowerOpen = false, optional boolean upperOpen = false);
+6 -9
View File
@@ -63,17 +63,14 @@ interface IDBObjectStore {
partial interface IDBObjectStore {
// Success fires IDBTransactionEvent, result == array of values for given keys
[Throws]
IDBRequest mozGetAll (optional any key, optional unsigned long limit);
IDBRequest mozGetAll (optional any key, [EnforceRange] optional unsigned long limit);
[Throws,
Func="mozilla::dom::indexedDB::IndexedDatabaseManager::ExperimentalFeaturesEnabled"]
IDBRequest getAll (optional any key, optional unsigned long limit);
[Throws]
IDBRequest getAll (optional any key, [EnforceRange] optional unsigned long limit);
[Throws,
Func="mozilla::dom::indexedDB::IndexedDatabaseManager::ExperimentalFeaturesEnabled"]
IDBRequest getAllKeys (optional any key, optional unsigned long limit);
[Throws]
IDBRequest getAllKeys (optional any key, [EnforceRange] optional unsigned long limit);
[Throws,
Func="mozilla::dom::indexedDB::IndexedDatabaseManager::ExperimentalFeaturesEnabled"]
[Throws]
IDBRequest openKeyCursor (optional any range, optional IDBCursorDirection direction = "next");
};

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