Merge m-c to fx-team

This commit is contained in:
Wes Kocher 2014-07-21 17:39:05 -07:00
commit 28ee81fd61
172 changed files with 2783 additions and 2470 deletions

View File

@ -102,3 +102,4 @@ ba2cc1eda988a1614d8986ae145d28e1268409b9 FIREFOX_AURORA_29_BASE
83c9853e136451474dfa6d1aaa60a7fca7d2d83a FIREFOX_AURORA_30_BASE
cfde3603b0206e119abea76fdd6e134b634348f1 FIREFOX_AURORA_31_BASE
16f3cac5e8fe471e12f76d6a94a477b14e78df7c FIREFOX_AURORA_32_BASE
dc23164ba2a289a8b22902e30990c77d9677c214 FIREFOX_AURORA_33_BASE

View File

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Clobber to work around bug 959928.
Merge day clobber

View File

@ -19,13 +19,13 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1c9eb3d16167c2e5a9f7789eb46ee17830e6054e"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="649245c238a043af32acb109b2613f578323f8e1"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7f792d756385bb894fba7645da59c67fe2c804bf"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="227354333a185180b85471f2cc6abfb029e44718"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8b04b5aca4b0a894de40f4d53ae9750222d349a8"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="31215645c296ba7a62bcb3176f69e0014ab9be07"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
<project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>

View File

@ -17,10 +17,10 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1c9eb3d16167c2e5a9f7789eb46ee17830e6054e"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="649245c238a043af32acb109b2613f578323f8e1"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7f792d756385bb894fba7645da59c67fe2c804bf"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8b04b5aca4b0a894de40f4d53ae9750222d349a8"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="31215645c296ba7a62bcb3176f69e0014ab9be07"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="276ce45e78b09c4a4ee643646f691d22804754c1">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1c9eb3d16167c2e5a9f7789eb46ee17830e6054e"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="649245c238a043af32acb109b2613f578323f8e1"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7f792d756385bb894fba7645da59c67fe2c804bf"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8b04b5aca4b0a894de40f4d53ae9750222d349a8"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="31215645c296ba7a62bcb3176f69e0014ab9be07"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/>

View File

@ -19,13 +19,13 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1c9eb3d16167c2e5a9f7789eb46ee17830e6054e"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="649245c238a043af32acb109b2613f578323f8e1"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7f792d756385bb894fba7645da59c67fe2c804bf"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="227354333a185180b85471f2cc6abfb029e44718"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8b04b5aca4b0a894de40f4d53ae9750222d349a8"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="31215645c296ba7a62bcb3176f69e0014ab9be07"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
<project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>

View File

@ -17,10 +17,10 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1c9eb3d16167c2e5a9f7789eb46ee17830e6054e"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="649245c238a043af32acb109b2613f578323f8e1"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7f792d756385bb894fba7645da59c67fe2c804bf"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8b04b5aca4b0a894de40f4d53ae9750222d349a8"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="31215645c296ba7a62bcb3176f69e0014ab9be07"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->

View File

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "cea1598e51f188fe8c48196cbb2c73aacbf3b1dc",
"revision": "591c866cb04a88306e472c873429669229f28540",
"repo_path": "/integration/gaia-central"
}

View File

@ -17,12 +17,12 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1c9eb3d16167c2e5a9f7789eb46ee17830e6054e"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="649245c238a043af32acb109b2613f578323f8e1"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7f792d756385bb894fba7645da59c67fe2c804bf"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8b04b5aca4b0a894de40f4d53ae9750222d349a8"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="31215645c296ba7a62bcb3176f69e0014ab9be07"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
<project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>

View File

@ -15,7 +15,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1c9eb3d16167c2e5a9f7789eb46ee17830e6054e"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="649245c238a043af32acb109b2613f578323f8e1"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7f792d756385bb894fba7645da59c67fe2c804bf"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -17,10 +17,10 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1c9eb3d16167c2e5a9f7789eb46ee17830e6054e"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="649245c238a043af32acb109b2613f578323f8e1"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7f792d756385bb894fba7645da59c67fe2c804bf"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8b04b5aca4b0a894de40f4d53ae9750222d349a8"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="31215645c296ba7a62bcb3176f69e0014ab9be07"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->

View File

@ -17,12 +17,12 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1c9eb3d16167c2e5a9f7789eb46ee17830e6054e"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="649245c238a043af32acb109b2613f578323f8e1"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7f792d756385bb894fba7645da59c67fe2c804bf"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8b04b5aca4b0a894de40f4d53ae9750222d349a8"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="31215645c296ba7a62bcb3176f69e0014ab9be07"/>
<project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>

View File

@ -5,7 +5,7 @@
MOZ_APP_BASENAME=B2G
MOZ_APP_VENDOR=Mozilla
MOZ_APP_VERSION=33.0a1
MOZ_APP_VERSION=34.0a1
MOZ_APP_UA_NAME=Firefox
MOZ_UA_OS_AGNOSTIC=1

View File

@ -12,9 +12,6 @@ Cu.import("resource://gre/modules/FxAccounts.jsm");
let fxAccountsCommon = {};
Cu.import("resource://gre/modules/FxAccountsCommon.js", fxAccountsCommon);
// for master-password utilities
Cu.import("resource://services-sync/util.js");
const PREF_LAST_FXA_USER = "identity.fxaccounts.lastSignedInUserHash";
const PREF_SYNC_SHOW_CUSTOMIZATION = "services.sync.ui.showCustomizationDialog";
@ -107,12 +104,6 @@ let wrapper = {
return;
}
// If a master-password is enabled, we want to encourage the user to
// unlock it. Things still work if not, but the user will probably need
// to re-auth next startup (in which case we will get here again and
// re-prompt)
Utils.ensureMPUnlocked();
let iframe = document.getElementById("remote");
this.iframe = iframe;
iframe.addEventListener("load", this);

View File

@ -4,6 +4,20 @@
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/Services.jsm");
let service = Cc["@mozilla.org/weave/service;1"]
.getService(Ci.nsISupports)
.wrappedJSObject;
if (!service.allowPasswordsEngine) {
let checkbox = document.getElementById("fxa-pweng-chk");
checkbox.checked = false;
checkbox.disabled = true;
}
addEventListener("dialogaccept", function () {
let pane = document.getElementById("sync-customize-pane");
pane.writePreferences(true);

View File

@ -45,7 +45,8 @@
<checkbox label="&engine.bookmarks.label;"
accesskey="&engine.bookmarks.accesskey;"
preference="engine.bookmarks"/>
<checkbox label="&engine.passwords.label;"
<checkbox id="fxa-pweng-chk"
label="&engine.passwords.label;"
accesskey="&engine.passwords.accesskey;"
preference="engine.passwords"/>
<checkbox label="&engine.history.label;"

View File

@ -87,6 +87,12 @@ let gSyncUtils = {
this._openLink(Weave.Svc.Prefs.get(root + "privacyURL"));
},
openMPInfoPage: function (event) {
event.stopPropagation();
let baseURL = Services.urlFormatter.formatURLPref("app.support.baseURL");
this._openLink(baseURL + "sync-master-password");
},
openFirstSyncProgressPage: function () {
this._openLink("about:sync-progress");
},

View File

@ -154,6 +154,17 @@ let gSyncPane = {
for (let checkbox of engines.querySelectorAll("checkbox")) {
checkbox.disabled = enginesListDisabled;
}
let checkbox = document.getElementById("fxa-pweng-chk");
let help = document.getElementById("fxa-pweng-help");
let allowPasswordsEngine = service.allowPasswordsEngine;
if (!allowPasswordsEngine) {
checkbox.checked = false;
}
checkbox.disabled = !allowPasswordsEngine || enginesListDisabled;
help.hidden = allowPasswordsEngine || enginesListDisabled;
});
// If fxAccountEnabled is false and we are in a "not configured" state,
// then fxAccounts is probably fully disabled rather than just unconfigured,

View File

@ -283,9 +283,20 @@
<checkbox label="&engine.bookmarks.label;"
accesskey="&engine.bookmarks.accesskey;"
preference="engine.bookmarks"/>
<checkbox label="&engine.passwords.label;"
accesskey="&engine.passwords.accesskey;"
preference="engine.passwords"/>
<hbox>
<checkbox id="fxa-pweng-chk"
label="&engine.passwords.label;"
accesskey="&engine.passwords.accesskey;"
preference="engine.passwords"/>
<vbox id="fxa-pweng-help">
<spacer flex="1"/>
<hbox id="fxa-pweng-help-link">
<image onclick="gSyncUtils.openMPInfoPage(event);" />
</hbox>
<spacer flex="1"/>
</vbox>
</hbox>
<checkbox label="&engine.history.label;"
accesskey="&engine.history.accesskey;"
preference="engine.history"/>

View File

@ -154,6 +154,17 @@ let gSyncPane = {
for (let checkbox of engines.querySelectorAll("checkbox")) {
checkbox.disabled = enginesListDisabled;
}
let checkbox = document.getElementById("fxa-pweng-chk");
let help = document.getElementById("fxa-pweng-help");
let allowPasswordsEngine = service.allowPasswordsEngine;
if (!allowPasswordsEngine) {
checkbox.checked = false;
}
checkbox.disabled = !allowPasswordsEngine || enginesListDisabled;
help.hidden = allowPasswordsEngine || enginesListDisabled;
});
// If fxAccountEnabled is false and we are in a "not configured" state,
// then fxAccounts is probably fully disabled rather than just unconfigured,

View File

@ -265,9 +265,20 @@
<checkbox label="&engine.bookmarks.label;"
accesskey="&engine.bookmarks.accesskey;"
preference="engine.bookmarks"/>
<checkbox label="&engine.passwords.label;"
accesskey="&engine.passwords.accesskey;"
preference="engine.passwords"/>
<hbox>
<checkbox id="fxa-pweng-chk"
label="&engine.passwords.label;"
accesskey="&engine.passwords.accesskey;"
preference="engine.passwords"/>
<vbox id="fxa-pweng-help">
<spacer flex="1"/>
<hbox id="fxa-pweng-help-link">
<image onclick="gSyncUtils.openMPInfoPage(event);" />
</hbox>
<spacer flex="1"/>
</vbox>
</hbox>
<checkbox label="&engine.history.label;"
accesskey="&engine.history.accesskey;"
preference="engine.history"/>

View File

@ -1 +1 @@
33.0a1
34.0a1

View File

@ -171,4 +171,12 @@ label.small {
margin-bottom: 0.6em;
}
#fxa-pweng-help-link > label {
margin: 0;
}
#fxa-pweng-help-link > image {
list-style-image: url("chrome://global/skin/icons/question-16.png");
}
%endif

View File

@ -233,4 +233,20 @@ html|a.inline-link:-moz-focusring {
margin-bottom: 0.6em;
}
#fxa-pweng-help-link > label {
margin: 0;
}
#fxa-pweng-help-link > image {
width: 16px;
height: 16px;
list-style-image: url("chrome://global/skin/icons/question-16.png");
}
@media (min-resolution: 2dppx) {
#fxa-pweng-help-link > image {
list-style-image: url("chrome://global/skin/icons/question-32.png");
}
}
%endif

View File

@ -161,4 +161,12 @@ label.small {
margin-bottom: 0.6em;
}
#fxa-pweng-help-link > label {
margin: 0;
}
#fxa-pweng-help-link > image {
list-style-image: url("chrome://global/skin/icons/question-16.png");
}
%endif

View File

@ -10,4 +10,4 @@
# hardcoded milestones in the tree from these two files.
#--------------------------------------------------------
33.0a1
34.0a1

View File

@ -69,6 +69,7 @@
#include "mozilla/dom/TreeWalker.h"
#include "nsIServiceManager.h"
#include "nsIServiceWorkerManager.h"
#include "nsContentCID.h"
#include "nsError.h"
@ -4465,6 +4466,24 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject)
if (mTemplateContentsOwner && mTemplateContentsOwner != this) {
mTemplateContentsOwner->SetScriptGlobalObject(aScriptGlobalObject);
}
nsCOMPtr<nsIChannel> channel = GetChannel();
if (!mMaybeServiceWorkerControlled && channel) {
nsLoadFlags loadFlags = 0;
channel->GetLoadFlags(&loadFlags);
// If we are shift-reloaded, don't associate with a ServiceWorker.
// FIXME(nsm): Bug 1041339.
if (loadFlags & nsIRequest::LOAD_BYPASS_CACHE) {
NS_WARNING("Page was shift reloaded, skipping ServiceWorker control");
return;
}
nsCOMPtr<nsIServiceWorkerManager> swm = do_GetService(SERVICEWORKERMANAGER_CONTRACTID);
if (swm) {
swm->MaybeStartControlling(this);
mMaybeServiceWorkerControlled = true;
}
}
}
nsIScriptGlobalObject*
@ -8483,6 +8502,11 @@ nsDocument::Destroy()
mRegistry = nullptr;
nsCOMPtr<nsIServiceWorkerManager> swm = do_GetService(SERVICEWORKERMANAGER_CONTRACTID);
if (swm) {
swm->MaybeStopControlling(this);
}
// XXX We really should let cycle collection do this, but that currently still
// leaks (see https://bugzilla.mozilla.org/show_bug.cgi?id=406684).
ReleaseWrapper(static_cast<nsINode*>(this));

View File

@ -1742,6 +1742,10 @@ private:
nsCOMPtr<nsIDocument> mMasterDocument;
nsRefPtr<mozilla::dom::ImportManager> mImportManager;
// Set to true when the document is possibly controlled by the ServiceWorker.
// Used to prevent multiple requests to ServiceWorkerManager.
bool mMaybeServiceWorkerControlled;
#ifdef DEBUG
public:
bool mWillReparent;

View File

@ -26,7 +26,6 @@
#include "nsJSNPRuntime.h"
#include "nsINestedURI.h"
#include "nsIPresShell.h"
#include "nsIScriptGlobalObject.h"
#include "nsScriptSecurityManager.h"
#include "nsIScriptSecurityManager.h"
#include "nsIStreamConverterService.h"
@ -80,6 +79,7 @@
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/Event.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/EventStates.h"
#include "mozilla/Telemetry.h"
@ -2914,21 +2914,9 @@ nsObjectLoadingContent::NotifyContentObjectWrapper()
nsCOMPtr<nsIContent> thisContent =
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
nsCOMPtr<nsIDocument> doc = thisContent->GetDocument();
if (!doc)
return;
nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(doc->GetScopeObject());
if (!sgo)
return;
nsIScriptContext *scx = sgo->GetContext();
if (!scx)
return;
JSContext *cx = scx->GetNativeContext();
nsCxPusher pusher;
pusher.Push(cx);
AutoJSAPI jsapi;
jsapi.Init();
JSContext* cx = jsapi.cx();
JS::Rooted<JSObject*> obj(cx, thisContent->GetWrapper());
if (!obj) {
@ -3297,12 +3285,7 @@ nsObjectLoadingContent::SetupProtoChain(JSContext* aCx,
}
if (!nsContentUtils::IsSafeToRunScript()) {
// This may be null if the JS context is not a DOM context. That's ok, we'll
// use the safe context from XPConnect in the runnable.
nsCOMPtr<nsIScriptContext> scriptContext = GetScriptContextFromJSContext(aCx);
nsRefPtr<SetupProtoChainRunner> runner =
new SetupProtoChainRunner(scriptContext, this);
nsRefPtr<SetupProtoChainRunner> runner = new SetupProtoChainRunner(this);
nsContentUtils::AddScriptRunner(runner);
return;
}
@ -3510,10 +3493,8 @@ nsObjectLoadingContent::GetOwnPropertyNames(JSContext* aCx,
// SetupProtoChainRunner implementation
nsObjectLoadingContent::SetupProtoChainRunner::SetupProtoChainRunner(
nsIScriptContext* scriptContext,
nsObjectLoadingContent* aContent)
: mContext(scriptContext)
, mContent(aContent)
: mContent(aContent)
{
}
@ -3524,12 +3505,9 @@ nsObjectLoadingContent::SetupProtoChainRunner::~SetupProtoChainRunner()
NS_IMETHODIMP
nsObjectLoadingContent::SetupProtoChainRunner::Run()
{
// XXXbz Does it really matter what JSContext we use here? Seems
// like we could just always use the safe context....
nsCxPusher pusher;
JSContext* cx = mContext ? mContext->GetNativeContext()
: nsContentUtils::GetSafeJSContext();
pusher.Push(cx);
AutoJSAPI jsapi;
jsapi.Init();
JSContext* cx = jsapi.cx();
nsCOMPtr<nsIContent> content;
CallQueryInterface(mContent.get(), getter_AddRefs(content));

View File

@ -477,13 +477,11 @@ class nsObjectLoadingContent : public nsImageLoadingContent
public:
NS_DECL_ISUPPORTS
SetupProtoChainRunner(nsIScriptContext* scriptContext,
nsObjectLoadingContent* aContent);
SetupProtoChainRunner(nsObjectLoadingContent* aContent);
NS_IMETHOD Run() MOZ_OVERRIDE;
private:
nsCOMPtr<nsIScriptContext> mContext;
// We store an nsIObjectLoadingContent because we can
// unambiguously refcount that.
nsRefPtr<nsIObjectLoadingContent> mContent;

View File

@ -21,20 +21,7 @@ SOURCES += [
]
if CONFIG['MOZ_WMF']:
EXPORTS += [
'wmf/MFTDecoder.h',
'wmf/WMFAudioMFTManager.h',
'wmf/WMFDecoderModule.h',
'wmf/WMFMediaDataDecoder.h',
'wmf/WMFVideoMFTManager.h',
]
UNIFIED_SOURCES += [
'wmf/MFTDecoder.cpp',
'wmf/WMFAudioMFTManager.cpp',
'wmf/WMFDecoderModule.cpp',
'wmf/WMFMediaDataDecoder.cpp',
'wmf/WMFVideoMFTManager.cpp',
]
PARALLEL_DIRS += [ 'wmf' ];
if CONFIG['MOZ_FFMPEG']:
EXPORTS += [

View File

@ -133,7 +133,7 @@ MFTDecoder::CreateInputSample(const uint8_t* aData,
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
RefPtr<IMFMediaBuffer> buffer;
int32_t bufferSize = std::max(uint32_t(mInputStreamInfo.cbSize), aDataSize);
int32_t bufferSize = std::max<uint32_t>(uint32_t(mInputStreamInfo.cbSize), aDataSize);
UINT32 alignment = (mInputStreamInfo.cbAlignment > 1) ? mInputStreamInfo.cbAlignment - 1 : 0;
hr = wmf::MFCreateAlignedMemoryBuffer(bufferSize, alignment, byRef(buffer));
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);

View File

@ -0,0 +1,24 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXPORTS += [
'MFTDecoder.h',
'WMFAudioMFTManager.h',
'WMFDecoderModule.h',
'WMFMediaDataDecoder.h',
'WMFVideoMFTManager.h',
]
UNIFIED_SOURCES += [
'MFTDecoder.cpp',
'WMFAudioMFTManager.cpp',
'WMFDecoderModule.cpp',
'WMFMediaDataDecoder.cpp',
'WMFVideoMFTManager.cpp',
]
FINAL_LIBRARY = 'gklayout'
FAIL_ON_WARNINGS = True

View File

@ -14,6 +14,8 @@
#include "nsIRunnable.h"
#include "mozIGeckoMediaPluginService.h"
#include "mozilla/unused.h"
#include "nsIObserverService.h"
#include "mtransport/runnable_utils.h"
#include "mozilla/dom/CrashReporterParent.h"
using mozilla::dom::CrashReporterParent;
@ -321,16 +323,37 @@ GMPParent::GetCrashID(nsString& aResult)
}
#endif
static void
GMPNotifyObservers(nsAString& aData)
{
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) {
nsString temp(aData);
obs->NotifyObservers(nullptr, "gmp-plugin-crash", temp.get());
}
}
void
GMPParent::ActorDestroy(ActorDestroyReason aWhy)
{
#ifdef MOZ_CRASHREPORTER
if (AbnormalShutdown == aWhy) {
nsString dumpID;
#ifdef MOZ_CRASHREPORTER
GetCrashID(dumpID);
#endif
// now do something with the crash ID, bug 1038961
nsString id;
// use the parent address to identify it
// We could use any unique-to-the-parent value
id.AppendInt(reinterpret_cast<uint64_t>(this));
id.Append(NS_LITERAL_STRING(" "));
AppendUTF8toUTF16(mDisplayName, id);
id.Append(NS_LITERAL_STRING(" "));
id.Append(dumpID);
// NotifyObservers is mainthread-only
NS_DispatchToMainThread(WrapRunnableNM(&GMPNotifyObservers, id),
NS_DISPATCH_NORMAL);
}
#endif
// warn us off trying to close again
mState = GMPStateClosing;
CloseActive();

View File

@ -42,6 +42,7 @@ public:
virtual nsresult Reset() MOZ_OVERRIDE;
virtual nsresult Drain() MOZ_OVERRIDE;
virtual nsresult DecodingComplete() MOZ_OVERRIDE;
virtual const uint64_t ParentID() MOZ_OVERRIDE { return reinterpret_cast<uint64_t>(mPlugin.get()); }
// GMPSharedMemManager
virtual void CheckThread();

View File

@ -28,6 +28,7 @@ public:
virtual nsresult Reset() = 0;
virtual nsresult Drain() = 0;
virtual nsresult DecodingComplete() = 0;
virtual const uint64_t ParentID() = 0;
};
#endif

View File

@ -43,6 +43,7 @@ public:
virtual GMPErr SetRates(uint32_t aNewBitRate, uint32_t aFrameRate) MOZ_OVERRIDE;
virtual GMPErr SetPeriodicKeyFrames(bool aEnable) MOZ_OVERRIDE;
virtual void EncodingComplete() MOZ_OVERRIDE;
virtual const uint64_t ParentID() MOZ_OVERRIDE { return reinterpret_cast<uint64_t>(mPlugin.get()); }
// GMPSharedMemManager
virtual void CheckThread();

View File

@ -35,6 +35,7 @@ public:
virtual GMPErr SetRates(uint32_t aNewBitRate, uint32_t aFrameRate) = 0;
virtual GMPErr SetPeriodicKeyFrames(bool aEnable) = 0;
virtual void EncodingComplete() = 0;
virtual const uint64_t ParentID() = 0;
};
#endif // GMPVideoEncoderProxy_h_

View File

@ -381,7 +381,8 @@ skip-if = buildapp == 'b2g' || toolkit == 'android' # mimetype check, bug 969289
[test_mediarecorder_unsupported_src.html]
[test_mediarecorder_record_getdata_afterstart.html]
[test_mediatrack_consuming_mediaresource.html]
[test_mediatrack_events_and_consuming_ms.html]
[test_mediatrack_consuming_mediastream.html]
[test_mediatrack_events.html]
[test_mediatrack_replay_from_end.html]
[test_metadata.html]
[test_mixed_principals.html]
@ -398,7 +399,6 @@ skip-if = true # bug 567954 and intermittent leaks
# Seamonkey: Bug 598252, B2G: Bug 982100, Android: Bug 758476, bug 981086
skip-if = appname == "seamonkey" || toolkit == 'gonk' || toolkit == 'android'
[test_playback.html]
skip-if = buildapp == 'b2g' || toolkit == 'android' # Disabled on Android & B2G due to bug 668973
[test_playback_errors.html]
[test_playback_rate.html]
[test_playback_rate_playpause.html]

View File

@ -23,7 +23,7 @@ function cloneLoaded(event) {
}
e.removeEventListener("loadeddata", cloneLoaded, false);
removeNodeAndSource(e);
manager.finished(e.token);
}
@ -39,6 +39,17 @@ function tryClone(event) {
}
clone.addEventListener("loadeddata", cloneLoaded, false);
clone.onloadstart = function(evt) {
info("cloned " + evt.target.token + " start loading.");
evt.target.onloadstart = null;
// Since there is only one H264 decoder instance, we have to delete the
// decoder of the original element for the cloned element to load. However,
// we can't delete the decoder too early otherwise cloning decoder will
// fail to kick in. We wait for 'loadstart' event of the cloned element to
// know when the decoder is already cloned and we can delete the decoder of
// the original element.
removeNodeAndSource(e);
}
e.removeEventListener("loadeddata", tryClone, false);
}

View File

@ -0,0 +1,157 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test track interfaces when consuming a MediaStream from gUM</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript" src="manifest.js"></script>
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
function startTest() {
navigator.mozGetUserMedia({audio:true, video:true, fake:true},
function(stream) {
var element = document.createElement("video");
var audioOnchange = 0;
var audioOnaddtrack = 0;
var audioOnremovetrack = 0;
var videoOnchange = 0;
var videoOnaddtrack = 0;
var videoOnremovetrack = 0;
var isPlaying = false;
element.audioTracks.onaddtrack = function(e) {
audioOnaddtrack++;
}
element.audioTracks.onremovetrack = function(e) {
audioOnremovetrack++;
}
element.audioTracks.onchange = function(e) {
audioOnchange++;
}
element.videoTracks.onaddtrack = function(e) {
videoOnaddtrack++;
}
element.videoTracks.onremovetrack = function(e) {
videoOnremovetrack++;
}
element.videoTracks.onchange = function(e) {
videoOnchange++;
}
function checkTrackRemoved() {
if (isPlaying) {
is(audioOnremovetrack, 1, 'Calls of onremovetrack on audioTracks should be 1.');
is(element.audioTracks.length, 0, 'The length of audioTracks should be 0.');
is(videoOnremovetrack, 1, 'Calls of onremovetrack on videoTracks should be 1.');
is(element.videoTracks.length, 0, 'The length of videoTracks should be 0.');
}
}
function onended() {
ok(true, 'Event ended is expected to be fired on element.');
checkTrackRemoved();
element.onended = null;
element.onplaying = null;
element.onpause = null;
SimpleTest.finish();
}
function checkTrackAdded() {
isPlaying = true;
is(audioOnaddtrack, 1, 'Calls of onaddtrack on audioTracks should be 1.');
is(element.audioTracks.length, 1, 'The length of audioTracks should be 1.');
ok(element.audioTracks[0].enabled, 'Audio track should be enabled as default.');
is(videoOnaddtrack, 1, 'Calls of onaddtrack on videoTracks should be 1.');
is(element.videoTracks.length, 1, 'The length of videoTracks should be 1.');
is(element.videoTracks.selectedIndex, 0,
'The first video track is set selected as default.');
}
function setTrackEnabled(enabled) {
element.audioTracks[0].enabled = enabled;
element.videoTracks[0].selected = enabled;
}
function checkTrackChanged(calls, enabled) {
is(audioOnchange, calls, 'Calls of onchange on audioTracks should be '+calls);
is(element.audioTracks[0].enabled, enabled,
'Enabled value of the audio track should be ' +enabled);
is(videoOnchange, calls, 'Calls of onchange on videoTracks should be '+calls);
is(element.videoTracks[0].selected, enabled,
'Selected value of the video track should be ' +enabled);
var index = enabled ? 0 : -1;
is(element.videoTracks.selectedIndex, index,
'SelectedIndex of video tracks should be ' +index);
}
function onpause() {
element.onpause = null;
if (element.ended) {
return;
}
if (steps == 1) {
setTrackEnabled(false);
element.onplaying = onplaying;
element.play();
steps++;
} else if (steps == 2) {
setTrackEnabled(true);
element.onplaying = onplaying;
element.play();
steps++;
}
}
function onplaying() {
element.onplaying = null;
if (element.ended) {
return;
}
if (steps == 1) {
element.onpause = onpause;
element.pause();
checkTrackAdded();
} else if (steps == 2) {
element.onpause = onpause;
element.pause();
checkTrackChanged(1, false);
} else if (steps == 3) {
checkTrackChanged(2, true);
stream.stop();
}
}
var steps = 0;
element.mozSrcObject = stream;
element.onplaying = onplaying;
element.onended = onended;
element.play();
steps++;
},
function(err) {
ok(false, 'Unexpected error fired with: ' + err);
SimpleTest.finish();
}
);
}
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv(
{
"set": [
["media.track.enabled", true]
]
}, startTest);
</script>
</pre>
</body>
</html>

View File

@ -0,0 +1,125 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test events of media track interfaces</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript" src="manifest.js"></script>
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
function startTest() {
navigator.mozGetUserMedia({audio:true, video:true, fake:true},
function(stream) {
var element = document.createElement("video");
isnot(element.audioTracks, undefined,
'HTMLMediaElement::AudioTracks() property should be available.');
isnot(element.videoTracks, undefined,
'HTMLMediaElement::VideoTracks() property should be available.');
function verifyEvent(e, type) {
is(e.type, type, "Event type should be " + type);
ok(e.isTrusted, "Event should be trusted.");
ok(!e.bubbles, "Event shouldn't bubble.");
ok(!e.cancelable, "Event shouldn't be cancelable.");
}
element.audioTracks.onaddtrack = function(e) {
ok(e instanceof TrackEvent, "Event fired from onaddtrack should be a TrackEvent");
ok(true, 'onaddtrack is expected to be called from audioTracks.');
verifyEvent(e, "addtrack");
}
element.audioTracks.onremovetrack = function(e) {
ok(e instanceof TrackEvent, "Event fired from onremovetrack should be a TrackEvent");
ok(true, 'onremovetrack is expected to be called from audioTracks.');
verifyEvent(e, "removetrack");
}
element.audioTracks.onchange = function(e) {
ok(e instanceof window.Event, "Event fired from onchange should be a simple event.");
ok(true, 'onchange is expected to be called from audioTracks.');
verifyEvent(e, "change");
}
element.videoTracks.onaddtrack = function(e) {
ok(e instanceof TrackEvent, "Event fired from onaddtrack should be a TrackEvent");
ok(true, 'onaddtrack is expected to be called from videoTracks.');
verifyEvent(e, "addtrack");
}
element.videoTracks.onremovetrack = function(e) {
ok(e instanceof TrackEvent, "Event fired from onremovetrack should be a TrackEvent");
ok(true, 'onremovetrack is expected to be called from videoTracks.');
verifyEvent(e, "removetrack");
}
element.videoTracks.onchange = function(e) {
ok(e instanceof window.Event, "Event fired from onchange should be a simple event.");
ok(true, 'onchange is expected to be called from videoTracks.');
verifyEvent(e, "change");
}
function onended() {
ok(true, 'Event ended is expected to be fired on element.');
element.onended = null;
element.onplaying = null;
element.onpause = null;
SimpleTest.finish();
}
function onpause() {
element.onpause = null;
if (element.ended) {
return;
}
if (steps == 1) {
element.audioTracks[0].enabled = false;
element.videoTracks[0].selected = false;
element.onplaying = onplaying;
element.play();
steps++;
}
}
function onplaying() {
element.onplaying = null;
if (element.ended) {
return;
}
if (steps == 1) {
element.onpause = onpause;
element.pause();
} else if (steps == 2) {
stream.stop();
}
}
var steps = 0;
element.mozSrcObject = stream;
element.onplaying = onplaying;
element.onended = onended;
element.play();
steps++;
},
function(err) {
ok(false, 'Unexpected error fired with: ' + err);
SimpleTest.finish();
}
);
}
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv(
{
"set": [
["media.track.enabled", true]
]
}, startTest);
</script>
</pre>
</body>
</html>

View File

@ -1,189 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test track interfaces when consuming a MediaStream from gUM</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript" src="manifest.js"></script>
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
function startTest() {
navigator.mozGetUserMedia({audio:true, video:true, fake:true},
function(stream) {
var audioStreamTracks = stream.getAudioTracks();
var videoStreamTracks = stream.getVideoTracks();
var audioOnchange = 0;
var audioOnaddtrack = 0;
var audioOnremovetrack = 0;
var videoOnchange = 0;
var videoOnaddtrack = 0;
var videoOnremovetrack = 0;
var element = document.createElement("video");
isnot(element.audioTracks, undefined, "HTMLMediaElement::AudioTracks() property should be available.");
isnot(element.videoTracks, undefined, "HTMLMediaElement::VideoTracks() property should be available.");
function verify_event(e, type) {
is(e.type, type, "Event type should be " + type);
ok(e.isTrusted, "Event should be trusted.");
ok(!e.bubbles, "Event shouldn't bubble.");
ok(!e.cancelable, "Event shouldn't be cancelable.");
}
function setAudioEnabled(enabled, index) {
return new Promise(function(resolve, reject) {
element.audioTracks[index].enabled = enabled;
element.audioTracks.onchange = function(e) {
ok(e instanceof window.Event, "Event fired from onchange should be a simple event.");
ok(true, 'onchange is expected to be called from audioTracks.');
verify_event(e, "change");
audioOnchange++;
resolve();
}
});
}
function setVideoSelected(selected, index) {
return new Promise(function(resolve, reject) {
element.videoTracks[index].selected = selected;
element.videoTracks.onchange = function(e) {
ok(e instanceof window.Event, "Event fired from onchange should be a simple event.");
ok(true, 'onchange is expected to be called from videoTracks.');
verify_event(e, "change");
var noVideoSelected = true;
for (var i=0; i < element.videoTracks.length; ++i) {
var track = element.videoTracks[i];
if (track.selected == true) {
noVideoSelected = false;
break;
}
}
if (selected) {
is(element.videoTracks.selectedIndex, index,
'SelectedIndex shuld be '+index+' if video track is set selected.');
} else {
if (noVideoSelected) {
is(element.videoTracks.selectedIndex, -1,
'SelectedIndex shuld be -1 if no video track is set selected.');
} else {
reject();
}
}
videoOnchange++;
resolve();
}
});
}
element.audioTracks.onaddtrack = function(e) {
ok(e instanceof TrackEvent, "Event fired from onaddtrack should be a TrackEvent");
ok(true, 'onaddtrack is expected to be called from audioTracks.');
verify_event(e, "addtrack");
audioOnaddtrack++;
}
element.audioTracks.onremovetrack = function(e) {
ok(e instanceof TrackEvent, "Event fired from onremovetrack should be a TrackEvent");
ok(true, 'onremovetrack is expected to be called from audioTracks.');
verify_event(e, "removetrack");
audioOnremovetrack++;
}
element.videoTracks.onaddtrack = function(e) {
ok(e instanceof TrackEvent, "Event fired from onaddtrack should be a TrackEvent");
ok(true, 'onaddtrack is expected to be called from videoTracks.');
verify_event(e, "addtrack");
videoOnaddtrack++;
}
element.videoTracks.onremovetrack = function(e) {
ok(e instanceof TrackEvent, "Event fired from onremovetrack should be a TrackEvent");
ok(true, 'onremovetrack is expected to be called from videoTracks.');
verify_event(e, "removetrack");
videoOnremovetrack++;
}
element.onended = function() {
is(audioOnchange, 2, 'change event on audioTracks should fired twice.');
is(videoOnchange, 2, 'change event on videoTracks should fired twice.');
is(audioOnremovetrack, audioStreamTracks.length,
'Calls of onremovetrack from audioTracks should match the numbers of AudioStreamTrack.');
is(videoOnremovetrack, videoStreamTracks.length,
'Calls of onremovetrack from videoTracks should match the numbers of VideoStreamTrack.');
SimpleTest.finish();
}
var promise = new Promise(function(resolve, reject) {
element.mozSrcObject = stream;
element.play();
element.onloadedmetadata = function() {
is(audioOnaddtrack, audioStreamTracks.length,
'Calls of onaddtrack from audioTracks should match the numbers of AudioStreamTrack.');
is(videoOnaddtrack, videoStreamTracks.length,
'Calls of onaddtrack from videoTracks should match the numbers of VideoStreamTrack.');
is(element.audioTracks.length, audioStreamTracks.length,
'Length of audioTracks should be the same as the length of AudioStreamTrack.');
is(element.videoTracks.length, videoStreamTracks.length,
'Length of videoTracks should be the same as the length of VideoStreamTrack.');
for (var i=0; i < audioStreamTracks.length; ++i) {
var track = element.audioTracks.getTrackById(audioStreamTracks[i].id);
isnot(track, null, 'Successfully get '+ track.id + ' from audioTracks.');
}
for (var i=0; i < videoStreamTracks.length; ++i) {
var track = element.videoTracks.getTrackById(videoStreamTracks[i].id);
isnot(track, null, 'Successfully get '+ track.id + ' from videoTracks.');
}
is(element.videoTracks.selectedIndex, 0,
'The first video track is set selected as default.');
resolve();
}
});
promise.then(function() {
var p1 = setAudioEnabled(false, 0);
var p2 = setVideoSelected(false, 0);
return Promise.all([p1, p2]);
}).catch(function(err) {
ok(false, 'Something went wrong in onchange callback.');
}).then(function() {
var p3 = setAudioEnabled(true, 0);
var p4 = setVideoSelected(true, 0);
return Promise.all([p3, p4]);
}).catch(function(err) {
ok(false, 'Something went wrong in onchange callback.');
}).then(function() {
stream.stop();
});
},
function(err) {
ok(false, 'Unexpected error fired with: ' + err);
SimpleTest.finish();
}
);
}
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv(
{
"set": [
["media.track.enabled", true]
]
}, startTest);
</script>
</pre>
</body>
</html>

View File

@ -10,13 +10,37 @@
<pre id="test">
<script class="testbody" type="text/javascript">
//longer timeout for sometimes B2G emulator runs very slowly
if (SpecialPowers.Services.appinfo.name == "B2G") {
SimpleTest.requestLongerTimeout(3);
}
var manager = new MediaTestManager;
function localCheckMetadata(msg, e, test) {
if (test.width) {
is(e.videoWidth, test.width, msg + " video width");
}
if (test.height) {
is(e.videoHeight, test.height, msg + " video height");
}
if (test.duration) {
// see bug 1039901 for skipping mp3 duration test on B2G
if (SpecialPowers.Services.appinfo.name == "B2G" && /mp3$/.test(test.name)) {
todo(false, "Fix mp3 duration bug on B2G");
return;
}
ok(Math.abs(e.duration - test.duration) < 0.1,
msg + " duration (" + e.duration + ") should be around " + test.duration);
}
}
function startTest(test, token) {
var v = document.createElement('video');
v.preload = "metadata";
v.token = token;
manager.started(token);
var checkMetadata = localCheckMetadata;
v.src = test.name;
v.name = test.name;

View File

@ -34,6 +34,16 @@ which makes Windows Media Foundation unavailable.
#include <wmcodecdsp.h>
#include <codecapi.h>
// The Windows headers helpfully declare min and max macros, which don't
// compile in the prescence of std::min and std::max and unified builds.
// So undef them here.
#ifdef min
#undef min
#endif
#ifdef max
#undef max
#endif
// Some SDK versions don't define the AAC decoder CLSID.
#ifndef CLSID_CMSAACDecMFT
extern "C" const CLSID CLSID_CMSAACDecMFT;

View File

@ -168,10 +168,11 @@ public:
JSContext* cx() const {
MOZ_ASSERT(mCx, "Must call Init before using an AutoJSAPI");
MOZ_ASSERT_IF(NS_IsMainThread(), CxPusherIsStackTop());
return mCx;
}
bool CxPusherIsStackTop() { return mCxPusher.ref().IsStackTop(); }
bool CxPusherIsStackTop() const { return mCxPusher.ref().IsStackTop(); }
protected:
// Protected constructor, allowing subclasses to specify a particular cx to

View File

@ -936,8 +936,12 @@ nsJSContext::InitContext()
nsresult
nsJSContext::SetProperty(JS::Handle<JSObject*> aTarget, const char* aPropName, nsISupports* aArgs)
{
nsCxPusher pusher;
pusher.Push(mContext);
AutoJSAPI jsapi;
if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReporting(GetGlobalObject()))) {
return NS_ERROR_FAILURE;
}
MOZ_ASSERT(jsapi.cx() == mContext,
"AutoJSAPI should have found our own JSContext*");
JS::AutoValueVector args(mContext);

View File

@ -12,17 +12,18 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=923010
/** Test for Bug 923010 **/
try {
var conn = new mozRTCPeerConnection();
var candidate = new mozRTCIceCandidate({candidate: null });
try {
conn.createAnswer(function() {
ok(false, "The call to createAnswer succeeded when it should have thrown");
conn.addIceCandidate(candidate, function() {
ok(false, "The call to addIceCandidate succeeded when it should have thrown");
}, function() {
ok(false, "The call to createAnswer failed when it should have thrown");
}, { "mandatory": { "BOGUS": 5 } } )
ok(false, "That call to createAnswer should have thrown");
ok(false, "The call to addIceCandidate failed when it should have thrown");
})
ok(false, "That call to addIceCandidate should have thrown");
} catch (e) {
is(e.lineNumber, 16, "Exception should have been on line 16");
is(e.lineNumber, 17, "Exception should have been on line 17");
is(e.message,
"createAnswer passed invalid constraints - unknown mandatory constraint: BOGUS",
"Invalid candidate passed to addIceCandidate!",
"Should have the exception we expect");
}
} catch (e) {

View File

@ -457,7 +457,10 @@ BluetoothAdapter::StopDiscovery(ErrorResult& aRv)
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsRefPtr<Promise> promise = new Promise(global);
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
if (aRv.Failed()) {
return nullptr;
}
/**
* Ensure
@ -819,11 +822,7 @@ BluetoothAdapter::EnableDisable(bool aEnable, ErrorResult& aRv)
}
// Notify applications of adapter state change to Enabling/Disabling
nsTArray<nsString> types;
BT_APPEND_ENUM_STRING(types,
BluetoothAdapterAttribute,
BluetoothAdapterAttribute::State);
DispatchAttributeEvent(types);
HandleAdapterStateChanged();
// Wrap runnable to handle result
nsRefPtr<BluetoothReplyRunnable> result =
@ -832,8 +831,11 @@ BluetoothAdapter::EnableDisable(bool aEnable, ErrorResult& aRv)
methodName);
if(NS_FAILED(bs->EnableDisable(aEnable, result))) {
// Restore mState and notify applications of adapter state change
mState = aEnable ? BluetoothAdapterState::Disabled
: BluetoothAdapterState::Enabled;
HandleAdapterStateChanged();
promise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);
}
@ -894,6 +896,16 @@ BluetoothAdapter::IsAdapterAttributeChanged(BluetoothAdapterAttribute aType,
}
}
void
BluetoothAdapter::HandleAdapterStateChanged()
{
nsTArray<nsString> types;
BT_APPEND_ENUM_STRING(types,
BluetoothAdapterAttribute,
BluetoothAdapterAttribute::State);
DispatchAttributeEvent(types);
}
void
BluetoothAdapter::HandlePropertyChanged(const BluetoothValue& aValue)
{

View File

@ -193,6 +193,7 @@ private:
bool IsAdapterAttributeChanged(BluetoothAdapterAttribute aType,
const BluetoothValue& aValue);
void HandleAdapterStateChanged();
void HandlePropertyChanged(const BluetoothValue& aValue);
void DispatchAttributeEvent(const nsTArray<nsString>& aTypes);
BluetoothAdapterAttribute

View File

@ -5,9 +5,10 @@
#include "domstubs.idl"
interface nsIDocument;
interface nsIURI;
[uuid(6117cdf1-cb10-42a3-9901-4f1bab7ffa4d)]
[uuid(6e1382f4-3cbc-435f-8ce0-70175f6eb400)]
interface nsIServiceWorkerManager : nsISupports
{
// Returns a Promise
@ -20,6 +21,21 @@ interface nsIServiceWorkerManager : nsISupports
[noscript] void AddContainerEventListener(in nsIURI aPageURI, in nsIDOMEventTarget aTarget);
[noscript] void RemoveContainerEventListener(in nsIURI aPageURI, in nsIDOMEventTarget aTarget);
/**
* Call this to request that document `aDoc` be controlled by a ServiceWorker
* if a registration exists for it's scope.
*
* This MUST only be called once per document!
*/
[notxpcom,nostdcall] void MaybeStartControlling(in nsIDocument aDoc);
/**
* Documents that have called MaybeStartControlling() should call this when
* they are destroyed. This function may be called multiple times, and is
* idempotent.
*/
[notxpcom,nostdcall] void MaybeStopControlling(in nsIDocument aDoc);
// Testing
DOMString getScopeForUrl(in DOMString path);
};

View File

@ -42,6 +42,7 @@ function GlobalPCList() {
Services.obs.addObserver(this, "profile-change-net-teardown", true);
Services.obs.addObserver(this, "network:offline-about-to-go-offline", true);
Services.obs.addObserver(this, "network:offline-status-changed", true);
Services.obs.addObserver(this, "gmp-plugin-crash", true);
}
GlobalPCList.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
@ -107,6 +108,27 @@ GlobalPCList.prototype = {
}
};
let hasPluginId = function(list, winID, pluginID, name, crashReport) {
if (list.hasOwnProperty(winID)) {
list[winID].forEach(function(pcref) {
let pc = pcref.get();
if (pc) {
if (pc._pc.pluginCrash(pluginID)) {
// Notify DOM window of the crash
let event = new CustomEvent("PluginCrashed",
{ bubbles: false, cancelable: false,
detail: {
pluginName: name,
pluginDumpId: crashReport,
submittedCrashReport: false }
});
pc._win.dispatchEvent(event);
}
}
});
}
};
if (topic == "inner-window-destroyed") {
let winID = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
cleanupWinId(this._list, winID);
@ -134,6 +156,19 @@ GlobalPCList.prototype = {
} else if (data == "online") {
this._networkdown = false;
}
} else if (topic == "gmp-plugin-crash") {
// a plugin crashed; if it's associated with any of our PCs, fire an
// event to the DOM window
let sep = data.indexOf(' ');
let pluginId = data.slice(0, sep);
let rest = data.slice(sep+1);
// This presumes no spaces in the name!
sep = rest.indexOf(' ');
let name = rest.slice(0, sep);
let crashId = rest.slice(sep+1);
for (let winId in this._list) {
hasPluginId(this._list, winId, pluginId, name, crashId);
}
}
},
@ -465,50 +500,6 @@ RTCPeerConnection.prototype = {
}
},
/**
* MediaConstraints look like this:
*
* {
* mandatory: {"OfferToReceiveAudio": true, "OfferToReceiveVideo": true },
* optional: [{"VoiceActivityDetection": true}, {"FooBar": 10}]
* }
*
* WebIDL normalizes the top structure for us, but the mandatory constraints
* member comes in as a raw object so we can detect unknown constraints. We
* compare its members against ones we support, and fail if not found.
*/
_mustValidateConstraints: function(constraints, errorMsg) {
if (constraints.mandatory) {
let supported;
try {
// Passing the raw constraints.mandatory here validates its structure
supported = this._observer.getSupportedConstraints(constraints.mandatory);
} catch (e) {
throw new this._win.DOMError("", errorMsg + " - " + e.message);
}
for (let constraint of Object.keys(constraints.mandatory)) {
if (!(constraint in supported)) {
throw new this._win.DOMError("",
errorMsg + " - unknown mandatory constraint: " + constraint);
}
}
}
if (constraints.optional) {
let len = constraints.optional.length;
for (let i = 0; i < len; i++) {
let constraints_per_entry = 0;
for (let constraint in Object.keys(constraints.optional[i])) {
if (constraints_per_entry) {
throw new this._win.DOMError("", errorMsg +
" - optional constraint must be single key/value pair");
}
constraints_per_entry += 1;
}
}
}
},
// Ideally, this should be of the form _checkState(state),
// where the state is taken from an enumeration containing
// the valid peer connection states defined in the WebRTC
@ -574,26 +565,22 @@ RTCPeerConnection.prototype = {
});
},
createOffer: function(onSuccess, onError, constraints) {
if (!constraints) {
constraints = {};
}
this._mustValidateConstraints(constraints, "createOffer passed invalid constraints");
createOffer: function(onSuccess, onError, options) {
options = options || {};
this._queueOrRun({
func: this._createOffer,
args: [onSuccess, onError, constraints],
args: [onSuccess, onError, options],
wait: true
});
},
_createOffer: function(onSuccess, onError, constraints) {
_createOffer: function(onSuccess, onError, options) {
this._onCreateOfferSuccess = onSuccess;
this._onCreateOfferFailure = onError;
this._impl.createOffer(constraints);
this._impl.createOffer(options);
},
_createAnswer: function(onSuccess, onError, constraints, provisional) {
_createAnswer: function(onSuccess, onError) {
this._onCreateAnswerSuccess = onSuccess;
this._onCreateAnswerFailure = onError;
@ -610,26 +597,13 @@ RTCPeerConnection.prototype = {
"No outstanding offer");
return;
}
// TODO: Implement provisional answer.
this._impl.createAnswer(constraints);
this._impl.createAnswer();
},
createAnswer: function(onSuccess, onError, constraints, provisional) {
if (!constraints) {
constraints = {};
}
this._mustValidateConstraints(constraints, "createAnswer passed invalid constraints");
if (!provisional) {
provisional = false;
}
createAnswer: function(onSuccess, onError) {
this._queueOrRun({
func: this._createAnswer,
args: [onSuccess, onError, constraints, provisional],
args: [onSuccess, onError],
wait: true
});
},
@ -794,7 +768,7 @@ RTCPeerConnection.prototype = {
gotAssertion);
},
updateIce: function(config, constraints) {
updateIce: function(config) {
throw new this._win.DOMError("", "updateIce not yet implemented");
},
@ -815,22 +789,17 @@ RTCPeerConnection.prototype = {
cand.sdpMLineIndex + 1);
},
addStream: function(stream, constraints) {
if (!constraints) {
constraints = {};
}
this._mustValidateConstraints(constraints,
"addStream passed invalid constraints");
addStream: function(stream) {
if (stream.currentTime === undefined) {
throw new this._win.DOMError("", "Invalid stream passed to addStream!");
}
this._queueOrRun({ func: this._addStream,
args: [stream, constraints],
args: [stream],
wait: false });
},
_addStream: function(stream, constraints) {
this._impl.addStream(stream, constraints);
_addStream: function(stream) {
this._impl.addStream(stream);
},
removeStream: function(stream) {
@ -1293,11 +1262,7 @@ PeerConnectionObserver.prototype = {
notifyDataChannel: function(channel) {
this.dispatchEvent(new this._dompc._win.RTCDataChannelEvent("datachannel",
{ channel: channel }));
},
getSupportedConstraints: function(dict) {
return dict;
},
}
};
function RTCPeerConnectionStatic() {

View File

@ -759,10 +759,10 @@ function PCT_setMediaConstraints(constraintsLocal, constraintsRemote) {
*
* @param {object} constraints the media constraints to use on createOffer
*/
PeerConnectionTest.prototype.setOfferConstraints =
function PCT_setOfferConstraints(constraints) {
PeerConnectionTest.prototype.setOfferOptions =
function PCT_setOfferOptions(options) {
if (this.pcLocal)
this.pcLocal.offerConstraints = constraints;
this.pcLocal.offerOptions = options;
};
/**
@ -1362,7 +1362,7 @@ function PeerConnectionWrapper(label, configuration, h264) {
this.whenCreated = Date.now();
this.constraints = [ ];
this.offerConstraints = {};
this.offerOptions = {};
this.streams = [ ];
this.mediaCheckers = [ ];
@ -1637,7 +1637,7 @@ PeerConnectionWrapper.prototype = {
offer.sdp = removeVP8(offer.sdp);
}
onSuccess(offer);
}, generateErrorCallback(), this.offerConstraints);
}, generateErrorCallback(), this.offerOptions);
},
/**

View File

@ -18,7 +18,7 @@
var pc = new mozRTCPeerConnection();
// necessary to circumvent bug 864109
var options = { mandatory: { OfferToReceiveAudio: true} };
var options = { offerToReceiveAudio: true };
pc.createOffer(function (offer) {
ok(!offer.sdp.contains("m=application"),

View File

@ -41,7 +41,7 @@
});
}, function (err) {
croak("createOffer failed: " + err);
}, { mandatory: { OfferToReceiveAudio: true} });
}, { offerToReceiveAudio: true });
});
</script>
</pre>

View File

@ -32,24 +32,15 @@
ok(!exception, "createOffer(step1, failed, {}) succeeds");
exception = null;
try {
pconnect.createOffer(step1, failed, { mandatory: { FooBar: true } });
pconnect.updateIce();
} catch (e) {
ok(e.message.indexOf("FooBar") > 0, "createOffer has readable exceptions");
ok(e.message.indexOf("updateIce") >= 0, "PeerConnection.js has readable exceptions");
exception = e;
}
ok(exception, "createOffer(step1, failed, { mandatory: { FooBar: true } }) throws");
ok(exception, "updateIce not yet implemented and throws");
exception = null;
try { pconnects.createOffer(step1, failed, { optional: [] }); } catch (e) { exception = e; }
ok(!exception, "createOffer(step1, failed, { optional: [] }) succeeds");
exception = null;
try { pconnect.createOffer(step1, failed, { optional: [1] }); } catch (e) { exception = e; }
ok(exception, "createOffer(step1, failed, { optional: [1] }) throws");
exception = null;
try { pconnect.createOffer(step1, failed, { optional: [{ OfferToReceiveVideo: false, OfferToReceiveAudio: true, }] }); } catch (e) { exception = e; }
ok(exception, "createOffer(step1, failed, { optional: [{ OfferToReceiveVideo: false, OfferToReceiveAudio: true, }] }) throws");
exception = null;
try { pconnects.createOffer(step1, failed, { mandatory: { OfferToReceiveVideo: false, OfferToReceiveAudio: true, MozDontOfferDataChannel: true}, optional: [{ VoiceActivityDetection: true }, { FooBar: "42" }] }); } catch (e) { exception = e; }
ok(!exception, "createOffer(step1, failed, { mandatory: { OfferToReceiveVideo: false, OfferToReceiveAudio: true, MozDontOfferDataChannel: true}, optional: [{ VoiceActivityDetection: true }, { FooBar: \"42\" }] }) succeeds");
try { pconnects.createOffer(step1, failed, { offerToReceiveVideo: false, offerToReceiveAudio: true, MozDontOfferDataChannel: true }); } catch (e) { exception = e; }
ok(!exception, "createOffer(step1, failed, { offerToReceiveVideo: false, offerToReceiveAudio: true, MozDontOfferDataChannel: true }) succeeds");
pconnect.close();
pconnects.close();
pconnect = null;

View File

@ -1,4 +1,4 @@
<!DOCTYPE HTML>
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
@ -18,7 +18,7 @@
runNetworkTest(function() {
var test = new PeerConnectionTest();
test.setOfferConstraints({ mandatory: { OfferToReceiveAudio: true } });
test.setOfferOptions({ offerToReceiveAudio: true });
test.run();
});
</script>

View File

@ -1,4 +1,4 @@
<!DOCTYPE HTML>
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
@ -18,7 +18,7 @@
runNetworkTest(function() {
var test = new PeerConnectionTest();
test.setOfferConstraints({ mandatory: { OfferToReceiveVideo: true } });
test.setOfferOptions({ offerToReceiveVideo: true });
test.run();
});
</script>

View File

@ -1,4 +1,4 @@
<!DOCTYPE HTML>
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
@ -18,10 +18,10 @@
runNetworkTest(function() {
var test = new PeerConnectionTest();
test.setOfferConstraints({ mandatory: {
OfferToReceiveVideo: true,
OfferToReceiveAudio: true
}});
test.setOfferOptions({
offerToReceiveVideo: true,
offerToReceiveAudio: true
});
test.run();
});
</script>

View File

@ -5,6 +5,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
XPIDL_SOURCES += [
'nsICellInfo.idl',
'nsIMobileCellInfo.idl',
'nsIMobileConnectionInfo.idl',
'nsIMobileConnectionProvider.idl',

View File

@ -0,0 +1,256 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
[scriptable, uuid(1aed4c36-979e-4d20-9fa0-55139da8301e)]
interface nsICellInfoListCallback : nsISupports
{
/**
* result is an array of nsICellInfo.
*/
void notifyGetCellInfoList(in jsval result);
/**
* Callback function with error message.
*/
void notifyGetCellInfoListFailed(in DOMString error);
};
[scriptable, uuid(86667898-c9ab-44ee-8a9a-026916b3183e)]
interface nsICellInfo : nsISupports
{
const long CELL_INFO_TYPE_GSM = 1;
const long CELL_INFO_TYPE_CDMA = 2;
const long CELL_INFO_TYPE_LTE = 3;
const long CELL_INFO_TYPE_WCDMA = 4;
const long TIMESTAMP_TYPE_UNKNOWN = 0;
const long TIMESTAMP_TYPE_ANTENNA = 1;
const long TIMESTAMP_TYPE_MODEM = 2;
const long TIMESTAMP_TYPE_OEM_RIL = 3;
const long TIMESTAMP_TYPE_JAVA_RIL = 4;
/**
* Network type. One of the CELL_INFO_TYPE_* constants.
*/
readonly attribute long type;
/*
* Registration state of this cell.
*/
readonly attribute boolean registered;
/**
* Time stamp type. One of the TIMESTAMP_TYPE_* constants.
*/
readonly attribute long timestampType;
/**
* Time in nanoseconds since boot.
*/
readonly attribute long long timestamp;
};
[scriptable, uuid(6345967c-61fc-45a1-8362-39e9261df052)]
interface nsIGsmCellInfo : nsICellInfo
{
/**
* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown.
*/
readonly attribute long mcc;
/**
* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown.
*/
readonly attribute long mnc;
/**
* 16-bit Location Area Code, 0..65535, INT_MAX if unknown.
*/
readonly attribute long lac;
/**
* 16-bit GSM Cell Identity described in TS 27.007, 0..65535, INT_MAX if unknown.
*/
readonly attribute long cid;
/**
* Valid values are 0-31 as defined in TS 27.007 8.5, 99 if unknown.
*/
readonly attribute long signalStrength;
/**
* Bit error rate 0-7 as defined in TS 27.007 8.5, 99 if unknown.
*/
readonly attribute long bitErrorRate;
};
[scriptable, uuid(19693f98-943d-45e7-a3e8-25373228ce6b)]
interface nsIWcdmaCellInfo : nsICellInfo
{
/**
* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown.
*/
readonly attribute long mcc;
/**
* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown.
*/
readonly attribute long mnc;
/**
* 16-bit Location Area Code, 0..65535, INT_MAX if unknown.
*/
readonly attribute long lac;
/**
* 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455,
* INT_MAX if unknown.
*/
readonly attribute long cid;
/**
* 9-bit UMTS Primary Scrambling Code described in TS 25.331, 0..511,
* INT_MAX if unknown.
*/
readonly attribute long psc;
/**
* Valid values are 0-31 as defined in TS 27.007 8.5, 99 if unknown.
*/
readonly attribute long signalStrength;
/**
* Bit error rate 0-7 as defined in TS 27.007 8.5, 99 if unknown.
*/
readonly attribute long bitErrorRate;
};
[scriptable, uuid(76b4a35d-7e45-42bc-a2e0-bc07a6434db3)]
interface nsICdmaCellInfo : nsICellInfo
{
/**
* Network Id, 0..65535, INT_MAX if unknown.
*/
readonly attribute long networkId;
/**
* CDMA System Id, 0..32767, INT_MAX if unknown.
*/
readonly attribute long systemId;
/**
* Base Station Id, 0..65535, INT_MAX if unknown.
*/
readonly attribute long baseStationId;
/**
* Longitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0.
* It is represented in units of 0.25 seconds and ranges from -2592000 to
* 2592000, INT_MAX if unknown.
*/
readonly attribute long longitude;
/**
* Latitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0.
* It is represented in units of 0.25 seconds and ranges from -1296000 to
* 1296000, INT_MAX if unknown.
*/
readonly attribute long latitude;
/**
* Valid values are positive integers, INT_MAX if unknown. This value is the
* actual RSSI value multiplied by -1.
*/
readonly attribute long cdmaDbm;
/**
* Valid values are positive integers, INT_MAX if unknown. This value is the
* actual Ec/Io multiplied by -10. -1 if unknown.
*/
readonly attribute long cdmaEcio;
/**
* Valid values are positive integers, INT_MAX if unknown. This value is the
* actual Evdo RSSI value multiplied by -1.
*/
readonly attribute long evdoDbm;
/**
* Valid values are positive integers, INT_MAX if unknown. This value is the
* actual Evdo Ec/Io multiplied by -10.
*/
readonly attribute long evdoEcio;
/**
* Valid values are 0-8, INT_MAX if unknown. 8 is the highest signal to noise
* ratio.
*/
readonly attribute long evdoSnr;
};
[scriptable, uuid(122937d9-1ee5-45e0-a360-5959d578bc31)]
interface nsILteCellInfo : nsICellInfo
{
/**
* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown.
*/
readonly attribute long mcc;
/**
* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown.
*/
readonly attribute long mnc;
/**
* 28-bit Cell Identity, 0..268435455, INT_MAX if unknown.
*/
readonly attribute long cid;
/**
* Physical cell id, 0..503, INT_MAX if unknown.
*/
readonly attribute long pcid;
/**
* 16-bit tracking area code, 0..65535, INT_MAX if unknown.
*/
readonly attribute long tac;
/**
* Valid values are 0-31 as defined in TS 27.007 8.5, 99 if unknown.
*/
readonly attribute long signalStrength;
/**
* The current Reference Signal Receive Power in dBm multipled by -1.
* Range: 44 to 140 dBm, INT_MAX if unknown.
*/
readonly attribute long rsrp;
/**
* The current Reference Signal Receive Quality in dB multiplied by -1.
* Range: 3 to 20 dB, INT_MAX if unknown.
*/
readonly attribute long rsrq;
/**
* The current reference signal signal-to-noise ratio in 0.1 dB units.
* Range: -200 to +300 (-200 = -20.0 dB, +300 = 30dB), INT_MAX if unknown.
*/
readonly attribute long rssnr;
/**
* The current Channel Quality Indicator. Range: 0 to 15, INT_MAX if unknown.
*/
readonly attribute long cqi;
/**
* Timing advance in micro seconds for a one way trip from cell to device.
* Approximate distance can be calculated using 300m/us * timingAdvance.
* Range: 0 to 0x7FFFFFFE, INT_MAX if unknown.
*/
readonly attribute long timingAdvance;
};

View File

@ -27,6 +27,7 @@
#include "nsWrapperCacheInlines.h"
#include "js/HashTable.h"
#include "mozilla/HashFunctions.h"
#include "mozilla/dom/ScriptSettings.h"
#define NPRUNTIME_JSCLASS_NAME "NPObject JS wrapper class"
@ -291,8 +292,8 @@ namespace mozilla {
namespace plugins {
namespace parent {
JSContext *
GetJSContext(NPP npp)
static nsIGlobalObject*
GetGlobalObject(NPP npp)
{
NS_ENSURE_TRUE(npp, nullptr);
@ -306,8 +307,13 @@ GetJSContext(NPP npp)
owner->GetDocument(getter_AddRefs(doc));
NS_ENSURE_TRUE(doc, nullptr);
nsCOMPtr<nsISupports> documentContainer = doc->GetContainer();
nsCOMPtr<nsIScriptGlobalObject> sgo(do_GetInterface(documentContainer));
return doc->GetScopeObject();
}
JSContext *
GetJSContext(NPP npp)
{
nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(GetGlobalObject(npp));
NS_ENSURE_TRUE(sgo, nullptr);
nsIScriptContext *scx = sgo->GetContext();
@ -571,11 +577,11 @@ bool
nsJSObjWrapper::NP_HasMethod(NPObject *npobj, NPIdentifier id)
{
NPP npp = NPPStack::Peek();
JSContext *cx = GetJSContext(npp);
if (!cx) {
dom::AutoJSAPI jsapi;
if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReporting(GetGlobalObject(npp)))) {
return false;
}
JSContext *cx = jsapi.cx();
if (!npobj) {
ThrowJSException(cx,
@ -586,8 +592,6 @@ nsJSObjWrapper::NP_HasMethod(NPObject *npobj, NPIdentifier id)
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
nsCxPusher pusher;
pusher.Push(cx);
JSAutoCompartment ac(cx, npjsobj->mJSObj);
AutoJSExceptionReporter reporter(cx);
@ -696,11 +700,11 @@ bool
nsJSObjWrapper::NP_HasProperty(NPObject *npobj, NPIdentifier npid)
{
NPP npp = NPPStack::Peek();
JSContext *cx = GetJSContext(npp);
if (!cx) {
dom::AutoJSAPI jsapi;
if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReporting(GetGlobalObject(npp)))) {
return false;
}
JSContext *cx = jsapi.cx();
if (!npobj) {
ThrowJSException(cx,
@ -712,8 +716,6 @@ nsJSObjWrapper::NP_HasProperty(NPObject *npobj, NPIdentifier npid)
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
bool found, ok = false;
nsCxPusher pusher;
pusher.Push(cx);
AutoJSExceptionReporter reporter(cx);
JS::Rooted<JSObject*> jsobj(cx, npjsobj->mJSObj);
JSAutoCompartment ac(cx, jsobj);
@ -799,11 +801,11 @@ bool
nsJSObjWrapper::NP_RemoveProperty(NPObject *npobj, NPIdentifier npid)
{
NPP npp = NPPStack::Peek();
JSContext *cx = GetJSContext(npp);
if (!cx) {
dom::AutoJSAPI jsapi;
if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReporting(GetGlobalObject(npp)))) {
return false;
}
JSContext *cx = jsapi.cx();
if (!npobj) {
ThrowJSException(cx,
@ -815,8 +817,6 @@ nsJSObjWrapper::NP_RemoveProperty(NPObject *npobj, NPIdentifier npid)
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
bool ok = false;
nsCxPusher pusher;
pusher.Push(cx);
AutoJSExceptionReporter reporter(cx);
bool deleted = false;
JS::Rooted<JSObject*> obj(cx, npjsobj->mJSObj);
@ -850,15 +850,15 @@ nsJSObjWrapper::NP_Enumerate(NPObject *npobj, NPIdentifier **idarray,
uint32_t *count)
{
NPP npp = NPPStack::Peek();
JSContext *cx = GetJSContext(npp);
dom::AutoJSAPI jsapi;
if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReporting(GetGlobalObject(npp)))) {
return false;
}
JSContext *cx = jsapi.cx();
*idarray = 0;
*count = 0;
if (!cx) {
return false;
}
if (!npobj) {
ThrowJSException(cx,
"Null npobj in nsJSObjWrapper::NP_Enumerate!");
@ -868,8 +868,6 @@ nsJSObjWrapper::NP_Enumerate(NPObject *npobj, NPIdentifier **idarray,
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
nsCxPusher pusher;
pusher.Push(cx);
AutoJSExceptionReporter reporter(cx);
JS::Rooted<JSObject*> jsobj(cx, npjsobj->mJSObj);
JSAutoCompartment ac(cx, jsobj);

View File

@ -28,6 +28,7 @@
namespace android {
class MOZ_EXPORT MtpServer;
class MOZ_EXPORT MtpStorage;
class MOZ_EXPORT MtpStringBuffer;
class MOZ_EXPORT MtpDatabase;
class MOZ_EXPORT MtpDataPacket;
class MOZ_EXPORT MtpProperty;
@ -39,6 +40,7 @@ namespace android {
#include <MtpProperty.h>
#include <MtpServer.h>
#include <MtpStorage.h>
#include <MtpStringBuffer.h>
#include <MtpTypes.h>
#endif // mozilla_system_mtpcommon_h__

View File

@ -29,6 +29,7 @@ ObjectPropertyAsStr(MtpObjectProperty aProperty)
{
switch (aProperty) {
case MTP_PROPERTY_STORAGE_ID: return "MTP_PROPERTY_STORAGE_ID";
case MTP_PROPERTY_OBJECT_FILE_NAME: return "MTP_PROPERTY_OBJECT_FILE_NAME";
case MTP_PROPERTY_OBJECT_FORMAT: return "MTP_PROPERTY_OBJECT_FORMAT";
case MTP_PROPERTY_OBJECT_SIZE: return "MTP_PROPERTY_OBJECT_SIZE";
case MTP_PROPERTY_WIDTH: return "MTP_PROPERTY_WIDTH";
@ -102,6 +103,22 @@ MozMtpDatabase::BaseName(const nsCString& path)
return path;
}
static nsCString
GetPathWithoutFileName(const nsCString& aFullPath)
{
nsCString path;
int32_t offset = aFullPath.RFindChar('/');
if (offset != kNotFound) {
// The trailing slash will be as part of 'path'
path = StringHead(aFullPath, offset + 1);
}
MTP_LOG("returning '%s'", path.get());
return path;
}
void
MozMtpDatabase::ParseDirectory(const char *aDir, MtpObjectHandle aParent)
{
@ -353,14 +370,84 @@ MozMtpDatabase::getObjectPropertyValue(MtpObjectHandle aHandle,
return MTP_RESPONSE_OK;
}
static int
GetTypeOfObjectProp(MtpObjectProperty aProperty)
{
struct PropertyTableEntry {
MtpObjectProperty property;
int type;
};
static const PropertyTableEntry kObjectPropertyTable[] = {
{MTP_PROPERTY_STORAGE_ID, MTP_TYPE_UINT32 },
{MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16 },
{MTP_PROPERTY_PROTECTION_STATUS, MTP_TYPE_UINT16 },
{MTP_PROPERTY_OBJECT_SIZE, MTP_TYPE_UINT64 },
{MTP_PROPERTY_OBJECT_FILE_NAME, MTP_TYPE_STR },
{MTP_PROPERTY_DATE_MODIFIED, MTP_TYPE_STR },
{MTP_PROPERTY_PARENT_OBJECT, MTP_TYPE_UINT32 },
{MTP_PROPERTY_DISPLAY_NAME, MTP_TYPE_STR },
{MTP_PROPERTY_DATE_ADDED, MTP_TYPE_STR },
};
int count = sizeof(kObjectPropertyTable) / sizeof(kObjectPropertyTable[0]);
const PropertyTableEntry* entryProp = kObjectPropertyTable;
int type = 0;
for (int i = 0; i < count; ++i, ++entryProp) {
if (entryProp->property == aProperty) {
type = entryProp->type;
break;
}
}
return type;
}
//virtual
MtpResponseCode
MozMtpDatabase::setObjectPropertyValue(MtpObjectHandle aHandle,
MtpObjectProperty aProperty,
MtpDataPacket& aPacket)
{
MTP_LOG("Handle: 0x%08x (NOT SUPPORTED)", aHandle);
return MTP_RESPONSE_OPERATION_NOT_SUPPORTED;
MTP_LOG("Handle: 0x%08x Property: 0x%08x", aHandle, aProperty);
// Only support file name change
if (aProperty != MTP_PROPERTY_OBJECT_FILE_NAME) {
MTP_ERR("property 0x%x not supported", aProperty);
return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED;
}
if (GetTypeOfObjectProp(aProperty) != MTP_TYPE_STR) {
MTP_ERR("property type 0x%x not supported", GetTypeOfObjectProp(aProperty));
return MTP_RESPONSE_GENERAL_ERROR;
}
RefPtr<DbEntry> entry = GetEntry(aHandle);
if (!entry) {
MTP_ERR("Invalid Handle: 0x%08x", aHandle);
return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
}
MtpStringBuffer buf;
aPacket.getString(buf);
nsDependentCString newFileName(buf);
nsCString newFileFullPath(GetPathWithoutFileName(entry->mPath) + newFileName);
if (PR_Rename(entry->mPath.get(), newFileFullPath.get()) != PR_SUCCESS) {
MTP_ERR("Failed to rename '%s' to '%s'",
entry->mPath.get(), newFileFullPath.get());
return MTP_RESPONSE_GENERAL_ERROR;
}
MTP_LOG("renamed '%s' to '%s'", entry->mPath.get(), newFileFullPath.get());
entry->mPath = newFileFullPath;
entry->mObjectName = BaseName(entry->mPath);
entry->mDisplayName = entry->mObjectName;
return MTP_RESPONSE_OK;
}
//virtual
@ -635,7 +722,13 @@ MozMtpDatabase::getObjectInfo(MtpObjectHandle aHandle,
aInfo.mStorageID = entry->mStorageID;
aInfo.mFormat = entry->mObjectFormat;
aInfo.mProtectionStatus = 0x0;
aInfo.mCompressedSize = 0;
if (entry->mObjectSize > 0xFFFFFFFFuLL) {
aInfo.mCompressedSize = 0xFFFFFFFFuLL;
} else {
aInfo.mCompressedSize = entry->mObjectSize;
}
aInfo.mThumbFormat = entry->mObjectFormat;
aInfo.mThumbCompressedSize = 20*20*4;
aInfo.mThumbPixWidth = 20;
@ -748,18 +841,36 @@ MozMtpDatabase::getObjectPropertyDesc(MtpObjectProperty aProperty,
{
MTP_LOG("Property: %s 0x%08x", ObjectPropertyAsStr(aProperty), aProperty);
// TODO: Perhaps Filesize should be 64-bit?
MtpProperty* result = nullptr;
switch (aProperty)
{
case MTP_PROPERTY_STORAGE_ID: result = new MtpProperty(aProperty, MTP_TYPE_UINT32); break;
case MTP_PROPERTY_OBJECT_FORMAT: result = new MtpProperty(aProperty, MTP_TYPE_UINT32); break;
case MTP_PROPERTY_OBJECT_SIZE: result = new MtpProperty(aProperty, MTP_TYPE_UINT32); break;
case MTP_PROPERTY_WIDTH: result = new MtpProperty(aProperty, MTP_TYPE_UINT32); break;
case MTP_PROPERTY_HEIGHT: result = new MtpProperty(aProperty, MTP_TYPE_UINT32); break;
case MTP_PROPERTY_IMAGE_BIT_DEPTH: result = new MtpProperty(aProperty, MTP_TYPE_UINT32); break;
case MTP_PROPERTY_DISPLAY_NAME: result = new MtpProperty(aProperty, MTP_TYPE_STR); break;
case MTP_PROPERTY_PROTECTION_STATUS:
result = new MtpProperty(aProperty, MTP_TYPE_UINT16);
break;
case MTP_PROPERTY_OBJECT_FORMAT:
result = new MtpProperty(aProperty, MTP_TYPE_UINT16, false, aFormat);
break;
case MTP_PROPERTY_STORAGE_ID:
case MTP_PROPERTY_PARENT_OBJECT:
case MTP_PROPERTY_WIDTH:
case MTP_PROPERTY_HEIGHT:
case MTP_PROPERTY_IMAGE_BIT_DEPTH:
result = new MtpProperty(aProperty, MTP_TYPE_UINT32);
break;
case MTP_PROPERTY_OBJECT_SIZE:
result = new MtpProperty(aProperty, MTP_TYPE_UINT64);
break;
case MTP_PROPERTY_DISPLAY_NAME:
result = new MtpProperty(aProperty, MTP_TYPE_STR);
break;
case MTP_PROPERTY_OBJECT_FILE_NAME:
result = new MtpProperty(aProperty, MTP_TYPE_STR, true);
break;
case MTP_PROPERTY_DATE_MODIFIED:
case MTP_PROPERTY_DATE_ADDED:
result = new MtpProperty(aProperty, MTP_TYPE_STR);
result->setFormDateTime();
break;
default:
break;
}

View File

@ -59,6 +59,14 @@ const CDMAICCINFO_CID =
Components.ID("{39ba3c08-aacc-46d0-8c04-9b619c387061}");
const NEIGHBORINGCELLINFO_CID =
Components.ID("{f9dfe26a-851e-4a8b-a769-cbb1baae7ded}");
const GSMCELLINFO_CID =
Components.ID("{41f6201e-7263-42e3-b31f-38a9dc8a280a}");
const WCDMACELLINFO_CID =
Components.ID("{eeaaf307-df6e-4c98-b121-e3302b1fc468}");
const CDMACELLINFO_CID =
Components.ID("{b497d6e4-4cb8-4d6e-b673-840c7d5ddf25}");
const LTECELLINFO_CID =
Components.ID("{c7e0a78a-4e99-42f5-9251-e6172c5ed8d8}");
const NS_XPCOM_SHUTDOWN_OBSERVER_ID = "xpcom-shutdown";
const kNetworkInterfaceStateChangedTopic = "network-interface-state-changed";
@ -97,6 +105,9 @@ const RADIO_POWER_OFF_TIMEOUT = 30000;
const SMS_HANDLED_WAKELOCK_TIMEOUT = 5000;
const HW_DEFAULT_CLIENT_ID = 0;
const INT32_MAX = 2147483647;
const UNKNOWN_RSSI = 99;
const RIL_IPC_MOBILECONNECTION_MSG_NAMES = [
"RIL:GetRilContext",
"RIL:GetAvailableNetworks",
@ -1076,7 +1087,109 @@ NeighboringCellInfo.prototype = {
gsmLocationAreaCode: -1,
gsmCellId: -1,
wcdmaPsc: -1,
signalStrength: 99
signalStrength: UNKNOWN_RSSI
};
function CellInfo() {}
CellInfo.prototype = {
type: null,
registered: false,
timestampType: Ci.nsICellInfo.TIMESTAMP_TYPE_UNKNOWN,
timestamp: 0
};
function GsmCellInfo() {}
GsmCellInfo.prototype = {
__proto__: CellInfo.prototype,
QueryInterface: XPCOMUtils.generateQI([Ci.nsIGsmCellInfo]),
classID: GSMCELLINFO_CID,
classInfo: XPCOMUtils.generateCI({
classID: GSMCELLINFO_CID,
classDescription: "GsmCellInfo",
interfaces: [Ci.nsIGsmCellInfo]
}),
// nsIGsmCellInfo
mcc: INT32_MAX,
mnc: INT32_MAX,
lac: INT32_MAX,
cid: INT32_MAX,
signalStrength: UNKNOWN_RSSI,
bitErrorRate: UNKNOWN_RSSI
};
function WcdmaCellInfo() {}
WcdmaCellInfo.prototype = {
__proto__: CellInfo.prototype,
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWcdmaCellInfo]),
classID: WCDMACELLINFO_CID,
classInfo: XPCOMUtils.generateCI({
classID: WCDMACELLINFO_CID,
classDescription: "WcdmaCellInfo",
interfaces: [Ci.nsIWcdmaCellInfo]
}),
// nsIWcdmaCellInfo
mcc: INT32_MAX,
mnc: INT32_MAX,
lac: INT32_MAX,
cid: INT32_MAX,
psc: INT32_MAX,
signalStrength: UNKNOWN_RSSI,
bitErrorRate: UNKNOWN_RSSI
};
function LteCellInfo() {}
LteCellInfo.prototype = {
__proto__: CellInfo.prototype,
QueryInterface: XPCOMUtils.generateQI([Ci.nsILteCellInfo]),
classID: LTECELLINFO_CID,
classInfo: XPCOMUtils.generateCI({
classID: LTECELLINFO_CID,
classDescription: "LteCellInfo",
interfaces: [Ci.nsILteCellInfo]
}),
// nsILteCellInfo
mcc: INT32_MAX,
mnc: INT32_MAX,
cid: INT32_MAX,
pcid: INT32_MAX,
tac: INT32_MAX,
signalStrength: UNKNOWN_RSSI,
rsrp: INT32_MAX,
rsrq: INT32_MAX,
rssnr: INT32_MAX,
cqi: INT32_MAX,
timingAdvance: INT32_MAX
};
function CdmaCellInfo() {}
CdmaCellInfo.prototype = {
__proto__: CellInfo.prototype,
QueryInterface: XPCOMUtils.generateQI([Ci.nsICdmaCellInfo]),
classID: CDMACELLINFO_CID,
classInfo: XPCOMUtils.generateCI({
classID: CDMACELLINFO_CID,
classDescription: "CdmaCellInfo",
interfaces: [Ci.nsICdmaCellInfo]
}),
// nsICdmaCellInfo
networkId: INT32_MAX,
systemId: INT32_MAX,
baseStationId: INT32_MAX,
longitude: INT32_MAX,
latitude: INT32_MAX,
cdmaDbm: INT32_MAX,
cdmaEcio: INT32_MAX,
evdoDbm: INT32_MAX,
evdoEcio: INT32_MAX,
evdoSnr: INT32_MAX
};
function DataConnectionHandler(clientId, radioInterface) {
@ -4420,6 +4533,45 @@ RadioInterface.prototype = {
}
},
getCellInfoList: function(callback) {
this.workerMessenger.send("getCellInfoList",
null,
function(response) {
if (response.errorMsg) {
callback.notifyGetCellInfoListFailed(response.errorMsg);
return;
}
let cellInfoList = [];
let count = response.result.length;
for (let i = 0; i < count; i++) {
let srcCellInfo = response.result[i];
let cellInfo;
switch (srcCellInfo.type) {
case RIL.CELL_INFO_TYPE_GSM:
cellInfo = new GsmCellInfo();
break;
case RIL.CELL_INFO_TYPE_WCDMA:
cellInfo = new WcdmaCellInfo();
break;
case RIL.CELL_INFO_TYPE_LTE:
cellInfo = new LteCellInfo();
break;
case RIL.CELL_INFO_TYPE_CDMA:
cellInfo = new CdmaCellInfo();
break;
}
if (!cellInfo) {
continue;
}
this.updateInfo(srcCellInfo, cellInfo);
cellInfoList.push(cellInfo);
}
callback.notifyGetCellInfoList(cellInfoList);
}.bind(this));
},
getNeighboringCellIds: function(callback) {
this.workerMessenger.send("getNeighboringCellIds",
null,

View File

@ -9,6 +9,7 @@ interface nsIDOMMozIccInfo;
interface nsIMobileConnectionInfo;
interface nsIMobileMessageCallback;
interface nsINeighboringCellIdsCallback;
interface nsICellInfoListCallback;
[scriptable, uuid(6e0f45b8-410e-11e3-8c8e-b715b2cd0128)]
interface nsIRilNetworkInterface : nsINetworkInterface
@ -56,7 +57,7 @@ interface nsIRilSendWorkerMessageCallback : nsISupports
boolean handleResponse(in jsval response);
};
[scriptable, uuid(31ba65b6-05c7-4bc8-abdc-f1a219811fb4)]
[scriptable, uuid(c13a8890-797b-4557-b92f-6b959f56c1d8)]
interface nsIRadioInterface : nsISupports
{
readonly attribute nsIRilContext rilContext;
@ -88,9 +89,15 @@ interface nsIRadioInterface : nsISupports
void getSmscAddress(in nsIMobileMessageCallback request);
/**
* Cell Info functionality.
* Request neighboring cell ids in GSM/UMTS network.
*/
void getNeighboringCellIds(in nsINeighboringCellIdsCallback callback);
/**
* Request all of the current cell information known to the radio, including
* neighboring cells.
*/
void getCellInfoList(in nsICellInfoListCallback callback);
};
[scriptable, uuid(78b65e8c-68e7-4510-9a05-65bba12b283e)]

View File

@ -129,6 +129,7 @@ this.REQUEST_ISIM_AUTHENTICATION = 105;
this.REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU = 106;
this.REQUEST_STK_SEND_ENVELOPE_WITH_STATUS = 107;
this.REQUEST_VOICE_RADIO_TECH = 108;
this.REQUEST_GET_CELL_INFO_LIST = 109;
// Flame specific parcel types.
this.REQUEST_SET_UICC_SUBSCRIPTION = 114;
@ -465,6 +466,11 @@ this.NETWORK_CREG_TECH_LTE = 14;
this.NETWORK_CREG_TECH_HSPAP = 15;
this.NETWORK_CREG_TECH_GSM = 16;
this.CELL_INFO_TYPE_GSM = 1;
this.CELL_INFO_TYPE_CDMA = 2;
this.CELL_INFO_TYPE_LTE = 3;
this.CELL_INFO_TYPE_WCDMA = 4;
this.CALL_STATE_UNKNOWN = -1;
this.CALL_STATE_ACTIVE = 0;
this.CALL_STATE_HOLDING = 1;

View File

@ -1312,6 +1312,13 @@ RilObject.prototype = {
this.context.Buf.simpleRequest(REQUEST_GET_NEIGHBORING_CELL_IDS, options);
},
/**
* Request all of the current cell information known to the radio.
*/
getCellInfoList: function(options) {
this.context.Buf.simpleRequest(REQUEST_GET_CELL_INFO_LIST, options);
},
/**
* Request various states about the network.
*/
@ -6447,6 +6454,66 @@ RilObject.prototype[REQUEST_GET_NEIGHBORING_CELL_IDS] = function REQUEST_GET_NEI
options.result = neighboringCellIds;
this.sendChromeMessage(options);
};
RilObject.prototype[REQUEST_GET_CELL_INFO_LIST] = function REQUEST_GET_CELL_INFO_LIST(length, options) {
if (options.rilRequestError) {
options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
this.sendChromeMessage(options);
return;
}
let Buf = this.context.Buf;
let cellInfoList = [];
let num = Buf.readInt32();
for (let i = 0; i < num; i++) {
let cellInfo = {};
cellInfo.type = Buf.readInt32();
cellInfo.registered = Buf.readInt32() ? true : false;
cellInfo.timestampType = Buf.readInt32();
cellInfo.timestamp = Buf.readInt64();
switch(cellInfo.type) {
case CELL_INFO_TYPE_GSM:
case CELL_INFO_TYPE_WCDMA:
cellInfo.mcc = Buf.readInt32();
cellInfo.mnc = Buf.readInt32();
cellInfo.lac = Buf.readInt32();
cellInfo.cid = Buf.readInt32();
if (cellInfo.type == CELL_INFO_TYPE_WCDMA) {
cellInfo.psc = Buf.readInt32();
}
cellInfo.signalStrength = Buf.readInt32();
cellInfo.bitErrorRate = Buf.readInt32();
break;
case CELL_INFO_TYPE_CDMA:
cellInfo.networkId = Buf.readInt32();
cellInfo.systemId = Buf.readInt32();
cellInfo.basestationId = Buf.readInt32();
cellInfo.longitude = Buf.readInt32();
cellInfo.latitude = Buf.readInt32();
cellInfo.cdmaDbm = Buf.readInt32();
cellInfo.cdmaEcio = Buf.readInt32();
cellInfo.evdoDbm = Buf.readInt32();
cellInfo.evdoEcio = Buf.readInt32();
cellInfo.evdoSnr = Buf.readInt32();
break;
case CELL_INFO_TYPE_LTE:
cellInfo.mcc = Buf.readInt32();
cellInfo.mnc = Buf.readInt32();
cellInfo.cid = Buf.readInt32();
cellInfo.pcid = Buf.readInt32();
cellInfo.tac = Buf.readInt32();
cellInfo.signalStrength = Buf.readInt32();
cellInfo.rsrp = Buf.readInt32();
cellInfo.rsrq = Buf.readInt32();
cellInfo.rssnr = Buf.readInt32();
cellInfo.cqi = Buf.readInt32();
break;
}
cellInfoList.push(cellInfo);
}
options.result = cellInfoList;
this.sendChromeMessage(options);
};
RilObject.prototype[REQUEST_SET_LOCATION_UPDATES] = null;
RilObject.prototype[REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE] = null;
RilObject.prototype[REQUEST_CDMA_SET_ROAMING_PREFERENCE] = function REQUEST_CDMA_SET_ROAMING_PREFERENCE(length, options) {

View File

@ -267,6 +267,19 @@ let Buf = {
this.readUint8() << 16 | this.readUint8() << 24;
},
readInt64: function() {
// Avoid using bitwise operators as the operands of all bitwise operators
// are converted to signed 32-bit integers.
return this.readUint8() +
this.readUint8() * Math.pow(2, 8) +
this.readUint8() * Math.pow(2, 16) +
this.readUint8() * Math.pow(2, 24) +
this.readUint8() * Math.pow(2, 32) +
this.readUint8() * Math.pow(2, 40) +
this.readUint8() * Math.pow(2, 48) +
this.readUint8() * Math.pow(2, 56);
},
readInt32List: function() {
let length = this.readInt32();
let ints = [];

View File

@ -25,9 +25,9 @@ interface PeerConnectionImpl {
nsISupports thread);
/* JSEP calls */
[Throws]
void createOffer(optional MediaConstraintsInternal constraints);
void createOffer(optional RTCOfferOptions options);
[Throws]
void createAnswer(optional MediaConstraintsInternal constraints);
void createAnswer();
[Throws]
void setLocalDescription(long action, DOMString sdp);
[Throws]
@ -40,8 +40,7 @@ interface PeerConnectionImpl {
/* Adds the stream created by GetUserMedia */
[Throws]
void addStream(MediaStream stream,
optional MediaConstraintsInternal constraints);
void addStream(MediaStream stream);
[Throws]
void removeStream(MediaStream stream);
[Throws]
@ -61,6 +60,9 @@ interface PeerConnectionImpl {
/* Puts the SIPCC engine back to 'kIdle', shuts down threads, deletes state */
void close();
/* Notify DOM window if this plugin crash is ours */
boolean pluginCrash(unsigned long pluginId);
/* Attributes */
readonly attribute DOMString fingerprint;
readonly attribute DOMString localDescription;

View File

@ -39,9 +39,4 @@ interface PeerConnectionObserver
void onRemoveStream();
void onAddTrack();
void onRemoveTrack();
/* Helper function to access supported constraints defined in webidl. Needs to
* be in a separate webidl object we hold, so putting it here was convenient.
*/
MediaConstraintSet getSupportedConstraints(optional MediaConstraintSet constraints);
};

View File

@ -52,33 +52,13 @@ dictionary RTCDataChannelInit {
unsigned short stream; // now id
};
// Misnomer dictionaries housing PeerConnection-specific constraints.
//
// Important! Do not ever add members that might need tracing (e.g. object)
// to MediaConstraintSet or any dictionary marked XxxInternal here
dictionary MediaConstraintSet {
boolean OfferToReceiveAudio;
boolean OfferToReceiveVideo;
dictionary RTCOfferOptions {
long offerToReceiveVideo;
long offerToReceiveAudio;
boolean MozDontOfferDataChannel;
boolean MozBundleOnly;
};
// MediaConstraint = single-property-subset of MediaConstraintSet
// Implemented as full set. Test Object.keys(pair).length == 1
// typedef MediaConstraintSet MediaConstraint; // TODO: Bug 913053
dictionary MediaConstraints {
object mandatory; // so we can see unknown + unsupported constraints
sequence<MediaConstraintSet> _optional; // a.k.a. MediaConstraint
};
dictionary MediaConstraintsInternal {
MediaConstraintSet mandatory; // holds only supported constraints
sequence<MediaConstraintSet> _optional; // a.k.a. MediaConstraint
};
interface RTCDataChannel;
[Pref="media.peerconnection.enabled",
@ -95,10 +75,9 @@ interface mozRTCPeerConnection : EventTarget {
void getIdentityAssertion();
void createOffer (RTCSessionDescriptionCallback successCallback,
RTCPeerConnectionErrorCallback failureCallback,
optional MediaConstraints constraints);
optional RTCOfferOptions options);
void createAnswer (RTCSessionDescriptionCallback successCallback,
RTCPeerConnectionErrorCallback failureCallback,
optional MediaConstraints constraints);
RTCPeerConnectionErrorCallback failureCallback);
void setLocalDescription (mozRTCSessionDescription description,
optional VoidFunction successCallback,
optional RTCPeerConnectionErrorCallback failureCallback);
@ -108,8 +87,7 @@ interface mozRTCPeerConnection : EventTarget {
readonly attribute mozRTCSessionDescription? localDescription;
readonly attribute mozRTCSessionDescription? remoteDescription;
readonly attribute RTCSignalingState signalingState;
void updateIce (optional RTCConfiguration configuration,
optional MediaConstraints constraints);
void updateIce (optional RTCConfiguration configuration);
void addIceCandidate (mozRTCIceCandidate candidate,
optional VoidFunction successCallback,
optional RTCPeerConnectionErrorCallback failureCallback);
@ -121,10 +99,11 @@ interface mozRTCPeerConnection : EventTarget {
[ChromeOnly]
readonly attribute DOMString id;
RTCConfiguration getConfiguration ();
sequence<MediaStream> getLocalStreams ();
sequence<MediaStream> getRemoteStreams ();
MediaStream? getStreamById (DOMString streamId);
void addStream (MediaStream stream, optional MediaConstraints constraints);
void addStream (MediaStream stream);
void removeStream (MediaStream stream);
void close ();
attribute EventHandler onnegotiationneeded;

View File

@ -11,7 +11,6 @@
#include "jsapi.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/DOMError.h"
#include "mozilla/dom/ErrorEvent.h"
@ -299,12 +298,15 @@ FinishFetchOnMainThreadRunnable::Run()
}
ServiceWorkerRegistration::ServiceWorkerRegistration(const nsACString& aScope)
: mScope(aScope),
: mControlledDocumentsCounter(0),
mScope(aScope),
mPendingUninstall(false)
{ }
ServiceWorkerRegistration::~ServiceWorkerRegistration()
{ }
{
MOZ_ASSERT(!IsControllingDocuments());
}
//////////////////////////
// ServiceWorkerManager //
@ -360,18 +362,16 @@ public:
NS_IMETHODIMP
Run()
{
nsCString domain;
nsresult rv = mScriptURI->GetHost(domain);
if (NS_WARN_IF(NS_FAILED(rv))) {
mPromise->MaybeReject(rv);
return NS_OK;
}
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
nsRefPtr<ServiceWorkerManager::ServiceWorkerDomainInfo> domainInfo;
// XXXnsm: This pattern can be refactored if we end up using it
// often enough.
if (!swm->mDomainMap.Get(domain, getter_AddRefs(domainInfo))) {
nsRefPtr<ServiceWorkerManager::ServiceWorkerDomainInfo> domainInfo = swm->GetDomainInfo(mScriptURI);
if (!domainInfo) {
nsCString domain;
nsresult rv = mScriptURI->GetHost(domain);
if (NS_WARN_IF(NS_FAILED(rv))) {
mPromise->MaybeReject(rv);
return NS_OK;
}
domainInfo = new ServiceWorkerManager::ServiceWorkerDomainInfo;
swm->mDomainMap.Put(domain, domainInfo);
}
@ -380,7 +380,7 @@ public:
domainInfo->GetRegistration(mScope);
nsCString spec;
rv = mScriptURI->GetSpec(spec);
nsresult rv = mScriptURI->GetSpec(spec);
if (NS_WARN_IF(NS_FAILED(rv))) {
mPromise->MaybeReject(rv);
return NS_OK;
@ -399,12 +399,12 @@ public:
// There is no update in progress and since SW updating is upto the UA,
// we will not update right now. Simply resolve with whatever worker we
// have.
ServiceWorkerInfo info = registration->Newest();
if (info.IsValid()) {
nsRefPtr<ServiceWorkerInfo> info = registration->Newest();
if (info) {
nsRefPtr<ServiceWorker> serviceWorker;
nsresult rv =
swm->CreateServiceWorkerForWindow(mWindow,
info.GetScriptSpec(),
info->GetScriptSpec(),
registration->mScope,
getter_AddRefs(serviceWorker));
@ -563,14 +563,14 @@ ServiceWorkerManager::Update(ServiceWorkerRegistration* aRegistration,
aRegistration->mUpdateInstance = nullptr;
}
if (aRegistration->mInstallingWorker.IsValid()) {
if (aRegistration->mInstallingWorker) {
// FIXME(nsm): Terminate the worker. We still haven't figured out worker
// instance ownership when not associated with a window, so let's wait on
// this.
// FIXME(nsm): We should be setting the state on the actual worker
// instance.
// FIXME(nsm): Fire "statechange" on installing worker instance.
aRegistration->mInstallingWorker.Invalidate();
aRegistration->mInstallingWorker = nullptr;
}
aRegistration->mUpdatePromise = new UpdatePromise();
@ -657,7 +657,7 @@ ServiceWorkerManager::FinishFetch(ServiceWorkerRegistration* aRegistration,
ResolveRegisterPromises(aRegistration, aRegistration->mScriptSpec);
ServiceWorkerInfo info(aRegistration->mScriptSpec);
nsRefPtr<ServiceWorkerInfo> info = new ServiceWorkerInfo(aRegistration->mScriptSpec);
Install(aRegistration, info);
}
@ -680,14 +680,8 @@ ServiceWorkerManager::HandleError(JSContext* aCx,
return;
}
nsCString domain;
rv = uri->GetHost(domain);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
nsRefPtr<ServiceWorkerDomainInfo> domainInfo;
if (!mDomainMap.Get(domain, getter_AddRefs(domainInfo))) {
nsRefPtr<ServiceWorkerDomainInfo> domainInfo = GetDomainInfo(uri);
if (!domainInfo) {
return;
}
@ -760,7 +754,7 @@ public:
AssertIsOnMainThread();
// FIXME(nsm): Change installing worker state to redundant.
// FIXME(nsm): Fire statechange.
mRegistration->mInstallingWorker.Invalidate();
mRegistration->mInstallingWorker = nullptr;
return NS_OK;
}
};
@ -881,7 +875,7 @@ private:
void
ServiceWorkerManager::Install(ServiceWorkerRegistration* aRegistration,
ServiceWorkerInfo aServiceWorkerInfo)
ServiceWorkerInfo* aServiceWorkerInfo)
{
AssertIsOnMainThread();
aRegistration->mInstallingWorker = aServiceWorkerInfo;
@ -891,12 +885,12 @@ ServiceWorkerManager::Install(ServiceWorkerRegistration* aRegistration,
nsRefPtr<ServiceWorker> serviceWorker;
nsresult rv =
CreateServiceWorker(aServiceWorkerInfo.GetScriptSpec(),
CreateServiceWorker(aServiceWorkerInfo->GetScriptSpec(),
aRegistration->mScope,
getter_AddRefs(serviceWorker));
if (NS_WARN_IF(NS_FAILED(rv))) {
aRegistration->mInstallingWorker.Invalidate();
aRegistration->mInstallingWorker = nullptr;
return;
}
@ -936,12 +930,11 @@ ServiceWorkerManager::FinishInstall(ServiceWorkerRegistration* aRegistration)
{
AssertIsOnMainThread();
if (aRegistration->mWaitingWorker.IsValid()) {
if (aRegistration->mWaitingWorker) {
// FIXME(nsm): Actually update the state of active ServiceWorker instances.
}
aRegistration->mWaitingWorker = aRegistration->mInstallingWorker;
aRegistration->mInstallingWorker.Invalidate();
aRegistration->mWaitingWorker = aRegistration->mInstallingWorker.forget();
// FIXME(nsm): Actually update state of active ServiceWorker instances to
// installed.
@ -995,8 +988,8 @@ ServiceWorkerManager::CreateServiceWorkerForWindow(nsPIDOMWindow* aWindow,
already_AddRefed<ServiceWorkerRegistration>
ServiceWorkerManager::GetServiceWorkerRegistration(nsPIDOMWindow* aWindow)
{
nsCOMPtr<nsIURI> documentURI = aWindow->GetDocumentURI();
return GetServiceWorkerRegistration(documentURI);
nsCOMPtr<nsIDocument> document = aWindow->GetExtantDoc();
return GetServiceWorkerRegistration(document);
}
already_AddRefed<ServiceWorkerRegistration>
@ -1158,6 +1151,53 @@ ServiceWorkerManager::GetDomainInfo(const nsCString& aURL)
return GetDomainInfo(uri);
}
void
ServiceWorkerManager::MaybeStartControlling(nsIDocument* aDoc)
{
AssertIsOnMainThread();
if (!Preferences::GetBool("dom.serviceWorkers.enabled")) {
return;
}
nsRefPtr<ServiceWorkerDomainInfo> domainInfo = GetDomainInfo(aDoc);
if (!domainInfo) {
return;
}
nsRefPtr<ServiceWorkerRegistration> registration =
GetServiceWorkerRegistration(aDoc);
if (registration) {
MOZ_ASSERT(!domainInfo->mControlledDocuments.Contains(aDoc));
registration->StartControllingADocument();
// Use the already_AddRefed<> form of Put to avoid the addref-deref since
// we don't need the registration pointer in this function anymore.
domainInfo->mControlledDocuments.Put(aDoc, registration.forget());
}
}
void
ServiceWorkerManager::MaybeStopControlling(nsIDocument* aDoc)
{
MOZ_ASSERT(aDoc);
if (!Preferences::GetBool("dom.serviceWorkers.enabled")) {
return;
}
nsRefPtr<ServiceWorkerDomainInfo> domainInfo = GetDomainInfo(aDoc);
if (!domainInfo) {
return;
}
nsRefPtr<ServiceWorkerRegistration> registration;
domainInfo->mControlledDocuments.Remove(aDoc, getter_AddRefs(registration));
// A document which was uncontrolled does not maintain that state itself, so
// it will always call MaybeStopControlling() even if there isn't an
// associated registration. So this check is required.
if (registration) {
registration->StopControllingADocument();
}
}
NS_IMETHODIMP
ServiceWorkerManager::GetScopeForUrl(const nsAString& aUrl, nsAString& aScope)
{

View File

@ -10,6 +10,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/LinkedList.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/ServiceWorkerContainer.h"
@ -72,35 +73,22 @@ private:
* _GetNewestWorker(serviceWorkerRegistration)", we represent the description
* by this class and spawn a ServiceWorker in the right global when required.
*/
class ServiceWorkerInfo
class ServiceWorkerInfo MOZ_FINAL
{
nsCString mScriptSpec;
~ServiceWorkerInfo()
{ }
public:
bool
IsValid() const
{
return !mScriptSpec.IsVoid();
}
void
Invalidate()
{
mScriptSpec.SetIsVoid(true);
}
NS_INLINE_DECL_REFCOUNTING(ServiceWorkerInfo)
const nsCString&
GetScriptSpec() const
{
MOZ_ASSERT(IsValid());
return mScriptSpec;
}
ServiceWorkerInfo()
{
Invalidate();
}
explicit ServiceWorkerInfo(const nsACString& aScriptSpec)
: mScriptSpec(aScriptSpec)
{ }
@ -110,6 +98,8 @@ public:
// non-ISupports classes.
class ServiceWorkerRegistration MOZ_FINAL : public nsISupports
{
uint32_t mControlledDocumentsCounter;
virtual ~ServiceWorkerRegistration();
public:
@ -120,9 +110,9 @@ public:
// the URLs of the following three workers.
nsCString mScriptSpec;
ServiceWorkerInfo mCurrentWorker;
ServiceWorkerInfo mWaitingWorker;
ServiceWorkerInfo mInstallingWorker;
nsRefPtr<ServiceWorkerInfo> mCurrentWorker;
nsRefPtr<ServiceWorkerInfo> mWaitingWorker;
nsRefPtr<ServiceWorkerInfo> mInstallingWorker;
nsAutoPtr<UpdatePromise> mUpdatePromise;
nsRefPtr<ServiceWorkerUpdateInstance> mUpdateInstance;
@ -147,16 +137,37 @@ public:
explicit ServiceWorkerRegistration(const nsACString& aScope);
ServiceWorkerInfo
Newest() const
already_AddRefed<ServiceWorkerInfo>
Newest()
{
if (mInstallingWorker.IsValid()) {
return mInstallingWorker;
} else if (mWaitingWorker.IsValid()) {
return mWaitingWorker;
nsRefPtr<ServiceWorkerInfo> newest;
if (mInstallingWorker) {
newest = mInstallingWorker;
} else if (mWaitingWorker) {
newest = mWaitingWorker;
} else {
return mCurrentWorker;
newest = mCurrentWorker;
}
return newest.forget();
}
void
StartControllingADocument()
{
++mControlledDocumentsCounter;
}
void
StopControllingADocument()
{
--mControlledDocumentsCounter;
}
bool
IsControllingDocuments() const
{
return mControlledDocumentsCounter > 0;
}
};
@ -186,6 +197,11 @@ public:
static ServiceWorkerManager* FactoryCreate()
{
AssertIsOnMainThread();
if (!Preferences::GetBool("dom.serviceWorkers.enabled")) {
return nullptr;
}
ServiceWorkerManager* res = new ServiceWorkerManager;
NS_ADDREF(res);
return res;
@ -216,6 +232,8 @@ public:
// The containers inform the SWM on creation and destruction.
nsTObserverArray<ServiceWorkerContainer*> mServiceWorkerContainers;
nsRefPtrHashtable<nsISupportsHashKey, ServiceWorkerRegistration> mControlledDocuments;
ServiceWorkerDomainInfo()
{ }
@ -290,7 +308,7 @@ private:
void
Install(ServiceWorkerRegistration* aRegistration,
ServiceWorkerInfo aServiceWorkerInfo);
ServiceWorkerInfo* aServiceWorkerInfo);
NS_IMETHOD
CreateServiceWorkerForWindow(nsPIDOMWindow* aWindow,

View File

@ -46,10 +46,10 @@
#include "nsIScriptContext.h"
#include "xpcpublic.h"
#include "jswrapper.h"
#include "nsCxPusher.h"
#include "nsThreadUtils.h"
#include "mozilla/dom/NodeListBinding.h"
#include "mozilla/dom/ScriptSettings.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -638,21 +638,9 @@ nsBindingManager::GetBindingImplementation(nsIContent* aContent, REFNSIID aIID,
// We have never made a wrapper for this implementation.
// Create an XPC wrapper for the script object and hand it back.
nsIDocument* doc = aContent->OwnerDoc();
nsCOMPtr<nsIScriptGlobalObject> global =
do_QueryInterface(doc->GetWindow());
if (!global)
return NS_NOINTERFACE;
nsIScriptContext *context = global->GetContext();
if (!context)
return NS_NOINTERFACE;
AutoPushJSContext cx(context->GetNativeContext());
if (!cx)
return NS_NOINTERFACE;
AutoJSAPI jsapi;
jsapi.Init();
JSContext* cx = jsapi.cx();
nsIXPConnect *xpConnect = nsContentUtils::XPConnect();
@ -666,8 +654,7 @@ nsBindingManager::GetBindingImplementation(nsIContent* aContent, REFNSIID aIID,
// because they're chrome-only and no Xrays are involved.
//
// If there's no separate XBL scope, or if the reflector itself lives in
// the XBL scope, we'll end up with the global of the reflector, and this
// will all be a no-op.
// the XBL scope, we'll end up with the global of the reflector.
JS::Rooted<JSObject*> xblScope(cx, xpc::GetXBLScopeOrGlobal(cx, jsobj));
JSAutoCompartment ac(cx, xblScope);
bool ok = JS_WrapObject(cx, &jsobj);

View File

@ -10,12 +10,12 @@
#include "nsXBLPrototypeBinding.h"
#include "nsContentUtils.h"
#include "nsCxPusher.h"
#include "nsGlobalWindow.h"
#include "nsIContent.h"
#include "nsIAtom.h"
#include "nsIDOMKeyEvent.h"
#include "nsIDOMMouseEvent.h"
#include "nsNameSpaceManager.h"
#include "nsIScriptContext.h"
#include "nsIDocument.h"
#include "nsIController.h"
#include "nsIControllers.h"
@ -46,6 +46,8 @@
#include "mozilla/JSEventHandler.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/EventHandlerBinding.h"
#include "mozilla/dom/ScriptSettings.h"
#include "xpcpublic.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -259,10 +261,6 @@ nsXBLPrototypeHandler::ExecuteHandler(EventTarget* aTarget,
if (!boundGlobal)
return NS_OK;
nsIScriptContext *boundContext = boundGlobal->GetScriptContext();
if (!boundContext)
return NS_OK;
nsISupports *scriptTarget;
if (winRoot) {
@ -271,16 +269,17 @@ nsXBLPrototypeHandler::ExecuteHandler(EventTarget* aTarget,
scriptTarget = aTarget;
}
// We're about to create a new JSEventHandler, which means that we're
// responsible for pushing the context of the event target. See the similar
// comment in nsEventManagerListener.cpp.
nsCxPusher pusher;
NS_ENSURE_STATE(pusher.Push(aTarget));
AutoPushJSContext cx(boundContext->GetNativeContext());
// We're about to create a new JSEventHandler, which means that we need to
// Initiatize an AutoJSAPI with aTarget's bound global to make sure any errors
// are reported to the correct place.
AutoJSAPI jsapi;
if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReporting(boundGlobal))) {
return NS_OK;
}
JSContext* cx = jsapi.cx();
JS::Rooted<JSObject*> handler(cx);
rv = EnsureEventHandler(boundGlobal, boundContext, onEventAtom, &handler);
rv = EnsureEventHandler(jsapi, onEventAtom, &handler);
NS_ENSURE_SUCCESS(rv, rv);
JSAddonId* addonId = MapURIToAddonID(mPrototypeBinding->DocURI());
@ -338,15 +337,14 @@ nsXBLPrototypeHandler::ExecuteHandler(EventTarget* aTarget,
}
nsresult
nsXBLPrototypeHandler::EnsureEventHandler(nsIScriptGlobalObject* aGlobal,
nsIScriptContext *aBoundContext,
nsIAtom *aName,
nsXBLPrototypeHandler::EnsureEventHandler(AutoJSAPI& jsapi, nsIAtom* aName,
JS::MutableHandle<JSObject*> aHandler)
{
AutoPushJSContext cx(aBoundContext->GetNativeContext());
JSContext* cx = jsapi.cx();
// Check to see if we've already compiled this
nsCOMPtr<nsPIDOMWindow> pWindow = do_QueryInterface(aGlobal);
JS::Rooted<JSObject*> globalObject(cx, JS::CurrentGlobalOrNull(cx));
nsCOMPtr<nsPIDOMWindow> pWindow = xpc::WindowOrNull(globalObject);
if (pWindow) {
JS::Rooted<JSObject*> cachedHandler(cx, pWindow->GetCachedXBLPrototypeHandler(this));
if (cachedHandler) {
@ -363,7 +361,6 @@ nsXBLPrototypeHandler::EnsureEventHandler(nsIScriptGlobalObject* aGlobal,
JSAddonId* addonId = MapURIToAddonID(mPrototypeBinding->DocURI());
JS::Rooted<JSObject*> globalObject(cx, aGlobal->GetGlobalJSObject());
JS::Rooted<JSObject*> scopeObject(cx, xpc::GetScopeForXBLExecution(cx, globalObject, addonId));
NS_ENSURE_TRUE(scopeObject, NS_ERROR_OUT_OF_MEMORY);

View File

@ -13,7 +13,6 @@
#include "nsAutoPtr.h"
#include "nsXBLEventHandler.h"
#include "nsIWeakReference.h"
#include "nsIScriptGlobalObject.h"
#include "nsCycleCollectionParticipant.h"
#include "js/TypeDecls.h"
@ -28,6 +27,7 @@ class nsXBLPrototypeBinding;
namespace mozilla {
namespace dom {
class AutoJSAPI;
class EventTarget;
}
}
@ -166,8 +166,7 @@ protected:
bool aIgnoreShiftKey = false);
nsresult DispatchXBLCommand(mozilla::dom::EventTarget* aTarget, nsIDOMEvent* aEvent);
nsresult DispatchXULKeyCommand(nsIDOMEvent* aEvent);
nsresult EnsureEventHandler(nsIScriptGlobalObject* aGlobal,
nsIScriptContext *aBoundContext, nsIAtom *aName,
nsresult EnsureEventHandler(mozilla::dom::AutoJSAPI& jsapi, nsIAtom* aName,
JS::MutableHandle<JSObject*> aHandler);
static int32_t KeyToMask(int32_t key);
static int32_t AccelKeyMask();

View File

@ -272,8 +272,8 @@ float Axis::ScaleWillOverscrollAmount(float aScale, float aFocus) {
float originAfterScale = (GetOrigin() + aFocus) - (aFocus / aScale);
bool both = ScaleWillOverscrollBothSides(aScale);
bool minus = originAfterScale < GetPageStart();
bool plus = (originAfterScale + (GetCompositionLength() / aScale)) > GetPageEnd();
bool minus = GetPageStart() - originAfterScale > COORDINATE_EPSILON;
bool plus = (originAfterScale + (GetCompositionLength() / aScale)) - GetPageEnd() > COORDINATE_EPSILON;
if ((minus && plus) || both) {
// If we ever reach here it's a bug in the client code.
@ -330,7 +330,7 @@ bool Axis::ScaleWillOverscrollBothSides(float aScale) {
CSSToParentLayerScale scale(metrics.GetZoomToParent().scale * aScale);
CSSRect cssCompositionBounds = metrics.mCompositionBounds / scale;
return GetRectLength(metrics.GetExpandedScrollableRect()) < GetRectLength(cssCompositionBounds);
return GetRectLength(cssCompositionBounds) - GetRectLength(metrics.GetExpandedScrollableRect()) > COORDINATE_EPSILON;
}
const FrameMetrics& Axis::GetFrameMetrics() const {

View File

@ -141,8 +141,13 @@ static void
TranslateShadowLayer2D(Layer* aLayer,
const gfxPoint& aTranslation)
{
// This layer might also be a scrollable layer and have an async transform.
// To make sure we don't clobber that, we start with the shadow transform.
// Any adjustments to the shadow transform made in this function in previous
// frames have been cleared in ClearAsyncTransforms(), so such adjustments
// will not compound over successive frames.
Matrix layerTransform;
if (!GetBaseTransform2D(aLayer, &layerTransform)) {
if (!aLayer->GetLocalTransform().Is2D(&layerTransform)) {
return;
}
@ -894,6 +899,18 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer)
aLayer->GetLocalTransform(), fixedLayerMargins);
}
void
ClearAsyncTransforms(Layer* aLayer)
{
if (!aLayer->AsLayerComposite()->GetShadowTransformSetByAnimation()) {
aLayer->AsLayerComposite()->SetShadowTransform(aLayer->GetBaseTransform());
}
for (Layer* child = aLayer->GetFirstChild();
child; child = child->GetNextSibling()) {
ClearAsyncTransforms(child);
}
}
bool
AsyncCompositionManager::TransformShadowTree(TimeStamp aCurrentFrame)
{
@ -909,6 +926,12 @@ AsyncCompositionManager::TransformShadowTree(TimeStamp aCurrentFrame)
// transforms.
bool wantNextFrame = SampleAnimations(root, aCurrentFrame);
// Clear any async transforms (not due to animations) set in previous frames.
// This is necessary because some things called by
// ApplyAsyncContentTransformToTree (in particular, TranslateShadowLayer2D),
// add to the shadow transform rather than overwriting it.
ClearAsyncTransforms(root);
// FIXME/bug 775437: unify this interface with the ~native-fennec
// derived code
//

View File

@ -220,12 +220,6 @@ def main(argv):
prefix += ['-f', prolog]
# Avoid racing on the cache by having the js shell create a new cache
# subdir for each process. The js shell takes care of deleting these
# subdirs when the process exits.
if options.max_jobs > 1 and jittests.HAVE_MULTIPROCESSING:
prefix += ['--js-cache-per-process']
# Clean up any remnants from previous crashes etc
shutil.rmtree(jittests.JS_CACHE_DIR, ignore_errors=True)
os.mkdir(jittests.JS_CACHE_DIR)

View File

@ -35,7 +35,7 @@ function asmCompileCached()
for (var i = 0; i < arguments.length; i++)
quotedArgs.push("'" + arguments[i] + "'");
var code = "var f = new Function(" + quotedArgs.join(',') + ");assertEq(isAsmJSModule(f), true);";
nestedShell("--js-cache", "--execute=" + code);
nestedShell("--js-cache", "--no-js-cache-per-process", "--execute=" + code);
var f = Function.apply(null, arguments);
assertEq(isAsmJSModuleLoadedFromCache(f), true);

View File

@ -10,7 +10,7 @@ if (!isAsmJSCompilationAvailable())
// nestedShell() (and the loadedFromCache assertion) to see if the error
// reproduces.
var code = "setIonCheckGraphCoherency(false); load('" + libdir + "bullet.js'); runBullet()";
nestedShell("--js-cache", "--execute=" + code);
nestedShell("--js-cache", "--no-js-cache-per-process", "--execute=" + code);
setIonCheckGraphCoherency(false);
load(libdir + 'bullet.js');
var results = runBullet();

View File

@ -22,6 +22,33 @@ assertEq(f(0x7f),0x7f);
assertEq(f(0xff),-1);
assertEq(f(0x100),0);
// Test signal handlers deactivation
(function() {
var jco = getJitCompilerOptions();
var signalHandlersBefore = jco["signals.enable"];
if (signalHandlersBefore == 1) {
setJitCompilerOption("signals.enable", 0);
if (isCachingEnabled()) {
// Cloned modules should fail on linking if the initial module has
// been compiled with signals but signals are deactivated.
var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i32[0] = i; return i8[0]|0}; return f');
assertAsmLinkFail(code, this, null, new ArrayBuffer(4096));
}
var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + '/* not a clone */ function f(i) {i=i|0; i32[0] = i; return i8[0]|0}; return f');
var f = asmLink(code, this, null, new ArrayBuffer(4096));
assertEq(f(0),0);
assertEq(f(0x7f),0x7f);
assertEq(f(0xff),-1);
assertEq(f(0x100),0);
setJitCompilerOption("signals.enable", 1);
}
jco = getJitCompilerOptions();
var signalHandlersAfter = jco["signals.enable"];
assertEq(signalHandlersBefore, signalHandlersAfter);
})();
var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i32[0] = i; return u8[0]|0}; return f');
var f = asmLink(code, this, null, new ArrayBuffer(4096));
assertEq(f(0),0);

View File

@ -0,0 +1,28 @@
// |jit-test| exitstatus: 6;
load(libdir + "asm.js");
var jco = getJitCompilerOptions();
if (jco["signals.enable"] === 0 || !isCachingEnabled() || !isAsmJSCompilationAvailable())
quit(6);
// Modules compiled without signal handlers should still work even if signal
// handlers have been reactivated.
setJitCompilerOption("signals.enable", 0);
var code = USE_ASM + "function f() {} function g() { while(1) { f() } } return g";
var m = asmCompile(code);
assertEq(isAsmJSModule(m), true);
assertEq(isAsmJSModuleLoadedFromCache(m), false);
setJitCompilerOption("signals.enable", 1);
var m = asmCompile(code);
assertEq(isAsmJSModule(m), true);
assertEq(isAsmJSModuleLoadedFromCache(m), true);
var g = asmLink(m);
timeout(1);
g();
assertEq(true, false);

View File

@ -0,0 +1,9 @@
// |jit-test| exitstatus: 6;
load(libdir + "asm.js");
setJitCompilerOption("signals.enable", 0);
var g = asmLink(asmCompile(USE_ASM + "function f() {} function g() { while(1) { f() } } return g"));
timeout(1);
g();
assertEq(true, false);

View File

@ -0,0 +1,9 @@
// |jit-test| exitstatus: 6;
load(libdir + "asm.js");
setJitCompilerOption("signals.enable", 0);
var g = asmLink(asmCompile(USE_ASM + "function g() { while(1) {} } return g"));
timeout(1);
g();
assertEq(true, false);

View File

@ -0,0 +1,9 @@
// |jit-test| exitstatus: 6;
load(libdir + "asm.js");
setJitCompilerOption("signals.enable", 0);
var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; if (!i) return; f((i-1)|0); f((i-1)|0); f((i-1)|0); f((i-1)|0); f((i-1)|0); } return f"));
timeout(1);
f(100);
assertEq(true, false);

View File

@ -0,0 +1,9 @@
// |jit-test| exitstatus: 6;
load(libdir + "asm.js");
setJitCompilerOption("signals.enable", 0);
var g = asmLink(asmCompile(USE_ASM + "function f(d) { d=+d; d=d*.1; d=d/.4; return +d } function g() { while(1) { +f(1.1) } } return g"));
timeout(1);
g();
assertEq(true, false);

View File

@ -0,0 +1,5 @@
// |jit-test| exitstatus: 6;
setJitCompilerOption('signals.enable', 0);
timeout(1);
for(;;);

View File

@ -6065,7 +6065,11 @@ GenerateEntry(ModuleCompiler &m, const AsmJSModule::ExportedFunction &exportedFu
return true;
}
static inline bool
// This function and InvokeFromAsmJS* functions all return int32_t rather than
// bool to prevent the compiler from optimizing bits higher than what's
// actually needed for a bool (as the result is tested in asm.js generated code
// which the compiler isn't aware of).
static inline int32_t
TryEnablingIon(JSContext *cx, AsmJSModule &module, HandleFunction fun, uint32_t exitIndex,
int32_t argc, Value *argv)
{
@ -6105,64 +6109,53 @@ TryEnablingIon(JSContext *cx, AsmJSModule &module, HandleFunction fun, uint32_t
namespace js {
// See comment above TryEnablingIon.
int32_t
InvokeFromAsmJS_Ignore(JSContext *cx, int32_t exitIndex, int32_t argc, Value *argv)
InvokeFromAsmJS(JSContext *cx, int32_t exitIndex, int32_t argc, Value *argv,
MutableHandleValue rval)
{
AsmJSModule &module = cx->mainThread().asmJSActivationStackFromOwnerThread()->module();
RootedFunction fun(cx, module.exitIndexToGlobalDatum(exitIndex).fun);
RootedValue fval(cx, ObjectValue(*fun));
if (!Invoke(cx, UndefinedValue(), fval, argc, argv, rval))
return false;
return TryEnablingIon(cx, module, fun, exitIndex, argc, argv);
}
int32_t
InvokeFromAsmJS_Ignore(JSContext *cx, int32_t exitIndex, int32_t argc, Value *argv)
{
RootedValue rval(cx);
if (!Invoke(cx, UndefinedValue(), fval, argc, argv, &rval))
return false;
if (!TryEnablingIon(cx, module, fun, exitIndex, argc, argv))
return false;
return true;
return InvokeFromAsmJS(cx, exitIndex, argc, argv, &rval);
}
int32_t
InvokeFromAsmJS_ToInt32(JSContext *cx, int32_t exitIndex, int32_t argc, Value *argv)
{
AsmJSModule &module = cx->mainThread().asmJSActivationStackFromOwnerThread()->module();
RootedFunction fun(cx, module.exitIndexToGlobalDatum(exitIndex).fun);
RootedValue fval(cx, ObjectValue(*fun));
RootedValue rval(cx);
if (!Invoke(cx, UndefinedValue(), fval, argc, argv, &rval))
return false;
if (!TryEnablingIon(cx, module, fun, exitIndex, argc, argv))
if (!InvokeFromAsmJS(cx, exitIndex, argc, argv, &rval))
return false;
int32_t i32;
if (!ToInt32(cx, rval, &i32))
return false;
argv[0] = Int32Value(i32);
return true;
}
int32_t
InvokeFromAsmJS_ToNumber(JSContext *cx, int32_t exitIndex, int32_t argc, Value *argv)
{
AsmJSModule &module = cx->mainThread().asmJSActivationStackFromOwnerThread()->module();
RootedFunction fun(cx, module.exitIndexToGlobalDatum(exitIndex).fun);
RootedValue fval(cx, ObjectValue(*fun));
RootedValue rval(cx);
if (!Invoke(cx, UndefinedValue(), fval, argc, argv, &rval))
return false;
if (!TryEnablingIon(cx, module, fun, exitIndex, argc, argv))
if (!InvokeFromAsmJS(cx, exitIndex, argc, argv, &rval))
return false;
double dbl;
if (!ToNumber(cx, rval, &dbl))
return false;
argv[0] = DoubleValue(dbl);
return true;
}

View File

@ -8808,10 +8808,11 @@ CodeGenerator::visitInterruptCheck(LInterruptCheck *lir)
bool
CodeGenerator::visitAsmJSInterruptCheck(LAsmJSInterruptCheck *lir)
{
Label rejoin;
Register scratch = ToRegister(lir->scratch());
masm.movePtr(AsmJSImmPtr(AsmJSImm_RuntimeInterrupt), scratch);
masm.branchIfFalseBool(scratch, &rejoin);
masm.load8ZeroExtend(Address(scratch, 0), scratch);
Label rejoin;
masm.branch32(Assembler::Equal, scratch, Imm32(0), &rejoin);
{
uint32_t stackFixup = ComputeByteAlignment(masm.framePushed() + AsmJSFrameSize,
StackAlignment);

View File

@ -739,6 +739,12 @@ class LAsmJSInterruptCheck : public LInstructionHelper<0, 0, 1>
}
};
class LInterruptCheck : public LInstructionHelper<0, 0, 0>
{
public:
LIR_HEADER(InterruptCheck)
};
// Alternative to LInterruptCheck which does not emit an explicit check of the
// interrupt flag but relies on the loop backedge being patched via a signal
// handler.

View File

@ -397,12 +397,6 @@ class LGuardObjectType : public LInstructionHelper<0, 1, 1>
}
};
class LInterruptCheck : public LInstructionHelper<0, 0, 0>
{
public:
LIR_HEADER(InterruptCheck);
};
class LMulI : public LBinaryMath<0>
{
public:

View File

@ -345,12 +345,6 @@ class LGuardObjectType : public LInstructionHelper<0, 1, 1>
}
};
class LInterruptCheck : public LInstructionHelper<0, 0, 0>
{
public:
LIR_HEADER(InterruptCheck);
};
class LMulI : public LBinaryMath<0>
{
public:

View File

@ -295,12 +295,6 @@ class LGuardObjectType : public LInstructionHelper<0, 1, 0>
}
};
class LInterruptCheck : public LInstructionHelper<0, 0, 0>
{
public:
LIR_HEADER(InterruptCheck)
};
class LMulI : public LBinaryMath<0, 1>
{
public:

View File

@ -187,15 +187,9 @@ class MacroAssemblerX86Shared : public Assembler
void not32(Register reg) {
notl(reg);
}
void inc32(const Operand &addr) {
incl(addr);
}
void atomic_inc32(const Operand &addr) {
lock_incl(addr);
}
void dec32(const Operand &addr) {
decl(addr);
}
void atomic_dec32(const Operand &addr) {
lock_decl(addr);
}

View File

@ -6309,6 +6309,15 @@ JS_SetGlobalJitCompilerOption(JSRuntime *rt, JSJitCompilerOption opt, uint32_t v
IonSpew(js::jit::IonSpew_Scripts, "Disable offthread compilation");
}
break;
case JSJITCOMPILER_SIGNALS_ENABLE:
if (value == 1) {
rt->setCanUseSignalHandlers(true);
IonSpew(js::jit::IonSpew_Scripts, "Enable signals");
} else if (value == 0) {
rt->setCanUseSignalHandlers(false);
IonSpew(js::jit::IonSpew_Scripts, "Disable signals");
}
break;
default:
break;
}
@ -6330,6 +6339,8 @@ JS_GetGlobalJitCompilerOption(JSRuntime *rt, JSJitCompilerOption opt)
return JS::RuntimeOptionsRef(rt).baseline();
case JSJITCOMPILER_OFFTHREAD_COMPILATION_ENABLE:
return rt->canUseOffthreadIonCompilation();
case JSJITCOMPILER_SIGNALS_ENABLE:
return rt->canUseSignalHandlers();
default:
break;
}

View File

@ -4926,7 +4926,8 @@ JS_SetOffthreadIonCompilationEnabled(JSRuntime *rt, bool enabled);
Register(ION_USECOUNT_TRIGGER, "ion.usecount.trigger") \
Register(ION_ENABLE, "ion.enable") \
Register(BASELINE_ENABLE, "baseline.enable") \
Register(OFFTHREAD_COMPILATION_ENABLE, "offthread-compilation.enable")
Register(OFFTHREAD_COMPILATION_ENABLE, "offthread-compilation.enable") \
Register(SIGNALS_ENABLE, "signals.enable")
typedef enum JSJitCompilerOption {
#define JIT_COMPILER_DECLARE(key, str) \

View File

@ -344,27 +344,35 @@ static const AllocKind FinalizePhaseScripts[] = {
FINALIZE_LAZY_SCRIPT
};
#ifdef JS_ION
static const AllocKind FinalizePhaseJitCode[] = {
FINALIZE_JITCODE
};
#endif
static const AllocKind * const FinalizePhases[] = {
FinalizePhaseStrings,
FinalizePhaseScripts,
FinalizePhaseJitCode
#ifdef JS_ION
FinalizePhaseJitCode,
#endif
};
static const int FinalizePhaseCount = sizeof(FinalizePhases) / sizeof(AllocKind*);
static const int FinalizePhaseLength[] = {
sizeof(FinalizePhaseStrings) / sizeof(AllocKind),
sizeof(FinalizePhaseScripts) / sizeof(AllocKind),
sizeof(FinalizePhaseJitCode) / sizeof(AllocKind)
#ifdef JS_ION
sizeof(FinalizePhaseJitCode) / sizeof(AllocKind),
#endif
};
static const gcstats::Phase FinalizePhaseStatsPhase[] = {
gcstats::PHASE_SWEEP_STRING,
gcstats::PHASE_SWEEP_SCRIPT,
gcstats::PHASE_SWEEP_JITCODE
#ifdef JS_ION
gcstats::PHASE_SWEEP_JITCODE,
#endif
};
/*
@ -2142,12 +2150,14 @@ ArenaLists::queueScriptsForSweep(FreeOp *fop)
queueForForegroundSweep(fop, FINALIZE_LAZY_SCRIPT);
}
#ifdef JS_ION
void
ArenaLists::queueJitCodeForSweep(FreeOp *fop)
{
gcstats::AutoPhase ap(fop->runtime()->gc.stats, gcstats::PHASE_SWEEP_JITCODE);
queueForForegroundSweep(fop, FINALIZE_JITCODE);
}
#endif
void
ArenaLists::queueShapesForSweep(FreeOp *fop)

View File

@ -919,7 +919,9 @@ class ArenaLists
void queueStringsAndSymbolsForSweep(FreeOp *fop);
void queueShapesForSweep(FreeOp *fop);
void queueScriptsForSweep(FreeOp *fop);
#ifdef JS_ION
void queueJitCodeForSweep(FreeOp *fop);
#endif
bool foregroundFinalize(FreeOp *fop, AllocKind thingKind, SliceBudget &sliceBudget,
SortedArenaList &sweepList);

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