mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 10:44:56 +00:00
Merge inbound to m-c. a=merge
CLOSED TREE
This commit is contained in:
commit
74f80ff51c
@ -34,7 +34,10 @@ var security = {
|
||||
|
||||
var isBroken =
|
||||
(ui.state & Components.interfaces.nsIWebProgressListener.STATE_IS_BROKEN);
|
||||
var isInsecure =
|
||||
var isMixed =
|
||||
(ui.state & (Components.interfaces.nsIWebProgressListener.STATE_LOADED_MIXED_ACTIVE_CONTENT |
|
||||
Components.interfaces.nsIWebProgressListener.STATE_LOADED_MIXED_DISPLAY_CONTENT));
|
||||
var isInsecure =
|
||||
(ui.state & Components.interfaces.nsIWebProgressListener.STATE_IS_INSECURE);
|
||||
var isEV =
|
||||
(ui.state & Components.interfaces.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL);
|
||||
@ -54,6 +57,7 @@ var security = {
|
||||
encryptionStrength : undefined,
|
||||
version: undefined,
|
||||
isBroken : isBroken,
|
||||
isMixed : isMixed,
|
||||
isEV : isEV,
|
||||
cert : cert,
|
||||
fullLocation : gWindow.location
|
||||
@ -92,6 +96,7 @@ var security = {
|
||||
encryptionStrength : 0,
|
||||
version: "",
|
||||
isBroken : isBroken,
|
||||
isMixed : isMixed,
|
||||
isEV : isEV,
|
||||
cert : null,
|
||||
fullLocation : gWindow.location
|
||||
@ -253,7 +258,14 @@ function securityOnLoad() {
|
||||
var msg2;
|
||||
|
||||
if (info.isBroken) {
|
||||
hdr = pkiBundle.getString("pageInfo_MixedContent");
|
||||
if (info.isMixed) {
|
||||
hdr = pkiBundle.getString("pageInfo_MixedContent");
|
||||
} else {
|
||||
hdr = pkiBundle.getFormattedString("pageInfo_BrokenEncryption",
|
||||
[info.encryptionAlgorithm,
|
||||
info.encryptionStrength + "",
|
||||
info.version]);
|
||||
}
|
||||
msg1 = pkiBundle.getString("pageInfo_Privacy_Broken1");
|
||||
msg2 = pkiBundle.getString("pageInfo_Privacy_None2");
|
||||
}
|
||||
|
@ -16,6 +16,12 @@ add_task(function* () {
|
||||
"rc4.example.com": "security-state-weak",
|
||||
};
|
||||
|
||||
yield new promise(resolve => {
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["security.tls.insecure_fallback_hosts", "rc4.example.com"]
|
||||
]}, resolve);
|
||||
});
|
||||
|
||||
let [tab, debuggee, monitor] = yield initNetMonitor(CUSTOM_GET_URL);
|
||||
let { $, EVENTS, NetMonitorView } = monitor.panelWin;
|
||||
let { RequestsMenu } = NetMonitorView;
|
||||
|
@ -40,9 +40,12 @@ add_task(function* () {
|
||||
let { RequestsMenu, NetworkDetails } = NetMonitorView;
|
||||
RequestsMenu.lazyUpdate = false;
|
||||
|
||||
info("Enabling SSLv3 for the test.");
|
||||
info("Enabling SSLv3 and RC4 for the test.");
|
||||
yield new promise(resolve => {
|
||||
SpecialPowers.pushPrefEnv({"set": [["security.tls.version.min", 0]]}, resolve);
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["security.tls.version.min", 0],
|
||||
["security.tls.insecure_fallback_hosts", "rc4.example.com,ssl3rc4.example.com"]
|
||||
]}, resolve);
|
||||
});
|
||||
|
||||
let cipher = $("#security-warning-cipher");
|
||||
|
@ -98,7 +98,7 @@ function _imageFromURI(doc, uri, privateMode, callback) {
|
||||
// favicon).
|
||||
let defaultURI = faviconSvc.defaultFavicon;
|
||||
if (!defaultURI.equals(uri))
|
||||
_imageFromURI(defaultURI, callback);
|
||||
_imageFromURI(doc, defaultURI, privateMode, callback);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -22,8 +22,8 @@ nsChromeRegistryContent::RegisterRemoteChrome(
|
||||
const nsACString& aLocale,
|
||||
bool aReset)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aReset || mLocale.IsEmpty(),
|
||||
"RegisterChrome twice?");
|
||||
MOZ_ASSERT(aReset || mLocale.IsEmpty(),
|
||||
"RegisterChrome twice?");
|
||||
|
||||
if (aReset) {
|
||||
mPackagesHash.Clear();
|
||||
|
@ -27,7 +27,7 @@ ComputedTimingFunction::Init(const nsTimingFunction &aFunction)
|
||||
static inline double
|
||||
StepEnd(uint32_t aSteps, double aPortion)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(0.0 <= aPortion && aPortion <= 1.0, "out of range");
|
||||
MOZ_ASSERT(0.0 <= aPortion && aPortion <= 1.0, "out of range");
|
||||
uint32_t step = uint32_t(aPortion * aSteps); // floor
|
||||
return double(step) / double(aSteps);
|
||||
}
|
||||
@ -47,7 +47,7 @@ ComputedTimingFunction::GetValue(double aPortion) const
|
||||
// really meant it.
|
||||
return 1.0 - StepEnd(mSteps, 1.0 - aPortion);
|
||||
default:
|
||||
NS_ABORT_IF_FALSE(false, "bad type");
|
||||
MOZ_ASSERT(false, "bad type");
|
||||
// fall through
|
||||
case nsTimingFunction::StepEnd:
|
||||
return StepEnd(mSteps, aPortion);
|
||||
|
@ -831,6 +831,7 @@ WebappsApplicationMgmt.prototype = {
|
||||
"Webapps:Uninstall:Return:KO",
|
||||
"Webapps:Install:Return:OK",
|
||||
"Webapps:GetNotInstalled:Return:OK",
|
||||
"Webapps:GetIcon:Return",
|
||||
"Webapps:Import:Return",
|
||||
"Webapps:ExtractManifest:Return",
|
||||
"Webapps:SetEnabled:Return"]);
|
||||
@ -896,6 +897,21 @@ WebappsApplicationMgmt.prototype = {
|
||||
return request;
|
||||
},
|
||||
|
||||
getIcon: function(aApp, aIconID, aEntryPoint) {
|
||||
return this.createPromise(function(aResolve, aReject) {
|
||||
cpmm.sendAsyncMessage("Webapps:GetIcon", {
|
||||
oid: this._id,
|
||||
manifestURL: aApp.manifestURL,
|
||||
iconID: aIconID,
|
||||
entryPoint: aEntryPoint,
|
||||
requestID: this.getPromiseResolverId({
|
||||
resolve: aResolve,
|
||||
reject: aReject
|
||||
})
|
||||
});
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
getNotInstalled: function() {
|
||||
let request = this.createRequest();
|
||||
let principal = this._window.document.nodePrincipal;
|
||||
@ -970,7 +986,8 @@ WebappsApplicationMgmt.prototype = {
|
||||
let msg = aMessage.data;
|
||||
let req;
|
||||
|
||||
if (["Webapps:Import:Return",
|
||||
if (["Webapps:GetIcon:Return",
|
||||
"Webapps:Import:Return",
|
||||
"Webapps:ExtractManifest:Return"]
|
||||
.indexOf(aMessage.name) != -1) {
|
||||
req = this.takePromiseResolver(msg.requestID);
|
||||
@ -1036,7 +1053,18 @@ WebappsApplicationMgmt.prototype = {
|
||||
this.__DOM_IMPL__.dispatchEvent(event);
|
||||
}
|
||||
break;
|
||||
case "Webapps:GetIcon:Return":
|
||||
if (msg.blob) {
|
||||
req.resolve(Cu.cloneInto(msg.blob, this._window));
|
||||
} else if (msg.error && msg.error == "NETWORK_ERROR"
|
||||
&& !this._window.navigator.onLine) {
|
||||
req.reject(new this._window.DOMError("NETWORK_OFFLINE"));
|
||||
} else {
|
||||
req.reject(new this._window.DOMError(msg.error || ""));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (aMessage.name !== "Webapps:Uninstall:Broadcast:Return:OK") {
|
||||
this.removeRequest(msg.requestID);
|
||||
}
|
||||
|
@ -224,6 +224,7 @@ this.DOMApplicationRegistry = {
|
||||
"Webapps:RegisterBEP",
|
||||
"Webapps:Export",
|
||||
"Webapps:Import",
|
||||
"Webapps:GetIcon",
|
||||
"Webapps:ExtractManifest",
|
||||
"Webapps:SetEnabled",
|
||||
"child-process-shutdown"];
|
||||
@ -650,7 +651,7 @@ this.DOMApplicationRegistry = {
|
||||
// c. for all apps in the new core registry, install them if they are not
|
||||
// yet in the current registry, and run installPermissions()
|
||||
installSystemApps: function() {
|
||||
return Task.spawn(function() {
|
||||
return Task.spawn(function*() {
|
||||
let file;
|
||||
try {
|
||||
file = FileUtils.getFile("coreAppsDir", ["webapps", "webapps.json"], false);
|
||||
@ -727,7 +728,7 @@ this.DOMApplicationRegistry = {
|
||||
},
|
||||
|
||||
loadAndUpdateApps: function() {
|
||||
return Task.spawn(function() {
|
||||
return Task.spawn(function*() {
|
||||
let runUpdate = AppsUtils.isFirstRun(Services.prefs);
|
||||
|
||||
yield this.loadCurrentRegistry();
|
||||
@ -760,13 +761,16 @@ this.DOMApplicationRegistry = {
|
||||
if (runUpdate) {
|
||||
|
||||
// Run migration before uninstall of core apps happens.
|
||||
try {
|
||||
let appMigrator = Components.classes["@mozilla.org/app-migrator;1"].createInstance(Components.interfaces.nsIObserver);
|
||||
appMigrator.observe(null, "webapps-before-update-merge", null);
|
||||
} catch(e) {
|
||||
debug("Exception running app migration: ");
|
||||
debug(e.name + " " + e.message);
|
||||
debug("Skipping app migration.");
|
||||
let appMigrator = Components.classes["@mozilla.org/app-migrator;1"];
|
||||
if (appMigrator) {
|
||||
try {
|
||||
appMigrator = appMigrator.createInstance(Components.interfaces.nsIObserver);
|
||||
appMigrator.observe(null, "webapps-before-update-merge", null);
|
||||
} catch(e) {
|
||||
debug("Exception running app migration: ");
|
||||
debug(e.name + " " + e.message);
|
||||
debug("Skipping app migration.");
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
@ -1425,6 +1429,9 @@ this.DOMApplicationRegistry = {
|
||||
case "Webapps:RegisterBEP":
|
||||
this.registerBrowserElementParentForApp(msg, mm);
|
||||
break;
|
||||
case "Webapps:GetIcon":
|
||||
this.getIcon(msg, mm);
|
||||
break;
|
||||
case "Webapps:Export":
|
||||
this.doExport(msg, mm);
|
||||
break;
|
||||
@ -2357,7 +2364,6 @@ this.DOMApplicationRegistry = {
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
updatePackagedApp: Task.async(function*(aData, aId, aApp, aNewManifest) {
|
||||
debug("updatePackagedApp");
|
||||
|
||||
@ -3035,7 +3041,7 @@ this.DOMApplicationRegistry = {
|
||||
this.webapps[id].manifestURL, jsonManifest);
|
||||
}
|
||||
|
||||
for each (let prop in ["installState", "downloadAvailable", "downloading",
|
||||
for (let prop of ["installState", "downloadAvailable", "downloading",
|
||||
"downloadSize", "readyToApplyDownload"]) {
|
||||
aData.app[prop] = appObject[prop];
|
||||
}
|
||||
@ -3348,7 +3354,6 @@ this.DOMApplicationRegistry = {
|
||||
|
||||
oldPackage = oldPackage || (hash == aOldApp.packageHash);
|
||||
|
||||
|
||||
if (oldPackage) {
|
||||
debug("package's etag or hash unchanged; sending 'applied' event");
|
||||
// The package's Etag or hash has not changed.
|
||||
@ -4281,6 +4286,74 @@ this.DOMApplicationRegistry = {
|
||||
});
|
||||
},
|
||||
|
||||
getIcon: function(aData, aMm) {
|
||||
function sendError(aError) {
|
||||
debug("getIcon error: " + aError);
|
||||
aData.error = aError;
|
||||
aMm.sendAsyncMessage("Webapps:GetIcon:Return", aData);
|
||||
}
|
||||
|
||||
let app = this.getAppByManifestURL(aData.manifestURL);
|
||||
if (!app) {
|
||||
sendError("NO_APP");
|
||||
return;
|
||||
}
|
||||
|
||||
function loadIcon(aUrl) {
|
||||
let fallbackMimeType = aUrl.indexOf('.') >= 0 ?
|
||||
"image/" + aUrl.split(".").reverse()[0] : "";
|
||||
// Set up an xhr to download a blob.
|
||||
let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
|
||||
.createInstance(Ci.nsIXMLHttpRequest);
|
||||
xhr.mozBackgroundRequest = true;
|
||||
xhr.open("GET", aUrl, true);
|
||||
xhr.responseType = "blob";
|
||||
xhr.addEventListener("load", function() {
|
||||
debug("Got http status=" + xhr.status + " for " + aUrl);
|
||||
if (xhr.status == 200) {
|
||||
let blob = xhr.response;
|
||||
// Reusing aData with sendAsyncMessage() leads to an empty blob in
|
||||
// the child.
|
||||
let payload = {
|
||||
"oid": aData.oid,
|
||||
"requestID": aData.requestID,
|
||||
"blob": blob,
|
||||
"type": xhr.getResponseHeader("Content-Type") || fallbackMimeType
|
||||
};
|
||||
aMm.sendAsyncMessage("Webapps:GetIcon:Return", payload);
|
||||
} else if (xhr.status === 0) {
|
||||
sendError("NETWORK_ERROR");
|
||||
} else {
|
||||
sendError("FETCH_ICON_FAILED");
|
||||
}
|
||||
});
|
||||
xhr.addEventListener("error", function() {
|
||||
sendError("FETCH_ICON_FAILED");
|
||||
});
|
||||
xhr.send();
|
||||
}
|
||||
|
||||
// Get the manifest, to find the icon url in the current locale.
|
||||
this.getManifestFor(aData.manifestURL, aData.entryPoint)
|
||||
.then((aManifest) => {
|
||||
if (!aManifest) {
|
||||
sendError("FETCH_ICON_FAILED");
|
||||
return;
|
||||
}
|
||||
|
||||
let manifest = new ManifestHelper(aManifest, app.origin, app.manifestURL);
|
||||
let url = manifest.iconURLForSize(aData.iconID);
|
||||
if (!url) {
|
||||
sendError("NO_ICON");
|
||||
return;
|
||||
}
|
||||
loadIcon(url);
|
||||
}).catch(() => {
|
||||
sendError("FETCH_ICON_FAILED");
|
||||
return;
|
||||
});
|
||||
},
|
||||
|
||||
getAll: function(aCallback) {
|
||||
debug("getAll");
|
||||
let apps = [];
|
||||
@ -4514,7 +4587,7 @@ this.DOMApplicationRegistry = {
|
||||
});
|
||||
},
|
||||
|
||||
getManifestFor: function(aManifestURL) {
|
||||
getManifestFor: function(aManifestURL, aEntryPoint) {
|
||||
let id = this._appIdForManifestURL(aManifestURL);
|
||||
let app = this.webapps[id];
|
||||
if (!id || (app.installState == "pending" && !app.retryingDownload)) {
|
||||
@ -4522,7 +4595,11 @@ this.DOMApplicationRegistry = {
|
||||
}
|
||||
|
||||
return this._readManifests([{ id: id }]).then((aResult) => {
|
||||
return aResult[0].manifest;
|
||||
if (aEntryPoint) {
|
||||
return aResult[0].manifest.entry_points[aEntryPoint];
|
||||
} else {
|
||||
return aResult[0].manifest;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -1,13 +1,19 @@
|
||||
{
|
||||
"name": "My W3C Web App",
|
||||
"short_name": "My App",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/favicon.ico",
|
||||
"sizes": "64x64",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"icons": {
|
||||
"15": "/tests/dom/apps/tests/icon15.png",
|
||||
"48": "/tests/dom/apps/tests/icon48.png"
|
||||
},
|
||||
"start_url": "/index.html",
|
||||
"display": "standalone"
|
||||
}
|
||||
"display": "standalone",
|
||||
"entry_points": {
|
||||
"ep1": {
|
||||
"name": "This is an entry point",
|
||||
"icons": {
|
||||
"15": "/tests/dom/apps/tests/icon15alternate.png",
|
||||
"48": "/tests/dom/apps/tests/icon48.png"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,26 @@ var gAppName = "appname";
|
||||
var gDevName = "devname";
|
||||
var gDevUrl = "http://dev.url";
|
||||
|
||||
var gIconData =
|
||||
"\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52" +
|
||||
"\x00\x00\x00\x0F\x00\x00\x00\x0F\x08\x03\x00\x00\x00\x0C\x08\x65" +
|
||||
"\x78\x00\x00\x00\x04\x67\x41\x4D\x41\x00\x00\xD6\xD8\xD4\x4F\x58" +
|
||||
"\x32\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6F\x66\x74\x77\x61\x72" +
|
||||
"\x65\x00\x41\x64\x6F\x62\x65\x20\x49\x6D\x61\x67\x65\x52\x65\x61" +
|
||||
"\x64\x79\x71\xC9\x65\x3C\x00\x00\x00\x39\x50\x4C\x54\x45\xB5\x42" +
|
||||
"\x42\xCE\x94\x94\xCE\x84\x84\x9C\x21\x21\xAD\x21\x21\xCE\x73\x73" +
|
||||
"\x9C\x10\x10\xBD\x52\x52\xEF\xD6\xD6\xB5\x63\x63\xA5\x10\x10\xB5" +
|
||||
"\x00\x00\xE7\xC6\xC6\xE7\xB5\xB5\x9C\x00\x00\x8C\x00\x00\xFF\xFF" +
|
||||
"\xFF\x7B\x00\x00\xAD\x00\x00\xEC\xAD\x83\x63\x00\x00\x00\x66\x49" +
|
||||
"\x44\x41\x54\x78\xDA\x6C\x89\x0B\x12\xC2\x40\x08\x43\xB3\xDB\x8F" +
|
||||
"\x5A\x21\x40\xEF\x7F\x58\xA1\x55\x67\xB6\xD3\xC0\x03\x42\xF0\xDE" +
|
||||
"\x87\xC2\x3E\xEA\xCE\xF3\x4B\x0D\x30\x27\xAB\xCF\x03\x9C\xFB\xA3" +
|
||||
"\xEB\xBC\x2D\xBA\xD4\x0F\x84\x97\x9E\x49\x67\xE5\x74\x87\x26\x70" +
|
||||
"\x21\x0D\x66\xAE\xB6\x26\xB5\x8D\xE5\xE5\xCF\xB4\x9E\x79\x1C\xB9" +
|
||||
"\x4C\x2E\xB0\x90\x16\x96\x84\xB6\x68\x2F\x84\x45\xF5\x0F\xC4\xA8" +
|
||||
"\xAB\xFF\x08\x30\x00\x16\x91\x0C\xDD\xAB\xF1\x05\x11\x00\x00\x00" +
|
||||
"\x00\x49\x45\x4E\x44\xAE\x42\x60\x82";
|
||||
|
||||
function handleRequest(request, response) {
|
||||
var query = getQuery(request);
|
||||
|
||||
@ -87,6 +107,9 @@ function handleRequest(request, response) {
|
||||
appName, devName, devUrl);
|
||||
addZipEntry(zipWriter, app, "index.html");
|
||||
|
||||
var iconString = gIconData;
|
||||
addZipEntry(zipWriter, iconString, "icon.png");
|
||||
|
||||
zipWriter.close();
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,9 @@
|
||||
"downloads": {}
|
||||
},
|
||||
"launch_path": "tests/dom/apps/tests/file_packaged_app.sjs",
|
||||
"icons": {
|
||||
"15": "icon.png"
|
||||
},
|
||||
"developer": {
|
||||
"name": "DEVELOPERTOKEN",
|
||||
"url": "DEVELOPERURLTOKEN"
|
||||
|
BIN
dom/apps/tests/icon15.png
Normal file
BIN
dom/apps/tests/icon15.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 281 B |
BIN
dom/apps/tests/icon15alternate.png
Normal file
BIN
dom/apps/tests/icon15alternate.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 224 B |
BIN
dom/apps/tests/icon48.png
Normal file
BIN
dom/apps/tests/icon48.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.7 KiB |
@ -29,6 +29,9 @@ support-files =
|
||||
test_packaged_app_common.js
|
||||
marketplace/*
|
||||
pkg_install_iframe.html
|
||||
icon15.png
|
||||
icon15alternate.png
|
||||
icon48.png
|
||||
|
||||
[test_app_addons.html]
|
||||
skip-if = os == "android" || toolkit == "gonk" # embed-apps doesn't work in mochitest app
|
||||
|
@ -76,6 +76,28 @@ function checkInstalledApp(aMiniManifestURL,
|
||||
};
|
||||
}
|
||||
|
||||
var gIconData =
|
||||
"\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52" +
|
||||
"\x00\x00\x00\x0F\x00\x00\x00\x0F\x08\x03\x00\x00\x00\x0C\x08\x65" +
|
||||
"\x78\x00\x00\x00\x04\x67\x41\x4D\x41\x00\x00\xD6\xD8\xD4\x4F\x58" +
|
||||
"\x32\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6F\x66\x74\x77\x61\x72" +
|
||||
"\x65\x00\x41\x64\x6F\x62\x65\x20\x49\x6D\x61\x67\x65\x52\x65\x61" +
|
||||
"\x64\x79\x71\xC9\x65\x3C\x00\x00\x00\x39\x50\x4C\x54\x45\xB5\x42" +
|
||||
"\x42\xCE\x94\x94\xCE\x84\x84\x9C\x21\x21\xAD\x21\x21\xCE\x73\x73" +
|
||||
"\x9C\x10\x10\xBD\x52\x52\xEF\xD6\xD6\xB5\x63\x63\xA5\x10\x10\xB5" +
|
||||
"\x00\x00\xE7\xC6\xC6\xE7\xB5\xB5\x9C\x00\x00\x8C\x00\x00\xFF\xFF" +
|
||||
"\xFF\x7B\x00\x00\xAD\x00\x00\xEC\xAD\x83\x63\x00\x00\x00\x66\x49" +
|
||||
"\x44\x41\x54\x78\xDA\x6C\x89\x0B\x12\xC2\x40\x08\x43\xB3\xDB\x8F" +
|
||||
"\x5A\x21\x40\xEF\x7F\x58\xA1\x55\x67\xB6\xD3\xC0\x03\x42\xF0\xDE" +
|
||||
"\x87\xC2\x3E\xEA\xCE\xF3\x4B\x0D\x30\x27\xAB\xCF\x03\x9C\xFB\xA3" +
|
||||
"\xEB\xBC\x2D\xBA\xD4\x0F\x84\x97\x9E\x49\x67\xE5\x74\x87\x26\x70" +
|
||||
"\x21\x0D\x66\xAE\xB6\x26\xB5\x8D\xE5\xE5\xCF\xB4\x9E\x79\x1C\xB9" +
|
||||
"\x4C\x2E\xB0\x90\x16\x96\x84\xB6\x68\x2F\x84\x45\xF5\x0F\xC4\xA8" +
|
||||
"\xAB\xFF\x08\x30\x00\x16\x91\x0C\xDD\xAB\xF1\x05\x11\x00\x00\x00" +
|
||||
"\x00\x49\x45\x4E\x44\xAE\x42\x60\x82";
|
||||
|
||||
var gIconSize = 15;
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.requestFlakyTimeout("untriaged");
|
||||
|
||||
@ -195,6 +217,7 @@ var steps = [
|
||||
info("== TEST == Install packaged app");
|
||||
var miniManifestURL = PackagedTestHelper.gSJS +
|
||||
"?getManifest=true";
|
||||
|
||||
navigator.mozApps.mgmt.oninstall = function(evt) {
|
||||
info("Got oninstall event");
|
||||
PackagedTestHelper.gApp = evt.application;
|
||||
@ -231,6 +254,25 @@ var steps = [
|
||||
function() {
|
||||
PackagedTestHelper.setAppVersion(3, PackagedTestHelper.next, false, true);
|
||||
},
|
||||
function() {
|
||||
info("== TEST == Get icon");
|
||||
var app = PackagedTestHelper.gApp;
|
||||
|
||||
navigator.mozApps.mgmt.getIcon(app, gIconSize).then((blob) => {
|
||||
var reader = new FileReader();
|
||||
|
||||
reader.onloadend = function() {
|
||||
var success = reader.result == gIconData;
|
||||
ok(success, "== TEST == Icon matches expected icon");
|
||||
PackagedTestHelper.next();
|
||||
}
|
||||
|
||||
reader.readAsBinaryString(blob);
|
||||
}, (err) => {
|
||||
ok(false, "Can't get icon: " + err);
|
||||
PackagedTestHelper.finish();
|
||||
});
|
||||
},
|
||||
function() {
|
||||
info("== TEST == Install packaged app with a cancel/resume");
|
||||
var miniManifestURL = PackagedTestHelper.gSJS +
|
||||
|
@ -19,6 +19,43 @@ https://bugzilla.mozilla.org/show_bug.cgi?id={1075716}
|
||||
<pre id="test">
|
||||
<script class="testbody" type="application/javascript;version=1.7">
|
||||
|
||||
var gIconData =
|
||||
"\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52" +
|
||||
"\x00\x00\x00\x0F\x00\x00\x00\x0F\x08\x03\x00\x00\x00\x0C\x08\x65" +
|
||||
"\x78\x00\x00\x00\x04\x67\x41\x4D\x41\x00\x00\xD6\xD8\xD4\x4F\x58" +
|
||||
"\x32\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6F\x66\x74\x77\x61\x72" +
|
||||
"\x65\x00\x41\x64\x6F\x62\x65\x20\x49\x6D\x61\x67\x65\x52\x65\x61" +
|
||||
"\x64\x79\x71\xC9\x65\x3C\x00\x00\x00\x39\x50\x4C\x54\x45\xB5\x42" +
|
||||
"\x42\xCE\x94\x94\xCE\x84\x84\x9C\x21\x21\xAD\x21\x21\xCE\x73\x73" +
|
||||
"\x9C\x10\x10\xBD\x52\x52\xEF\xD6\xD6\xB5\x63\x63\xA5\x10\x10\xB5" +
|
||||
"\x00\x00\xE7\xC6\xC6\xE7\xB5\xB5\x9C\x00\x00\x8C\x00\x00\xFF\xFF" +
|
||||
"\xFF\x7B\x00\x00\xAD\x00\x00\xEC\xAD\x83\x63\x00\x00\x00\x66\x49" +
|
||||
"\x44\x41\x54\x78\xDA\x6C\x89\x0B\x12\xC2\x40\x08\x43\xB3\xDB\x8F" +
|
||||
"\x5A\x21\x40\xEF\x7F\x58\xA1\x55\x67\xB6\xD3\xC0\x03\x42\xF0\xDE" +
|
||||
"\x87\xC2\x3E\xEA\xCE\xF3\x4B\x0D\x30\x27\xAB\xCF\x03\x9C\xFB\xA3" +
|
||||
"\xEB\xBC\x2D\xBA\xD4\x0F\x84\x97\x9E\x49\x67\xE5\x74\x87\x26\x70" +
|
||||
"\x21\x0D\x66\xAE\xB6\x26\xB5\x8D\xE5\xE5\xCF\xB4\x9E\x79\x1C\xB9" +
|
||||
"\x4C\x2E\xB0\x90\x16\x96\x84\xB6\x68\x2F\x84\x45\xF5\x0F\xC4\xA8" +
|
||||
"\xAB\xFF\x08\x30\x00\x16\x91\x0C\xDD\xAB\xF1\x05\x11\x00\x00\x00" +
|
||||
"\x00\x49\x45\x4E\x44\xAE\x42\x60\x82";
|
||||
|
||||
var gAlternateIconData =
|
||||
"\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52" +
|
||||
"\x00\x00\x00\x0F\x00\x00\x00\x0F\x08\x02\x00\x00\x00\xB4\xB4\x02" +
|
||||
"\x1D\x00\x00\x00\xA7\x49\x44\x41\x54\x28\x15\x63\x64\x95\x9D\xC0" +
|
||||
"\x40\x34\x60\x22\x5A\x25\x48\xE1\x50\x55\xCD\x02\xF1\xE5\xAF\x47" +
|
||||
"\xF9\xC8\xDE\x7D\x79\xE3\x86\xB8\x86\x06\x44\x64\x6F\x67\x9B\xE7" +
|
||||
"\x54\x6E\x08\x1B\xC5\x97\x0B\x7C\x5C\x6F\xEF\xDC\x06\x94\x00\x2A" +
|
||||
"\x05\xB2\x81\x08\xC8\x56\x72\x70\x82\x28\x05\x92\x50\xB3\x81\x2C" +
|
||||
"\xA0\xBA\x5B\xD7\x8F\x3C\xCF\xBF\x54\x79\xE3\x25\x84\x0D\x51\xF4" +
|
||||
"\xE7\xC3\x3B\xB8\x6A\x84\xD9\x2C\x02\x42\x40\xD1\xCF\xBF\x3F\x01" +
|
||||
"\x49\x08\x1B\xA2\x08\x85\x0D\xD7\x07\x31\xE3\xC3\xEF\xBF\x40\x11" +
|
||||
"\x64\xF3\x20\x0A\x80\x1E\xBB\x7F\xF2\x04\xD4\x25\x40\xD6\xB3\xFB" +
|
||||
"\x0F\x80\x4A\x05\x58\x99\xE1\x6C\xA0\x3A\xA0\x93\x80\xE2\x40\xC6" +
|
||||
"\xC1\x19\xD3\x1E\x5F\x3C\xCF\x38\x68\xD2\x09\x00\x73\x68\x4B\x47" +
|
||||
"\x39\xF8\xEA\x1A\x00\x00\x00\x00\x49\x45\x4E\x44\xAE\x42\x60\x82";
|
||||
|
||||
|
||||
var gGenerator = runTest();
|
||||
|
||||
function go() {
|
||||
@ -45,6 +82,20 @@ function cbError(aEvent) {
|
||||
finish();
|
||||
}
|
||||
|
||||
function iconTest(app, iconSize, entryPoint, testFunction) {
|
||||
navigator.mozApps.mgmt.getIcon(app, iconSize, entryPoint).then((blob) => {
|
||||
var reader = new FileReader();
|
||||
reader.onloadend = function() {
|
||||
testFunction(reader.result);
|
||||
continueTest();
|
||||
}
|
||||
reader.readAsBinaryString(blob);
|
||||
}, (err) => {
|
||||
ok(false, "Couldn't get icon.");
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
/**
|
||||
@ -77,6 +128,30 @@ function runTest() {
|
||||
ok(app, "App is non-null");
|
||||
is(app.manifestURL, manifestURL, "App manifest url is correct.");
|
||||
|
||||
info("Fetching 15x15 icon");
|
||||
iconTest(app, 15, undefined, (iconData) => {
|
||||
is(iconData, gIconData, "Fetches 15x15 icon successfully.")
|
||||
});
|
||||
yield undefined;
|
||||
|
||||
info("Fetching 48x48 icon");
|
||||
iconTest(app, 48, "ep1", (iconData) => {
|
||||
ok(iconData.length == 4762, "Fetches 48x48 icon successfully.")
|
||||
});
|
||||
yield undefined;
|
||||
|
||||
info("Fetching 30x30 icon");
|
||||
iconTest(app, 30, undefined, (iconData) => {
|
||||
is(iconData, gIconData, "Fetches 15x15 icon as best fit for 30x30.")
|
||||
});
|
||||
yield undefined;
|
||||
|
||||
info("Fetching entry-point icon");
|
||||
iconTest(app, 15, "ep1", (iconData) => {
|
||||
is(iconData, gAlternateIconData, "Entry-point Icon fetched successfully.")
|
||||
});
|
||||
yield undefined;
|
||||
|
||||
request = navigator.mozApps.mgmt.uninstall(app);
|
||||
request.onerror = cbError;
|
||||
request.onsuccess = continueTest;
|
||||
|
@ -42,7 +42,7 @@ private: //data
|
||||
NS_IMETHODIMP
|
||||
ArchiveRequestEvent::Run()
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mRequest, "the request is not longer valid");
|
||||
MOZ_ASSERT(mRequest, "the request is not longer valid");
|
||||
mRequest->Run();
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -48,9 +48,9 @@ Attr::Attr(nsDOMAttributeMap *aAttrMap,
|
||||
const nsAString &aValue, bool aNsAware)
|
||||
: nsIAttribute(aAttrMap, aNodeInfo, aNsAware), mValue(aValue)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mNodeInfo, "We must get a nodeinfo here!");
|
||||
NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::ATTRIBUTE_NODE,
|
||||
"Wrong nodeType");
|
||||
MOZ_ASSERT(mNodeInfo, "We must get a nodeinfo here!");
|
||||
MOZ_ASSERT(mNodeInfo->NodeType() == nsIDOMNode::ATTRIBUTE_NODE,
|
||||
"Wrong nodeType");
|
||||
|
||||
// We don't add a reference to our content. It will tell us
|
||||
// to drop our reference when it goes away.
|
||||
|
@ -19,8 +19,8 @@ class Comment MOZ_FINAL : public nsGenericDOMDataNode,
|
||||
private:
|
||||
void Init()
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::COMMENT_NODE,
|
||||
"Bad NodeType in aNodeInfo");
|
||||
MOZ_ASSERT(mNodeInfo->NodeType() == nsIDOMNode::COMMENT_NODE,
|
||||
"Bad NodeType in aNodeInfo");
|
||||
}
|
||||
|
||||
virtual ~Comment();
|
||||
|
@ -56,7 +56,7 @@ Crypto::GetRandomValues(JSContext* aCx, const ArrayBufferView& aArray,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Called on the wrong thread");
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Called on the wrong thread");
|
||||
|
||||
JS::Rooted<JSObject*> view(aCx, aArray.Obj());
|
||||
|
||||
|
@ -27,11 +27,10 @@ class DocumentFragment : public FragmentOrElement,
|
||||
private:
|
||||
void Init()
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mNodeInfo->NodeType() ==
|
||||
nsIDOMNode::DOCUMENT_FRAGMENT_NODE &&
|
||||
mNodeInfo->Equals(nsGkAtoms::documentFragmentNodeName,
|
||||
kNameSpaceID_None),
|
||||
"Bad NodeType in aNodeInfo");
|
||||
MOZ_ASSERT(mNodeInfo->NodeType() == nsIDOMNode::DOCUMENT_FRAGMENT_NODE &&
|
||||
mNodeInfo->Equals(nsGkAtoms::documentFragmentNodeName,
|
||||
kNameSpaceID_None),
|
||||
"Bad NodeType in aNodeInfo");
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -74,8 +74,8 @@ DocumentType::DocumentType(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
|
||||
mSystemId(aSystemId),
|
||||
mInternalSubset(aInternalSubset)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::DOCUMENT_TYPE_NODE,
|
||||
"Bad NodeType in aNodeInfo");
|
||||
MOZ_ASSERT(mNodeInfo->NodeType() == nsIDOMNode::DOCUMENT_TYPE_NODE,
|
||||
"Bad NodeType in aNodeInfo");
|
||||
}
|
||||
|
||||
DocumentType::~DocumentType()
|
||||
|
@ -204,9 +204,9 @@ Element::NotifyStateChange(EventStates aStates)
|
||||
void
|
||||
Element::UpdateLinkState(EventStates aState)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(!aState.HasAtLeastOneOfStates(~(NS_EVENT_STATE_VISITED |
|
||||
NS_EVENT_STATE_UNVISITED)),
|
||||
"Unexpected link state bits");
|
||||
MOZ_ASSERT(!aState.HasAtLeastOneOfStates(~(NS_EVENT_STATE_VISITED |
|
||||
NS_EVENT_STATE_UNVISITED)),
|
||||
"Unexpected link state bits");
|
||||
mState =
|
||||
(mState & ~(NS_EVENT_STATE_VISITED | NS_EVENT_STATE_UNVISITED)) |
|
||||
aState;
|
||||
|
@ -152,8 +152,8 @@ public:
|
||||
FragmentOrElement(aNodeInfo),
|
||||
mState(NS_EVENT_STATE_MOZ_READONLY)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::ELEMENT_NODE,
|
||||
"Bad NodeType in aNodeInfo");
|
||||
MOZ_ASSERT(mNodeInfo->NodeType() == nsIDOMNode::ELEMENT_NODE,
|
||||
"Bad NodeType in aNodeInfo");
|
||||
SetIsElement();
|
||||
}
|
||||
#endif // MOZILLA_INTERNAL_API
|
||||
|
@ -580,9 +580,9 @@ EventSource::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
|
||||
nsresult
|
||||
EventSource::OnRedirectVerifyCallback(nsresult aResult)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mRedirectCallback, "mRedirectCallback not set in callback");
|
||||
NS_ABORT_IF_FALSE(mNewRedirectChannel,
|
||||
"mNewRedirectChannel not set in callback");
|
||||
MOZ_ASSERT(mRedirectCallback, "mRedirectCallback not set in callback");
|
||||
MOZ_ASSERT(mNewRedirectChannel,
|
||||
"mNewRedirectChannel not set in callback");
|
||||
|
||||
NS_ENSURE_SUCCESS(aResult, aResult);
|
||||
|
||||
|
@ -29,7 +29,7 @@ Link::Link(Element *aElement)
|
||||
, mNeedsRegistration(false)
|
||||
, mRegistered(false)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mElement, "Must have an element");
|
||||
MOZ_ASSERT(mElement, "Must have an element");
|
||||
}
|
||||
|
||||
Link::~Link()
|
||||
@ -58,9 +58,9 @@ Link::SetLinkState(nsLinkState aState)
|
||||
// Per IHistory interface documentation, we are no longer registered.
|
||||
mRegistered = false;
|
||||
|
||||
NS_ABORT_IF_FALSE(LinkState() == NS_EVENT_STATE_VISITED ||
|
||||
LinkState() == NS_EVENT_STATE_UNVISITED,
|
||||
"Unexpected state obtained from LinkState()!");
|
||||
MOZ_ASSERT(LinkState() == NS_EVENT_STATE_VISITED ||
|
||||
LinkState() == NS_EVENT_STATE_UNVISITED,
|
||||
"Unexpected state obtained from LinkState()!");
|
||||
|
||||
// Tell the element to update its visited state
|
||||
mElement->UpdateState(true);
|
||||
|
@ -48,7 +48,7 @@ NodeInfo::NodeInfo(nsIAtom *aName, nsIAtom *aPrefix, int32_t aNamespaceID,
|
||||
nsNodeInfoManager *aOwnerManager)
|
||||
{
|
||||
CheckValidNodeInfo(aNodeType, aName, aNamespaceID, aExtraName);
|
||||
NS_ABORT_IF_FALSE(aOwnerManager, "Invalid aOwnerManager");
|
||||
MOZ_ASSERT(aOwnerManager, "Invalid aOwnerManager");
|
||||
|
||||
// Initialize mInner
|
||||
NS_ADDREF(mInner.mName = aName);
|
||||
@ -104,8 +104,7 @@ NodeInfo::NodeInfo(nsIAtom *aName, nsIAtom *aPrefix, int32_t aNamespaceID,
|
||||
SetDOMStringToNull(mLocalName);
|
||||
break;
|
||||
default:
|
||||
NS_ABORT_IF_FALSE(aNodeType == UINT16_MAX,
|
||||
"Unknown node type");
|
||||
MOZ_ASSERT(aNodeType == UINT16_MAX, "Unknown node type");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,42 +75,42 @@ inline void
|
||||
CheckValidNodeInfo(uint16_t aNodeType, nsIAtom *aName, int32_t aNamespaceID,
|
||||
nsIAtom* aExtraName)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aNodeType == nsIDOMNode::ELEMENT_NODE ||
|
||||
aNodeType == nsIDOMNode::ATTRIBUTE_NODE ||
|
||||
aNodeType == nsIDOMNode::TEXT_NODE ||
|
||||
aNodeType == nsIDOMNode::CDATA_SECTION_NODE ||
|
||||
aNodeType == nsIDOMNode::PROCESSING_INSTRUCTION_NODE ||
|
||||
aNodeType == nsIDOMNode::COMMENT_NODE ||
|
||||
aNodeType == nsIDOMNode::DOCUMENT_NODE ||
|
||||
aNodeType == nsIDOMNode::DOCUMENT_TYPE_NODE ||
|
||||
aNodeType == nsIDOMNode::DOCUMENT_FRAGMENT_NODE ||
|
||||
aNodeType == UINT16_MAX,
|
||||
"Invalid nodeType");
|
||||
NS_ABORT_IF_FALSE((aNodeType == nsIDOMNode::PROCESSING_INSTRUCTION_NODE ||
|
||||
aNodeType == nsIDOMNode::DOCUMENT_TYPE_NODE) ==
|
||||
!!aExtraName,
|
||||
"Supply aExtraName for and only for PIs and doctypes");
|
||||
NS_ABORT_IF_FALSE(aNodeType == nsIDOMNode::ELEMENT_NODE ||
|
||||
aNodeType == nsIDOMNode::ATTRIBUTE_NODE ||
|
||||
aNodeType == UINT16_MAX ||
|
||||
aNamespaceID == kNameSpaceID_None,
|
||||
"Only attributes and elements can be in a namespace");
|
||||
NS_ABORT_IF_FALSE(aName && aName != nsGkAtoms::_empty, "Invalid localName");
|
||||
NS_ABORT_IF_FALSE(((aNodeType == nsIDOMNode::TEXT_NODE) ==
|
||||
(aName == nsGkAtoms::textTagName)) &&
|
||||
((aNodeType == nsIDOMNode::CDATA_SECTION_NODE) ==
|
||||
(aName == nsGkAtoms::cdataTagName)) &&
|
||||
((aNodeType == nsIDOMNode::COMMENT_NODE) ==
|
||||
(aName == nsGkAtoms::commentTagName)) &&
|
||||
((aNodeType == nsIDOMNode::DOCUMENT_NODE) ==
|
||||
(aName == nsGkAtoms::documentNodeName)) &&
|
||||
((aNodeType == nsIDOMNode::DOCUMENT_FRAGMENT_NODE) ==
|
||||
(aName == nsGkAtoms::documentFragmentNodeName)) &&
|
||||
((aNodeType == nsIDOMNode::DOCUMENT_TYPE_NODE) ==
|
||||
(aName == nsGkAtoms::documentTypeNodeName)) &&
|
||||
((aNodeType == nsIDOMNode::PROCESSING_INSTRUCTION_NODE) ==
|
||||
(aName == nsGkAtoms::processingInstructionTagName)),
|
||||
"Wrong localName for nodeType");
|
||||
MOZ_ASSERT(aNodeType == nsIDOMNode::ELEMENT_NODE ||
|
||||
aNodeType == nsIDOMNode::ATTRIBUTE_NODE ||
|
||||
aNodeType == nsIDOMNode::TEXT_NODE ||
|
||||
aNodeType == nsIDOMNode::CDATA_SECTION_NODE ||
|
||||
aNodeType == nsIDOMNode::PROCESSING_INSTRUCTION_NODE ||
|
||||
aNodeType == nsIDOMNode::COMMENT_NODE ||
|
||||
aNodeType == nsIDOMNode::DOCUMENT_NODE ||
|
||||
aNodeType == nsIDOMNode::DOCUMENT_TYPE_NODE ||
|
||||
aNodeType == nsIDOMNode::DOCUMENT_FRAGMENT_NODE ||
|
||||
aNodeType == UINT16_MAX,
|
||||
"Invalid nodeType");
|
||||
MOZ_ASSERT((aNodeType == nsIDOMNode::PROCESSING_INSTRUCTION_NODE ||
|
||||
aNodeType == nsIDOMNode::DOCUMENT_TYPE_NODE) ==
|
||||
!!aExtraName,
|
||||
"Supply aExtraName for and only for PIs and doctypes");
|
||||
MOZ_ASSERT(aNodeType == nsIDOMNode::ELEMENT_NODE ||
|
||||
aNodeType == nsIDOMNode::ATTRIBUTE_NODE ||
|
||||
aNodeType == UINT16_MAX ||
|
||||
aNamespaceID == kNameSpaceID_None,
|
||||
"Only attributes and elements can be in a namespace");
|
||||
MOZ_ASSERT(aName && aName != nsGkAtoms::_empty, "Invalid localName");
|
||||
MOZ_ASSERT(((aNodeType == nsIDOMNode::TEXT_NODE) ==
|
||||
(aName == nsGkAtoms::textTagName)) &&
|
||||
((aNodeType == nsIDOMNode::CDATA_SECTION_NODE) ==
|
||||
(aName == nsGkAtoms::cdataTagName)) &&
|
||||
((aNodeType == nsIDOMNode::COMMENT_NODE) ==
|
||||
(aName == nsGkAtoms::commentTagName)) &&
|
||||
((aNodeType == nsIDOMNode::DOCUMENT_NODE) ==
|
||||
(aName == nsGkAtoms::documentNodeName)) &&
|
||||
((aNodeType == nsIDOMNode::DOCUMENT_FRAGMENT_NODE) ==
|
||||
(aName == nsGkAtoms::documentFragmentNodeName)) &&
|
||||
((aNodeType == nsIDOMNode::DOCUMENT_TYPE_NODE) ==
|
||||
(aName == nsGkAtoms::documentTypeNodeName)) &&
|
||||
((aNodeType == nsIDOMNode::PROCESSING_INSTRUCTION_NODE) ==
|
||||
(aName == nsGkAtoms::processingInstructionTagName)),
|
||||
"Wrong localName for nodeType");
|
||||
}
|
||||
|
||||
#endif /* mozilla_dom_NodeInfoInlines_h___ */
|
||||
#endif /* mozilla_dom_NodeInfoInlines_h___ */
|
||||
|
@ -78,9 +78,10 @@ TextInputProcessor::~TextInputProcessor()
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TextInputProcessor::Init(nsIDOMWindow* aWindow,
|
||||
nsITextInputProcessorCallback* aCallback,
|
||||
bool* aSucceeded)
|
||||
TextInputProcessor::BeginInputTransaction(
|
||||
nsIDOMWindow* aWindow,
|
||||
nsITextInputProcessorCallback* aCallback,
|
||||
bool* aSucceeded)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(aSucceeded, "aSucceeded must not be nullptr");
|
||||
MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
|
||||
@ -88,27 +89,29 @@ TextInputProcessor::Init(nsIDOMWindow* aWindow,
|
||||
*aSucceeded = false;
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
return InitInternal(aWindow, aCallback, false, *aSucceeded);
|
||||
return BeginInputTransactionInternal(aWindow, aCallback, false, *aSucceeded);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TextInputProcessor::InitForTests(nsIDOMWindow* aWindow,
|
||||
nsITextInputProcessorCallback* aCallback,
|
||||
uint8_t aOptionalArgc,
|
||||
bool* aSucceeded)
|
||||
TextInputProcessor::BeginInputTransactionForTests(
|
||||
nsIDOMWindow* aWindow,
|
||||
nsITextInputProcessorCallback* aCallback,
|
||||
uint8_t aOptionalArgc,
|
||||
bool* aSucceeded)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(aSucceeded, "aSucceeded must not be nullptr");
|
||||
MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
|
||||
nsITextInputProcessorCallback* callback =
|
||||
aOptionalArgc >= 1 ? aCallback : nullptr;
|
||||
return InitInternal(aWindow, callback, true, *aSucceeded);
|
||||
return BeginInputTransactionInternal(aWindow, callback, true, *aSucceeded);
|
||||
}
|
||||
|
||||
nsresult
|
||||
TextInputProcessor::InitInternal(nsIDOMWindow* aWindow,
|
||||
nsITextInputProcessorCallback* aCallback,
|
||||
bool aForTests,
|
||||
bool& aSucceeded)
|
||||
TextInputProcessor::BeginInputTransactionInternal(
|
||||
nsIDOMWindow* aWindow,
|
||||
nsITextInputProcessorCallback* aCallback,
|
||||
bool aForTests,
|
||||
bool& aSucceeded)
|
||||
{
|
||||
aSucceeded = false;
|
||||
if (NS_WARN_IF(!aWindow)) {
|
||||
@ -164,9 +167,9 @@ TextInputProcessor::InitInternal(nsIDOMWindow* aWindow,
|
||||
UnlinkFromTextEventDispatcher();
|
||||
|
||||
if (aForTests) {
|
||||
rv = dispatcher->InitForTests(this);
|
||||
rv = dispatcher->BeginInputTransactionForTests(this);
|
||||
} else {
|
||||
rv = dispatcher->Init(this);
|
||||
rv = dispatcher->BeginInputTransaction(this);
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
@ -190,7 +193,7 @@ TextInputProcessor::UnlinkFromTextEventDispatcher()
|
||||
mCallback = nullptr;
|
||||
|
||||
nsRefPtr<TextInputProcessorNotification> notification =
|
||||
new TextInputProcessorNotification("notify-detached");
|
||||
new TextInputProcessorNotification("notify-end-input-transaction");
|
||||
bool result = false;
|
||||
callback->OnNotify(this, notification, &result);
|
||||
}
|
||||
|
@ -38,10 +38,11 @@ protected:
|
||||
virtual ~TextInputProcessor();
|
||||
|
||||
private:
|
||||
nsresult InitInternal(nsIDOMWindow* aWindow,
|
||||
nsITextInputProcessorCallback* aCallback,
|
||||
bool aForTests,
|
||||
bool& aSucceeded);
|
||||
nsresult BeginInputTransactionInternal(
|
||||
nsIDOMWindow* aWindow,
|
||||
nsITextInputProcessorCallback* aCallback,
|
||||
bool aForTests,
|
||||
bool& aSucceeded);
|
||||
nsresult CommitCompositionInternal(const nsAString* aCommitString = nullptr,
|
||||
bool* aSucceeded = nullptr);
|
||||
nsresult CancelCompositionInternal();
|
||||
|
@ -1482,7 +1482,7 @@ WebSocketImpl::Init(JSContext* aCx,
|
||||
void
|
||||
WebSocketImpl::AsyncOpen(ErrorResult& aRv)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Not running on main thread");
|
||||
|
||||
nsCString asciiOrigin;
|
||||
aRv = nsContentUtils::GetASCIIOrigin(mPrincipal, asciiOrigin);
|
||||
@ -1527,7 +1527,7 @@ nsresult
|
||||
WebSocketImpl::InitializeConnection()
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
NS_ABORT_IF_FALSE(!mChannel, "mChannel should be null");
|
||||
MOZ_ASSERT(!mChannel, "mChannel should be null");
|
||||
|
||||
nsCOMPtr<nsIWebSocketChannel> wsChannel;
|
||||
nsAutoCloseWS autoClose(this);
|
||||
|
@ -1032,8 +1032,7 @@ nsAttrValue::Equals(const nsAttrValue& aOther) const
|
||||
// If that changes then we probably want to add methods to the
|
||||
// corresponding SVG types to compare their base values.
|
||||
// As a shortcut, however, we can begin by comparing the pointers.
|
||||
NS_ABORT_IF_FALSE(false, "Comparing nsAttrValues that point to SVG "
|
||||
"data");
|
||||
MOZ_ASSERT(false, "Comparing nsAttrValues that point to SVG data");
|
||||
return false;
|
||||
}
|
||||
NS_NOTREACHED("unknown type stored in MiscContainer");
|
||||
@ -1754,7 +1753,7 @@ nsAttrValue::ResetMiscAtomOrString()
|
||||
void
|
||||
nsAttrValue::SetSVGType(ValueType aType, const void* aValue,
|
||||
const nsAString* aSerialized) {
|
||||
NS_ABORT_IF_FALSE(IsSVGType(aType), "Not an SVG type");
|
||||
MOZ_ASSERT(IsSVGType(aType), "Not an SVG type");
|
||||
|
||||
MiscContainer* cont = EnsureEmptyMiscContainer();
|
||||
// All SVG types are just pointers to classes so just setting any of them
|
||||
|
@ -4277,7 +4277,7 @@ nsContentUtils::ParseFragmentXML(const nsAString& aSourceBuffer,
|
||||
// sXMLFragmentSink now owns the sink
|
||||
}
|
||||
nsCOMPtr<nsIContentSink> contentsink = do_QueryInterface(sXMLFragmentSink);
|
||||
NS_ABORT_IF_FALSE(contentsink, "Sink doesn't QI to nsIContentSink!");
|
||||
MOZ_ASSERT(contentsink, "Sink doesn't QI to nsIContentSink!");
|
||||
sXMLFragmentParser->SetContentSink(contentsink);
|
||||
|
||||
sXMLFragmentSink->SetTargetDocument(aDocument);
|
||||
|
@ -1765,7 +1765,7 @@ GetXPCProto(nsIXPConnect *aXPConnect, JSContext *cx, nsGlobalWindow *aWin,
|
||||
nsCOMPtr<nsIClassInfo> ci;
|
||||
if (aNameStruct->mType == nsGlobalNameStruct::eTypeClassConstructor) {
|
||||
int32_t id = aNameStruct->mDOMClassInfoID;
|
||||
NS_ABORT_IF_FALSE(id >= 0, "Negative DOM classinfo?!?");
|
||||
MOZ_ASSERT(id >= 0, "Negative DOM classinfo?!?");
|
||||
|
||||
nsDOMClassInfoID ci_id = (nsDOMClassInfoID)id;
|
||||
|
||||
|
@ -269,7 +269,7 @@ nsDOMDataChannel::Send(const nsAString& aData, ErrorResult& aRv)
|
||||
void
|
||||
nsDOMDataChannel::Send(File& aData, ErrorResult& aRv)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Not running on main thread");
|
||||
|
||||
nsCOMPtr<nsIInputStream> msgStream;
|
||||
nsresult rv = aData.GetInternalStream(getter_AddRefs(msgStream));
|
||||
@ -296,7 +296,7 @@ nsDOMDataChannel::Send(File& aData, ErrorResult& aRv)
|
||||
void
|
||||
nsDOMDataChannel::Send(const ArrayBuffer& aData, ErrorResult& aRv)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Not running on main thread");
|
||||
|
||||
aData.ComputeLengthAndData();
|
||||
|
||||
@ -312,7 +312,7 @@ nsDOMDataChannel::Send(const ArrayBuffer& aData, ErrorResult& aRv)
|
||||
void
|
||||
nsDOMDataChannel::Send(const ArrayBufferView& aData, ErrorResult& aRv)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Not running on main thread");
|
||||
|
||||
aData.ComputeLengthAndData();
|
||||
|
||||
|
@ -182,7 +182,7 @@ void
|
||||
nsDOMTokenList::RemoveInternal(const nsAttrValue* aAttr,
|
||||
const nsTArray<nsString>& aTokens)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aAttr, "Need an attribute");
|
||||
MOZ_ASSERT(aAttr, "Need an attribute");
|
||||
|
||||
nsAutoString input;
|
||||
aAttr->ToString(input);
|
||||
@ -204,7 +204,7 @@ nsDOMTokenList::RemoveInternal(const nsAttrValue* aAttr,
|
||||
if (iter == end) {
|
||||
// At this point we're sure the last seen token (if any) wasn't to be
|
||||
// removed. So the trailing spaces will need to be kept.
|
||||
NS_ABORT_IF_FALSE(!lastTokenRemoved, "How did this happen?");
|
||||
MOZ_ASSERT(!lastTokenRemoved, "How did this happen?");
|
||||
|
||||
output.Append(Substring(copyStart, end));
|
||||
break;
|
||||
@ -227,8 +227,8 @@ nsDOMTokenList::RemoveInternal(const nsAttrValue* aAttr,
|
||||
} else {
|
||||
|
||||
if (lastTokenRemoved && !output.IsEmpty()) {
|
||||
NS_ABORT_IF_FALSE(!nsContentUtils::IsHTMLWhitespace(
|
||||
output.Last()), "Invalid last output token");
|
||||
MOZ_ASSERT(!nsContentUtils::IsHTMLWhitespace(output.Last()),
|
||||
"Invalid last output token");
|
||||
output.Append(char16_t(' '));
|
||||
}
|
||||
lastTokenRemoved = false;
|
||||
|
@ -1716,9 +1716,9 @@ CanvasToDataSourceSurface(nsIDOMHTMLCanvasElement* aCanvas)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NS_ABORT_IF_FALSE(node->IsElement(),
|
||||
"An nsINode that implements nsIDOMHTMLCanvasElement should "
|
||||
"be an element.");
|
||||
MOZ_ASSERT(node->IsElement(),
|
||||
"An nsINode that implements nsIDOMHTMLCanvasElement should "
|
||||
"be an element.");
|
||||
nsLayoutUtils::SurfaceFromElementResult result =
|
||||
nsLayoutUtils::SurfaceFromElement(node->AsElement());
|
||||
return result.mSourceSurface->GetDataSurface();
|
||||
@ -2309,7 +2309,7 @@ nsDOMWindowUtils::GetClassName(JS::Handle<JS::Value> aObject, JSContext* aCx,
|
||||
}
|
||||
|
||||
*aName = NS_strdup(JS_GetClass(aObject.toObjectOrNull())->name);
|
||||
NS_ABORT_IF_FALSE(*aName, "NS_strdup should be infallible.");
|
||||
MOZ_ASSERT(*aName, "NS_strdup should be infallible.");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -2698,9 +2698,9 @@ nsDOMWindowUtils::ComputeAnimationDistance(nsIDOMElement* aElement,
|
||||
property = eCSSProperty_UNKNOWN;
|
||||
}
|
||||
|
||||
NS_ABORT_IF_FALSE(property == eCSSProperty_UNKNOWN ||
|
||||
!nsCSSProps::IsShorthand(property),
|
||||
"should not have shorthand");
|
||||
MOZ_ASSERT(property == eCSSProperty_UNKNOWN ||
|
||||
!nsCSSProps::IsShorthand(property),
|
||||
"should not have shorthand");
|
||||
|
||||
StyleAnimationValue v1, v2;
|
||||
if (property == eCSSProperty_UNKNOWN ||
|
||||
|
@ -1056,8 +1056,8 @@ void
|
||||
TransferZoomLevels(nsIDocument* aFromDoc,
|
||||
nsIDocument* aToDoc)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aFromDoc && aToDoc,
|
||||
"transferring zoom levels from/to null doc");
|
||||
MOZ_ASSERT(aFromDoc && aToDoc,
|
||||
"transferring zoom levels from/to null doc");
|
||||
|
||||
nsIPresShell* fromShell = aFromDoc->GetShell();
|
||||
if (!fromShell)
|
||||
@ -1083,8 +1083,8 @@ TransferZoomLevels(nsIDocument* aFromDoc,
|
||||
void
|
||||
TransferShowingState(nsIDocument* aFromDoc, nsIDocument* aToDoc)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aFromDoc && aToDoc,
|
||||
"transferring showing state from/to null doc");
|
||||
MOZ_ASSERT(aFromDoc && aToDoc,
|
||||
"transferring showing state from/to null doc");
|
||||
|
||||
if (aFromDoc->IsShowing()) {
|
||||
aToDoc->OnPageShow(true, nullptr);
|
||||
@ -1624,8 +1624,8 @@ ClearAllBoxObjects(nsIContent* aKey, nsPIBoxObject* aBoxObject, void* aUserArg)
|
||||
|
||||
nsIDocument::~nsIDocument()
|
||||
{
|
||||
NS_ABORT_IF_FALSE(PR_CLIST_IS_EMPTY(&mDOMMediaQueryLists),
|
||||
"must not have media query lists left");
|
||||
MOZ_ASSERT(PR_CLIST_IS_EMPTY(&mDOMMediaQueryLists),
|
||||
"must not have media query lists left");
|
||||
|
||||
if (mNodeInfoManager) {
|
||||
mNodeInfoManager->DropDocumentReference();
|
||||
@ -2211,8 +2211,8 @@ nsDocument::Init()
|
||||
// mNodeInfo keeps NodeInfoManager alive!
|
||||
mNodeInfo = mNodeInfoManager->GetDocumentNodeInfo();
|
||||
NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_OUT_OF_MEMORY);
|
||||
NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::DOCUMENT_NODE,
|
||||
"Bad NodeType in aNodeInfo");
|
||||
MOZ_ASSERT(mNodeInfo->NodeType() == nsIDOMNode::DOCUMENT_NODE,
|
||||
"Bad NodeType in aNodeInfo");
|
||||
|
||||
NS_ASSERTION(OwnerDoc() == this, "Our nodeinfo is busted!");
|
||||
|
||||
@ -4672,11 +4672,11 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject)
|
||||
"Script global object must be an inner window!");
|
||||
}
|
||||
#endif
|
||||
NS_ABORT_IF_FALSE(aScriptGlobalObject || !mAnimationController ||
|
||||
mAnimationController->IsPausedByType(
|
||||
nsSMILTimeContainer::PAUSE_PAGEHIDE |
|
||||
nsSMILTimeContainer::PAUSE_BEGIN),
|
||||
"Clearing window pointer while animations are unpaused");
|
||||
MOZ_ASSERT(aScriptGlobalObject || !mAnimationController ||
|
||||
mAnimationController->IsPausedByType(
|
||||
nsSMILTimeContainer::PAUSE_PAGEHIDE |
|
||||
nsSMILTimeContainer::PAUSE_BEGIN),
|
||||
"Clearing window pointer while animations are unpaused");
|
||||
|
||||
if (mScriptGlobalObject && !aScriptGlobalObject) {
|
||||
// We're detaching from the window. We need to grab a pointer to
|
||||
@ -10406,8 +10406,8 @@ nsDocument::RemoveImage(imgIRequest* aImage, uint32_t aFlags)
|
||||
// Get the old count. It should exist and be > 0.
|
||||
uint32_t count = 0;
|
||||
DebugOnly<bool> found = mImageTracker.Get(aImage, &count);
|
||||
NS_ABORT_IF_FALSE(found, "Removing image that wasn't in the tracker!");
|
||||
NS_ABORT_IF_FALSE(count > 0, "Entry in the cache tracker with count 0!");
|
||||
MOZ_ASSERT(found, "Removing image that wasn't in the tracker!");
|
||||
MOZ_ASSERT(count > 0, "Entry in the cache tracker with count 0!");
|
||||
|
||||
// We're removing, so decrement the count.
|
||||
count--;
|
||||
|
@ -90,7 +90,6 @@
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "mozilla/dom/HTMLIFrameElement.h"
|
||||
#include "mozilla/dom/SVGIFrameElement.h"
|
||||
#include "nsSandboxFlags.h"
|
||||
#include "mozilla/layers/CompositorChild.h"
|
||||
|
||||
@ -211,8 +210,7 @@ nsFrameLoader::LoadFrame()
|
||||
|
||||
nsAutoString src;
|
||||
|
||||
bool isSrcdoc = (mOwnerContent->IsHTML(nsGkAtoms::iframe) ||
|
||||
mOwnerContent->IsSVG(nsGkAtoms::iframe)) &&
|
||||
bool isSrcdoc = mOwnerContent->IsHTML(nsGkAtoms::iframe) &&
|
||||
mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::srcdoc);
|
||||
if (isSrcdoc) {
|
||||
src.AssignLiteral("about:srcdoc");
|
||||
@ -415,8 +413,7 @@ nsFrameLoader::ReallyStartLoadingInternal()
|
||||
nsCOMPtr<nsIURI> referrer;
|
||||
|
||||
nsAutoString srcdoc;
|
||||
bool isSrcdoc = (mOwnerContent->IsHTML(nsGkAtoms::iframe) ||
|
||||
mOwnerContent->IsSVG(nsGkAtoms::iframe)) &&
|
||||
bool isSrcdoc = mOwnerContent->IsHTML(nsGkAtoms::iframe) &&
|
||||
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::srcdoc,
|
||||
srcdoc);
|
||||
|
||||
@ -1657,13 +1654,8 @@ nsFrameLoader::MaybeCreateDocShell()
|
||||
// Apply sandbox flags even if our owner is not an iframe, as this copies
|
||||
// flags from our owning content's owning document.
|
||||
uint32_t sandboxFlags = 0;
|
||||
if (!mOwnerContent->IsSVG(nsGkAtoms::iframe)) {
|
||||
HTMLIFrameElement* iframe = HTMLIFrameElement::FromContent(mOwnerContent);
|
||||
if (iframe) {
|
||||
sandboxFlags = iframe->GetSandboxFlags();
|
||||
}
|
||||
} else {
|
||||
SVGIFrameElement* iframe = static_cast<SVGIFrameElement*>(mOwnerContent);
|
||||
HTMLIFrameElement* iframe = HTMLIFrameElement::FromContent(mOwnerContent);
|
||||
if (iframe) {
|
||||
sandboxFlags = iframe->GetSandboxFlags();
|
||||
}
|
||||
ApplySandboxFlags(sandboxFlags);
|
||||
@ -1679,8 +1671,7 @@ nsFrameLoader::MaybeCreateDocShell()
|
||||
nsAutoString frameName;
|
||||
|
||||
int32_t namespaceID = mOwnerContent->GetNameSpaceID();
|
||||
if ((namespaceID == kNameSpaceID_XHTML || namespaceID == kNameSpaceID_SVG)
|
||||
&& !mOwnerContent->IsInHTMLDocument()) {
|
||||
if (namespaceID == kNameSpaceID_XHTML && !mOwnerContent->IsInHTMLDocument()) {
|
||||
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::id, frameName);
|
||||
} else {
|
||||
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::name, frameName);
|
||||
|
@ -1,21 +0,0 @@
|
||||
--- nsFrameLoader.cpp
|
||||
+++ nsFrameLoader.cpp
|
||||
@@ -48,17 +48,17 @@
|
||||
#include "nsIDOMHTMLDocument.h"
|
||||
#include "nsIXULWindow.h"
|
||||
#include "nsIEditor.h"
|
||||
#include "nsIMozBrowserFrame.h"
|
||||
#include "nsIPermissionManager.h"
|
||||
#include "nsISHistory.h"
|
||||
#include "nsNullPrincipal.h"
|
||||
#include "nsIScriptError.h"
|
||||
-
|
||||
+#include "nsGlobalWindow.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsView.h"
|
||||
|
||||
#include "nsIURI.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
#include "nsGkAtoms.h"
|
@ -1537,41 +1537,42 @@ nsFrameScriptExecutor::TryCacheLoadAndCompileScript(const nsAString& aURL,
|
||||
|
||||
if (dataStringBuf && dataStringLength > 0) {
|
||||
AutoSafeJSContext cx;
|
||||
JS::Rooted<JSObject*> global(cx, mGlobal->GetJSObject());
|
||||
if (global) {
|
||||
JSAutoCompartment ac(cx, global);
|
||||
JS::CompileOptions options(cx);
|
||||
options.setFileAndLine(url.get(), 1);
|
||||
options.setNoScriptRval(true);
|
||||
JS::Rooted<JSScript*> script(cx);
|
||||
// Compile the script in the compilation scope instead of the current global
|
||||
// to avoid keeping the current compartment alive.
|
||||
JS::Rooted<JSObject*> global(cx, xpc::CompilationScope());
|
||||
|
||||
if (aRunInGlobalScope) {
|
||||
if (!JS::Compile(cx, JS::NullPtr(), options, srcBuf, &script)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// We can't clone compile-and-go scripts.
|
||||
options.setCompileAndGo(false);
|
||||
if (!JS::Compile(cx, JS::NullPtr(), options, srcBuf, &script)) {
|
||||
return;
|
||||
}
|
||||
JSAutoCompartment ac(cx, global);
|
||||
JS::CompileOptions options(cx, JSVERSION_LATEST);
|
||||
options.setFileAndLine(url.get(), 1);
|
||||
options.setNoScriptRval(true);
|
||||
JS::Rooted<JSScript*> script(cx);
|
||||
|
||||
if (aRunInGlobalScope) {
|
||||
if (!JS::Compile(cx, JS::NullPtr(), options, srcBuf, &script)) {
|
||||
return;
|
||||
}
|
||||
|
||||
aScriptp.set(script);
|
||||
|
||||
nsAutoCString scheme;
|
||||
uri->GetScheme(scheme);
|
||||
// We don't cache data: scripts!
|
||||
if (aShouldCache && !scheme.EqualsLiteral("data")) {
|
||||
nsFrameScriptObjectExecutorHolder* holder;
|
||||
|
||||
// Root the object also for caching.
|
||||
if (script) {
|
||||
holder = new nsFrameScriptObjectExecutorHolder(cx, script, aRunInGlobalScope);
|
||||
}
|
||||
sCachedScripts->Put(aURL, holder);
|
||||
} else {
|
||||
// We can't clone compile-and-go scripts.
|
||||
options.setCompileAndGo(false);
|
||||
if (!JS::Compile(cx, JS::NullPtr(), options, srcBuf, &script)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
aScriptp.set(script);
|
||||
|
||||
nsAutoCString scheme;
|
||||
uri->GetScheme(scheme);
|
||||
// We don't cache data: scripts!
|
||||
if (aShouldCache && !scheme.EqualsLiteral("data")) {
|
||||
nsFrameScriptObjectExecutorHolder* holder;
|
||||
|
||||
// Root the object also for caching.
|
||||
if (script) {
|
||||
holder = new nsFrameScriptObjectExecutorHolder(cx, script, aRunInGlobalScope);
|
||||
}
|
||||
sCachedScripts->Put(aURL, holder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,25 +42,23 @@ using namespace mozilla::dom;
|
||||
nsGenericDOMDataNode::nsGenericDOMDataNode(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
|
||||
: nsIContent(aNodeInfo)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::TEXT_NODE ||
|
||||
mNodeInfo->NodeType() == nsIDOMNode::CDATA_SECTION_NODE ||
|
||||
mNodeInfo->NodeType() == nsIDOMNode::COMMENT_NODE ||
|
||||
mNodeInfo->NodeType() ==
|
||||
nsIDOMNode::PROCESSING_INSTRUCTION_NODE ||
|
||||
mNodeInfo->NodeType() == nsIDOMNode::DOCUMENT_TYPE_NODE,
|
||||
"Bad NodeType in aNodeInfo");
|
||||
MOZ_ASSERT(mNodeInfo->NodeType() == nsIDOMNode::TEXT_NODE ||
|
||||
mNodeInfo->NodeType() == nsIDOMNode::CDATA_SECTION_NODE ||
|
||||
mNodeInfo->NodeType() == nsIDOMNode::COMMENT_NODE ||
|
||||
mNodeInfo->NodeType() == nsIDOMNode::PROCESSING_INSTRUCTION_NODE ||
|
||||
mNodeInfo->NodeType() == nsIDOMNode::DOCUMENT_TYPE_NODE,
|
||||
"Bad NodeType in aNodeInfo");
|
||||
}
|
||||
|
||||
nsGenericDOMDataNode::nsGenericDOMDataNode(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
|
||||
: nsIContent(aNodeInfo)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::TEXT_NODE ||
|
||||
mNodeInfo->NodeType() == nsIDOMNode::CDATA_SECTION_NODE ||
|
||||
mNodeInfo->NodeType() == nsIDOMNode::COMMENT_NODE ||
|
||||
mNodeInfo->NodeType() ==
|
||||
nsIDOMNode::PROCESSING_INSTRUCTION_NODE ||
|
||||
mNodeInfo->NodeType() == nsIDOMNode::DOCUMENT_TYPE_NODE,
|
||||
"Bad NodeType in aNodeInfo");
|
||||
MOZ_ASSERT(mNodeInfo->NodeType() == nsIDOMNode::TEXT_NODE ||
|
||||
mNodeInfo->NodeType() == nsIDOMNode::CDATA_SECTION_NODE ||
|
||||
mNodeInfo->NodeType() == nsIDOMNode::COMMENT_NODE ||
|
||||
mNodeInfo->NodeType() == nsIDOMNode::PROCESSING_INSTRUCTION_NODE ||
|
||||
mNodeInfo->NodeType() == nsIDOMNode::DOCUMENT_TYPE_NODE,
|
||||
"Bad NodeType in aNodeInfo");
|
||||
}
|
||||
|
||||
nsGenericDOMDataNode::~nsGenericDOMDataNode()
|
||||
|
@ -1524,7 +1524,7 @@ nsGlobalWindow::CleanUp()
|
||||
}
|
||||
|
||||
if (mCleanMessageManager) {
|
||||
NS_ABORT_IF_FALSE(mIsChrome, "only chrome should have msg manager cleaned");
|
||||
MOZ_ASSERT(mIsChrome, "only chrome should have msg manager cleaned");
|
||||
nsGlobalChromeWindow *asChrome = static_cast<nsGlobalChromeWindow*>(this);
|
||||
if (asChrome->mMessageManager) {
|
||||
static_cast<nsFrameMessageManager*>(
|
||||
@ -8119,10 +8119,10 @@ PopulateMessagePortList(MessagePortBase* aKey, MessagePortBase* aValue, void* aC
|
||||
NS_IMETHODIMP
|
||||
PostMessageEvent::Run()
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mTargetWindow->IsOuterWindow(),
|
||||
"should have been passed an outer window!");
|
||||
NS_ABORT_IF_FALSE(!mSource || mSource->IsOuterWindow(),
|
||||
"should have been passed an outer window!");
|
||||
MOZ_ASSERT(mTargetWindow->IsOuterWindow(),
|
||||
"should have been passed an outer window!");
|
||||
MOZ_ASSERT(!mSource || mSource->IsOuterWindow(),
|
||||
"should have been passed an outer window!");
|
||||
|
||||
AutoJSAPI jsapi;
|
||||
jsapi.Init();
|
||||
@ -8137,8 +8137,8 @@ PostMessageEvent::Run()
|
||||
targetWindow->IsClosedOrClosing())
|
||||
return NS_OK;
|
||||
|
||||
NS_ABORT_IF_FALSE(targetWindow->IsInnerWindow(),
|
||||
"we ordered an inner window!");
|
||||
MOZ_ASSERT(targetWindow->IsInnerWindow(),
|
||||
"we ordered an inner window!");
|
||||
JSAutoCompartment ac(cx, targetWindow->GetWrapperPreserveColor());
|
||||
|
||||
// Ensure that any origin which might have been provided is the origin of this
|
||||
@ -8235,8 +8235,8 @@ nsGlobalWindow::PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||
nsRefPtr<nsGlobalWindow> callerInnerWin = CallerInnerWindow();
|
||||
nsIPrincipal* callerPrin;
|
||||
if (callerInnerWin) {
|
||||
NS_ABORT_IF_FALSE(callerInnerWin->IsInnerWindow(),
|
||||
"should have gotten an inner window here");
|
||||
MOZ_ASSERT(callerInnerWin->IsInnerWindow(),
|
||||
"should have gotten an inner window here");
|
||||
|
||||
// Compute the caller's origin either from its principal or, in the case the
|
||||
// principal doesn't carry a URI (e.g. the system principal), the caller's
|
||||
|
@ -1718,8 +1718,8 @@ protected:
|
||||
|
||||
~nsGlobalChromeWindow()
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mCleanMessageManager,
|
||||
"chrome windows may always disconnect the msg manager");
|
||||
MOZ_ASSERT(mCleanMessageManager,
|
||||
"chrome windows may always disconnect the msg manager");
|
||||
|
||||
mGroupMessageManagers.EnumerateRead(DisconnectGroupMessageManager, nullptr);
|
||||
mGroupMessageManagers.Clear();
|
||||
|
@ -94,8 +94,7 @@ nsHostObjectURI::CloneInternal(nsSimpleURI::RefHandlingEnum aRefHandlingMode,
|
||||
#ifdef DEBUG
|
||||
nsRefPtr<nsHostObjectURI> uriCheck;
|
||||
rv = simpleClone->QueryInterface(kHOSTOBJECTURICID, getter_AddRefs(uriCheck));
|
||||
NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv) && uriCheck,
|
||||
"Unexpected!");
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv) && uriCheck);
|
||||
#endif
|
||||
|
||||
nsHostObjectURI* u = static_cast<nsHostObjectURI*>(simpleClone.get());
|
||||
|
@ -1062,7 +1062,7 @@ nsINode::IsEqualNode(nsINode* aOther)
|
||||
break;
|
||||
}
|
||||
default:
|
||||
NS_ABORT_IF_FALSE(false, "Unknown node type");
|
||||
MOZ_ASSERT(false, "Unknown node type");
|
||||
}
|
||||
|
||||
nsINode* nextNode = node1->GetFirstChild();
|
||||
@ -1357,7 +1357,7 @@ nsINode::Traverse(nsINode *tmp, nsCycleCollectionTraversalCallback &cb)
|
||||
// return early.
|
||||
nsIContent* parent = tmp->GetParent();
|
||||
if (parent && !parent->UnoptimizableCCNode() && parent->IsBlack()) {
|
||||
NS_ABORT_IF_FALSE(parent->IndexOf(tmp) >= 0, "Parent doesn't own us?");
|
||||
MOZ_ASSERT(parent->IndexOf(tmp) >= 0, "Parent doesn't own us?");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -2584,7 +2584,7 @@ FindMatchingElements(nsINode* aRoot, nsCSSSelectorList* aSelectorList, T &aList,
|
||||
struct ElementHolder {
|
||||
ElementHolder() : mElement(nullptr) {}
|
||||
void AppendElement(Element* aElement) {
|
||||
NS_ABORT_IF_FALSE(!mElement, "Should only get one element");
|
||||
MOZ_ASSERT(!mElement, "Should only get one element");
|
||||
mElement = aElement;
|
||||
}
|
||||
void SetCapacity(uint32_t aCapacity) { MOZ_CRASH("Don't call me!"); }
|
||||
|
@ -136,7 +136,7 @@ nsImageLoadingContent::Notify(imgIRequest* aRequest,
|
||||
|
||||
if (aType == imgINotificationObserver::LOAD_COMPLETE) {
|
||||
// We should definitely have a request here
|
||||
NS_ABORT_IF_FALSE(aRequest, "no request?");
|
||||
MOZ_ASSERT(aRequest, "no request?");
|
||||
|
||||
NS_PRECONDITION(aRequest == mCurrentRequest || aRequest == mPendingRequest,
|
||||
"Unknown request");
|
||||
@ -227,8 +227,8 @@ nsImageLoadingContent::OnLoadComplete(imgIRequest* aRequest, nsresult aStatus)
|
||||
if (aRequest == mPendingRequest) {
|
||||
MakePendingRequestCurrent();
|
||||
}
|
||||
NS_ABORT_IF_FALSE(aRequest == mCurrentRequest,
|
||||
"One way or another, we should be current by now");
|
||||
MOZ_ASSERT(aRequest == mCurrentRequest,
|
||||
"One way or another, we should be current by now");
|
||||
|
||||
// We just loaded all the data we're going to get. If we're visible and
|
||||
// haven't done an initial paint (*), we want to make sure the image starts
|
||||
@ -890,9 +890,9 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
|
||||
// time. It should always be the same as the principal of this node.
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsIContent> thisContent = do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
|
||||
NS_ABORT_IF_FALSE(thisContent &&
|
||||
thisContent->NodePrincipal() == aDocument->NodePrincipal(),
|
||||
"Principal mismatch?");
|
||||
MOZ_ASSERT(thisContent &&
|
||||
thisContent->NodePrincipal() == aDocument->NodePrincipal(),
|
||||
"Principal mismatch?");
|
||||
#endif
|
||||
|
||||
// Are we blocked?
|
||||
@ -1219,7 +1219,7 @@ void
|
||||
nsImageLoadingContent::SetBlockedRequest(nsIURI* aURI, int16_t aContentDecision)
|
||||
{
|
||||
// Sanity
|
||||
NS_ABORT_IF_FALSE(!NS_CP_ACCEPTED(aContentDecision), "Blocked but not?");
|
||||
MOZ_ASSERT(!NS_CP_ACCEPTED(aContentDecision), "Blocked but not?");
|
||||
|
||||
// We do some slightly illogical stuff here to maintain consistency with
|
||||
// old behavior that people probably depend on. Even in the case where the
|
||||
@ -1347,8 +1347,8 @@ nsImageLoadingContent::ClearCurrentRequest(nsresult aReason,
|
||||
mCurrentRequestFlags = 0;
|
||||
return;
|
||||
}
|
||||
NS_ABORT_IF_FALSE(!mCurrentURI,
|
||||
"Shouldn't have both mCurrentRequest and mCurrentURI!");
|
||||
MOZ_ASSERT(!mCurrentURI,
|
||||
"Shouldn't have both mCurrentRequest and mCurrentURI!");
|
||||
|
||||
// Deregister this image from the refresh driver so it no longer receives
|
||||
// notifications.
|
||||
|
@ -605,8 +605,8 @@ nsPerformance::PerformanceEntryComparator::Equals(
|
||||
const PerformanceEntry* aElem1,
|
||||
const PerformanceEntry* aElem2) const
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aElem1 && aElem2,
|
||||
"Trying to compare null performance entries");
|
||||
MOZ_ASSERT(aElem1 && aElem2,
|
||||
"Trying to compare null performance entries");
|
||||
return aElem1->StartTime() == aElem2->StartTime();
|
||||
}
|
||||
|
||||
@ -615,8 +615,8 @@ nsPerformance::PerformanceEntryComparator::LessThan(
|
||||
const PerformanceEntry* aElem1,
|
||||
const PerformanceEntry* aElem2) const
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aElem1 && aElem2,
|
||||
"Trying to compare null performance entries");
|
||||
MOZ_ASSERT(aElem1 && aElem2,
|
||||
"Trying to compare null performance entries");
|
||||
return aElem1->StartTime() < aElem2->StartTime();
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ void
|
||||
nsReferencedElement::Reset(nsIContent* aFromContent, nsIURI* aURI,
|
||||
bool aWatch, bool aReferenceImage)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aFromContent, "Reset() expects non-null content pointer");
|
||||
MOZ_ASSERT(aFromContent, "Reset() expects non-null content pointer");
|
||||
|
||||
Unlink();
|
||||
|
||||
|
@ -26,8 +26,8 @@ class nsTextNode : public mozilla::dom::Text,
|
||||
private:
|
||||
void Init()
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::TEXT_NODE,
|
||||
"Bad NodeType in aNodeInfo");
|
||||
MOZ_ASSERT(mNodeInfo->NodeType() == nsIDOMNode::TEXT_NODE,
|
||||
"Bad NodeType in aNodeInfo");
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -1103,8 +1103,8 @@ nsTreeSanitizer::SanitizeStyleSheet(const nsAString& aOriginal,
|
||||
aDocument->NodePrincipal(), 0, false);
|
||||
NS_ENSURE_SUCCESS(rv, true);
|
||||
// Mark the sheet as complete.
|
||||
NS_ABORT_IF_FALSE(!sheet->IsModified(),
|
||||
"should not get marked modified during parsing");
|
||||
MOZ_ASSERT(!sheet->IsModified(),
|
||||
"should not get marked modified during parsing");
|
||||
sheet->SetComplete();
|
||||
// Loop through all the rules found in the CSS text
|
||||
int32_t ruleCount = sheet->StyleRuleCount();
|
||||
|
@ -321,7 +321,7 @@ nsXMLHttpRequest::~nsXMLHttpRequest()
|
||||
Abort();
|
||||
}
|
||||
|
||||
NS_ABORT_IF_FALSE(!(mState & XML_HTTP_REQUEST_SYNCLOOPING), "we rather crash than hang");
|
||||
MOZ_ASSERT(!(mState & XML_HTTP_REQUEST_SYNCLOOPING), "we rather crash than hang");
|
||||
mState &= ~XML_HTTP_REQUEST_SYNCLOOPING;
|
||||
|
||||
mResultJSON.setUndefined();
|
||||
@ -1915,7 +1915,7 @@ nsXMLHttpRequest::OnDataAvailable(nsIRequest *request,
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(inStr);
|
||||
|
||||
NS_ABORT_IF_FALSE(mContext.get() == ctxt,"start context different from OnDataAvailable context");
|
||||
MOZ_ASSERT(mContext.get() == ctxt,"start context different from OnDataAvailable context");
|
||||
|
||||
mProgressSinceLastProgressEvent = true;
|
||||
|
||||
@ -3236,8 +3236,8 @@ nsXMLHttpRequest::SetTimeout(uint32_t aTimeout, ErrorResult& aRv)
|
||||
void
|
||||
nsXMLHttpRequest::StartTimeoutTimer()
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mRequestSentTime,
|
||||
"StartTimeoutTimer mustn't be called before the request was sent!");
|
||||
MOZ_ASSERT(mRequestSentTime,
|
||||
"StartTimeoutTimer mustn't be called before the request was sent!");
|
||||
if (mState & XML_HTTP_REQUEST_DONE) {
|
||||
// do nothing!
|
||||
return;
|
||||
|
@ -64,11 +64,18 @@ function make_object()
|
||||
|
||||
let for_json = { "n": 3, "a": array, "s": "hello", o: { "x": 10 } };
|
||||
|
||||
let proto = { data: 42 };
|
||||
let with_proto = Object.create(proto);
|
||||
|
||||
let with_null_proto = Object.create(null);
|
||||
|
||||
return { "data": o,
|
||||
"throwing": throwing,
|
||||
"document": content.document,
|
||||
"array": array,
|
||||
"for_json": for_json
|
||||
"for_json": for_json,
|
||||
"with_proto": with_proto,
|
||||
"with_null_proto": with_null_proto
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -126,6 +126,14 @@
|
||||
ok(j2.a[2] === 3, "JSON array index");
|
||||
ok(j2.s === "hello", "JSON string property");
|
||||
ok(j2.o.x === 10, "JSON object property");
|
||||
|
||||
let with_proto = message.objects.with_proto;
|
||||
let proto = Object.getPrototypeOf(with_proto);
|
||||
ok(proto.data == 42, "Object.getPrototypeOf works on CPOW");
|
||||
|
||||
let with_null_proto = message.objects.with_null_proto;
|
||||
proto = Object.getPrototypeOf(with_null_proto);
|
||||
ok(proto === null, "Object.getPrototypeOf works on CPOW (null proto)");
|
||||
}
|
||||
|
||||
function recvAsyncMessage(message) {
|
||||
|
@ -73,9 +73,9 @@ function createTIP()
|
||||
createInstance(Components.interfaces.nsITextInputProcessor);
|
||||
}
|
||||
|
||||
function runInitMethodTests()
|
||||
function runBeginInputTransactionMethodTests()
|
||||
{
|
||||
var description = "runInitMethodTest: ";
|
||||
var description = "runBeginInputTransactionMethodTests: ";
|
||||
input.value = "";
|
||||
input.focus();
|
||||
|
||||
@ -97,19 +97,19 @@ function runInitMethodTests()
|
||||
isnot(TIP1, TIP2,
|
||||
description + "TIP instances should be different");
|
||||
|
||||
// init() and initForTests() can take ownership if there is no composition.
|
||||
ok(TIP1.init(window, simpleCallback),
|
||||
description + "TIP1.init(window) should succeed because there is no composition");
|
||||
ok(TIP1.initForTests(window),
|
||||
description + "TIP1.initForTests(window) should succeed because there is no composition");
|
||||
ok(TIP2.init(window, simpleCallback),
|
||||
description + "TIP2.init(window) should succeed because there is no composition");
|
||||
ok(TIP2.initForTests(window),
|
||||
description + "TIP2.initForTests(window) should succeed because there is no composition");
|
||||
// beginInputTransaction() and beginInputTransactionForTests() can take ownership if there is no composition.
|
||||
ok(TIP1.beginInputTransaction(window, simpleCallback),
|
||||
description + "TIP1.beginInputTransaction(window) should succeed because there is no composition");
|
||||
ok(TIP1.beginInputTransactionForTests(window),
|
||||
description + "TIP1.beginInputTransactionForTests(window) should succeed because there is no composition");
|
||||
ok(TIP2.beginInputTransaction(window, simpleCallback),
|
||||
description + "TIP2.beginInputTransaction(window) should succeed because there is no composition");
|
||||
ok(TIP2.beginInputTransactionForTests(window),
|
||||
description + "TIP2.beginInputTransactionForTests(window) should succeed because there is no composition");
|
||||
|
||||
// Start composition with TIP1, then, other TIPs cannot take ownership during a composition.
|
||||
ok(TIP1.initForTests(window),
|
||||
description + "TIP1.initForTests() should succeed because there is no composition");
|
||||
ok(TIP1.beginInputTransactionForTests(window),
|
||||
description + "TIP1.beginInputTransactionForTests() should succeed because there is no composition");
|
||||
var composingStr = "foo";
|
||||
TIP1.setPendingCompositionString(composingStr);
|
||||
TIP1.appendClauseToPendingComposition(composingStr.length, TIP1.ATTR_RAW_CLAUSE);
|
||||
@ -120,37 +120,37 @@ function runInitMethodTests()
|
||||
|
||||
// Composing nsITextInputProcessor instance shouldn't allow initialize it again.
|
||||
try {
|
||||
TIP1.init(window, simpleCallback);
|
||||
TIP1.beginInputTransaction(window, simpleCallback);
|
||||
ok(false,
|
||||
"TIP1.init(window) should cause throwing an exception because it's composing with different purpose");
|
||||
"TIP1.beginInputTransaction(window) should cause throwing an exception because it's composing with different purpose");
|
||||
} catch (e) {
|
||||
ok(e.message.contains("NS_ERROR_ALREADY_INITIALIZED"),
|
||||
description + "TIP1.init(window) should cause throwing an exception including NS_ERROR_ALREADY_INITIALIZED because it's composing for tests");
|
||||
description + "TIP1.beginInputTransaction(window) should cause throwing an exception including NS_ERROR_ALREADY_INITIALIZED because it's composing for tests");
|
||||
}
|
||||
try {
|
||||
TIP1.initForTests(otherWindow);
|
||||
TIP1.beginInputTransactionForTests(otherWindow);
|
||||
ok(false,
|
||||
"TIP1.initForTests(otherWindow) should cause throwing an exception because it's composing on different window");
|
||||
"TIP1.beginInputTransactionForTests(otherWindow) should cause throwing an exception because it's composing on different window");
|
||||
} catch (e) {
|
||||
ok(e.message.contains("NS_ERROR_ALREADY_INITIALIZED"),
|
||||
description + "TIP1.init(otherWindow) should cause throwing an exception including NS_ERROR_ALREADY_INITIALIZED because it's composing on this window");
|
||||
description + "TIP1.beginInputTransaction(otherWindow) should cause throwing an exception including NS_ERROR_ALREADY_INITIALIZED because it's composing on this window");
|
||||
}
|
||||
ok(TIP1.initForTests(window),
|
||||
description + "TIP1.initForTests(window) should succeed because TextEventDispatcher was initialized with same purpose");
|
||||
ok(TIP1.initForTests(childWindow),
|
||||
description + "TIP1.initForTests(childWindow) should succeed because TextEventDispatcher was initialized with same purpose and is shared by window and childWindow");
|
||||
ok(!TIP2.init(window, simpleCallback),
|
||||
description + "TIP2.init(window) should not succeed because there is composition synthesized by TIP1");
|
||||
ok(!TIP2.initForTests(window),
|
||||
description + "TIP2.initForTests(window) should not succeed because there is composition synthesized by TIP1");
|
||||
ok(!TIP2.init(childWindow, simpleCallback),
|
||||
description + "TIP2.init(childWindow) should not succeed because there is composition synthesized by TIP1");
|
||||
ok(!TIP2.initForTests(childWindow),
|
||||
description + "TIP2.initForTests(childWindow) should not succeed because there is composition synthesized by TIP1");
|
||||
ok(TIP2.init(otherWindow, simpleCallback),
|
||||
description + "TIP2.init(otherWindow) should succeed because there is composition synthesized by TIP1 but it's in other window");
|
||||
ok(TIP2.initForTests(otherWindow),
|
||||
description + "TIP2.initForTests(otherWindow) should succeed because there is composition synthesized by TIP1 but it's in other window");
|
||||
ok(TIP1.beginInputTransactionForTests(window),
|
||||
description + "TIP1.beginInputTransactionForTests(window) should succeed because TextEventDispatcher was initialized with same purpose");
|
||||
ok(TIP1.beginInputTransactionForTests(childWindow),
|
||||
description + "TIP1.beginInputTransactionForTests(childWindow) should succeed because TextEventDispatcher was initialized with same purpose and is shared by window and childWindow");
|
||||
ok(!TIP2.beginInputTransaction(window, simpleCallback),
|
||||
description + "TIP2.beginInputTransaction(window) should not succeed because there is composition synthesized by TIP1");
|
||||
ok(!TIP2.beginInputTransactionForTests(window),
|
||||
description + "TIP2.beginInputTransactionForTests(window) should not succeed because there is composition synthesized by TIP1");
|
||||
ok(!TIP2.beginInputTransaction(childWindow, simpleCallback),
|
||||
description + "TIP2.beginInputTransaction(childWindow) should not succeed because there is composition synthesized by TIP1");
|
||||
ok(!TIP2.beginInputTransactionForTests(childWindow),
|
||||
description + "TIP2.beginInputTransactionForTests(childWindow) should not succeed because there is composition synthesized by TIP1");
|
||||
ok(TIP2.beginInputTransaction(otherWindow, simpleCallback),
|
||||
description + "TIP2.beginInputTransaction(otherWindow) should succeed because there is composition synthesized by TIP1 but it's in other window");
|
||||
ok(TIP2.beginInputTransactionForTests(otherWindow),
|
||||
description + "TIP2.beginInputTransactionForTests(otherWindow) should succeed because there is composition synthesized by TIP1 but it's in other window");
|
||||
|
||||
// Let's confirm that the composing string is NOT committed by above tests.
|
||||
ok(TIP1.commitComposition(),
|
||||
@ -158,12 +158,12 @@ function runInitMethodTests()
|
||||
is(input.value, composingStr,
|
||||
description + "TIP1.commitString() without specifying commit string should be committed with the last composing string");
|
||||
|
||||
ok(TIP1.init(window, simpleCallback),
|
||||
description + "TIP1.init() should succeed because there is no composition #2");
|
||||
ok(TIP1.initForTests(window),
|
||||
description + "TIP1.initForTests() should succeed because there is no composition #2");
|
||||
ok(TIP2.initForTests(window),
|
||||
description + "TIP2.initForTests() should succeed because the composition was already committed #2");
|
||||
ok(TIP1.beginInputTransaction(window, simpleCallback),
|
||||
description + "TIP1.beginInputTransaction() should succeed because there is no composition #2");
|
||||
ok(TIP1.beginInputTransactionForTests(window),
|
||||
description + "TIP1.beginInputTransactionForTests() should succeed because there is no composition #2");
|
||||
ok(TIP2.beginInputTransactionForTests(window),
|
||||
description + "TIP2.beginInputTransactionForTests() should succeed because the composition was already committed #2");
|
||||
|
||||
// Let's check if startComposition() throws an exception after ownership is strolen.
|
||||
input.value = "";
|
||||
@ -181,10 +181,10 @@ function runInitMethodTests()
|
||||
}
|
||||
|
||||
// Let's check if flushPendingComposition() throws an exception after ownership is stolen.
|
||||
ok(TIP1.initForTests(window),
|
||||
description + "TIP1.initForTests() should succeed because there is no composition");
|
||||
ok(TIP2.initForTests(window),
|
||||
description + "TIP2.initForTests() should succeed because there is no composition");
|
||||
ok(TIP1.beginInputTransactionForTests(window),
|
||||
description + "TIP1.beginInputTransactionForTests() should succeed because there is no composition");
|
||||
ok(TIP2.beginInputTransactionForTests(window),
|
||||
description + "TIP2.beginInputTransactionForTests() should succeed because there is no composition");
|
||||
input.value = "";
|
||||
try {
|
||||
TIP1.setPendingCompositionString(composingStr);
|
||||
@ -202,10 +202,10 @@ function runInitMethodTests()
|
||||
}
|
||||
|
||||
// Let's check if commitComposition("bar") throws an exception after ownership is stolen.
|
||||
ok(TIP1.initForTests(window),
|
||||
description + "TIP1.initForTests() should succeed because there is no composition");
|
||||
ok(TIP2.initForTests(window),
|
||||
description + "TIP2.initForTests() should succeed because there is no composition");
|
||||
ok(TIP1.beginInputTransactionForTests(window),
|
||||
description + "TIP1.beginInputTransactionForTests() should succeed because there is no composition");
|
||||
ok(TIP2.beginInputTransactionForTests(window),
|
||||
description + "TIP2.beginInputTransactionForTests() should succeed because there is no composition");
|
||||
input.value = "";
|
||||
try {
|
||||
TIP1.commitComposition("bar");
|
||||
@ -219,34 +219,34 @@ function runInitMethodTests()
|
||||
description + "The input element should not have commit string");
|
||||
}
|
||||
|
||||
// aCallback of nsITextInputProcessor.init() must not be omitted.
|
||||
// aCallback of nsITextInputProcessor.beginInputTransaction() must not be omitted.
|
||||
try {
|
||||
TIP1.init(window);
|
||||
TIP1.beginInputTransaction(window);
|
||||
ok(false,
|
||||
description + "TIP1.init(window) should be failed since aCallback is omitted");
|
||||
description + "TIP1.beginInputTransaction(window) should be failed since aCallback is omitted");
|
||||
} catch (e) {
|
||||
ok(e.message.contains("Not enough arguments"),
|
||||
description + "TIP1.init(window) should cause throwing an exception including \"Not enough arguments\" since aCallback is omitted");
|
||||
description + "TIP1.beginInputTransaction(window) should cause throwing an exception including \"Not enough arguments\" since aCallback is omitted");
|
||||
}
|
||||
|
||||
// aCallback of nsITextInputProcessor.init() must not be undefined.
|
||||
// aCallback of nsITextInputProcessor.beginInputTransaction() must not be undefined.
|
||||
try {
|
||||
TIP1.init(window, undefined);
|
||||
TIP1.beginInputTransaction(window, undefined);
|
||||
ok(false,
|
||||
description + "TIP1.init(window, undefined) should be failed since aCallback is undefined");
|
||||
description + "TIP1.beginInputTransaction(window, undefined) should be failed since aCallback is undefined");
|
||||
} catch (e) {
|
||||
ok(e.message.contains("NS_ERROR_ILLEGAL_VALUE"),
|
||||
description + "TIP1.init(window, undefined) should cause throwing an exception including NS_ERROR_ILLEGAL_VALUE since aCallback is undefined");
|
||||
description + "TIP1.beginInputTransaction(window, undefined) should cause throwing an exception including NS_ERROR_ILLEGAL_VALUE since aCallback is undefined");
|
||||
}
|
||||
|
||||
// aCallback of nsITextInputProcessor.init() must not be null.
|
||||
// aCallback of nsITextInputProcessor.beginInputTransaction() must not be null.
|
||||
try {
|
||||
TIP1.init(window, null);
|
||||
TIP1.beginInputTransaction(window, null);
|
||||
ok(false,
|
||||
description + "TIP1.init(window, null) should be failed since aCallback is null");
|
||||
description + "TIP1.beginInputTransaction(window, null) should be failed since aCallback is null");
|
||||
} catch (e) {
|
||||
ok(e.message.contains("NS_ERROR_ILLEGAL_VALUE"),
|
||||
description + "TIP1.init(window, null) should cause throwing an exception including NS_ERROR_ILLEGAL_VALUE since aCallback is null");
|
||||
description + "TIP1.beginInputTransaction(window, null) should cause throwing an exception including NS_ERROR_ILLEGAL_VALUE since aCallback is null");
|
||||
}
|
||||
}
|
||||
|
||||
@ -255,8 +255,8 @@ function runReleaseTests()
|
||||
var description = "runReleaseTests(): ";
|
||||
|
||||
var TIP = createTIP();
|
||||
ok(TIP.initForTests(window),
|
||||
description + "TIP.initForTests() should succeed");
|
||||
ok(TIP.beginInputTransactionForTests(window),
|
||||
description + "TIP.beginInputTransactionForTests() should succeed");
|
||||
|
||||
input.value = "";
|
||||
input.focus();
|
||||
@ -277,8 +277,8 @@ function runReleaseTests()
|
||||
description + "the input should be empty because the composition should be canceled");
|
||||
|
||||
TIP = createTIP();
|
||||
ok(TIP.initForTests(window),
|
||||
description + "TIP.initForTests() should succeed #2");
|
||||
ok(TIP.beginInputTransactionForTests(window),
|
||||
description + "TIP.beginInputTransactionForTests() should succeed #2");
|
||||
}
|
||||
|
||||
function runCompositionTests()
|
||||
@ -286,8 +286,8 @@ function runCompositionTests()
|
||||
var description = "runCompositionTests(): ";
|
||||
|
||||
var TIP = createTIP();
|
||||
ok(TIP.initForTests(window),
|
||||
description + "TIP.initForTests() should succeed");
|
||||
ok(TIP.beginInputTransactionForTests(window),
|
||||
description + "TIP.beginInputTransactionForTests() should succeed");
|
||||
|
||||
var events;
|
||||
|
||||
@ -530,8 +530,8 @@ function runErrorTests()
|
||||
var description = "runErrorTests(): ";
|
||||
|
||||
var TIP = createTIP();
|
||||
ok(TIP.initForTests(window),
|
||||
description + "TIP.initForTests() should succeed");
|
||||
ok(TIP.beginInputTransactionForTests(window),
|
||||
description + "TIP.beginInputTransactionForTests() should succeed");
|
||||
|
||||
input.value = "";
|
||||
input.focus();
|
||||
@ -674,8 +674,8 @@ function runCommitCompositionTests()
|
||||
var description = "runCommitCompositionTests(): ";
|
||||
|
||||
var TIP = createTIP();
|
||||
ok(TIP.initForTests(window),
|
||||
description + "TIP.initForTests() should succeed");
|
||||
ok(TIP.beginInputTransactionForTests(window),
|
||||
description + "TIP.beginInputTransactionForTests() should succeed");
|
||||
|
||||
input.focus();
|
||||
|
||||
@ -815,8 +815,8 @@ function runUnloadTests1(aNextTest)
|
||||
var description = "runUnloadTests1(): ";
|
||||
|
||||
var TIP1 = createTIP();
|
||||
ok(TIP1.initForTests(childWindow),
|
||||
description + "TIP1.initForTests() should succeed");
|
||||
ok(TIP1.beginInputTransactionForTests(childWindow),
|
||||
description + "TIP1.beginInputTransactionForTests() should succeed");
|
||||
|
||||
var oldSrc = iframe.src;
|
||||
var parentWindow = window;
|
||||
@ -838,8 +838,8 @@ function runUnloadTests1(aNextTest)
|
||||
// The composition should be committed internally. So, another TIP should
|
||||
// be able to steal the rights to using TextEventDispatcher.
|
||||
var TIP2 = createTIP();
|
||||
ok(TIP2.initForTests(parentWindow),
|
||||
description + "TIP2.initForTests() should succeed");
|
||||
ok(TIP2.beginInputTransactionForTests(parentWindow),
|
||||
description + "TIP2.beginInputTransactionForTests() should succeed");
|
||||
|
||||
input.focus();
|
||||
input.value = "";
|
||||
@ -877,8 +877,8 @@ function runUnloadTests2(aNextTest)
|
||||
var description = "runUnloadTests2(): ";
|
||||
|
||||
var TIP = createTIP();
|
||||
ok(TIP.initForTests(childWindow),
|
||||
description + "TIP.initForTests() should succeed");
|
||||
ok(TIP.beginInputTransactionForTests(childWindow),
|
||||
description + "TIP.beginInputTransactionForTests() should succeed");
|
||||
|
||||
var oldSrc = iframe.src;
|
||||
var parentWindow = window;
|
||||
@ -967,9 +967,9 @@ function runCallbackTests(aForTests)
|
||||
}
|
||||
|
||||
if (aForTests) {
|
||||
TIP.initForTests(window, callback);
|
||||
TIP.beginInputTransactionForTests(window, callback);
|
||||
} else {
|
||||
TIP.init(window, callback);
|
||||
TIP.beginInputTransaction(window, callback);
|
||||
}
|
||||
|
||||
notifications = [];
|
||||
@ -1003,13 +1003,13 @@ function runCallbackTests(aForTests)
|
||||
notifications = [];
|
||||
var TIP2 = createTIP();
|
||||
if (aForTests) {
|
||||
TIP2.initForTests(window, callback);
|
||||
TIP2.beginInputTransactionForTests(window, callback);
|
||||
} else {
|
||||
TIP2.init(window, callback);
|
||||
TIP2.beginInputTransaction(window, callback);
|
||||
}
|
||||
is(notifications.length, 1,
|
||||
description + "Initializing another TIP should cause a notification");
|
||||
is(notifications[0].type, "notify-detached",
|
||||
is(notifications[0].type, "notify-end-input-transaction",
|
||||
description + "Initializing another TIP should cause \"notify-detached\"");
|
||||
dumpUnexpectedNotifications(1);
|
||||
}
|
||||
@ -1018,7 +1018,7 @@ function runTests()
|
||||
{
|
||||
textareaInFrame = iframe.contentDocument.getElementById("textarea");
|
||||
|
||||
runInitMethodTests();
|
||||
runBeginInputTransactionMethodTests();
|
||||
runReleaseTests();
|
||||
runCompositionTests();
|
||||
runErrorTests();
|
||||
|
@ -638,6 +638,8 @@ BrowserElementChild.prototype = {
|
||||
// We clear selectionStateChangedTarget if selection carets are invisible.
|
||||
if (e.visible && !isCollapsed) {
|
||||
this._selectionStateChangedTarget = e.target;
|
||||
} else if (canPaste && isCollapsed) {
|
||||
this._selectionStateChangedTarget = e.target;
|
||||
} else {
|
||||
this._selectionStateChangedTarget = null;
|
||||
}
|
||||
@ -1167,6 +1169,7 @@ BrowserElementChild.prototype = {
|
||||
|
||||
_recvDoCommand: function(data) {
|
||||
if (this._isCommandEnabled(data.json.command)) {
|
||||
this._selectionStateChangedTarget = null;
|
||||
docShell.doCommand(COMMAND_MAP[data.json.command]);
|
||||
}
|
||||
},
|
||||
|
@ -251,9 +251,8 @@ static uint32_t CountNewlinesInXPLength(nsIContent* aContent,
|
||||
return 0;
|
||||
}
|
||||
// For automated tests, we should abort on debug build.
|
||||
NS_ABORT_IF_FALSE(
|
||||
(aXPLength == UINT32_MAX || aXPLength <= text->GetLength()),
|
||||
"aXPLength is out-of-bounds");
|
||||
MOZ_ASSERT(aXPLength == UINT32_MAX || aXPLength <= text->GetLength(),
|
||||
"aXPLength is out-of-bounds");
|
||||
const uint32_t length = std::min(aXPLength, text->GetLength());
|
||||
uint32_t newlines = 0;
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
@ -283,7 +282,7 @@ static uint32_t CountNewlinesInNativeLength(nsIContent* aContent,
|
||||
i < xpLength && nativeOffset < aNativeLength;
|
||||
++i, ++nativeOffset) {
|
||||
// For automated tests, we should abort on debug build.
|
||||
NS_ABORT_IF_FALSE(i < text->GetLength(), "i is out-of-bounds");
|
||||
MOZ_ASSERT(i < text->GetLength(), "i is out-of-bounds");
|
||||
if (text->CharAt(i) == '\n') {
|
||||
++newlines;
|
||||
++nativeOffset;
|
||||
@ -943,8 +942,13 @@ ContentEventHandler::OnQueryTextRect(WidgetQueryContentEvent* aEvent)
|
||||
nsPoint ptOffset;
|
||||
firstFrame->GetPointFromOffset(nodeOffset, &ptOffset);
|
||||
// minus 1 to avoid creating an empty rect
|
||||
rect.x += ptOffset.x - 1;
|
||||
rect.width -= ptOffset.x - 1;
|
||||
if (firstFrame->GetWritingMode().IsVertical()) {
|
||||
rect.y += ptOffset.y - 1;
|
||||
rect.height -= ptOffset.y - 1;
|
||||
} else {
|
||||
rect.x += ptOffset.x - 1;
|
||||
rect.width -= ptOffset.x - 1;
|
||||
}
|
||||
|
||||
// get the ending frame
|
||||
nodeOffset = range->EndOffset();
|
||||
@ -985,7 +989,11 @@ ContentEventHandler::OnQueryTextRect(WidgetQueryContentEvent* aEvent)
|
||||
// get the ending frame rect
|
||||
lastFrame->GetPointFromOffset(nodeOffset, &ptOffset);
|
||||
// minus 1 to avoid creating an empty rect
|
||||
frameRect.width -= lastFrame->GetRect().width - ptOffset.x - 1;
|
||||
if (lastFrame->GetWritingMode().IsVertical()) {
|
||||
frameRect.height -= lastFrame->GetRect().height - ptOffset.y - 1;
|
||||
} else {
|
||||
frameRect.width -= lastFrame->GetRect().width - ptOffset.x - 1;
|
||||
}
|
||||
|
||||
if (firstFrame == lastFrame) {
|
||||
rect.IntersectRect(rect, frameRect);
|
||||
@ -994,6 +1002,7 @@ ContentEventHandler::OnQueryTextRect(WidgetQueryContentEvent* aEvent)
|
||||
}
|
||||
aEvent->mReply.mRect = LayoutDevicePixel::FromUntyped(
|
||||
rect.ToOutsidePixels(mPresContext->AppUnitsPerDevPixel()));
|
||||
aEvent->mReply.mWritingMode = lastFrame->GetWritingMode();
|
||||
aEvent->mSucceeded = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -401,8 +401,8 @@ HTMLImageElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
(aName == nsGkAtoms::name || aName == nsGkAtoms::id) &&
|
||||
aValue && !aValue->IsEmptyString()) {
|
||||
// add the image to the hashtable as needed
|
||||
NS_ABORT_IF_FALSE(aValue->Type() == nsAttrValue::eAtom,
|
||||
"Expected atom value for name/id");
|
||||
MOZ_ASSERT(aValue->Type() == nsAttrValue::eAtom,
|
||||
"Expected atom value for name/id");
|
||||
mForm->AddImageElementToTable(this,
|
||||
nsDependentAtomString(aValue->GetAtomValue()));
|
||||
}
|
||||
|
@ -275,7 +275,7 @@ public:
|
||||
: mElement(aElement),
|
||||
mLoadID(aElement->GetCurrentLoadID())
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mElement, "Must pass an element to call back");
|
||||
MOZ_ASSERT(mElement, "Must pass an element to call back");
|
||||
}
|
||||
|
||||
private:
|
||||
@ -2083,7 +2083,6 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed<mozilla::dom::NodeInfo>& aNo
|
||||
mAudioChannelFaded(false),
|
||||
mPlayingThroughTheAudioChannel(false),
|
||||
mDisableVideo(false),
|
||||
mWaitingFor(MediaWaitingFor::None),
|
||||
mElementInTreeState(ELEMENT_NOT_INTREE)
|
||||
{
|
||||
#ifdef PR_LOGGING
|
||||
@ -4329,12 +4328,6 @@ HTMLMediaElement::SetMediaKeys(mozilla::dom::MediaKeys* aMediaKeys,
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
MediaWaitingFor
|
||||
HTMLMediaElement::WaitingFor() const
|
||||
{
|
||||
return mWaitingFor;
|
||||
}
|
||||
|
||||
EventHandlerNonNull*
|
||||
HTMLMediaElement::GetOnencrypted()
|
||||
{
|
||||
|
@ -25,13 +25,6 @@
|
||||
#endif
|
||||
#include "nsGkAtoms.h"
|
||||
|
||||
// Something on Linux #defines None, which is an entry in the
|
||||
// MediaWaitingFor enum, so undef it here before including the binfing,
|
||||
// so that the build doesn't fail...
|
||||
#ifdef None
|
||||
#undef None
|
||||
#endif
|
||||
|
||||
// X.h on Linux #defines CurrentTime as 0L, so we have to #undef it here.
|
||||
#ifdef CurrentTime
|
||||
#undef CurrentTime
|
||||
@ -552,8 +545,6 @@ public:
|
||||
already_AddRefed<Promise> SetMediaKeys(MediaKeys* mediaKeys,
|
||||
ErrorResult& aRv);
|
||||
|
||||
MediaWaitingFor WaitingFor() const;
|
||||
|
||||
mozilla::dom::EventHandlerNonNull* GetOnencrypted();
|
||||
void SetOnencrypted(mozilla::dom::EventHandlerNonNull* listener);
|
||||
|
||||
@ -1337,8 +1328,6 @@ protected:
|
||||
|
||||
nsRefPtr<VideoTrackList> mVideoTrackList;
|
||||
|
||||
MediaWaitingFor mWaitingFor;
|
||||
|
||||
enum ElementInTreeState {
|
||||
// The MediaElement is not in the DOM tree now.
|
||||
ELEMENT_NOT_INTREE,
|
||||
|
@ -712,8 +712,8 @@ nsGenericHTMLElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||
{
|
||||
if (aNamespaceID == kNameSpaceID_None) {
|
||||
if (IsEventAttributeName(aName) && aValue) {
|
||||
NS_ABORT_IF_FALSE(aValue->Type() == nsAttrValue::eString,
|
||||
"Expected string value for script body");
|
||||
MOZ_ASSERT(aValue->Type() == nsAttrValue::eString,
|
||||
"Expected string value for script body");
|
||||
nsresult rv = SetEventHandler(aName, aValue->GetStringValue());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
@ -2152,8 +2152,8 @@ nsGenericHTMLFormElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
|
||||
if (mForm && (aName == nsGkAtoms::name || aName == nsGkAtoms::id) &&
|
||||
aValue && !aValue->IsEmptyString()) {
|
||||
NS_ABORT_IF_FALSE(aValue->Type() == nsAttrValue::eAtom,
|
||||
"Expected atom value for name/id");
|
||||
MOZ_ASSERT(aValue->Type() == nsAttrValue::eAtom,
|
||||
"Expected atom value for name/id");
|
||||
mForm->AddElementToTable(this,
|
||||
nsDependentAtomString(aValue->GetAtomValue()));
|
||||
}
|
||||
|
@ -1899,8 +1899,8 @@ nsHTMLDocument::WriteCommon(JSContext *cx,
|
||||
if (NS_FAILED(rv) || !mParser) {
|
||||
return rv;
|
||||
}
|
||||
NS_ABORT_IF_FALSE(!JS_IsExceptionPending(cx),
|
||||
"Open() succeeded but JS exception is pending");
|
||||
MOZ_ASSERT(!JS_IsExceptionPending(cx),
|
||||
"Open() succeeded but JS exception is pending");
|
||||
}
|
||||
|
||||
static NS_NAMED_LITERAL_STRING(new_line, "\n");
|
||||
@ -2773,7 +2773,7 @@ nsHTMLDocument::EditingStateChanged()
|
||||
// We might already have an editor if it was set up for mail, let's see
|
||||
// if this is actually the case.
|
||||
nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(existingEditor);
|
||||
NS_ABORT_IF_FALSE(htmlEditor, "If we have an editor, it must be an HTML editor");
|
||||
MOZ_ASSERT(htmlEditor, "If we have an editor, it must be an HTML editor");
|
||||
uint32_t flags = 0;
|
||||
existingEditor->GetFlags(&flags);
|
||||
if (flags & nsIPlaintextEditor::eEditorMailMask) {
|
||||
|
@ -2107,7 +2107,7 @@ nsTextEditorState::UpdatePlaceholderVisibility(bool aNotify)
|
||||
void
|
||||
nsTextEditorState::HideSelectionIfBlurred()
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mSelCon, "Should have a selection controller if we have a frame!");
|
||||
MOZ_ASSERT(mSelCon, "Should have a selection controller if we have a frame!");
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(mTextCtrlElement);
|
||||
if (!nsContentUtils::IsFocusedContent(content)) {
|
||||
mSelCon->SetDisplaySelection(nsISelectionController::SELECTION_HIDDEN);
|
||||
|
@ -1243,7 +1243,8 @@ let CompositionManager = {
|
||||
Cc["@mozilla.org/text-input-processor;1"].
|
||||
createInstance(Ci.nsITextInputProcessor);
|
||||
}
|
||||
return this._textInputProcessor.init(aWindow, this._callback);
|
||||
return this._textInputProcessor.beginInputTransaction(aWindow,
|
||||
this._callback);
|
||||
},
|
||||
|
||||
setComposition: function cm_setComposition(element, text, cursor, clauses) {
|
||||
|
@ -10,11 +10,12 @@ interface nsITextInputProcessorCallback;
|
||||
|
||||
/**
|
||||
* An nsITextInputProcessor instance is associated with a top level widget which
|
||||
* handles native IME. It's associated by calling init() or initForTests().
|
||||
* While an instance has composition, nobody can steal the rights to make
|
||||
* composition on the top level widget. In other words, if another instance is
|
||||
* composing on a top level widget, either init() or initForTests() returns
|
||||
* false (i.e., not throws an exception).
|
||||
* handles native IME. It's associated by calling beginInputTransaction() or
|
||||
* beginInputTransactionForTests(). While an instance has composition, nobody
|
||||
* can steal the rights to make composition on the top level widget. In other
|
||||
* words, if another instance is composing on a top level widget, either
|
||||
* beginInputTransaction() or beginInputTransactionForTests() returns false
|
||||
* (i.e., not throws an exception).
|
||||
*
|
||||
* NOTE: See nsITextInputProcessorCallback.idl for examples of |callback| in
|
||||
* following examples,
|
||||
@ -23,7 +24,7 @@ interface nsITextInputProcessorCallback;
|
||||
*
|
||||
* var TIP = Components.classes["@mozilla.org/text-input-processor;1"].
|
||||
* createInstance(Components.interfaces.nsITextInputProcessor);
|
||||
* if (!TIP.init(window, callback)) {
|
||||
* if (!TIP.beginInputTransaction(window, callback)) {
|
||||
* return; // You failed to get the rights to make composition
|
||||
* }
|
||||
* // Set new composition string first
|
||||
@ -84,14 +85,14 @@ interface nsITextInputProcessorCallback;
|
||||
*
|
||||
* Example #6 JS-IME can insert text only with commitComposition():
|
||||
*
|
||||
* if (!TIP.init(window, callback)) {
|
||||
* if (!TIP.beginInputTransaction(window, callback)) {
|
||||
* return; // You failed to get the rights to make composition
|
||||
* }
|
||||
* TIP.commitComposition("Some words");
|
||||
*
|
||||
* Example #7 JS-IME can start composition explicitly:
|
||||
*
|
||||
* if (!TIP.init(window, callback)) {
|
||||
* if (!TIP.beginInputTransaction(window, callback)) {
|
||||
* return; // You failed to get the rights to make composition
|
||||
* }
|
||||
* // If JS-IME don't want to show composing string in the focused editor,
|
||||
@ -104,12 +105,12 @@ interface nsITextInputProcessorCallback;
|
||||
* TIP.commitComposition("selected-words");
|
||||
*/
|
||||
|
||||
[scriptable, builtinclass, uuid(8c20753c-8339-4e9c-86c5-ae30f1b456c3)]
|
||||
[scriptable, builtinclass, uuid(512f1efe-9e0f-48a4-b423-3936ef948f34)]
|
||||
interface nsITextInputProcessor : nsISupports
|
||||
{
|
||||
/**
|
||||
* When you create an instance, you must call init() first except when you
|
||||
* created the instance for automated tests.
|
||||
* When you create an instance, you must call beginInputTransaction() first
|
||||
* except when you created the instance for automated tests.
|
||||
*
|
||||
* @param aWindow A DOM window. The instance will look for a top
|
||||
* level widget from this.
|
||||
@ -122,18 +123,20 @@ interface nsITextInputProcessor : nsISupports
|
||||
* when this returns true. If this returns false,
|
||||
* your TIP should wait next chance.
|
||||
*/
|
||||
boolean init(in nsIDOMWindow aWindow,
|
||||
in nsITextInputProcessorCallback aCallback);
|
||||
boolean beginInputTransaction(in nsIDOMWindow aWindow,
|
||||
in nsITextInputProcessorCallback aCallback);
|
||||
|
||||
/**
|
||||
* When you create an instance for automated test, you must call
|
||||
* initForTest(), first. See init() for more detail of this.
|
||||
* beginInputTransaction(), first. See beginInputTransaction() for more
|
||||
* detail of this.
|
||||
* Note that aCallback can be null. If it's null, nsITextInputProcessor
|
||||
* implementation will handle them automatically.
|
||||
*/
|
||||
[optional_argc] boolean
|
||||
initForTests(in nsIDOMWindow aWindow,
|
||||
[optional] in nsITextInputProcessorCallback aCallback);
|
||||
beginInputTransactionForTests(
|
||||
in nsIDOMWindow aWindow,
|
||||
[optional] in nsITextInputProcessorCallback aCallback);
|
||||
|
||||
/**
|
||||
* startComposition() dispatches compositionstart event explicitly.
|
||||
|
@ -30,9 +30,11 @@ interface nsITextInputProcessorNotification : nsISupports
|
||||
* nsITextInputProcessorCallback::onNotify() has to handle this
|
||||
* notification.
|
||||
*
|
||||
* "notify-detached" (optional)
|
||||
* "notify-end-input-transaction" (optional)
|
||||
* This is notified when the callback is detached from
|
||||
* nsITextInputProcessor.
|
||||
* nsITextInputProcessor. I.e., the TextInputProcessor lost the rights
|
||||
* to input text and needs to call .beginInputTransaction() before next
|
||||
* input.
|
||||
*
|
||||
* "notify-focus" (optional)
|
||||
* This is notified when an editable editor gets focus and Gecko starts
|
||||
|
@ -1964,8 +1964,8 @@ ContentChild::RecvAddPermission(const IPC::Permission& permission)
|
||||
services::GetPermissionManager();
|
||||
nsPermissionManager* permissionManager =
|
||||
static_cast<nsPermissionManager*>(permissionManagerIface.get());
|
||||
NS_ABORT_IF_FALSE(permissionManager,
|
||||
"We have no permissionManager in the Content process !");
|
||||
MOZ_ASSERT(permissionManager,
|
||||
"We have no permissionManager in the Content process !");
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
NS_NewURI(getter_AddRefs(uri), NS_LITERAL_CSTRING("http://") + nsCString(permission.host));
|
||||
|
@ -2425,12 +2425,12 @@ ContentParent::RecvReadPermissions(InfallibleTArray<IPC::Permission>* aPermissio
|
||||
services::GetPermissionManager();
|
||||
nsPermissionManager* permissionManager =
|
||||
static_cast<nsPermissionManager*>(permissionManagerIface.get());
|
||||
NS_ABORT_IF_FALSE(permissionManager,
|
||||
"We have no permissionManager in the Chrome process !");
|
||||
MOZ_ASSERT(permissionManager,
|
||||
"We have no permissionManager in the Chrome process !");
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> enumerator;
|
||||
DebugOnly<nsresult> rv = permissionManager->GetEnumerator(getter_AddRefs(enumerator));
|
||||
NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv), "Could not get enumerator!");
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv), "Could not get enumerator!");
|
||||
while(1) {
|
||||
bool hasMore;
|
||||
enumerator->HasMoreElements(&hasMore);
|
||||
@ -4425,8 +4425,8 @@ ContentParent::RecvBackUpXResources(const FileDescriptor& aXSocketFd)
|
||||
#ifndef MOZ_X11
|
||||
NS_RUNTIMEABORT("This message only makes sense on X11 platforms");
|
||||
#else
|
||||
NS_ABORT_IF_FALSE(0 > mChildXSocketFdDup.get(),
|
||||
"Already backed up X resources??");
|
||||
MOZ_ASSERT(0 > mChildXSocketFdDup.get(),
|
||||
"Already backed up X resources??");
|
||||
mChildXSocketFdDup.forget();
|
||||
if (aXSocketFd.IsValid()) {
|
||||
mChildXSocketFdDup.reset(aXSocketFd.PlatformHandle());
|
||||
|
@ -3179,8 +3179,8 @@ TabChild::InitRenderingState(const ScrollingBehavior& aScrolling,
|
||||
ShadowLayerForwarder* lf =
|
||||
mWidget->GetLayerManager(shadowManager, mTextureFactoryIdentifier.mParentBackend)
|
||||
->AsShadowForwarder();
|
||||
NS_ABORT_IF_FALSE(lf && lf->HasShadowManager(),
|
||||
"PuppetWidget should have shadow manager");
|
||||
MOZ_ASSERT(lf && lf->HasShadowManager(),
|
||||
"PuppetWidget should have shadow manager");
|
||||
lf->IdentifyTextureHost(mTextureFactoryIdentifier);
|
||||
ImageBridgeChild::IdentifyCompositorTextureHost(mTextureFactoryIdentifier);
|
||||
|
||||
|
@ -1927,6 +1927,7 @@ TabParent::HandleQueryContentEvent(WidgetQueryContentEvent& aEvent)
|
||||
aEvent.mReply.mOffset = aEvent.mInput.mOffset;
|
||||
aEvent.mReply.mRect =
|
||||
aEvent.mReply.mRect - LayoutDevicePixel::FromUntyped(GetChildProcessOffset());
|
||||
aEvent.mReply.mWritingMode = mWritingMode;
|
||||
aEvent.mSucceeded = true;
|
||||
}
|
||||
break;
|
||||
@ -2182,8 +2183,8 @@ TabParent::RecvGetDPI(float* aValue)
|
||||
{
|
||||
TryCacheDPIAndScale();
|
||||
|
||||
NS_ABORT_IF_FALSE(mDPI > 0,
|
||||
"Must not ask for DPI before OwnerElement is received!");
|
||||
MOZ_ASSERT(mDPI > 0,
|
||||
"Must not ask for DPI before OwnerElement is received!");
|
||||
*aValue = mDPI;
|
||||
return true;
|
||||
}
|
||||
@ -2193,8 +2194,8 @@ TabParent::RecvGetDefaultScale(double* aValue)
|
||||
{
|
||||
TryCacheDPIAndScale();
|
||||
|
||||
NS_ABORT_IF_FALSE(mDefaultScale.scale > 0,
|
||||
"Must not ask for scale before OwnerElement is received!");
|
||||
MOZ_ASSERT(mDefaultScale.scale > 0,
|
||||
"Must not ask for scale before OwnerElement is received!");
|
||||
*aValue = mDefaultScale.scale;
|
||||
return true;
|
||||
}
|
||||
|
@ -536,7 +536,7 @@ nsJSONListener::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext,
|
||||
|
||||
JS::ConstTwoByteChars chars(reinterpret_cast<const char16_t*>(mBufferedChars.Elements()),
|
||||
mBufferedChars.Length());
|
||||
bool ok = JS_ParseJSONWithReviver(mCx, chars.get(),
|
||||
bool ok = JS_ParseJSONWithReviver(mCx, chars.start().get(),
|
||||
uint32_t(mBufferedChars.Length()),
|
||||
reviver, &value);
|
||||
|
||||
@ -645,7 +645,7 @@ nsJSONListener::ConsumeConverted(const char* aBuffer, uint32_t aByteLength)
|
||||
rv = mDecoder->Convert(aBuffer, &srcLen, endelems, &unicharLength);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
NS_ABORT_IF_FALSE(preLength >= unicharLength, "GetMaxLength lied");
|
||||
MOZ_ASSERT(preLength >= unicharLength, "GetMaxLength lied");
|
||||
if (preLength > unicharLength)
|
||||
mBufferedChars.TruncateLength(mBufferedChars.Length() - (preLength - unicharLength));
|
||||
return NS_OK;
|
||||
|
@ -371,7 +371,7 @@ AudioStream::Init(int32_t aNumChannels, int32_t aRate,
|
||||
// selected based on the observed behaviour of the existing AudioStream
|
||||
// implementations.
|
||||
uint32_t bufferLimit = FramesToBytes(aRate);
|
||||
NS_ABORT_IF_FALSE(bufferLimit % mBytesPerFrame == 0, "Must buffer complete frames");
|
||||
MOZ_ASSERT(bufferLimit % mBytesPerFrame == 0, "Must buffer complete frames");
|
||||
mBuffer.SetCapacity(bufferLimit);
|
||||
|
||||
if (aLatencyRequest == LowLatency) {
|
||||
@ -632,8 +632,8 @@ AudioStream::Write(const AudioDataValue* aBuf, uint32_t aFrames, TimeStamp *aTim
|
||||
|
||||
while (bytesToCopy > 0) {
|
||||
uint32_t available = std::min(bytesToCopy, mBuffer.Available());
|
||||
NS_ABORT_IF_FALSE(available % mBytesPerFrame == 0,
|
||||
"Must copy complete frames.");
|
||||
MOZ_ASSERT(available % mBytesPerFrame == 0,
|
||||
"Must copy complete frames.");
|
||||
|
||||
mBuffer.AppendElements(src, available);
|
||||
src += available;
|
||||
@ -678,14 +678,14 @@ uint32_t
|
||||
AudioStream::Available()
|
||||
{
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
NS_ABORT_IF_FALSE(mBuffer.Length() % mBytesPerFrame == 0, "Buffer invariant violated.");
|
||||
MOZ_ASSERT(mBuffer.Length() % mBytesPerFrame == 0, "Buffer invariant violated.");
|
||||
return BytesToFrames(mBuffer.Available());
|
||||
}
|
||||
|
||||
void
|
||||
AudioStream::SetVolume(double aVolume)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aVolume >= 0.0 && aVolume <= 1.0, "Invalid volume");
|
||||
MOZ_ASSERT(aVolume >= 0.0 && aVolume <= 1.0, "Invalid volume");
|
||||
|
||||
if (cubeb_stream_set_volume(mCubebStream.get(), aVolume * CubebUtils::GetVolumeScale()) != CUBEB_OK) {
|
||||
NS_WARNING("Could not change volume on cubeb stream.");
|
||||
@ -1035,7 +1035,7 @@ AudioStream::Reset()
|
||||
// selected based on the observed behaviour of the existing AudioStream
|
||||
// implementations.
|
||||
uint32_t bufferLimit = FramesToBytes(mInRate);
|
||||
NS_ABORT_IF_FALSE(bufferLimit % mBytesPerFrame == 0, "Must buffer complete frames");
|
||||
MOZ_ASSERT(bufferLimit % mBytesPerFrame == 0, "Must buffer complete frames");
|
||||
mBuffer.Reset();
|
||||
mBuffer.SetCapacity(bufferLimit);
|
||||
|
||||
@ -1054,7 +1054,7 @@ AudioStream::DataCallback(void* aBuffer, long aFrames)
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
MOZ_ASSERT(mState != SHUTDOWN, "No data callback after shutdown");
|
||||
uint32_t available = std::min(static_cast<uint32_t>(FramesToBytes(aFrames)), mBuffer.Length());
|
||||
NS_ABORT_IF_FALSE(available % mBytesPerFrame == 0, "Must copy complete frames");
|
||||
MOZ_ASSERT(available % mBytesPerFrame == 0, "Must copy complete frames");
|
||||
AudioDataValue* output = reinterpret_cast<AudioDataValue*>(aBuffer);
|
||||
uint32_t underrunFrames = 0;
|
||||
uint32_t servicedFrames = 0;
|
||||
@ -1113,7 +1113,7 @@ AudioStream::DataCallback(void* aBuffer, long aFrames)
|
||||
servicedFrames = GetTimeStretched(output, aFrames, insertTime);
|
||||
}
|
||||
|
||||
NS_ABORT_IF_FALSE(mBuffer.Length() % mBytesPerFrame == 0, "Must copy complete frames");
|
||||
MOZ_ASSERT(mBuffer.Length() % mBytesPerFrame == 0, "Must copy complete frames");
|
||||
|
||||
// Notify any blocked Write() call that more space is available in mBuffer.
|
||||
mon.NotifyAll();
|
||||
|
@ -88,7 +88,7 @@ public:
|
||||
// Set the capacity of the buffer in bytes. Must be called before any
|
||||
// call to append or pop elements.
|
||||
void SetCapacity(uint32_t aCapacity) {
|
||||
NS_ABORT_IF_FALSE(!mBuffer, "Buffer allocated.");
|
||||
MOZ_ASSERT(!mBuffer, "Buffer allocated.");
|
||||
mCapacity = aCapacity;
|
||||
mBuffer = new uint8_t[mCapacity];
|
||||
}
|
||||
@ -108,8 +108,8 @@ public:
|
||||
// Append aLength bytes from aSrc to the buffer. Caller must check that
|
||||
// sufficient space is available.
|
||||
void AppendElements(const uint8_t* aSrc, uint32_t aLength) {
|
||||
NS_ABORT_IF_FALSE(mBuffer && mCapacity, "Buffer not initialized.");
|
||||
NS_ABORT_IF_FALSE(aLength <= Available(), "Buffer full.");
|
||||
MOZ_ASSERT(mBuffer && mCapacity, "Buffer not initialized.");
|
||||
MOZ_ASSERT(aLength <= Available(), "Buffer full.");
|
||||
|
||||
uint32_t end = (mStart + mCount) % mCapacity;
|
||||
|
||||
@ -124,8 +124,8 @@ public:
|
||||
// must not specify an aSize larger than Length().
|
||||
void PopElements(uint32_t aSize, void** aData1, uint32_t* aSize1,
|
||||
void** aData2, uint32_t* aSize2) {
|
||||
NS_ABORT_IF_FALSE(mBuffer && mCapacity, "Buffer not initialized.");
|
||||
NS_ABORT_IF_FALSE(aSize <= Length(), "Request too large.");
|
||||
MOZ_ASSERT(mBuffer && mCapacity, "Buffer not initialized.");
|
||||
MOZ_ASSERT(aSize <= Length(), "Request too large.");
|
||||
|
||||
*aData1 = &mBuffer[mStart];
|
||||
*aSize1 = std::min(mCapacity - mStart, aSize);
|
||||
@ -139,7 +139,7 @@ public:
|
||||
// Throw away all but aSize bytes from the buffer. Returns new size, which
|
||||
// may be less than aSize
|
||||
uint32_t ContractTo(uint32_t aSize) {
|
||||
NS_ABORT_IF_FALSE(mBuffer && mCapacity, "Buffer not initialized.");
|
||||
MOZ_ASSERT(mBuffer && mCapacity, "Buffer not initialized.");
|
||||
if (aSize >= mCount) {
|
||||
return mCount;
|
||||
}
|
||||
|
@ -212,8 +212,9 @@ nsresult FileBlockCache::Run()
|
||||
// mDataMonitor to take mFileMonitor.
|
||||
int32_t blockIndex = mChangeIndexList.PopFront();
|
||||
nsRefPtr<BlockChange> change = mBlockChanges[blockIndex];
|
||||
NS_ABORT_IF_FALSE(change,
|
||||
"Change index list should only contain entries for blocks with changes");
|
||||
MOZ_ASSERT(change,
|
||||
"Change index list should only contain entries for blocks "
|
||||
"with changes");
|
||||
{
|
||||
MonitorAutoUnlock unlock(mDataMonitor);
|
||||
MonitorAutoLock lock(mFileMonitor);
|
||||
|
@ -2264,7 +2264,7 @@ MediaCacheStream::Read(char* aBuffer, uint32_t aCount, uint32_t* aBytes)
|
||||
int64_t bytes = std::min<int64_t>(size, streamWithPartialBlock->mChannelOffset - mStreamOffset);
|
||||
// Clamp bytes until 64-bit file size issues are fixed.
|
||||
bytes = std::min(bytes, int64_t(INT32_MAX));
|
||||
NS_ABORT_IF_FALSE(bytes >= 0 && bytes <= aCount, "Bytes out of range.");
|
||||
MOZ_ASSERT(bytes >= 0 && bytes <= aCount, "Bytes out of range.");
|
||||
memcpy(aBuffer,
|
||||
reinterpret_cast<char*>(streamWithPartialBlock->mPartialBlockBuffer.get()) + offsetInStreamBlock, bytes);
|
||||
if (mCurrentMode == MODE_METADATA) {
|
||||
@ -2289,7 +2289,7 @@ MediaCacheStream::Read(char* aBuffer, uint32_t aCount, uint32_t* aBytes)
|
||||
|
||||
int64_t offset = cacheBlock*BLOCK_SIZE + offsetInStreamBlock;
|
||||
int32_t bytes;
|
||||
NS_ABORT_IF_FALSE(size >= 0 && size <= INT32_MAX, "Size out of range.");
|
||||
MOZ_ASSERT(size >= 0 && size <= INT32_MAX, "Size out of range.");
|
||||
nsresult rv = gMediaCache->ReadCacheFile(offset, aBuffer + count, int32_t(size), &bytes);
|
||||
if (NS_FAILED(rv)) {
|
||||
if (count == 0)
|
||||
@ -2361,7 +2361,7 @@ MediaCacheStream::ReadFromCache(char* aBuffer, int64_t aOffset, int64_t aCount)
|
||||
// Clamp bytes until 64-bit file size issues are fixed.
|
||||
int64_t toCopy = std::min<int64_t>(size, mChannelOffset - streamOffset);
|
||||
bytes = std::min(toCopy, int64_t(INT32_MAX));
|
||||
NS_ABORT_IF_FALSE(bytes >= 0 && bytes <= toCopy, "Bytes out of range.");
|
||||
MOZ_ASSERT(bytes >= 0 && bytes <= toCopy, "Bytes out of range.");
|
||||
memcpy(aBuffer + count,
|
||||
reinterpret_cast<char*>(mPartialBlockBuffer.get()) + offsetInStreamBlock, bytes);
|
||||
} else {
|
||||
@ -2370,7 +2370,7 @@ MediaCacheStream::ReadFromCache(char* aBuffer, int64_t aOffset, int64_t aCount)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
int64_t offset = cacheBlock*BLOCK_SIZE + offsetInStreamBlock;
|
||||
NS_ABORT_IF_FALSE(size >= 0 && size <= INT32_MAX, "Size out of range.");
|
||||
MOZ_ASSERT(size >= 0 && size <= INT32_MAX, "Size out of range.");
|
||||
nsresult rv = gMediaCache->ReadCacheFile(offset, aBuffer + count, int32_t(size), &bytes);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
|
@ -350,6 +350,71 @@ MediaDecoder::DecodedStreamGraphListener::NotifyEvent(MediaStreamGraph* aGraph,
|
||||
}
|
||||
}
|
||||
|
||||
class MediaDecoder::OutputStreamListener : public MediaStreamListener {
|
||||
public:
|
||||
OutputStreamListener(MediaDecoder* aDecoder, MediaStream* aStream)
|
||||
: mDecoder(aDecoder), mStream(aStream) {}
|
||||
|
||||
virtual void NotifyEvent(
|
||||
MediaStreamGraph* aGraph,
|
||||
MediaStreamListener::MediaStreamGraphEvent event) MOZ_OVERRIDE {
|
||||
if (event == EVENT_FINISHED) {
|
||||
nsRefPtr<nsIRunnable> r = NS_NewRunnableMethod(
|
||||
this, &OutputStreamListener::DoNotifyFinished);
|
||||
aGraph->DispatchToMainThreadAfterStreamStateUpdate(r.forget());
|
||||
}
|
||||
}
|
||||
|
||||
void Forget() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mDecoder = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
void DoNotifyFinished() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (!mDecoder) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the finished stream so it won't block the decoded stream.
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
auto& streams = mDecoder->OutputStreams();
|
||||
// Don't read |mDecoder| in the loop since removing the element will lead
|
||||
// to ~OutputStreamData() which will call Forget() to reset |mDecoder|.
|
||||
for (int32_t i = streams.Length() - 1; i >= 0; --i) {
|
||||
auto& os = streams[i];
|
||||
MediaStream* p = os.mStream.get();
|
||||
if (p == mStream.get()) {
|
||||
if (os.mPort) {
|
||||
os.mPort->Destroy();
|
||||
os.mPort = nullptr;
|
||||
}
|
||||
streams.RemoveElementAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Main thread only
|
||||
MediaDecoder* mDecoder;
|
||||
nsRefPtr<MediaStream> mStream;
|
||||
};
|
||||
|
||||
void
|
||||
MediaDecoder::OutputStreamData::Init(MediaDecoder* aDecoder,
|
||||
ProcessedMediaStream* aStream)
|
||||
{
|
||||
mStream = aStream;
|
||||
mListener = new OutputStreamListener(aDecoder, aStream);
|
||||
aStream->AddListener(mListener);
|
||||
}
|
||||
|
||||
MediaDecoder::OutputStreamData::~OutputStreamData()
|
||||
{
|
||||
mListener->Forget();
|
||||
}
|
||||
|
||||
void MediaDecoder::DestroyDecodedStream()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
@ -366,22 +431,20 @@ void MediaDecoder::DestroyDecodedStream()
|
||||
// need to be explicitly blocked again.
|
||||
for (int32_t i = mOutputStreams.Length() - 1; i >= 0; --i) {
|
||||
OutputStreamData& os = mOutputStreams[i];
|
||||
// Explicitly remove all existing ports.
|
||||
// This is not strictly necessary but it's good form.
|
||||
MOZ_ASSERT(os.mPort, "Double-delete of the ports!");
|
||||
os.mPort->Destroy();
|
||||
os.mPort = nullptr;
|
||||
// During cycle collection, nsDOMMediaStream can be destroyed and send
|
||||
// its Destroy message before this decoder is destroyed. So we have to
|
||||
// be careful not to send any messages after the Destroy().
|
||||
if (os.mStream->IsDestroyed()) {
|
||||
// Probably the DOM MediaStream was GCed. Clean up.
|
||||
MOZ_ASSERT(os.mPort, "Double-delete of the ports!");
|
||||
os.mPort->Destroy();
|
||||
mOutputStreams.RemoveElementAt(i);
|
||||
continue;
|
||||
} else {
|
||||
os.mStream->ChangeExplicitBlockerCount(1);
|
||||
}
|
||||
os.mStream->ChangeExplicitBlockerCount(1);
|
||||
// Explicitly remove all existing ports. This is not strictly necessary but it's
|
||||
// good form.
|
||||
MOZ_ASSERT(os.mPort, "Double-delete of the ports!");
|
||||
os.mPort->Destroy();
|
||||
os.mPort = nullptr;
|
||||
}
|
||||
|
||||
mDecodedStream = nullptr;
|
||||
@ -429,12 +492,8 @@ void MediaDecoder::RecreateDecodedStream(int64_t aStartTimeUSecs)
|
||||
// between main-thread stable states take effect atomically.
|
||||
for (int32_t i = mOutputStreams.Length() - 1; i >= 0; --i) {
|
||||
OutputStreamData& os = mOutputStreams[i];
|
||||
if (os.mStream->IsDestroyed()) {
|
||||
// Probably the DOM MediaStream was GCed. Clean up.
|
||||
// No need to destroy the port; all ports have been destroyed here.
|
||||
mOutputStreams.RemoveElementAt(i);
|
||||
continue;
|
||||
}
|
||||
MOZ_ASSERT(!os.mStream->IsDestroyed(),
|
||||
"Should've been removed in DestroyDecodedStream()");
|
||||
ConnectDecodedStreamToOutputStream(&os);
|
||||
}
|
||||
UpdateStreamBlockingForStateMachinePlaying();
|
||||
@ -462,7 +521,7 @@ void MediaDecoder::AddOutputStream(ProcessedMediaStream* aStream,
|
||||
RecreateDecodedStream(t);
|
||||
}
|
||||
OutputStreamData* os = mOutputStreams.AppendElement();
|
||||
os->Init(aStream, aFinishWhenEnded);
|
||||
os->Init(this, aStream);
|
||||
ConnectDecodedStreamToOutputStream(os);
|
||||
if (aFinishWhenEnded) {
|
||||
// Ensure that aStream finishes the moment mDecodedStream does.
|
||||
@ -718,7 +777,7 @@ nsresult MediaDecoder::Seek(double aTime, SeekTarget::Type aSeekType)
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
UpdateDormantState(false /* aDormantTimeout */, true /* aActivity */);
|
||||
|
||||
NS_ABORT_IF_FALSE(aTime >= 0.0, "Cannot seek to a negative value.");
|
||||
MOZ_ASSERT(aTime >= 0.0, "Cannot seek to a negative value.");
|
||||
|
||||
int64_t timeUsecs = 0;
|
||||
nsresult rv = SecondsToUsecs(aTime, timeUsecs);
|
||||
@ -945,32 +1004,6 @@ void MediaDecoder::PlaybackEnded()
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
|
||||
for (int32_t i = mOutputStreams.Length() - 1; i >= 0; --i) {
|
||||
OutputStreamData& os = mOutputStreams[i];
|
||||
if (os.mStream->IsDestroyed()) {
|
||||
// Probably the DOM MediaStream was GCed. Clean up.
|
||||
MOZ_ASSERT(os.mPort, "Double-delete of the ports!");
|
||||
os.mPort->Destroy();
|
||||
mOutputStreams.RemoveElementAt(i);
|
||||
continue;
|
||||
}
|
||||
if (os.mFinishWhenEnded) {
|
||||
// Shouldn't really be needed since mDecodedStream should already have
|
||||
// finished, but doesn't hurt.
|
||||
os.mStream->Finish();
|
||||
MOZ_ASSERT(os.mPort, "Double-delete of the ports!");
|
||||
os.mPort->Destroy();
|
||||
// Not really needed but it keeps the invariant that a stream not
|
||||
// connected to mDecodedStream is explicity blocked.
|
||||
os.mStream->ChangeExplicitBlockerCount(1);
|
||||
mOutputStreams.RemoveElementAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PlaybackPositionChanged();
|
||||
ChangeState(PLAY_STATE_ENDED);
|
||||
InvalidateWithFlags(VideoFrameContainer::INVALIDATE_FORCE);
|
||||
@ -1551,7 +1584,7 @@ bool MediaDecoder::OnDecodeThread() const {
|
||||
}
|
||||
|
||||
ReentrantMonitor& MediaDecoder::GetReentrantMonitor() {
|
||||
return mReentrantMonitor.GetReentrantMonitor();
|
||||
return mReentrantMonitor;
|
||||
}
|
||||
|
||||
ImageContainer* MediaDecoder::GetImageContainer()
|
||||
|
@ -346,14 +346,6 @@ public:
|
||||
// the seek target.
|
||||
virtual nsresult Seek(double aTime, SeekTarget::Type aSeekType);
|
||||
|
||||
// Enables decoders to supply an enclosing byte range for a seek offset.
|
||||
// E.g. used by ChannelMediaResource to download a whole cluster for
|
||||
// DASH-WebM.
|
||||
virtual nsresult GetByteRangeForSeek(int64_t const aOffset,
|
||||
MediaByteRange &aByteRange) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
// Initialize state machine and schedule it.
|
||||
nsresult InitializeStateMachine(MediaDecoder* aCloneDonor);
|
||||
|
||||
@ -487,17 +479,17 @@ public:
|
||||
bool mStreamFinishedOnMainThread;
|
||||
};
|
||||
|
||||
class OutputStreamListener;
|
||||
|
||||
struct OutputStreamData {
|
||||
void Init(ProcessedMediaStream* aStream, bool aFinishWhenEnded)
|
||||
{
|
||||
mStream = aStream;
|
||||
mFinishWhenEnded = aFinishWhenEnded;
|
||||
}
|
||||
void Init(MediaDecoder* aDecoder, ProcessedMediaStream* aStream);
|
||||
~OutputStreamData();
|
||||
nsRefPtr<ProcessedMediaStream> mStream;
|
||||
// mPort connects mDecodedStream->mStream to our mStream.
|
||||
nsRefPtr<MediaInputPort> mPort;
|
||||
bool mFinishWhenEnded;
|
||||
nsRefPtr<OutputStreamListener> mListener;
|
||||
};
|
||||
|
||||
/**
|
||||
* Connects mDecodedStream->mStream to aStream->mStream.
|
||||
*/
|
||||
@ -1082,40 +1074,11 @@ protected:
|
||||
// Media data resource.
|
||||
nsRefPtr<MediaResource> mResource;
|
||||
|
||||
private:
|
||||
// |ReentrantMonitor| for detecting when the video play state changes. A call
|
||||
// to |Wait| on this monitor will block the thread until the next state
|
||||
// change.
|
||||
// Using a wrapper class to restrict direct access to the |ReentrantMonitor|
|
||||
// object. Subclasses may override |MediaDecoder|::|GetReentrantMonitor|
|
||||
// e.g. |DASHRepDecoder|::|GetReentrantMonitor| returns the monitor in the
|
||||
// main |DASHDecoder| object. In this case, directly accessing the
|
||||
// member variable mReentrantMonitor in |DASHRepDecoder| is wrong.
|
||||
// The wrapper |RestrictedAccessMonitor| restricts use to the getter
|
||||
// function rather than the object itself.
|
||||
private:
|
||||
class RestrictedAccessMonitor
|
||||
{
|
||||
public:
|
||||
explicit RestrictedAccessMonitor(const char* aName) :
|
||||
mReentrantMonitor(aName)
|
||||
{
|
||||
MOZ_COUNT_CTOR(RestrictedAccessMonitor);
|
||||
}
|
||||
~RestrictedAccessMonitor()
|
||||
{
|
||||
MOZ_COUNT_DTOR(RestrictedAccessMonitor);
|
||||
}
|
||||
|
||||
// Returns a ref to the reentrant monitor
|
||||
ReentrantMonitor& GetReentrantMonitor() {
|
||||
return mReentrantMonitor;
|
||||
}
|
||||
private:
|
||||
ReentrantMonitor mReentrantMonitor;
|
||||
};
|
||||
|
||||
// The |RestrictedAccessMonitor| member object.
|
||||
RestrictedAccessMonitor mReentrantMonitor;
|
||||
// change. Explicitly private for force access via GetReentrantMonitor.
|
||||
ReentrantMonitor mReentrantMonitor;
|
||||
|
||||
#ifdef MOZ_EME
|
||||
nsRefPtr<CDMProxy> mProxy;
|
||||
|
@ -228,8 +228,6 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
|
||||
mQuickBufferingLowDataThresholdUsecs(detail::QUICK_BUFFERING_LOW_DATA_USECS),
|
||||
mIsAudioPrerolling(false),
|
||||
mIsVideoPrerolling(false),
|
||||
mAudioRequestStatus(RequestStatus::Idle),
|
||||
mVideoRequestStatus(RequestStatus::Idle),
|
||||
mAudioCaptured(false),
|
||||
mPositionChangeQueued(false),
|
||||
mAudioCompleted(false),
|
||||
@ -707,7 +705,7 @@ MediaDecoderStateMachine::OnAudioDecoded(AudioData* aAudioSample)
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
nsRefPtr<AudioData> audio(aAudioSample);
|
||||
MOZ_ASSERT(audio);
|
||||
mAudioRequestStatus = RequestStatus::Idle;
|
||||
mAudioDataRequest.Complete();
|
||||
mDecodedAudioEndTime = audio->GetEndTime();
|
||||
|
||||
SAMPLE_LOG("OnAudioDecoded [%lld,%lld] disc=%d",
|
||||
@ -824,13 +822,17 @@ void
|
||||
MediaDecoderStateMachine::OnNotDecoded(MediaData::Type aType,
|
||||
MediaDecoderReader::NotDecodedReason aReason)
|
||||
{
|
||||
MOZ_ASSERT(OnDecodeThread());
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
SAMPLE_LOG("OnNotDecoded (aType=%u, aReason=%u)", aType, aReason);
|
||||
bool isAudio = aType == MediaData::AUDIO_DATA;
|
||||
MOZ_ASSERT_IF(!isAudio, aType == MediaData::VIDEO_DATA);
|
||||
|
||||
// This callback means that the pending request is dead.
|
||||
RequestStatusRef(aType) = RequestStatus::Idle;
|
||||
if (isAudio) {
|
||||
mAudioDataRequest.Complete();
|
||||
} else {
|
||||
mVideoDataRequest.Complete();
|
||||
}
|
||||
|
||||
// If this is a decode error, delegate to the generic error path.
|
||||
if (aReason == MediaDecoderReader::DECODE_ERROR) {
|
||||
@ -843,10 +845,10 @@ MediaDecoderStateMachine::OnNotDecoded(MediaData::Type aType,
|
||||
if (aReason == MediaDecoderReader::WAITING_FOR_DATA) {
|
||||
MOZ_ASSERT(mReader->IsWaitForDataSupported(),
|
||||
"Readers that send WAITING_FOR_DATA need to implement WaitForData");
|
||||
RequestStatusRef(aType) = RequestStatus::Waiting;
|
||||
mReader->WaitForData(aType)->Then(DecodeTaskQueue(), __func__, this,
|
||||
&MediaDecoderStateMachine::OnWaitForDataResolved,
|
||||
&MediaDecoderStateMachine::OnWaitForDataRejected);
|
||||
WaitRequestRef(aType).Begin(mReader->WaitForData(aType)
|
||||
->RefableThen(DecodeTaskQueue(), __func__, this,
|
||||
&MediaDecoderStateMachine::OnWaitForDataResolved,
|
||||
&MediaDecoderStateMachine::OnWaitForDataRejected));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -940,7 +942,7 @@ MediaDecoderStateMachine::OnVideoDecoded(VideoData* aVideoSample)
|
||||
MOZ_ASSERT(OnDecodeThread());
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
nsRefPtr<VideoData> video(aVideoSample);
|
||||
mVideoRequestStatus = RequestStatus::Idle;
|
||||
mVideoDataRequest.Complete();
|
||||
mDecodedVideoEndTime = video ? video->GetEndTime() : mDecodedVideoEndTime;
|
||||
|
||||
SAMPLE_LOG("OnVideoDecoded [%lld,%lld] disc=%d",
|
||||
@ -1863,9 +1865,9 @@ MediaDecoderStateMachine::DispatchDecodeTasksIfNeeded()
|
||||
!needToDecodeVideo &&
|
||||
!IsPlaying();
|
||||
|
||||
SAMPLE_LOG("DispatchDecodeTasksIfNeeded needAudio=%d audioStatus=%d needVideo=%d videoStatus=%d needIdle=%d",
|
||||
needToDecodeAudio, mAudioRequestStatus,
|
||||
needToDecodeVideo, mVideoRequestStatus,
|
||||
SAMPLE_LOG("DispatchDecodeTasksIfNeeded needAudio=%d audioStatus=%s needVideo=%d videoStatus=%s needIdle=%d",
|
||||
needToDecodeAudio, AudioRequestStatus(),
|
||||
needToDecodeVideo, VideoRequestStatus(),
|
||||
needIdle);
|
||||
|
||||
if (needToDecodeAudio) {
|
||||
@ -1924,8 +1926,8 @@ MediaDecoderStateMachine::EnsureAudioDecodeTaskQueued()
|
||||
NS_ASSERTION(OnStateMachineThread() || OnDecodeThread(),
|
||||
"Should be on state machine or decode thread.");
|
||||
|
||||
SAMPLE_LOG("EnsureAudioDecodeTaskQueued isDecoding=%d status=%d",
|
||||
IsAudioDecoding(), mAudioRequestStatus);
|
||||
SAMPLE_LOG("EnsureAudioDecodeTaskQueued isDecoding=%d status=%s",
|
||||
IsAudioDecoding(), AudioRequestStatus());
|
||||
|
||||
if (mState != DECODER_STATE_DECODING &&
|
||||
mState != DECODER_STATE_DECODING_FIRSTFRAME &&
|
||||
@ -1934,18 +1936,19 @@ MediaDecoderStateMachine::EnsureAudioDecodeTaskQueued()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!IsAudioDecoding() || mAudioRequestStatus != RequestStatus::Idle || mWaitingForDecoderSeek) {
|
||||
if (!IsAudioDecoding() || mAudioDataRequest.Exists() ||
|
||||
mAudioWaitRequest.Exists() || mWaitingForDecoderSeek) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
SAMPLE_LOG("Queueing audio task - queued=%i, decoder-queued=%o",
|
||||
AudioQueue().GetSize(), mReader->SizeOfAudioQueueInFrames());
|
||||
|
||||
mAudioRequestStatus = RequestStatus::Pending;
|
||||
ProxyMediaCall(DecodeTaskQueue(), mReader.get(), __func__, &MediaDecoderReader::RequestAudioData)
|
||||
->Then(DecodeTaskQueue(), __func__, this,
|
||||
&MediaDecoderStateMachine::OnAudioDecoded,
|
||||
&MediaDecoderStateMachine::OnAudioNotDecoded);
|
||||
mAudioDataRequest.Begin(ProxyMediaCall(DecodeTaskQueue(), mReader.get(),
|
||||
__func__, &MediaDecoderReader::RequestAudioData)
|
||||
->RefableThen(DecodeTaskQueue(), __func__, this,
|
||||
&MediaDecoderStateMachine::OnAudioDecoded,
|
||||
&MediaDecoderStateMachine::OnAudioNotDecoded));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1969,8 +1972,8 @@ MediaDecoderStateMachine::EnsureVideoDecodeTaskQueued()
|
||||
{
|
||||
AssertCurrentThreadInMonitor();
|
||||
|
||||
SAMPLE_LOG("EnsureVideoDecodeTaskQueued isDecoding=%d status=%d",
|
||||
IsVideoDecoding(), mVideoRequestStatus);
|
||||
SAMPLE_LOG("EnsureVideoDecodeTaskQueued isDecoding=%d status=%s",
|
||||
IsVideoDecoding(), VideoRequestStatus());
|
||||
|
||||
NS_ASSERTION(OnStateMachineThread() || OnDecodeThread(),
|
||||
"Should be on state machine or decode thread.");
|
||||
@ -1982,7 +1985,8 @@ MediaDecoderStateMachine::EnsureVideoDecodeTaskQueued()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!IsVideoDecoding() || mVideoRequestStatus != RequestStatus::Idle || mWaitingForDecoderSeek) {
|
||||
if (!IsVideoDecoding() || mVideoDataRequest.Exists() ||
|
||||
mVideoWaitRequest.Exists() || mWaitingForDecoderSeek) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1998,13 +2002,12 @@ MediaDecoderStateMachine::EnsureVideoDecodeTaskQueued()
|
||||
VideoQueue().GetSize(), mReader->SizeOfVideoQueueInFrames(), skipToNextKeyFrame,
|
||||
currentTime);
|
||||
|
||||
mVideoRequestStatus = RequestStatus::Pending;
|
||||
ProxyMediaCall(DecodeTaskQueue(), mReader.get(), __func__,
|
||||
&MediaDecoderReader::RequestVideoData, skipToNextKeyFrame, currentTime)
|
||||
->Then(DecodeTaskQueue(), __func__, this,
|
||||
&MediaDecoderStateMachine::OnVideoDecoded,
|
||||
&MediaDecoderStateMachine::OnVideoNotDecoded);
|
||||
|
||||
mVideoDataRequest.Begin(ProxyMediaCall(DecodeTaskQueue(), mReader.get(), __func__,
|
||||
&MediaDecoderReader::RequestVideoData,
|
||||
skipToNextKeyFrame, currentTime)
|
||||
->RefableThen(DecodeTaskQueue(), __func__, this,
|
||||
&MediaDecoderStateMachine::OnVideoDecoded,
|
||||
&MediaDecoderStateMachine::OnVideoNotDecoded));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -2287,21 +2290,22 @@ MediaDecoderStateMachine::DecodeFirstFrame()
|
||||
nsresult res = FinishDecodeFirstFrame();
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
} else {
|
||||
// NB: We're already on the decode thread, but we proxy these anyway so that
|
||||
// we don't need to worry about dropping locks.
|
||||
if (HasAudio()) {
|
||||
mAudioRequestStatus = RequestStatus::Pending;
|
||||
ReentrantMonitorAutoExit unlock(mDecoder->GetReentrantMonitor());
|
||||
mReader->RequestAudioData()->Then(DecodeTaskQueue(), __func__, this,
|
||||
&MediaDecoderStateMachine::OnAudioDecoded,
|
||||
&MediaDecoderStateMachine::OnAudioNotDecoded);
|
||||
mAudioDataRequest.Begin(ProxyMediaCall(DecodeTaskQueue(), mReader.get(),
|
||||
__func__, &MediaDecoderReader::RequestAudioData)
|
||||
->RefableThen(DecodeTaskQueue(), __func__, this,
|
||||
&MediaDecoderStateMachine::OnAudioDecoded,
|
||||
&MediaDecoderStateMachine::OnAudioNotDecoded));
|
||||
}
|
||||
if (HasVideo()) {
|
||||
mVideoDecodeStartTime = TimeStamp::Now();
|
||||
mVideoRequestStatus = RequestStatus::Pending;
|
||||
ReentrantMonitorAutoExit unlock(mDecoder->GetReentrantMonitor());
|
||||
mReader->RequestVideoData(false, 0)
|
||||
->Then(DecodeTaskQueue(), __func__, this,
|
||||
&MediaDecoderStateMachine::OnVideoDecoded,
|
||||
&MediaDecoderStateMachine::OnVideoNotDecoded);
|
||||
mVideoDataRequest.Begin(ProxyMediaCall(DecodeTaskQueue(), mReader.get(),
|
||||
__func__, &MediaDecoderReader::RequestVideoData, false, int64_t(0))
|
||||
->RefableThen(DecodeTaskQueue(), __func__, this,
|
||||
&MediaDecoderStateMachine::OnVideoDecoded,
|
||||
&MediaDecoderStateMachine::OnVideoNotDecoded));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2758,8 +2762,6 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
|
||||
DebugOnly<nsresult> rv = DecodeTaskQueue()->Dispatch(
|
||||
NS_NewRunnableMethod(mReader, &MediaDecoderReader::ReleaseMediaResources));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
mAudioRequestStatus = RequestStatus::Idle;
|
||||
mVideoRequestStatus = RequestStatus::Idle;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -2827,12 +2829,12 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
|
||||
MOZ_ASSERT(mReader->IsWaitForDataSupported(),
|
||||
"Don't yet have a strategy for non-heuristic + non-WaitForData");
|
||||
DispatchDecodeTasksIfNeeded();
|
||||
MOZ_ASSERT_IF(!mMinimizePreroll && OutOfDecodedAudio(), mAudioRequestStatus != RequestStatus::Idle);
|
||||
MOZ_ASSERT_IF(!mMinimizePreroll && OutOfDecodedVideo(), mVideoRequestStatus != RequestStatus::Idle);
|
||||
MOZ_ASSERT_IF(!mMinimizePreroll && OutOfDecodedAudio(), mAudioDataRequest.Exists() || mAudioWaitRequest.Exists());
|
||||
MOZ_ASSERT_IF(!mMinimizePreroll && OutOfDecodedVideo(), mVideoDataRequest.Exists() || mVideoWaitRequest.Exists());
|
||||
DECODER_LOG("In buffering mode, waiting to be notified: outOfAudio: %d, "
|
||||
"mAudioStatus: %d, outOfVideo: %d, mVideoStatus: %d",
|
||||
OutOfDecodedAudio(), mAudioRequestStatus,
|
||||
OutOfDecodedVideo(), mVideoRequestStatus);
|
||||
"mAudioStatus: %s, outOfVideo: %d, mVideoStatus: %s",
|
||||
OutOfDecodedAudio(), AudioRequestStatus(),
|
||||
OutOfDecodedVideo(), VideoRequestStatus());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -3096,8 +3098,8 @@ void MediaDecoderStateMachine::AdvanceFrame()
|
||||
(JustExitedQuickBuffering() || HasLowUndecodedData());
|
||||
} else {
|
||||
MOZ_ASSERT(mReader->IsWaitForDataSupported());
|
||||
shouldBuffer = (OutOfDecodedAudio() && mAudioRequestStatus == RequestStatus::Waiting) ||
|
||||
(OutOfDecodedVideo() && mVideoRequestStatus == RequestStatus::Waiting);
|
||||
shouldBuffer = (OutOfDecodedAudio() && mAudioWaitRequest.Exists()) ||
|
||||
(OutOfDecodedVideo() && mVideoWaitRequest.Exists());
|
||||
}
|
||||
if (shouldBuffer) {
|
||||
if (currentFrame) {
|
||||
|
@ -399,12 +399,10 @@ public:
|
||||
void OnNotDecoded(MediaData::Type aType, MediaDecoderReader::NotDecodedReason aReason);
|
||||
void OnAudioNotDecoded(MediaDecoderReader::NotDecodedReason aReason)
|
||||
{
|
||||
MOZ_ASSERT(OnDecodeThread());
|
||||
OnNotDecoded(MediaData::AUDIO_DATA, aReason);
|
||||
}
|
||||
void OnVideoNotDecoded(MediaDecoderReader::NotDecodedReason aReason)
|
||||
{
|
||||
MOZ_ASSERT(OnDecodeThread());
|
||||
OnNotDecoded(MediaData::VIDEO_DATA, aReason);
|
||||
}
|
||||
|
||||
@ -414,17 +412,14 @@ public:
|
||||
void OnWaitForDataResolved(MediaData::Type aType)
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
if (RequestStatusRef(aType) == RequestStatus::Waiting) {
|
||||
RequestStatusRef(aType) = RequestStatus::Idle;
|
||||
DispatchDecodeTasksIfNeeded();
|
||||
}
|
||||
WaitRequestRef(aType).Complete();
|
||||
DispatchDecodeTasksIfNeeded();
|
||||
}
|
||||
|
||||
void OnWaitForDataRejected(WaitForDataRejectValue aRejection)
|
||||
{
|
||||
if (RequestStatusRef(aRejection.mType) == RequestStatus::Waiting) {
|
||||
RequestStatusRef(aRejection.mType) = RequestStatus::Idle;
|
||||
}
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
WaitRequestRef(aRejection.mType).Complete();
|
||||
}
|
||||
|
||||
private:
|
||||
@ -1019,21 +1014,38 @@ protected:
|
||||
bool mIsAudioPrerolling;
|
||||
bool mIsVideoPrerolling;
|
||||
|
||||
enum class RequestStatus {
|
||||
Idle,
|
||||
Pending,
|
||||
Waiting
|
||||
};
|
||||
// Only one of a given pair of ({Audio,Video}DataPromise, WaitForDataPromise)
|
||||
// should exist at any given moment.
|
||||
|
||||
// True when we have dispatched a task to the decode task queue to request
|
||||
// decoded audio/video, and/or we are waiting for the requested sample to be
|
||||
// returned by callback from the Reader.
|
||||
RequestStatus mAudioRequestStatus;
|
||||
RequestStatus mVideoRequestStatus;
|
||||
|
||||
RequestStatus& RequestStatusRef(MediaData::Type aType)
|
||||
MediaPromiseConsumerHolder<MediaDecoderReader::AudioDataPromise> mAudioDataRequest;
|
||||
MediaPromiseConsumerHolder<MediaDecoderReader::WaitForDataPromise> mAudioWaitRequest;
|
||||
const char* AudioRequestStatus()
|
||||
{
|
||||
return aType == MediaData::AUDIO_DATA ? mAudioRequestStatus : mVideoRequestStatus;
|
||||
if (mAudioDataRequest.Exists()) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(!mAudioWaitRequest.Exists());
|
||||
return "pending";
|
||||
} else if (mAudioWaitRequest.Exists()) {
|
||||
return "waiting";
|
||||
}
|
||||
return "idle";
|
||||
}
|
||||
|
||||
MediaPromiseConsumerHolder<MediaDecoderReader::WaitForDataPromise> mVideoWaitRequest;
|
||||
MediaPromiseConsumerHolder<MediaDecoderReader::VideoDataPromise> mVideoDataRequest;
|
||||
const char* VideoRequestStatus()
|
||||
{
|
||||
if (mVideoDataRequest.Exists()) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(!mVideoWaitRequest.Exists());
|
||||
return "pending";
|
||||
} else if (mVideoWaitRequest.Exists()) {
|
||||
return "waiting";
|
||||
}
|
||||
return "idle";
|
||||
}
|
||||
|
||||
MediaPromiseConsumerHolder<MediaDecoderReader::WaitForDataPromise>& WaitRequestRef(MediaData::Type aType)
|
||||
{
|
||||
return aType == MediaData::AUDIO_DATA ? mAudioWaitRequest : mVideoWaitRequest;
|
||||
}
|
||||
|
||||
// True if we shouldn't play our audio (but still write it to any capturing
|
||||
|
@ -37,27 +37,28 @@ struct TrackInfo {
|
||||
// Stores info relevant to presenting media frames.
|
||||
class VideoInfo {
|
||||
private:
|
||||
VideoInfo(int32_t aWidth, int32_t aHeight, bool aHasVideo)
|
||||
: mDisplay(aWidth, aHeight)
|
||||
, mStereoMode(StereoMode::MONO)
|
||||
, mHasVideo(aHasVideo)
|
||||
, mIsHardwareAccelerated(false)
|
||||
void Init(int32_t aWidth, int32_t aHeight, bool aHasVideo)
|
||||
{
|
||||
mDisplay = nsIntSize(aWidth, aHeight);
|
||||
mStereoMode = StereoMode::MONO;
|
||||
mHasVideo = aHasVideo;
|
||||
mIsHardwareAccelerated = false;
|
||||
|
||||
// TODO: TrackInfo should be initialized by its specific codec decoder.
|
||||
// This following call should be removed once we have that implemented.
|
||||
mTrackInfo.Init(NS_LITERAL_STRING("2"), NS_LITERAL_STRING("main"),
|
||||
EmptyString(), EmptyString(), true);
|
||||
}
|
||||
|
||||
public:
|
||||
VideoInfo()
|
||||
: VideoInfo(0, 0, false)
|
||||
{
|
||||
// TODO: TrackInfo should be initialized by its specific codec decoder.
|
||||
// This following call should be removed once we have that implemented.
|
||||
mTrackInfo.Init(NS_LITERAL_STRING("2"), NS_LITERAL_STRING("main"),
|
||||
EmptyString(), EmptyString(), true);
|
||||
Init(0, 0, false);
|
||||
}
|
||||
|
||||
VideoInfo(int32_t aWidth, int32_t aHeight)
|
||||
: VideoInfo(aWidth, aHeight, true)
|
||||
{
|
||||
Init(aWidth, aHeight, true);
|
||||
}
|
||||
|
||||
// Size in pixels at which the video is rendered. This is after it has
|
||||
|
@ -240,8 +240,7 @@ protected:
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// Can't mark MOZ_OVERRIDE due to bug in clang builders we use for osx b2g desktop. :-(
|
||||
virtual void AssertOnDispatchThread()
|
||||
virtual void AssertOnDispatchThread() MOZ_OVERRIDE
|
||||
{
|
||||
detail::AssertOnThread(mResponseTarget);
|
||||
}
|
||||
|
@ -979,7 +979,7 @@ MediaRecorder::Constructor(const GlobalObject& aGlobal,
|
||||
nsresult
|
||||
MediaRecorder::CreateAndDispatchBlobEvent(already_AddRefed<nsIDOMBlob>&& aBlob)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Not running on main thread");
|
||||
if (!CheckPrincipal()) {
|
||||
// Media is not same-origin, don't allow the data out.
|
||||
nsRefPtr<nsIDOMBlob> blob = aBlob;
|
||||
@ -1003,7 +1003,7 @@ MediaRecorder::CreateAndDispatchBlobEvent(already_AddRefed<nsIDOMBlob>&& aBlob)
|
||||
void
|
||||
MediaRecorder::DispatchSimpleEvent(const nsAString & aStr)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Not running on main thread");
|
||||
nsresult rv = CheckInnerWindowCorrectness();
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
@ -1034,7 +1034,7 @@ MediaRecorder::DispatchSimpleEvent(const nsAString & aStr)
|
||||
void
|
||||
MediaRecorder::NotifyError(nsresult aRv)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Not running on main thread");
|
||||
nsresult rv = CheckInnerWindowCorrectness();
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
@ -1070,7 +1070,7 @@ MediaRecorder::NotifyError(nsresult aRv)
|
||||
|
||||
bool MediaRecorder::CheckPrincipal()
|
||||
{
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Not running on main thread");
|
||||
if (!mDOMStream && !mAudioNode) {
|
||||
return false;
|
||||
}
|
||||
|
@ -35,10 +35,10 @@ EMEVideoDecoder::GetNodeId()
|
||||
return mProxy->GetNodeId();
|
||||
}
|
||||
|
||||
GMPUniquePtr<GMPVideoEncodedFrame>
|
||||
GMPUnique<GMPVideoEncodedFrame>::Ptr
|
||||
EMEVideoDecoder::CreateFrame(mp4_demuxer::MP4Sample* aSample)
|
||||
{
|
||||
GMPUniquePtr<GMPVideoEncodedFrame> frame = GMPVideoDecoder::CreateFrame(aSample);
|
||||
GMPUnique<GMPVideoEncodedFrame>::Ptr frame = GMPVideoDecoder::CreateFrame(aSample);
|
||||
if (frame && aSample->crypto.valid) {
|
||||
static_cast<gmp::GMPVideoEncodedFrameImpl*>(frame.get())->InitCrypto(aSample->crypto);
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ public:
|
||||
private:
|
||||
virtual void InitTags(nsTArray<nsCString>& aTags) MOZ_OVERRIDE;
|
||||
virtual nsCString GetNodeId() MOZ_OVERRIDE;
|
||||
virtual GMPUniquePtr<GMPVideoEncodedFrame> CreateFrame(mp4_demuxer::MP4Sample* aSample) MOZ_OVERRIDE;
|
||||
virtual GMPUnique<GMPVideoEncodedFrame>::Ptr CreateFrame(mp4_demuxer::MP4Sample* aSample) MOZ_OVERRIDE;
|
||||
|
||||
nsRefPtr<CDMProxy> mProxy;
|
||||
};
|
||||
|
@ -17,7 +17,7 @@ static bool IsOnGMPThread();
|
||||
void
|
||||
VideoCallbackAdapter::Decoded(GMPVideoi420Frame* aDecodedFrame)
|
||||
{
|
||||
GMPUniquePtr<GMPVideoi420Frame> decodedFrame(aDecodedFrame);
|
||||
GMPUnique<GMPVideoi420Frame>::Ptr decodedFrame(aDecodedFrame);
|
||||
|
||||
MOZ_ASSERT(IsOnGMPThread());
|
||||
|
||||
@ -113,7 +113,7 @@ GMPVideoDecoder::GetNodeId()
|
||||
return NS_LITERAL_CSTRING("");
|
||||
}
|
||||
|
||||
GMPUniquePtr<GMPVideoEncodedFrame>
|
||||
GMPUnique<GMPVideoEncodedFrame>::Ptr
|
||||
GMPVideoDecoder::CreateFrame(mp4_demuxer::MP4Sample* aSample)
|
||||
{
|
||||
GMPVideoFrame* ftmp = nullptr;
|
||||
@ -123,7 +123,7 @@ GMPVideoDecoder::CreateFrame(mp4_demuxer::MP4Sample* aSample)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GMPUniquePtr<GMPVideoEncodedFrame> frame(static_cast<GMPVideoEncodedFrame*>(ftmp));
|
||||
GMPUnique<GMPVideoEncodedFrame>::Ptr frame(static_cast<GMPVideoEncodedFrame*>(ftmp));
|
||||
err = frame->CreateEmptyFrame(aSample->size);
|
||||
if (GMP_FAILED(err)) {
|
||||
mCallback->Error();
|
||||
@ -193,7 +193,7 @@ GMPVideoDecoder::Input(mp4_demuxer::MP4Sample* aSample)
|
||||
|
||||
mAdapter->SetLastStreamOffset(sample->byte_offset);
|
||||
|
||||
GMPUniquePtr<GMPVideoEncodedFrame> frame = CreateFrame(sample);
|
||||
GMPUnique<GMPVideoEncodedFrame>::Ptr frame = CreateFrame(sample);
|
||||
nsTArray<uint8_t> info; // No codec specific per-frame info to pass.
|
||||
nsresult rv = mGMP->Decode(Move(frame), false, info, 0);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -88,7 +88,7 @@ public:
|
||||
protected:
|
||||
virtual void InitTags(nsTArray<nsCString>& aTags);
|
||||
virtual nsCString GetNodeId();
|
||||
virtual GMPUniquePtr<GMPVideoEncodedFrame> CreateFrame(mp4_demuxer::MP4Sample* aSample);
|
||||
virtual GMPUnique<GMPVideoEncodedFrame>::Ptr CreateFrame(mp4_demuxer::MP4Sample* aSample);
|
||||
|
||||
private:
|
||||
const mp4_demuxer::VideoDecoderConfig& mConfig;
|
||||
|
@ -36,12 +36,12 @@ GMPProcessChild::Init()
|
||||
// (after the binary name) here is indeed the plugin module path.
|
||||
// Keep in sync with dom/plugins/PluginModuleParent.
|
||||
std::vector<std::string> values = CommandLine::ForCurrentProcess()->argv();
|
||||
NS_ABORT_IF_FALSE(values.size() >= 3, "not enough args");
|
||||
MOZ_ASSERT(values.size() >= 3, "not enough args");
|
||||
pluginFilename = values[1];
|
||||
voucherFilename = values[2];
|
||||
#elif defined(OS_WIN)
|
||||
std::vector<std::wstring> values = CommandLine::ForCurrentProcess()->GetLooseValues();
|
||||
NS_ABORT_IF_FALSE(values.size() >= 2, "not enough loose args");
|
||||
MOZ_ASSERT(values.size() >= 2, "not enough loose args");
|
||||
pluginFilename = WideToUTF8(values[0]);
|
||||
voucherFilename = WideToUTF8(values[1]);
|
||||
#else
|
||||
|
@ -18,8 +18,11 @@ struct DestroyPolicy
|
||||
}
|
||||
};
|
||||
|
||||
// Ideally, this would be a template alias, but GCC 4.6 doesn't support them. See bug 1124021.
|
||||
template<typename T>
|
||||
using GMPUniquePtr = mozilla::UniquePtr<T, DestroyPolicy<T>>;
|
||||
struct GMPUnique {
|
||||
typedef mozilla::UniquePtr<T, DestroyPolicy<T>> Ptr;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -109,7 +109,7 @@ GMPVideoDecoderParent::InitDecode(const GMPVideoCodec& aCodecSettings,
|
||||
}
|
||||
|
||||
nsresult
|
||||
GMPVideoDecoderParent::Decode(GMPUniquePtr<GMPVideoEncodedFrame> aInputFrame,
|
||||
GMPVideoDecoderParent::Decode(GMPUnique<GMPVideoEncodedFrame>::Ptr aInputFrame,
|
||||
bool aMissingFrames,
|
||||
const nsTArray<uint8_t>& aCodecSpecificInfo,
|
||||
int64_t aRenderTimeMs)
|
||||
@ -121,7 +121,7 @@ GMPVideoDecoderParent::Decode(GMPUniquePtr<GMPVideoEncodedFrame> aInputFrame,
|
||||
|
||||
MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
GMPUniquePtr<GMPVideoEncodedFrameImpl> inputFrameImpl(
|
||||
GMPUnique<GMPVideoEncodedFrameImpl>::Ptr inputFrameImpl(
|
||||
static_cast<GMPVideoEncodedFrameImpl*>(aInputFrame.release()));
|
||||
|
||||
// Very rough kill-switch if the plugin stops processing. If it's merely
|
||||
|
@ -38,7 +38,7 @@ public:
|
||||
const nsTArray<uint8_t>& aCodecSpecific,
|
||||
GMPVideoDecoderCallbackProxy* aCallback,
|
||||
int32_t aCoreCount) MOZ_OVERRIDE;
|
||||
virtual nsresult Decode(GMPUniquePtr<GMPVideoEncodedFrame> aInputFrame,
|
||||
virtual nsresult Decode(GMPUnique<GMPVideoEncodedFrame>::Ptr aInputFrame,
|
||||
bool aMissingFrames,
|
||||
const nsTArray<uint8_t>& aCodecSpecificInfo,
|
||||
int64_t aRenderTimeMs = -1) MOZ_OVERRIDE;
|
||||
|
@ -38,7 +38,7 @@ public:
|
||||
const nsTArray<uint8_t>& aCodecSpecific,
|
||||
GMPVideoDecoderCallbackProxy* aCallback,
|
||||
int32_t aCoreCount) = 0;
|
||||
virtual nsresult Decode(mozilla::GMPUniquePtr<GMPVideoEncodedFrame> aInputFrame,
|
||||
virtual nsresult Decode(mozilla::GMPUnique<GMPVideoEncodedFrame>::Ptr aInputFrame,
|
||||
bool aMissingFrames,
|
||||
const nsTArray<uint8_t>& aCodecSpecificInfo,
|
||||
int64_t aRenderTimeMs = -1) = 0;
|
||||
|
@ -126,7 +126,7 @@ GMPVideoEncoderParent::InitEncode(const GMPVideoCodec& aCodecSettings,
|
||||
}
|
||||
|
||||
GMPErr
|
||||
GMPVideoEncoderParent::Encode(GMPUniquePtr<GMPVideoi420Frame> aInputFrame,
|
||||
GMPVideoEncoderParent::Encode(GMPUnique<GMPVideoi420Frame>::Ptr aInputFrame,
|
||||
const nsTArray<uint8_t>& aCodecSpecificInfo,
|
||||
const nsTArray<GMPVideoFrameType>& aFrameTypes)
|
||||
{
|
||||
@ -137,7 +137,7 @@ GMPVideoEncoderParent::Encode(GMPUniquePtr<GMPVideoi420Frame> aInputFrame,
|
||||
|
||||
MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
GMPUniquePtr<GMPVideoi420FrameImpl> inputFrameImpl(
|
||||
GMPUnique<GMPVideoi420FrameImpl>::Ptr inputFrameImpl(
|
||||
static_cast<GMPVideoi420FrameImpl*>(aInputFrame.release()));
|
||||
|
||||
// Very rough kill-switch if the plugin stops processing. If it's merely
|
||||
|
@ -39,7 +39,7 @@ public:
|
||||
GMPVideoEncoderCallbackProxy* aCallback,
|
||||
int32_t aNumberOfCores,
|
||||
uint32_t aMaxPayloadSize) MOZ_OVERRIDE;
|
||||
virtual GMPErr Encode(GMPUniquePtr<GMPVideoi420Frame> aInputFrame,
|
||||
virtual GMPErr Encode(GMPUnique<GMPVideoi420Frame>::Ptr aInputFrame,
|
||||
const nsTArray<uint8_t>& aCodecSpecificInfo,
|
||||
const nsTArray<GMPVideoFrameType>& aFrameTypes) MOZ_OVERRIDE;
|
||||
virtual GMPErr SetChannelParameters(uint32_t aPacketLoss, uint32_t aRTT) MOZ_OVERRIDE;
|
||||
|
@ -40,7 +40,7 @@ public:
|
||||
GMPVideoEncoderCallbackProxy* aCallback,
|
||||
int32_t aNumberOfCores,
|
||||
uint32_t aMaxPayloadSize) = 0;
|
||||
virtual GMPErr Encode(mozilla::GMPUniquePtr<GMPVideoi420Frame> aInputFrame,
|
||||
virtual GMPErr Encode(mozilla::GMPUnique<GMPVideoi420Frame>::Ptr aInputFrame,
|
||||
const nsTArray<uint8_t>& aCodecSpecificInfo,
|
||||
const nsTArray<GMPVideoFrameType>& aFrameTypes) = 0;
|
||||
virtual GMPErr SetChannelParameters(uint32_t aPacketLoss, uint32_t aRTT) = 0;
|
||||
|
@ -39,5 +39,7 @@ skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac"))
|
||||
[test_SetModeThrows.html]
|
||||
[test_SplitAppendDelay.html]
|
||||
[test_SplitAppend.html]
|
||||
[test_TimestampOffset_mp4.html]
|
||||
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
|
||||
[test_WaitingOnMissingData.html]
|
||||
skip-if = android_version == '10' # bug 1115148 - frequent failures on Android 2.3
|
||||
|
83
dom/media/mediasource/test/test_TimestampOffset_mp4.html
Normal file
83
dom/media/mediasource/test/test_TimestampOffset_mp4.html
Normal file
@ -0,0 +1,83 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>MSE: basic functionality</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="mediasource.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function range(start, end) {
|
||||
var rv = [];
|
||||
for (var i = start; i < end; ++i) {
|
||||
rv.push(i);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
var eps = 0.01;
|
||||
runWithMSE(function(ms, el) {
|
||||
|
||||
once(ms, 'sourceopen').then(function() {
|
||||
ok(true, "Receive a sourceopen event");
|
||||
var audiosb = ms.addSourceBuffer("audio/mp4");
|
||||
var videosb = ms.addSourceBuffer("video/mp4");
|
||||
// We divide the video into 3 chunks:
|
||||
// chunk 0: segments 1-4
|
||||
// chunk 1: segments 5-8
|
||||
// chunk 2: segments 9-13
|
||||
// We then fill the timeline so that it seamlessly plays the chunks in order 0, 2, 1.
|
||||
var vchunks = [ {start: 0, end: 3.2033}, { start: 3.2033, end: 6.4066}, { start: 6.4066, end: 10.01} ];
|
||||
var firstvoffset = vchunks[2].end - vchunks[2].start; // Duration of chunk 2
|
||||
var secondvoffset = -(vchunks[1].end - vchunks[1].start); // -(Duration of chunk 1)
|
||||
|
||||
fetchAndLoad(videosb, 'bipbop/bipbop_video', ['init'], '.mp4')
|
||||
.then(fetchAndLoad.bind(null, videosb, 'bipbop/bipbop_video', range(1, 5), '.m4s'))
|
||||
.then(function() {
|
||||
is(videosb.buffered.length, 1, "No discontinuity");
|
||||
isfuzzy(videosb.buffered.start(0), vchunks[0].start, eps, "Chunk start");
|
||||
isfuzzy(videosb.buffered.end(0), vchunks[0].end, eps, "Chunk end");
|
||||
videosb.timestampOffset = firstvoffset;
|
||||
return fetchAndLoad(videosb, 'bipbop/bipbop_video', range(5, 9), '.m4s');
|
||||
})
|
||||
.then(function(data) {
|
||||
is(videosb.buffered.length, 2, "One discontinuity");
|
||||
isfuzzy(videosb.buffered.start(0), vchunks[0].start, eps, "First Chunk start");
|
||||
isfuzzy(videosb.buffered.end(0), vchunks[0].end, eps, "First chunk end");
|
||||
isfuzzy(videosb.buffered.start(1), vchunks[1].start + firstvoffset, eps, "Second chunk start");
|
||||
isfuzzy(videosb.buffered.end(1), vchunks[1].end + firstvoffset, eps, "Second chunk end");
|
||||
videosb.timestampOffset = secondvoffset;
|
||||
return fetchAndLoad(videosb, 'bipbop/bipbop_video', range(9, 14), '.m4s');
|
||||
})
|
||||
.then(function() {
|
||||
is(videosb.buffered.length, 1, "No discontinuity (end)");
|
||||
isfuzzy(videosb.buffered.start(0), vchunks[0].start, eps, "Chunk start");
|
||||
isfuzzy(videosb.buffered.end(0), vchunks[2].end, eps, "Chunk end");
|
||||
audiosb.timestampOffset = 3;
|
||||
}).then(fetchAndLoad.bind(null, audiosb, 'bipbop/bipbop_audio', ['init'], '.mp4'))
|
||||
.then(fetchAndLoad.bind(null, audiosb, 'bipbop/bipbop_audio', range(1, 12), '.m4s'))
|
||||
.then(function() {
|
||||
is(audiosb.buffered.length, 1, "No audio discontinuity");
|
||||
isfuzzy(audiosb.buffered.start(0), 3, eps, "Audio starts at 3");
|
||||
|
||||
// Trim the rest of the audio.
|
||||
ms.duration = videosb.buffered.end(0);
|
||||
return Promise.all([audiosb.updating ? once(audiosb, 'updateend') : Promise.resolve(),
|
||||
videosb.updating ? once(videosb, 'updateend') : Promise.resolve()]);
|
||||
}).then(function() {
|
||||
ms.endOfStream();
|
||||
once(el, 'ended').then(SimpleTest.finish.bind(SimpleTest));
|
||||
el.play();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -73,7 +73,7 @@ function Log(token, msg) {
|
||||
info(TimeStamp(token) + " " + msg);
|
||||
}
|
||||
|
||||
function UpdateSessionFunc(test, token, sessionType) {
|
||||
function UpdateSessionFunc(test, token, sessionType, resolve, reject) {
|
||||
return function(ev) {
|
||||
var msgStr = ArrayBufferToString(ev.message);
|
||||
var msg = JSON.parse(msgStr);
|
||||
@ -110,7 +110,11 @@ function UpdateSessionFunc(test, token, sessionType) {
|
||||
|
||||
ev.target.update(StringToArrayBuffer(update)).then(function() {
|
||||
Log(token, "MediaKeySession update ok!");
|
||||
}, bail(token + " MediaKeySession update failed"));
|
||||
resolve(ev.target);
|
||||
}).catch(function(reason) {
|
||||
bail(token + " MediaKeySession update failed")(reason);
|
||||
reject();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -223,31 +227,57 @@ function SetupEME(test, token, params)
|
||||
videoType: test.type,
|
||||
}
|
||||
];
|
||||
navigator.requestMediaKeySystemAccess(KEYSYSTEM_TYPE, options)
|
||||
.then(function(keySystemAccess) {
|
||||
return keySystemAccess.createMediaKeys();
|
||||
}, bail(token + " Failed to request key system access."))
|
||||
|
||||
.then(function(mediaKeys) {
|
||||
Log(token, "created MediaKeys object ok");
|
||||
mediaKeys.sessions = [];
|
||||
return v.setMediaKeys(mediaKeys);
|
||||
}, bail("failed to create MediaKeys object"))
|
||||
function chain(promise, onReject) {
|
||||
return promise.then(function(value) {
|
||||
return Promise.resolve(value);
|
||||
}).catch(function(reason) {
|
||||
onReject(reason);
|
||||
return Promise.reject();
|
||||
})
|
||||
}
|
||||
|
||||
.then(function() {
|
||||
Log(token, "set MediaKeys on <video> element ok");
|
||||
var sessionType = (params && params.sessionType) ? params.sessionType : "temporary";
|
||||
var session = v.mediaKeys.createSession(sessionType);
|
||||
if (params && params.onsessioncreated) {
|
||||
params.onsessioncreated(session);
|
||||
}
|
||||
session.addEventListener("message", UpdateSessionFunc(test, token, sessionType));
|
||||
return session.generateRequest(ev.initDataType, ev.initData);
|
||||
}, onSetKeysFail)
|
||||
var p = navigator.requestMediaKeySystemAccess(KEYSYSTEM_TYPE, options);
|
||||
var r = bail(token + " Failed to request key system access.");
|
||||
chain(p, r)
|
||||
.then(function(keySystemAccess) {
|
||||
var p = keySystemAccess.createMediaKeys();
|
||||
var r = bail(token + " Failed to create MediaKeys object");
|
||||
return chain(p, r);
|
||||
})
|
||||
|
||||
.then(function() {
|
||||
Log(token, "generated request");
|
||||
}, bail(token + " Failed to request key system access2."));
|
||||
.then(function(mediaKeys) {
|
||||
Log(token, "created MediaKeys object ok");
|
||||
mediaKeys.sessions = [];
|
||||
var p = v.setMediaKeys(mediaKeys);
|
||||
return chain(p, onSetKeysFail);
|
||||
})
|
||||
|
||||
.then(function() {
|
||||
Log(token, "set MediaKeys on <video> element ok");
|
||||
var sessionType = (params && params.sessionType) ? params.sessionType : "temporary";
|
||||
var session = v.mediaKeys.createSession(sessionType);
|
||||
if (params && params.onsessioncreated) {
|
||||
params.onsessioncreated(session);
|
||||
}
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
session.addEventListener("message", UpdateSessionFunc(test, token, sessionType, resolve, reject));
|
||||
session.generateRequest(ev.initDataType, ev.initData).catch(function(reason) {
|
||||
// Reject the promise if generateRequest() failed. Otherwise it will
|
||||
// be resolve in UpdateSessionFunc().
|
||||
bail(token + ": session.generateRequest failed")(reason);
|
||||
reject();
|
||||
});
|
||||
});
|
||||
})
|
||||
|
||||
.then(function(session) {
|
||||
Log(token, ": session.generateRequest succeeded");
|
||||
if (params && params.onsessionupdated) {
|
||||
params.onsessionupdated(session);
|
||||
}
|
||||
});
|
||||
});
|
||||
return v;
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ function UsableKeyIdsMatch(usableKeyIds, expectedKeyIds) {
|
||||
|
||||
function AwaitAllKeysUsable(session, keys, token) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
function listener(event) {
|
||||
function check() {
|
||||
var map = session.keyStatuses;
|
||||
var usableKeyIds = [];
|
||||
for (var [key, val] of map.entries()) {
|
||||
@ -38,25 +38,26 @@ function AwaitAllKeysUsable(session, keys, token) {
|
||||
usableKeyIds.push(key);
|
||||
}
|
||||
if (UsableKeyIdsMatch(usableKeyIds, keys)) {
|
||||
Log(token, "resolving AwaitAllKeysUsable promise");
|
||||
session.removeEventListener("keystatuseschange", listener);
|
||||
session.removeEventListener("keystatuseschange", check);
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
session.addEventListener("keystatuseschange", listener);
|
||||
session.addEventListener("keystatuseschange", check);
|
||||
check(); // in case all keys are already usable
|
||||
});
|
||||
}
|
||||
|
||||
function AwaitAllKeysNotUsable(session, token) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
function listener(event) {
|
||||
function check() {
|
||||
var map = session.keyStatuses;
|
||||
if (map.size == 0) {
|
||||
session.removeEventListener("keystatuseschange", listener);
|
||||
session.removeEventListener("keystatuseschange", check);
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
session.addEventListener("keystatuseschange", listener);
|
||||
session.addEventListener("keystatuseschange", check);
|
||||
check(); // in case all keys are already removed
|
||||
});
|
||||
}
|
||||
|
||||
@ -70,59 +71,76 @@ function startTest(test, token)
|
||||
|
||||
var v = SetupEME(test, token,
|
||||
{
|
||||
onsessioncreated: function(session) {
|
||||
onsessionupdated: function(session) {
|
||||
Log(token, "Session created");
|
||||
var sessionId;
|
||||
initialSession = session;
|
||||
|
||||
// Once the session has loaded and has all its keys usable, close
|
||||
// all sessions without calling remove() on them.
|
||||
AwaitAllKeysUsable(session, test.keys, token).then(
|
||||
function() {
|
||||
sessionId = session.sessionId;
|
||||
Log(token, "Closing session with id=" + sessionId);
|
||||
session.close();
|
||||
}
|
||||
);
|
||||
AwaitAllKeysUsable(session, test.keys, token)
|
||||
.then(function() {
|
||||
sessionId = session.sessionId;
|
||||
Log(token, "Closing session with id=" + sessionId);
|
||||
return session.close();
|
||||
})
|
||||
|
||||
// Once the session is closed, reload the MediaKeys and reload the session
|
||||
session.closed.then(function() {
|
||||
return navigator.requestMediaKeySystemAccess(KEYSYSTEM_TYPE)
|
||||
}, bail("close promise rejected"))
|
||||
.then(function() {
|
||||
return navigator.requestMediaKeySystemAccess(KEYSYSTEM_TYPE);
|
||||
})
|
||||
|
||||
.then(function(requestedKeySystemAccess) {
|
||||
keySystemAccess = requestedKeySystemAccess;
|
||||
return keySystemAccess.createMediaKeys();
|
||||
}, bail(token + " Failed to request key system access."))
|
||||
})
|
||||
|
||||
.then(function(mediaKeys) {
|
||||
Log(token, "re-created MediaKeys object ok");
|
||||
recreatedSession = mediaKeys.createSession("persistent");
|
||||
Log(token, "Created recreatedSession, loading sessionId=" + sessionId);
|
||||
return Promise.all([AwaitAllKeysUsable(recreatedSession, test.keys, token), recreatedSession.load(sessionId)]);
|
||||
}, bail(token + " failed to create mediaKeys"))
|
||||
return recreatedSession.load(sessionId);
|
||||
})
|
||||
|
||||
.then(function(suceeded) {
|
||||
if (suceeded) {
|
||||
return Promise.resolve();
|
||||
} else {
|
||||
return Promise.reject("Fail to load recreatedSession, sessionId=" + sessionId);
|
||||
}
|
||||
})
|
||||
|
||||
.then(function() {
|
||||
return AwaitAllKeysUsable(recreatedSession, test.keys, token);
|
||||
})
|
||||
|
||||
.then(function() {
|
||||
Log(token, "re-loaded persistent session, all keys still usable");
|
||||
return Promise.all([AwaitAllKeysNotUsable(recreatedSession, token), recreatedSession.remove()]);
|
||||
}, bail(token + " failed to get reload session or keys"))
|
||||
})
|
||||
|
||||
.then(function() {
|
||||
Log(token, "removed session, all keys unusable.");
|
||||
// Attempt to recreate the session, the attempt should fail.
|
||||
return keySystemAccess.createMediaKeys();
|
||||
}, bail(token + " failed to remove session"))
|
||||
})
|
||||
|
||||
.then(function(mediaKeys) {
|
||||
Log(token, "re-re-created MediaKeys object ok");
|
||||
// Trying to load the removed persistent session should fail.
|
||||
return mediaKeys.createSession("persistent").load(sessionId);
|
||||
}, bail(token + " failed to create mediaKeys"))
|
||||
})
|
||||
|
||||
.then(function(suceeded) {
|
||||
is(suceeded, false, token + " we expect the third session creation to fail, as the session should have been removed.");
|
||||
manager.finished(token);
|
||||
}, bail(token + " failure to load session."));
|
||||
})
|
||||
|
||||
.catch(function(reason) {
|
||||
// Catch rejections if any.
|
||||
ok(false, token + " rejected, reason=" + reason);
|
||||
manager.finished(token);
|
||||
});
|
||||
|
||||
},
|
||||
sessionType: "persistent",
|
||||
|
@ -88,7 +88,13 @@ function startTest(test, token)
|
||||
manager.finished(token);
|
||||
});
|
||||
|
||||
LoadTest(test, v, token).then(function(){v.play();}, bail(token + " failed to load"));
|
||||
LoadTest(test, v, token)
|
||||
.then(function() {
|
||||
v.play();
|
||||
}).catch(function() {
|
||||
ok(false, token + " failed to load");
|
||||
manager.finished(token);
|
||||
});
|
||||
}
|
||||
|
||||
function beginTest() {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user