This commit is contained in:
Carsten "Tomcat" Book 2014-09-09 16:03:23 +02:00
Родитель bb4b05365a e1bf1e82e4
Коммит 57fcc86793
337 изменённых файлов: 2714 добавлений и 2550 удалений

Просмотреть файл

@ -193,9 +193,9 @@ const LRESULT = ctypes.size_t;
const ULONG_PTR = ctypes.uintptr_t;
const PVOID = ctypes.voidptr_t;
const LPVOID = PVOID;
const LPCTSTR = ctypes.jschar.ptr;
const LPCWSTR = ctypes.jschar.ptr;
const LPTSTR = ctypes.jschar.ptr;
const LPCTSTR = ctypes.char16_t.ptr;
const LPCWSTR = ctypes.char16_t.ptr;
const LPTSTR = ctypes.char16_t.ptr;
const LPSTR = ctypes.char.ptr;
const LPCSTR = ctypes.char.ptr;
const LPBYTE = ctypes.char.ptr;
@ -707,8 +707,8 @@ function subprocess_win32(options) {
if(environment.length) {
//An environment block consists of
//a null-terminated block of null-terminated strings.
//Using CREATE_UNICODE_ENVIRONMENT so needs to be jschar
environment = ctypes.jschar.array()(environment.join('\0') + '\0');
//Using CREATE_UNICODE_ENVIRONMENT so needs to be char16_t
environment = ctypes.char16_t.array()(environment.join('\0') + '\0');
} else {
environment = null;
}

Просмотреть файл

@ -976,12 +976,12 @@ pref("apz.subframe.enabled", true);
// Overscroll-related settings
pref("apz.overscroll.enabled", true);
pref("apz.overscroll.fling_friction", "0.02");
pref("apz.overscroll.fling_friction", "0.05");
pref("apz.overscroll.fling_stopped_threshold", "0.4");
pref("apz.overscroll.stretch_factor", "0.5");
pref("apz.overscroll.snap_back.spring_stiffness", "0.6");
pref("apz.overscroll.snap_back.spring_stiffness", "0.05");
pref("apz.overscroll.snap_back.spring_friction", "0.1");
pref("apz.overscroll.snap_back.mass", "1200");
pref("apz.overscroll.snap_back.mass", "100");
// This preference allows FirefoxOS apps (and content, I think) to force
// the use of software (instead of hardware accelerated) 2D canvases by

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="fe92ddd450e03b38edb2d465de7897971d68ac68">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="4acd3e69b263b54f4111e3586ff4ade84b49b4da"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="4abb193ddae0f9780ad12ffe5e31772feee3926a"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

Просмотреть файл

@ -19,7 +19,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="4acd3e69b263b54f4111e3586ff4ade84b49b4da"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="4abb193ddae0f9780ad12ffe5e31772feee3926a"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

Просмотреть файл

@ -17,7 +17,7 @@
</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="4acd3e69b263b54f4111e3586ff4ade84b49b4da"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="4abb193ddae0f9780ad12ffe5e31772feee3926a"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="facdb3593e63dcbb740709303a5b2527113c50a0"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="fe92ddd450e03b38edb2d465de7897971d68ac68">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="4acd3e69b263b54f4111e3586ff4ade84b49b4da"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="4abb193ddae0f9780ad12ffe5e31772feee3926a"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

Просмотреть файл

@ -19,7 +19,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="4acd3e69b263b54f4111e3586ff4ade84b49b4da"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="4abb193ddae0f9780ad12ffe5e31772feee3926a"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="fe92ddd450e03b38edb2d465de7897971d68ac68">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="4acd3e69b263b54f4111e3586ff4ade84b49b4da"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="4abb193ddae0f9780ad12ffe5e31772feee3926a"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

Просмотреть файл

@ -17,7 +17,7 @@
</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="4acd3e69b263b54f4111e3586ff4ade84b49b4da"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="4abb193ddae0f9780ad12ffe5e31772feee3926a"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="facdb3593e63dcbb740709303a5b2527113c50a0"/>

Просмотреть файл

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "4ea08e48f566bc02e4df1600ec1aeae413c1a1d7",
"revision": "d43b2e2dba496f624d62c1b72a22dc5e34953fbd",
"repo_path": "/integration/gaia-central"
}

Просмотреть файл

@ -17,7 +17,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="4acd3e69b263b54f4111e3586ff4ade84b49b4da"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="4abb193ddae0f9780ad12ffe5e31772feee3926a"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

Просмотреть файл

@ -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="4acd3e69b263b54f4111e3586ff4ade84b49b4da"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="4abb193ddae0f9780ad12ffe5e31772feee3926a"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

Просмотреть файл

@ -17,7 +17,7 @@
</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="4acd3e69b263b54f4111e3586ff4ade84b49b4da"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="4abb193ddae0f9780ad12ffe5e31772feee3926a"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="facdb3593e63dcbb740709303a5b2527113c50a0"/>

Просмотреть файл

@ -17,7 +17,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="4acd3e69b263b54f4111e3586ff4ade84b49b4da"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="4abb193ddae0f9780ad12ffe5e31772feee3926a"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

Просмотреть файл

@ -1279,6 +1279,7 @@ pref("services.sync.prefs.sync.privacy.clearOnShutdown.siteSettings", true);
pref("services.sync.prefs.sync.privacy.donottrackheader.enabled", true);
pref("services.sync.prefs.sync.privacy.donottrackheader.value", true);
pref("services.sync.prefs.sync.privacy.sanitize.sanitizeOnShutdown", true);
pref("services.sync.prefs.sync.privacy.trackingprotection.enabled", true);
pref("services.sync.prefs.sync.security.OCSP.enabled", true);
pref("services.sync.prefs.sync.security.OCSP.require", true);
pref("services.sync.prefs.sync.security.default_personal_cert", true);

Просмотреть файл

@ -44,8 +44,11 @@ const gXPInstallObserver = {
} catch (e) {
browser = winOrBrowser;
}
if (!browser)
// Note that the above try/catch will pass through dead object proxies and
// other degenerate objects. Make sure the browser is bonafide.
if (!browser || gBrowser.browsers.indexOf(browser) == -1)
return;
const anchorID = "addons-notification-icon";
var messageString, action;
var brandShortName = brandBundle.getString("brandShortName");
@ -80,8 +83,16 @@ const gXPInstallObserver = {
action, null, options);
break;
case "addon-install-blocked":
let originatingHost;
try {
originatingHost = installInfo.originatingURI.host;
} catch (ex) {
// Need to deal with missing originatingURI and with about:/data: URIs more gracefully,
// see bug 1063418 - but for now, bail:
return;
}
messageString = gNavigatorBundle.getFormattedString("xpinstallPromptWarning",
[brandShortName, installInfo.originatingURI.host]);
[brandShortName, originatingHost]);
let secHistogram = Components.classes["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry).getHistogramById("SECURITY_UI");
action = {

Просмотреть файл

@ -2336,6 +2336,9 @@ let BrowserOnClick = {
let originalTarget = event.originalTarget;
let ownerDoc = originalTarget.ownerDocument;
if (!ownerDoc) {
return;
}
if (gMultiProcessBrowser &&
ownerDoc.documentURI.toLowerCase() == "about:newtab") {

Просмотреть файл

@ -370,6 +370,9 @@ let ClickEventHandler = {
let originalTarget = event.originalTarget;
let ownerDoc = originalTarget.ownerDocument;
if (!ownerDoc) {
return;
}
// Handle click events from about pages
if (ownerDoc.documentURI.startsWith("about:certerror")) {

Просмотреть файл

@ -143,6 +143,7 @@ add_task(function* formHistory() {
let deferred = Promise.defer();
Services.obs.addObserver(function onAdd(subj, topic, data) {
if (data == "formhistory-add") {
Services.obs.removeObserver(onAdd, "satchel-storage-changed");
executeSoon(() => deferred.resolve());
}
}, "satchel-storage-changed", false);
@ -167,8 +168,9 @@ add_task(function* formHistory() {
// Wait for Satchel.
deferred = Promise.defer();
Services.obs.addObserver(function onAdd(subj, topic, data) {
Services.obs.addObserver(function onRemove(subj, topic, data) {
if (data == "formhistory-remove") {
Services.obs.removeObserver(onRemove, "satchel-storage-changed");
executeSoon(() => deferred.resolve());
}
}, "satchel-storage-changed", false);

Просмотреть файл

@ -659,7 +659,7 @@ var gAdvancedPane = {
}
try {
const DRIVE_FIXED = 3;
const LPCWSTR = ctypes.jschar.ptr;
const LPCWSTR = ctypes.char16_t.ptr;
const UINT = ctypes.uint32_t;
let kernel32 = ctypes.open("kernel32");
let GetDriveType = kernel32.declare("GetDriveTypeW", ctypes.default_abi, UINT, LPCWSTR);

Просмотреть файл

@ -133,7 +133,9 @@ function windowLoad(event, win, dialog) {
return;
if (tests[currentTest].observances.length == 0) {
// Should fail here as we are not expecting a notification.
// Should fail here as we are not expecting a notification, but we don't.
// See bug 1063410.
return;
}
let permission = aSubject.QueryInterface(Ci.nsIPermission);

Просмотреть файл

@ -17,6 +17,10 @@ function notification(win, topic) {
}
let { notification, window } = expected.shift();
if (Cu.isDeadWrapper(window)) {
// Sometimes we end up with a nuked window reference here :-(
return;
}
is(topic, notification, "Saw the expected notification");
is(win, window, "Saw the expected window");
}

Просмотреть файл

@ -45,7 +45,7 @@ add_task(function* SetCurrentEngine() {
info("Test observed " + data);
if (data == "engine-current") {
ok(true, "Test observed engine-current");
Services.obs.removeObserver(obs, "browser-search-engine-modified", false);
Services.obs.removeObserver(obs, "browser-search-engine-modified");
deferred.resolve();
}
}, "browser-search-engine-modified", false);
@ -188,6 +188,7 @@ add_task(function* GetSuggestions_AddFormHistoryEntry_RemoveFormHistoryEntry() {
let deferred = Promise.defer();
Services.obs.addObserver(function onAdd(subj, topic, data) {
if (data == "formhistory-add") {
Services.obs.removeObserver(onAdd, "satchel-storage-changed");
executeSoon(() => deferred.resolve());
}
}, "satchel-storage-changed", false);
@ -224,6 +225,7 @@ add_task(function* GetSuggestions_AddFormHistoryEntry_RemoveFormHistoryEntry() {
deferred = Promise.defer();
Services.obs.addObserver(function onRemove(subj, topic, data) {
if (data == "formhistory-remove") {
Services.obs.removeObserver(onRemove, "satchel-storage-changed");
executeSoon(() => deferred.resolve());
}
}, "satchel-storage-changed", false);

Просмотреть файл

@ -255,7 +255,8 @@ function test_auth() {
let winObs = new WindowObserver(function(authWin) {
ok(authWin, "Authentication window opened");
ok(authWin.contentWindow.location);
// See bug 1063404.
// ok(authWin.location);
});
Services.ww.registerNotification(winObs);

Просмотреть файл

@ -33,6 +33,7 @@
#include "nsTextFormatter.h"
#include "nsIStringBundle.h"
#include "nsNetUtil.h"
#include "nsIEffectiveTLDService.h"
#include "nsIProperties.h"
#include "nsDirectoryServiceDefs.h"
#include "nsIFile.h"
@ -580,6 +581,35 @@ DenyAccessIfURIHasFlags(nsIURI* aURI, uint32_t aURIFlags)
return NS_OK;
}
static bool
EqualOrSubdomain(nsIURI* aProbeArg, nsIURI* aBase)
{
// Make a clone of the incoming URI, because we're going to mutate it.
nsCOMPtr<nsIURI> probe;
nsresult rv = aProbeArg->Clone(getter_AddRefs(probe));
NS_ENSURE_SUCCESS(rv, false);
nsCOMPtr<nsIEffectiveTLDService> tldService = do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
NS_ENSURE_TRUE(tldService, false);
while (true) {
if (nsScriptSecurityManager::SecurityCompareURIs(probe, aBase)) {
return true;
}
nsAutoCString host, newHost;
nsresult rv = probe->GetHost(host);
NS_ENSURE_SUCCESS(rv, false);
rv = tldService->GetNextSubDomain(host, newHost);
if (rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
return false;
}
NS_ENSURE_SUCCESS(rv, false);
rv = probe->SetHost(newHost);
NS_ENSURE_SUCCESS(rv, false);
}
}
NS_IMETHODIMP
nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
nsIURI *aTargetURI,
@ -796,7 +826,7 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
// Allow domains that were whitelisted in the prefs. In 99.9% of cases,
// this array is empty.
for (size_t i = 0; i < mFileURIWhitelist.Length(); ++i) {
if (SecurityCompareURIs(mFileURIWhitelist[i], sourceURI)) {
if (EqualOrSubdomain(sourceURI, mFileURIWhitelist[i])) {
return NS_OK;
}
}
@ -1433,7 +1463,7 @@ nsScriptSecurityManager::AddSitesToFileURIWhitelist(const nsCString& aSiteList)
if (NS_FAILED(sIOService->ExtractScheme(site, unused))) {
AddSitesToFileURIWhitelist(NS_LITERAL_CSTRING("http://") + site);
AddSitesToFileURIWhitelist(NS_LITERAL_CSTRING("https://") + site);
return;
continue;
}
// Convert it to a URI and add it to our list.

Просмотреть файл

@ -82,13 +82,18 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=995943
pushPrefs.bind(null, [['capability.policy.policynames', ',somepolicy, someotherpolicy, '],
['capability.policy.somepolicy.checkloaduri.enabled', 'allaccess'],
['capability.policy.someotherpolicy.checkloaduri.enabled', 'nope'],
['capability.policy.somepolicy.sites', ' http://example.org https://example.com test1.example.com'],
['capability.policy.somepolicy.sites', ' http://example.org test1.example.com https://test2.example.com '],
['capability.policy.someotherpolicy.sites', 'http://example.net ']]))
.then(checkLoadFileURI.bind(null, 'http://example.org', true))
.then(checkLoadFileURI.bind(null, 'http://example.com', false))
.then(checkLoadFileURI.bind(null, 'http://test2.example.com', false))
.then(checkLoadFileURI.bind(null, 'https://test2.example.com', true))
.then(checkLoadFileURI.bind(null, 'http://sub1.test2.example.com', false))
.then(checkLoadFileURI.bind(null, 'https://sub1.test2.example.com', true))
.then(checkLoadFileURI.bind(null, 'http://example.net', false))
.then(checkLoadFileURI.bind(null, 'http://test1.example.com', true))
.then(checkLoadFileURI.bind(null, 'https://test1.example.com', true))
.then(checkLoadFileURI.bind(null, 'http://sub1.test1.example.com', true))
.then(checkLoadFileURI.bind(null, 'https://sub1.test1.example.com', true))
.then(pushPrefs.bind(null, [['capability.policy.someotherpolicy.checkloaduri.enabled', 'allAccess']]))
.then(checkLoadFileURI.bind(null, 'http://example.net', true))
.then(popPrefs)

Просмотреть файл

@ -574,10 +574,6 @@ def tarjan(V, E):
def main():
# Suppress the build time check if MOZ_NO_BUILD_TIME_SM_CHECKS is set.
if "MOZ_NO_BUILD_TIME_SM_CHECKS" in os.environ:
sys.exit(0)
ok = check_style()
if ok:

Просмотреть файл

@ -6408,7 +6408,7 @@ nsContentUtils::IsPatternMatching(nsAString& aValue, nsAString& aPattern,
JS::Rooted<JSObject*> re(cx,
JS_NewUCRegExpObjectNoStatics(cx,
static_cast<jschar*>(aPattern.BeginWriting()),
static_cast<char16_t*>(aPattern.BeginWriting()),
aPattern.Length(), 0));
if (!re) {
JS_ClearPendingException(cx);
@ -6418,7 +6418,7 @@ nsContentUtils::IsPatternMatching(nsAString& aValue, nsAString& aPattern,
JS::Rooted<JS::Value> rval(cx, JS::NullValue());
size_t idx = 0;
if (!JS_ExecuteRegExpNoStatics(cx, re,
static_cast<jschar*>(aValue.BeginWriting()),
static_cast<char16_t*>(aValue.BeginWriting()),
aValue.Length(), &idx, true, &rval)) {
JS_ClearPendingException(cx);
return true;

Просмотреть файл

@ -512,7 +512,7 @@ nsFrameMessageManager::GetDelayedFrameScripts(JSContext* aCx, JS::MutableHandle<
}
static bool
JSONCreator(const jschar* aBuf, uint32_t aLen, void* aData)
JSONCreator(const char16_t* aBuf, uint32_t aLen, void* aData)
{
nsAString* result = static_cast<nsAString*>(aData);
result->Append(static_cast<const char16_t*>(aBuf),
@ -542,7 +542,7 @@ GetParamsForMessage(JSContext* aCx,
NS_ENSURE_TRUE(!json.IsEmpty(), false);
JS::Rooted<JS::Value> val(aCx, JS::NullValue());
NS_ENSURE_TRUE(JS_ParseJSON(aCx, static_cast<const jschar*>(json.get()),
NS_ENSURE_TRUE(JS_ParseJSON(aCx, static_cast<const char16_t*>(json.get()),
json.Length(), &val), false);
return WriteStructuredClone(aCx, val, aBuffer, aClosure);
@ -638,7 +638,7 @@ nsFrameMessageManager::SendMessage(const nsAString& aMessageName,
}
JS::Rooted<JS::Value> ret(aCx);
if (!JS_ParseJSON(aCx, static_cast<const jschar*>(retval[i].get()),
if (!JS_ParseJSON(aCx, static_cast<const char16_t*>(retval[i].get()),
retval[i].Length(), &ret)) {
return NS_ERROR_UNEXPECTED;
}
@ -996,7 +996,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
}
JS::Rooted<JSString*> jsMessage(cx,
JS_NewUCStringCopyN(cx,
static_cast<const jschar*>(aMessage.BeginReading()),
static_cast<const char16_t*>(aMessage.BeginReading()),
aMessage.Length()));
NS_ENSURE_TRUE(jsMessage, NS_ERROR_OUT_OF_MEMORY);
JS::Rooted<JS::Value> syncv(cx, JS::BooleanValue(aIsSync));
@ -1489,7 +1489,7 @@ nsFrameScriptExecutor::TryCacheLoadAndCompileScript(const nsAString& aURL,
nsCOMPtr<nsIInputStream> input;
channel->Open(getter_AddRefs(input));
nsString dataString;
jschar* dataStringBuf = nullptr;
char16_t* dataStringBuf = nullptr;
size_t dataStringLength = 0;
uint64_t avail64 = 0;
if (input && NS_SUCCEEDED(input->Available(&avail64)) && avail64) {

Просмотреть файл

@ -109,7 +109,7 @@ public:
bool mIsInline; // Is the script inline or loaded?
bool mHasSourceMapURL; // Does the HTTP header have a source map url?
nsString mSourceMapURL; // Holds source map url for loaded scripts
jschar* mScriptTextBuf; // Holds script text for non-inline scripts. Don't
char16_t* mScriptTextBuf; // Holds script text for non-inline scripts. Don't
size_t mScriptTextLength; // use nsString so we can give ownership to jsapi.
uint32_t mJSVersion;
nsCOMPtr<nsIURI> mURI;
@ -898,7 +898,7 @@ nsScriptLoader::ProcessRequest(nsScriptLoadRequest* aRequest, void **aOffThreadT
NS_ENSURE_ARG(aRequest);
nsAutoString textData;
const jschar* scriptBuf = nullptr;
const char16_t* scriptBuf = nullptr;
size_t scriptLength = 0;
JS::SourceBufferHolder::Ownership giveScriptOwnership =
JS::SourceBufferHolder::NoOwnership;
@ -1278,7 +1278,7 @@ DetectByteOrderMark(const unsigned char* aBytes, int32_t aLen, nsCString& oChars
nsScriptLoader::ConvertToUTF16(nsIChannel* aChannel, const uint8_t* aData,
uint32_t aLength, const nsAString& aHintCharset,
nsIDocument* aDocument,
jschar*& aBufOut, size_t& aLengthOut)
char16_t*& aBufOut, size_t& aLengthOut)
{
if (!aLength) {
aBufOut = nullptr;
@ -1335,7 +1335,7 @@ nsScriptLoader::ConvertToUTF16(nsIChannel* aChannel, const uint8_t* aData,
aLength, &unicodeLength);
NS_ENSURE_SUCCESS(rv, rv);
aBufOut = static_cast<jschar*>(js_malloc(unicodeLength * sizeof(jschar)));
aBufOut = static_cast<char16_t*>(js_malloc(unicodeLength * sizeof(char16_t)));
if (!aBufOut) {
aLengthOut = 0;
return NS_ERROR_OUT_OF_MEMORY;

Просмотреть файл

@ -170,17 +170,17 @@ public:
* attribute). May be the empty string.
* @param aDocument Document which the data is loaded for. Must not be
* null.
* @param aBufOut [out] jschar array allocated by ConvertToUTF16 and
* @param aBufOut [out] char16_t array allocated by ConvertToUTF16 and
* containing data converted to unicode. Caller must
* js_free() this data when no longer needed.
* @param aLengthOut [out] Length of array returned in aBufOut in number
* of jschars.
* of char16_t code units.
*/
static nsresult ConvertToUTF16(nsIChannel* aChannel, const uint8_t* aData,
uint32_t aLength,
const nsAString& aHintCharset,
nsIDocument* aDocument,
jschar*& aBufOut, size_t& aLengthOut);
char16_t*& aBufOut, size_t& aLengthOut);
/**
* Processes any pending requests that are ready for processing.

Просмотреть файл

@ -766,7 +766,7 @@ nsXMLHttpRequest::CreateResponseParsedJSON(JSContext* aCx)
// The Unicode converter has already zapped the BOM if there was one
JS::Rooted<JS::Value> value(aCx);
if (!JS_ParseJSON(aCx,
static_cast<const jschar*>(mResponseText.get()), mResponseText.Length(),
static_cast<const char16_t*>(mResponseText.get()), mResponseText.Length(),
&value)) {
return NS_ERROR_FAILURE;
}

Просмотреть файл

@ -36,7 +36,8 @@ function afterLoad() {
.getService(SpecialPowers.Ci.nsIProperties)
.get("TmpD", SpecialPowers.Ci.nsILocalFile);
file.append("345339_test.file");
file.createUnique(SpecialPowers.Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
// Only the file's path is used, so it doesn't need to be created.
// See also bug 1058977.
filePath = file.path;
SpecialPowers.wrap(iframeDoc).getElementById("file").value = filePath;

Просмотреть файл

@ -1,2 +1,5 @@
[DEFAULT]
support-files =
submit_invalid_file.sjs
[test_autocompleteinfo.html]
[test_submit_invalid_file.html]

Просмотреть файл

@ -1,7 +1,6 @@
[DEFAULT]
support-files =
save_restore_radio_groups.sjs
submit_invalid_file.sjs
test_input_number_data.js
[test_bug1039548.html]
@ -91,7 +90,6 @@ skip-if = e10s
[test_step_attribute.html]
skip-if = e10s
[test_stepup_stepdown.html]
[test_submit_invalid_file.html]
[test_textarea_attributes_reflection.html]
[test_validation.html]
skip-if = buildapp == 'b2g' || e10s # b2g(374 total, bug 901848, no keygen support) b2g-debug(374 total, bug 901848, no keygen support) b2g-desktop(374 total, bug 901848, no keygen support)

Просмотреть файл

@ -67,7 +67,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=722599
function testUserInput() {
//Simulating an OK click and with a file name return.
MockFilePicker.useAnyFile();
MockFilePicker.useBlobFile();
MockFilePicker.returnValue = MockFilePicker.returnOK;
var input = document.getElementById('fileInput');
input.focus();

Просмотреть файл

@ -59,7 +59,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=851780
function testUserInput() {
// Simulating an OK click and with a file name return.
MockFilePicker.useAnyFile();
MockFilePicker.useBlobFile();
MockFilePicker.returnValue = MockFilePicker.returnOK;
var input = document.getElementById('fileInput');
input.focus();

Просмотреть файл

@ -179,17 +179,12 @@ for (var test of data) {
.getService(SpecialPowers.Ci.nsIProperties);
var file = dirSvc.get("ProfD", SpecialPowers.Ci.nsIFile);
file.append('635499_file');
var outStream = SpecialPowers.Cc["@mozilla.org/network/file-output-stream;1"].
createInstance(SpecialPowers.Ci.nsIFileOutputStream);
outStream.init(file, 0x02 | 0x08 | 0x20, // write, create, truncate
0666, 0);
outStream.write("foo", 3);
outStream.close();
// Only the file's path is used, so it doesn't need to be created.
// See also bug 1058977.
SpecialPowers.wrap(input).value = file.path;
checkValidity(input, true, apply, apply);
file.remove(false);
break;
case 'date':
input.max = '2012-06-27';

Просмотреть файл

@ -177,17 +177,12 @@ for (var test of data) {
.getService(SpecialPowers.Ci.nsIProperties);
var file = dirSvc.get("ProfD", SpecialPowers.Ci.nsIFile);
file.append('635499_file');
var outStream = SpecialPowers.Cc["@mozilla.org/network/file-output-stream;1"].
createInstance(SpecialPowers.Ci.nsIFileOutputStream);
outStream.init(file, 0x02 | 0x08 | 0x20, // write, create, truncate
0666, 0);
outStream.write("foo", 3);
outStream.close();
// Only the file's path is used, so it doesn't need to be created.
// See also bug 1058977.
SpecialPowers.wrap(input).value = file.path;
checkValidity(input, true, apply, apply);
file.remove(false);
break;
case 'date':
input.value = '2012-06-28';

Просмотреть файл

@ -308,22 +308,18 @@ function checkInputRequiredValidityForFile()
element.type = 'file'
document.forms[0].appendChild(element);
function createFileWithData(fileName, fileData) {
function createFile(fileName) {
var dirSvc = SpecialPowers.Cc["@mozilla.org/file/directory_service;1"]
.getService(SpecialPowers.Ci.nsIProperties);
var testFile = dirSvc.get("ProfD", SpecialPowers.Ci.nsIFile);
testFile.append(fileName);
var outStream = SpecialPowers.Cc["@mozilla.org/network/file-output-stream;1"].
createInstance(SpecialPowers.Ci.nsIFileOutputStream);
outStream.init(testFile, 0x02 | 0x08 | 0x20, // write, create, truncate
0666, 0);
outStream.write(fileData, fileData.length);
outStream.close();
// Only the file's path is used, so it doesn't need to be created.
// See also bug 1058977.
return testFile;
}
var file = createFileWithData("345822_file", "file content");
var file = createFile("345822_file");
SpecialPowers.wrap(element).value = "";
element.required = false;
@ -350,7 +346,6 @@ function checkInputRequiredValidityForFile()
element.required = true;
SpecialPowers.wrap(element).value = '';
file.remove(false);
document.forms[0].removeChild(element);
checkSufferingFromBeingMissing(element, true);
}

Просмотреть файл

@ -132,17 +132,12 @@ for (var test of data) {
.getService(SpecialPowers.Ci.nsIProperties);
var file = dirSvc.get("ProfD", SpecialPowers.Ci.nsIFile);
file.append('635499_file');
var outStream = SpecialPowers.Cc["@mozilla.org/network/file-output-stream;1"].
createInstance(SpecialPowers.Ci.nsIFileOutputStream);
outStream.init(file, 0x02 | 0x08 | 0x20, // write, create, truncate
0666, 0);
outStream.write("foo", 3);
outStream.close();
// Only the file's path is used, so it doesn't need to be created.
// See also bug 1058977.
SpecialPowers.wrap(input).value = file.path;
checkValidity(input, true, apply);
file.remove(false);
break;
case 'date':
// For date, the step is calulated on the timestamp since 1970-01-01

Просмотреть файл

@ -6,14 +6,14 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=702949
<head>
<meta charset="utf-8">
<title>Test invalid file submission</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=702949">Mozilla Bug 702949</a>
<p id="display"></p>
<div id="content" style="display: none">
<form action='submit_invalid_file.sjs' method='post' target='result'
<form action='http://mochi.test:8888/chrome/content/html/content/test/forms/submit_invalid_file.sjs' method='post' target='result'
enctype='multipart/form-data'>
<input type='file' name='file'>
</form>

Просмотреть файл

@ -60,7 +60,7 @@ SimpleTest.waitForFocus(function() {
b2.click();
// Now, we can launch tests when file picker isn't canceled.
MockFilePicker.useAnyFile();
MockFilePicker.useBlobFile();
MockFilePicker.returnValue = MockFilePicker.returnOK;
var b = document.getElementById('b');

Просмотреть файл

@ -30,7 +30,9 @@ class nsXPCClassInfo;
namespace mozilla {
class DOMLocalMediaStream;
class MediaStream;
class MediaEngineSource;
namespace dom {
class AudioNode;
@ -102,6 +104,8 @@ public:
virtual void StopTrack(TrackID aTrackID);
virtual DOMLocalMediaStream* AsDOMLocalMediaStream() { return nullptr; }
bool IsFinished();
/**
* Returns a principal indicating who may access this stream. The stream contents
@ -301,6 +305,8 @@ public:
virtual void Stop();
virtual MediaEngineSource* GetMediaEngine(TrackID aTrackID) { return nullptr; }
/**
* Create an nsDOMLocalMediaStream whose underlying stream is a SourceMediaStream.
*/

Просмотреть файл

@ -11,8 +11,10 @@
#include "mozilla/dom/ImageCaptureErrorEvent.h"
#include "mozilla/dom/ImageCaptureErrorEventBinding.h"
#include "mozilla/dom/VideoStreamTrack.h"
#include "nsDOMFile.h"
#include "nsIDocument.h"
#include "CaptureTask.h"
#include "MediaEngine.h"
namespace mozilla {
@ -77,6 +79,69 @@ ImageCapture::GetVideoStreamTrack() const
return mVideoStreamTrack;
}
nsresult
ImageCapture::TakePhotoByMediaEngine()
{
// Callback for TakPhoto(), it also monitor the principal. If principal
// changes, it returns PHOTO_ERROR with security error.
class TakePhotoCallback : public MediaEngineSource::PhotoCallback,
public DOMMediaStream::PrincipalChangeObserver
{
public:
TakePhotoCallback(DOMMediaStream* aStream, ImageCapture* aImageCapture)
: mStream(aStream)
, mImageCapture(aImageCapture)
, mPrincipalChanged(false)
{
MOZ_ASSERT(NS_IsMainThread());
mStream->AddPrincipalChangeObserver(this);
}
void PrincipalChanged(DOMMediaStream* aMediaStream) MOZ_OVERRIDE
{
mPrincipalChanged = true;
}
nsresult PhotoComplete(already_AddRefed<DOMFile> aBlob) MOZ_OVERRIDE
{
nsRefPtr<DOMFile> blob = aBlob;
if (mPrincipalChanged) {
return PhotoError(NS_ERROR_DOM_SECURITY_ERR);
}
return mImageCapture->PostBlobEvent(blob);
}
nsresult PhotoError(nsresult aRv) MOZ_OVERRIDE
{
return mImageCapture->PostErrorEvent(ImageCaptureError::PHOTO_ERROR, aRv);
}
protected:
~TakePhotoCallback()
{
MOZ_ASSERT(NS_IsMainThread());
mStream->RemovePrincipalChangeObserver(this);
}
nsRefPtr<DOMMediaStream> mStream;
nsRefPtr<ImageCapture> mImageCapture;
bool mPrincipalChanged;
};
nsRefPtr<DOMMediaStream> domStream = mVideoStreamTrack->GetStream();
DOMLocalMediaStream* domLocalStream = domStream->AsDOMLocalMediaStream();
if (domLocalStream) {
nsRefPtr<MediaEngineSource> mediaEngine =
domLocalStream->GetMediaEngine(mVideoStreamTrack->GetTrackID());
nsRefPtr<MediaEngineSource::PhotoCallback> callback =
new TakePhotoCallback(domStream, this);
return mediaEngine->TakePhoto(callback);
}
return NS_ERROR_NOT_IMPLEMENTED;
}
void
ImageCapture::TakePhoto(ErrorResult& aResult)
{
@ -90,12 +155,20 @@ ImageCapture::TakePhoto(ErrorResult& aResult)
return;
}
nsRefPtr<CaptureTask> task =
new CaptureTask(this, mVideoStreamTrack->GetTrackID());
// Try if MediaEngine supports taking photo.
nsresult rv = TakePhotoByMediaEngine();
// It adds itself into MediaStreamGraph, so ImageCapture doesn't need to hold the
// reference.
task->AttachStream();
// It falls back to MediaStreamGraph image capture if MediaEngine doesn't
// support TakePhoto().
if (rv == NS_ERROR_NOT_IMPLEMENTED) {
IC_LOG("MediaEngine doesn't support TakePhoto(), it falls back to MediaStreamGraph.");
nsRefPtr<CaptureTask> task =
new CaptureTask(this, mVideoStreamTrack->GetTrackID());
// It adds itself into MediaStreamGraph, so ImageCapture doesn't need to hold
// the reference.
task->AttachStream();
}
}
nsresult

Просмотреть файл

@ -41,6 +41,11 @@ class VideoStreamTrack;
* be sent back as a JPG format via Blob event.
*
* All the functions in ImageCapture are run in main thread.
*
* There are two ways to capture image, MediaEngineSource and MediaStreamGraph.
* When the implementation of MediaEngineSource supports TakePhoto() in platform
* like B2G, it uses the platform camera to grab image. Otherwise, it falls back
* to the MediaStreamGraph way.
*/
class ImageCapture MOZ_FINAL : public DOMEventTargetHelper
@ -86,6 +91,10 @@ public:
protected:
virtual ~ImageCapture();
// Capture image by MediaEngine. If it's not support taking photo, this function
// should return NS_ERROR_NOT_IMPLEMENTED.
nsresult TakePhotoByMediaEngine();
nsRefPtr<VideoStreamTrack> mVideoStreamTrack;
};

Просмотреть файл

@ -173,17 +173,8 @@ MediaSourceDecoder::SetMediaSourceDuration(double aDuration)
}
void
MediaSourceDecoder::WaitForData()
MediaSourceDecoder::NotifyTimeRangesChanged()
{
MSE_DEBUG("MediaSourceDecoder(%p)::WaitForData()", this);
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
mon.Wait();
}
void
MediaSourceDecoder::NotifyGotData()
{
MSE_DEBUG("MediaSourceDecoder(%p)::NotifyGotData()", this);
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
mon.NotifyAll();
}

Просмотреть файл

@ -55,11 +55,9 @@ public:
void SetMediaSourceDuration(double aDuration);
// Provide a mechanism for MediaSourceReader to block waiting on data from a SourceBuffer.
void WaitForData();
// Called whenever a SourceBuffer has new data appended.
void NotifyGotData();
// Called whenever a TrackBuffer has new data appended or a new decoder
// initializes. Safe to call from any thread.
void NotifyTimeRangesChanged();
// Indicates the point in time at which the reader should consider
// registered TrackBuffers essential for initialization.

Просмотреть файл

@ -84,16 +84,15 @@ MediaSourceReader::RequestAudioData()
GetCallback()->OnDecodeError();
return;
}
if (SwitchAudioReader(double(mLastAudioTime) / USECS_PER_S)) {
MSE_DEBUGV("MediaSourceReader(%p)::RequestAudioData switching audio reader", this);
}
mAudioIsSeeking = false;
SwitchAudioReader(double(mLastAudioTime) / USECS_PER_S);
mAudioReader->RequestAudioData();
}
void
MediaSourceReader::OnAudioDecoded(AudioData* aSample)
{
MSE_DEBUGV("MediaSourceReader(%p)::OnAudioDecoded mTime=%lld mDuration=%lld d=%d",
MSE_DEBUGV("MediaSourceReader(%p)::OnAudioDecoded [mTime=%lld mDuration=%lld mDiscontinuity=%d]",
this, aSample->mTime, aSample->mDuration, aSample->mDiscontinuity);
if (mDropAudioBeforeThreshold) {
if (aSample->mTime < mTimeThreshold) {
@ -106,14 +105,12 @@ MediaSourceReader::OnAudioDecoded(AudioData* aSample)
mDropAudioBeforeThreshold = false;
}
// If we are seeking we need to make sure the first sample decoded after
// that seek has the mDiscontinuity field set to ensure the media decoder
// state machine picks up that the seek is complete.
if (mAudioIsSeeking) {
mAudioIsSeeking = false;
aSample->mDiscontinuity = true;
// Any OnAudioDecoded callbacks received while mAudioIsSeeking must be not
// update our last used timestamp, as these are emitted by the reader we're
// switching away from.
if (!mAudioIsSeeking) {
mLastAudioTime = aSample->mTime + aSample->mDuration;
}
mLastAudioTime = aSample->mTime + aSample->mDuration;
GetCallback()->OnAudioDecoded(aSample);
}
@ -148,16 +145,15 @@ MediaSourceReader::RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThres
mDropAudioBeforeThreshold = true;
mDropVideoBeforeThreshold = true;
}
if (SwitchVideoReader(double(mLastVideoTime) / USECS_PER_S)) {
MSE_DEBUGV("MediaSourceReader(%p)::RequestVideoData switching video reader", this);
}
mVideoIsSeeking = false;
SwitchVideoReader(double(mLastVideoTime) / USECS_PER_S);
mVideoReader->RequestVideoData(aSkipToNextKeyframe, aTimeThreshold);
}
void
MediaSourceReader::OnVideoDecoded(VideoData* aSample)
{
MSE_DEBUGV("MediaSourceReader(%p)::OnVideoDecoded mTime=%lld mDuration=%lld d=%d",
MSE_DEBUGV("MediaSourceReader(%p)::OnVideoDecoded [mTime=%lld mDuration=%lld mDiscontinuity=%d]",
this, aSample->mTime, aSample->mDuration, aSample->mDiscontinuity);
if (mDropVideoBeforeThreshold) {
if (aSample->mTime < mTimeThreshold) {
@ -170,14 +166,12 @@ MediaSourceReader::OnVideoDecoded(VideoData* aSample)
mDropVideoBeforeThreshold = false;
}
// If we are seeking we need to make sure the first sample decoded after
// that seek has the mDiscontinuity field set to ensure the media decoder
// state machine picks up that the seek is complete.
if (mVideoIsSeeking) {
mVideoIsSeeking = false;
aSample->mDiscontinuity = true;
// Any OnVideoDecoded callbacks received while mVideoIsSeeking must be not
// update our last used timestamp, as these are emitted by the reader we're
// switching away from.
if (!mVideoIsSeeking) {
mLastVideoTime = aSample->mTime + aSample->mDuration;
}
mLastVideoTime = aSample->mTime + aSample->mDuration;
GetCallback()->OnVideoDecoded(aSample);
}
@ -234,45 +228,90 @@ MediaSourceReader::BreakCycles()
}
bool
MediaSourceReader::SwitchAudioReader(double aTarget)
MediaSourceReader::CanSelectAudioReader(MediaDecoderReader* aNewReader)
{
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
// XXX: Can't handle adding an audio track after ReadMetadata yet.
if (!mAudioTrack) {
AudioInfo currentInfo = mAudioReader->GetMediaInfo().mAudio;
AudioInfo newInfo = aNewReader->GetMediaInfo().mAudio;
// TODO: We can't handle switching audio formats yet.
if (currentInfo.mRate != newInfo.mRate ||
currentInfo.mChannels != newInfo.mChannels) {
MSE_DEBUGV("MediaSourceReader(%p)::CanSelectAudioReader(%p) skip reader due to format mismatch",
this, aNewReader);
return false;
}
auto& decoders = mAudioTrack->Decoders();
for (uint32_t i = 0; i < decoders.Length(); ++i) {
nsRefPtr<dom::TimeRanges> ranges = new dom::TimeRanges();
decoders[i]->GetBuffered(ranges);
MediaDecoderReader* newReader = decoders[i]->GetReader();
MSE_DEBUGV("MediaDecoderReader(%p)::SwitchAudioReader(%f) audioReader=%p reader=%p ranges=%s",
this, aTarget, mAudioReader.get(), newReader, DumpTimeRanges(ranges).get());
if (aNewReader->AudioQueue().AtEndOfStream()) {
MSE_DEBUGV("MediaSourceReader(%p)::CanSelectAudioReader(%p) skip reader due to queue EOS",
this, aNewReader);
return false;
}
AudioInfo targetInfo = newReader->GetMediaInfo().mAudio;
AudioInfo currentInfo = mAudioReader->GetMediaInfo().mAudio;
return true;
}
// TODO: We can't handle switching audio formats yet.
if (currentInfo.mRate != targetInfo.mRate ||
currentInfo.mChannels != targetInfo.mChannels) {
bool
MediaSourceReader::CanSelectVideoReader(MediaDecoderReader* aNewReader)
{
if (aNewReader->VideoQueue().AtEndOfStream()) {
MSE_DEBUGV("MediaSourceReader(%p)::CanSelectVideoReader(%p) skip reader due to queue EOS",
this, aNewReader);
return false;
}
return true;
}
already_AddRefed<MediaDecoderReader>
MediaSourceReader::SelectReader(double aTarget,
bool (MediaSourceReader::*aCanSelectReader)(MediaDecoderReader*),
const nsTArray<nsRefPtr<SourceBufferDecoder>>& aTrackDecoders)
{
mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
// Consider decoders in order of newest to oldest, as a newer decoder
// providing a given buffered range is expected to replace an older one.
for (int32_t i = aTrackDecoders.Length() - 1; i >= 0; --i) {
nsRefPtr<MediaDecoderReader> newReader = aTrackDecoders[i]->GetReader();
// Check the track-type-specific aspects first, as it's assumed these
// are cheaper than a buffered range comparison, which seems worthwhile
// to avoid on any reader we'd subsequently reject.
if (!(this->*aCanSelectReader)(newReader)) {
continue;
}
if (ranges->Find(aTarget) != dom::TimeRanges::NoIndex) {
if (newReader->AudioQueue().AtEndOfStream()) {
continue;
}
if (mAudioReader) {
mAudioReader->SetIdle();
}
mAudioReader = newReader;
MSE_DEBUG("MediaDecoderReader(%p)::SwitchAudioReader(%f) switching to audio reader %p",
this, aTarget, mAudioReader.get());
return true;
nsRefPtr<dom::TimeRanges> ranges = new dom::TimeRanges();
aTrackDecoders[i]->GetBuffered(ranges);
if (ranges->Find(aTarget) == dom::TimeRanges::NoIndex) {
MSE_DEBUGV("MediaSourceReader(%p)::SelectReader(%f) newReader=%p target not in ranges=%s",
this, aTarget, newReader.get(), DumpTimeRanges(ranges).get());
continue;
}
return newReader.forget();
}
return nullptr;
}
bool
MediaSourceReader::SwitchAudioReader(double aTarget)
{
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
// XXX: Can't handle adding an audio track after ReadMetadata.
if (!mAudioTrack) {
return false;
}
nsRefPtr<MediaDecoderReader> newReader = SelectReader(aTarget,
&MediaSourceReader::CanSelectAudioReader,
mAudioTrack->Decoders());
if (newReader && newReader != mAudioReader) {
mAudioReader->SetIdle();
mAudioReader = newReader;
MSE_DEBUGV("MediaSourceReader(%p)::SwitchAudioReader switched reader to %p", this, mAudioReader.get());
return true;
}
return false;
}
@ -280,33 +319,19 @@ bool
MediaSourceReader::SwitchVideoReader(double aTarget)
{
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
// XXX: Can't handle adding a video track after ReadMetadata yet.
// XXX: Can't handle adding a video track after ReadMetadata.
if (!mVideoTrack) {
return false;
}
auto& decoders = mVideoTrack->Decoders();
for (uint32_t i = 0; i < decoders.Length(); ++i) {
nsRefPtr<dom::TimeRanges> ranges = new dom::TimeRanges();
decoders[i]->GetBuffered(ranges);
MediaDecoderReader* newReader = decoders[i]->GetReader();
MSE_DEBUGV("MediaDecoderReader(%p)::SwitchVideoReader(%f) videoReader=%p reader=%p ranges=%s",
this, aTarget, mVideoReader.get(), newReader, DumpTimeRanges(ranges).get());
if (ranges->Find(aTarget) != dom::TimeRanges::NoIndex) {
if (newReader->VideoQueue().AtEndOfStream()) {
continue;
}
if (mVideoReader) {
mVideoReader->SetIdle();
}
mVideoReader = newReader;
MSE_DEBUG("MediaDecoderReader(%p)::SwitchVideoReader(%f) switching to video reader %p",
this, aTarget, mVideoReader.get());
return true;
}
nsRefPtr<MediaDecoderReader> newReader = SelectReader(aTarget,
&MediaSourceReader::CanSelectVideoReader,
mVideoTrack->Decoders());
if (newReader && newReader != mVideoReader) {
mVideoReader->SetIdle();
mVideoReader = newReader;
MSE_DEBUGV("MediaSourceReader(%p)::SwitchVideoReader switched reader to %p", this, mVideoReader.get());
return true;
}
return false;
}
@ -413,6 +438,21 @@ private:
nsRefPtr<AbstractMediaDecoder> mDecoder;
};
void
MediaSourceReader::WaitForTimeRange(double aTime)
{
MSE_DEBUG("MediaSourceReader(%p)::WaitForTimeRange(%f)", this, aTime);
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
// Loop until we have the requested time range in the active TrackBuffers.
// Ideally, this wait loop would use an async request and callback
// instead. Bug 1056441 covers that change.
while (!TrackBuffersContainTime(aTime) && !IsShutdown() && !IsEnded()) {
MSE_DEBUG("MediaSourceReader(%p)::WaitForTimeRange(%f) waiting", this, aTime);
mon.Wait();
}
}
bool
MediaSourceReader::TrackBuffersContainTime(double aTime)
{
@ -448,14 +488,7 @@ MediaSourceReader::Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
NS_DispatchToMainThread(new ChangeToHaveMetadata(mDecoder));
}
// Loop until we have the requested time range in the source buffers.
// This is a workaround for our lack of async functionality in the
// MediaDecoderStateMachine. Bug 979104 implements what we need and
// we'll remove this for an async approach based on that in bug 1056441.
while (!TrackBuffersContainTime(target) && !IsShutdown() && !IsEnded()) {
MSE_DEBUG("MediaSourceReader(%p)::Seek waiting for target=%f", this, target);
static_cast<MediaSourceDecoder*>(mDecoder)->WaitForData();
}
WaitForTimeRange(target);
if (IsShutdown()) {
return NS_ERROR_FAILURE;
@ -463,8 +496,8 @@ MediaSourceReader::Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
if (mAudioTrack) {
mAudioIsSeeking = true;
DebugOnly<bool> ok = SwitchAudioReader(target);
MOZ_ASSERT(ok && static_cast<SourceBufferDecoder*>(mAudioReader->GetDecoder())->ContainsTime(target));
SwitchAudioReader(target);
MOZ_ASSERT(static_cast<SourceBufferDecoder*>(mAudioReader->GetDecoder())->ContainsTime(target));
nsresult rv = mAudioReader->Seek(aTime, aStartTime, aEndTime, aCurrentTime);
MSE_DEBUG("MediaSourceReader(%p)::Seek audio reader=%p rv=%x", this, mAudioReader.get(), rv);
if (NS_FAILED(rv)) {
@ -473,8 +506,8 @@ MediaSourceReader::Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
}
if (mVideoTrack) {
mVideoIsSeeking = true;
DebugOnly<bool> ok = SwitchVideoReader(target);
MOZ_ASSERT(ok && static_cast<SourceBufferDecoder*>(mVideoReader->GetDecoder())->ContainsTime(target));
SwitchVideoReader(target);
MOZ_ASSERT(static_cast<SourceBufferDecoder*>(mVideoReader->GetDecoder())->ContainsTime(target));
nsresult rv = mVideoReader->Seek(aTime, aStartTime, aEndTime, aCurrentTime);
MSE_DEBUG("MediaSourceReader(%p)::Seek video reader=%p rv=%x", this, mVideoReader.get(), rv);
if (NS_FAILED(rv)) {

Просмотреть файл

@ -105,6 +105,27 @@ private:
bool SwitchAudioReader(double aTarget);
bool SwitchVideoReader(double aTarget);
// Return a reader from the set available in aTrackDecoders that is considered
// usable by the aCanUserReader callback and has data available in the range
// requested by aTarget.
// aCanSelectReader is passed each reader available in aTrackDecoders and is
// expected to return true if the reader is considerable selectable.
already_AddRefed<MediaDecoderReader> SelectReader(double aTarget,
bool (MediaSourceReader::*aCanSelectReader)(MediaDecoderReader*),
const nsTArray<nsRefPtr<SourceBufferDecoder>>& aTrackDecoders);
// Passed to SelectReader to enforce any track format specific requirements.
// In the case of CanSelectAudioReader, verifies that aNewReader has a
// matching audio format to the existing reader, as format switching is not
// yet supported.
bool CanSelectAudioReader(MediaDecoderReader* aNewReader);
bool CanSelectVideoReader(MediaDecoderReader* aNewReader);
// Waits on the decoder monitor for aTime to become available in the active
// TrackBuffers. Used to block a Seek call until the necessary data has been
// provided to the relevant SourceBuffers.
void WaitForTimeRange(double aTime);
nsRefPtr<MediaDecoderReader> mAudioReader;
nsRefPtr<MediaDecoderReader> mVideoReader;

Просмотреть файл

@ -440,8 +440,13 @@ SourceBuffer::Remove(double aStart, double aEnd, ErrorResult& aRv)
return;
}
StartUpdating();
/// TODO: Run coded frame removal algorithm asynchronously (would call StopUpdating()).
StopUpdating();
/// TODO: Run coded frame removal algorithm.
// Run the final step of the coded frame removal algorithm asynchronously
// to ensure the SourceBuffer's updating flag transition behaves as
// required by the spec.
nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &SourceBuffer::StopUpdating);
NS_DispatchToMainThread(event);
}
void
@ -561,7 +566,7 @@ SourceBuffer::AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aR
// TODO: Run coded frame eviction algorithm.
// TODO: Test buffer full flag.
StartUpdating();
// TODO: Run buffer append algorithm asynchronously (would call StopUpdating()).
// TODO: Run more of the buffer append algorithm asynchronously.
if (mParser->IsInitSegmentPresent(aData, aLength)) {
MSE_DEBUG("SourceBuffer(%p)::AppendData: New initialization segment.", this);
mMediaSource->QueueInitializationEvent();
@ -632,13 +637,16 @@ SourceBuffer::AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aR
// the current start point.
mMediaSource->NotifyEvicted(0.0, GetBufferedStart());
}
StopUpdating();
// Run the final step of the buffer append algorithm asynchronously to
// ensure the SourceBuffer's updating flag transition behaves as required
// by the spec.
nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &SourceBuffer::StopUpdating);
NS_DispatchToMainThread(event);
// Schedule the state machine thread to ensure playback starts
// if required when data is appended.
mMediaSource->GetDecoder()->ScheduleStateMachineThread();
mMediaSource->GetDecoder()->NotifyGotData();
}
double

Просмотреть файл

@ -106,10 +106,13 @@ TrackBuffer::AppendData(const uint8_t* aData, uint32_t aLength)
}
SourceBufferResource* resource = mCurrentDecoder->GetResource();
int64_t appendOffset = resource->GetLength();
resource->AppendData(aData, aLength);
// XXX: For future reference: NDA call must run on the main thread.
mCurrentDecoder->NotifyDataArrived(reinterpret_cast<const char*>(aData),
aLength, resource->GetLength());
resource->AppendData(aData, aLength);
aLength, appendOffset);
mParentDecoder->NotifyTimeRangesChanged();
return true;
}
@ -245,6 +248,7 @@ TrackBuffer::RegisterDecoder(nsRefPtr<SourceBufferDecoder> aDecoder)
MSE_DEBUG("TrackBuffer(%p)::RegisterDecoder with mismatched audio/video tracks", this);
}
mInitializedDecoders.AppendElement(aDecoder);
mParentDecoder->NotifyTimeRangesChanged();
}
void

Просмотреть файл

@ -9,9 +9,7 @@ function fetchWithXHR(uri, onLoadFunction) {
xhr.open("GET", uri, true);
xhr.responseType = "blob";
xhr.addEventListener("load", function (e) {
if (xhr.status != 200) {
return;
}
is(xhr.status, 200, "fetchWithXHR load uri='" + uri + "' status=" + xhr.status);
var rdr = new FileReader();
rdr.addEventListener("load", function (e) {
onLoadFunction(e.target.result);

Просмотреть файл

@ -1,15 +1,13 @@
[DEFAULT]
skip-if = e10s
support-files = mediasource.js seek.webm seek.webm^headers^
[test_MediaSource.html]
skip-if = buildapp == 'b2g' # b2g( ReferenceError: MediaSource is not defined)
[test_SplitAppend.html]
skip-if = buildapp == 'b2g' # b2g( ReferenceError: MediaSource is not defined)
[test_SplitAppendDelay.html]
skip-if = buildapp == 'b2g' # b2g( ReferenceError: MediaSource is not defined)
skip-if = e10s || buildapp == 'b2g' # b2g( ReferenceError: MediaSource is not defined)
support-files =
mediasource.js
seek.webm seek.webm^headers^
seek_lowres.webm seek_lowres.webm^headers^
[test_BufferedSeek.html]
skip-if = buildapp == 'b2g' # b2g( ReferenceError: MediaSource is not defined)
[test_FrameSelection.html]
[test_MediaSource.html]
[test_SplitAppendDelay.html]
[test_SplitAppend.html]

Двоичные данные
content/media/mediasource/test/seek_lowres.webm Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1 @@
Cache-Control: no-store

Просмотреть файл

@ -25,7 +25,9 @@ runWithMSE(function () {
fetchWithXHR("seek.webm", function (arrayBuffer) {
sb.appendBuffer(new Uint8Array(arrayBuffer));
ms.endOfStream();
sb.addEventListener("updateend", function () {
ms.endOfStream()
});
});
var target = 2;

Просмотреть файл

@ -0,0 +1,79 @@
<!DOCTYPE HTML>
<html>
<head>
<title>MSE: verify correct frames selected for given position</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="mediasource.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
runWithMSE(function () {
var ms = new MediaSource();
var v = document.createElement("video");
v.preload = "auto";
v.src = URL.createObjectURL(ms);
document.body.appendChild(v);
ms.addEventListener("sourceopen", function () {
var sb = ms.addSourceBuffer("video/webm");
fetchWithXHR("seek.webm", function (arrayBuffer) {
// Append entire file covering range [0, 4].
sb.appendBuffer(new Uint8Array(arrayBuffer));
});
var targets = [{ currentTime: 3, videoWidth: 160, videoHeight: 120 },
{ currentTime: 2, videoWidth: 160, videoHeight: 120 },
{ currentTime: 0, videoWidth: 320, videoHeight: 240 }];
var target;
v.addEventListener("loadedmetadata", function () {
is(v.currentTime, 0, "currentTime has incorrect initial value");
is(v.videoWidth, 320, "videoWidth has incorrect initial value");
is(v.videoHeight, 240, "videoHeight has incorrect initial value");
fetchWithXHR("seek_lowres.webm", function (arrayBuffer) {
// Append initialization segment.
sb.appendBuffer(new Uint8Array(arrayBuffer, 0, 438));
var first = true;
sb.addEventListener("updateend", function () {
if (first) {
// Append media segment covering range [2, 4].
sb.appendBuffer(new Uint8Array(arrayBuffer, 51003));
first = false;
} else {
ms.endOfStream();
}
});
target = targets.shift();
v.currentTime = target.currentTime;
});
});
v.addEventListener("seeked", function () {
is(v.currentTime, target.currentTime, "Video currentTime not at target");
is(v.videoWidth, target.videoWidth, "videoWidth has incorrect final value");
is(v.videoHeight, target.videoHeight, "videoHeight has incorrect final value");
target = targets.shift();
if (target) {
v.currentTime = target.currentTime;
} else {
v.parentNode.removeChild(v);
SimpleTest.finish();
}
});
});
});
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -52,7 +52,16 @@ runWithMSE(function () {
fetchWithXHR("seek.webm", function (arrayBuffer) {
sb.appendBuffer(new Uint8Array(arrayBuffer));
is(sb.updating, true, "SourceBuffer.updating is expected value after appendBuffer");
});
sb.addEventListener("update", function () {
is(sb.updating, false, "SourceBuffer.updating is expected value in update event");
ms.endOfStream();
});
sb.addEventListener("updateend", function () {
is(sb.updating, false, "SourceBuffer.updating is expected value in updateend event");
v.play();
});
});

Просмотреть файл

@ -25,8 +25,15 @@ runWithMSE(function () {
fetchWithXHR("seek.webm", function (arrayBuffer) {
sb.appendBuffer(new Uint8Array(arrayBuffer, 0, 318));
sb.appendBuffer(new Uint8Array(arrayBuffer, 318));
ms.endOfStream();
var first = true;
sb.addEventListener("updateend", function () {
if (first) {
sb.appendBuffer(new Uint8Array(arrayBuffer, 318));
first = false;
} else {
ms.endOfStream();
}
});
v.play();
});
});

Просмотреть файл

@ -25,10 +25,17 @@ runWithMSE(function () {
fetchWithXHR("seek.webm", function (arrayBuffer) {
sb.appendBuffer(new Uint8Array(arrayBuffer, 0, 318));
window.setTimeout(function () {
sb.appendBuffer(new Uint8Array(arrayBuffer, 318));
ms.endOfStream();
}, 1000);
var first = true;
sb.addEventListener("updateend", function () {
if (first) {
window.setTimeout(function () {
sb.appendBuffer(new Uint8Array(arrayBuffer, 318));
first = false;
}, 1000);
} else {
ms.endOfStream();
}
});
v.play();
});
});

Просмотреть файл

@ -10,9 +10,14 @@
#include "DOMMediaStream.h"
#include "MediaStreamGraph.h"
#include "mozilla/dom/MediaStreamTrackBinding.h"
#include "mozilla/dom/VideoStreamTrack.h"
namespace mozilla {
namespace dom {
class DOMFile;
}
struct VideoTrackConstraintsN;
struct AudioTrackConstraintsN;
@ -137,6 +142,29 @@ public:
/* Returns the type of media source (camera, microphone, screen, window, etc) */
virtual const MediaSourceType GetMediaSource() = 0;
// Callback interface for TakePhoto(). Either PhotoComplete() or PhotoError()
// should be called.
class PhotoCallback {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PhotoCallback)
// aBlob is the image captured by MediaEngineSource. It is
// called on main thread.
virtual nsresult PhotoComplete(already_AddRefed<dom::DOMFile> aBlob) = 0;
// It is called on main thread. aRv is the error code.
virtual nsresult PhotoError(nsresult aRv) = 0;
protected:
virtual ~PhotoCallback() {}
};
/* If implementation of MediaEngineSource supports TakePhoto(), the picture
* should be return via aCallback object. Otherwise, it returns NS_ERROR_NOT_IMPLEMENTED.
* Currently, only Gonk MediaEngineSource implementation supports it.
*/
virtual nsresult TakePhoto(PhotoCallback* aCallback) = 0;
/* Return false if device is currently allocated or started */
bool IsAvailable() {
if (mState == kAllocated || mState == kStarted) {

Просмотреть файл

@ -65,6 +65,11 @@ public:
return MediaSourceType::Camera;
}
virtual nsresult TakePhoto(PhotoCallback* aCallback)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSITIMERCALLBACK
@ -125,6 +130,11 @@ public:
return MediaSourceType::Microphone;
}
virtual nsresult TakePhoto(PhotoCallback* aCallback)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSITIMERCALLBACK

Просмотреть файл

@ -34,6 +34,11 @@ class MediaEngineTabVideoSource : public MediaEngineVideoSource, nsIDOMEventList
return MediaSourceType::Browser;
}
virtual nsresult TakePhoto(PhotoCallback* aCallback)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
void Draw();
class StartRunnable : public nsRunnable {

Просмотреть файл

@ -80,7 +80,7 @@ class GetCameraNameRunnable;
* MainThread:
* mCaptureIndex, mLastCapture, mState, mWidth, mHeight,
*
* Where mWidth, mHeight, mImage are protected by mMonitor
* Where mWidth, mHeight, mImage, mPhotoCallbacks are protected by mMonitor
* mState is protected by mCallbackMonitor
* Other variable is accessed only from single thread
*/
@ -175,6 +175,11 @@ public:
#ifndef MOZ_B2G_CAMERA
NS_DECL_THREADSAFE_ISUPPORTS
nsresult TakePhoto(PhotoCallback* aCallback)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
#else
// We are subclassed from CameraControlListener, which implements a
// threadsafe reference-count for us.
@ -193,6 +198,9 @@ public:
void SnapshotImpl();
void RotateImage(layers::Image* aImage, uint32_t aWidth, uint32_t aHeight);
void Notify(const mozilla::hal::ScreenConfiguration& aConfiguration);
nsresult TakePhoto(PhotoCallback* aCallback) MOZ_OVERRIDE;
#endif
// This runnable is for creating a temporary file on the main thread.
@ -230,6 +238,7 @@ private:
// This is only modified on MainThread (AllocImpl and DeallocImpl)
nsRefPtr<ICameraControl> mCameraControl;
nsCOMPtr<nsIDOMFile> mLastCapture;
nsTArray<nsRefPtr<PhotoCallback>> mPhotoCallbacks;
// These are protected by mMonitor below
int mRotation;
@ -330,6 +339,11 @@ public:
return MediaSourceType::Microphone;
}
virtual nsresult TakePhoto(PhotoCallback* aCallback)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
// VoEMediaProcess.
void Process(int channel, webrtc::ProcessingTypes type,
int16_t audio10ms[], int length,

Просмотреть файл

@ -877,18 +877,95 @@ MediaEngineWebRTCVideoSource::GetRotation()
void
MediaEngineWebRTCVideoSource::OnUserError(UserContext aContext, nsresult aError)
{
ReentrantMonitorAutoEnter sync(mCallbackMonitor);
mCallbackMonitor.Notify();
{
// Scope the monitor, since there is another monitor below and we don't want
// unexpected deadlock.
ReentrantMonitorAutoEnter sync(mCallbackMonitor);
mCallbackMonitor.Notify();
}
// A main thread runnable to send error code to all queued PhotoCallbacks.
class TakePhotoError : public nsRunnable {
public:
TakePhotoError(nsTArray<nsRefPtr<PhotoCallback>>& aCallbacks,
nsresult aRv)
: mRv(aRv)
{
mCallbacks.SwapElements(aCallbacks);
}
NS_IMETHOD Run()
{
uint32_t callbackNumbers = mCallbacks.Length();
for (uint8_t i = 0; i < callbackNumbers; i++) {
mCallbacks[i]->PhotoError(mRv);
}
// PhotoCallback needs to dereference on main thread.
mCallbacks.Clear();
return NS_OK;
}
protected:
nsTArray<nsRefPtr<PhotoCallback>> mCallbacks;
nsresult mRv;
};
if (aContext == UserContext::kInTakePicture) {
MonitorAutoLock lock(mMonitor);
if (mPhotoCallbacks.Length()) {
NS_DispatchToMainThread(new TakePhotoError(mPhotoCallbacks, aError));
}
}
}
void
MediaEngineWebRTCVideoSource::OnTakePictureComplete(uint8_t* aData, uint32_t aLength, const nsAString& aMimeType)
{
ReentrantMonitorAutoEnter sync(mCallbackMonitor);
mLastCapture = dom::DOMFile::CreateMemoryFile(static_cast<void*>(aData),
static_cast<uint64_t>(aLength),
aMimeType);
mCallbackMonitor.Notify();
// It needs to start preview because Gonk camera will stop preview while
// taking picture.
mCameraControl->StartPreview();
// Create a main thread runnable to generate a blob and call all current queued
// PhotoCallbacks.
class GenerateBlobRunnable : public nsRunnable {
public:
GenerateBlobRunnable(nsTArray<nsRefPtr<PhotoCallback>>& aCallbacks,
uint8_t* aData,
uint32_t aLength,
const nsAString& aMimeType)
{
mCallbacks.SwapElements(aCallbacks);
mPhoto.AppendElements(aData, aLength);
mMimeType = aMimeType;
}
NS_IMETHOD Run()
{
nsRefPtr<dom::DOMFile> blob =
dom::DOMFile::CreateMemoryFile(mPhoto.Elements(), mPhoto.Length(), mMimeType);
uint32_t callbackCounts = mCallbacks.Length();
for (uint8_t i = 0; i < callbackCounts; i++) {
nsRefPtr<dom::DOMFile> tempBlob = blob;
mCallbacks[i]->PhotoComplete(tempBlob.forget());
}
// PhotoCallback needs to dereference on main thread.
mCallbacks.Clear();
return NS_OK;
}
nsTArray<nsRefPtr<PhotoCallback>> mCallbacks;
nsTArray<uint8_t> mPhoto;
nsString mMimeType;
};
// All elements in mPhotoCallbacks will be swapped in GenerateBlobRunnable
// constructor. This captured image will be sent to all the queued
// PhotoCallbacks in this runnable.
MonitorAutoLock lock(mMonitor);
if (mPhotoCallbacks.Length()) {
NS_DispatchToMainThread(
new GenerateBlobRunnable(mPhotoCallbacks, aData, aLength, aMimeType));
}
}
void
@ -976,6 +1053,28 @@ MediaEngineWebRTCVideoSource::OnNewPreviewFrame(layers::Image* aImage, uint32_t
return true; // return true because we're accepting the frame
}
nsresult
MediaEngineWebRTCVideoSource::TakePhoto(PhotoCallback* aCallback)
{
MOZ_ASSERT(NS_IsMainThread());
MonitorAutoLock lock(mMonitor);
// If other callback exists, that means there is a captured picture on the way,
// it doesn't need to TakePicture() again.
if (!mPhotoCallbacks.Length()) {
nsresult rv = mCameraControl->TakePicture();
if (NS_FAILED(rv)) {
return rv;
}
}
mPhotoCallbacks.AppendElement(aCallback);
return NS_OK;
}
#endif
}

Просмотреть файл

@ -455,7 +455,7 @@ protected:
* If the current transcluded script is being compiled off thread, the
* source for that script.
*/
jschar* mOffThreadCompileStringBuf;
char16_t* mOffThreadCompileStringBuf;
size_t mOffThreadCompileStringLength;
/**

Просмотреть файл

@ -1584,8 +1584,8 @@ static const uint32_t sAsmJSCookie = 0x600d600d;
bool
OpenEntryForRead(nsIPrincipal* aPrincipal,
const jschar* aBegin,
const jschar* aLimit,
const char16_t* aBegin,
const char16_t* aLimit,
size_t* aSize,
const uint8_t** aMemory,
intptr_t* aFile)
@ -1643,8 +1643,8 @@ CloseEntryForRead(size_t aSize,
bool
OpenEntryForWrite(nsIPrincipal* aPrincipal,
bool aInstalled,
const jschar* aBegin,
const jschar* aEnd,
const char16_t* aBegin,
const char16_t* aEnd,
size_t aSize,
uint8_t** aMemory,
intptr_t* aFile)

Просмотреть файл

@ -80,8 +80,8 @@ struct WriteParams
// Parameters specific to opening a cache entry for reading
struct ReadParams
{
const jschar* mBegin;
const jschar* mLimit;
const char16_t* mBegin;
const char16_t* mLimit;
ReadParams()
: mBegin(nullptr),
@ -103,8 +103,8 @@ struct ReadParams
bool
OpenEntryForRead(nsIPrincipal* aPrincipal,
const jschar* aBegin,
const jschar* aLimit,
const char16_t* aBegin,
const char16_t* aLimit,
size_t* aSize,
const uint8_t** aMemory,
intptr_t *aHandle);
@ -115,8 +115,8 @@ CloseEntryForRead(size_t aSize,
bool
OpenEntryForWrite(nsIPrincipal* aPrincipal,
bool aInstalled,
const jschar* aBegin,
const jschar* aEnd,
const char16_t* aBegin,
const char16_t* aEnd,
size_t aSize,
uint8_t** aMemory,
intptr_t* aHandle);

Просмотреть файл

@ -1366,7 +1366,7 @@ nsDOMClassInfo::PostCreatePrototype(JSContext * cx, JSObject * aProto)
// Don't overwrite a property set by content.
bool contentDefinedProperty;
if (!::JS_AlreadyHasOwnUCProperty(cx, global, reinterpret_cast<const jschar*>(mData->mNameUTF16),
if (!::JS_AlreadyHasOwnUCProperty(cx, global, reinterpret_cast<const char16_t*>(mData->mNameUTF16),
NS_strlen(mData->mNameUTF16),
&contentDefinedProperty)) {
return NS_ERROR_FAILURE;

Просмотреть файл

@ -97,10 +97,6 @@ using namespace mozilla::dom;
const size_t gStackSize = 8192;
#ifdef PR_LOGGING
static PRLogModuleInfo* gJSDiagnostics;
#endif
// Thank you Microsoft!
#ifdef CompareString
#undef CompareString
@ -352,212 +348,102 @@ NS_HandleScriptError(nsIScriptGlobalObject *aScriptGlobal,
return called;
}
namespace mozilla {
namespace dom {
AsyncErrorReporter::AsyncErrorReporter(JSRuntime* aRuntime,
JSErrorReport* aErrorReport,
const char* aFallbackMessage,
bool aIsChromeError,
nsPIDOMWindow* aWindow)
: mSourceLine(static_cast<const char16_t*>(aErrorReport->uclinebuf))
, mLineNumber(aErrorReport->lineno)
, mColumn(aErrorReport->column)
, mFlags(aErrorReport->flags)
{
if (!aErrorReport->filename) {
mFileName.SetIsVoid(true);
} else {
mFileName.AssignWithConversion(aErrorReport->filename);
}
const char16_t* m = static_cast<const char16_t*>(aErrorReport->ucmessage);
if (m) {
JSFlatString* name = js::GetErrorTypeName(aRuntime, aErrorReport->exnType);
if (name) {
AssignJSFlatString(mErrorMsg, name);
mErrorMsg.AppendLiteral(": ");
}
mErrorMsg.Append(m);
}
if (mErrorMsg.IsEmpty() && aFallbackMessage) {
mErrorMsg.AssignWithConversion(aFallbackMessage);
}
mCategory = aIsChromeError ? NS_LITERAL_CSTRING("chrome javascript") :
NS_LITERAL_CSTRING("content javascript");
mInnerWindowID = 0;
if (aWindow) {
MOZ_ASSERT(aWindow->IsInnerWindow());
mInnerWindowID = aWindow->WindowID();
}
}
void
AsyncErrorReporter::ReportError()
{
nsCOMPtr<nsIScriptError> errorObject =
do_CreateInstance("@mozilla.org/scripterror;1");
if (!errorObject) {
return;
}
nsresult rv = errorObject->InitWithWindowID(mErrorMsg, mFileName,
mSourceLine, mLineNumber,
mColumn, mFlags, mCategory,
mInnerWindowID);
if (NS_FAILED(rv)) {
return;
}
nsCOMPtr<nsIConsoleService> consoleService =
do_GetService(NS_CONSOLESERVICE_CONTRACTID);
if (!consoleService) {
return;
}
consoleService->LogMessage(errorObject);
return;
}
} // namespace dom
} // namespace mozilla
class ScriptErrorEvent : public AsyncErrorReporter
class ScriptErrorEvent : public nsRunnable
{
public:
ScriptErrorEvent(JSRuntime* aRuntime,
JSErrorReport* aErrorReport,
const char* aFallbackMessage,
xpc::ErrorReport* aReport,
nsIPrincipal* aScriptOriginPrincipal,
nsIPrincipal* aGlobalPrincipal,
nsPIDOMWindow* aWindow,
JS::Handle<JS::Value> aError,
bool aDispatchEvent)
// Pass an empty category, then compute ours
: AsyncErrorReporter(aRuntime, aErrorReport, aFallbackMessage,
nsContentUtils::IsSystemPrincipal(aGlobalPrincipal),
aWindow)
: mReport(aReport)
, mOriginPrincipal(aScriptOriginPrincipal)
, mDispatchEvent(aDispatchEvent)
, mError(aRuntime, aError)
, mWindow(aWindow)
{
MOZ_ASSERT_IF(mWindow, mWindow->IsInnerWindow());
}
{}
NS_IMETHOD Run()
{
nsEventStatus status = nsEventStatus_eIgnore;
nsPIDOMWindow* win = mReport->mWindow;
MOZ_ASSERT(win);
// First, notify the DOM that we have a script error, but only if
// our window is still the current inner, if we're associated with a window.
if (mDispatchEvent && (!mWindow || mWindow->IsCurrentInnerWindow())) {
nsIDocShell* docShell = mWindow ? mWindow->GetDocShell() : nullptr;
if (docShell &&
!JSREPORT_IS_WARNING(mFlags) &&
!sHandlingScriptError) {
AutoRestore<bool> recursionGuard(sHandlingScriptError);
sHandlingScriptError = true;
// our window is still the current inner.
if (mDispatchEvent && win->IsCurrentInnerWindow() &&
win->GetDocShell() && !JSREPORT_IS_WARNING(mReport->mFlags) &&
!sHandlingScriptError)
{
AutoRestore<bool> recursionGuard(sHandlingScriptError);
sHandlingScriptError = true;
nsRefPtr<nsPresContext> presContext;
docShell->GetPresContext(getter_AddRefs(presContext));
nsRefPtr<nsPresContext> presContext;
win->GetDocShell()->GetPresContext(getter_AddRefs(presContext));
ThreadsafeAutoJSContext cx;
RootedDictionary<ErrorEventInit> init(cx);
init.mCancelable = true;
init.mFilename = mFileName;
init.mBubbles = true;
ThreadsafeAutoJSContext cx;
RootedDictionary<ErrorEventInit> init(cx);
init.mCancelable = true;
init.mFilename = mReport->mFileName;
init.mBubbles = true;
nsCOMPtr<nsIScriptObjectPrincipal> sop(do_QueryInterface(mWindow));
NS_ENSURE_STATE(sop);
nsIPrincipal* p = sop->GetPrincipal();
NS_ENSURE_STATE(p);
nsCOMPtr<nsIScriptObjectPrincipal> sop(do_QueryInterface(win));
NS_ENSURE_STATE(sop);
nsIPrincipal* p = sop->GetPrincipal();
NS_ENSURE_STATE(p);
bool sameOrigin = !mOriginPrincipal;
bool sameOrigin = !mOriginPrincipal;
if (p && !sameOrigin) {
if (NS_FAILED(p->Subsumes(mOriginPrincipal, &sameOrigin))) {
sameOrigin = false;
}
if (p && !sameOrigin) {
if (NS_FAILED(p->Subsumes(mOriginPrincipal, &sameOrigin))) {
sameOrigin = false;
}
NS_NAMED_LITERAL_STRING(xoriginMsg, "Script error.");
if (sameOrigin) {
init.mMessage = mErrorMsg;
init.mLineno = mLineNumber;
init.mColno = mColumn;
init.mError = mError;
} else {
NS_WARNING("Not same origin error!");
init.mMessage = xoriginMsg;
init.mLineno = 0;
}
nsRefPtr<ErrorEvent> event =
ErrorEvent::Constructor(static_cast<nsGlobalWindow*>(mWindow.get()),
NS_LITERAL_STRING("error"), init);
event->SetTrusted(true);
EventDispatcher::DispatchDOMEvent(mWindow, nullptr, event, presContext,
&status);
}
NS_NAMED_LITERAL_STRING(xoriginMsg, "Script error.");
if (sameOrigin) {
init.mMessage = mReport->mErrorMsg;
init.mLineno = mReport->mLineNumber;
init.mColno = mReport->mColumn;
init.mError = mError;
} else {
NS_WARNING("Not same origin error!");
init.mMessage = xoriginMsg;
init.mLineno = 0;
}
nsRefPtr<ErrorEvent> event =
ErrorEvent::Constructor(static_cast<nsGlobalWindow*>(win),
NS_LITERAL_STRING("error"), init);
event->SetTrusted(true);
EventDispatcher::DispatchDOMEvent(win, nullptr, event, presContext,
&status);
}
if (status != nsEventStatus_eConsumeNoDefault) {
AsyncErrorReporter::ReportError();
mReport->LogToConsole();
}
return NS_OK;
}
private:
nsRefPtr<xpc::ErrorReport> mReport;
nsCOMPtr<nsIPrincipal> mOriginPrincipal;
bool mDispatchEvent;
JS::PersistentRootedValue mError;
nsCOMPtr<nsPIDOMWindow> mWindow;
static bool sHandlingScriptError;
};
bool ScriptErrorEvent::sHandlingScriptError = false;
// NOTE: This function could be refactored to use the above. The only reason
// it has not been done is that the code below only fills the error event
// after it has a good nsPresContext - whereas using the above function
// would involve always filling it. Is that a concern?
// This temporarily lives here to avoid code churn. It will go away entirely
// soon.
namespace xpc {
void
NS_ScriptErrorReporter(JSContext *cx,
const char *message,
JSErrorReport *report)
SystemErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
{
// We don't want to report exceptions too eagerly, but warnings in the
// absence of werror are swallowed whole, so report those now.
if (!JSREPORT_IS_WARNING(report->flags)) {
nsIXPConnect* xpc = nsContentUtils::XPConnect();
if (JS::DescribeScriptedCaller(cx)) {
xpc->MarkErrorUnreported(cx);
return;
}
if (xpc) {
nsAXPCNativeCallContext *cc = nullptr;
xpc->GetCurrentNativeCallContext(&cc);
if (cc) {
nsAXPCNativeCallContext *prev = cc;
while (NS_SUCCEEDED(prev->GetPreviousCallContext(&prev)) && prev) {
uint16_t lang;
if (NS_SUCCEEDED(prev->GetLanguage(&lang)) &&
lang == nsAXPCNativeCallContext::LANG_JS) {
xpc->MarkErrorUnreported(cx);
return;
}
}
}
}
}
JS::Rooted<JS::Value> exception(cx);
::JS_GetPendingException(cx, &exception);
@ -566,27 +452,43 @@ NS_ScriptErrorReporter(JSContext *cx,
MOZ_ASSERT(cx == nsContentUtils::GetCurrentJSContext());
nsCOMPtr<nsIGlobalObject> globalObject;
// The eventual plan is for error reporting to happen in the AutoJSAPI
// destructor using the global with which the AutoJSAPI was initialized. We
// can't _quite_ do that yet, so we take a sloppy stab at those semantics. If
// we have an nsIScriptContext, we'll get the right answer modulo
// non-current-inners.
//
// Otherwise, we just use the privileged junk scope. This has the effect of
// causing us to report the error as "chrome javascript" rather than "content
// javascript", and not invoking any error reporters. This is exactly what we
// want here.
if (nsIScriptContext* scx = GetScriptContextFromJSContext(cx)) {
nsCOMPtr<nsPIDOMWindow> outer = do_QueryInterface(scx->GetGlobalObject());
if (outer) {
globalObject = static_cast<nsGlobalWindow*>(outer->GetCurrentInnerWindow());
}
} else {
globalObject = xpc::GetNativeForGlobal(xpc::PrivilegedJunkScope());
}
if (globalObject) {
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(globalObject);
MOZ_ASSERT_IF(win, win->IsInnerWindow());
nsCOMPtr<nsIScriptObjectPrincipal> scriptPrincipal =
do_QueryInterface(globalObject);
NS_ASSERTION(scriptPrincipal, "Global objects must implement "
"nsIScriptObjectPrincipal");
if (globalObject) {
nsRefPtr<xpc::ErrorReport> xpcReport = new xpc::ErrorReport();
xpcReport->Init(report, message, globalObject);
// If there's no window to fire an event at, report it to the console
// directly.
if (!xpcReport->mWindow) {
xpcReport->LogToConsole();
return;
}
// Otherwise, we need to asynchronously invoke onerror before we can decide
// whether or not to report the error to the console.
nsContentUtils::AddScriptRunner(
new ScriptErrorEvent(JS_GetRuntime(cx),
report,
message,
xpcReport,
nsJSPrincipals::get(report->originPrincipals),
scriptPrincipal->GetPrincipal(),
win,
exception,
/* We do not try to report Out Of Memory via a dom
* event because the dom event handler would
@ -597,51 +499,10 @@ NS_ScriptErrorReporter(JSContext *cx,
*/
report->errorNumber != JSMSG_OUT_OF_MEMORY));
}
if (nsContentUtils::DOMWindowDumpEnabled()) {
// Print it to stderr as well, for the benefit of those invoking
// mozilla with -console.
nsAutoCString error;
error.AssignLiteral("JavaScript ");
if (JSREPORT_IS_STRICT(report->flags))
error.AppendLiteral("strict ");
if (JSREPORT_IS_WARNING(report->flags))
error.AppendLiteral("warning: ");
else
error.AppendLiteral("error: ");
error.Append(report->filename);
error.AppendLiteral(", line ");
error.AppendInt(report->lineno, 10);
error.AppendLiteral(": ");
if (report->ucmessage) {
AppendUTF16toUTF8(reinterpret_cast<const char16_t*>(report->ucmessage),
error);
} else {
error.Append(message);
}
fprintf(stderr, "%s\n", error.get());
fflush(stderr);
}
#ifdef PR_LOGGING
if (!gJSDiagnostics)
gJSDiagnostics = PR_NewLogModule("JSDiagnostics");
if (gJSDiagnostics) {
PR_LOG(gJSDiagnostics,
JSREPORT_IS_WARNING(report->flags) ? PR_LOG_WARNING : PR_LOG_ERROR,
("file %s, line %u: %s\n%s%s",
report->filename, report->lineno, message,
report->linebuf ? report->linebuf : "",
(report->linebuf &&
report->linebuf[strlen(report->linebuf)-1] != '\n')
? "\n"
: ""));
}
#endif
}
} /* namespace xpc */
#ifdef DEBUG
// A couple of useful functions to call when you're debugging.
nsGlobalWindow *
@ -899,7 +760,7 @@ nsJSContext::InitContext()
if (!mContext)
return NS_ERROR_OUT_OF_MEMORY;
::JS_SetErrorReporter(mContext, NS_ScriptErrorReporter);
JS_SetErrorReporter(mContext, xpc::SystemErrorReporter);
JSOptionChangedCallback(js_options_dot_str, this);
@ -1071,7 +932,7 @@ nsJSContext::AddSupportsPrimitiveTojsvals(nsISupports *aArg, JS::Value *aArgv)
p->GetData(data);
// cast is probably safe since wchar_t and jschar are expected
// cast is probably safe since wchar_t and char16_t are expected
// to be equivalent; both unsigned 16-bit entities
JSString *str =
::JS_NewUCStringCopyN(cx, data.get(), data.Length());
@ -2458,8 +2319,8 @@ NotifyGCEndRunnable::Run()
return NS_OK;
}
const jschar oomMsg[3] = { '{', '}', 0 };
const jschar *toSend = mMessage.get() ? mMessage.get() : oomMsg;
const char16_t oomMsg[3] = { '{', '}', 0 };
const char16_t *toSend = mMessage.get() ? mMessage.get() : oomMsg;
observerService->NotifyObservers(nullptr, "garbage-collection-statistics", toSend);
return NS_OK;
@ -2829,8 +2690,8 @@ NS_DOMStructuredCloneError(JSContext* cx,
static bool
AsmJSCacheOpenEntryForRead(JS::Handle<JSObject*> aGlobal,
const jschar* aBegin,
const jschar* aLimit,
const char16_t* aBegin,
const char16_t* aLimit,
size_t* aSize,
const uint8_t** aMemory,
intptr_t *aHandle)
@ -2844,8 +2705,8 @@ AsmJSCacheOpenEntryForRead(JS::Handle<JSObject*> aGlobal,
static bool
AsmJSCacheOpenEntryForWrite(JS::Handle<JSObject*> aGlobal,
bool aInstalled,
const jschar* aBegin,
const jschar* aEnd,
const char16_t* aBegin,
const char16_t* aEnd,
size_t aSize,
uint8_t** aMemory,
intptr_t* aHandle)

Просмотреть файл

@ -14,7 +14,9 @@
#include "nsIXPConnect.h"
#include "nsIArray.h"
#include "mozilla/Attributes.h"
#include "nsPIDOMWindow.h"
#include "nsThreadUtils.h"
#include "xpcpublic.h"
class nsICycleCollectorListener;
class nsIXPConnectJSObjectHolder;
@ -189,30 +191,18 @@ class AsyncErrorReporter : public nsRunnable
{
public:
// aWindow may be null if this error report is not associated with a window
AsyncErrorReporter(JSRuntime* aRuntime,
JSErrorReport* aErrorReport,
const char* aFallbackMessage,
bool aIsChromeError, // To determine category
nsPIDOMWindow* aWindow);
AsyncErrorReporter(JSRuntime* aRuntime, xpc::ErrorReport* aReport)
: mReport(aReport)
{}
NS_IMETHOD Run()
{
ReportError();
mReport->LogToConsole();
return NS_OK;
}
protected:
// Do the actual error reporting
void ReportError();
nsString mErrorMsg;
nsString mFileName;
nsString mSourceLine;
nsCString mCategory;
uint32_t mLineNumber;
uint32_t mColumn;
uint32_t mFlags;
uint64_t mInnerWindowID;
nsRefPtr<xpc::ErrorReport> mReport;
};
} // namespace dom
@ -238,9 +228,6 @@ public:
NS_DEFINE_STATIC_IID_ACCESSOR(nsIJSArgArray, NS_IJSARGARRAY_IID)
/* prototypes */
void NS_ScriptErrorReporter(JSContext *cx, const char *message, JSErrorReport *report);
JSObject* NS_DOMReadStructuredClone(JSContext* cx,
JSStructuredCloneReader* reader, uint32_t tag,
uint32_t data, void* closure);

Просмотреть файл

@ -42,8 +42,8 @@ protected:
private:
// aString is expected to actually be an nsAString*. Should only be
// called from StringifyToJSON.
static bool AppendJSONToString(const jschar* aJSONData, uint32_t aDataLength,
void* aString);
static bool AppendJSONToString(const char16_t* aJSONData,
uint32_t aDataLength, void* aString);
};
// Struct that serves as a base class for all typed arrays and array buffers and

Просмотреть файл

@ -157,7 +157,7 @@ ErrorResult::ReportTypeError(JSContext* aCx)
Message* message = mMessage;
const uint32_t argCount = message->mArgs.Length();
const jschar* args[11];
const char16_t* args[11];
for (uint32_t i = 0; i < argCount; ++i) {
args[i] = message->mArgs.ElementAt(i).get();
}
@ -1629,9 +1629,7 @@ DictionaryBase::ParseJSON(JSContext* aCx,
if (aJSON.IsEmpty()) {
return true;
}
return JS_ParseJSON(aCx,
static_cast<const jschar*>(PromiseFlatString(aJSON).get()),
aJSON.Length(), aVal);
return JS_ParseJSON(aCx, PromiseFlatString(aJSON).get(), aJSON.Length(), aVal);
}
bool
@ -1645,18 +1643,15 @@ DictionaryBase::StringifyToJSON(JSContext* aCx,
/* static */
bool
DictionaryBase::AppendJSONToString(const jschar* aJSONData,
DictionaryBase::AppendJSONToString(const char16_t* aJSONData,
uint32_t aDataLength,
void* aString)
{
nsAString* string = static_cast<nsAString*>(aString);
string->Append(static_cast<const char16_t*>(aJSONData),
aDataLength);
string->Append(aJSONData, aDataLength);
return true;
}
static JSString*
ConcatJSString(JSContext* cx, const char* pre, JS::Handle<JSString*> str, const char* post)
{
@ -2244,10 +2239,10 @@ ConvertJSValueToByteString(JSContext* cx, JS::Handle<JS::Value> v,
// and report the error outside the AutoCheckCannotGC scope.
bool foundBadChar = false;
size_t badCharIndex;
jschar badChar;
char16_t badChar;
{
JS::AutoCheckCannotGC nogc;
const jschar* chars = JS_GetTwoByteStringCharsAndLength(cx, nogc, s, &length);
const char16_t* chars = JS_GetTwoByteStringCharsAndLength(cx, nogc, s, &length);
if (!chars) {
return false;
}
@ -2270,11 +2265,11 @@ ConvertJSValueToByteString(JSContext* cx, JS::Handle<JS::Value> v,
char index[21];
static_assert(sizeof(size_t) <= 8, "index array too small");
PR_snprintf(index, sizeof(index), "%d", badCharIndex);
// A jschar is 16 bits long. The biggest unsigned 16 bit
// A char16_t is 16 bits long. The biggest unsigned 16 bit
// number (65,535) has 5 digits, plus one more for the null
// terminator.
char badCharArray[6];
static_assert(sizeof(jschar) <= 2, "badCharArray too small");
static_assert(sizeof(char16_t) <= 2, "badCharArray too small");
PR_snprintf(badCharArray, sizeof(badCharArray), "%d", badChar);
ThrowErrorMessage(cx, MSG_INVALID_BYTESTRING, index, badCharArray);
return false;

Просмотреть файл

@ -1145,8 +1145,8 @@ FindEnumStringIndex(JSContext* cx, JS::Handle<JS::Value> v, const EnumEntry* val
}
index = FindEnumStringIndexImpl(chars, length, values);
} else {
const jschar* chars = JS_GetTwoByteStringCharsAndLength(cx, nogc, str,
&length);
const char16_t* chars = JS_GetTwoByteStringCharsAndLength(cx, nogc, str,
&length);
if (!chars) {
*ok = false;
return 0;

Просмотреть файл

@ -3385,7 +3385,7 @@ class CGIsPermittedMethod(CGAbstractMethod):
self.crossOriginSetters = crossOriginSetters
self.crossOriginMethods = crossOriginMethods
args = [Argument("JSFlatString*", "prop"),
Argument("jschar", "propFirstChar"),
Argument("char16_t", "propFirstChar"),
Argument("bool", "set")]
CGAbstractMethod.__init__(self, descriptor, "IsPermitted", "bool", args,
inline=True)

Просмотреть файл

@ -150,7 +150,7 @@ GetArrayIndexFromId(JSContext* cx, JS::Handle<jsid> id)
}
if (MOZ_LIKELY(JSID_IS_ATOM(id))) {
JSAtom* atom = JSID_TO_ATOM(id);
jschar s;
char16_t s;
{
JS::AutoCheckCannotGC nogc;
if (js::AtomHasLatin1Chars(atom)) {

Просмотреть файл

@ -534,15 +534,29 @@ public:
// Allow whatever element types the bindings are willing to pass
// us in TexSubImage2D
template<class ElementType>
void TexSubImage2D(GLenum target, GLint level,
void TexSubImage2D(GLenum texImageTarget, GLint level,
GLint xoffset, GLint yoffset, GLenum format,
GLenum type, ElementType& elt, ErrorResult& rv)
{
if (IsContextLost())
return;
const GLenum target = TexImageTargetToTexTarget(texImageTarget);
if (target == LOCAL_GL_NONE)
return ErrorInvalidEnumInfo("texSubImage2D: target", texImageTarget);
if (!ValidateTexImageFormatAndType(format, type, WebGLTexImageFunc::TexImage))
return;
if (level < 0)
return ErrorInvalidValue("texSubImage2D: level is negative");
const int32_t maxLevel = MaxTextureLevelForTexImageTarget(texImageTarget);
if (level > maxLevel)
return ErrorInvalidValue("texSubImage2D: level %d is too large, max is %d", level, maxLevel);
// Trying to handle the video by GPU directly first
if (TexImageFromVideoElement(target, level, format, format, type, elt)) {
if (TexImageFromVideoElement(texImageTarget, level, format, format, type, elt)) {
return;
}
@ -556,7 +570,7 @@ public:
gfx::IntSize size = data->GetSize();
uint32_t byteLength = data->Stride() * size.height;
return TexSubImage2D_base(target, level, xoffset, yoffset,
return TexSubImage2D_base(texImageTarget, level, xoffset, yoffset,
size.width, size.height,
data->Stride(), format, type,
data->GetData(), byteLength,

Просмотреть файл

@ -2964,7 +2964,6 @@ WebCryptoTask::CreateUnwrapKeyTask(JSContext* aCx,
}
return new FailureTask(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
}
} // namespace dom

Просмотреть файл

@ -103,7 +103,7 @@ GetJSValFromKeyPathString(JSContext* aCx,
NS_ASSERTION(!token.IsEmpty(), "Should be a valid keypath");
const jschar* keyPathChars = token.BeginReading();
const char16_t* keyPathChars = token.BeginReading();
const size_t keyPathLen = token.Length();
bool hasProp;

Просмотреть файл

@ -651,7 +651,8 @@ ContentParent::GetNewOrPreallocatedAppProcess(mozIApplication* aApp,
NS_ERROR("Failed to get manifest URL");
return nullptr;
}
process->TransformPreallocatedIntoApp(manifestURL);
process->TransformPreallocatedIntoApp(aOpener,
manifestURL);
if (aTookPreAllocated) {
*aTookPreAllocated = true;
}
@ -799,15 +800,9 @@ ContentParent::GetNewOrUsedBrowserProcess(bool aForBrowserElement,
// Try to take and transform the preallocated process into browser.
nsRefPtr<ContentParent> p = PreallocatedProcessManager::Take();
if (p) {
p->TransformPreallocatedIntoBrowser();
p->TransformPreallocatedIntoBrowser(aOpener);
} else {
// Failed in using the preallocated process: fork from the chrome process.
#ifdef MOZ_NUWA_PROCESS
if (Preferences::GetBool("dom.ipc.processPrelaunch.enabled", false)) {
// Wait until the Nuwa process forks a new process.
return nullptr;
}
#endif
p = new ContentParent(/* app = */ nullptr,
aOpener,
aForBrowserElement,
@ -898,7 +893,10 @@ ContentParent::RecvCreateChildProcess(const IPCTabContext& aContext,
}
if (!cp) {
return false;
*aId = 0;
*aIsForApp = false;
*aIsForBrowser = false;
return true;
}
*aId = cp->ChildID();
@ -948,13 +946,15 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext,
nsRefPtr<nsIContentParent> constructorSender;
if (isInContentProcess) {
MOZ_ASSERT(aContext.IsBrowserElement());
constructorSender = CreateContentBridgeParent(aContext, initialPriority);
constructorSender =
CreateContentBridgeParent(aContext, initialPriority);
} else {
if (aOpenerContentParent) {
constructorSender = aOpenerContentParent;
} else {
constructorSender = GetNewOrUsedBrowserProcess(aContext.IsBrowserElement(),
initialPriority);
constructorSender =
GetNewOrUsedBrowserProcess(aContext.IsBrowserElement(),
initialPriority);
}
}
if (constructorSender) {
@ -1149,6 +1149,9 @@ ContentParent::CreateContentBridgeParent(const TabContext& aContext,
&isForBrowser)) {
return nullptr;
}
if (id == 0) {
return nullptr;
}
if (!child->CallBridgeToChildProcess(id)) {
return nullptr;
}
@ -1381,17 +1384,20 @@ TryGetNameFromManifestURL(const nsAString& aManifestURL,
}
void
ContentParent::TransformPreallocatedIntoApp(const nsAString& aAppManifestURL)
ContentParent::TransformPreallocatedIntoApp(ContentParent* aOpener,
const nsAString& aAppManifestURL)
{
MOZ_ASSERT(IsPreallocated());
mOpener = aOpener;
mAppManifestURL = aAppManifestURL;
TryGetNameFromManifestURL(aAppManifestURL, mAppName);
}
void
ContentParent::TransformPreallocatedIntoBrowser()
ContentParent::TransformPreallocatedIntoBrowser(ContentParent* aOpener)
{
// Reset mAppManifestURL, mIsForBrowser and mOSPrivileges for browser.
mOpener = aOpener;
mAppManifestURL.Truncate();
mIsForBrowser = true;
}

Просмотреть файл

@ -363,11 +363,12 @@ private:
// Transform a pre-allocated app process into a "real" app
// process, for the specified manifest URL.
void TransformPreallocatedIntoApp(const nsAString& aAppManifestURL);
void TransformPreallocatedIntoApp(ContentParent* aOpener,
const nsAString& aAppManifestURL);
// Transform a pre-allocated app process into a browser process. If this
// returns false, the child process has died.
void TransformPreallocatedIntoBrowser();
void TransformPreallocatedIntoBrowser(ContentParent* aOpener);
/**
* Mark this ContentParent as dead for the purposes of Get*().

Просмотреть файл

@ -492,7 +492,7 @@ TabChildBase::DispatchMessageManagerMessage(const nsAString& aMessageName,
StructuredCloneData cloneData;
JSAutoStructuredCloneBuffer buffer;
if (JS_ParseJSON(cx,
static_cast<const jschar*>(aJSONData.BeginReading()),
static_cast<const char16_t*>(aJSONData.BeginReading()),
aJSONData.Length(),
&json)) {
WriteStructuredClone(cx, json, buffer, cloneData.mClosure);
@ -747,7 +747,10 @@ TabChild::PreloadSlowThings()
{
MOZ_ASSERT(!sPreallocatedTab);
nsRefPtr<TabChild> tab(new TabChild(ContentChild::GetSingleton(),
// Pass nullptr to aManager since at this point the TabChild is
// not connected to any manager. Any attempt to use the TabChild
// in IPC will crash.
nsRefPtr<TabChild> tab(new TabChild(nullptr,
TabContext(), /* chromeFlags */ 0));
if (!NS_SUCCEEDED(tab->Init()) ||
!tab->InitTabChildGlobal(DONT_LOAD_SCRIPTS)) {
@ -777,7 +780,9 @@ TabChild::PreloadSlowThings()
}
/*static*/ already_AddRefed<TabChild>
TabChild::Create(nsIContentChild* aManager, const TabContext &aContext, uint32_t aChromeFlags)
TabChild::Create(nsIContentChild* aManager,
const TabContext &aContext,
uint32_t aChromeFlags)
{
if (sPreallocatedTab &&
sPreallocatedTab->mChromeFlags == aChromeFlags &&
@ -788,6 +793,7 @@ TabChild::Create(nsIContentChild* aManager, const TabContext &aContext, uint32_t
MOZ_ASSERT(!child->mTriedBrowserInit);
child->mManager = aManager;
child->SetTabContext(aContext);
child->NotifyTabContextUpdated();
return child.forget();
@ -799,7 +805,9 @@ TabChild::Create(nsIContentChild* aManager, const TabContext &aContext, uint32_t
}
TabChild::TabChild(nsIContentChild* aManager, const TabContext& aContext, uint32_t aChromeFlags)
TabChild::TabChild(nsIContentChild* aManager,
const TabContext& aContext,
uint32_t aChromeFlags)
: TabContext(aContext)
, mRemoteFrame(nullptr)
, mManager(aManager)

Просмотреть файл

@ -67,7 +67,8 @@ nsIContentChild::AllocPBrowserChild(const IPCTabContext& aContext,
MOZ_CRASH("Invalid TabContext received from the parent process.");
}
nsRefPtr<TabChild> child = TabChild::Create(this, tc.GetTabContext(), aChromeFlags);
nsRefPtr<TabChild> child =
TabChild::Create(this, tc.GetTabContext(), aChromeFlags);
// The ref here is released in DeallocPBrowserChild.
return child.forget().take();

Просмотреть файл

@ -163,7 +163,7 @@ nsJSON::EncodeToStream(nsIOutputStream *aStream,
}
static bool
WriteCallback(const jschar *buf, uint32_t len, void *data)
WriteCallback(const char16_t *buf, uint32_t len, void *data)
{
nsJSONWriter *writer = static_cast<nsJSONWriter*>(data);
nsresult rv = writer->Write((const char16_t*)buf, (uint32_t)len);
@ -389,7 +389,7 @@ NS_IMETHODIMP
nsJSON::DecodeToJSVal(const nsAString &str, JSContext *cx,
JS::MutableHandle<JS::Value> result)
{
if (!JS_ParseJSON(cx, static_cast<const jschar*>(PromiseFlatString(str).get()),
if (!JS_ParseJSON(cx, static_cast<const char16_t*>(PromiseFlatString(str).get()),
str.Length(), result)) {
return NS_ERROR_UNEXPECTED;
}
@ -525,7 +525,7 @@ nsJSONListener::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext,
JS::Rooted<JS::Value> reviver(mCx, JS::NullValue()), value(mCx);
JS::ConstTwoByteChars chars(reinterpret_cast<const jschar*>(mBufferedChars.Elements()),
JS::ConstTwoByteChars chars(reinterpret_cast<const char16_t*>(mBufferedChars.Elements()),
mBufferedChars.Length());
bool ok = JS_ParseJSONWithReviver(mCx, chars.get(),
uint32_t(mBufferedChars.Length()),

Просмотреть файл

@ -505,15 +505,18 @@ public:
(aVideoSource ? DOMMediaStream::HINT_CONTENTS_VIDEO : 0);
nsRefPtr<nsDOMUserMediaStream> stream = new nsDOMUserMediaStream(aListener,
aAudioSource);
aAudioSource,
aVideoSource);
stream->InitTrackUnionStream(aWindow, hints);
return stream.forget();
}
nsDOMUserMediaStream(GetUserMediaCallbackMediaStreamListener* aListener,
MediaEngineSource *aAudioSource) :
MediaEngineSource *aAudioSource,
MediaEngineSource *aVideoSource) :
mListener(aListener),
mAudioSource(aAudioSource),
mVideoSource(aVideoSource),
mEchoOn(true),
mAgcOn(false),
mNoiseOn(true),
@ -625,12 +628,32 @@ public:
GetStream()->AsProcessedStream()->ForwardTrackEnabled(aID, aEnabled);
}
virtual DOMLocalMediaStream* AsDOMLocalMediaStream()
{
return this;
}
virtual MediaEngineSource* GetMediaEngine(TrackID aTrackID)
{
// MediaEngine supports only one video and on video track now and TrackID is
// fixed in MediaEngine.
if (aTrackID == kVideoTrack) {
return mVideoSource;
}
else if (aTrackID == kAudioTrack) {
return mAudioSource;
}
return nullptr;
}
// The actual MediaStream is a TrackUnionStream. But these resources need to be
// explicitly destroyed too.
nsRefPtr<SourceMediaStream> mSourceStream;
nsRefPtr<MediaInputPort> mPort;
nsRefPtr<GetUserMediaCallbackMediaStreamListener> mListener;
nsRefPtr<MediaEngineSource> mAudioSource; // so we can turn on AEC
nsRefPtr<MediaEngineSource> mVideoSource;
bool mEchoOn;
bool mAgcOn;
bool mNoiseOn;

Просмотреть файл

@ -23,8 +23,8 @@ DialogWatcher.prototype.init = function() {
this.findWindow = user32.declare("FindWindowW",
ctypes.winapi_abi,
ctypes.uintptr_t,
ctypes.jschar.ptr,
ctypes.jschar.ptr);
ctypes.char16_t.ptr,
ctypes.char16_t.ptr);
}
if (!this.winEventProcType) {
this.winEventProcType = ctypes.FunctionType(ctypes.stdcall_abi,
@ -94,7 +94,7 @@ DialogWatcher.prototype.init = function() {
ctypes.winapi_abi,
ctypes.int,
ctypes.uintptr_t,
ctypes.jschar.ptr,
ctypes.char16_t.ptr,
ctypes.int);
}
if (!this.messageBox) {
@ -103,14 +103,14 @@ DialogWatcher.prototype.init = function() {
ctypes.winapi_abi,
ctypes.int,
ctypes.uintptr_t,
ctypes.jschar.ptr,
ctypes.jschar.ptr,
ctypes.char16_t.ptr,
ctypes.char16_t.ptr,
ctypes.uint32_t);
}
};
DialogWatcher.prototype.getWindowText = function(hwnd) {
var bufType = ctypes.ArrayType(ctypes.jschar);
var bufType = ctypes.ArrayType(ctypes.char16_t);
var buffer = new bufType(256);
if (this.getWindowTextW(hwnd, buffer, buffer.length)) {
@ -181,4 +181,3 @@ DialogWatcher.prototype.processWindowEvents = function(timeout) {
// Returns true if the hook was successful, something was found, and we never timed out
return this.hwnd !== undefined && waitStatus == WAIT_OBJECT_0;
};

Просмотреть файл

@ -33,8 +33,8 @@ function initCTypes() {
ctypes.winapi_abi,
ctypes.int,
ctypes.uintptr_t,
ctypes.jschar.ptr,
ctypes.jschar.ptr,
ctypes.char16_t.ptr,
ctypes.char16_t.ptr,
ctypes.uint32_t);
}
if (!watcher) {

Просмотреть файл

@ -1005,19 +1005,13 @@ Promise::MaybeReportRejected()
return;
}
// Remains null in case of worker.
nsCOMPtr<nsPIDOMWindow> win;
bool isChromeError = false;
nsRefPtr<xpc::ErrorReport> xpcReport = new xpc::ErrorReport();
if (MOZ_LIKELY(NS_IsMainThread())) {
nsIPrincipal* principal;
win = xpc::WindowGlobalOrNull(obj);
principal = nsContentUtils::ObjectPrincipal(obj);
isChromeError = nsContentUtils::IsSystemPrincipal(principal);
nsIGlobalObject* global = xpc::GetNativeForGlobal(js::GetGlobalForObjectCrossCompartment(obj));
xpcReport->Init(report.report(), report.message(), global);
} else {
WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(worker);
isChromeError = worker->IsChromeWorker();
xpcReport->InitOnWorkerThread(report.report(), report.message(),
GetCurrentThreadWorkerPrivate()->IsChromeWorker());
}
// Now post an event to do the real reporting async
@ -1025,11 +1019,7 @@ Promise::MaybeReportRejected()
// AsyncErrorReporter, otherwise if the call to DispatchToMainThread fails, it
// will leak. See Bug 958684.
nsRefPtr<AsyncErrorReporter> r =
new AsyncErrorReporter(CycleCollectedJSRuntime::Get()->Runtime(),
report.report(),
report.message(),
isChromeError,
win);
new AsyncErrorReporter(CycleCollectedJSRuntime::Get()->Runtime(), xpcReport);
NS_DispatchToMainThread(r);
}

Просмотреть файл

@ -363,13 +363,14 @@ MozMtpDatabase::CreateEntryForFile(const nsACString& aPath, DeviceStorageFile* a
if (slash == kNotFound) {
component.Rebind(aPath, 0, aPath.Length());
} else {
component.Rebind(aPath, slash, aPath.Length() - slash);
component.Rebind(aPath, 0 , slash);
}
if (doFind) {
MtpObjectHandle entryHandle = FindEntryByPath(component);
if (entryHandle != 0) {
// We found an entry.
parent = entryHandle;
offset = slash + 1 ;
continue;
}
}
@ -408,6 +409,7 @@ MozMtpDatabase::CreateEntryForFile(const nsACString& aPath, DeviceStorageFile* a
AddEntry(entry);
parent = entry->mHandle;
offset = slash + 1;
} while (slash != kNotFound);
return parent; // parent will be entry->mHandle

Просмотреть файл

@ -163,7 +163,7 @@ void LossyConvertUTF8toUTF16(const char* aInput, uint32_t aLength, nsAString& aO
char16_t dst[aLength]; // Allocating for worst case.
// First, count how many jschars need to be in the inflated string.
// Count how many char16_t characters are needed in the inflated string.
// |i| is the index into |src|, and |j| is the the index into |dst|.
size_t srclen = src.length();
uint32_t j = 0;
@ -214,20 +214,20 @@ void LossyConvertUTF8toUTF16(const char* aInput, uint32_t aLength, nsAString& aO
if ((src[i + m] & 0xC0) != 0x80)
INVALID(ReportInvalidCharacter, i, m);
// Determine the code unit's length in jschars and act accordingly.
// Determine the code unit's length in char16_t units and act accordingly.
v = JS::Utf8ToOneUcs4Char((uint8_t *)&src[i], n);
if (v < 0x10000) {
// The n-byte UTF8 code unit will fit in a single jschar.
dst[j] = jschar(v);
// The n-byte UTF8 code unit will fit in a single char16_t.
dst[j] = char16_t(v);
} else {
v -= 0x10000;
if (v <= 0xFFFFF) {
// The n-byte UTF8 code unit will fit in two jschars.
dst[j] = jschar((v >> 10) + 0xD800);
// The n-byte UTF8 code unit will fit in two char16_t units.
dst[j] = char16_t((v >> 10) + 0xD800);
j++;
dst[j] = jschar((v & 0x3FF) + 0xDC00);
dst[j] = char16_t((v & 0x3FF) + 0xDC00);
} else {
// The n-byte UTF8 code unit won't fit in two jschars.
// The n-byte UTF8 code unit won't fit in two char16_t units.
INVALID(ReportTooBigCharacter, v, 1);
}
}

Просмотреть файл

@ -21,7 +21,7 @@ namespace {
#ifdef BUILD_CTYPES
char*
UnicodeToNative(JSContext* aCx, const jschar* aSource, size_t aSourceLen)
UnicodeToNative(JSContext* aCx, const char16_t* aSource, size_t aSourceLen)
{
nsDependentString unicode(aSource, aSourceLen);

Просмотреть файл

@ -737,8 +737,8 @@ GetPrincipalForAsmJSCacheOp()
static bool
AsmJSCacheOpenEntryForRead(JS::Handle<JSObject*> aGlobal,
const jschar* aBegin,
const jschar* aLimit,
const char16_t* aBegin,
const char16_t* aLimit,
size_t* aSize,
const uint8_t** aMemory,
intptr_t *aHandle)
@ -755,8 +755,8 @@ AsmJSCacheOpenEntryForRead(JS::Handle<JSObject*> aGlobal,
static bool
AsmJSCacheOpenEntryForWrite(JS::Handle<JSObject*> aGlobal,
bool aInstalled,
const jschar* aBegin,
const jschar* aEnd,
const char16_t* aBegin,
const char16_t* aEnd,
size_t aSize,
uint8_t** aMemory,
intptr_t* aHandle)

Просмотреть файл

@ -156,7 +156,7 @@ struct ScriptLoadInfo
nsString mURL;
nsCOMPtr<nsIChannel> mChannel;
jschar* mScriptTextBuf;
char16_t* mScriptTextBuf;
size_t mScriptTextLength;
nsresult mLoadResult;

Просмотреть файл

@ -337,7 +337,7 @@ nsXBLProtoImpl::UndefineFields(JSContext *cx, JS::Handle<JSObject*> obj) const
for (nsXBLProtoImplField* f = mFields; f; f = f->GetNext()) {
nsDependentString name(f->GetName());
const jschar* s = name.get();
const char16_t* s = name.get();
bool hasProp;
if (::JS_AlreadyHasOwnUCProperty(cx, obj, s, name.Length(), &hasProp) &&
hasProp) {

Просмотреть файл

@ -445,7 +445,7 @@ nsXBLProtoImplField::InstallField(JS::Handle<JSObject*> aBoundNode,
nsDependentString name(mName);
if (!JS_WrapValue(cx, &result) ||
!::JS_DefineUCProperty(cx, aBoundNode,
reinterpret_cast<const jschar*>(mName),
reinterpret_cast<const char16_t*>(mName),
name.Length(), result, mJSAttributes)) {
return NS_ERROR_OUT_OF_MEMORY;
}

Просмотреть файл

@ -115,7 +115,7 @@ nsXBLProtoImplMethod::InstallMember(JSContext* aCx,
NS_ENSURE_TRUE(method, NS_ERROR_OUT_OF_MEMORY);
if (!::JS_DefineUCProperty(aCx, aTargetClassObject,
static_cast<const jschar*>(mName),
static_cast<const char16_t*>(mName),
name.Length(), method,
JSPROP_ENUMERATE)) {
return NS_ERROR_OUT_OF_MEMORY;

Просмотреть файл

@ -147,7 +147,7 @@ nsXBLProtoImplProperty::InstallMember(JSContext *aCx,
nsDependentString name(mName);
if (!::JS_DefineUCProperty(aCx, aTargetClassObject,
static_cast<const jschar*>(mName),
static_cast<const char16_t*>(mName),
name.Length(), JS::UndefinedHandleValue, mJSAttributes,
JS_DATA_TO_FUNC_PTR(JSPropertyOp, getter.get()),
JS_DATA_TO_FUNC_PTR(JSStrictPropertyOp, setter.get())))

Просмотреть файл

@ -49,12 +49,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=502673
}
},
QueryInterface: function(iid) {
QueryInterface: SpecialPowers.wrapCallback(function(iid) {
if (iid.equals(SpecialPowers.Ci.nsIDocumentStateListener) ||
iid.equals(SpecialPowers.Ci.nsISupports))
return this;
throw SpecialPowers.Cr.NS_ERROR_NO_INTERFACE;
},
}),
};
function doTest() {

Просмотреть файл

@ -0,0 +1,8 @@
[DEFAULT]
skip-if = buildapp == 'b2g'
support-files =
320x240.ogv
bug449141_page.html
[test_bug449141.html]
skip-if = toolkit == 'android'

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше