Merge mozilla-central to fx-team

This commit is contained in:
Carsten "Tomcat" Book 2015-01-22 14:46:42 +01:00
Родитель c993303a3d fbdef879d2
Коммит f5994ff800
187 изменённых файлов: 4746 добавлений и 4529 удалений

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

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 1115998 - (DOMString or sequence<DOMString>) needs binding flush (Bug 1103153)
Bug 1006707 - (DOMString or sequence<DOMString>) needs binding flush (Bug 1103153)

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e06971db7acf7a35c32eb74d675a4e12e288e6be">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="917b6c36717fddc6e71ffc1ec249633c8044c93c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="966b3a7a13a7f0d5b86cbc9e64cb78d43ec7dba8"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

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

@ -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="917b6c36717fddc6e71ffc1ec249633c8044c93c"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="966b3a7a13a7f0d5b86cbc9e64cb78d43ec7dba8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>

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

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="917b6c36717fddc6e71ffc1ec249633c8044c93c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="966b3a7a13a7f0d5b86cbc9e64cb78d43ec7dba8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="fe91ec3af5396edab45b15e546e21613785724b5"/>

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e06971db7acf7a35c32eb74d675a4e12e288e6be">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="917b6c36717fddc6e71ffc1ec249633c8044c93c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="966b3a7a13a7f0d5b86cbc9e64cb78d43ec7dba8"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

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

@ -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="917b6c36717fddc6e71ffc1ec249633c8044c93c"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="966b3a7a13a7f0d5b86cbc9e64cb78d43ec7dba8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e06971db7acf7a35c32eb74d675a4e12e288e6be">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="917b6c36717fddc6e71ffc1ec249633c8044c93c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="966b3a7a13a7f0d5b86cbc9e64cb78d43ec7dba8"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

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

@ -17,7 +17,7 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="917b6c36717fddc6e71ffc1ec249633c8044c93c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="966b3a7a13a7f0d5b86cbc9e64cb78d43ec7dba8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="fe91ec3af5396edab45b15e546e21613785724b5"/>

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

@ -1,9 +1,9 @@
{
"git": {
"git_revision": "917b6c36717fddc6e71ffc1ec249633c8044c93c",
"git_revision": "966b3a7a13a7f0d5b86cbc9e64cb78d43ec7dba8",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
"revision": "3033c2214b5863d8ac50d2067b34c5cb02fb054d",
"revision": "9a9aef701b1c69e9fb76eb3cc629be10aecfa3f3",
"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="917b6c36717fddc6e71ffc1ec249633c8044c93c"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="966b3a7a13a7f0d5b86cbc9e64cb78d43ec7dba8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>

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

@ -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="917b6c36717fddc6e71ffc1ec249633c8044c93c"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="966b3a7a13a7f0d5b86cbc9e64cb78d43ec7dba8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

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

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="917b6c36717fddc6e71ffc1ec249633c8044c93c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="966b3a7a13a7f0d5b86cbc9e64cb78d43ec7dba8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="fe91ec3af5396edab45b15e546e21613785724b5"/>

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

@ -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="917b6c36717fddc6e71ffc1ec249633c8044c93c"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="966b3a7a13a7f0d5b86cbc9e64cb78d43ec7dba8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

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

@ -1703,7 +1703,7 @@ pref("plain_text.wrap_long_lines", true);
pref("dom.debug.propagate_gesture_events_through_content", false);
// The request URL of the GeoLocation backend.
pref("geo.wifi.uri", "https://www.googleapis.com/geolocation/v1/geolocate?key=%GOOGLE_API_KEY%");
pref("geo.wifi.uri", "https://location.services.mozilla.com/v1/geolocate?key=%MOZILLA_API_KEY%");
// Necko IPC security checks only needed for app isolation for cookies/cache/etc:
// currently irrelevant for desktop e10s

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

@ -240,16 +240,11 @@ SearchSuggestionUIController.prototype = {
// Commit composition string forcibly, because setting input value does not
// work if input has composition string (see bug 1115616 and bug 632744).
try {
let imeEditor = this.input.editor.QueryInterface(Components.interfaces.nsIEditorIMESupport);
if (imeEditor.composing) {
// Ignore input event for compisition end to avoid getting suggestion
// again.
this._ignoreInputEvent = true;
imeEditor.forceCompositionEnd();
this._ignoreInputEvent = false;
}
} catch(e) { }
// Ignore input event for composition end to avoid getting suggestion again.
this._ignoreInputEvent = true;
this.input.blur();
this.input.focus();
this._ignoreInputEvent = false;
this.input.value = suggestion;
this.input.setAttribute("selection-index", idx);

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

@ -380,6 +380,56 @@ let gTests = [
});
}
},
{
desc: "Clicking suggestion list while composing",
setup: function() {},
run: function()
{
return Task.spawn(function* () {
// Start composition and type "x"
let input = gBrowser.contentDocument.getElementById("searchText");
input.focus();
EventUtils.synthesizeComposition({ type: "compositionstart", data: "" });
EventUtils.synthesizeComposition({ type: "compositionupdate", data: "x" });
EventUtils.synthesizeCompositionChange({
composition: {
string: "x",
clauses: [
{ length: 1, attr: EventUtils.COMPOSITION_ATTR_RAWINPUT }
]
},
caret: { start: 1, length: 0 }
});
// Wait for the search suggestions to become visible.
let table =
gBrowser.contentDocument.getElementById("searchSuggestionTable");
let deferred = Promise.defer();
let observer = new MutationObserver(() => {
if (input.getAttribute("aria-expanded") == "true") {
observer.disconnect();
ok(!table.hidden, "Search suggestion table unhidden");
deferred.resolve();
}
});
observer.observe(input, {
attributes: true,
attributeFilter: ["aria-expanded"],
});
yield deferred.promise;
// Click the second suggestion.
let expectedURL = Services.search.currentEngine.
getSubmission("xbar", null, "homepage").
uri.spec;
let loadPromise = waitForDocLoadAndStopIt(expectedURL);
let row = table.children[1];
EventUtils.sendMouseEvent({ type: "mousedown" }, row, gBrowser.contentWindow);
yield loadPromise;
ok(input.value == "xbar", "Suggestion is selected");
});
}
},
{
desc: "Cmd+k should focus the search box in the page when the search box in the toolbar is absent",
setup: function () {

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

@ -411,7 +411,7 @@ pref("privacy.sanitize.migrateFx3Prefs", false);
// enable geo
pref("geo.enabled", true);
pref("geo.wifi.uri", "https://www.googleapis.com/geolocation/v1/geolocate?key=%GOOGLE_API_KEY%");
pref("geo.wifi.uri", "https://location.services.mozilla.com/v1/geolocate?key=%MOZILLA_API_KEY%");
// snapped view
pref("browser.ui.snapped.maxWidth", 600);

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

@ -12871,9 +12871,16 @@ nsDocShell::GetTopFrameElement(nsIDOMElement** aElement)
win->GetScriptableTop(getter_AddRefs(top));
NS_ENSURE_TRUE(top, NS_ERROR_FAILURE);
// GetFrameElement, /not/ GetScriptableFrameElement -- if |top| is inside
// <iframe mozbrowser>, we want to return the iframe, not null.
return top->GetFrameElement(aElement);
nsCOMPtr<nsPIDOMWindow> piTop = do_QueryInterface(top);
NS_ENSURE_TRUE(piTop, NS_ERROR_FAILURE);
// GetFrameElementInternal, /not/ GetScriptableFrameElement -- if |top| is
// inside <iframe mozbrowser>, we want to return the iframe, not null.
// And we want to cross the content/chrome boundary.
nsCOMPtr<nsIDOMElement> elt =
do_QueryInterface(piTop->GetFrameElementInternal());
elt.forget(aElement);
return NS_OK;
}
NS_IMETHODIMP

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

@ -35,11 +35,14 @@ interface nsILoadContext : nsISupports
readonly attribute nsIDOMWindow topWindow;
/**
* topFrameElement is the <iframe> or <frame> element which contains the
* topWindow with which the load is associated.
* topFrameElement is the <iframe>, <frame>, or <browser> element which
* contains the topWindow with which the load is associated.
*
* Note that we may have a topFrameElement even when we don't have an
* associatedWindow, if the topFrameElement's content lives out of process.
* topFrameElement is available in single-process and multiprocess contexts.
* Note that topFrameElement may be in chrome even when the nsILoadContext is
* associated with content.
*/
readonly attribute nsIDOMElement topFrameElement;

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

@ -3617,7 +3617,7 @@ nsDocument::SetBaseURI(nsIURI* aURI)
nsCOMPtr<nsIContentSecurityPolicy> csp;
nsresult rv = NodePrincipal()->GetCsp(getter_AddRefs(csp));
NS_ENSURE_SUCCESS(rv, rv);
if (csp) {
if (csp && aURI) {
bool permitsBaseURI = false;
// base-uri is only enforced if explicitly defined in the

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

@ -99,10 +99,6 @@ public:
bool IsParentActivated()
{
if (mParentFocusType == ParentFocusType_Ignore) {
return mActiveWindow != nullptr;
}
return mParentFocusType == ParentFocusType_Active;
}

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

@ -13266,7 +13266,12 @@ nsGlobalWindow::AddSizeOfIncludingThis(nsWindowSizes* aWindowSizes) const
elm->ListenerCount();
}
if (mDoc) {
mDoc->DocAddSizeOfIncludingThis(aWindowSizes);
// Multiple global windows can share a document. So only measure the
// document if it (a) doesn't have a global window, or (b) it's the
// primary document for the window.
if (!mDoc->GetInnerWindow() || mDoc->GetInnerWindow() == this) {
mDoc->DocAddSizeOfIncludingThis(aWindowSizes);
}
}
}

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

@ -365,7 +365,7 @@ nsresult TestPaths() {
{ "connect-src http://www.example.com/foo%3bsessionid=12%2c34",
"connect-src http://www.example.com/foo;sessionid=12,34" },
{ "connect-src http://test.com/pathIncludingAz19-._~!$&'()*+=:@",
"connect-src http://test.com/pathincludingaz19-._~!$&'()*+=:@" },
"connect-src http://test.com/pathIncludingAz19-._~!$&'()*+=:@" },
{ "script-src http://www.example.com:88/.js",
"script-src http://www.example.com:88/.js" },
{ "script-src https://foo.com/_abc/abc_/_/_a_b_c_",

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

@ -62,6 +62,12 @@ var policies = [
["blocked", "test1.example.com:8888/tests"],
["blocked", "test1.example.com:8888/tests/dom/base/test/csp"],
["blocked", "test1.example.com:8888/tests/dom/base/test/csp/file_csp_path_matching.py"],
// case insensitive matching for scheme and host, but case sensitive matching for paths
["allowed", "HTTP://test1.EXAMPLE.com/tests/"],
["allowed", "test1.EXAMPLE.com/tests/"],
["blocked", "test1.example.com/tests/dom/base/test/CSP/?foo=val"],
["blocked", "test1.example.com/tests/dom/base/test/csp/FILE_csp_path_matching.js?foo=val"],
]
var counter = 0;

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

@ -2995,16 +2995,7 @@ CanvasRenderingContext2D::SetFont(const nsAString& font,
const nsStyleFont* fontStyle = sc->StyleFont();
nsIAtom* language = fontStyle->mLanguage;
if (!language) {
language = presShell->GetPresContext()->GetLanguageFromCharset();
}
// use CSS pixels instead of dev pixels to avoid being affected by page zoom
const uint32_t aupcp = nsPresContext::AppUnitsPerCSSPixel();
bool printerFont = (presShell->GetPresContext()->Type() == nsPresContext::eContext_PrintPreview ||
presShell->GetPresContext()->Type() == nsPresContext::eContext_Print);
nsPresContext *c = presShell->GetPresContext();
// Purposely ignore the font size that respects the user's minimum
// font preference (fontStyle->mFont.size) in favor of the computed
@ -3012,28 +3003,28 @@ CanvasRenderingContext2D::SetFont(const nsAString& font,
// https://bugzilla.mozilla.org/show_bug.cgi?id=698652.
MOZ_ASSERT(!fontStyle->mAllowZoom,
"expected text zoom to be disabled on this nsStyleFont");
gfxFontStyle style(fontStyle->mFont.style,
fontStyle->mFont.weight,
fontStyle->mFont.stretch,
NSAppUnitsToFloatPixels(fontStyle->mSize, float(aupcp)),
language,
fontStyle->mExplicitLanguage,
fontStyle->mFont.sizeAdjust,
fontStyle->mFont.systemFont,
printerFont,
fontStyle->mFont.synthesis & NS_FONT_SYNTHESIS_WEIGHT,
fontStyle->mFont.synthesis & NS_FONT_SYNTHESIS_STYLE,
fontStyle->mFont.languageOverride);
nsFont resizedFont(fontStyle->mFont);
// Create a font group working in units of CSS pixels instead of the usual
// device pixels, to avoid being affected by page zoom. nsFontMetrics will
// convert nsFont size in app units to device pixels for the font group, so
// here we first apply to the size the equivalent of a conversion from device
// pixels to CSS pixels, to adjust for the difference in expectations from
// other nsFontMetrics clients.
resizedFont.size =
(fontStyle->mSize * c->AppUnitsPerDevPixel()) / c->AppUnitsPerCSSPixel();
fontStyle->mFont.AddFontFeaturesToStyle(&style);
nsRefPtr<nsFontMetrics> metrics;
c->DeviceContext()->GetMetricsFor(resizedFont,
fontStyle->mLanguage,
fontStyle->mExplicitLanguage,
gfxFont::eHorizontal,
c->GetUserFontSet(),
c->GetTextPerfMetrics(),
*getter_AddRefs(metrics));
nsPresContext *c = presShell->GetPresContext();
CurrentState().fontGroup =
gfxPlatform::GetPlatform()->CreateFontGroup(fontStyle->mFont.fontlist,
&style,
c->GetUserFontSet());
gfxFontGroup* newFontGroup = metrics->GetThebesFontGroup();
CurrentState().fontGroup = newFontGroup;
NS_ASSERTION(CurrentState().fontGroup, "Could not get font group");
CurrentState().fontGroup->SetTextPerfMetrics(c->GetTextPerfMetrics());
CurrentState().font = usedFont;
CurrentState().fontFont = fontStyle->mFont;
CurrentState().fontFont.size = fontStyle->mSize;

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

@ -90,9 +90,12 @@ ContactManager.prototype = {
},
_convertContact: function(aContact) {
let contact = Cu.cloneInto(aContact, this._window);
let newContact = new this._window.mozContact(contact.properties);
newContact.setMetadata(contact.id, contact.published, contact.updated);
let properties = aContact.properties;
if (properties.photo && properties.photo.length) {
properties.photo = Cu.cloneInto(properties.photo, this._window);
}
let newContact = new this._window.mozContact(aContact.properties);
newContact.setMetadata(aContact.id, aContact.published, aContact.updated);
return newContact;
},

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

@ -458,6 +458,10 @@ FORWARDED_EVENT(load,
NS_LOAD,
EventNameType_All,
eBasicEventClass)
FORWARDED_EVENT(resize,
NS_RESIZE_EVENT,
EventNameType_All,
eBasicEventClass)
FORWARDED_EVENT(scroll,
NS_SCROLL_EVENT,
(EventNameType_HTMLXUL | EventNameType_SVGSVG),
@ -512,11 +516,6 @@ WINDOW_EVENT(popstate,
eBasicEventClass)
// Not supported yet
// WINDOW_EVENT(redo)
WINDOW_EVENT(resize,
NS_RESIZE_EVENT,
(EventNameType_XUL | EventNameType_SVGSVG |
EventNameType_HTMLBodyOrFramesetOnly),
eBasicEventClass)
// Not supported yet
// WINDOW_EVENT(storage)
// Not supported yet

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

@ -16,6 +16,7 @@
#include "mozilla/TextComposition.h"
#include "mozilla/TextEvents.h"
#include "mozilla/dom/HTMLFormElement.h"
#include "mozilla/dom/TabParent.h"
#include "HTMLInputElement.h"
#include "IMEContentObserver.h"
@ -388,6 +389,27 @@ IMEStateManager::OnChangeFocusInternal(nsPresContext* aPresContext,
}
IMEState newState = GetNewIMEState(aPresContext, aContent);
// In e10s, remote content may have IME focus. The main process (i.e. this process)
// would attempt to set state to DISABLED if, for example, the user clicks
// some other remote content. The content process would later re-ENABLE IME, meaning
// that all state-changes were unnecessary.
// Here we filter the common case where the main process knows that the remote
// process controls IME focus. The DISABLED->re-ENABLED progression can
// still happen since remote content may be concurrently communicating its claim
// on focus to the main process... but this cannot cause bugs like missed keypresses.
// (It just means a lot of needless IPC.)
if ((newState.mEnabled == IMEState::DISABLED) && TabParent::GetIMETabParent()) {
PR_LOG(sISMLog, PR_LOG_DEBUG,
("ISM: IMEStateManager::OnChangeFocusInternal(), "
"Parent process cancels to set DISABLED state because the content process "
"has IME focus and has already sets IME state"));
MOZ_ASSERT(XRE_IsParentProcess(),
"TabParent::GetIMETabParent() should never return non-null value "
"in the content process");
return NS_OK;
}
if (!focusActuallyChanging) {
// actual focus isn't changing, but if IME enabled state is changing,
// we should do it.

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

@ -527,14 +527,14 @@ HTMLMediaElement::GetMozSrcObject() const
void
HTMLMediaElement::SetMozSrcObject(DOMMediaStream& aValue)
{
mSrcAttrStream = &aValue;
Load();
SetMozSrcObject(&aValue);
}
void
HTMLMediaElement::SetMozSrcObject(DOMMediaStream* aValue)
{
SetMozSrcObject(*aValue);
mSrcAttrStream = aValue;
Load();
}
/* readonly attribute nsIDOMHTMLMediaElement mozAutoplayEnabled; */
@ -2524,15 +2524,13 @@ nsresult HTMLMediaElement::BindToTree(nsIDocument* aDocument, nsIContent* aParen
// It's value may have changed, so update it.
UpdatePreloadAction();
}
mElementInTreeState = ELEMENT_INTREE;
if (mDecoder) {
// When the MediaElement is binding to tree, the dormant status is
// aligned to document's hidden status.
nsIDocument* ownerDoc = OwnerDoc();
if (ownerDoc) {
mDecoder->SetDormantIfNecessary(ownerDoc->Hidden());
}
mDecoder->NotifyOwnerActivityChanged();
}
mElementInTreeState = ELEMENT_INTREE;
return rv;
}
@ -2543,12 +2541,14 @@ void HTMLMediaElement::UnbindFromTree(bool aDeep,
if (!mPaused && mNetworkState != nsIDOMHTMLMediaElement::NETWORK_EMPTY)
Pause();
if (mDecoder) {
mDecoder->SetDormantIfNecessary(true);
}
mElementInTreeState = ELEMENT_NOT_INTREE_HAD_INTREE;
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
if (mDecoder) {
MOZ_ASSERT(IsHidden());
mDecoder->NotifyOwnerActivityChanged();
}
}
/* static */
@ -3002,6 +3002,10 @@ void HTMLMediaElement::MetadataLoaded(const MediaInfo* aInfo,
mLoadedDataFired = false;
ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_METADATA);
DispatchAsyncEvent(NS_LITERAL_STRING("durationchange"));
if (IsVideo() && mHasVideo) {
mMediaSize = aInfo->mVideo.mDisplay;
DispatchAsyncEvent(NS_LITERAL_STRING("resize"));
}
DispatchAsyncEvent(NS_LITERAL_STRING("loadedmetadata"));
if (mDecoder && mDecoder->IsTransportSeekable() && mDecoder->IsMediaSeekable()) {
ProcessMediaFragmentURI();
@ -3519,6 +3523,21 @@ void HTMLMediaElement::CheckAutoplayDataReady()
}
}
bool HTMLMediaElement::IsActive()
{
nsIDocument* ownerDoc = OwnerDoc();
return ownerDoc && ownerDoc->IsActive() && ownerDoc->IsVisible();
}
bool HTMLMediaElement::IsHidden()
{
if (mElementInTreeState == ELEMENT_NOT_INTREE_HAD_INTREE) {
return true;
}
nsIDocument* ownerDoc = OwnerDoc();
return !ownerDoc || ownerDoc->Hidden();
}
VideoFrameContainer* HTMLMediaElement::GetVideoFrameContainer()
{
if (mVideoFrameContainer)
@ -3642,6 +3661,10 @@ void HTMLMediaElement::NotifyDecoderPrincipalChanged()
void HTMLMediaElement::UpdateMediaSize(nsIntSize size)
{
if (IsVideo() && mReadyState != HAVE_NOTHING && mMediaSize != size) {
DispatchAsyncEvent(NS_LITERAL_STRING("resize"));
}
mMediaSize = size;
UpdateReadyStateForData(mLastNextFrameStatus);
}
@ -3698,15 +3721,7 @@ void HTMLMediaElement::NotifyOwnerDocumentActivityChanged()
if (mDecoder) {
mDecoder->SetElementVisibility(!ownerDoc->Hidden());
if (mElementInTreeState == ELEMENT_NOT_INTREE_HAD_INTREE) {
mDecoder->SetDormantIfNecessary(true);
} else if (mElementInTreeState == ELEMENT_NOT_INTREE ||
mElementInTreeState == ELEMENT_INTREE) {
// The MediaElement had never been binded to tree, or in the tree now,
// align to document.
mDecoder->SetDormantIfNecessary(ownerDoc->Hidden());
}
mDecoder->NotifyOwnerActivityChanged();
}
// SetVisibilityState will update mMuted with MUTED_BY_AUDIO_CHANNEL via the
@ -3716,10 +3731,9 @@ void HTMLMediaElement::NotifyOwnerDocumentActivityChanged()
AutoNoJSAPI nojsapi;
mAudioChannelAgent->SetVisibilityState(!ownerDoc->Hidden());
}
bool suspendEvents = !ownerDoc->IsActive() || !ownerDoc->IsVisible();
bool pauseElement = suspendEvents || (mMuted & MUTED_BY_AUDIO_CHANNEL);
bool pauseElement = !IsActive() || (mMuted & MUTED_BY_AUDIO_CHANNEL);
SuspendOrResumeElement(pauseElement, suspendEvents);
SuspendOrResumeElement(pauseElement, !IsActive());
AddRemoveSelfReference();
}

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

@ -211,6 +211,10 @@ public:
// suspended the channel.
virtual void NotifySuspendedByCache(bool aIsSuspended) MOZ_FINAL MOZ_OVERRIDE;
virtual bool IsActive() MOZ_FINAL MOZ_OVERRIDE;
virtual bool IsHidden() MOZ_FINAL MOZ_OVERRIDE;
// Called by the media decoder and the video frame to get the
// ImageContainer containing the video data.
virtual VideoFrameContainer* GetVideoFrameContainer() MOZ_FINAL MOZ_OVERRIDE;
@ -374,7 +378,7 @@ public:
// Called by the media decoder object, on the main thread,
// when the connection between Rtsp server and client gets lost.
void ResetConnectionState() MOZ_FINAL MOZ_OVERRIDE;
virtual void ResetConnectionState() MOZ_FINAL MOZ_OVERRIDE;
// XPCOM GetPreload() is OK
void SetPreload(const nsAString& aValue, ErrorResult& aRv)

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

@ -8,7 +8,7 @@
interface nsIDocument;
interface nsIURI;
[builtinclass, uuid(d6a9d4b6-39b0-4cd2-957d-28a57df5a031)]
[builtinclass, uuid(d4367ffe-e435-4195-95f8-0a51b1bbfdfb)]
interface nsIServiceWorkerUnregisterCallback : nsISupports
{
// aState is true if the unregistration succeded.
@ -28,7 +28,7 @@ interface nsIServiceWorkerManager : nsISupports
*
* Returns a Promise.
*/
nsISupports register(in DOMString aScope, in DOMString aScriptURI);
nsISupports register(in nsIDOMWindow aWindow, in DOMString aScope, in DOMString aScriptURI);
/**
* Unregister an existing ServiceWorker registration for `aScope`.

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

@ -3337,7 +3337,6 @@ BlobChild::GetOrCreateFromImpl(ChildManagerType* aManager,
ParentBlobConstructorParams params(blobParams);
if (NS_WARN_IF(!aManager->SendPBlobConstructor(actor, params))) {
BlobChild::Destroy(actor);
return nullptr;
}
@ -3402,7 +3401,6 @@ BlobChild::SendSliceConstructor(ChildManagerType* aManager,
return newActor;
}
BlobChild::Destroy(newActor);
return nullptr;
}
@ -3888,7 +3886,6 @@ BlobParent::GetOrCreateFromImpl(ParentManagerType* aManager,
ChildBlobConstructorParams params(id, blobParams);
if (NS_WARN_IF(!aManager->SendPBlobConstructor(actor, params))) {
BlobParent::Destroy(actor);
return nullptr;
}
@ -4051,7 +4048,6 @@ BlobParent::SendSliceConstructor(
return newActor;
}
BlobParent::Destroy(newActor);
return nullptr;
}

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

@ -2028,14 +2028,25 @@ TabParent::RecvSetInputContext(const int32_t& aIMEEnabled,
const int32_t& aCause,
const int32_t& aFocusChange)
{
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget || !AllowContentIME()) {
return true;
}
InputContext oldContext = widget->GetInputContext();
// Ignore if current widget IME setting is not DISABLED and didn't come
// from remote content. Chrome content may have taken over.
if (oldContext.mIMEState.mEnabled != IMEState::DISABLED &&
oldContext.IsOriginMainProcess()) {
return true;
}
// mIMETabParent (which is actually static) tracks which if any TabParent has IMEFocus
// When the input mode is set to anything but IMEState::DISABLED,
// mIMETabParent should be set to this
mIMETabParent =
aIMEEnabled != static_cast<int32_t>(IMEState::DISABLED) ? this : nullptr;
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget || !AllowContentIME())
return true;
InputContext context;
context.mIMEState.mEnabled = static_cast<IMEState::Enabled>(aIMEEnabled);
@ -2043,6 +2054,8 @@ TabParent::RecvSetInputContext(const int32_t& aIMEEnabled,
context.mHTMLInputType.Assign(aType);
context.mHTMLInputInputmode.Assign(aInputmode);
context.mActionHint.Assign(aActionHint);
context.mOrigin = InputContext::ORIGIN_CONTENT;
InputContextAction action(
static_cast<InputContextAction::Cause>(aCause),
static_cast<InputContextAction::FocusChange>(aFocusChange));

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

@ -22,11 +22,9 @@ class SoundTouch;
namespace mozilla {
template<>
struct DefaultDelete<cubeb_stream>
struct DestroyPolicy
{
void operator()(cubeb_stream* aStream) const
{
void operator()(cubeb_stream* aStream) const {
cubeb_stream_destroy(aStream);
}
};
@ -362,7 +360,7 @@ private:
CircularByteBuffer mBuffer;
// Owning reference to a cubeb_stream.
UniquePtr<cubeb_stream> mCubebStream;
UniquePtr<cubeb_stream, DestroyPolicy> mCubebStream;
uint32_t mBytesPerFrame;

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

@ -118,7 +118,7 @@ NS_IMPL_ISUPPORTS(MediaMemoryTracker, nsIMemoryReporter)
NS_IMPL_ISUPPORTS(MediaDecoder, nsIObserver)
void MediaDecoder::SetDormantIfNecessary(bool aDormant)
void MediaDecoder::NotifyOwnerActivityChanged()
{
MOZ_ASSERT(NS_IsMainThread());
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
@ -129,7 +129,28 @@ void MediaDecoder::SetDormantIfNecessary(bool aDormant)
return;
}
if(aDormant) {
if (!mOwner) {
NS_WARNING("MediaDecoder without a decoder owner, can't update dormant");
return;
}
bool prevDormant = mIsDormant;
mIsDormant = false;
if (!mOwner->IsActive() && mOwner->GetVideoFrameContainer()) {
mIsDormant = true;
}
#ifdef MOZ_WIDGET_GONK
if (mOwner->IsHidden() && mOwner->GetVideoFrameContainer()) {
mIsDormant = true;
}
#endif
if (prevDormant == mIsDormant) {
// No update to dormant state
return;
}
if (mIsDormant) {
// enter dormant state
mDecoderStateMachine->SetDormant(true);
@ -450,7 +471,8 @@ MediaDecoder::MediaDecoder() :
mShuttingDown(false),
mPausedForPlaybackRateNull(false),
mMinimizePreroll(false),
mMediaTracksConstructed(false)
mMediaTracksConstructed(false),
mIsDormant(false)
{
MOZ_COUNT_CTOR(MediaDecoder);
MOZ_ASSERT(NS_IsMainThread());

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

@ -360,11 +360,12 @@ public:
// called.
virtual nsresult Play();
// Set/Unset dormant state if necessary.
// Notify activity of the decoder owner is changed.
// Based on the activity, dormant state is updated.
// Dormant state is a state to free all scarce media resources
// (like hw video codec), did not decoding and stay dormant.
// It is used to share scarece media resources in system.
virtual void SetDormantIfNecessary(bool aDormant);
virtual void NotifyOwnerActivityChanged();
// Pause video playback.
virtual void Pause();
@ -1215,6 +1216,9 @@ protected:
// Stores media info, including info of audio tracks and video tracks, should
// only be accessed from main thread.
nsAutoPtr<MediaInfo> mInfo;
// True if MediaDecoder is in dormant state.
bool mIsDormant;
};
} // namespace mozilla

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

@ -120,6 +120,12 @@ public:
// HAVE_FUTURE_DATA or HAVE_ENOUGH_DATA.
virtual void UpdateReadyStateForData(NextFrameStatus aNextFrame) = 0;
// Check if the decoder owner is active.
virtual bool IsActive() = 0;
// Check if the decoder owner is hidden.
virtual bool IsHidden() = 0;
// Called by the media decoder and the video frame to get the
// ImageContainer containing the video data.
virtual VideoFrameContainer* GetVideoFrameContainer() = 0;

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

@ -50,10 +50,15 @@ public:
CANCELED
};
typedef MediaPromise<nsRefPtr<AudioData>, NotDecodedReason> AudioDataPromise;
typedef MediaPromise<nsRefPtr<VideoData>, NotDecodedReason> VideoDataPromise;
typedef MediaPromise<int64_t, nsresult> SeekPromise;
typedef MediaPromise<MediaData::Type, WaitForDataRejectValue> WaitForDataPromise;
typedef MediaPromise<nsRefPtr<AudioData>, NotDecodedReason, /* IsExclusive = */ true> AudioDataPromise;
typedef MediaPromise<nsRefPtr<VideoData>, NotDecodedReason, /* IsExclusive = */ true> VideoDataPromise;
typedef MediaPromise<int64_t, nsresult, /* IsExclusive = */ true> SeekPromise;
// Note that, conceptually, WaitForData makes sense in a non-exclusive sense.
// But in the current architecture it's only ever used exclusively (by MDSM),
// so we mark it that way to verify our assumptions. If you have a use-case
// for multiple WaitForData consumers, feel free to flip the exclusivity here.
typedef MediaPromise<MediaData::Type, WaitForDataRejectValue, /* IsExclusive = */ true> WaitForDataPromise;
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDecoderReader)

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

@ -86,6 +86,11 @@ extern PRLogModuleInfo* gMediaDecoderLog;
#undef GetCurrentTime
#endif
// Certain constants get stored as member variables and then adjusted by various
// scale factors on a per-decoder basis. We want to make sure to avoid using these
// constants directly, so we put them in a namespace.
namespace detail {
// If audio queue has less than this many usecs of decoded audio, we won't risk
// trying to decode the video, we'll skip decoding video up to the next
// keyframe. We may increase this value for an individual decoder if we
@ -98,6 +103,8 @@ static const uint32_t LOW_AUDIO_USECS = 300000;
// less than the low audio threshold.
const int64_t AMPLE_AUDIO_USECS = 1000000;
} // namespace detail
// When we're only playing audio and we don't have a video stream, we divide
// AMPLE_AUDIO_USECS and LOW_AUDIO_USECS by the following value. This reduces
// the amount of decoded audio we buffer, reducing our memory usage. We only
@ -126,6 +133,8 @@ static const int AUDIO_DURATION_USECS = 40000;
// increase it by more.
static const int THRESHOLD_FACTOR = 2;
namespace detail {
// If we have less than this much undecoded data available, we'll consider
// ourselves to be running low on undecoded data. We determine how much
// undecoded data we have remaining using the reader's GetBuffered()
@ -137,6 +146,8 @@ static const int64_t LOW_DATA_THRESHOLD_USECS = 5000000;
static_assert(LOW_DATA_THRESHOLD_USECS > AMPLE_AUDIO_USECS,
"LOW_DATA_THRESHOLD_USECS is too small");
} // namespace detail
// Amount of excess usecs of data to add in to the "should we buffer" calculation.
static const uint32_t EXHAUSTED_DATA_MARGIN_USECS = 60000;
@ -151,6 +162,8 @@ static const uint32_t EXHAUSTED_DATA_MARGIN_USECS = 60000;
// back to buffering normally.
static const uint32_t QUICK_BUFFER_THRESHOLD_USECS = 2000000;
namespace detail {
// If we're quick buffering, we'll remain in buffering mode while we have less than
// QUICK_BUFFERING_LOW_DATA_USECS of decoded data available.
static const uint32_t QUICK_BUFFERING_LOW_DATA_USECS = 1000000;
@ -162,6 +175,8 @@ static const uint32_t QUICK_BUFFERING_LOW_DATA_USECS = 1000000;
static_assert(QUICK_BUFFERING_LOW_DATA_USECS <= AMPLE_AUDIO_USECS,
"QUICK_BUFFERING_LOW_DATA_USECS is too large");
} // namespace detail
// The amount of instability we tollerate in calls to
// MediaDecoderStateMachine::UpdateEstimatedDuration(); changes of duration
// less than this are ignored, as they're assumed to be the result of
@ -202,8 +217,9 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
mPlaybackRate(1.0),
mPreservesPitch(true),
mAmpleVideoFrames(2),
mLowAudioThresholdUsecs(LOW_AUDIO_USECS),
mAmpleAudioThresholdUsecs(AMPLE_AUDIO_USECS),
mLowAudioThresholdUsecs(detail::LOW_AUDIO_USECS),
mAmpleAudioThresholdUsecs(detail::AMPLE_AUDIO_USECS),
mQuickBufferingLowDataThresholdUsecs(detail::QUICK_BUFFERING_LOW_DATA_USECS),
mIsAudioPrerolling(false),
mIsVideoPrerolling(false),
mAudioRequestStatus(RequestStatus::Idle),
@ -235,7 +251,7 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
std::max<uint32_t>(Preferences::GetUint("media.video-queue.default-size", 10), 3);
mBufferingWait = IsRealTime() ? 0 : 30;
mLowDataThresholdUsecs = IsRealTime() ? 0 : LOW_DATA_THRESHOLD_USECS;
mLowDataThresholdUsecs = IsRealTime() ? 0 : detail::LOW_DATA_THRESHOLD_USECS;
#ifdef XP_WIN
// Ensure high precision timers are enabled on Windows, otherwise the state
@ -1022,7 +1038,7 @@ MediaDecoderStateMachine::OnVideoDecoded(VideoData* aVideoSample)
!HasLowUndecodedData())
{
mLowAudioThresholdUsecs =
std::min(THRESHOLD_FACTOR * DurationToUsecs(decodeTime), AMPLE_AUDIO_USECS);
std::min(THRESHOLD_FACTOR * DurationToUsecs(decodeTime), mAmpleAudioThresholdUsecs);
mAmpleAudioThresholdUsecs = std::max(THRESHOLD_FACTOR * mLowAudioThresholdUsecs,
mAmpleAudioThresholdUsecs);
DECODER_LOG("Slow video decode, set mLowAudioThresholdUsecs=%lld mAmpleAudioThresholdUsecs=%lld",
@ -2336,6 +2352,7 @@ MediaDecoderStateMachine::FinishDecodeFirstFrame()
// order to reduce memory usage.
mAmpleAudioThresholdUsecs /= NO_VIDEO_AMPLE_AUDIO_DIVISOR;
mLowAudioThresholdUsecs /= NO_VIDEO_AMPLE_AUDIO_DIVISOR;
mQuickBufferingLowDataThresholdUsecs /= NO_VIDEO_AMPLE_AUDIO_DIVISOR;
}
// Get potentially updated metadata
@ -2803,7 +2820,7 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
bool isLiveStream = resource->GetLength() == -1;
if ((isLiveStream || !mDecoder->CanPlayThrough()) &&
elapsed < TimeDuration::FromSeconds(mBufferingWait * mPlaybackRate) &&
(mQuickBuffering ? HasLowDecodedData(QUICK_BUFFERING_LOW_DATA_USECS)
(mQuickBuffering ? HasLowDecodedData(mQuickBufferingLowDataThresholdUsecs)
: HasLowUndecodedData(mBufferingWait * USECS_PER_S)) &&
mDecoder->IsExpectingMoreData())
{
@ -2922,12 +2939,6 @@ MediaDecoderStateMachine::FlushDecoding()
DecodeTaskQueue()->FlushAndDispatch(task);
}
// These flags will be reset when the decoded data returned in OnAudioDecoded()
// and OnVideoDecoded(). Because the decode tasks are flushed, these flags need
// to be reset here.
mAudioRequestStatus = RequestStatus::Idle;
mVideoRequestStatus = RequestStatus::Idle;
// We must reset playback so that all references to frames queued
// in the state machine are dropped, else subsequent calls to Shutdown()
// or ReleaseMediaResources() can fail on B2G.

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

@ -955,6 +955,10 @@ protected:
// we detect that the decode can't keep up with rendering.
int64_t mAmpleAudioThresholdUsecs;
// If we're quick buffering, we'll remain in buffering mode while we have less than
// QUICK_BUFFERING_LOW_DATA_USECS of decoded data available.
int64_t mQuickBufferingLowDataThresholdUsecs;
// At the start of decoding we want to "preroll" the decode until we've
// got a few frames decoded before we consider whether decode is falling
// behind. Otherwise our "we're falling behind" logic will trigger

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

@ -439,17 +439,22 @@ VideoDevice::SatisfiesConstraintSets(
for (size_t i = 0; i < aConstraintSets.Length(); i++) {
auto& c = *aConstraintSets[i];
if (c.mFacingMode.WasPassed()) {
auto& value = c.mFacingMode.Value();
nsString s;
GetFacingMode(s);
if (!s.EqualsASCII(dom::VideoFacingModeEnumValues::strings[
static_cast<uint32_t>(c.mFacingMode.Value())].value)) {
return false;
if (value.IsString()) {
if (s != value.GetAsString()) {
return false;
}
} else {
if (!value.GetAsStringSequence().Contains(s)) {
return false;
}
}
}
nsString s;
GetMediaSource(s);
if (!s.EqualsASCII(dom::MediaSourceEnumValues::strings[
static_cast<uint32_t>(c.mMediaSource)].value)) {
if (s != c.mMediaSource) {
return false;
}
}
@ -517,9 +522,9 @@ MediaDevice::GetFacingMode(nsAString& aFacingMode)
NS_IMETHODIMP
MediaDevice::GetMediaSource(nsAString& aMediaSource)
{
if (mMediaSource == MediaSourceType::Microphone) {
if (mMediaSource == dom::MediaSourceEnum::Microphone) {
aMediaSource.Assign(NS_LITERAL_STRING("microphone"));
} else if (mMediaSource == MediaSourceType::Window) { // this will go away
} else if (mMediaSource == dom::MediaSourceEnum::Window) { // this will go away
aMediaSource.Assign(NS_LITERAL_STRING("window"));
} else { // all the rest are shared
aMediaSource.Assign(NS_ConvertUTF8toUTF16(
@ -943,7 +948,7 @@ template<class DeviceType, class ConstraintsType>
static void
GetSources(MediaEngine *engine,
ConstraintsType &aConstraints,
void (MediaEngine::* aEnumerate)(MediaSourceType,
void (MediaEngine::* aEnumerate)(dom::MediaSourceEnum,
nsTArray<nsRefPtr<typename DeviceType::Source> >*),
nsTArray<nsRefPtr<DeviceType>>& aResult,
const char* media_device_name = nullptr)
@ -955,8 +960,8 @@ static void
SourceSet candidateSet;
{
nsTArray<nsRefPtr<typename DeviceType::Source> > sources;
// all MediaSourceEnums are contained in MediaSourceType
(engine->*aEnumerate)((MediaSourceType)((int)aConstraints.mMediaSource), &sources);
(engine->*aEnumerate)(aConstraints.mMediaSourceEnumValue, &sources);
/**
* We're allowing multiple tabs to access the same camera for parity
* with Chrome. See bug 811757 for some of the issues surrounding
@ -1630,15 +1635,16 @@ MediaManager::GetUserMedia(
auto& tc = c.mVideo.GetAsMediaTrackConstraints();
if (!tc.mRequire.WasPassed() &&
tc.mMandatory.mFacingMode.WasPassed() && !tc.mFacingMode.WasPassed()) {
tc.mFacingMode.Construct(tc.mMandatory.mFacingMode.Value());
tc.mFacingMode.Construct().SetAsString() = tc.mMandatory.mFacingMode.Value();
tc.mRequire.Construct().AppendElement(NS_LITERAL_STRING("facingMode"));
}
if (tc.mOptional.WasPassed() && !tc.mAdvanced.WasPassed()) {
tc.mAdvanced.Construct();
for (uint32_t i = 0; i < tc.mOptional.Value().Length(); i++) {
for (size_t i = 0; i < tc.mOptional.Value().Length(); i++) {
if (tc.mOptional.Value()[i].mFacingMode.WasPassed()) {
MediaTrackConstraintSet n;
n.mFacingMode.Construct(tc.mOptional.Value()[i].mFacingMode.Value());
n.mFacingMode.Construct().SetAsString() =
tc.mOptional.Value()[i].mFacingMode.Value();
tc.mAdvanced.Value().AppendElement(n);
}
}
@ -1654,8 +1660,8 @@ MediaManager::GetUserMedia(
}
if (tc.mAdvanced.WasPassed()) {
uint32_t length = tc.mAdvanced.Value().Length();
for (uint32_t i = 0; i < length; i++) {
size_t length = tc.mAdvanced.Value().Length();
for (size_t i = 0; i < length; i++) {
if (tc.mAdvanced.Value()[i].mBrowserWindow.WasPassed()) {
tc.mAdvanced.Value()[i].mBrowserWindow.Construct(-1);
}
@ -1679,33 +1685,45 @@ MediaManager::GetUserMedia(
if (c.mVideo.IsMediaTrackConstraints()) {
auto& tc = c.mVideo.GetAsMediaTrackConstraints();
// deny screensharing request if support is disabled
if (tc.mMediaSource != dom::MediaSourceEnum::Camera) {
if (tc.mMediaSource == dom::MediaSourceEnum::Browser) {
if (!Preferences::GetBool("media.getusermedia.browser.enabled", false)) {
return task->Denied(NS_LITERAL_STRING("PermissionDeniedError"));
}
} else if (!Preferences::GetBool("media.getusermedia.screensharing.enabled", false)) {
return task->Denied(NS_LITERAL_STRING("PermissionDeniedError"));
}
/* Deny screensharing if the requesting document is not from a host
on the whitelist. */
// Block screen/window sharing on Mac OSX 10.6 and WinXP until proved that they work
if (
MediaSourceEnum src = StringToEnum(dom::MediaSourceEnumValues::strings,
tc.mMediaSource,
dom::MediaSourceEnum::Other);
switch (src) {
case dom::MediaSourceEnum::Camera:
break;
case dom::MediaSourceEnum::Browser:
case dom::MediaSourceEnum::Screen:
case dom::MediaSourceEnum::Application:
case dom::MediaSourceEnum::Window:
// Deny screensharing request if support is disabled, or
// the requesting document is not from a host on the whitelist, or
// we're on Mac OSX 10.6 and WinXP until proved that they work
if (!Preferences::GetBool(((src == dom::MediaSourceEnum::Browser)?
"media.getusermedia.browser.enabled" :
"media.getusermedia.screensharing.enabled"),
false) ||
#if defined(XP_MACOSX) || defined(XP_WIN)
(
!Preferences::GetBool("media.getusermedia.screensharing.allow_on_old_platforms", false) &&
!Preferences::GetBool("media.getusermedia.screensharing.allow_on_old_platforms",
false) &&
#if defined(XP_MACOSX)
!nsCocoaFeatures::OnLionOrLater()
#endif
#if defined (XP_WIN)
!IsVistaOrLater()
#endif
) ||
) ||
#endif
(!privileged && !HostHasPermission(*docURI))) {
return task->Denied(NS_LITERAL_STRING("PermissionDeniedError"));
}
break;
case dom::MediaSourceEnum::Microphone:
case dom::MediaSourceEnum::Other:
default:
return task->Denied(NS_LITERAL_STRING("NotFoundError"));
}
}
@ -2383,9 +2401,9 @@ GetUserMediaCallbackMediaStreamListener::StopScreenWindowSharing()
{
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
if (mVideoSource && !mStopped &&
(mVideoSource->GetMediaSource() == MediaSourceType::Screen ||
mVideoSource->GetMediaSource() == MediaSourceType::Application ||
mVideoSource->GetMediaSource() == MediaSourceType::Window)) {
(mVideoSource->GetMediaSource() == dom::MediaSourceEnum::Screen ||
mVideoSource->GetMediaSource() == dom::MediaSourceEnum::Application ||
mVideoSource->GetMediaSource() == dom::MediaSourceEnum::Window)) {
// Stop the whole stream if there's no audio; just the video track if we have both
MediaManager::GetMessageLoop()->PostTask(FROM_HERE,
new MediaOperationTask(mAudioSource ? MEDIA_STOP_TRACK : MEDIA_STOP,

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

@ -116,7 +116,7 @@ public:
{
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
return mVideoSource && !mStopped &&
mVideoSource->GetMediaSource() == MediaSourceType::Camera &&
mVideoSource->GetMediaSource() == dom::MediaSourceEnum::Camera &&
(!mVideoSource->IsFake() ||
Preferences::GetBool("media.navigator.permission.fake"));
}
@ -131,19 +131,19 @@ public:
{
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
return mVideoSource && !mStopped && !mVideoSource->IsAvailable() &&
mVideoSource->GetMediaSource() == MediaSourceType::Screen;
mVideoSource->GetMediaSource() == dom::MediaSourceEnum::Screen;
}
bool CapturingWindow()
{
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
return mVideoSource && !mStopped && !mVideoSource->IsAvailable() &&
mVideoSource->GetMediaSource() == MediaSourceType::Window;
mVideoSource->GetMediaSource() == dom::MediaSourceEnum::Window;
}
bool CapturingApplication()
{
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
return mVideoSource && !mStopped && !mVideoSource->IsAvailable() &&
mVideoSource->GetMediaSource() == MediaSourceType::Application;
mVideoSource->GetMediaSource() == dom::MediaSourceEnum::Application;
}
void SetStopped()
@ -508,7 +508,7 @@ protected:
nsString mID;
bool mHasFacingMode;
dom::VideoFacingModeEnum mFacingMode;
MediaSourceType mMediaSource;
dom::MediaSourceEnum mMediaSource;
nsRefPtr<MediaEngineSource> mSource;
};

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

@ -45,11 +45,11 @@ nsresult DispatchMediaPromiseRunnable(nsIEventTarget* aTarget, nsIRunnable* aRun
* callbacks to be invoked (asynchronously, on a specified thread) when the
* request is either completed (resolved) or cannot be completed (rejected).
*
* By default, resolve and reject callbacks are always invoked on the same thread
* where Then() was invoked.
* When IsExclusive is true, the MediaPromise does a release-mode assertion that
* there is at most one call to either Then(...) or ChainTo(...).
*/
template<typename T> class MediaPromiseHolder;
template<typename ResolveValueT, typename RejectValueT>
template<typename ResolveValueT, typename RejectValueT, bool IsExclusive>
class MediaPromise
{
public:
@ -60,24 +60,23 @@ public:
explicit MediaPromise(const char* aCreationSite)
: mCreationSite(aCreationSite)
, mMutex("MediaPromise Mutex")
, mHaveConsumer(false)
{
PROMISE_LOG("%s creating MediaPromise (%p)", mCreationSite, this);
}
static nsRefPtr<MediaPromise<ResolveValueT, RejectValueT>>
static nsRefPtr<MediaPromise>
CreateAndResolve(ResolveValueType aResolveValue, const char* aResolveSite)
{
nsRefPtr<MediaPromise<ResolveValueT, RejectValueT>> p =
new MediaPromise<ResolveValueT, RejectValueT>(aResolveSite);
nsRefPtr<MediaPromise> p = new MediaPromise(aResolveSite);
p->Resolve(aResolveValue, aResolveSite);
return p;
}
static nsRefPtr<MediaPromise<ResolveValueT, RejectValueT>>
static nsRefPtr<MediaPromise>
CreateAndReject(RejectValueType aRejectValue, const char* aRejectSite)
{
nsRefPtr<MediaPromise<ResolveValueT, RejectValueT>> p =
new MediaPromise<ResolveValueT, RejectValueT>(aRejectSite);
nsRefPtr<MediaPromise> p = new MediaPromise(aRejectSite);
p->Reject(aRejectValue, aRejectSite);
return p;
}
@ -246,6 +245,8 @@ public:
ResolveMethodType aResolveMethod, RejectMethodType aRejectMethod)
{
MutexAutoLock lock(mMutex);
MOZ_RELEASE_ASSERT(!IsExclusive || !mHaveConsumer);
mHaveConsumer = true;
ThenValueBase* thenValue = new ThenValue<TargetType, ThisType, ResolveMethodType,
RejectMethodType>(aResponseTarget, aThisVal,
aResolveMethod, aRejectMethod,
@ -262,6 +263,8 @@ public:
void ChainTo(already_AddRefed<MediaPromise> aChainedPromise, const char* aCallSite)
{
MutexAutoLock lock(mMutex);
MOZ_RELEASE_ASSERT(!IsExclusive || !mHaveConsumer);
mHaveConsumer = true;
nsRefPtr<MediaPromise> chainedPromise = aChainedPromise;
PROMISE_LOG("%s invoking Chain() [this=%p, chainedPromise=%p, isPending=%d]",
aCallSite, this, chainedPromise.get(), (int) IsPending());
@ -330,6 +333,7 @@ protected:
Maybe<RejectValueType> mRejectValue;
nsTArray<ThenValueBase*> mThenValues;
nsTArray<nsRefPtr<MediaPromise>> mChainedPromises;
bool mHaveConsumer;
};
/*

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

@ -1475,6 +1475,9 @@ nsresult FileMediaResource::ReadFromCache(char* aBuffer, int64_t aOffset, uint32
MutexAutoLock lock(mLock);
EnsureSizeInitialized();
if (!aCount) {
return NS_OK;
}
int64_t offset = 0;
nsresult res = mSeekable->Tell(&offset);
NS_ENSURE_SUCCESS(res,res);
@ -1486,6 +1489,9 @@ nsresult FileMediaResource::ReadFromCache(char* aBuffer, int64_t aOffset, uint32
uint32_t bytesToRead = aCount - bytesRead;
res = mInput->Read(aBuffer, bytesToRead, &x);
bytesRead += x;
if (!x) {
res = NS_ERROR_FAILURE;
}
} while (bytesRead != aCount && res == NS_OK);
// Reset read head to original position so we don't disturb any other

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

@ -20,7 +20,7 @@ namespace mozilla {
class SharedThreadPool;
typedef MediaPromise<bool, bool> ShutdownPromise;
typedef MediaPromise<bool, bool, false> ShutdownPromise;
// Abstracts executing runnables in order in a thread pool. The runnables
// dispatched to the MediaTaskQueue will be executed in the order in which

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

@ -18,7 +18,7 @@
namespace mozilla {
class EMEAudioDecoder : public MediaDataDecoder
, public GMPAudioDecoderProxyCallback
, public GMPAudioDecoderCallbackProxy
{
typedef mp4_demuxer::MP4Sample MP4Sample;
typedef mp4_demuxer::AudioDecoderConfig AudioDecoderConfig;
@ -37,7 +37,7 @@ public:
virtual nsresult Drain() MOZ_OVERRIDE;
virtual nsresult Shutdown() MOZ_OVERRIDE;
// GMPAudioDecoderProxyCallback implementation.
// GMPAudioDecoderCallbackProxy implementation.
virtual void Decoded(const nsTArray<int16_t>& aPCM,
uint64_t aTimeStamp,
uint32_t aChannels,

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

@ -312,7 +312,7 @@ EMEH264Decoder::GmpInput(MP4Sample* aSample)
return NS_ERROR_FAILURE;
}
UniquePtr<gmp::GMPVideoEncodedFrameImpl> frame(static_cast<gmp::GMPVideoEncodedFrameImpl*>(ftmp));
GMPUniquePtr<gmp::GMPVideoEncodedFrameImpl> frame(static_cast<gmp::GMPVideoEncodedFrameImpl*>(ftmp));
err = frame->CreateEmptyFrame(sample->size);
if (GMP_FAILED(err)) {
mCallback->Error();
@ -333,7 +333,7 @@ EMEH264Decoder::GmpInput(MP4Sample* aSample)
frame->SetBufferType(GMP_BufferLength32);
nsTArray<uint8_t> info; // No codec specific per-frame info to pass.
nsresult rv = mGMP->Decode(UniquePtr<GMPVideoEncodedFrame>(frame.release()), false, info, 0);
nsresult rv = mGMP->Decode(GMPUniquePtr<GMPVideoEncodedFrame>(frame.release()), false, info, 0);
if (NS_FAILED(rv)) {
mCallback->Error();
return rv;

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

@ -48,7 +48,7 @@ GMPAudioDecoderParent::InitDecode(GMPAudioCodecType aCodecType,
uint32_t aBitsPerChannel,
uint32_t aSamplesPerSecond,
nsTArray<uint8_t>& aExtraData,
GMPAudioDecoderProxyCallback* aCallback)
GMPAudioDecoderCallbackProxy* aCallback)
{
if (mIsOpen) {
NS_WARNING("Trying to re-init an in-use GMP audio decoder!");

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

@ -34,7 +34,7 @@ public:
uint32_t aBitsPerChannel,
uint32_t aSamplesPerSecond,
nsTArray<uint8_t>& aExtraData,
GMPAudioDecoderProxyCallback* aCallback) MOZ_OVERRIDE;
GMPAudioDecoderCallbackProxy* aCallback) MOZ_OVERRIDE;
virtual nsresult Decode(GMPAudioSamplesImpl& aInput) MOZ_OVERRIDE;
virtual nsresult Reset() MOZ_OVERRIDE;
virtual nsresult Drain() MOZ_OVERRIDE;
@ -55,7 +55,7 @@ private:
bool mIsOpen;
bool mShuttingDown;
nsRefPtr<GMPParent> mPlugin;
GMPAudioDecoderProxyCallback* mCallback;
GMPAudioDecoderCallbackProxy* mCallback;
};
} // namespace gmp

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

@ -12,9 +12,9 @@
#include "nsTArray.h"
#include "mozilla/gmp/GMPTypes.h"
class GMPAudioDecoderProxyCallback : public GMPCallbackBase {
class GMPAudioDecoderCallbackProxy : public GMPCallbackBase {
public:
virtual ~GMPAudioDecoderProxyCallback() {}
virtual ~GMPAudioDecoderCallbackProxy() {}
// Note: aChannelCount and aSamplesPerSecond may not be consistent from
// one invocation to the next.
virtual void Decoded(const nsTArray<int16_t>& aPCM,
@ -36,7 +36,7 @@ public:
uint32_t aBitsPerChannel,
uint32_t aSamplesPerSecond,
nsTArray<uint8_t>& aExtraData,
GMPAudioDecoderProxyCallback* aCallback) = 0;
GMPAudioDecoderCallbackProxy* aCallback) = 0;
virtual nsresult Decode(mozilla::gmp::GMPAudioSamplesImpl& aSamples) = 0;
virtual nsresult Reset() = 0;
virtual nsresult Drain() = 0;

26
dom/media/gmp/GMPUtils.h Normal file
Просмотреть файл

@ -0,0 +1,26 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GMPUtils_h_
#define GMPUtils_h_
#include "mozilla/UniquePtr.h"
namespace mozilla {
template<typename T>
struct DestroyPolicy
{
void operator()(T* aGMPObject) const {
aGMPObject->Destroy();
}
};
template<typename T>
using GMPUniquePtr = mozilla::UniquePtr<T, DestroyPolicy<T>>;
} // namespace mozilla
#endif

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

@ -8,6 +8,7 @@
#include "mozilla/unused.h"
#include "nsAutoRef.h"
#include "nsThreadUtils.h"
#include "GMPUtils.h"
#include "GMPVideoEncodedFrameImpl.h"
#include "GMPVideoi420FrameImpl.h"
#include "GMPParent.h"
@ -108,7 +109,7 @@ GMPVideoDecoderParent::InitDecode(const GMPVideoCodec& aCodecSettings,
}
nsresult
GMPVideoDecoderParent::Decode(UniquePtr<GMPVideoEncodedFrame> aInputFrame,
GMPVideoDecoderParent::Decode(GMPUniquePtr<GMPVideoEncodedFrame> aInputFrame,
bool aMissingFrames,
const nsTArray<uint8_t>& aCodecSpecificInfo,
int64_t aRenderTimeMs)
@ -120,7 +121,7 @@ GMPVideoDecoderParent::Decode(UniquePtr<GMPVideoEncodedFrame> aInputFrame,
MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
UniquePtr<GMPVideoEncodedFrameImpl> inputFrameImpl(
GMPUniquePtr<GMPVideoEncodedFrameImpl> inputFrameImpl(
static_cast<GMPVideoEncodedFrameImpl*>(aInputFrame.release()));
// Very rough kill-switch if the plugin stops processing. If it's merely

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

@ -11,6 +11,7 @@
#include "mozilla/gmp/PGMPVideoDecoderParent.h"
#include "GMPMessageUtils.h"
#include "GMPSharedMemManager.h"
#include "GMPUtils.h"
#include "GMPVideoHost.h"
#include "GMPVideoDecoderProxy.h"
@ -37,7 +38,7 @@ public:
const nsTArray<uint8_t>& aCodecSpecific,
GMPVideoDecoderCallbackProxy* aCallback,
int32_t aCoreCount) MOZ_OVERRIDE;
virtual nsresult Decode(UniquePtr<GMPVideoEncodedFrame> aInputFrame,
virtual nsresult Decode(GMPUniquePtr<GMPVideoEncodedFrame> aInputFrame,
bool aMissingFrames,
const nsTArray<uint8_t>& aCodecSpecificInfo,
int64_t aRenderTimeMs = -1) MOZ_OVERRIDE;

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

@ -12,7 +12,7 @@
#include "gmp-video-frame-encoded.h"
#include "GMPCallbackBase.h"
#include "mozilla/UniquePtr.h"
#include "GMPUtils.h"
class GMPVideoDecoderCallbackProxy : public GMPCallbackBase,
public GMPVideoDecoderCallback
@ -38,7 +38,7 @@ public:
const nsTArray<uint8_t>& aCodecSpecific,
GMPVideoDecoderCallbackProxy* aCallback,
int32_t aCoreCount) = 0;
virtual nsresult Decode(mozilla::UniquePtr<GMPVideoEncodedFrame> aInputFrame,
virtual nsresult Decode(mozilla::GMPUniquePtr<GMPVideoEncodedFrame> aInputFrame,
bool aMissingFrames,
const nsTArray<uint8_t>& aCodecSpecificInfo,
int64_t aRenderTimeMs = -1) = 0;
@ -51,17 +51,4 @@ public:
virtual void Close() = 0;
};
namespace mozilla {
template<>
struct DefaultDelete<GMPVideoEncodedFrame>
{
void operator()(GMPVideoEncodedFrame* aFrame) const
{
aFrame->Destroy();
}
};
} // namespace mozilla
#endif

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

@ -35,7 +35,6 @@
#include "gmp-video-frame.h"
#include "gmp-video-frame-encoded.h"
#include "gmp-decryption.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/ipc/Shmem.h"
#include "mp4_demuxer/DecoderData.h"
@ -116,15 +115,6 @@ private:
} // namespace gmp
template<>
struct DefaultDelete<mozilla::gmp::GMPVideoEncodedFrameImpl>
{
void operator()(mozilla::gmp::GMPVideoEncodedFrameImpl* aFrame) const
{
aFrame->Destroy();
}
};
} // namespace mozilla
#endif // GMPVideoEncodedFrameImpl_h_

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

@ -15,6 +15,7 @@
#include "nsThread.h"
#include "nsThreadUtils.h"
#include "runnable_utils.h"
#include "GMPUtils.h"
namespace mozilla {
@ -125,7 +126,7 @@ GMPVideoEncoderParent::InitEncode(const GMPVideoCodec& aCodecSettings,
}
GMPErr
GMPVideoEncoderParent::Encode(UniquePtr<GMPVideoi420Frame> aInputFrame,
GMPVideoEncoderParent::Encode(GMPUniquePtr<GMPVideoi420Frame> aInputFrame,
const nsTArray<uint8_t>& aCodecSpecificInfo,
const nsTArray<GMPVideoFrameType>& aFrameTypes)
{
@ -136,7 +137,7 @@ GMPVideoEncoderParent::Encode(UniquePtr<GMPVideoi420Frame> aInputFrame,
MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
UniquePtr<GMPVideoi420FrameImpl> inputFrameImpl(
GMPUniquePtr<GMPVideoi420FrameImpl> inputFrameImpl(
static_cast<GMPVideoi420FrameImpl*>(aInputFrame.release()));
// Very rough kill-switch if the plugin stops processing. If it's merely

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

@ -11,6 +11,7 @@
#include "mozilla/gmp/PGMPVideoEncoderParent.h"
#include "GMPMessageUtils.h"
#include "GMPSharedMemManager.h"
#include "GMPUtils.h"
#include "GMPVideoHost.h"
#include "GMPVideoEncoderProxy.h"
@ -38,7 +39,7 @@ public:
GMPVideoEncoderCallbackProxy* aCallback,
int32_t aNumberOfCores,
uint32_t aMaxPayloadSize) MOZ_OVERRIDE;
virtual GMPErr Encode(UniquePtr<GMPVideoi420Frame> aInputFrame,
virtual GMPErr Encode(GMPUniquePtr<GMPVideoi420Frame> aInputFrame,
const nsTArray<uint8_t>& aCodecSpecificInfo,
const nsTArray<GMPVideoFrameType>& aFrameTypes) MOZ_OVERRIDE;
virtual GMPErr SetChannelParameters(uint32_t aPacketLoss, uint32_t aRTT) MOZ_OVERRIDE;

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

@ -12,7 +12,7 @@
#include "gmp-video-frame-encoded.h"
#include "GMPCallbackBase.h"
#include "mozilla/UniquePtr.h"
#include "GMPUtils.h"
class GMPVideoEncoderCallbackProxy : public GMPCallbackBase {
public:
@ -40,7 +40,7 @@ public:
GMPVideoEncoderCallbackProxy* aCallback,
int32_t aNumberOfCores,
uint32_t aMaxPayloadSize) = 0;
virtual GMPErr Encode(mozilla::UniquePtr<GMPVideoi420Frame> aInputFrame,
virtual GMPErr Encode(mozilla::GMPUniquePtr<GMPVideoi420Frame> aInputFrame,
const nsTArray<uint8_t>& aCodecSpecificInfo,
const nsTArray<GMPVideoFrameType>& aFrameTypes) = 0;
virtual GMPErr SetChannelParameters(uint32_t aPacketLoss, uint32_t aRTT) = 0;
@ -53,17 +53,4 @@ public:
virtual void Close() = 0;
};
namespace mozilla {
template<>
struct DefaultDelete<GMPVideoi420Frame>
{
void operator()(GMPVideoi420Frame* aFrame) const
{
aFrame->Destroy();
}
};
} // namespace mozilla
#endif // GMPVideoEncoderProxy_h_

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

@ -7,7 +7,6 @@
#define GMPVideoi420FrameImpl_h_
#include "gmp-video-frame-i420.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/ipc/Shmem.h"
#include "GMPVideoPlaneImpl.h"
@ -80,15 +79,6 @@ private:
} // namespace gmp
template<>
struct DefaultDelete<mozilla::gmp::GMPVideoi420FrameImpl>
{
void operator()(mozilla::gmp::GMPVideoi420FrameImpl* aFrame) const
{
aFrame->Destroy();
}
};
} // namespace mozilla
#endif // GMPVideoi420FrameImpl_h_

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

@ -51,6 +51,7 @@ EXPORTS += [
'GMPStorageParent.h',
'GMPTimerChild.h',
'GMPTimerParent.h',
'GMPUtils.h',
'GMPVideoDecoderChild.h',
'GMPVideoDecoderParent.h',
'GMPVideoDecoderProxy.h',

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

@ -24,12 +24,28 @@ var startTest = function(test, token) {
var numVideoElementsFinished = 0;
var ondurationchange = function(ev) {
var v = ev.target;
info(v.testName + " got durationchange");
v.durationchange = true;
};
var onresize = function(ev) {
var v = ev.target;
info(v.testName + " got resize");
ok(!v.resize, v.testName + " should only fire resize once for same size");
v.resize = true;
ok(v.durationchange, v.testName +
" durationchange event should have been emitted before resize");
is(v.videoWidth, test.width, v.testName + " width should be set on resize");
is(v.videoHeight, test.height, v.testName + " height should be set on resize");
};
var onloadedmetadata = function(ev) {
var v = ev.target;
info(v.testName + " got loadedmetadata");
ok(!v.loadedmetadata, v.testName + " should only fire loadedmetadata once");
v.loadedmetadata = true;
is(v.videoWidth, test.width, v.testName + " video width should be set on loadedmetadata");
is(v.videoHeight, test.height, v.testName + " video height should be set on loadedmetadata");
ok(v.resize, v.testName +
" resize event should have been emitted before loadedmetadata");
numVideoElementsFinished += 1;
if (v === v1) {
@ -45,6 +61,10 @@ var startTest = function(test, token) {
}
};
var setupElement = function(v, id) {
v.durationchange = false;
v.ondurationchange = ondurationchange;
v.resize = false;
v.onresize = onresize;
v.loadedmetadata = false;
v.onloadedmetadata = onloadedmetadata;
document.body.appendChild(v);

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

@ -23,24 +23,42 @@ var common_tests = [
constraints: { video: { facingMode:'left', require:["facingMode"] },
fake: true },
error: "NotFoundError" },
{ message: "video overconstrained by facingMode array fails",
constraints: { video: { facingMode:['left', 'right'], require:["facingMode"] },
fake: true },
error: "NotFoundError" },
{ message: "audio overconstrained by facingMode fails",
constraints: { audio: { facingMode:'left', require:["facingMode"] },
fake: true },
error: "NotFoundError" },
{ message: "full screensharing requires permission",
constraints: { video: { mediaSource:'screen' } },
error: "PermissionDeniedError" },
{ message: "application screensharing requires permission",
constraints: { video: { mediaSource:'application' } },
error: "PermissionDeniedError" },
{ message: "window screensharing requires permission",
constraints: { video: { mediaSource:'window' } },
error: "PermissionDeniedError" },
{ message: "browser screensharing requires permission",
constraints: { video: { mediaSource:'browser' } },
error: "PermissionDeniedError" },
{ message: "unknown mediaSource fails",
constraints: { video: { mediaSource:'uncle' } },
error: "NotFoundError" },
{ message: "Success-path: optional video facingMode + audio ignoring facingMode",
constraints: { fake: true,
audio: { facingMode:'left',
foo:0,
advanced: [{ facingMode:'environment' },
{ facingMode:'user' },
{ bar:0 }] },
video: { // TODO: Bug 767924 sequences in unions
//facingMode:['left', 'right', 'user', 'environment'],
//require:["facingMode"],
audio: { mediaSource:'microphone',
facingMode:'left',
foo:0,
advanced: [{ facingMode:'environment' },
{ facingMode:'user' },
{ bar:0 }] },
video: { mediaSource:'camera',
facingMode:['left', 'right', 'user', 'environment'],
foo:0,
advanced: [{ facingMode:'environment' },
{ facingMode:['user'] },
{ bar:0 }] } },
error: null }
];
@ -63,12 +81,14 @@ function testConstraints(tests) {
});
}
var p = new Promise(function(resolve) { resolve(); });
var p = new Promise(r => SpecialPowers.pushPrefEnv({
set : [ ['media.getusermedia.browser.enabled', false],
['media.getusermedia.screensharing.enabled', false] ]
}, r));
tests.forEach(function(test) {
p = testgum(p, test);
});
p.catch(function(reason) {
ok(false, "Unexpected failure: " + reason.message);
})
p.catch(reason => ok(false, "Unexpected failure: " + reason.message))
.then(SimpleTest.finish);
}

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

@ -43,7 +43,6 @@ skip-if = (toolkit == 'gonk' && debug) # debug-only failure, turned an intermitt
skip-if = toolkit == 'gonk' || toolkit == 'android' # Bug 907352, backwards-compatible behavior on mobile only
[test_getUserMedia_constraints_mobile.html]
skip-if = toolkit != 'gonk' && toolkit != 'android' # Bug 907352, backwards-compatible behavior on mobile only
[test_getUserMedia_exceptions.html]
[test_getUserMedia_gumWithinGum.html]
[test_getUserMedia_playAudioTwice.html]
[test_getUserMedia_playVideoAudioTwice.html]

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

@ -1,94 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=795367
-->
<head>
<meta charset="utf-8">
<title>Test mozGetUserMedia Exceptions</title>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="head.js"></script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=795367">Test mozGetUserMedia Exceptions</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/**
These tests verify that the appropriate exception is thrown when incorrect
values are provided to the immediate mozGetUserMedia call.
*/
var exceptionTests = [
// Each test here verifies that a caller is required to have all
// three arguments in order to call mozGetUserMedia
{ params: undefined,
error: "Not enough arguments to Navigator.mozGetUserMedia.",
message: "no arguments specified" },
{ params: [{video: true, fake: true}],
error: "Not enough arguments to Navigator.mozGetUserMedia.",
message: "one argument specified" },
{ params: [{video: true, fake: true}, unexpectedCall],
error: "Not enough arguments to Navigator.mozGetUserMedia.",
message: "two arguments specified" },
// Each test here verifies that providing an incorret object
// type to any mozGetUserMedia parameter should throw
// the correct exception specified
{ params: [1, unexpectedCall, unexpectedCall],
error: "Argument 1 of Navigator.mozGetUserMedia can't be converted to a dictionary.",
message: "wrong object type as first parameter" },
{ params: [{video: true, fake: true}, 1, unexpectedCall],
error: "Argument 2 of Navigator.mozGetUserMedia is not an object.",
message: "wrong object type as second parameter" },
{ params: [{video: true, fake: true}, unexpectedCall, 1],
error: "Argument 3 of Navigator.mozGetUserMedia is not an object.",
message: "wrong object type as third parameter" },
// Each test here verifies constraint syntax as defined in webidl
{ params: [{ fake: true, video: { advanced: [{ facingMode:'foo' }] } },
unexpectedCall, unexpectedCall],
error: "'facingMode' member of MediaTrackConstraintSet 'foo' is not a valid value for enumeration VideoFacingModeEnum.",
message: "invalid facingMode enum value" }
];
/**
* A callback function that is only called if a particular
* exception was not thrown, resulting in the test failing.
*
* @param {MediaStream} argument ignored
*/
function unexpectedCall(obj) {
ok(false, "Callback should not have been called");
}
/**
* Starts the test run by running through each exception
* test by verifying that the correct exception type specified
* is thrown on the mozGetUserMedia call with the parameters
* specified.
*/
runTest(function () {
exceptionTests.forEach(function (test) {
var exception = false;
try {
navigator.mozGetUserMedia.apply(navigator, test.params);
} catch (e) {
exception = (e.message === test.error);
if(!exception) {
info(e.message);
}
}
ok(exception, "Exception for " + test.message);
});
SimpleTest.finish();
});
</script>
</pre>
</body>
</html>

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

@ -39,16 +39,6 @@ enum MediaEngineState {
kReleased
};
// includes everything from dom::MediaSourceEnum (really video sources), plus audio sources
enum MediaSourceType {
Camera = (int) dom::MediaSourceEnum::Camera,
Screen = (int) dom::MediaSourceEnum::Screen,
Application = (int) dom::MediaSourceEnum::Application,
Window, // = (int) dom::MediaSourceEnum::Window, // XXX bug 1038926
Browser = (int) dom::MediaSourceEnum::Browser, // proposed in WG, unclear if it's useful
Microphone
};
class MediaEngine
{
public:
@ -64,12 +54,12 @@ public:
/* Populate an array of video sources in the nsTArray. Also include devices
* that are currently unavailable. */
virtual void EnumerateVideoDevices(MediaSourceType,
virtual void EnumerateVideoDevices(dom::MediaSourceEnum,
nsTArray<nsRefPtr<MediaEngineVideoSource> >*) = 0;
/* Populate an array of audio sources in the nsTArray. Also include devices
* that are currently unavailable. */
virtual void EnumerateAudioDevices(MediaSourceType,
virtual void EnumerateAudioDevices(dom::MediaSourceEnum,
nsTArray<nsRefPtr<MediaEngineAudioSource> >*) = 0;
protected:
@ -127,7 +117,7 @@ public:
virtual bool IsFake() = 0;
/* Returns the type of media source (camera, microphone, screen, window, etc) */
virtual const MediaSourceType GetMediaSource() = 0;
virtual const dom::MediaSourceEnum GetMediaSource() = 0;
// Callback interface for TakePhoto(). Either PhotoComplete() or PhotoError()
// should be called.

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

@ -49,8 +49,8 @@ public:
return false;
}
virtual const MediaSourceType GetMediaSource() MOZ_OVERRIDE {
return MediaSourceType::Camera;
virtual const dom::MediaSourceEnum GetMediaSource() MOZ_OVERRIDE {
return dom::MediaSourceEnum::Camera;
}
virtual nsresult TakePhoto(PhotoCallback* aCallback) MOZ_OVERRIDE

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

@ -469,12 +469,12 @@ MediaEngineDefaultAudioSource::Notify(nsITimer* aTimer)
}
void
MediaEngineDefault::EnumerateVideoDevices(MediaSourceType aMediaSource,
MediaEngineDefault::EnumerateVideoDevices(dom::MediaSourceEnum aMediaSource,
nsTArray<nsRefPtr<MediaEngineVideoSource> >* aVSources) {
MutexAutoLock lock(mMutex);
// only supports camera sources (for now). See Bug 1038241
if (aMediaSource != MediaSourceType::Camera) {
if (aMediaSource != dom::MediaSourceEnum::Camera) {
return;
}
@ -490,7 +490,7 @@ MediaEngineDefault::EnumerateVideoDevices(MediaSourceType aMediaSource,
}
void
MediaEngineDefault::EnumerateAudioDevices(MediaSourceType aMediaSource,
MediaEngineDefault::EnumerateAudioDevices(dom::MediaSourceEnum aMediaSource,
nsTArray<nsRefPtr<MediaEngineAudioSource> >* aASources) {
MutexAutoLock lock(mMutex);
int32_t len = mASources.Length();

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

@ -64,8 +64,8 @@ public:
return true;
}
virtual const MediaSourceType GetMediaSource() MOZ_OVERRIDE {
return MediaSourceType::Camera;
virtual const dom::MediaSourceEnum GetMediaSource() MOZ_OVERRIDE {
return dom::MediaSourceEnum::Camera;
}
virtual nsresult TakePhoto(PhotoCallback* aCallback) MOZ_OVERRIDE
@ -127,8 +127,8 @@ public:
return true;
}
virtual const MediaSourceType GetMediaSource() MOZ_OVERRIDE {
return MediaSourceType::Microphone;
virtual const dom::MediaSourceEnum GetMediaSource() MOZ_OVERRIDE {
return dom::MediaSourceEnum::Microphone;
}
virtual nsresult TakePhoto(PhotoCallback* aCallback) MOZ_OVERRIDE
@ -158,9 +158,9 @@ public:
, mMutex("mozilla::MediaEngineDefault")
{}
virtual void EnumerateVideoDevices(MediaSourceType,
virtual void EnumerateVideoDevices(dom::MediaSourceEnum,
nsTArray<nsRefPtr<MediaEngineVideoSource> >*);
virtual void EnumerateAudioDevices(MediaSourceType,
virtual void EnumerateAudioDevices(dom::MediaSourceEnum,
nsTArray<nsRefPtr<MediaEngineAudioSource> >*);
protected:

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

@ -29,8 +29,8 @@ class MediaEngineTabVideoSource : public MediaEngineVideoSource, nsIDOMEventList
virtual nsresult Stop(mozilla::SourceMediaStream*, mozilla::TrackID) MOZ_OVERRIDE;
virtual nsresult Config(bool, uint32_t, bool, uint32_t, bool, uint32_t, int32_t) MOZ_OVERRIDE;
virtual bool IsFake() MOZ_OVERRIDE;
virtual const MediaSourceType GetMediaSource() MOZ_OVERRIDE {
return MediaSourceType::Browser;
virtual const dom::MediaSourceEnum GetMediaSource() MOZ_OVERRIDE {
return dom::MediaSourceEnum::Browser;
}
virtual bool SatisfiesConstraintSets(
const nsTArray<const dom::MediaTrackConstraintSet*>& aConstraintSets) MOZ_OVERRIDE

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

@ -72,14 +72,14 @@ MediaEngineWebRTC::MediaEngineWebRTC(MediaEnginePrefs &aPrefs)
}
void
MediaEngineWebRTC::EnumerateVideoDevices(MediaSourceType aMediaSource,
MediaEngineWebRTC::EnumerateVideoDevices(dom::MediaSourceEnum aMediaSource,
nsTArray<nsRefPtr<MediaEngineVideoSource> >* aVSources)
{
// We spawn threads to handle gUM runnables, so we must protect the member vars
MutexAutoLock lock(mMutex);
#ifdef MOZ_B2G_CAMERA
if (aMediaSource != MediaSourceType::Camera) {
if (aMediaSource != dom::MediaSourceEnum::Camera) {
// only supports camera sources
return;
}
@ -137,7 +137,7 @@ MediaEngineWebRTC::EnumerateVideoDevices(MediaSourceType aMediaSource,
#endif
switch (aMediaSource) {
case MediaSourceType::Window:
case dom::MediaSourceEnum::Window:
mWinEngineConfig.Set<webrtc::CaptureDeviceInfo>(
new webrtc::CaptureDeviceInfo(webrtc::CaptureDeviceType::Window));
if (!mWinEngine) {
@ -148,7 +148,7 @@ MediaEngineWebRTC::EnumerateVideoDevices(MediaSourceType aMediaSource,
videoEngine = mWinEngine;
videoEngineInit = &mWinEngineInit;
break;
case MediaSourceType::Application:
case dom::MediaSourceEnum::Application:
mAppEngineConfig.Set<webrtc::CaptureDeviceInfo>(
new webrtc::CaptureDeviceInfo(webrtc::CaptureDeviceType::Application));
if (!mAppEngine) {
@ -159,7 +159,7 @@ MediaEngineWebRTC::EnumerateVideoDevices(MediaSourceType aMediaSource,
videoEngine = mAppEngine;
videoEngineInit = &mAppEngineInit;
break;
case MediaSourceType::Screen:
case dom::MediaSourceEnum::Screen:
mScreenEngineConfig.Set<webrtc::CaptureDeviceInfo>(
new webrtc::CaptureDeviceInfo(webrtc::CaptureDeviceType::Screen));
if (!mScreenEngine) {
@ -170,7 +170,7 @@ MediaEngineWebRTC::EnumerateVideoDevices(MediaSourceType aMediaSource,
videoEngine = mScreenEngine;
videoEngineInit = &mScreenEngineInit;
break;
case MediaSourceType::Browser:
case dom::MediaSourceEnum::Browser:
mBrowserEngineConfig.Set<webrtc::CaptureDeviceInfo>(
new webrtc::CaptureDeviceInfo(webrtc::CaptureDeviceType::Browser));
if (!mBrowserEngine) {
@ -181,7 +181,7 @@ MediaEngineWebRTC::EnumerateVideoDevices(MediaSourceType aMediaSource,
videoEngine = mBrowserEngine;
videoEngineInit = &mBrowserEngineInit;
break;
case MediaSourceType::Camera:
case dom::MediaSourceEnum::Camera:
// fall through
default:
if (!mVideoEngine) {
@ -274,7 +274,7 @@ MediaEngineWebRTC::EnumerateVideoDevices(MediaSourceType aMediaSource,
}
}
if (mHasTabVideoSource || MediaSourceType::Browser == aMediaSource)
if (mHasTabVideoSource || dom::MediaSourceEnum::Browser == aMediaSource)
aVSources->AppendElement(new MediaEngineTabVideoSource());
return;
@ -282,7 +282,7 @@ MediaEngineWebRTC::EnumerateVideoDevices(MediaSourceType aMediaSource,
}
void
MediaEngineWebRTC::EnumerateAudioDevices(MediaSourceType aMediaSource,
MediaEngineWebRTC::EnumerateAudioDevices(dom::MediaSourceEnum aMediaSource,
nsTArray<nsRefPtr<MediaEngineAudioSource> >* aASources)
{
ScopedCustomReleasePtr<webrtc::VoEBase> ptrVoEBase;

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

@ -79,7 +79,7 @@ public:
virtual bool IsTextureSupported() MOZ_OVERRIDE { return false; }
MediaEngineWebRTCVideoSource(webrtc::VideoEngine* aVideoEnginePtr, int aIndex,
MediaSourceType aMediaSource = MediaSourceType::Camera)
dom::MediaSourceEnum aMediaSource = dom::MediaSourceEnum::Camera)
: MediaEngineCameraVideoSource(aIndex, "WebRTCCamera.Monitor")
, mVideoEngine(aVideoEnginePtr)
, mMinFps(-1)
@ -99,7 +99,7 @@ public:
TrackID aId,
StreamTime aDesiredTime) MOZ_OVERRIDE;
virtual const MediaSourceType GetMediaSource() MOZ_OVERRIDE {
virtual const dom::MediaSourceEnum GetMediaSource() MOZ_OVERRIDE {
return mMediaSource;
}
virtual nsresult TakePhoto(PhotoCallback* aCallback) MOZ_OVERRIDE
@ -127,7 +127,7 @@ private:
webrtc::ViERender* mViERender;
int mMinFps; // Min rate we want to accept
MediaSourceType mMediaSource; // source of media (camera | application | screen)
dom::MediaSourceEnum mMediaSource; // source of media (camera | application | screen)
static bool SatisfiesConstraintSet(const dom::MediaTrackConstraintSet& aConstraints,
const webrtc::CaptureCapability& aCandidate);
@ -185,8 +185,8 @@ public:
return false;
}
virtual const MediaSourceType GetMediaSource() MOZ_OVERRIDE {
return MediaSourceType::Microphone;
virtual const dom::MediaSourceEnum GetMediaSource() MOZ_OVERRIDE {
return dom::MediaSourceEnum::Microphone;
}
virtual nsresult TakePhoto(PhotoCallback* aCallback) MOZ_OVERRIDE
@ -254,9 +254,9 @@ public:
// before invoking Shutdown on this class.
void Shutdown();
virtual void EnumerateVideoDevices(MediaSourceType,
virtual void EnumerateVideoDevices(dom::MediaSourceEnum,
nsTArray<nsRefPtr<MediaEngineVideoSource> >*);
virtual void EnumerateAudioDevices(MediaSourceType,
virtual void EnumerateAudioDevices(dom::MediaSourceEnum,
nsTArray<nsRefPtr<MediaEngineAudioSource> >*);
private:
~MediaEngineWebRTC() {

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

@ -12,6 +12,22 @@
namespace mozilla {
template<class EnumValuesStrings, class Enum>
static const char* EnumToASCII(const EnumValuesStrings& aStrings, Enum aValue) {
return aStrings[uint32_t(aValue)].value;
}
template<class EnumValuesStrings, class Enum>
static Enum StringToEnum(const EnumValuesStrings& aStrings, const nsAString& aValue,
Enum aDefaultValue) {
for (size_t i = 0; aStrings[i].value; i++) {
if (aValue.EqualsASCII(aStrings[i].value)) {
return Enum(i);
}
}
return aDefaultValue;
}
// Normalized internal version of MediaTrackConstraints to simplify downstream
// processing. This implementation-only helper is included as needed by both
// MediaManager (for gUM camera selection) and MediaEngine (for applyConstraints).
@ -25,6 +41,7 @@ public:
bool mUnsupportedRequirement;
MediaTrackConstraintSet mRequired;
dom::Sequence<MediaTrackConstraintSet> mNonrequired;
dom::MediaSourceEnum mMediaSourceEnumValue;
MediaTrackConstraintsN(const dom::MediaTrackConstraints &aOther,
const dom::EnumEntry* aStrings)
@ -34,8 +51,8 @@ public:
{
if (mRequire.WasPassed()) {
auto& array = mRequire.Value();
for (uint32_t i = 0; i < array.Length(); i++) {
auto value = ToEnum(array[i]);
for (size_t i = 0; i < array.Length(); i++) {
auto value = StringToEnum(mStrings, array[i], Kind::Other);
if (value != Kind::Other) {
mRequireN.AppendElement(value);
} else {
@ -43,18 +60,22 @@ public:
}
}
}
// treat MediaSource special because it's always required
mRequired.mMediaSource = mMediaSource;
// we guarantee (int) equivalence from MediaSourceEnum ->MediaSourceType
// (but not the other way)
if (mMediaSource != dom::MediaSourceEnum::Camera && mAdvanced.WasPassed()) {
// iterate through advanced, forcing mediaSource to match "root"
auto& array = mAdvanced.Value();
for (uint32_t i = 0; i < array.Length(); i++) {
if (array[i].mMediaSource == dom::MediaSourceEnum::Camera) {
array[i].mMediaSource = mMediaSource;
mMediaSourceEnumValue = StringToEnum(dom::MediaSourceEnumValues::strings,
mMediaSource,
dom::MediaSourceEnum::Other);
if (mAdvanced.WasPassed()) {
if(mMediaSourceEnumValue != dom::MediaSourceEnum::Camera) {
// iterate through advanced, forcing mediaSource to match "root"
auto& array = mAdvanced.Value();
for (uint32_t i = 0; i < array.Length(); i++) {
auto& ms = array[i].mMediaSource;
if (ms.EqualsASCII(EnumToASCII(dom::MediaSourceEnumValues::strings,
dom::MediaSourceEnum::Camera))) {
ms = mMediaSource;
}
}
}
}
@ -69,14 +90,6 @@ protected:
}
}
private:
Kind ToEnum(const nsAString& aSrc) {
for (size_t i = 0; mStrings[i].value; i++) {
if (aSrc.EqualsASCII(mStrings[i].value)) {
return Kind(i);
}
}
return Kind::Other;
}
const dom::EnumEntry* mStrings;
};

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

@ -97,6 +97,7 @@ LOCAL_INCLUDES += [
'/dom/plugins/ipc',
'/layout/generic',
'/layout/xul',
'/netwerk/base',
'/widget',
'/widget/android',
'/widget/cocoa',

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

@ -30,7 +30,7 @@
#include "nsIURL.h"
#include "nsTArray.h"
#include "nsReadableUtils.h"
#include "nsIProtocolProxyService2.h"
#include "nsProtocolProxyService.h"
#include "nsIStreamConverterService.h"
#include "nsIFile.h"
#if defined(XP_MACOSX)
@ -606,32 +606,30 @@ nsresult nsPluginHost::FindProxyForURL(const char* url, char* *result)
}
nsresult res;
nsCOMPtr<nsIURI> uriIn;
nsCOMPtr<nsIProtocolProxyService> proxyService;
nsCOMPtr<nsIProtocolProxyService2> proxyService2;
nsCOMPtr<nsIIOService> ioService;
proxyService = do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID, &res);
nsCOMPtr<nsIProtocolProxyService> proxyService =
do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID, &res);
if (NS_FAILED(res) || !proxyService)
return res;
proxyService2 = do_QueryInterface(proxyService, &res);
if (NS_FAILED(res) || !proxyService2)
return res;
nsRefPtr<nsProtocolProxyService> rawProxyService = do_QueryObject(proxyService);
if (!rawProxyService) {
return NS_ERROR_FAILURE;
}
ioService = do_GetService(NS_IOSERVICE_CONTRACTID, &res);
nsCOMPtr<nsIIOService> ioService = do_GetService(NS_IOSERVICE_CONTRACTID, &res);
if (NS_FAILED(res) || !ioService)
return res;
// make an nsURI from the argument url
res = ioService->NewURI(nsDependentCString(url), nullptr, nullptr, getter_AddRefs(uriIn));
// make a temporary channel from the argument url
nsCOMPtr<nsIChannel> tempChannel;
res = ioService->NewChannel(nsDependentCString(url), nullptr, nullptr, getter_AddRefs(tempChannel));
if (NS_FAILED(res))
return res;
nsCOMPtr<nsIProxyInfo> pi;
// Remove this with bug 778201
res = proxyService2->DeprecatedBlockingResolve(uriIn, 0, getter_AddRefs(pi));
// Remove this deprecated call in the future (see Bug 778201):
res = rawProxyService->DeprecatedBlockingResolve(tempChannel, 0, getter_AddRefs(pi));
if (NS_FAILED(res))
return res;

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

@ -510,14 +510,12 @@ void
nsCSPHostSrc::setPort(const nsAString& aPort)
{
mPort = aPort;
ToLowerCase(mPort);
}
void
nsCSPHostSrc::appendPath(const nsAString& aPath)
{
mPath.Append(aPath);
ToLowerCase(mPath);
}
/* ===== nsCSPKeywordSrc ===================== */

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

@ -7,6 +7,10 @@
// These dictionaries need to be in a separate file from their use in unions
// in MediaTrackConstraintSet.webidl due to a webidl compiler limitation.
// These enums are in the spec even though they're not used directly in the API
// due to https://www.w3.org/Bugs/Public/show_bug.cgi?id=19936
// Their binding code is quite useful though, and is used in the implementation.
enum VideoFacingModeEnum {
"user",
"environment",
@ -19,7 +23,9 @@ enum MediaSourceEnum {
"screen",
"application",
"window",
"browser"
"browser",
"microphone",
"other"
};
dictionary ConstrainLongRange {

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

@ -75,6 +75,7 @@ interface GlobalEventHandlers {
attribute EventHandler onprogress;
attribute EventHandler onratechange;
attribute EventHandler onreset;
attribute EventHandler onresize;
attribute EventHandler onscroll;
attribute EventHandler onseeked;
attribute EventHandler onseeking;
@ -130,7 +131,6 @@ interface WindowEventHandlers {
attribute EventHandler onpagehide;
attribute EventHandler onpageshow;
attribute EventHandler onpopstate;
attribute EventHandler onresize;
//(Not implemented)attribute EventHandler onstorage;
attribute EventHandler onunload;
};

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

@ -21,7 +21,7 @@ dictionary MediaTrackConstraints : MediaTrackConstraintSet {
// TODO(jib): Remove in 6+ weeks (Bug 997365)
dictionary MobileLegacyMediaTrackConstraintSet {
VideoFacingModeEnum facingMode;
DOMString facingMode;
};
interface MediaStreamTrack {

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

@ -22,24 +22,16 @@ enum SupportedAudioConstraints {
"other"
};
dictionary MediaTrackConstraintSet {
ConstrainLongRange width;
ConstrainLongRange height;
ConstrainDoubleRange frameRate;
ConstrainVideoFacingMode facingMode;
ConstrainMediaSource mediaSource = "camera";
ConstrainDOMString facingMode;
DOMString mediaSource = "camera";
long long browserWindow;
boolean scrollWithPage;
};
// TODO: Bug 995352 can't nest unions
//typedef (long or ConstrainLongRange) ConstrainLong;
//typedef (double or ConstrainDoubleRange) ConstrainDouble;
typedef VideoFacingModeEnum ConstrainVideoFacingMode;
typedef MediaSourceEnum ConstrainMediaSource;
// TODO: Bug 767924 sequences in unions
//typedef (VideoFacingModeEnum or sequence<VideoFacingModeEnum>) ConstrainVideoFacingMode;
//typedef (MediaSourceEnum or sequence<MediaSourceEnum>) ConstrainMediaSource;
typedef (long or ConstrainLongRange) ConstrainLong;
typedef (double or ConstrainDoubleRange) ConstrainDouble;
typedef (DOMString or sequence<DOMString>) ConstrainDOMString;

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

@ -4,21 +4,19 @@
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* http://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html
* http://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#service-worker-obj
*
*/
// Still unclear what should be subclassed.
// https://github.com/slightlyoff/ServiceWorker/issues/189
[Pref="dom.serviceWorkers.enabled",
// XXXbz I have no idea where this should be exposed. The spec makes
// no sense. But since it's got a pref, let's say window.
// FIXME(nsm): Bug 1113522. Should also be exposed on Workers too.
Exposed=Window]
interface ServiceWorker : EventTarget {
readonly attribute DOMString scope;
readonly attribute DOMString url;
readonly attribute USVString scriptURL;
readonly attribute ServiceWorkerState state;
attribute EventHandler onstatechange;
};

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

@ -2203,7 +2203,6 @@ RuntimeService::CreateServiceWorker(const GlobalObject& aGlobal,
new ServiceWorker(window, sharedWorker);
serviceWorker->mURL = aScriptURL;
serviceWorker->mScope = NS_ConvertUTF8toUTF16(aScope);
serviceWorker.forget(aServiceWorker);
return rv;
@ -2230,7 +2229,6 @@ RuntimeService::CreateServiceWorkerFromLoadInfo(JSContext* aCx,
new ServiceWorker(nullptr, sharedWorker);
serviceWorker->mURL = aScriptURL;
serviceWorker->mScope = NS_ConvertUTF8toUTF16(aScope);
serviceWorker.forget(aServiceWorker);
return rv;

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

@ -41,13 +41,7 @@ public:
}
void
GetScope(nsString& aScope) const
{
aScope = mScope;
}
void
GetUrl(nsString& aURL) const
GetScriptURL(nsString& aURL) const
{
aURL = mURL;
}
@ -63,7 +57,6 @@ private:
~ServiceWorker();
ServiceWorkerState mState;
nsString mScope;
nsString mURL;
// To allow ServiceWorkers to potentially drop the backing DOMEventTargetHelper and

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

@ -81,7 +81,7 @@ ServiceWorkerContainer::Register(const nsAString& aScriptURL,
return nullptr;
}
aRv = swm->Register(aOptions.mScope, aScriptURL, getter_AddRefs(promise));
aRv = swm->Register(GetOwner(), aOptions.mScope, aScriptURL, getter_AddRefs(promise));
if (aRv.Failed()) {
return nullptr;
}

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

@ -52,6 +52,7 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED(InstallPhaseEvent, Event, mPromise)
InstallEvent::InstallEvent(EventTarget* aOwner)
: InstallPhaseEvent(aOwner)
, mActivateImmediately(false)
{
}

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

@ -78,6 +78,7 @@ class InstallEvent MOZ_FINAL : public InstallPhaseEvent
{
// FIXME(nsm): Bug 982787 will allow actually populating this.
nsRefPtr<ServiceWorker> mActiveWorker;
bool mActivateImmediately;
protected:
explicit InstallEvent(mozilla::dom::EventTarget* aOwner);
@ -126,9 +127,14 @@ public:
void
Replace()
{
// FIXME(nsm): Unspecced. Bug 982711
NS_WARNING("Not Implemented");
mActivateImmediately = true;
};
bool
ActivateImmediately() const
{
return mActivateImmediately;
}
};
END_WORKERS_NAMESPACE

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -16,6 +16,7 @@
#include "mozilla/WeakPtr.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/ServiceWorkerBinding.h" // For ServiceWorkerState
#include "mozilla/dom/ServiceWorkerCommon.h"
#include "nsRefPtrHashtable.h"
#include "nsTArrayForwardDeclare.h"
@ -32,45 +33,6 @@ class ServiceWorkerRegistration;
namespace workers {
class ServiceWorker;
class ServiceWorkerUpdateInstance;
/**
* UpdatePromise is a utility class that sort of imitates Promise, but not
* completely. Using DOM Promise from C++ is a pain when we know the precise types
* we're dealing with since it involves dealing with JSAPI. In this case we
* also don't (yet) need the 'thenables added after resolution should trigger
* immediately' support and other things like that. All we want is something
* that works reasonably Promise like and can resolve real DOM Promises added
* pre-emptively.
*/
class UpdatePromise MOZ_FINAL
{
public:
UpdatePromise();
~UpdatePromise();
void AddPromise(Promise* aPromise);
void ResolveAllPromises(const nsACString& aScriptSpec, const nsACString& aScope);
void RejectAllPromises(nsresult aRv);
void RejectAllPromises(const ErrorEventInit& aErrorDesc);
bool
IsRejected() const
{
return mState == Rejected;
}
private:
enum {
Pending,
Resolved,
Rejected
} mState;
// XXXnsm: Right now we don't need to support AddPromise() after
// already being resolved (i.e. true Promise-like behaviour).
nsTArray<WeakPtr<Promise>> mPromises;
};
/*
* Wherever the spec treats a worker instance and a description of said worker
@ -81,6 +43,7 @@ private:
class ServiceWorkerInfo MOZ_FINAL
{
nsCString mScriptSpec;
ServiceWorkerState mState;
~ServiceWorkerInfo()
{ }
@ -96,7 +59,98 @@ public:
explicit ServiceWorkerInfo(const nsACString& aScriptSpec)
: mScriptSpec(aScriptSpec)
, mState(ServiceWorkerState::EndGuard_)
{ }
void
UpdateState(ServiceWorkerState aState)
{
#ifdef DEBUG
// Any state can directly transition to redundant, but everything else is
// ordered.
if (aState != ServiceWorkerState::Redundant) {
MOZ_ASSERT_IF(mState == ServiceWorkerState::EndGuard_, aState == ServiceWorkerState::Installing);
MOZ_ASSERT_IF(mState == ServiceWorkerState::Installing, aState == ServiceWorkerState::Installed);
MOZ_ASSERT_IF(mState == ServiceWorkerState::Installed, aState == ServiceWorkerState::Activating);
MOZ_ASSERT_IF(mState == ServiceWorkerState::Activating, aState == ServiceWorkerState::Activated);
}
// Activated can only go to redundant.
MOZ_ASSERT_IF(mState == ServiceWorkerState::Activated, aState == ServiceWorkerState::Redundant);
#endif
mState = aState;
// FIXME(nsm): Inform all relevant ServiceWorker instances.
}
};
class ServiceWorkerJobQueue;
class ServiceWorkerJob : public nsISupports
{
// The queue keeps the jobs alive, so they can hold a rawptr back to the
// queue.
ServiceWorkerJobQueue* mQueue;
public:
NS_DECL_ISUPPORTS
virtual void Start() = 0;
protected:
explicit ServiceWorkerJob(ServiceWorkerJobQueue* aQueue)
: mQueue(aQueue)
{
}
virtual ~ServiceWorkerJob()
{ }
void
Done(nsresult aStatus);
};
class ServiceWorkerJobQueue MOZ_FINAL
{
friend class ServiceWorkerJob;
nsTArray<nsRefPtr<ServiceWorkerJob>> mJobs;
public:
~ServiceWorkerJobQueue()
{
// FIXME(nsm): Clean up jobs.
MOZ_ASSERT(mJobs.IsEmpty());
}
void
Append(ServiceWorkerJob* aJob)
{
MOZ_ASSERT(aJob);
MOZ_ASSERT(!mJobs.Contains(aJob));
bool wasEmpty = mJobs.IsEmpty();
mJobs.AppendElement(aJob);
if (wasEmpty) {
aJob->Start();
}
}
private:
void
Pop()
{
MOZ_ASSERT(!mJobs.IsEmpty());
mJobs.RemoveElementAt(0);
if (!mJobs.IsEmpty()) {
mJobs[0]->Start();
}
}
void
Done(ServiceWorkerJob* aJob)
{
MOZ_ASSERT(!mJobs.IsEmpty());
MOZ_ASSERT(mJobs[0] == aJob);
Pop();
}
};
// Needs to inherit from nsISupports because NS_ProxyRelease() does not support
@ -115,30 +169,15 @@ public:
// the URLs of the following three workers.
nsCString mScriptSpec;
nsRefPtr<ServiceWorkerInfo> mCurrentWorker;
nsRefPtr<ServiceWorkerInfo> mActiveWorker;
nsRefPtr<ServiceWorkerInfo> mWaitingWorker;
nsRefPtr<ServiceWorkerInfo> mInstallingWorker;
nsAutoPtr<UpdatePromise> mUpdatePromise;
nsRefPtr<ServiceWorkerUpdateInstance> mUpdateInstance;
void
AddUpdatePromiseObserver(Promise* aPromise)
{
MOZ_ASSERT(HasUpdatePromise());
mUpdatePromise->AddPromise(aPromise);
}
bool
HasUpdatePromise()
{
return mUpdatePromise;
}
// When unregister() is called on a registration, it is not immediately
// removed since documents may be controlled. It is marked as
// pendingUninstall and when all controlling documents go away, removed.
bool mPendingUninstall;
bool mWaitingToActivate;
explicit ServiceWorkerRegistrationInfo(const nsACString& aScope);
@ -151,7 +190,7 @@ public:
} else if (mWaitingWorker) {
newest = mWaitingWorker;
} else {
newest = mCurrentWorker;
newest = mActiveWorker;
}
return newest.forget();
@ -172,11 +211,20 @@ public:
bool
IsControllingDocuments() const
{
return mControlledDocumentsCounter > 0;
return mActiveWorker && mControlledDocumentsCounter > 0;
}
void
Clear();
void
TryToActivate();
void
Activate();
void
FinishActivate(bool aSuccess);
};
#define NS_SERVICEWORKERMANAGER_IMPL_IID \
@ -195,14 +243,13 @@ public:
class ServiceWorkerManager MOZ_FINAL : public nsIServiceWorkerManager
{
friend class ActivationRunnable;
friend class RegisterRunnable;
friend class CallInstallRunnable;
friend class CancelServiceWorkerInstallationRunnable;
friend class ServiceWorkerRegistrationInfo;
friend class ServiceWorkerUpdateInstance;
friend class ServiceWorkerRegisterJob;
friend class GetReadyPromiseRunnable;
friend class GetRegistrationsRunnable;
friend class GetRegistrationRunnable;
friend class QueueFireUpdateFoundRunnable;
friend class UnregisterRunnable;
public:
NS_DECL_ISUPPORTS
@ -244,6 +291,8 @@ public:
nsRefPtrHashtable<nsISupportsHashKey, ServiceWorkerRegistrationInfo> mControlledDocuments;
nsClassHashtable<nsCStringHashKey, ServiceWorkerJobQueue> mJobQueues;
ServiceWorkerDomainInfo()
{ }
@ -275,6 +324,12 @@ public:
mServiceWorkerRegistrationInfos.Remove(aRegistration->mScope);
}
ServiceWorkerJobQueue*
GetOrCreateJobQueue(const nsCString& aScope)
{
return mJobQueues.LookupOrAdd(aScope);
}
NS_INLINE_DECL_REFCOUNTING(ServiceWorkerDomainInfo)
private:
@ -284,26 +339,9 @@ public:
nsRefPtrHashtable<nsCStringHashKey, ServiceWorkerDomainInfo> mDomainMap;
void
ResolveRegisterPromises(ServiceWorkerRegistrationInfo* aRegistration,
const nsACString& aWorkerScriptSpec);
void
RejectUpdatePromiseObservers(ServiceWorkerRegistrationInfo* aRegistration,
nsresult aResult);
void
RejectUpdatePromiseObservers(ServiceWorkerRegistrationInfo* aRegistration,
const ErrorEventInit& aErrorDesc);
void
FinishFetch(ServiceWorkerRegistrationInfo* aRegistration);
void
FinishInstall(ServiceWorkerRegistrationInfo* aRegistration);
void
FinishActivate(ServiceWorkerRegistrationInfo* aRegistration);
void
HandleError(JSContext* aCx,
@ -333,10 +371,6 @@ private:
nsresult
Update(ServiceWorkerRegistrationInfo* aRegistration);
void
Install(ServiceWorkerRegistrationInfo* aRegistration,
ServiceWorkerInfo* aServiceWorkerInfo);
NS_IMETHOD
CreateServiceWorkerForWindow(nsPIDOMWindow* aWindow,
const nsACString& aScriptSpec,
@ -390,10 +424,17 @@ private:
static void
RemoveScope(nsTArray<nsCString>& aList, const nsACString& aScope);
void
QueueFireEventOnServiceWorkerRegistrations(ServiceWorkerRegistrationInfo* aRegistration,
const nsAString& aName);
void
FireEventOnServiceWorkerRegistrations(ServiceWorkerRegistrationInfo* aRegistration,
const nsAString& aName);
void
FireControllerChange(ServiceWorkerRegistrationInfo* aRegistration);
void
StorePendingReadyPromise(nsPIDOMWindow* aWindow, nsIURI* aURI, Promise* aPromise);

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

@ -237,7 +237,9 @@ ServiceWorkerRegistration::GetWorkerReference(WhichServiceWorker aWhichOne)
MOZ_CRASH("Invalid enum value");
}
if (NS_WARN_IF(NS_FAILED(rv))) {
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv) || rv == NS_ERROR_DOM_NOT_FOUND_ERR,
"Unexpected error getting service worker instance from ServiceWorkerManager");
if (NS_FAILED(rv)) {
return nullptr;
}

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

@ -462,14 +462,14 @@ GetterOnlyJSNative(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
namespace {
class UnregisterRunnable;
class WorkerScopeUnregisterRunnable;
class UnregisterResultRunnable MOZ_FINAL : public WorkerRunnable
{
public:
enum State { Succeeded, Failed };
UnregisterResultRunnable(WorkerPrivate* aWorkerPrivate,
UnregisterRunnable* aRunnable,
WorkerScopeUnregisterRunnable* aRunnable,
State aState, bool aValue)
: WorkerRunnable(aWorkerPrivate,
WorkerThreadUnchangedBusyCount)
@ -483,14 +483,14 @@ public:
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) MOZ_OVERRIDE;
private:
nsRefPtr<UnregisterRunnable> mRunnable;
nsRefPtr<WorkerScopeUnregisterRunnable> mRunnable;
State mState;
bool mValue;
};
class UnregisterRunnable MOZ_FINAL : public nsRunnable
, public nsIServiceWorkerUnregisterCallback
, public WorkerFeature
class WorkerScopeUnregisterRunnable MOZ_FINAL : public nsRunnable
, public nsIServiceWorkerUnregisterCallback
, public WorkerFeature
{
WorkerPrivate* mWorkerPrivate;
nsRefPtr<Promise> mWorkerPromise;
@ -500,9 +500,9 @@ class UnregisterRunnable MOZ_FINAL : public nsRunnable
public:
NS_DECL_ISUPPORTS_INHERITED
UnregisterRunnable(WorkerPrivate* aWorkerPrivate,
Promise* aWorkerPromise,
const nsAString& aScope)
WorkerScopeUnregisterRunnable(WorkerPrivate* aWorkerPrivate,
Promise* aWorkerPromise,
const nsAString& aScope)
: mWorkerPrivate(aWorkerPrivate)
, mWorkerPromise(aWorkerPromise)
, mScope(aScope)
@ -564,7 +564,7 @@ public:
}
private:
~UnregisterRunnable()
~WorkerScopeUnregisterRunnable()
{
MOZ_ASSERT(mCleanedUp);
}
@ -604,7 +604,7 @@ private:
}
};
NS_IMPL_ISUPPORTS_INHERITED(UnregisterRunnable, nsRunnable,
NS_IMPL_ISUPPORTS_INHERITED(WorkerScopeUnregisterRunnable, nsRunnable,
nsIServiceWorkerUnregisterCallback)
bool
@ -635,8 +635,8 @@ ServiceWorkerGlobalScope::Unregister(ErrorResult& aRv)
return nullptr;
}
nsRefPtr<UnregisterRunnable> runnable =
new UnregisterRunnable(mWorkerPrivate, promise, mScope);
nsRefPtr<WorkerScopeUnregisterRunnable> runnable =
new WorkerScopeUnregisterRunnable(mWorkerPrivate, promise, mScope);
NS_DispatchToMainThread(runnable);
return promise.forget();

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

@ -24,37 +24,42 @@
window.opener.postMessage({status: "done"}, "*");
}
if (navigator.serviceWorker.controller) {
my_ok(navigator.serviceWorker.controller.scope.match(/serviceworkers\/control$/),
navigator.serviceWorker.ready.then(function(swr) {
my_ok(swr.scope.match(/serviceworkers\/control$/),
"This page should be controlled by upper level registration");
my_ok(navigator.serviceWorker.installing == undefined,
my_ok(swr.installing == undefined,
"Upper level registration should not have a installing worker.");
// We are controlled.
// Register a new worker for this sub-scope. After that, controller should still be for upper level, but active should change to be this scope's.
navigator.serviceWorker.register("../worker2.js", { scope: "./" }).then(function(e) {
my_ok("installing" in e, "ServiceWorkerRegistration.installing exists.");
my_ok(e.installing instanceof ServiceWorker, "ServiceWorkerRegistration.installing is a ServiceWorker.");
if (navigator.serviceWorker.controller) {
// We are controlled.
// Register a new worker for this sub-scope. After that, controller should still be for upper level, but active should change to be this scope's.
navigator.serviceWorker.register("../worker2.js", { scope: "./" }).then(function(e) {
my_ok("installing" in e, "ServiceWorkerRegistration.installing exists.");
my_ok(e.installing instanceof ServiceWorker, "ServiceWorkerRegistration.installing is a ServiceWorker.");
my_ok("waiting" in e, "ServiceWorkerRegistration.waiting exists.");
my_ok("active" in e, "ServiceWorkerRegistration.active exists.");
my_ok("waiting" in e, "ServiceWorkerRegistration.waiting exists.");
my_ok("active" in e, "ServiceWorkerRegistration.active exists.");
my_ok(e.installing &&
e.installing.scope.match(/controller\/$/),
"Installing is serviceworker/controller");
my_ok(e.installing &&
e.installing.scriptURL.match(/worker2.js$/),
"Installing is serviceworker/controller");
my_ok("scope" in e, "ServiceWorkerRegistration.scope exists.");
my_ok(e.scope.match(/serviceworkers\/controller\/$/), "Scope is serviceworker/controller " + e.scope);
my_ok("scope" in e, "ServiceWorkerRegistration.scope exists.");
my_ok(e.scope.match(/serviceworkers\/controller\/$/), "Scope is serviceworker/controller " + e.scope);
my_ok("unregister" in e, "ServiceWorkerRegistration.unregister exists.");
my_ok("unregister" in e, "ServiceWorkerRegistration.unregister exists.");
my_ok(navigator.serviceWorker.controller.scope.match(/serviceworkers\/control$/),
"Controller is still serviceworker/control");
my_ok(navigator.serviceWorker.controller.scriptURL.match(/worker\.js$/),
"Controller is still worker.js");
finish();
});
} else {
my_ok(false, "Should've been controlled!");
finish();
});
} else {
my_ok(false, "Should've been controlled!");
}
}).catch(function(e) {
my_ok(false, "Some test threw an error " + e);
finish();
}
});
</script>
</pre>
</body>

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

@ -10,8 +10,10 @@ support-files =
simpleregister/ready.html
controller/index.html
unregister/index.html
workerUpdate/update.html
sw_clients/simple.html
get_serviced_worker.js
worker_update.js
[test_unregister.html]
skip-if = true # bug 1094375
@ -22,3 +24,5 @@ skip-if = true # bug 1094375
[test_navigator.html]
[test_scopes.html]
[test_controller.html]
[test_workerUpdate.html]
skip-if = true # Enable after Bug 982726 postMessage is landed.

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

@ -66,9 +66,9 @@
// because the registration is for the realworker scope, so the workers
// should be obtained for that scope and not for
// test_installation_simple.html
var worker = wr.installing || wr.waiting || wr.active;
ok(worker && worker.scope.match(/realworker$/) &&
worker.url.match(/worker.js$/), "Valid worker instance should be available.");
var worker = wr.installing;
ok(worker && wr.scope.match(/realworker$/) &&
worker.scriptURL.match(/worker.js$/), "Valid worker instance should be available.");
}, function(e) {
info("Error: " + e.name);
ok(false, "realWorker Registration should have succeeded!");

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

@ -0,0 +1,54 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE HTML>
<html>
<head>
<title>Bug 1065366 - Test ServiceWorkerGlobalScope.update</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<div id="container"></div>
<script class="testbody" type="text/javascript">
function simpleRegister() {
return navigator.serviceWorker.register("worker_update.js", { scope: "workerUpdate/" });
}
function waitForMessages(sw) {
var p = new Promise(function(resolve, reject) {
window.onmessage = function(e) {
if (e.data === "FINISH") {
ok(true, "The worker has updated itself");
resolve();
}
}
});
var frame = document.createElement("iframe");
frame.setAttribute("src", "workerUpdate/update.html");
document.body.appendChild(frame);
return p;
}
function runTest() {
simpleRegister().then(waitForMessages).catch(function(e) {
ok(false, "Something went wrong.");
}).then(function() {
SimpleTest.finish();
});
}
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]
]}, runTest);
</script>
</pre>
</body>
</html>

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

@ -0,0 +1,24 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE HTML>
<html>
<head>
<title>Test worker::update</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<script type="text/javascript">
onmessage = function(e) { parent.postMessage(e.data, "*"); }
navigator.serviceWorker.ready.then(function() {
navigator.serviceWorker.controller.postMessage("GO");
});
</script>
</pre>
</body>
</html>

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

@ -0,0 +1,14 @@
// For now this test only calls update to verify that our registration
// job queueing works properly when called from the worker thread. We should
// test actual update scenarios with a SJS test.
onmessage = function(e) {
self.update();
clients.getServiced().then(function(c) {
if (c.length == 0) {
// We cannot proceed.
return;
}
c[0].postMessage('FINISH');
});
}

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

@ -9,6 +9,8 @@
#include <cmath>
#include "mozilla/Attributes.h"
#include "mozilla/ToString.h"
#include "mozilla/FloatingPoint.h"
#include "mozilla/TypeTraits.h"
namespace mozilla {
namespace gfx {
@ -80,6 +82,14 @@ struct BasePoint {
return *static_cast<Sub*>(this);
}
// "Finite" means not inf and not NaN
bool IsFinite() const
{
typedef typename mozilla::Conditional<mozilla::IsSame<T, float>::value, float, double>::Type FloatType;
return (mozilla::IsFinite(FloatType(x)) && mozilla::IsFinite(FloatType(y)));
return true;
}
friend std::ostream& operator<<(std::ostream& stream, const BasePoint<T, Sub, Coord>& aPoint) {
return stream << '(' << aPoint.x << ',' << aPoint.y << ')';
}

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

@ -571,13 +571,13 @@ Factory::CreateDualDrawTargetForD3D10Textures(ID3D10Texture2D *aTextureA,
newTargetA = new DrawTargetD2D();
if (!newTargetA->Init(aTextureA, aFormat)) {
gfxWarning() << "Failed to create draw target for D3D10 texture.";
gfxWarning() << "Failed to create dual draw target for D3D10 texture.";
return nullptr;
}
newTargetB = new DrawTargetD2D();
if (!newTargetB->Init(aTextureB, aFormat)) {
gfxWarning() << "Failed to create draw target for D3D10 texture.";
gfxWarning() << "Failed to create new draw target for D3D10 texture.";
return nullptr;
}
@ -633,7 +633,7 @@ Factory::CreateDrawTargetForD3D11Texture(ID3D11Texture2D *aTexture, SurfaceForma
return retVal;
}
gfxWarning() << "Failed to create draw target for D3D10 texture.";
gfxWarning() << "Failed to create draw target for D3D11 texture.";
// Failed
return nullptr;

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

@ -20,12 +20,19 @@ PathBuilderCG::~PathBuilderCG()
void
PathBuilderCG::MoveTo(const Point &aPoint)
{
if (!aPoint.IsFinite()) {
return;
}
CGPathMoveToPoint(mCGPath, nullptr, aPoint.x, aPoint.y);
}
void
PathBuilderCG::LineTo(const Point &aPoint)
{
if (!aPoint.IsFinite()) {
return;
}
if (CGPathIsEmpty(mCGPath))
MoveTo(aPoint);
else
@ -37,6 +44,9 @@ PathBuilderCG::BezierTo(const Point &aCP1,
const Point &aCP2,
const Point &aCP3)
{
if (!aCP1.IsFinite() || !aCP2.IsFinite() || !aCP3.IsFinite()) {
return;
}
if (CGPathIsEmpty(mCGPath))
MoveTo(aCP1);
@ -49,13 +59,17 @@ PathBuilderCG::BezierTo(const Point &aCP1,
void
PathBuilderCG::QuadraticBezierTo(const Point &aCP1,
const Point &aCP2)
const Point &aCP2)
{
if (!aCP1.IsFinite() || !aCP2.IsFinite()) {
return;
}
if (CGPathIsEmpty(mCGPath))
MoveTo(aCP1);
CGPathAddQuadCurveToPoint(mCGPath, nullptr,
aCP1.x, aCP1.y,
aCP2.x, aCP2.y);
aCP1.x, aCP1.y,
aCP2.x, aCP2.y);
}
void
@ -69,6 +83,11 @@ void
PathBuilderCG::Arc(const Point &aOrigin, Float aRadius, Float aStartAngle,
Float aEndAngle, bool aAntiClockwise)
{
if (!aOrigin.IsFinite() || !IsFinite(aRadius) ||
!IsFinite(aStartAngle) || !IsFinite(aEndAngle)) {
return;
}
// Disabled for now due to a CG bug when using CGPathAddArc with stroke
// dashing and rotation transforms that are multiples of 90 degrees. See:
// https://bugzilla.mozilla.org/show_bug.cgi?id=949661#c8

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

@ -364,7 +364,7 @@ RotatedContentBuffer::EnsureBufferOnWhite()
}
NS_WARN_IF_FALSE(mDTBufferOnWhite, "no buffer");
return mDTBufferOnWhite;
return !!mDTBufferOnWhite;
}
bool

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

@ -198,7 +198,7 @@ ParentLayerCoord Axis::GetOverscroll() const {
ParentLayerCoord result = (mOverscroll - mOverscrollOffset) / mOverscrollScale;
// Assert that we return overscroll in the correct direction
MOZ_ASSERT((result.value * mOverscrollOffset.value) >= 0.0f);
MOZ_ASSERT((result.value * mFirstOverscrollAnimationSample.value) >= 0.0f);
return result;
}

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