зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to inbound. a=merge
This commit is contained in:
Коммит
377a09c902
|
@ -22,6 +22,10 @@ const Cu = Components.utils;
|
||||||
Cu.import('resource://gre/modules/Services.jsm');
|
Cu.import('resource://gre/modules/Services.jsm');
|
||||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||||
|
|
||||||
|
XPCOMUtils.defineLazyServiceGetter(this, "settings",
|
||||||
|
"@mozilla.org/settingsService;1",
|
||||||
|
"nsISettingsService");
|
||||||
|
|
||||||
function debug(msg) {
|
function debug(msg) {
|
||||||
log(msg);
|
log(msg);
|
||||||
}
|
}
|
||||||
|
@ -89,14 +93,19 @@ ProcessGlobal.prototype = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
processWipeFile: function(text) {
|
processCommandsFile: function(text) {
|
||||||
log("processWipeFile " + text);
|
log("processCommandsFile " + text);
|
||||||
let lines = text.split("\n");
|
let lines = text.split("\n");
|
||||||
lines.forEach((line) => {
|
lines.forEach((line) => {
|
||||||
log(line);
|
log(line);
|
||||||
let params = line.split(" ");
|
let params = line.split(" ");
|
||||||
if (params[0] == "wipe") {
|
if (params[0] == "wipe") {
|
||||||
this.wipeDir(params[1]);
|
this.wipeDir(params[1]);
|
||||||
|
} else if (params[0] == "root") {
|
||||||
|
log("unrestrict devtools");
|
||||||
|
Services.prefs.setBoolPref("devtools.debugger.forbid-certified-apps", false);
|
||||||
|
let lock = settings.createLock();
|
||||||
|
lock.set("developer.menu.enabled", true, null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -113,7 +122,7 @@ ProcessGlobal.prototype = {
|
||||||
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
|
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
|
||||||
file.initWithPath(postResetFile);
|
file.initWithPath(postResetFile);
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
debug("Nothing to wipe.")
|
debug("No additional command.")
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +131,7 @@ ProcessGlobal.prototype = {
|
||||||
(array) => {
|
(array) => {
|
||||||
file.remove(false);
|
file.remove(false);
|
||||||
let decoder = new TextDecoder();
|
let decoder = new TextDecoder();
|
||||||
this.processWipeFile(decoder.decode(array));
|
this.processCommandsFile(decoder.decode(array));
|
||||||
},
|
},
|
||||||
function onError(error) {
|
function onError(error) {
|
||||||
debug("Error: " + error);
|
debug("Error: " + error);
|
||||||
|
|
|
@ -81,19 +81,24 @@ RecoveryService.prototype = {
|
||||||
}
|
}
|
||||||
|
|
||||||
log("factoryReset " + reason);
|
log("factoryReset " + reason);
|
||||||
|
let commands = [];
|
||||||
if (reason == "wipe") {
|
if (reason == "wipe") {
|
||||||
let volumeService = Cc["@mozilla.org/telephony/volume-service;1"]
|
let volumeService = Cc["@mozilla.org/telephony/volume-service;1"]
|
||||||
.getService(Ci.nsIVolumeService);
|
.getService(Ci.nsIVolumeService);
|
||||||
let volNames = volumeService.getVolumeNames();
|
let volNames = volumeService.getVolumeNames();
|
||||||
log("Found " + volNames.length + " volumes");
|
log("Found " + volNames.length + " volumes");
|
||||||
let text = "";
|
|
||||||
for (let i = 0; i < volNames.length; i++) {
|
for (let i = 0; i < volNames.length; i++) {
|
||||||
let name = volNames.queryElementAt(i, Ci.nsISupportsString);
|
let name = volNames.queryElementAt(i, Ci.nsISupportsString);
|
||||||
let volume = volumeService.getVolumeByName(name.data);
|
let volume = volumeService.getVolumeByName(name.data);
|
||||||
log("Got volume: " + name.data + " at " + volume.mountPoint);
|
log("Got volume: " + name.data + " at " + volume.mountPoint);
|
||||||
text += "wipe " + volume.mountPoint + "\n";
|
commands.push("wipe " + volume.mountPoint);
|
||||||
}
|
}
|
||||||
|
} else if (reason == "root") {
|
||||||
|
commands.push("root");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (commands.length > 0) {
|
||||||
Cu.import("resource://gre/modules/osfile.jsm");
|
Cu.import("resource://gre/modules/osfile.jsm");
|
||||||
let dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
|
let dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
|
||||||
dir.initWithPath("/persist");
|
dir.initWithPath("/persist");
|
||||||
|
@ -101,6 +106,7 @@ RecoveryService.prototype = {
|
||||||
OS.Path.join("/persist", gFactoryResetFile):
|
OS.Path.join("/persist", gFactoryResetFile):
|
||||||
OS.Path.join("/cache", gFactoryResetFile);
|
OS.Path.join("/cache", gFactoryResetFile);
|
||||||
let encoder = new TextEncoder();
|
let encoder = new TextEncoder();
|
||||||
|
let text = commands.join("\n");
|
||||||
let array = encoder.encode(text);
|
let array = encoder.encode(text);
|
||||||
let promise = OS.File.writeAtomic(postResetFile, array,
|
let promise = OS.File.writeAtomic(postResetFile, array,
|
||||||
{ tmpPath: postResetFile + ".tmp" });
|
{ tmpPath: postResetFile + ".tmp" });
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="6cfde14a9fc87659963092a6b9d7898a8c23ec74"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="bd4dcc8c4582e2368b47b0e62506d3031fb2fc09"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6cfde14a9fc87659963092a6b9d7898a8c23ec74"/>
|
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd4dcc8c4582e2368b47b0e62506d3031fb2fc09"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
|
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
</project>
|
</project>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="6cfde14a9fc87659963092a6b9d7898a8c23ec74"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="bd4dcc8c4582e2368b47b0e62506d3031fb2fc09"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="a3e4614c7fb0a6ffa8c748bf5d49b34612c9d6d4"/>
|
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="a3e4614c7fb0a6ffa8c748bf5d49b34612c9d6d4"/>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="6cfde14a9fc87659963092a6b9d7898a8c23ec74"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="bd4dcc8c4582e2368b47b0e62506d3031fb2fc09"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6cfde14a9fc87659963092a6b9d7898a8c23ec74"/>
|
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd4dcc8c4582e2368b47b0e62506d3031fb2fc09"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
|
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="6cfde14a9fc87659963092a6b9d7898a8c23ec74"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="bd4dcc8c4582e2368b47b0e62506d3031fb2fc09"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
</project>
|
</project>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="6cfde14a9fc87659963092a6b9d7898a8c23ec74"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="bd4dcc8c4582e2368b47b0e62506d3031fb2fc09"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="a3e4614c7fb0a6ffa8c748bf5d49b34612c9d6d4"/>
|
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="a3e4614c7fb0a6ffa8c748bf5d49b34612c9d6d4"/>
|
||||||
|
|
|
@ -4,6 +4,6 @@
|
||||||
"remote": "",
|
"remote": "",
|
||||||
"branch": ""
|
"branch": ""
|
||||||
},
|
},
|
||||||
"revision": "5f064a62ce5ee63c6f75ff3422a7472bec71f7bf",
|
"revision": "0d6dca3dab03252cef2eb22079d0cab6362eda1e",
|
||||||
"repo_path": "integration/gaia-central"
|
"repo_path": "integration/gaia-central"
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6cfde14a9fc87659963092a6b9d7898a8c23ec74"/>
|
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd4dcc8c4582e2368b47b0e62506d3031fb2fc09"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6cfde14a9fc87659963092a6b9d7898a8c23ec74"/>
|
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd4dcc8c4582e2368b47b0e62506d3031fb2fc09"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
</project>
|
</project>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="6cfde14a9fc87659963092a6b9d7898a8c23ec74"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="bd4dcc8c4582e2368b47b0e62506d3031fb2fc09"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="a3e4614c7fb0a6ffa8c748bf5d49b34612c9d6d4"/>
|
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="a3e4614c7fb0a6ffa8c748bf5d49b34612c9d6d4"/>
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6cfde14a9fc87659963092a6b9d7898a8c23ec74"/>
|
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd4dcc8c4582e2368b47b0e62506d3031fb2fc09"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||||
|
|
|
@ -346,6 +346,7 @@ let LoopRoomsInternal = {
|
||||||
.then(response => {
|
.then(response => {
|
||||||
this.rooms.delete(roomToken);
|
this.rooms.delete(roomToken);
|
||||||
eventEmitter.emit("delete", room);
|
eventEmitter.emit("delete", room);
|
||||||
|
eventEmitter.emit("delete:" + room.roomToken, room);
|
||||||
callback(null, room);
|
callback(null, room);
|
||||||
}, error => callback(error)).catch(error => callback(error));
|
}, error => callback(error)).catch(error => callback(error));
|
||||||
},
|
},
|
||||||
|
|
|
@ -211,6 +211,8 @@ loop.store.ActiveRoomStore = (function() {
|
||||||
|
|
||||||
this._mozLoop.rooms.on("update:" + actionData.roomToken,
|
this._mozLoop.rooms.on("update:" + actionData.roomToken,
|
||||||
this._handleRoomUpdate.bind(this));
|
this._handleRoomUpdate.bind(this));
|
||||||
|
this._mozLoop.rooms.on("delete:" + actionData.roomToken,
|
||||||
|
this._handleRoomDelete.bind(this));
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -230,6 +232,8 @@ loop.store.ActiveRoomStore = (function() {
|
||||||
|
|
||||||
this._mozLoop.rooms.on("update:" + actionData.roomToken,
|
this._mozLoop.rooms.on("update:" + actionData.roomToken,
|
||||||
this._handleRoomUpdate.bind(this));
|
this._handleRoomUpdate.bind(this));
|
||||||
|
this._mozLoop.rooms.on("delete:" + actionData.roomToken,
|
||||||
|
this._handleRoomDelete.bind(this));
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -259,6 +263,18 @@ loop.store.ActiveRoomStore = (function() {
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the deletion of a room, notified by the mozLoop rooms API.
|
||||||
|
*
|
||||||
|
* @param {String} eventName The name of the event
|
||||||
|
* @param {Object} roomData The roomData of the deleted room
|
||||||
|
*/
|
||||||
|
_handleRoomDelete: function(eventName, roomData) {
|
||||||
|
this._sdkDriver.forceDisconnectAll(function() {
|
||||||
|
window.close();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the action to join to a room.
|
* Handles the action to join to a room.
|
||||||
*/
|
*/
|
||||||
|
@ -391,7 +407,9 @@ loop.store.ActiveRoomStore = (function() {
|
||||||
this._leaveRoom(ROOM_STATES.CLOSING);
|
this._leaveRoom(ROOM_STATES.CLOSING);
|
||||||
|
|
||||||
// If we're closing the window, we can stop listening to updates.
|
// If we're closing the window, we can stop listening to updates.
|
||||||
this._mozLoop.rooms.off("update:" + this.getStoreState().roomToken);
|
var roomToken = this.getStoreState().roomToken;
|
||||||
|
this._mozLoop.rooms.off("update:" + roomToken);
|
||||||
|
this._mozLoop.rooms.off("delete:" + roomToken);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -25,6 +25,8 @@ loop.OTSdkDriver = (function() {
|
||||||
this.dispatcher = options.dispatcher;
|
this.dispatcher = options.dispatcher;
|
||||||
this.sdk = options.sdk;
|
this.sdk = options.sdk;
|
||||||
|
|
||||||
|
this.connections = {};
|
||||||
|
|
||||||
this.dispatcher.register(this, [
|
this.dispatcher.register(this, [
|
||||||
"setupStreamElements",
|
"setupStreamElements",
|
||||||
"setMute"
|
"setMute"
|
||||||
|
@ -115,6 +117,38 @@ loop.OTSdkDriver = (function() {
|
||||||
delete this._publisherReady;
|
delete this._publisherReady;
|
||||||
delete this._publishedLocalStream;
|
delete this._publishedLocalStream;
|
||||||
delete this._subscribedRemoteStream;
|
delete this._subscribedRemoteStream;
|
||||||
|
this.connections = {};
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Oust all users from an ongoing session. This is typically done when a room
|
||||||
|
* owner deletes the room.
|
||||||
|
*
|
||||||
|
* @param {Function} callback Function to be invoked once all connections are
|
||||||
|
* ousted
|
||||||
|
*/
|
||||||
|
forceDisconnectAll: function(callback) {
|
||||||
|
if (!this._sessionConnected) {
|
||||||
|
callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var connectionNames = Object.keys(this.connections);
|
||||||
|
if (connectionNames.length === 0) {
|
||||||
|
callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var disconnectCount = 0;
|
||||||
|
connectionNames.forEach(function(id) {
|
||||||
|
var connection = this.connections[id];
|
||||||
|
this.session.forceDisconnect(connection, function() {
|
||||||
|
// When all connections have disconnected, call the callback, since
|
||||||
|
// we're done.
|
||||||
|
if (++disconnectCount === connectionNames.length) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, this);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -139,10 +173,14 @@ loop.OTSdkDriver = (function() {
|
||||||
/**
|
/**
|
||||||
* Handles the connection event for a peer's connection being dropped.
|
* Handles the connection event for a peer's connection being dropped.
|
||||||
*
|
*
|
||||||
* @param {SessionDisconnectEvent} event The event details
|
* @param {ConnectionEvent} event The event details
|
||||||
* https://tokbox.com/opentok/libraries/client/js/reference/SessionDisconnectEvent.html
|
* https://tokbox.com/opentok/libraries/client/js/reference/ConnectionEvent.html
|
||||||
*/
|
*/
|
||||||
_onConnectionDestroyed: function(event) {
|
_onConnectionDestroyed: function(event) {
|
||||||
|
var connection = event.connection;
|
||||||
|
if (connection && (connection.id in this.connections)) {
|
||||||
|
delete this.connections[connection.id];
|
||||||
|
}
|
||||||
this.dispatcher.dispatch(new sharedActions.RemotePeerDisconnected({
|
this.dispatcher.dispatch(new sharedActions.RemotePeerDisconnected({
|
||||||
peerHungup: event.reason === "clientDisconnected"
|
peerHungup: event.reason === "clientDisconnected"
|
||||||
}));
|
}));
|
||||||
|
@ -164,11 +202,18 @@ loop.OTSdkDriver = (function() {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the connection event for a newly connecting peer.
|
||||||
|
*
|
||||||
|
* @param {ConnectionEvent} event The event details
|
||||||
|
* https://tokbox.com/opentok/libraries/client/js/reference/ConnectionEvent.html
|
||||||
|
*/
|
||||||
_onConnectionCreated: function(event) {
|
_onConnectionCreated: function(event) {
|
||||||
if (this.session.connection.id === event.connection.id) {
|
var connection = event.connection;
|
||||||
|
if (this.session.connection.id === connection.id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
this.connections[connection.id] = connection;
|
||||||
this.dispatcher.dispatch(new sharedActions.RemotePeerConnected());
|
this.dispatcher.dispatch(new sharedActions.RemotePeerConnected());
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,8 @@ describe("loop.store.ActiveRoomStore", function () {
|
||||||
|
|
||||||
fakeSdkDriver = {
|
fakeSdkDriver = {
|
||||||
connectSession: sandbox.stub(),
|
connectSession: sandbox.stub(),
|
||||||
disconnectSession: sandbox.stub()
|
disconnectSession: sandbox.stub(),
|
||||||
|
forceDisconnectAll: sandbox.stub().callsArg(0)
|
||||||
};
|
};
|
||||||
|
|
||||||
fakeMultiplexGum = {
|
fakeMultiplexGum = {
|
||||||
|
@ -740,7 +741,7 @@ describe("loop.store.ActiveRoomStore", function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should dispatch an UpdateRoomInfo action", function() {
|
it("should dispatch an UpdateRoomInfo action", function() {
|
||||||
sinon.assert.calledOnce(fakeMozLoop.rooms.on);
|
sinon.assert.calledTwice(fakeMozLoop.rooms.on);
|
||||||
|
|
||||||
var fakeRoomData = {
|
var fakeRoomData = {
|
||||||
roomName: "fakeName",
|
roomName: "fakeName",
|
||||||
|
@ -755,5 +756,30 @@ describe("loop.store.ActiveRoomStore", function () {
|
||||||
new sharedActions.UpdateRoomInfo(fakeRoomData));
|
new sharedActions.UpdateRoomInfo(fakeRoomData));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("delete:{roomToken}", function() {
|
||||||
|
var fakeRoomData = {
|
||||||
|
roomName: "Its a room",
|
||||||
|
roomOwner: "Me",
|
||||||
|
roomToken: "fakeToken",
|
||||||
|
roomUrl: "http://invalid"
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
store.setupRoomInfo(new sharedActions.SetupRoomInfo(fakeRoomData));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should disconnect all room connections", function() {
|
||||||
|
fakeMozLoop.rooms.on.callArgWith(1, "delete:" + fakeRoomData.roomToken, fakeRoomData);
|
||||||
|
|
||||||
|
sinon.assert.calledOnce(fakeSdkDriver.forceDisconnectAll);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not disconnect anything when another room is deleted", function() {
|
||||||
|
fakeMozLoop.rooms.on.callArgWith(1, "delete:invalidToken", fakeRoomData);
|
||||||
|
|
||||||
|
sinon.assert.calledOnce(fakeSdkDriver.forceDisconnectAll);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -34,7 +34,8 @@ describe("loop.OTSdkDriver", function () {
|
||||||
connect: sinon.stub(),
|
connect: sinon.stub(),
|
||||||
disconnect: sinon.stub(),
|
disconnect: sinon.stub(),
|
||||||
publish: sinon.stub(),
|
publish: sinon.stub(),
|
||||||
subscribe: sinon.stub()
|
subscribe: sinon.stub(),
|
||||||
|
forceDisconnect: sinon.stub()
|
||||||
}, Backbone.Events);
|
}, Backbone.Events);
|
||||||
|
|
||||||
publisher = _.extend({
|
publisher = _.extend({
|
||||||
|
@ -175,6 +176,43 @@ describe("loop.OTSdkDriver", function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("#forceDisconnectAll", function() {
|
||||||
|
it("should not disconnect anything when not connected", function() {
|
||||||
|
driver.session = session;
|
||||||
|
driver.forceDisconnectAll(function() {});
|
||||||
|
|
||||||
|
sinon.assert.notCalled(session.forceDisconnect);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should disconnect all remote connections when called", function() {
|
||||||
|
driver.connectSession(sessionData);
|
||||||
|
sinon.assert.calledOnce(session.connect);
|
||||||
|
driver._sessionConnected = true;
|
||||||
|
|
||||||
|
// Setup the right state in the driver to make `forceDisconnectAll` do
|
||||||
|
// something.
|
||||||
|
session.connection = {
|
||||||
|
id: "localUser"
|
||||||
|
};
|
||||||
|
session.trigger("connectionCreated", {
|
||||||
|
connection: {id: "remoteUser"}
|
||||||
|
});
|
||||||
|
expect(driver.connections).to.include.keys("remoteUser");
|
||||||
|
|
||||||
|
driver.forceDisconnectAll(function() {});
|
||||||
|
sinon.assert.calledOnce(session.forceDisconnect);
|
||||||
|
|
||||||
|
// Add another remote connection.
|
||||||
|
session.trigger("connectionCreated", {
|
||||||
|
connection: {id: "remoteUser2"}
|
||||||
|
});
|
||||||
|
expect(driver.connections).to.include.keys("remoteUser", "remoteUser2");
|
||||||
|
|
||||||
|
driver.forceDisconnectAll(function() {});
|
||||||
|
sinon.assert.calledThrice(session.forceDisconnect);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("Events", function() {
|
describe("Events", function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
driver.connectSession(sessionData);
|
driver.connectSession(sessionData);
|
||||||
|
@ -275,6 +313,9 @@ describe("loop.OTSdkDriver", function () {
|
||||||
sinon.assert.calledOnce(dispatcher.dispatch);
|
sinon.assert.calledOnce(dispatcher.dispatch);
|
||||||
sinon.assert.calledWithExactly(dispatcher.dispatch,
|
sinon.assert.calledWithExactly(dispatcher.dispatch,
|
||||||
new sharedActions.RemotePeerConnected());
|
new sharedActions.RemotePeerConnected());
|
||||||
|
it("should store the connection details for a remote user", function() {
|
||||||
|
expect(driver.connections).to.include.keys("remoteUser");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not dispatch an action if this is for a local user",
|
it("should not dispatch an action if this is for a local user",
|
||||||
|
@ -284,6 +325,9 @@ describe("loop.OTSdkDriver", function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
sinon.assert.notCalled(dispatcher.dispatch);
|
sinon.assert.notCalled(dispatcher.dispatch);
|
||||||
|
it("should not store the connection details for a local user", function() {
|
||||||
|
expect(driver.connections).to.not.include.keys("localUser");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,6 @@ devtools.lazyRequireGetter(this, "DevToolsUtils",
|
||||||
"devtools/toolkit/DevToolsUtils");
|
"devtools/toolkit/DevToolsUtils");
|
||||||
devtools.lazyRequireGetter(this, "L10N",
|
devtools.lazyRequireGetter(this, "L10N",
|
||||||
"devtools/profiler/global", true);
|
"devtools/profiler/global", true);
|
||||||
devtools.lazyRequireGetter(this, "FramerateFront",
|
|
||||||
"devtools/server/actors/framerate", true);
|
|
||||||
devtools.lazyRequireGetter(this, "Waterfall",
|
devtools.lazyRequireGetter(this, "Waterfall",
|
||||||
"devtools/timeline/waterfall", true);
|
"devtools/timeline/waterfall", true);
|
||||||
devtools.lazyRequireGetter(this, "MarkerDetails",
|
devtools.lazyRequireGetter(this, "MarkerDetails",
|
||||||
|
|
|
@ -3,8 +3,11 @@
|
||||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const OVERVIEW_UPDATE_INTERVAL = 100;
|
// No sense updating the overview more often than receiving data from the
|
||||||
const FRAMERATE_CALC_INTERVAL = 16; // ms
|
// backend. Make sure this isn't lower than DEFAULT_TIMELINE_DATA_PULL_TIMEOUT
|
||||||
|
// in toolkit/devtools/server/actors/timeline.js
|
||||||
|
const OVERVIEW_UPDATE_INTERVAL = 200; // ms
|
||||||
|
|
||||||
const FRAMERATE_GRAPH_HEIGHT = 60; // px
|
const FRAMERATE_GRAPH_HEIGHT = 60; // px
|
||||||
const GRAPH_SCROLL_EVENTS_DRAIN = 50; // ms
|
const GRAPH_SCROLL_EVENTS_DRAIN = 50; // ms
|
||||||
|
|
||||||
|
@ -13,11 +16,10 @@ const GRAPH_SCROLL_EVENTS_DRAIN = 50; // ms
|
||||||
* framerate over time.
|
* framerate over time.
|
||||||
*/
|
*/
|
||||||
let OverviewView = {
|
let OverviewView = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets up the view with event binding.
|
* Sets up the view with event binding.
|
||||||
*/
|
*/
|
||||||
initialize: function () {
|
initialize: Task.async(function *() {
|
||||||
this._framerateEl = $("#time-framerate");
|
this._framerateEl = $("#time-framerate");
|
||||||
this._ticksData = [];
|
this._ticksData = [];
|
||||||
|
|
||||||
|
@ -28,14 +30,14 @@ let OverviewView = {
|
||||||
this._onGraphMouseUp = this._onGraphMouseUp.bind(this);
|
this._onGraphMouseUp = this._onGraphMouseUp.bind(this);
|
||||||
this._onGraphScroll = this._onGraphScroll.bind(this);
|
this._onGraphScroll = this._onGraphScroll.bind(this);
|
||||||
|
|
||||||
this._initializeFramerateGraph();
|
yield this._initializeFramerateGraph();
|
||||||
|
|
||||||
this.framerateGraph.on("mouseup", this._onGraphMouseUp);
|
this.framerateGraph.on("mouseup", this._onGraphMouseUp);
|
||||||
this.framerateGraph.on("scroll", this._onGraphScroll);
|
this.framerateGraph.on("scroll", this._onGraphScroll);
|
||||||
PerformanceController.on(EVENTS.RECORDING_STARTED, this._start);
|
PerformanceController.on(EVENTS.RECORDING_STARTED, this._start);
|
||||||
PerformanceController.on(EVENTS.RECORDING_STOPPED, this._stop);
|
PerformanceController.on(EVENTS.RECORDING_STOPPED, this._stop);
|
||||||
PerformanceController.on(EVENTS.TIMELINE_DATA, this._onTimelineData);
|
PerformanceController.on(EVENTS.TIMELINE_DATA, this._onTimelineData);
|
||||||
},
|
}),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unbinds events.
|
* Unbinds events.
|
||||||
|
@ -55,9 +57,13 @@ let OverviewView = {
|
||||||
* data into all the corresponding overview graphs.
|
* data into all the corresponding overview graphs.
|
||||||
*/
|
*/
|
||||||
_onRecordingTick: Task.async(function *() {
|
_onRecordingTick: Task.async(function *() {
|
||||||
yield this.framerateGraph.setDataWhenReady(this._ticksData);
|
// The `ticks` event on the TimelineFront returns all ticks for the
|
||||||
|
// recording session, so just convert to plottable values and draw.
|
||||||
|
let [, timestamps] = this._ticksData;
|
||||||
|
yield this.framerateGraph.setDataFromTimestamps(timestamps);
|
||||||
|
|
||||||
this.emit(EVENTS.OVERVIEW_RENDERED);
|
this.emit(EVENTS.OVERVIEW_RENDERED);
|
||||||
this._draw();
|
this._prepareNextTick();
|
||||||
}),
|
}),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -94,20 +100,21 @@ let OverviewView = {
|
||||||
/**
|
/**
|
||||||
* Sets up the framerate graph.
|
* Sets up the framerate graph.
|
||||||
*/
|
*/
|
||||||
_initializeFramerateGraph: function () {
|
_initializeFramerateGraph: Task.async(function *() {
|
||||||
let graph = new LineGraphWidget(this._framerateEl, L10N.getStr("graphs.fps"));
|
let graph = new LineGraphWidget(this._framerateEl, L10N.getStr("graphs.fps"));
|
||||||
graph.minDistanceBetweenPoints = 1;
|
|
||||||
graph.fixedHeight = FRAMERATE_GRAPH_HEIGHT;
|
graph.fixedHeight = FRAMERATE_GRAPH_HEIGHT;
|
||||||
graph.selectionEnabled = false;
|
graph.selectionEnabled = false;
|
||||||
this.framerateGraph = graph;
|
this.framerateGraph = graph;
|
||||||
},
|
|
||||||
|
yield graph.ready();
|
||||||
|
}),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called to refresh the timer to keep firing _onRecordingTick.
|
* Called to refresh the timer to keep firing _onRecordingTick.
|
||||||
*/
|
*/
|
||||||
_draw: function () {
|
_prepareNextTick: function () {
|
||||||
// Check here to see if there's still a _timeoutId, incase
|
// Check here to see if there's still a _timeoutId, incase
|
||||||
// `stop` was called before the _draw call was executed.
|
// `stop` was called before the _prepareNextTick call was executed.
|
||||||
if (this._timeoutId) {
|
if (this._timeoutId) {
|
||||||
this._timeoutId = setTimeout(this._onRecordingTick, OVERVIEW_UPDATE_INTERVAL);
|
this._timeoutId = setTimeout(this._onRecordingTick, OVERVIEW_UPDATE_INTERVAL);
|
||||||
}
|
}
|
||||||
|
@ -134,11 +141,7 @@ let OverviewView = {
|
||||||
*/
|
*/
|
||||||
_onTimelineData: function (_, eventName, ...data) {
|
_onTimelineData: function (_, eventName, ...data) {
|
||||||
if (eventName === "ticks") {
|
if (eventName === "ticks") {
|
||||||
let [delta, timestamps] = data;
|
this._ticksData = data;
|
||||||
// the `ticks` event on the TimelineFront returns all ticks for the
|
|
||||||
// recording session, so just convert to plottable values
|
|
||||||
// and store.
|
|
||||||
this._ticksData = FramerateFront.plotFPS(timestamps, FRAMERATE_CALC_INTERVAL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -394,7 +394,6 @@ let ProfileView = {
|
||||||
|
|
||||||
let graph = new LineGraphWidget($(".framerate", panel), L10N.getStr("graphs.fps"));
|
let graph = new LineGraphWidget($(".framerate", panel), L10N.getStr("graphs.fps"));
|
||||||
graph.fixedHeight = FRAMERATE_GRAPH_HEIGHT;
|
graph.fixedHeight = FRAMERATE_GRAPH_HEIGHT;
|
||||||
graph.minDistanceBetweenPoints = 1;
|
|
||||||
graph.dataOffsetX = beginAt;
|
graph.dataOffsetX = beginAt;
|
||||||
|
|
||||||
yield graph.setDataWhenReady(framerateData);
|
yield graph.setDataWhenReady(framerateData);
|
||||||
|
|
|
@ -23,6 +23,7 @@ EXTRA_JS_MODULES.devtools += [
|
||||||
'widgets/BreadcrumbsWidget.jsm',
|
'widgets/BreadcrumbsWidget.jsm',
|
||||||
'widgets/Chart.jsm',
|
'widgets/Chart.jsm',
|
||||||
'widgets/Graphs.jsm',
|
'widgets/Graphs.jsm',
|
||||||
|
'widgets/GraphsWorker.js',
|
||||||
'widgets/SideMenuWidget.jsm',
|
'widgets/SideMenuWidget.jsm',
|
||||||
'widgets/SimpleListWidget.jsm',
|
'widgets/SimpleListWidget.jsm',
|
||||||
'widgets/VariablesView.jsm',
|
'widgets/VariablesView.jsm',
|
||||||
|
|
|
@ -19,6 +19,7 @@ this.EXPORTED_SYMBOLS = [
|
||||||
|
|
||||||
const HTML_NS = "http://www.w3.org/1999/xhtml";
|
const HTML_NS = "http://www.w3.org/1999/xhtml";
|
||||||
const GRAPH_SRC = "chrome://browser/content/devtools/graphs-frame.xhtml";
|
const GRAPH_SRC = "chrome://browser/content/devtools/graphs-frame.xhtml";
|
||||||
|
const WORKER_URL = "resource:///modules/devtools/GraphsWorker.js";
|
||||||
const L10N = new ViewHelpers.L10N();
|
const L10N = new ViewHelpers.L10N();
|
||||||
|
|
||||||
// Generic constants.
|
// Generic constants.
|
||||||
|
@ -44,7 +45,7 @@ const GRAPH_STRIPE_PATTERN_LINE_SPACING = 4; // px
|
||||||
// Line graph constants.
|
// Line graph constants.
|
||||||
|
|
||||||
const LINE_GRAPH_DAMPEN_VALUES = 0.85;
|
const LINE_GRAPH_DAMPEN_VALUES = 0.85;
|
||||||
const LINE_GRAPH_MIN_SQUARED_DISTANCE_BETWEEN_POINTS = 400; // 20 px
|
const LINE_GRAPH_MIN_SQUARED_DISTANCE_BETWEEN_POINTS = 1; // px
|
||||||
const LINE_GRAPH_TOOLTIP_SAFE_BOUNDS = 8; // px
|
const LINE_GRAPH_TOOLTIP_SAFE_BOUNDS = 8; // px
|
||||||
const LINE_GRAPH_MIN_MAX_TOOLTIP_DISTANCE = 14; // px
|
const LINE_GRAPH_MIN_MAX_TOOLTIP_DISTANCE = 14; // px
|
||||||
|
|
||||||
|
@ -92,10 +93,10 @@ const BAR_GRAPH_LEGEND_MOUSEOVER_DEBOUNCE = 50; // ms
|
||||||
/**
|
/**
|
||||||
* Small data primitives for all graphs.
|
* Small data primitives for all graphs.
|
||||||
*/
|
*/
|
||||||
this.GraphCursor = function() {}
|
this.GraphCursor = function() {};
|
||||||
this.GraphSelection = function() {}
|
this.GraphSelection = function() {};
|
||||||
this.GraphSelectionDragger = function() {}
|
this.GraphSelectionDragger = function() {};
|
||||||
this.GraphSelectionResizer = function() {}
|
this.GraphSelectionResizer = function() {};
|
||||||
|
|
||||||
GraphCursor.prototype = {
|
GraphCursor.prototype = {
|
||||||
x: null,
|
x: null,
|
||||||
|
@ -206,7 +207,7 @@ this.AbstractCanvasGraph = function(parent, name, sharpness) {
|
||||||
this._ready.resolve(this);
|
this._ready.resolve(this);
|
||||||
this.emit("ready", this);
|
this.emit("ready", this);
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
AbstractCanvasGraph.prototype = {
|
AbstractCanvasGraph.prototype = {
|
||||||
/**
|
/**
|
||||||
|
@ -895,7 +896,7 @@ AbstractCanvasGraph.prototype = {
|
||||||
while (node = node.offsetParent) {
|
while (node = node.offsetParent) {
|
||||||
x += node.offsetLeft;
|
x += node.offsetLeft;
|
||||||
y += node.offsetTop;
|
y += node.offsetTop;
|
||||||
};
|
}
|
||||||
|
|
||||||
return { left: x, top: y };
|
return { left: x, top: y };
|
||||||
},
|
},
|
||||||
|
@ -1178,7 +1179,7 @@ this.LineGraphWidget = function(parent, metric, ...args) {
|
||||||
this._avgTooltip = this._createTooltip("average", "end", "avg", metric);
|
this._avgTooltip = this._createTooltip("average", "end", "avg", metric);
|
||||||
this._minTooltip = this._createTooltip("minimum", "start", "min", metric);
|
this._minTooltip = this._createTooltip("minimum", "start", "min", metric);
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
LineGraphWidget.prototype = Heritage.extend(AbstractCanvasGraph.prototype, {
|
LineGraphWidget.prototype = Heritage.extend(AbstractCanvasGraph.prototype, {
|
||||||
backgroundColor: LINE_GRAPH_BACKGROUND_COLOR,
|
backgroundColor: LINE_GRAPH_BACKGROUND_COLOR,
|
||||||
|
@ -1211,7 +1212,7 @@ LineGraphWidget.prototype = Heritage.extend(AbstractCanvasGraph.prototype, {
|
||||||
* Points that are too close too each other in the graph will not be rendered.
|
* Points that are too close too each other in the graph will not be rendered.
|
||||||
* This scalar specifies the required minimum squared distance between points.
|
* This scalar specifies the required minimum squared distance between points.
|
||||||
*/
|
*/
|
||||||
minDistanceBetweenPoints: LINE_GRAPH_MIN_SQUARED_DISTANCE_BETWEEN_POINTS,
|
minSquaredDistanceBetweenPoints: LINE_GRAPH_MIN_SQUARED_DISTANCE_BETWEEN_POINTS,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies if min/max/avg tooltips have arrow handlers on their sides.
|
* Specifies if min/max/avg tooltips have arrow handlers on their sides.
|
||||||
|
@ -1224,6 +1225,36 @@ LineGraphWidget.prototype = Heritage.extend(AbstractCanvasGraph.prototype, {
|
||||||
*/
|
*/
|
||||||
withFixedTooltipPositions: false,
|
withFixedTooltipPositions: false,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes a list of numbers and plots them on a line graph representing
|
||||||
|
* the rate of occurences in a specified interval. Useful for drawing
|
||||||
|
* framerate, for example, from a sequence of timestamps.
|
||||||
|
*
|
||||||
|
* @param array timestamps
|
||||||
|
* A list of numbers representing time, ordered ascending. For example,
|
||||||
|
* this can be the raw data received from the framerate actor, which
|
||||||
|
* represents the elapsed time on each refresh driver tick.
|
||||||
|
* @param number interval
|
||||||
|
* The maximum amount of time to wait between calculations.
|
||||||
|
*/
|
||||||
|
setDataFromTimestamps: Task.async(function*(timestamps, interval) {
|
||||||
|
let {
|
||||||
|
plottedData,
|
||||||
|
plottedMinMaxSum
|
||||||
|
} = yield CanvasGraphUtils._performTaskInWorker("plotTimestampsGraph", {
|
||||||
|
width: this._width,
|
||||||
|
height: this._height,
|
||||||
|
dataOffsetX: this.dataOffsetX,
|
||||||
|
dampenValuesFactor: this.dampenValuesFactor,
|
||||||
|
minSquaredDistanceBetweenPoints: this.minSquaredDistanceBetweenPoints,
|
||||||
|
timestamps: timestamps,
|
||||||
|
interval: interval
|
||||||
|
});
|
||||||
|
|
||||||
|
this._tempMinMaxSum = plottedMinMaxSum;
|
||||||
|
this.setData(plottedData);
|
||||||
|
}),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders the graph's data source.
|
* Renders the graph's data source.
|
||||||
* @see AbstractCanvasGraph.prototype.buildGraphImage
|
* @see AbstractCanvasGraph.prototype.buildGraphImage
|
||||||
|
@ -1238,31 +1269,37 @@ LineGraphWidget.prototype = Heritage.extend(AbstractCanvasGraph.prototype, {
|
||||||
let lastTick = totalTicks ? this._data[totalTicks - 1].delta : 0;
|
let lastTick = totalTicks ? this._data[totalTicks - 1].delta : 0;
|
||||||
let maxValue = Number.MIN_SAFE_INTEGER;
|
let maxValue = Number.MIN_SAFE_INTEGER;
|
||||||
let minValue = Number.MAX_SAFE_INTEGER;
|
let minValue = Number.MAX_SAFE_INTEGER;
|
||||||
let sumValues = 0;
|
let avgValue = 0;
|
||||||
|
let forceDrawAllPoints = false;
|
||||||
|
|
||||||
for (let { delta, value } of this._data) {
|
if (this._tempMinMaxSum) {
|
||||||
maxValue = Math.max(value, maxValue);
|
maxValue = this._tempMinMaxSum.maxValue;
|
||||||
minValue = Math.min(value, minValue);
|
minValue = this._tempMinMaxSum.minValue;
|
||||||
sumValues += value;
|
avgValue = this._tempMinMaxSum.avgValue;
|
||||||
|
// If we use cached `minValue`, `maxValue`, `avgValue` then we can assume
|
||||||
|
// that we've already removed points that did not meet the
|
||||||
|
// `minSquaredDistanceBetweenPoints` requirement.
|
||||||
|
forceDrawAllPoints = true;
|
||||||
|
} else {
|
||||||
|
let sumValues = 0;
|
||||||
|
for (let { delta, value } of this._data) {
|
||||||
|
maxValue = Math.max(value, maxValue);
|
||||||
|
minValue = Math.min(value, minValue);
|
||||||
|
sumValues += value;
|
||||||
|
}
|
||||||
|
avgValue = sumValues / totalTicks;
|
||||||
}
|
}
|
||||||
|
|
||||||
let dataScaleX = this.dataScaleX = width / (lastTick - this.dataOffsetX);
|
let dataScaleX = this.dataScaleX = width / (lastTick - this.dataOffsetX);
|
||||||
let dataScaleY = this.dataScaleY = height / maxValue * this.dampenValuesFactor;
|
let dataScaleY = this.dataScaleY = height / maxValue * this.dampenValuesFactor;
|
||||||
|
|
||||||
/**
|
// Draw the background.
|
||||||
* Calculates the squared distance between two 2D points.
|
|
||||||
*/
|
|
||||||
function distSquared(x0, y0, x1, y1) {
|
|
||||||
let xs = x1 - x0;
|
|
||||||
let ys = y1 - y0;
|
|
||||||
return xs * xs + ys * ys;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw the graph.
|
|
||||||
|
|
||||||
ctx.fillStyle = this.backgroundColor;
|
ctx.fillStyle = this.backgroundColor;
|
||||||
ctx.fillRect(0, 0, width, height);
|
ctx.fillRect(0, 0, width, height);
|
||||||
|
|
||||||
|
// Draw the graph.
|
||||||
|
|
||||||
let gradient = ctx.createLinearGradient(0, height / 2, 0, height);
|
let gradient = ctx.createLinearGradient(0, height / 2, 0, height);
|
||||||
gradient.addColorStop(0, this.backgroundGradientStart);
|
gradient.addColorStop(0, this.backgroundGradientStart);
|
||||||
gradient.addColorStop(1, this.backgroundGradientEnd);
|
gradient.addColorStop(1, this.backgroundGradientEnd);
|
||||||
|
@ -1273,6 +1310,7 @@ LineGraphWidget.prototype = Heritage.extend(AbstractCanvasGraph.prototype, {
|
||||||
|
|
||||||
let prevX = 0;
|
let prevX = 0;
|
||||||
let prevY = 0;
|
let prevY = 0;
|
||||||
|
let minSqDist = this.minSquaredDistanceBetweenPoints;
|
||||||
|
|
||||||
for (let { delta, value } of this._data) {
|
for (let { delta, value } of this._data) {
|
||||||
let currX = (delta - this.dataOffsetX) * dataScaleX;
|
let currX = (delta - this.dataOffsetX) * dataScaleX;
|
||||||
|
@ -1283,8 +1321,7 @@ LineGraphWidget.prototype = Heritage.extend(AbstractCanvasGraph.prototype, {
|
||||||
ctx.lineTo(-LINE_GRAPH_STROKE_WIDTH, currY);
|
ctx.lineTo(-LINE_GRAPH_STROKE_WIDTH, currY);
|
||||||
}
|
}
|
||||||
|
|
||||||
let distance = distSquared(prevX, prevY, currX, currY);
|
if (forceDrawAllPoints || distSquared(prevX, prevY, currX, currY) >= minSqDist) {
|
||||||
if (distance >= this.minDistanceBetweenPoints) {
|
|
||||||
ctx.lineTo(currX, currY);
|
ctx.lineTo(currX, currY);
|
||||||
prevX = currX;
|
prevX = currX;
|
||||||
prevY = currY;
|
prevY = currY;
|
||||||
|
@ -1299,6 +1336,26 @@ LineGraphWidget.prototype = Heritage.extend(AbstractCanvasGraph.prototype, {
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
|
|
||||||
|
this._drawOverlays(ctx, minValue, maxValue, avgValue, dataScaleY);
|
||||||
|
|
||||||
|
return canvas;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws the min, max and average horizontal lines, along with their
|
||||||
|
* repsective tooltips.
|
||||||
|
*
|
||||||
|
* @param CanvasRenderingContext2D ctx
|
||||||
|
* @param number minValue
|
||||||
|
* @param number maxValue
|
||||||
|
* @param number avgValue
|
||||||
|
* @param number dataScaleY
|
||||||
|
*/
|
||||||
|
_drawOverlays: function(ctx, minValue, maxValue, avgValue, dataScaleY) {
|
||||||
|
let width = this._width;
|
||||||
|
let height = this._height;
|
||||||
|
let totalTicks = this._data.length;
|
||||||
|
|
||||||
// Draw the maximum value horizontal line.
|
// Draw the maximum value horizontal line.
|
||||||
|
|
||||||
ctx.strokeStyle = this.maximumLineColor;
|
ctx.strokeStyle = this.maximumLineColor;
|
||||||
|
@ -1316,7 +1373,6 @@ LineGraphWidget.prototype = Heritage.extend(AbstractCanvasGraph.prototype, {
|
||||||
ctx.lineWidth = LINE_GRAPH_HELPER_LINES_WIDTH;
|
ctx.lineWidth = LINE_GRAPH_HELPER_LINES_WIDTH;
|
||||||
ctx.setLineDash(LINE_GRAPH_HELPER_LINES_DASH);
|
ctx.setLineDash(LINE_GRAPH_HELPER_LINES_DASH);
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
let avgValue = totalTicks ? sumValues / totalTicks : 0;
|
|
||||||
let averageY = height - avgValue * dataScaleY;
|
let averageY = height - avgValue * dataScaleY;
|
||||||
ctx.moveTo(0, averageY);
|
ctx.moveTo(0, averageY);
|
||||||
ctx.lineTo(width, averageY);
|
ctx.lineTo(width, averageY);
|
||||||
|
@ -1342,15 +1398,6 @@ LineGraphWidget.prototype = Heritage.extend(AbstractCanvasGraph.prototype, {
|
||||||
this._minTooltip.querySelector("[text=value]").textContent =
|
this._minTooltip.querySelector("[text=value]").textContent =
|
||||||
L10N.numberWithDecimals(minValue, 2);
|
L10N.numberWithDecimals(minValue, 2);
|
||||||
|
|
||||||
/**
|
|
||||||
* Constrains a value to a range.
|
|
||||||
*/
|
|
||||||
function clamp(value, min, max) {
|
|
||||||
if (value < min) return min;
|
|
||||||
if (value > max) return max;
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
let bottom = height / this._pixelRatio;
|
let bottom = height / this._pixelRatio;
|
||||||
let maxPosY = map(maxValue * this.dampenValuesFactor, 0, maxValue, bottom, 0);
|
let maxPosY = map(maxValue * this.dampenValuesFactor, 0, maxValue, bottom, 0);
|
||||||
let avgPosY = map(avgValue * this.dampenValuesFactor, 0, maxValue, bottom, 0);
|
let avgPosY = map(avgValue * this.dampenValuesFactor, 0, maxValue, bottom, 0);
|
||||||
|
@ -1384,8 +1431,6 @@ LineGraphWidget.prototype = Heritage.extend(AbstractCanvasGraph.prototype, {
|
||||||
this._minTooltip.hidden = !totalTicks;
|
this._minTooltip.hidden = !totalTicks;
|
||||||
|
|
||||||
this._gutter.hidden = !this.withTooltipArrows;
|
this._gutter.hidden = !this.withTooltipArrows;
|
||||||
|
|
||||||
return canvas;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1445,7 +1490,6 @@ LineGraphWidget.prototype = Heritage.extend(AbstractCanvasGraph.prototype, {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A bar graph, plotting tuples of values as rectangles.
|
* A bar graph, plotting tuples of values as rectangles.
|
||||||
*
|
*
|
||||||
|
@ -1501,7 +1545,7 @@ this.BarGraphWidget = function(parent, ...args) {
|
||||||
}
|
}
|
||||||
this.outstandingEventListeners = null;
|
this.outstandingEventListeners = null;
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
BarGraphWidget.prototype = Heritage.extend(AbstractCanvasGraph.prototype, {
|
BarGraphWidget.prototype = Heritage.extend(AbstractCanvasGraph.prototype, {
|
||||||
clipheadLineColor: BAR_GRAPH_CLIPHEAD_LINE_COLOR,
|
clipheadLineColor: BAR_GRAPH_CLIPHEAD_LINE_COLOR,
|
||||||
|
@ -1955,6 +1999,9 @@ const gCachedStripePattern = new Map();
|
||||||
* Utility functions for graph canvases.
|
* Utility functions for graph canvases.
|
||||||
*/
|
*/
|
||||||
this.CanvasGraphUtils = {
|
this.CanvasGraphUtils = {
|
||||||
|
_graphUtilsWorker: null,
|
||||||
|
_graphUtilsTaskId: 0,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merges the animation loop of two graphs.
|
* Merges the animation loop of two graphs.
|
||||||
*/
|
*/
|
||||||
|
@ -2004,6 +2051,47 @@ this.CanvasGraphUtils = {
|
||||||
graph2.on("deselecting", () => {
|
graph2.on("deselecting", () => {
|
||||||
graph1.dropSelection();
|
graph1.dropSelection();
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the given task in a chrome worker, assuming it exists.
|
||||||
|
*
|
||||||
|
* @param string task
|
||||||
|
* The task name. Currently supported: "plotTimestampsGraph".
|
||||||
|
* @param any args
|
||||||
|
* Extra arguments to pass to the worker.
|
||||||
|
* @param array transferrable [optional]
|
||||||
|
* A list of transferrable objects, if any.
|
||||||
|
* @return object
|
||||||
|
* A promise that is resolved once the worker finishes the task.
|
||||||
|
*/
|
||||||
|
_performTaskInWorker: function(task, args, transferrable) {
|
||||||
|
let worker = this._graphUtilsWorker || new ChromeWorker(WORKER_URL);
|
||||||
|
let id = this._graphUtilsTaskId++;
|
||||||
|
worker.postMessage({ task, id, args }, transferrable);
|
||||||
|
return this._waitForWorkerResponse(worker, id);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Waits for the specified worker to finish a task.
|
||||||
|
*
|
||||||
|
* @param ChromeWorker worker
|
||||||
|
* The worker for which to add a message listener.
|
||||||
|
* @param number id
|
||||||
|
* The worker task id.
|
||||||
|
*/
|
||||||
|
_waitForWorkerResponse: function(worker, id) {
|
||||||
|
let deferred = promise.defer();
|
||||||
|
|
||||||
|
worker.addEventListener("message", function listener({ data }) {
|
||||||
|
if (data.id != id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
worker.removeEventListener("message", listener);
|
||||||
|
deferred.resolve(data);
|
||||||
|
});
|
||||||
|
|
||||||
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2016,6 +2104,26 @@ function map(value, istart, istop, ostart, ostop) {
|
||||||
return ostart + (ostop - ostart) * ((value - istart) / (istop - istart));
|
return ostart + (ostop - ostart) * ((value - istart) / (istop - istart));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constrains a value to a range.
|
||||||
|
* @param number value, min, max
|
||||||
|
* @return number
|
||||||
|
*/
|
||||||
|
function clamp(value, min, max) {
|
||||||
|
if (value < min) return min;
|
||||||
|
if (value > max) return max;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the squared distance between two 2D points.
|
||||||
|
*/
|
||||||
|
function distSquared(x0, y0, x1, y1) {
|
||||||
|
let xs = x1 - x0;
|
||||||
|
let ys = y1 - y0;
|
||||||
|
return xs * xs + ys * ys;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the first element in an array that validates a predicate.
|
* Finds the first element in an array that validates a predicate.
|
||||||
* @param array
|
* @param array
|
||||||
|
|
|
@ -0,0 +1,161 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
self.onmessage = e => {
|
||||||
|
const { id, task, args } = e.data;
|
||||||
|
|
||||||
|
switch (task) {
|
||||||
|
case "plotTimestampsGraph":
|
||||||
|
plotTimestampsGraph(id, args);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
self.postMessage({ id, error: e.message + "\n" + e.stack });
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see LineGraphWidget.prototype.setDataFromTimestamps in Graphs.jsm
|
||||||
|
* @param number id
|
||||||
|
* @param number width
|
||||||
|
* @param number height
|
||||||
|
* @param array timestamps
|
||||||
|
* @param number interval
|
||||||
|
*/
|
||||||
|
function plotTimestampsGraph(id, args) {
|
||||||
|
let plottedData = plotTimestamps(args.timestamps, args.interval);
|
||||||
|
let plottedMinMaxSum = getMinMaxSum(plottedData);
|
||||||
|
let sparsifiedData = sparsifyLineData(plottedData, plottedMinMaxSum, args);
|
||||||
|
|
||||||
|
let response = { id, plottedData: sparsifiedData, plottedMinMaxSum };
|
||||||
|
self.postMessage(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the min, max and average of the values in an array.
|
||||||
|
* @param array source
|
||||||
|
* @return object
|
||||||
|
*/
|
||||||
|
function getMinMaxSum(source) {
|
||||||
|
let totalTicks = source.length;
|
||||||
|
let maxValue = Number.MIN_SAFE_INTEGER;
|
||||||
|
let minValue = Number.MAX_SAFE_INTEGER;
|
||||||
|
let avgValue = 0;
|
||||||
|
let sumValues = 0;
|
||||||
|
|
||||||
|
for (let { value } of source) {
|
||||||
|
maxValue = Math.max(value, maxValue);
|
||||||
|
minValue = Math.min(value, minValue);
|
||||||
|
sumValues += value;
|
||||||
|
}
|
||||||
|
avgValue = sumValues / totalTicks;
|
||||||
|
|
||||||
|
return { minValue, maxValue, avgValue };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reduce a data source for a line graph, based off of a minimum distance
|
||||||
|
* between the points to render.
|
||||||
|
*/
|
||||||
|
function sparsifyLineData(plottedData, plottedMinMaxSum, options) {
|
||||||
|
let { width: graphWidth, height: graphHeight } = options;
|
||||||
|
let { dataOffsetX, dampenValuesFactor } = options;
|
||||||
|
let { minSquaredDistanceBetweenPoints } = options;
|
||||||
|
|
||||||
|
let result = [];
|
||||||
|
|
||||||
|
let totalTicks = plottedData.length;
|
||||||
|
let maxValue = plottedMinMaxSum.maxValue;
|
||||||
|
|
||||||
|
let firstTick = totalTicks ? plottedData[0].delta : 0;
|
||||||
|
let lastTick = totalTicks ? plottedData[totalTicks - 1].delta : 0;
|
||||||
|
let dataScaleX = graphWidth / (lastTick - dataOffsetX);
|
||||||
|
let dataScaleY = graphHeight / maxValue * dampenValuesFactor;
|
||||||
|
|
||||||
|
let prevX = 0;
|
||||||
|
let prevY = 0;
|
||||||
|
|
||||||
|
for (let { delta, value } of plottedData) {
|
||||||
|
let currX = (delta - dataOffsetX) * dataScaleX;
|
||||||
|
let currY = graphHeight - value * dataScaleY;
|
||||||
|
|
||||||
|
if (delta == firstTick || delta == lastTick) {
|
||||||
|
result.push({ delta, value });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let dist = distSquared(prevX, prevY, currX, currY);
|
||||||
|
if (dist >= minSquaredDistanceBetweenPoints) {
|
||||||
|
result.push({ delta, value });
|
||||||
|
prevX = currX;
|
||||||
|
prevY = currY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes a list of numbers and plots them on a line graph representing
|
||||||
|
* the rate of occurences in a specified interval.
|
||||||
|
*
|
||||||
|
* XXX: Copied almost verbatim from toolkit/devtools/server/actors/framerate.js
|
||||||
|
* Remove that dead code after the Performance panel lands, bug 1075567.
|
||||||
|
*
|
||||||
|
* @param array timestamps
|
||||||
|
* A list of numbers representing time, ordered ascending. For example,
|
||||||
|
* this can be the raw data received from the framerate actor, which
|
||||||
|
* represents the elapsed time on each refresh driver tick.
|
||||||
|
* @param number interval
|
||||||
|
* The maximum amount of time to wait between calculations.
|
||||||
|
* @param number clamp
|
||||||
|
* The maximum allowed value.
|
||||||
|
* @return array
|
||||||
|
* A collection of { delta, value } objects representing the
|
||||||
|
* plotted value at every delta time.
|
||||||
|
*/
|
||||||
|
function plotTimestamps(timestamps, interval = 100, clamp = 60) {
|
||||||
|
let timeline = [];
|
||||||
|
let totalTicks = timestamps.length;
|
||||||
|
|
||||||
|
// If the refresh driver didn't get a chance to tick before the
|
||||||
|
// recording was stopped, assume rate was 0.
|
||||||
|
if (totalTicks == 0) {
|
||||||
|
timeline.push({ delta: 0, value: 0 });
|
||||||
|
timeline.push({ delta: interval, value: 0 });
|
||||||
|
return timeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
let frameCount = 0;
|
||||||
|
let prevTime = +timestamps[0];
|
||||||
|
|
||||||
|
for (let i = 1; i < totalTicks; i++) {
|
||||||
|
let currTime = +timestamps[i];
|
||||||
|
frameCount++;
|
||||||
|
|
||||||
|
let elapsedTime = currTime - prevTime;
|
||||||
|
if (elapsedTime < interval) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let rate = Math.min(1000 / (elapsedTime / frameCount), clamp);
|
||||||
|
timeline.push({ delta: prevTime, value: rate });
|
||||||
|
timeline.push({ delta: currTime, value: rate });
|
||||||
|
|
||||||
|
frameCount = 0;
|
||||||
|
prevTime = currTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
return timeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the squared distance between two 2D points.
|
||||||
|
*/
|
||||||
|
function distSquared(x0, y0, x1, y1) {
|
||||||
|
let xs = x1 - x0;
|
||||||
|
let ys = y1 - y0;
|
||||||
|
return xs * xs + ys * ys;
|
||||||
|
}
|
|
@ -3,20 +3,26 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
/* CSS Variables specific to this panel that aren't defined by the themes */
|
||||||
|
.theme-dark {
|
||||||
|
--cell-border-color: rgba(255,255,255,0.15);
|
||||||
|
--focus-cell-border-color: rgba(255,255,255,0.5);
|
||||||
|
--row-alt-background-color: rgba(29,79,115,0.15);
|
||||||
|
--row-hover-background-color: rgba(29,79,115,0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-light {
|
||||||
|
--cell-border-color: rgba(0,0,0,0.15);
|
||||||
|
--focus-cell-border-color: rgba(0,0,0,0.3);
|
||||||
|
--row-alt-background-color: rgba(76,158,217,0.1);
|
||||||
|
--row-hover-background-color: rgba(76,158,217,0.2);
|
||||||
|
}
|
||||||
|
|
||||||
/* Toolbar */
|
/* Toolbar */
|
||||||
|
|
||||||
|
#performance-toolbar > tabs,
|
||||||
#performance-toolbar {
|
#performance-toolbar {
|
||||||
-moz-border-end: 1px solid;
|
-moz-border-end-color: var(--theme-splitter-color);
|
||||||
}
|
|
||||||
|
|
||||||
.theme-dark #performance-toolbar > tabs,
|
|
||||||
.theme-dark #performance-toolbar {
|
|
||||||
-moz-border-end-color: #000; /* Splitters */
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light #performance-toolbar > tabs,
|
|
||||||
.theme-light #performance-toolbar {
|
|
||||||
-moz-border-end-color: #aaa; /* Splitters */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Overview Panel */
|
/* Overview Panel */
|
||||||
|
@ -85,23 +91,14 @@
|
||||||
-moz-box-align: center;
|
-moz-box-align: center;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding: 1px 4px;
|
padding: 1px 4px;
|
||||||
|
color: var(--theme-body-color);
|
||||||
|
-moz-border-end-color: var(--cell-border-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.call-tree-header:not(:last-child),
|
.call-tree-header:not(:last-child),
|
||||||
.call-tree-cell:not(:last-child) {
|
.call-tree-cell:not(:last-child) {
|
||||||
-moz-border-end: 1px solid;
|
-moz-border-end-width: 1px;
|
||||||
}
|
-moz-border-end-style: solid;
|
||||||
|
|
||||||
.theme-dark .call-tree-header,
|
|
||||||
.theme-dark .call-tree-cell {
|
|
||||||
-moz-border-end-color: rgba(255,255,255,0.15);
|
|
||||||
color: #8fa1b2; /* Body Text */
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .call-tree-header,
|
|
||||||
.theme-light .call-tree-cell {
|
|
||||||
-moz-border-end-color: rgba(0,0,0,0.15);
|
|
||||||
color: #18191a; /* Body Text */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.call-tree-header:not(:last-child) {
|
.call-tree-header:not(:last-child) {
|
||||||
|
@ -112,56 +109,32 @@
|
||||||
text-align: end;
|
text-align: end;
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-dark .call-tree-header {
|
.call-tree-header {
|
||||||
background-color: #252c33; /* Tab Toolbar */
|
background-color: var(--theme-tab-toolbar-background);
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-light .call-tree-header {
|
.call-tree-item:last-child:not(:focus) {
|
||||||
background-color: #ebeced; /* Tab Toolbar */
|
border-bottom: 1px solid var(--cell-border-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-dark .call-tree-item:last-child:not(:focus) {
|
.call-tree-item:nth-child(2n) {
|
||||||
border-bottom: 1px solid rgba(255,255,255,0.15);
|
background-color: var(--row-alt-background-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-light .call-tree-item:last-child:not(:focus) {
|
.call-tree-item:hover {
|
||||||
border-bottom: 1px solid rgba(0,0,0,0.15);
|
background-color: var(--row-hover-background-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-dark .call-tree-item:nth-child(2n) {
|
.call-tree-item:focus {
|
||||||
background-color: rgba(29,79,115,0.15);
|
background-color: var(--theme-selection-background);
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .call-tree-item:nth-child(2n) {
|
|
||||||
background-color: rgba(76,158,217,0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-dark .call-tree-item:hover {
|
|
||||||
background-color: rgba(29,79,115,0.25);
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .call-tree-item:hover {
|
|
||||||
background-color: rgba(76,158,217,0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-dark .call-tree-item:focus {
|
|
||||||
background-color: #1d4f73; /* Select Highlight Blue */
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .call-tree-item:focus {
|
|
||||||
background-color: #4c9ed9; /* Select Highlight Blue */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.call-tree-item:focus label {
|
.call-tree-item:focus label {
|
||||||
color: #f5f7fa !important; /* Light foreground text */
|
color: var(--theme-selection-color) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-dark .call-tree-item:focus .call-tree-cell {
|
.call-tree-item:focus .call-tree-cell {
|
||||||
-moz-border-end-color: rgba(0,0,0,0.3);
|
-moz-border-end-color: var(--focus-cell-border-color);
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .call-tree-item:focus .call-tree-cell {
|
|
||||||
-moz-border-end-color: rgba(255,255,255,0.5);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.call-tree-item:not([origin="content"]) .call-tree-name,
|
.call-tree-item:not([origin="content"]) .call-tree-name,
|
||||||
|
@ -180,33 +153,18 @@
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-dark .call-tree-url {
|
.call-tree-url {
|
||||||
color: #46afe3;
|
color: var(--theme-highlight-blue);
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-light .call-tree-url {
|
.call-tree-line {
|
||||||
color: #0088cc;
|
color: var(--theme-highlight-orange);
|
||||||
}
|
|
||||||
|
|
||||||
.theme-dark .call-tree-line {
|
|
||||||
color: #d96629;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .call-tree-line {
|
|
||||||
color: #f13c00;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.call-tree-host {
|
.call-tree-host {
|
||||||
-moz-margin-start: 8px !important;
|
-moz-margin-start: 8px !important;
|
||||||
font-size: 90%;
|
font-size: 90%;
|
||||||
}
|
color: var(--theme-content-color2);
|
||||||
|
|
||||||
.theme-dark .call-tree-host {
|
|
||||||
color: #8fa1b2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .call-tree-host {
|
|
||||||
color: #8fa1b2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.call-tree-url[value=""],
|
.call-tree-url[value=""],
|
||||||
|
@ -307,15 +265,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.waterfall-sidebar {
|
.waterfall-sidebar {
|
||||||
-moz-border-end: 1px solid;
|
-moz-border-end: 1px solid var(--theme-splitter-color);
|
||||||
}
|
|
||||||
|
|
||||||
.theme-dark .waterfall-sidebar {
|
|
||||||
-moz-border-end-color: #000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .waterfall-sidebar {
|
|
||||||
-moz-border-end-color: #aaa;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.waterfall-marker-container:hover > .waterfall-sidebar {
|
.waterfall-marker-container:hover > .waterfall-sidebar {
|
||||||
|
@ -330,14 +280,7 @@
|
||||||
width: 100px;
|
width: 100px;
|
||||||
font-size: 9px;
|
font-size: 9px;
|
||||||
transform-origin: left center;
|
transform-origin: left center;
|
||||||
}
|
color: var(--theme-body-color);
|
||||||
|
|
||||||
.theme-dark .waterfall-header-tick {
|
|
||||||
color: #a9bacb;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .waterfall-header-tick {
|
|
||||||
color: #292e33;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.waterfall-header-tick:not(:first-child) {
|
.waterfall-header-tick:not(:first-child) {
|
||||||
|
@ -365,21 +308,14 @@
|
||||||
transform-origin: left center;
|
transform-origin: left center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-light .waterfall-marker-container.selected > .waterfall-sidebar,
|
.waterfall-marker-container.selected > .waterfall-marker-item {
|
||||||
.theme-light .waterfall-marker-container.selected > .waterfall-marker-item {
|
background-color: var(--theme-selection-background);
|
||||||
background-color: #4c9ed9; /* Select Highlight Blue */
|
color: var(--theme-selection-color);
|
||||||
color: #f5f7fa; /* Light foreground text */
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-dark .waterfall-marker-container.selected > .waterfall-sidebar,
|
|
||||||
.theme-dark .waterfall-marker-container.selected > .waterfall-marker-item {
|
|
||||||
background-color: #1d4f73; /* Select Highlight Blue */
|
|
||||||
color: #f5f7fa; /* Light foreground text */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.waterfall-marker-container.selected .waterfall-marker-bullet,
|
.waterfall-marker-container.selected .waterfall-marker-bullet,
|
||||||
.waterfall-marker-container.selected .waterfall-marker-bar {
|
.waterfall-marker-container.selected .waterfall-marker-bar {
|
||||||
border-color: initial!important;
|
border-color: initial !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#waterfall-details {
|
#waterfall-details {
|
||||||
|
|
|
@ -3,6 +3,21 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
/* CSS Variables specific to this panel that aren't defined by the themes */
|
||||||
|
.theme-dark {
|
||||||
|
--cell-border-color: rgba(255,255,255,0.15);
|
||||||
|
--focus-cell-border-color: rgba(0,0,0,0.3);
|
||||||
|
--row-alt-background-color: rgba(29,79,115,0.15);
|
||||||
|
--row-hover-background-color: rgba(29,79,115,0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-light {
|
||||||
|
--cell-border-color: rgba(0,0,0,0.15);
|
||||||
|
--focus-cell-border-color: rgba(255,255,255,0.5);
|
||||||
|
--row-alt-background-color: rgba(76,158,217,0.1);
|
||||||
|
--row-hover-background-color: rgba(76,158,217,0.2);
|
||||||
|
}
|
||||||
|
|
||||||
/* Reload and waiting notices */
|
/* Reload and waiting notices */
|
||||||
|
|
||||||
.notice-container {
|
.notice-container {
|
||||||
|
@ -245,17 +260,13 @@
|
||||||
|
|
||||||
.call-tree-header:not(:last-child),
|
.call-tree-header:not(:last-child),
|
||||||
.call-tree-cell:not(:last-child) {
|
.call-tree-cell:not(:last-child) {
|
||||||
-moz-border-end: 1px solid;
|
-moz-border-end-width: 1px;
|
||||||
|
-moz-border-end-style: solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-dark .call-tree-header,
|
.call-tree-header,
|
||||||
.theme-dark .call-tree-cell {
|
.call-tree-cell {
|
||||||
-moz-border-end-color: rgba(255,255,255,0.15);
|
-moz-border-end-color: var(--cell-border-color);
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .call-tree-header,
|
|
||||||
.theme-light .call-tree-cell {
|
|
||||||
-moz-border-end-color: rgba(0,0,0,0.15);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.call-tree-header:not(:last-child) {
|
.call-tree-header:not(:last-child) {
|
||||||
|
@ -270,28 +281,16 @@
|
||||||
background-color: var(--theme-tab-toolbar-background);
|
background-color: var(--theme-tab-toolbar-background);
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-dark .call-tree-item:last-child:not(:focus) {
|
.call-tree-item:last-child:not(:focus) {
|
||||||
border-bottom: 1px solid rgba(255,255,255,0.15);
|
border-bottom: 1px solid var(--cell-border-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-light .call-tree-item:last-child:not(:focus) {
|
.call-tree-item:nth-child(2n) {
|
||||||
border-bottom: 1px solid rgba(0,0,0,0.15);
|
background-color: var(--row-alt-background-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-dark .call-tree-item:nth-child(2n) {
|
.call-tree-item:hover {
|
||||||
background-color: rgba(29,79,115,0.15);
|
background-color: var(--row-hover-background-color);
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .call-tree-item:nth-child(2n) {
|
|
||||||
background-color: rgba(76,158,217,0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-dark .call-tree-item:hover {
|
|
||||||
background-color: rgba(29,79,115,0.25);
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .call-tree-item:hover {
|
|
||||||
background-color: rgba(76,158,217,0.2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.call-tree-item:focus {
|
.call-tree-item:focus {
|
||||||
|
@ -302,12 +301,8 @@
|
||||||
color: var(--theme-selection-color) !important;
|
color: var(--theme-selection-color) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-dark .call-tree-item:focus .call-tree-cell {
|
.call-tree-item:focus .call-tree-cell {
|
||||||
-moz-border-end-color: rgba(0,0,0,0.3);
|
-moz-border-end-color: var(--focus-cell-border-color);
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .call-tree-item:focus .call-tree-cell {
|
|
||||||
-moz-border-end-color: rgba(255,255,255,0.5);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.call-tree-item:not([origin="content"]) .call-tree-name,
|
.call-tree-item:not([origin="content"]) .call-tree-name,
|
||||||
|
|
|
@ -77,8 +77,13 @@ AudioOffloadPlayer::AudioOffloadPlayer(MediaOmxCommonDecoder* aObserver) :
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CHECK(aObserver);
|
CHECK(aObserver);
|
||||||
|
#if ANDROID_VERSION >= 21
|
||||||
|
mSessionId = AudioSystem::newAudioUniqueId();
|
||||||
|
AudioSystem::acquireAudioSessionId(mSessionId, -1);
|
||||||
|
#else
|
||||||
mSessionId = AudioSystem::newAudioSessionId();
|
mSessionId = AudioSystem::newAudioSessionId();
|
||||||
AudioSystem::acquireAudioSessionId(mSessionId);
|
AudioSystem::acquireAudioSessionId(mSessionId);
|
||||||
|
#endif
|
||||||
mAudioSink = new AudioOutput(mSessionId,
|
mAudioSink = new AudioOutput(mSessionId,
|
||||||
IPCThreadState::self()->getCallingUid());
|
IPCThreadState::self()->getCallingUid());
|
||||||
}
|
}
|
||||||
|
@ -86,7 +91,11 @@ AudioOffloadPlayer::AudioOffloadPlayer(MediaOmxCommonDecoder* aObserver) :
|
||||||
AudioOffloadPlayer::~AudioOffloadPlayer()
|
AudioOffloadPlayer::~AudioOffloadPlayer()
|
||||||
{
|
{
|
||||||
Reset();
|
Reset();
|
||||||
|
#if ANDROID_VERSION >= 21
|
||||||
|
AudioSystem::releaseAudioSessionId(mSessionId, -1);
|
||||||
|
#else
|
||||||
AudioSystem::releaseAudioSessionId(mSessionId);
|
AudioSystem::releaseAudioSessionId(mSessionId);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioOffloadPlayer::SetSource(const sp<MediaSource> &aSource)
|
void AudioOffloadPlayer::SetSource(const sp<MediaSource> &aSource)
|
||||||
|
|
|
@ -9,10 +9,13 @@ interface MozWakeLockListener;
|
||||||
* The reason for the factory reset.
|
* The reason for the factory reset.
|
||||||
* "normal" : simple factory reset.
|
* "normal" : simple factory reset.
|
||||||
* "wipe" : will also attempt to wipe all user storage areas.
|
* "wipe" : will also attempt to wipe all user storage areas.
|
||||||
|
* "root" : simple factory reset that also root the phone to get more
|
||||||
|
* privileges when using devtools.
|
||||||
*/
|
*/
|
||||||
enum FactoryResetReason {
|
enum FactoryResetReason {
|
||||||
"normal",
|
"normal",
|
||||||
"wipe"
|
"wipe",
|
||||||
|
"root"
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1777,6 +1777,8 @@ FactoryReset(FactoryResetReason& aReason)
|
||||||
|
|
||||||
if (aReason == FactoryResetReason::Wipe) {
|
if (aReason == FactoryResetReason::Wipe) {
|
||||||
recoveryService->FactoryReset("wipe");
|
recoveryService->FactoryReset("wipe");
|
||||||
|
} else if (aReason == FactoryResetReason::Root) {
|
||||||
|
recoveryService->FactoryReset("root");
|
||||||
} else {
|
} else {
|
||||||
recoveryService->FactoryReset("normal");
|
recoveryService->FactoryReset("normal");
|
||||||
}
|
}
|
||||||
|
|
|
@ -446,6 +446,8 @@ FactoryReset(FactoryResetReason& aReason)
|
||||||
Hal()->SendFactoryReset(NS_LITERAL_STRING("normal"));
|
Hal()->SendFactoryReset(NS_LITERAL_STRING("normal"));
|
||||||
} else if (aReason == FactoryResetReason::Wipe) {
|
} else if (aReason == FactoryResetReason::Wipe) {
|
||||||
Hal()->SendFactoryReset(NS_LITERAL_STRING("wipe"));
|
Hal()->SendFactoryReset(NS_LITERAL_STRING("wipe"));
|
||||||
|
} else if (aReason == FactoryResetReason::Root) {
|
||||||
|
Hal()->SendFactoryReset(NS_LITERAL_STRING("root"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -870,6 +872,8 @@ public:
|
||||||
reason = FactoryResetReason::Normal;
|
reason = FactoryResetReason::Normal;
|
||||||
} else if (aReason.EqualsLiteral("wipe")) {
|
} else if (aReason.EqualsLiteral("wipe")) {
|
||||||
reason = FactoryResetReason::Wipe;
|
reason = FactoryResetReason::Wipe;
|
||||||
|
} else if (aReason.EqualsLiteral("root")) {
|
||||||
|
reason = FactoryResetReason::Root;
|
||||||
} else {
|
} else {
|
||||||
// Invalid factory reset reason. That should never happen.
|
// Invalid factory reset reason. That should never happen.
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -65,7 +65,12 @@ public abstract class SessionParser {
|
||||||
for (int i = 0; i < tabs.length(); i++) {
|
for (int i = 0; i < tabs.length(); i++) {
|
||||||
final JSONObject tab = tabs.getJSONObject(i);
|
final JSONObject tab = tabs.getJSONObject(i);
|
||||||
final int index = tab.getInt("index");
|
final int index = tab.getInt("index");
|
||||||
final JSONObject entry = tab.getJSONArray("entries").getJSONObject(index - 1);
|
final JSONArray entries = tab.getJSONArray("entries");
|
||||||
|
if (index < 1 || entries.length() < index) {
|
||||||
|
Log.w(LOGTAG, "Session entries and index don't agree.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final JSONObject entry = entries.getJSONObject(index - 1);
|
||||||
final String url = entry.getString("url");
|
final String url = entry.getString("url");
|
||||||
|
|
||||||
String title = entry.optString("title");
|
String title = entry.optString("title");
|
||||||
|
|
|
@ -244,6 +244,7 @@ SandboxFilterImplContent::Build() {
|
||||||
Allow(SYSCALL(sched_setparam));
|
Allow(SYSCALL(sched_setparam));
|
||||||
Allow(SYSCALL(sigaltstack));
|
Allow(SYSCALL(sigaltstack));
|
||||||
Allow(SYSCALL(pipe));
|
Allow(SYSCALL(pipe));
|
||||||
|
Allow(SYSCALL(set_tid_address));
|
||||||
|
|
||||||
/* Always last and always OK calls */
|
/* Always last and always OK calls */
|
||||||
/* Architecture-specific very infrequently used syscalls */
|
/* Architecture-specific very infrequently used syscalls */
|
||||||
|
|
|
@ -34,6 +34,19 @@ const {FramerateActor} = require("devtools/server/actors/framerate");
|
||||||
// docShell, no event is sent).
|
// docShell, no event is sent).
|
||||||
const DEFAULT_TIMELINE_DATA_PULL_TIMEOUT = 200; // ms
|
const DEFAULT_TIMELINE_DATA_PULL_TIMEOUT = 200; // ms
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type representing an array of numbers as strings, serialized fast(er).
|
||||||
|
* http://jsperf.com/json-stringify-parse-vs-array-join-split/3
|
||||||
|
*
|
||||||
|
* XXX: It would be nice if on local connections (only), we could just *give*
|
||||||
|
* the array directly to the front, instead of going through all this
|
||||||
|
* serialization redundancy.
|
||||||
|
*/
|
||||||
|
protocol.types.addType("array-of-numbers-as-strings", {
|
||||||
|
write: (v) => v.join(","),
|
||||||
|
read: (v) => v.split(",")
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The timeline actor pops and forwards timeline markers registered in docshells.
|
* The timeline actor pops and forwards timeline markers registered in docshells.
|
||||||
*/
|
*/
|
||||||
|
@ -72,7 +85,7 @@ let TimelineActor = exports.TimelineActor = protocol.ActorClass({
|
||||||
"ticks" : {
|
"ticks" : {
|
||||||
type: "ticks",
|
type: "ticks",
|
||||||
delta: Arg(0, "number"),
|
delta: Arg(0, "number"),
|
||||||
timestamps: Arg(1, "array:number")
|
timestamps: Arg(1, "array-of-numbers-as-strings")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче