Merge inbound to m-c. a=merge

This commit is contained in:
Ryan VanderMeulen 2015-04-30 13:56:09 -04:00
commit 4e0f4f8c6c
214 changed files with 2744 additions and 1219 deletions

View File

@ -22,4 +22,5 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 1154356: escape variable name in Declaration::AppendVariableAndValueToString;
Bug 1159082 - Renaming *Readonly animation interfaces to *ReadOnly causes
build bustage on case-insensitive filesystems.

View File

@ -318,6 +318,11 @@ pref("media.cache_readahead_limit", 30);
// Enable/Disable Gonk Decoder Module
pref("media.fragmented-mp4.gonk.enabled", true);
#endif
//Encrypted media extensions.
pref("media.eme.enabled", true);
pref("media.eme.apiVisible", true);
// The default number of decoded video frames that are enqueued in
// MediaDecoderReader's mVideoQueue.
pref("media.video-queue.default-size", 3);

View File

@ -464,18 +464,22 @@
</div>
<div id="certificateErrorReportingPanel">
<p>&errorReporting.longDesc;</p>
<p>
<input type="checkbox" id="automaticallyReportInFuture" />
<label for="automaticallyReportInFuture" id="automaticallyReportInFuture">&errorReporting.automatic;</label>
</p>
<a href="https://support.mozilla.org/kb/tls-error-reports" id="learnMoreLink" target="new">&errorReporting.learnMore;</a>
<span id="reportingState">
<button id="reportCertificateError">&errorReporting.report;</button>
<button id="reportCertificateErrorRetry">&errorReporting.tryAgain;</button>
<span id="reportSendingMessage">&errorReporting.sending;</span>
<span id="reportSentMessage">&errorReporting.sent;</span>
</span>
<div id="certificateErrorReportingDescription">
<p>&errorReporting.longDesc;</p>
<p>
<input type="checkbox" id="automaticallyReportInFuture" />
<label for="automaticallyReportInFuture" id="automaticallyReportInFuture">&errorReporting.automatic;</label>
</p>
</div>
<div id="errorStatePanel">
<a href="https://support.mozilla.org/kb/tls-error-reports" id="learnMoreLink" target="new">&errorReporting.learnMore;</a>
<span id="reportingState">
<button id="reportCertificateError">&errorReporting.report;</button>
<button id="reportCertificateErrorRetry">&errorReporting.tryAgain;</button>
<span id="reportSendingMessage">&errorReporting.sending;</span>
<span id="reportSentMessage">&errorReporting.sent;</span>
</span>
</div>
</div>
</div>

View File

@ -28,10 +28,6 @@
command="Tools:PrivateBrowsing"
key="key_privatebrowsing"/>
#ifdef E10S_TESTING_ONLY
<menuitem id="menu_newRemoteWindow"
label="New e10s Window"
hidden="true"
command="Tools:RemoteWindow"/>
<menuitem id="menu_newNonRemoteWindow"
label="New Non-e10s Window"
hidden="true"

View File

@ -114,8 +114,6 @@
<command id="Tools:PrivateBrowsing"
oncommand="OpenBrowserWindow({private: true});" reserved="true"/>
#ifdef E10S_TESTING_ONLY
<command id="Tools:RemoteWindow"
oncommand="OpenBrowserWindow({remote: true});"/>
<command id="Tools:NonRemoteWindow"
oncommand="OpenBrowserWindow({remote: false});"/>
#endif

View File

@ -7230,10 +7230,8 @@ let gRemoteTabsUI = {
}
#endif
let newRemoteWindow = document.getElementById("menu_newRemoteWindow");
let newNonRemoteWindow = document.getElementById("menu_newNonRemoteWindow");
let autostart = Services.appinfo.browserTabsRemoteAutostart;
newRemoteWindow.hidden = autostart;
newNonRemoteWindow.hidden = !autostart;
}
};

View File

@ -208,6 +208,15 @@ let AboutNetErrorListener = {
if (automatic) {
this.onSendReport(evt);
}
// hide parts of the UI we don't need yet
let contentDoc = content.document;
let reportSendingMsg = contentDoc.getElementById("reportSendingMessage");
let reportSentMsg = contentDoc.getElementById("reportSentMessage");
let retryBtn = contentDoc.getElementById("reportCertificateErrorRetry");
reportSendingMsg.style.display = "none";
reportSentMsg.style.display = "none";
retryBtn.style.display = "none";
},
onSetAutomatic: function(evt) {
@ -234,23 +243,22 @@ let AboutNetErrorListener = {
reportBtn.style.display = "none";
retryBtn.style.display = "none";
reportSentMsg.style.display = "none";
reportSendingMsg.style.display = "inline";
reportSendingMsg.style.removeProperty("display");
break;
case "error":
// show the retry button
retryBtn.style.display = "inline";
retryBtn.style.removeProperty("display");
reportSendingMsg.style.display = "none";
break;
case "complete":
// Show a success indicator
reportSentMsg.style.display = "inline";
reportSentMsg.style.removeProperty("display");
reportSendingMsg.style.display = "none";
break;
}
}
});
let failedChannel = docShell.failedChannel;
let location = contentDoc.location.href;

View File

@ -531,15 +531,11 @@
<body><![CDATA[
var rv = true;
if (!aBrowser)
aBrowser = this.mCurrentBrowser;
if (aCallGlobalListeners != false &&
aBrowser == this.mCurrentBrowser) {
for (let p of this.mProgressListeners) {
function callListeners(listeners, args) {
for (let p of listeners) {
if (aMethod in p) {
try {
if (!p[aMethod].apply(p, aArguments))
if (!p[aMethod].apply(p, args))
rv = false;
} catch (e) {
// don't inhibit other listeners
@ -549,20 +545,18 @@
}
}
if (!aBrowser)
aBrowser = this.mCurrentBrowser;
if (aCallGlobalListeners != false &&
aBrowser == this.mCurrentBrowser) {
callListeners(this.mProgressListeners, aArguments);
}
if (aCallTabsListeners != false) {
aArguments.unshift(aBrowser);
for (let p of this.mTabsProgressListeners) {
if (aMethod in p) {
try {
if (!p[aMethod].apply(p, aArguments))
rv = false;
} catch (e) {
// don't inhibit other listeners
Components.utils.reportError(e);
}
}
}
callListeners(this.mTabsProgressListeners, aArguments);
}
return rv;
@ -1518,13 +1512,11 @@
aBrowser.webProgress.addProgressListener(filter, Ci.nsIWebProgress.NOTIFY_ALL);
if (aShouldBeRemote) {
tab.setAttribute("remote", "true");
// Switching the browser to be remote will connect to a new child
// process so the browser can no longer be considered to be
// crashed.
tab.removeAttribute("crashed");
} else {
tab.removeAttribute("remote");
aBrowser.messageManager.sendAsyncMessage("Browser:AppTab", { isAppTab: tab.pinned })
}
@ -1741,8 +1733,6 @@
let remote = gMultiProcessBrowser &&
!aForceNotRemote &&
E10SUtils.canLoadURIInProcess(aURI, Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT);
if (remote)
t.setAttribute("remote", "true");
this.tabContainer._unlockTabSizing();
@ -3685,9 +3675,11 @@
event.preventDefault();
return;
}
event.target.setAttribute("label", tab.mOverCloseButton ?
tab.getAttribute("closetabtext") :
tab.getAttribute("label"));
event.target.setAttribute("label",
tab.mOverCloseButton ?
tab.getAttribute("closetabtext") :
tab.getAttribute("label") +
(this.AppConstants.E10S_TESTING_ONLY && tab.linkedBrowser && tab.linkedBrowser.isRemoteBrowser ? " - e10s" : ""));
]]></body>
</method>

View File

@ -115,7 +115,7 @@ function delayed(aIsSelectedTab) {
if (!aIsSelectedTab) {
// If this was a background request, go on a foreground request.
content.location = REDIRECT_FROM + "#FG";
gBrowser.selectedBrowser.loadURI(REDIRECT_FROM + "#FG");
}
else {
// Othrewise, nothing to do remains.

View File

@ -107,64 +107,64 @@ let forward = Task.async(function*() {
// Tests that navigating from a page that should be in the remote process and
// a page that should be in the main process works and retains history
add_task(function* test_navigation() {
let expectedRemote = gMultiProcessBrowser ? "true" : "";
let expectedRemote = gMultiProcessBrowser;
info("1");
// Create a tab and load a remote page in it
gBrowser.selectedTab = gBrowser.addTab("about:blank", {skipAnimation: true});
let {permanentKey} = gBrowser.selectedBrowser;
yield waitForLoad("http://example.org/" + DUMMY_PATH);
is(gBrowser.selectedTab.getAttribute("remote"), expectedRemote, "Remote attribute should be correct");
is(gBrowser.selectedBrowser.isRemoteBrowser, expectedRemote, "Remote attribute should be correct");
is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
info("2");
// Load another page
yield waitForLoad("http://example.com/" + DUMMY_PATH);
is(gBrowser.selectedTab.getAttribute("remote"), expectedRemote, "Remote attribute should be correct");
is(gBrowser.selectedBrowser.isRemoteBrowser, expectedRemote, "Remote attribute should be correct");
is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
yield check_history();
info("3");
// Load a non-remote page
yield waitForLoad("about:robots");
is(gBrowser.selectedTab.getAttribute("remote"), "", "Remote attribute should be correct");
is(gBrowser.selectedBrowser.isRemoteBrowser, false, "Remote attribute should be correct");
is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
yield check_history();
info("4");
// Load a remote page
yield waitForLoad("http://example.org/" + DUMMY_PATH);
is(gBrowser.selectedTab.getAttribute("remote"), expectedRemote, "Remote attribute should be correct");
is(gBrowser.selectedBrowser.isRemoteBrowser, expectedRemote, "Remote attribute should be correct");
is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
yield check_history();
info("5");
yield back();
is(gBrowser.selectedTab.getAttribute("remote"), "", "Remote attribute should be correct");
is(gBrowser.selectedBrowser.isRemoteBrowser, false, "Remote attribute should be correct");
is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
yield check_history();
info("6");
yield back();
is(gBrowser.selectedTab.getAttribute("remote"), expectedRemote, "Remote attribute should be correct");
is(gBrowser.selectedBrowser.isRemoteBrowser, expectedRemote, "Remote attribute should be correct");
is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
yield check_history();
info("7");
yield forward();
is(gBrowser.selectedTab.getAttribute("remote"), "", "Remote attribute should be correct");
is(gBrowser.selectedBrowser.isRemoteBrowser, false, "Remote attribute should be correct");
is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
yield check_history();
info("8");
yield forward();
is(gBrowser.selectedTab.getAttribute("remote"), expectedRemote, "Remote attribute should be correct");
is(gBrowser.selectedBrowser.isRemoteBrowser, expectedRemote, "Remote attribute should be correct");
is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
yield check_history();
info("9");
yield back();
is(gBrowser.selectedTab.getAttribute("remote"), "", "Remote attribute should be correct");
is(gBrowser.selectedBrowser.isRemoteBrowser, false, "Remote attribute should be correct");
is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
yield check_history();
@ -172,7 +172,7 @@ add_task(function* test_navigation() {
// Load a new remote page, this should replace the last history entry
gExpectedHistory.entries.splice(gExpectedHistory.entries.length - 1, 1);
yield waitForLoad("http://example.com/" + DUMMY_PATH);
is(gBrowser.selectedTab.getAttribute("remote"), expectedRemote, "Remote attribute should be correct");
is(gBrowser.selectedBrowser.isRemoteBrowser, expectedRemote, "Remote attribute should be correct");
is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
yield check_history();
@ -184,36 +184,36 @@ add_task(function* test_navigation() {
// Tests that calling gBrowser.loadURI or browser.loadURI to load a page in a
// different process updates the browser synchronously
add_task(function* test_synchronous() {
let expectedRemote = gMultiProcessBrowser ? "true" : "";
let expectedRemote = gMultiProcessBrowser;
info("1");
// Create a tab and load a remote page in it
gBrowser.selectedTab = gBrowser.addTab("about:blank", {skipAnimation: true});
let {permanentKey} = gBrowser.selectedBrowser;
yield waitForLoad("http://example.org/" + DUMMY_PATH);
is(gBrowser.selectedTab.getAttribute("remote"), expectedRemote, "Remote attribute should be correct");
is(gBrowser.selectedBrowser.isRemoteBrowser, expectedRemote, "Remote attribute should be correct");
is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
info("2");
// Load another page
info("Loading about:robots");
gBrowser.selectedBrowser.loadURI("about:robots");
is(gBrowser.selectedTab.getAttribute("remote"), "", "Remote attribute should be correct");
is(gBrowser.selectedBrowser.isRemoteBrowser, false, "Remote attribute should be correct");
is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
yield waitForDocLoadComplete();
is(gBrowser.selectedTab.getAttribute("remote"), "", "Remote attribute should be correct");
is(gBrowser.selectedBrowser.isRemoteBrowser, false, "Remote attribute should be correct");
is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
info("3");
// Load the remote page again
info("Loading http://example.org/" + DUMMY_PATH);
gBrowser.loadURI("http://example.org/" + DUMMY_PATH);
is(gBrowser.selectedTab.getAttribute("remote"), expectedRemote, "Remote attribute should be correct");
is(gBrowser.selectedBrowser.isRemoteBrowser, expectedRemote, "Remote attribute should be correct");
is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
yield waitForDocLoadComplete();
is(gBrowser.selectedTab.getAttribute("remote"), expectedRemote, "Remote attribute should be correct");
is(gBrowser.selectedBrowser.isRemoteBrowser, expectedRemote, "Remote attribute should be correct");
is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
info("4");
@ -224,31 +224,31 @@ add_task(function* test_synchronous() {
// Tests that load flags are correctly passed through to the child process with
// normal loads
add_task(function* test_loadflags() {
let expectedRemote = gMultiProcessBrowser ? "true" : "";
let expectedRemote = gMultiProcessBrowser;
info("1");
// Create a tab and load a remote page in it
gBrowser.selectedTab = gBrowser.addTab("about:blank", {skipAnimation: true});
yield waitForLoadWithFlags("about:robots");
is(gBrowser.selectedTab.getAttribute("remote"), "", "Remote attribute should be correct");
is(gBrowser.selectedBrowser.isRemoteBrowser, false, "Remote attribute should be correct");
yield check_history();
info("2");
// Load a page in the remote process with some custom flags
yield waitForLoadWithFlags("http://example.com/" + DUMMY_PATH, Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY);
is(gBrowser.selectedTab.getAttribute("remote"), expectedRemote, "Remote attribute should be correct");
is(gBrowser.selectedBrowser.isRemoteBrowser, expectedRemote, "Remote attribute should be correct");
yield check_history();
info("3");
// Load a non-remote page
yield waitForLoadWithFlags("about:robots");
is(gBrowser.selectedTab.getAttribute("remote"), "", "Remote attribute should be correct");
is(gBrowser.selectedBrowser.isRemoteBrowser, false, "Remote attribute should be correct");
yield check_history();
info("4");
// Load another remote page
yield waitForLoadWithFlags("http://example.org/" + DUMMY_PATH, Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY);
is(gBrowser.selectedTab.getAttribute("remote"), expectedRemote, "Remote attribute should be correct");
is(gBrowser.selectedBrowser.isRemoteBrowser, expectedRemote, "Remote attribute should be correct");
yield check_history();
is(gExpectedHistory.entries.length, 2, "Should end with the right number of history entries");

View File

@ -1217,27 +1217,6 @@ if (Services.prefs.getBoolPref("browser.pocket.enabled")) {
}
#ifdef E10S_TESTING_ONLY
/**
* The e10s button's purpose is to lower the barrier of entry
* for our Nightly testers to use e10s windows. We'll be removing it
* once remote tabs are enabled. This button should never ever make it
* to production. If it does, that'd be bad, and we should all feel bad.
*/
let getCommandFunction = function(aOpenRemote) {
return function(aEvent) {
let win = aEvent.view;
if (win && typeof win.OpenBrowserWindow == "function") {
win.OpenBrowserWindow({remote: aOpenRemote});
}
};
}
let openRemote = !Services.appinfo.browserTabsRemoteAutostart;
// Like the XUL menuitem counterparts, we hard-code these strings in because
// this button should never roll into production.
let buttonLabel = openRemote ? "New e10s Window"
: "New Non-e10s Window";
let e10sDisabled = Services.appinfo.inSafeMode;
#ifdef XP_MACOSX
// On OS X, "Disable Hardware Acceleration" also disables OMTC and forces
@ -1245,12 +1224,19 @@ let e10sDisabled = Services.appinfo.inSafeMode;
e10sDisabled |= Services.prefs.getBoolPref("layers.acceleration.disabled");
#endif
CustomizableWidgets.push({
id: "e10s-button",
label: buttonLabel,
tooltiptext: buttonLabel,
disabled: e10sDisabled,
defaultArea: CustomizableUI.AREA_PANEL,
onCommand: getCommandFunction(openRemote),
});
if (Services.appinfo.browserTabsRemoteAutostart) {
CustomizableWidgets.push({
id: "e10s-button",
label: "New Non-e10s Window",
tooltiptext: "New Non-e10s Window",
disabled: e10sDisabled,
defaultArea: CustomizableUI.AREA_PANEL,
onCommand: function(aEvent) {
let win = aEvent.view;
if (win && typeof win.OpenBrowserWindow == "function") {
win.OpenBrowserWindow({remote: false});
}
},
});
}
#endif

View File

@ -120,6 +120,15 @@ div#certificateErrorReportingPanel:-moz-dir(rtl) {
right: 0;
}
#errorStatePanel {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
align-content: space-between;
align-items: flex-start;
}
span#hostname {
font-weight: bold;
}
@ -128,25 +137,12 @@ span#hostname {
cursor: pointer;
}
#reportingState {
padding-left: 150px;
}
#reportSendingMessage {
position: relative;
display: none;
/* adjust the line-height to match the link */
line-height: 22px;
}
#reportSentMessage {
position: relative;
display: none;
}
button#reportCertificateError {
position: relative;
}
button#reportCertificateErrorRetry {
position: relative;
display: none;
/* adjust the line-height to match the link */
line-height: 22px;
}

View File

@ -42,10 +42,6 @@
-moz-box-align: stretch;
}
.tabbrowser-tab[remote] {
text-decoration: underline;
}
/* The selected tab should appear above adjacent tabs, .tabs-newtab-button and the highlight of #nav-bar */
.tabbrowser-tab[visuallyselected=true] {
position: relative;

View File

@ -1500,9 +1500,11 @@ if test "$GNU_CC"; then
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=return-type"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=sequence-point"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=trigraphs"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=uninitialized"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=unknown-pragmas"
MOZ_C_SUPPORTS_WARNING(-Werror=, non-literal-null-conversion, ac_c_has_werror_non_literal_null_conversion)
MOZ_C_SUPPORTS_WARNING(-Werror=, sometimes-uninitialized, ac_c_has_sometimes_uninitialized)
fi
# Turn off the following warnings that -Wall turns on:
@ -1593,9 +1595,11 @@ if test "$GNU_CXX"; then
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=switch"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=trigraphs"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=type-limits"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=uninitialized"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=unused-label"
MOZ_CXX_SUPPORTS_WARNING(-Werror=, non-literal-null-conversion, ac_cxx_has_werror_non_literal_null_conversion)
MOZ_CXX_SUPPORTS_WARNING(-Werror=, sometimes-uninitialized, ac_cxx_has_sometimes_uninitialized)
fi
# Turn off the following warnings that -Wall turns on:
@ -6908,14 +6912,11 @@ if test -z "$MOZ_ENABLE_WARNINGS_AS_ERRORS"; then
WARNINGS_AS_ERRORS=''
elif test "$GNU_CC"; then
# Prevent the following GCC warnings from being treated as errors:
# -Wuninitialized - too many false positives
# -Wmaybe-uninitialized - too many false positives
# -Wdeprecated-declarations - we don't want our builds held hostage when a
# platform-specific API becomes deprecated.
# -Wfree-nonheap-object - false positives during PGO
# -Warray-bounds - false positives depending on optimization
MOZ_C_SUPPORTS_WARNING(-W, no-error=uninitialized, ac_c_has_noerror_uninitialized)
MOZ_CXX_SUPPORTS_WARNING(-W, no-error=uninitialized, ac_cxx_has_noerror_uninitialized)
MOZ_C_SUPPORTS_WARNING(-W, no-error=maybe-uninitialized, ac_c_has_noerror_maybe_uninitialized)
MOZ_CXX_SUPPORTS_WARNING(-W, no-error=maybe-uninitialized, ac_cxx_has_noerror_maybe_uninitialized)
MOZ_C_SUPPORTS_WARNING(-W, no-error=deprecated-declarations, ac_c_has_noerror_deprecated_declarations)

View File

@ -39,7 +39,7 @@ Animation::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
// ---------------------------------------------------------------------------
void
Animation::SetEffect(KeyframeEffectReadonly* aEffect)
Animation::SetEffect(KeyframeEffectReadOnly* aEffect)
{
if (mEffect) {
mEffect->SetParentTime(Nullable<TimeDuration>());

View File

@ -12,7 +12,7 @@
#include "mozilla/TimeStamp.h" // for TimeStamp, TimeDuration
#include "mozilla/dom/AnimationBinding.h" // for AnimationPlayState
#include "mozilla/dom/DocumentTimeline.h" // for DocumentTimeline
#include "mozilla/dom/KeyframeEffect.h" // for KeyframeEffectReadonly
#include "mozilla/dom/KeyframeEffect.h" // for KeyframeEffectReadOnly
#include "mozilla/dom/Promise.h" // for Promise
#include "nsCSSProperty.h" // for nsCSSProperty
@ -86,8 +86,8 @@ public:
// Animation interface methods
KeyframeEffectReadonly* GetEffect() const { return mEffect; }
void SetEffect(KeyframeEffectReadonly* aEffect);
KeyframeEffectReadOnly* GetEffect() const { return mEffect; }
void SetEffect(KeyframeEffectReadOnly* aEffect);
DocumentTimeline* Timeline() const { return mTimeline; }
Nullable<TimeDuration> GetStartTime() const { return mStartTime; }
void SetStartTime(const Nullable<TimeDuration>& aNewStartTime);
@ -318,7 +318,7 @@ protected:
AnimationCollection* GetCollection() const;
nsRefPtr<DocumentTimeline> mTimeline;
nsRefPtr<KeyframeEffectReadonly> mEffect;
nsRefPtr<KeyframeEffectReadOnly> mEffect;
// The beginning of the delay period.
Nullable<TimeDuration> mStartTime; // Timeline timescale
Nullable<TimeDuration> mHoldTime; // Animation timescale

View File

@ -3,18 +3,18 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/AnimationEffectReadonly.h"
#include "mozilla/dom/AnimationEffectReadonlyBinding.h"
#include "mozilla/dom/AnimationEffectReadOnly.h"
#include "mozilla/dom/AnimationEffectReadOnlyBinding.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(AnimationEffectReadonly, mParent)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(AnimationEffectReadOnly, mParent)
NS_IMPL_CYCLE_COLLECTING_ADDREF(AnimationEffectReadonly)
NS_IMPL_CYCLE_COLLECTING_RELEASE(AnimationEffectReadonly)
NS_IMPL_CYCLE_COLLECTING_ADDREF(AnimationEffectReadOnly)
NS_IMPL_CYCLE_COLLECTING_RELEASE(AnimationEffectReadOnly)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AnimationEffectReadonly)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AnimationEffectReadOnly)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END

View File

@ -14,18 +14,18 @@
namespace mozilla {
namespace dom {
class AnimationEffectReadonly
class AnimationEffectReadOnly
: public nsISupports
, public nsWrapperCache
{
protected:
virtual ~AnimationEffectReadonly() { }
virtual ~AnimationEffectReadOnly() { }
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(AnimationEffectReadonly)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(AnimationEffectReadOnly)
explicit AnimationEffectReadonly(nsISupports* aParent)
explicit AnimationEffectReadOnly(nsISupports* aParent)
: mParent(aParent)
{
}

View File

@ -59,35 +59,35 @@ const double ComputedTiming::kNullTimeFraction = PositiveInfinity<double>();
namespace dom {
NS_IMPL_CYCLE_COLLECTION_INHERITED(KeyframeEffectReadonly,
AnimationEffectReadonly,
NS_IMPL_CYCLE_COLLECTION_INHERITED(KeyframeEffectReadOnly,
AnimationEffectReadOnly,
mTarget)
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(KeyframeEffectReadonly,
AnimationEffectReadonly)
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(KeyframeEffectReadOnly,
AnimationEffectReadOnly)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(KeyframeEffectReadonly)
NS_INTERFACE_MAP_END_INHERITING(AnimationEffectReadonly)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(KeyframeEffectReadOnly)
NS_INTERFACE_MAP_END_INHERITING(AnimationEffectReadOnly)
NS_IMPL_ADDREF_INHERITED(KeyframeEffectReadonly, AnimationEffectReadonly)
NS_IMPL_RELEASE_INHERITED(KeyframeEffectReadonly, AnimationEffectReadonly)
NS_IMPL_ADDREF_INHERITED(KeyframeEffectReadOnly, AnimationEffectReadOnly)
NS_IMPL_RELEASE_INHERITED(KeyframeEffectReadOnly, AnimationEffectReadOnly)
JSObject*
KeyframeEffectReadonly::WrapObject(JSContext* aCx,
KeyframeEffectReadOnly::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto)
{
return KeyframeEffectReadonlyBinding::Wrap(aCx, this, aGivenProto);
return KeyframeEffectReadOnlyBinding::Wrap(aCx, this, aGivenProto);
}
void
KeyframeEffectReadonly::SetParentTime(Nullable<TimeDuration> aParentTime)
KeyframeEffectReadOnly::SetParentTime(Nullable<TimeDuration> aParentTime)
{
mParentTime = aParentTime;
}
ComputedTiming
KeyframeEffectReadonly::GetComputedTimingAt(
KeyframeEffectReadOnly::GetComputedTimingAt(
const Nullable<TimeDuration>& aLocalTime,
const AnimationTiming& aTiming)
{
@ -217,7 +217,7 @@ KeyframeEffectReadonly::GetComputedTimingAt(
}
StickyTimeDuration
KeyframeEffectReadonly::ActiveDuration(const AnimationTiming& aTiming)
KeyframeEffectReadOnly::ActiveDuration(const AnimationTiming& aTiming)
{
if (aTiming.mIterationCount == mozilla::PositiveInfinity<float>()) {
// An animation that repeats forever has an infinite active duration
@ -234,7 +234,7 @@ KeyframeEffectReadonly::ActiveDuration(const AnimationTiming& aTiming)
// http://w3c.github.io/web-animations/#in-play
bool
KeyframeEffectReadonly::IsInPlay(const Animation& aAnimation) const
KeyframeEffectReadOnly::IsInPlay(const Animation& aAnimation) const
{
if (IsFinishedTransition() ||
aAnimation.PlayState() == AnimationPlayState::Finished) {
@ -246,7 +246,7 @@ KeyframeEffectReadonly::IsInPlay(const Animation& aAnimation) const
// http://w3c.github.io/web-animations/#current
bool
KeyframeEffectReadonly::IsCurrent(const Animation& aAnimation) const
KeyframeEffectReadOnly::IsCurrent(const Animation& aAnimation) const
{
if (IsFinishedTransition() ||
aAnimation.PlayState() == AnimationPlayState::Finished) {
@ -259,7 +259,7 @@ KeyframeEffectReadonly::IsCurrent(const Animation& aAnimation) const
}
bool
KeyframeEffectReadonly::IsInEffect() const
KeyframeEffectReadOnly::IsInEffect() const
{
if (IsFinishedTransition()) {
return false;
@ -270,7 +270,7 @@ KeyframeEffectReadonly::IsInEffect() const
}
const AnimationProperty*
KeyframeEffectReadonly::GetAnimationOfProperty(nsCSSProperty aProperty) const
KeyframeEffectReadOnly::GetAnimationOfProperty(nsCSSProperty aProperty) const
{
for (size_t propIdx = 0, propEnd = mProperties.Length();
propIdx != propEnd; ++propIdx) {
@ -286,7 +286,7 @@ KeyframeEffectReadonly::GetAnimationOfProperty(nsCSSProperty aProperty) const
}
bool
KeyframeEffectReadonly::HasAnimationOfProperties(
KeyframeEffectReadOnly::HasAnimationOfProperties(
const nsCSSProperty* aProperties,
size_t aPropertyCount) const
{
@ -299,7 +299,7 @@ KeyframeEffectReadonly::HasAnimationOfProperties(
}
void
KeyframeEffectReadonly::ComposeStyle(
KeyframeEffectReadOnly::ComposeStyle(
nsRefPtr<css::AnimValuesStyleRule>& aStyleRule,
nsCSSPropertySet& aSetProperties)
{

View File

@ -15,7 +15,7 @@
#include "mozilla/StickyTimeDuration.h"
#include "mozilla/StyleAnimationValue.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/dom/AnimationEffectReadonly.h"
#include "mozilla/dom/AnimationEffectReadOnly.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/Nullable.h"
#include "nsSMILKeySpline.h"
@ -185,15 +185,15 @@ struct ElementPropertyTransition;
namespace dom {
class KeyframeEffectReadonly : public AnimationEffectReadonly
class KeyframeEffectReadOnly : public AnimationEffectReadOnly
{
public:
KeyframeEffectReadonly(nsIDocument* aDocument,
KeyframeEffectReadOnly(nsIDocument* aDocument,
Element* aTarget,
nsCSSPseudoElements::Type aPseudoType,
const AnimationTiming &aTiming,
const nsSubstring& aName)
: AnimationEffectReadonly(aDocument)
: AnimationEffectReadOnly(aDocument)
, mTarget(aTarget)
, mTiming(aTiming)
, mName(aName)
@ -204,8 +204,8 @@ public:
}
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(KeyframeEffectReadonly,
AnimationEffectReadonly)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(KeyframeEffectReadOnly,
AnimationEffectReadOnly)
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
@ -215,7 +215,7 @@ public:
return nullptr;
}
// KeyframeEffectReadonly interface
// KeyframeEffectReadOnly interface
Element* GetTarget() const {
// Currently we only implement Element.getAnimations() which only
// returns animations targetting Elements so this should never
@ -332,7 +332,7 @@ public:
nsCSSPropertySet& aSetProperties);
protected:
virtual ~KeyframeEffectReadonly() { }
virtual ~KeyframeEffectReadOnly() { }
nsCOMPtr<Element> mTarget;
Nullable<TimeDuration> mParentTime;

View File

@ -9,7 +9,7 @@ MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini']
EXPORTS.mozilla.dom += [
'Animation.h',
'AnimationEffectReadonly.h',
'AnimationEffectReadOnly.h',
'AnimationTimeline.h',
'DocumentTimeline.h',
'KeyframeEffect.h',
@ -22,7 +22,7 @@ EXPORTS.mozilla += [
UNIFIED_SOURCES += [
'Animation.cpp',
'AnimationEffectReadonly.cpp',
'AnimationEffectReadOnly.cpp',
'AnimationTimeline.cpp',
'DocumentTimeline.cpp',
'KeyframeEffect.cpp',

View File

@ -345,7 +345,7 @@ void
nsAnimationReceiver::RecordAnimationMutation(Animation* aAnimation,
AnimationMutation aMutationType)
{
KeyframeEffectReadonly* effect = aAnimation->GetEffect();
KeyframeEffectReadOnly* effect = aAnimation->GetEffect();
if (!effect) {
return;
}

View File

@ -218,7 +218,7 @@ nsNodeUtils::ContentRemoved(nsINode* aContainer,
static inline Element*
GetTarget(Animation* aAnimation)
{
KeyframeEffectReadonly* effect = aAnimation->GetEffect();
KeyframeEffectReadOnly* effect = aAnimation->GetEffect();
if (!effect) {
return nullptr;
}

View File

@ -88,7 +88,7 @@ DOMInterfaces = {
'concrete': False
},
'AnimationEffectReadonly': {
'AnimationEffectReadOnly': {
'concrete': False
},

View File

@ -0,0 +1,38 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Bug 1097479 - Allow embed remote apps or widgets in content
// process if nested-oop is enabled
"use strict";
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
SpecialPowers.setAllAppsLaunchable(true);
function runTest() {
var iframe = document.createElement('iframe');
iframe.setAttribute('mozbrowser', 'true');
iframe.addEventListener('mozbrowsershowmodalprompt', function(e) {
is(e.detail.message == 'app', true, e.detail.message);
SimpleTest.finish();
});
document.body.appendChild(iframe);
var context = { 'url': 'http://example.org',
'appId': SpecialPowers.Ci.nsIScriptSecurityManager.NO_APP_ID,
'isInBrowserElement': true };
SpecialPowers.pushPermissions([
{'type': 'browser', 'allow': 1, 'context': context},
{'type': 'embed-apps', 'allow': 1, 'context': context}
], function() {
iframe.src = 'http://example.org/tests/dom/browser-element/mochitest/file_browserElement_AllowEmbedAppsInNestedOOIframe.html';
});
}
addEventListener('testready', () => {
SpecialPowers.pushPrefEnv({"set": [["dom.ipc.tabs.nested.enabled", true]]}, runTest);
});

View File

@ -0,0 +1,19 @@
<html>
<head>
<script type="text/javascript">
addEventListener('load', function(e) {
var iframe = document.createElement('iframe');
iframe.setAttribute('mozbrowser', 'true');
iframe.setAttribute('remote', 'true');
iframe.setAttribute('mozapp', 'http://example.org/manifest.webapp');
iframe.addEventListener('mozbrowsershowmodalprompt', function(e) {
alert(e.detail.message);
});
document.body.appendChild(iframe);
iframe.src = 'http://example.org/tests/dom/browser-element/mochitest/file_browserElement_AppFramePermission.html';
});
</script>
</head>
<body>
</body>
</html>

View File

@ -16,6 +16,8 @@ skip-if = toolkit=='gonk'
skip-if = toolkit=='gonk' || (toolkit == 'gonk' && !debug)
[test_browserElement_oop_Alert.html]
[test_browserElement_oop_AlertInFrame.html]
[test_browserElement_oop_AllowEmbedAppsInNestedOOIframe.html]
skip-if = toolkit=='gonk'
[test_browserElement_oop_AppFramePermission.html]
skip-if = (toolkit == 'gonk' && !debug)
[test_browserElement_oop_AppWindowNamespace.html]

View File

@ -6,6 +6,7 @@ support-files =
browserElementTestHelpers.js
browserElement_Alert.js
browserElement_AlertInFrame.js
browserElement_AllowEmbedAppsInNestedOOIframe.js
browserElement_AppFramePermission.js
browserElement_AppWindowNamespace.js
browserElement_Auth.js
@ -73,6 +74,7 @@ support-files =
browserElement_GetContentDimensions.js
file_browserElement_AlertInFrame.html
file_browserElement_AlertInFrame_Inner.html
file_browserElement_AllowEmbedAppsInNestedOOIframe.html
file_browserElement_AppFramePermission.html
file_browserElement_AppWindowNamespace.html
file_browserElement_ThemeColor.html

View File

@ -0,0 +1,13 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for Bug 1097479</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="application/javascript;version=1.7" src="browserElement_AllowEmbedAppsInNestedOOIframe.js">
</script>
</body>
</html>

View File

@ -637,6 +637,10 @@ public:
GLint yoffset, GLenum format, GLenum type,
ElementType& elt, ErrorResult& rv)
{
// TODO: Consolidate all the parameter validation
// checks. Instead of spreading out the cheks in multple
// places, consolidate into one spot.
if (IsContextLost())
return;
@ -1308,7 +1312,7 @@ protected:
GLenum format, GLenum type, void* data,
uint32_t byteLength, js::Scalar::Type jsArrayType,
WebGLTexelFormat srcFormat, bool srcPremultiplied);
void TexSubImage2D_base(TexImageTarget texImageTarget, GLint level,
void TexSubImage2D_base(GLenum texImageTarget, GLint level,
GLint xoffset, GLint yoffset, GLsizei width,
GLsizei height, GLsizei srcStrideOrZero,
GLenum format, GLenum type, void* pixels,

View File

@ -3423,7 +3423,7 @@ WebGLContext::TexImage2D(GLenum rawTarget, GLint level,
void
WebGLContext::TexSubImage2D_base(TexImageTarget texImageTarget, GLint level,
WebGLContext::TexSubImage2D_base(GLenum rawImageTarget, GLint level,
GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height, GLsizei srcStrideOrZero,
GLenum format, GLenum type,
@ -3437,6 +3437,11 @@ WebGLContext::TexSubImage2D_base(TexImageTarget texImageTarget, GLint level,
if (type == LOCAL_GL_HALF_FLOAT_OES)
type = LOCAL_GL_HALF_FLOAT;
if (!ValidateTexImageTarget(rawImageTarget, func, dims))
return;
TexImageTarget texImageTarget(rawImageTarget);
WebGLTexture* tex = ActiveBoundTextureForTexImageTarget(texImageTarget);
if (!tex)
return ErrorInvalidOperation("texSubImage2D: no texture bound on active texture unit");

View File

@ -19,7 +19,10 @@ static void
UpdateUpperBound(uint32_t* const out_upperBound, uint32_t newBound)
{
MOZ_ASSERT(out_upperBound);
*out_upperBound = std::max(*out_upperBound, newBound);
// Move *out_upperBound to a local variable to work around a false positive
// -Wuninitialized gcc warning about std::max() in PGO builds.
uint32_t upperBound = *out_upperBound;
*out_upperBound = std::max(upperBound, newBound);
}
/* WebGLElementArrayCacheTree contains most of the implementation of

View File

@ -115,7 +115,7 @@ CheckSanity()
// ensure we exercise some nontrivial tree-walking
T data[numElems] = {1,0,3,1,2,6,5,4}; // intentionally specify only 8 elements for now
size_t numBytes = numElems * sizeof(T);
MOZ_ASSERT(numBytes == sizeof(data));
MOZ_RELEASE_ASSERT(numBytes == sizeof(data));
GLenum type = GLType<T>();
@ -139,7 +139,7 @@ CheckSanity()
CheckValidate(true, c, type, numElems, 0, numElems);
CheckValidate(false, c, type, numElems - 1, 0, numElems);
MOZ_ASSERT(numElems > 10);
MOZ_RELEASE_ASSERT(numElems > 10);
CheckValidate(true, c, type, numElems - 10, 10, numElems - 10);
CheckValidate(false, c, type, numElems - 11, 10, numElems - 10);
}
@ -156,7 +156,7 @@ CheckUintOverflow()
// ensure we exercise some nontrivial tree-walking
T data[numElems];
size_t numBytes = numElems * sizeof(T);
MOZ_ASSERT(numBytes == sizeof(data));
MOZ_RELEASE_ASSERT(numBytes == sizeof(data));
GLenum type = GLType<T>();

View File

@ -77,6 +77,12 @@ public:
return mInternalResponse->Headers();
}
const nsCString&
GetSecurityInfo() const
{
return mInternalResponse->GetSecurityInfo();
}
Headers* Headers_();
void

View File

@ -479,6 +479,20 @@ bool WidgetsEnabled()
return sMozWidgetsEnabled;
}
bool NestedEnabled()
{
static bool sMozNestedEnabled = false;
static bool sBoolVarCacheInitialized = false;
if (!sBoolVarCacheInitialized) {
sBoolVarCacheInitialized = true;
Preferences::AddBoolVarCache(&sMozNestedEnabled,
"dom.ipc.tabs.nested.enabled");
}
return sMozNestedEnabled;
}
} // anonymous namespace
/* [infallible] */ NS_IMETHODIMP
@ -581,8 +595,12 @@ nsGenericHTMLFrameElement::GetAppManifestURL(nsAString& aOut)
return NS_OK;
}
if (XRE_GetProcessType() != GeckoProcessType_Default) {
NS_WARNING("Can't embed-apps. Embed-apps is restricted to in-proc apps, see bug 1059662");
// Only allow content process to embed an app when nested content
// process is enabled.
if (XRE_GetProcessType() != GeckoProcessType_Default &&
!(GetBoolAttr(nsGkAtoms::Remote) && NestedEnabled())){
NS_WARNING("Can't embed-apps. Embed-apps is restricted to in-proc apps "
"or content processes with nested pref enabled, see bug 1097479");
return NS_OK;
}

View File

@ -13,6 +13,7 @@
#endif
#ifdef XP_WIN
#include "mozilla/WindowsVersion.h"
#include "WMFDecoderModule.h"
#endif
#include "nsContentCID.h"
#include "nsServiceManagerUtils.h"
@ -21,6 +22,7 @@
#include "mozilla/Services.h"
#include "nsIObserverService.h"
#include "mozilla/EMEUtils.h"
#include "GMPUtils.h"
namespace mozilla {
namespace dom {
@ -159,6 +161,13 @@ MediaKeySystemAccess::GetKeySystemStatus(const nsAString& aKeySystem,
if (!Preferences::GetBool("media.gmp-eme-adobe.enabled", false)) {
return MediaKeySystemStatus::Cdm_disabled;
}
if ((!WMFDecoderModule::HasH264() || !WMFDecoderModule::HasAAC()) ||
!EMEVoucherFileExists()) {
// The system doesn't have the codecs that Adobe EME relies
// on installed, or doesn't have a voucher for the plugin-container.
// Adobe EME isn't going to work, so don't advertise that it will.
return MediaKeySystemStatus::Cdm_not_supported;
}
return EnsureMinCDMVersion(mps, aKeySystem, aMinCdmVersion, true);
}
#endif

View File

@ -394,7 +394,7 @@ GonkVideoDecoderManager::Output(int64_t aStreamOffset,
}
case -EAGAIN:
{
GVDM_LOG("Need to try again!");
// GVDM_LOG("Need to try again!");
return NS_ERROR_NOT_AVAILABLE;
}
case android::ERROR_END_OF_STREAM:
@ -492,7 +492,7 @@ GonkVideoDecoderManager::codecReserved()
GVDM_LOG("codecReserved");
sp<AMessage> format = new AMessage;
sp<Surface> surface;
status_t rv = OK;
// Fixed values
GVDM_LOG("Configure mime type: %s, widht:%d, height:%d", mMimeType.get(), mVideoWidth, mVideoHeight);
format->setString("mime", mMimeType.get());
@ -503,8 +503,13 @@ GonkVideoDecoderManager::codecReserved()
}
mDecoder->configure(format, surface, nullptr, 0);
mDecoder->Prepare();
status_t rv = mDecoder->Input(mCodecSpecificData->Elements(), mCodecSpecificData->Length(), 0,
android::MediaCodec::BUFFER_FLAG_CODECCONFIG);
if (mMimeType.EqualsLiteral("video/mp4v-es")) {
rv = mDecoder->Input(mCodecSpecificData->Elements(),
mCodecSpecificData->Length(), 0,
android::MediaCodec::BUFFER_FLAG_CODECCONFIG);
}
if (rv != OK) {
GVDM_LOG("Failed to configure codec!!!!");
mReaderCallback->Error();

View File

@ -0,0 +1,12 @@
#
# 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/.
INSTALL_TARGETS += FAKE_GMP_OPENH264_PLUGIN
FAKE_GMP_OPENH264_PLUGIN_DEST = $(DEPTH)/dist/bin/gmp-fakeopenh264/1.0
FAKE_GMP_OPENH264_PLUGIN_FILES = \
$(srcdir)/fakeopenh264.info \
$(srcdir)/fakeopenh264.voucher \
$(NULL)

View File

@ -0,0 +1,4 @@
Name: fakeopenh264
Description: Fake GMP Plugin
Version: 1.0
APIs: encode-video[h264], decode-video[h264]

View File

@ -0,0 +1 @@
gmp-fakeopenh264 placeholder voucher

View File

@ -0,0 +1,26 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# largely a copy of dom/media/gmp-fake/moz.build
FINAL_TARGET = 'dist/bin/gmp-fakeopenh264/1.0'
SOURCES += [
'../gmp-plugin/gmp-fake.cpp',
]
SharedLibrary("fakeopenh264")
if CONFIG['OS_ARCH'] == 'WINNT':
OS_LIBS += [
'ole32',
]
USE_STATIC_LIBS = True
NO_VISIBILITY_FLAGS = True
# Don't use STL wrappers; this isn't Gecko code
DISABLE_STL_WRAPPING = True
FAIL_ON_WARNINGS = True

View File

@ -1,5 +1,5 @@
Name: fake
Description: Fake GMP Plugin
Version: 1.0
APIs: encode-video[h264], decode-video[h264], eme-decrypt-v7[fake]
APIs: encode-video[h264:fake], decode-video[h264:fake], eme-decrypt-v7[fake]
Libraries: dxva2.dll

View File

@ -49,10 +49,12 @@
#include "gmp-video-decode.h"
#include "gmp-video-frame-i420.h"
#include "gmp-video-frame-encoded.h"
#include "gmp-decryption.h"
#if defined(GMP_FAKE_SUPPORT_DECRYPT)
#include "gmp-decryption.h"
#include "gmp-test-decryptor.h"
#include "gmp-test-storage.h"
#endif
#if defined(_MSC_VER)
#define PUBLIC_FUNC __declspec(dllexport)
@ -407,12 +409,14 @@ extern "C" {
} else if (!strcmp (aApiName, GMP_API_VIDEO_ENCODER)) {
*aPluginApi = new FakeVideoEncoder (static_cast<GMPVideoHost*> (aHostAPI));
return GMPNoErr;
#if defined(GMP_FAKE_SUPPORT_DECRYPT)
} else if (!strcmp (aApiName, GMP_API_DECRYPTOR)) {
*aPluginApi = new FakeDecryptor(static_cast<GMPDecryptorHost*> (aHostAPI));
return GMPNoErr;
} else if (!strcmp (aApiName, GMP_API_ASYNC_SHUTDOWN)) {
*aPluginApi = new TestAsyncShutdown(static_cast<GMPAsyncShutdownHost*> (aHostAPI));
return GMPNoErr;
#endif
}
return GMPGenericErr;
}

View File

@ -11,6 +11,8 @@ SOURCES += [
'gmp-test-storage.cpp',
]
DEFINES['GMP_FAKE_SUPPORT_DECRYPT'] = True
SharedLibrary("fake")
if CONFIG['OS_ARCH'] == 'WINNT':

View File

@ -55,6 +55,7 @@ GMPParent::GMPParent()
, mDeleteProcessOnlyOnUnload(false)
, mAbnormalShutdownInProgress(false)
, mIsBlockingDeletion(false)
, mCanDecrypt(false)
, mGMPContentChildCount(0)
, mAsyncShutdownRequired(false)
, mAsyncShutdownInProgress(false)
@ -756,16 +757,20 @@ GMPParent::ReadGMPMetaData()
}
}
if (cap->mAPIName.EqualsLiteral(GMP_API_DECRYPTOR) ||
cap->mAPIName.EqualsLiteral(GMP_API_DECRYPTOR_COMPAT)) {
mCanDecrypt = true;
#if defined(XP_LINUX) && defined(MOZ_GMP_SANDBOX)
if (cap->mAPIName.EqualsLiteral(GMP_API_DECRYPTOR) &&
!mozilla::SandboxInfo::Get().CanSandboxMedia()) {
printf_stderr("GMPParent::ReadGMPMetaData: Plugin \"%s\" is an EME CDM"
" but this system can't sandbox it; not loading.\n",
mDisplayName.get());
delete cap;
return NS_ERROR_FAILURE;
}
if (!mozilla::SandboxInfo::Get().CanSandboxMedia()) {
printf_stderr("GMPParent::ReadGMPMetaData: Plugin \"%s\" is an EME CDM"
" but this system can't sandbox it; not loading.\n",
mDisplayName.get());
delete cap;
return NS_ERROR_FAILURE;
}
#endif
}
mCapabilities.AppendElement(cap);
}
@ -780,7 +785,12 @@ GMPParent::ReadGMPMetaData()
bool
GMPParent::CanBeSharedCrossNodeIds() const
{
return mNodeId.IsEmpty();
return mNodeId.IsEmpty() &&
// XXX bug 1159300 hack -- maybe remove after openh264 1.4
// We don't want to use CDM decoders for non-encrypted playback
// just yet; especially not for WebRTC. Don't allow CDMs to be used
// without a node ID.
!mCanDecrypt;
}
bool

View File

@ -199,6 +199,8 @@ private:
bool mAbnormalShutdownInProgress;
bool mIsBlockingDeletion;
bool mCanDecrypt;
nsTArray<nsRefPtr<GMPTimerParent>> mTimers;
nsTArray<nsRefPtr<GMPStorageParent>> mStorage;
nsCOMPtr<nsIThread> mGMPThread;

View File

@ -5,8 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "GMPProcessParent.h"
#include "nsDirectoryServiceDefs.h"
#include "nsIFile.h"
#include "GMPUtils.h"
#include "base/string_util.h"
#include "base/process_util.h"
@ -45,15 +44,13 @@ GMPProcessParent::~GMPProcessParent()
bool
GMPProcessParent::Launch(int32_t aTimeoutMs)
{
nsCOMPtr<nsIFile> greDir;
NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(greDir));
if (!greDir) {
NS_WARNING("GMPProcessParent can't get NS_GRE_DIR");
nsCOMPtr<nsIFile> path;
if (!GetEMEVoucherPath(getter_AddRefs(path))) {
NS_WARNING("GMPProcessParent can't get EME voucher path!");
return false;
}
greDir->AppendNative(NS_LITERAL_CSTRING("voucher.bin"));
nsAutoCString voucherPath;
greDir->GetNativePath(voucherPath);
path->GetNativePath(voucherPath);
vector<string> args;
args.push_back(mGMPPath);

View File

@ -673,21 +673,23 @@ GeckoMediaPluginServiceParent::ClonePlugin(const GMPParent* aOriginal)
class NotifyObserversTask final : public nsRunnable {
public:
explicit NotifyObserversTask(const char* aTopic)
explicit NotifyObserversTask(const char* aTopic, nsString aData = EmptyString())
: mTopic(aTopic)
, mData(aData)
{}
NS_IMETHOD Run() override {
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIObserverService> obsService = mozilla::services::GetObserverService();
MOZ_ASSERT(obsService);
if (obsService) {
obsService->NotifyObservers(nullptr, mTopic, nullptr);
obsService->NotifyObservers(nullptr, mTopic, mData.get());
}
return NS_OK;
}
private:
~NotifyObserversTask() {}
const char* mTopic;
const nsString mData;
};
void
@ -737,6 +739,11 @@ GeckoMediaPluginServiceParent::RemoveOnGMPThread(const nsAString& aDirectory,
return;
}
// Plugin destruction can modify |mPlugins|. Put them aside for now and
// destroy them once we're done with |mPlugins|.
nsTArray<nsRefPtr<GMPParent>> deadPlugins;
bool inUse = false;
MutexAutoLock lock(mMutex);
for (size_t i = mPlugins.Length() - 1; i < mPlugins.Length(); i--) {
nsCOMPtr<nsIFile> pluginpath = mPlugins[i]->GetDirectory();
@ -749,6 +756,7 @@ GeckoMediaPluginServiceParent::RemoveOnGMPThread(const nsAString& aDirectory,
if (aDeleteFromDisk && gmp->State() != GMPStateNotLoaded) {
// We have to wait for the child process to release its lib handle
// before we can delete the GMP.
inUse = true;
gmp->MarkForDeletion();
if (!mPluginsWaitingForDeletion.Contains(aDirectory)) {
@ -758,15 +766,25 @@ GeckoMediaPluginServiceParent::RemoveOnGMPThread(const nsAString& aDirectory,
if (gmp->State() == GMPStateNotLoaded || !aCanDefer) {
// GMP not in use or shutdown is being forced; can shut it down now.
gmp->AbortAsyncShutdown();
gmp->CloseActive(true);
deadPlugins.AppendElement(gmp);
mPlugins.RemoveElementAt(i);
}
}
if (aDeleteFromDisk) {
{
MutexAutoUnlock unlock(mMutex);
for (auto& gmp : deadPlugins) {
gmp->AbortAsyncShutdown();
gmp->CloseActive(true);
}
}
if (aDeleteFromDisk && !inUse) {
if (NS_SUCCEEDED(directory->Remove(true))) {
mPluginsWaitingForDeletion.RemoveElement(aDirectory);
NS_DispatchToMainThread(new NotifyObserversTask("gmp-directory-deleted",
nsString(aDirectory)),
NS_DISPATCH_NORMAL);
}
}
}

View File

@ -0,0 +1,38 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "GMPUtils.h"
#include "nsDirectoryServiceDefs.h"
#include "nsIFile.h"
#include "nsCOMPtr.h"
namespace mozilla {
bool
GetEMEVoucherPath(nsIFile** aPath)
{
nsCOMPtr<nsIFile> path;
NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(path));
if (!path) {
NS_WARNING("GetEMEVoucherPath can't get NS_GRE_DIR!");
return false;
}
path->AppendNative(NS_LITERAL_CSTRING("voucher.bin"));
path.forget(aPath);
return true;
}
bool
EMEVoucherFileExists()
{
nsCOMPtr<nsIFile> path;
bool exists;
return GetEMEVoucherPath(getter_AddRefs(path)) &&
NS_SUCCEEDED(path->Exists(&exists)) &&
exists;
}
} // namespace mozilla

View File

@ -21,6 +21,10 @@ struct DestroyPolicy
template<typename T>
using GMPUniquePtr = mozilla::UniquePtr<T, DestroyPolicy<T>>;
bool GetEMEVoucherPath(nsIFile** aPath);
bool EMEVoucherFileExists();
} // namespace mozilla
#endif

View File

@ -98,6 +98,7 @@ UNIFIED_SOURCES += [
'GMPStorageParent.cpp',
'GMPTimerChild.cpp',
'GMPTimerParent.cpp',
'GMPUtils.cpp',
'GMPVideoDecoderChild.cpp',
'GMPVideoDecoderParent.cpp',
'GMPVideoEncodedFrameImpl.cpp',

View File

@ -0,0 +1,46 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsThreadUtils.h"
#ifndef __GMPTestMonitor_h__
#define __GMPTestMonitor_h__
class GMPTestMonitor
{
public:
GMPTestMonitor()
: mFinished(false)
{
}
void AwaitFinished()
{
MOZ_ASSERT(NS_IsMainThread());
while (!mFinished) {
NS_ProcessNextEvent(nullptr, true);
}
mFinished = false;
}
private:
void MarkFinished()
{
mFinished = true;
}
public:
void SetFinished()
{
NS_DispatchToMainThread(NS_NewNonOwningRunnableMethod(this,
&GMPTestMonitor::MarkFinished));
}
private:
bool mFinished;
};
#endif // __GMPTestMonitor_h__

View File

@ -8,6 +8,7 @@
#include "nsIObserverService.h"
#include "mozilla/Services.h"
#include "mozilla/StaticPtr.h"
#include "GMPTestMonitor.h"
#include "GMPVideoDecoderProxy.h"
#include "GMPVideoEncoderProxy.h"
#include "GMPDecryptorProxy.h"
@ -28,40 +29,6 @@ using namespace std;
using namespace mozilla;
using namespace mozilla::gmp;
class GMPTestMonitor
{
public:
GMPTestMonitor()
: mFinished(false)
{
}
void AwaitFinished()
{
MOZ_ASSERT(NS_IsMainThread());
while (!mFinished) {
NS_ProcessNextEvent(nullptr, true);
}
mFinished = false;
}
private:
void MarkFinished()
{
mFinished = true;
}
public:
void SetFinished()
{
NS_DispatchToMainThread(NS_NewNonOwningRunnableMethod(this,
&GMPTestMonitor::MarkFinished));
}
private:
bool mFinished;
};
struct GMPTestRunner
{
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GMPTestRunner)

View File

@ -0,0 +1,449 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "GMPService.h"
#include "GMPTestMonitor.h"
#include "gmp-api/gmp-video-host.h"
#include "gtest/gtest.h"
#include "mozilla/Services.h"
#include "nsDirectoryServiceDefs.h"
#include "nsIObserverService.h"
#define GMP_DIR_NAME NS_LITERAL_STRING("gmp-fake")
#define GMP_OLD_VERSION NS_LITERAL_STRING("1.0")
#define GMP_NEW_VERSION NS_LITERAL_STRING("1.1")
#define GMP_DELETED_TOPIC "gmp-directory-deleted"
#define EXPECT_OK(X) EXPECT_TRUE(NS_SUCCEEDED(X))
class GMPRemoveTest : public nsIObserver
, public GMPVideoDecoderCallbackProxy
{
public:
GMPRemoveTest();
NS_DECL_THREADSAFE_ISUPPORTS
// Called when a GMP plugin directory has been successfully deleted.
// |aData| will contain the directory path.
NS_IMETHOD Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData) override;
// Create a new GMP plugin directory that we can trash and add it to the GMP
// service. Remove the original plugin directory. Original plugin directory
// gets re-added at destruction.
void Setup();
bool CreateVideoDecoder(nsCString aNodeId = EmptyCString());
void CloseVideoDecoder();
void DeletePluginDirectory(bool aCanDefer);
// Decode a dummy frame.
GMPErr Decode();
// Wait until TestMonitor has been signaled.
void Wait();
// Did we get a Terminated() callback from the plugin?
bool IsTerminated();
// From GMPVideoDecoderCallbackProxy
// Set mDecodeResult; unblock TestMonitor.
virtual void Decoded(GMPVideoi420Frame* aDecodedFrame) override;
virtual void Error(GMPErr aError) override;
// From GMPVideoDecoderCallbackProxy
// We expect this to be called when a plugin has been forcibly closed.
virtual void Terminated() override;
// Ignored GMPVideoDecoderCallbackProxy members
virtual void ReceivedDecodedReferenceFrame(const uint64_t aPictureId) override {}
virtual void ReceivedDecodedFrame(const uint64_t aPictureId) override {}
virtual void InputDataExhausted() override {}
virtual void DrainComplete() override {}
virtual void ResetComplete() override {}
private:
virtual ~GMPRemoveTest();
void gmp_Decode();
void gmp_GetVideoDecoder(nsCString aNodeId,
GMPVideoDecoderProxy** aOutDecoder,
GMPVideoHost** aOutHost);
void GeneratePlugin();
GMPTestMonitor mTestMonitor;
nsCOMPtr<nsIThread> mGMPThread;
bool mIsTerminated;
// Path to the cloned GMP we have created.
nsString mTmpPath;
nsCOMPtr<nsIFile> mTmpDir;
// Path to the original GMP. Store so that we can re-add it after we're done
// testing.
nsString mOriginalPath;
GMPVideoDecoderProxy* mDecoder;
GMPVideoHost* mHost;
GMPErr mDecodeResult;
};
/*
* Simple test that the plugin is deleted when forcibly removed and deleted.
*/
TEST(GeckoMediaPlugins, RemoveAndDeleteForcedSimple)
{
nsRefPtr<GMPRemoveTest> test(new GMPRemoveTest());
test->Setup();
test->DeletePluginDirectory(false /* force immediate */);
test->Wait();
}
/*
* Simple test that the plugin is deleted when deferred deletion is allowed.
*/
TEST(GeckoMediaPlugins, RemoveAndDeleteDeferredSimple)
{
nsRefPtr<GMPRemoveTest> test(new GMPRemoveTest());
test->Setup();
test->DeletePluginDirectory(true /* can defer */);
test->Wait();
}
/*
* Test that the plugin is unavailable immediately after a forced
* RemoveAndDelete, and that the plugin is deleted afterwards.
*/
TEST(GeckoMediaPlugins, RemoveAndDeleteForcedInUse)
{
nsRefPtr<GMPRemoveTest> test(new GMPRemoveTest());
test->Setup();
EXPECT_TRUE(test->CreateVideoDecoder(NS_LITERAL_CSTRING("thisOrigin")));
// Test that we can decode a frame.
GMPErr err = test->Decode();
EXPECT_EQ(err, GMPNoErr);
test->DeletePluginDirectory(false /* force immediate */);
test->Wait();
// Test that the VideoDecoder is no longer available.
EXPECT_FALSE(test->CreateVideoDecoder(NS_LITERAL_CSTRING("thisOrigin")));
// Test that we were notified of the plugin's destruction.
EXPECT_TRUE(test->IsTerminated());
}
/*
* Test that the plugin is still usable after a deferred RemoveAndDelete, and
* that the plugin is deleted afterwards.
*/
TEST(GeckoMediaPlugins, RemoveAndDeleteDeferredInUse)
{
nsRefPtr<GMPRemoveTest> test(new GMPRemoveTest());
test->Setup();
EXPECT_TRUE(test->CreateVideoDecoder(NS_LITERAL_CSTRING("thisOrigin")));
// Make sure decoding works before we do anything.
GMPErr err = test->Decode();
EXPECT_EQ(err, GMPNoErr);
test->DeletePluginDirectory(true /* can defer */);
// Test that decoding still works.
err = test->Decode();
EXPECT_EQ(err, GMPNoErr);
// Test that this origin is still able to fetch the video decoder.
EXPECT_TRUE(test->CreateVideoDecoder(NS_LITERAL_CSTRING("thisOrigin")));
test->CloseVideoDecoder();
test->Wait();
}
static StaticRefPtr<GeckoMediaPluginService> gService;
static StaticRefPtr<GeckoMediaPluginServiceParent> gServiceParent;
static GeckoMediaPluginService*
GetService()
{
if (!gService) {
nsRefPtr<GeckoMediaPluginService> service =
GeckoMediaPluginService::GetGeckoMediaPluginService();
gService = service;
}
return gService.get();
}
static GeckoMediaPluginServiceParent*
GetServiceParent()
{
if (!gServiceParent) {
nsRefPtr<GeckoMediaPluginServiceParent> parent =
GeckoMediaPluginServiceParent::GetSingleton();
gServiceParent = parent;
}
return gServiceParent.get();
}
NS_IMPL_ISUPPORTS(GMPRemoveTest, nsIObserver)
GMPRemoveTest::GMPRemoveTest()
: mIsTerminated(false)
, mDecoder(nullptr)
, mHost(nullptr)
{
}
GMPRemoveTest::~GMPRemoveTest()
{
bool exists;
EXPECT_TRUE(NS_SUCCEEDED(mTmpDir->Exists(&exists)) && !exists);
EXPECT_OK(GetServiceParent()->AddPluginDirectory(mOriginalPath));
}
void
GMPRemoveTest::Setup()
{
GeneratePlugin();
EXPECT_OK(GetServiceParent()->RemovePluginDirectory(mOriginalPath));
GetServiceParent()->AddPluginDirectory(mTmpPath);
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
obs->AddObserver(this, GMP_DELETED_TOPIC, false /* strong ref */);
GetService()->GetThread(getter_AddRefs(mGMPThread));
}
bool
GMPRemoveTest::CreateVideoDecoder(nsCString aNodeId)
{
GMPVideoHost* host;
GMPVideoDecoderProxy* decoder = nullptr;
mGMPThread->Dispatch(
NS_NewNonOwningRunnableMethodWithArgs<nsCString, GMPVideoDecoderProxy**, GMPVideoHost**>(
this, &GMPRemoveTest::gmp_GetVideoDecoder, aNodeId, &decoder, &host),
NS_DISPATCH_NORMAL);
mTestMonitor.AwaitFinished();
if (!decoder) {
return false;
}
GMPVideoCodec codec;
memset(&codec, 0, sizeof(codec));
codec.mGMPApiVersion = 33;
nsTArray<uint8_t> empty;
mGMPThread->Dispatch(
NS_NewNonOwningRunnableMethodWithArgs<const GMPVideoCodec&, const nsTArray<uint8_t>&, GMPVideoDecoderCallbackProxy*, int32_t>(
decoder, &GMPVideoDecoderProxy::InitDecode,
codec, empty, this, 1 /* core count */),
NS_DISPATCH_SYNC);
if (mDecoder) {
CloseVideoDecoder();
}
mDecoder = decoder;
mHost = host;
return true;
}
void
GMPRemoveTest::gmp_GetVideoDecoder(nsCString aNodeId,
GMPVideoDecoderProxy** aOutDecoder,
GMPVideoHost** aOutHost)
{
nsTArray<nsCString> tags;
tags.AppendElement(NS_LITERAL_CSTRING("h264"));
tags.AppendElement(NS_LITERAL_CSTRING("fake"));
class Callback : public GetGMPVideoDecoderCallback
{
public:
Callback(GMPTestMonitor* aMonitor, GMPVideoDecoderProxy** aDecoder, GMPVideoHost** aHost)
: mMonitor(aMonitor), mDecoder(aDecoder), mHost(aHost) { }
virtual void Done(GMPVideoDecoderProxy* aDecoder, GMPVideoHost* aHost) override {
*mDecoder = aDecoder;
*mHost = aHost;
mMonitor->SetFinished();
}
private:
GMPTestMonitor* mMonitor;
GMPVideoDecoderProxy** mDecoder;
GMPVideoHost** mHost;
};
UniquePtr<GetGMPVideoDecoderCallback>
cb(new Callback(&mTestMonitor, aOutDecoder, aOutHost));
if (NS_FAILED(GetService()->GetGMPVideoDecoder(&tags, aNodeId, Move(cb)))) {
mTestMonitor.SetFinished();
}
}
void
GMPRemoveTest::CloseVideoDecoder()
{
mGMPThread->Dispatch(
NS_NewNonOwningRunnableMethod(mDecoder, &GMPVideoDecoderProxy::Close),
NS_DISPATCH_SYNC);
mDecoder = nullptr;
mHost = nullptr;
}
void
GMPRemoveTest::DeletePluginDirectory(bool aCanDefer)
{
GetServiceParent()->RemoveAndDeletePluginDirectory(mTmpPath, aCanDefer);
}
GMPErr
GMPRemoveTest::Decode()
{
mGMPThread->Dispatch(
NS_NewNonOwningRunnableMethod(this, &GMPRemoveTest::gmp_Decode),
NS_DISPATCH_NORMAL);
mTestMonitor.AwaitFinished();
return mDecodeResult;
}
void
GMPRemoveTest::gmp_Decode()
{
// from gmp-fake.cpp
struct EncodedFrame {
uint32_t length_;
uint8_t h264_compat_;
uint32_t magic_;
uint32_t width_;
uint32_t height_;
uint8_t y_;
uint8_t u_;
uint8_t v_;
uint32_t timestamp_;
};
GMPVideoFrame* absFrame;
GMPErr err = mHost->CreateFrame(kGMPEncodedVideoFrame, &absFrame);
EXPECT_EQ(err, GMPNoErr);
GMPUniquePtr<GMPVideoEncodedFrame>
frame(static_cast<GMPVideoEncodedFrame*>(absFrame));
err = frame->CreateEmptyFrame(sizeof(EncodedFrame) /* size */);
EXPECT_EQ(err, GMPNoErr);
EncodedFrame* frameData = reinterpret_cast<EncodedFrame*>(frame->Buffer());
frameData->magic_ = 0x4652414d;
frameData->width_ = frameData->height_ = 16;
nsTArray<uint8_t> empty;
nsresult rv = mDecoder->Decode(Move(frame), false /* aMissingFrames */, empty);
EXPECT_OK(rv);
}
void
GMPRemoveTest::Wait()
{
mTestMonitor.AwaitFinished();
}
bool
GMPRemoveTest::IsTerminated()
{
return mIsTerminated;
}
// nsIObserver
NS_IMETHODIMP
GMPRemoveTest::Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData)
{
EXPECT_TRUE(!strcmp(GMP_DELETED_TOPIC, aTopic));
nsString data(aData);
if (mTmpPath.Equals(data)) {
mTestMonitor.SetFinished();
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
obs->RemoveObserver(this, GMP_DELETED_TOPIC);
}
return NS_OK;
}
// GMPVideoDecoderCallbackProxy
void
GMPRemoveTest::Decoded(GMPVideoi420Frame* aDecodedFrame)
{
aDecodedFrame->Destroy();
mDecodeResult = GMPNoErr;
mTestMonitor.SetFinished();
}
// GMPVideoDecoderCallbackProxy
void
GMPRemoveTest::Error(GMPErr aError)
{
mDecodeResult = aError;
mTestMonitor.SetFinished();
}
// GMPVideoDecoderCallbackProxy
void
GMPRemoveTest::Terminated()
{
mIsTerminated = true;
}
void
GMPRemoveTest::GeneratePlugin()
{
nsresult rv;
nsCOMPtr<nsIFile> gmpDir;
nsCOMPtr<nsIFile> origDir;
nsCOMPtr<nsIFile> tmpDir;
rv = NS_GetSpecialDirectory(NS_GRE_DIR,
getter_AddRefs(gmpDir));
EXPECT_OK(rv);
rv = gmpDir->Append(GMP_DIR_NAME);
EXPECT_OK(rv);
rv = gmpDir->Clone(getter_AddRefs(origDir));
EXPECT_OK(rv);
rv = origDir->Append(GMP_OLD_VERSION);
EXPECT_OK(rv);
rv = origDir->CopyTo(gmpDir, GMP_NEW_VERSION);
EXPECT_OK(rv);
rv = gmpDir->Clone(getter_AddRefs(tmpDir));
EXPECT_OK(rv);
rv = tmpDir->Append(GMP_NEW_VERSION);
EXPECT_OK(rv);
EXPECT_OK(origDir->GetPath(mOriginalPath));
EXPECT_OK(tmpDir->GetPath(mTmpPath));
mTmpDir = tmpDir;
}

View File

@ -8,6 +8,7 @@ UNIFIED_SOURCES += [
'MockMediaResource.cpp',
'TestAudioCompactor.cpp',
'TestGMPCrossOrigin.cpp',
'TestGMPRemoveAndDelete.cpp',
'TestMP4Demuxer.cpp',
'TestMP4Reader.cpp',
'TestTrackEncoder.cpp',

View File

@ -23,6 +23,7 @@ DIRS += [
'encoder',
'gmp',
'gmp-plugin',
'gmp-plugin-openh264',
'imagecapture',
'mediasource',
'ogg',

View File

@ -1546,7 +1546,7 @@ PeerConnectionWrapper.prototype = {
// As input we use the stream of |from|'s first available audio sender.
var inputSenderTracks = from._pc.getSenders().map(sn => sn.track);
var inputAudioStream = from._pc.getLocalStreams()
.find(s => s.getAudioTracks().some(t => inputSenderTracks.includes(t)));
.find(s => s.getAudioTracks().some(t => inputSenderTracks.some(t2 => t == t2)));
var inputAnalyser = new AudioStreamAnalyser(inputAudioStream);
// It would have been nice to have a working getReceivers() here, but until

View File

@ -16,9 +16,9 @@ namespace dom {
NS_IMPL_ISUPPORTS_INHERITED0(AnalyserNode, AudioNode)
class AnalyserNodeEngine : public AudioNodeEngine
class AnalyserNodeEngine final : public AudioNodeEngine
{
class TransferBuffer : public nsRunnable
class TransferBuffer final : public nsRunnable
{
public:
TransferBuffer(AudioNodeStream* aStream,

View File

@ -15,7 +15,7 @@ namespace dom {
class AudioContext;
class AnalyserNode : public AudioNode
class AnalyserNode final : public AudioNode
{
public:
explicit AnalyserNode(AudioContext* aContext);

View File

@ -53,11 +53,11 @@ NS_IMPL_RELEASE_INHERITED(AudioBufferSourceNode, AudioNode)
* AudioNodeStream::SetBuffer) and a non-zero mBufferEnd has been set (via
* AudioNodeStream::SetInt32Parameter).
*/
class AudioBufferSourceNodeEngine : public AudioNodeEngine
class AudioBufferSourceNodeEngine final : public AudioNodeEngine
{
public:
explicit AudioBufferSourceNodeEngine(AudioNode* aNode,
AudioDestinationNode* aDestination) :
AudioBufferSourceNodeEngine(AudioNode* aNode,
AudioDestinationNode* aDestination) :
AudioNodeEngine(aNode),
mStart(0.0), mBeginProcessing(0),
mStop(STREAM_TIME_MAX),
@ -713,12 +713,12 @@ void
AudioBufferSourceNode::NotifyMainThreadStateChanged()
{
if (mStream->IsFinished()) {
class EndedEventDispatcher : public nsRunnable
class EndedEventDispatcher final : public nsRunnable
{
public:
explicit EndedEventDispatcher(AudioBufferSourceNode* aNode)
: mNode(aNode) {}
NS_IMETHODIMP Run()
NS_IMETHODIMP Run() override
{
// If it's not safe to run scripts right now, schedule this to run later
if (!nsContentUtils::IsSafeToRunScript()) {

View File

@ -15,8 +15,8 @@ namespace dom {
class AudioParam;
class AudioBufferSourceNode : public AudioNode,
public MainThreadMediaStreamListener
class AudioBufferSourceNode final : public AudioNode,
public MainThreadMediaStreamListener
{
public:
explicit AudioBufferSourceNode(AudioContext* aContext);

View File

@ -30,7 +30,7 @@ namespace dom {
static uint8_t gWebAudioOutputKey;
class OfflineDestinationNodeEngine : public AudioNodeEngine
class OfflineDestinationNodeEngine final : public AudioNodeEngine
{
public:
typedef AutoFallibleTArray<nsAutoArrayPtr<float>, 2> InputChannels;
@ -135,7 +135,7 @@ public:
, mRenderedBuffer(aRenderedBuffer)
{}
NS_IMETHOD Run()
NS_IMETHOD Run() override
{
nsRefPtr<OfflineAudioCompletionEvent> event =
new OfflineAudioCompletionEvent(mAudioContext, nullptr, nullptr);
@ -210,7 +210,7 @@ private:
bool mBufferAllocated;
};
class InputMutedRunnable : public nsRunnable
class InputMutedRunnable final : public nsRunnable
{
public:
InputMutedRunnable(AudioNodeStream* aStream,
@ -220,7 +220,7 @@ public:
{
}
NS_IMETHOD Run()
NS_IMETHOD Run() override
{
MOZ_ASSERT(NS_IsMainThread());
nsRefPtr<AudioNode> node = mStream->Engine()->NodeMainThread();
@ -238,7 +238,7 @@ private:
bool mInputMuted;
};
class DestinationNodeEngine : public AudioNodeEngine
class DestinationNodeEngine final : public AudioNodeEngine
{
public:
explicit DestinationNodeEngine(AudioDestinationNode* aNode)

View File

@ -21,8 +21,10 @@ namespace mozilla {
namespace dom {
// This is an internal helper class and should not be used outside of this header.
struct AudioTimelineEvent {
enum Type : uint32_t {
struct AudioTimelineEvent final
{
enum Type : uint32_t
{
SetValue,
LinearRamp,
ExponentialRamp,

View File

@ -325,7 +325,8 @@ AudioNode::Disconnect(uint32_t aOutput, ErrorResult& aRv)
// ADDREF message to this (main) thread. Wait for a round trip before
// releasing nodes, to give engines receiving sound now time to keep their
// nodes alive.
class RunnableRelease : public nsRunnable {
class RunnableRelease final : public nsRunnable
{
public:
explicit RunnableRelease(already_AddRefed<AudioNode> aNode)
: mNode(aNode) {}

View File

@ -74,7 +74,8 @@ public:
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(AudioNode,
DOMEventTargetHelper)
virtual AudioBufferSourceNode* AsAudioBufferSourceNode() {
virtual AudioBufferSourceNode* AsAudioBufferSourceNode()
{
return nullptr;
}
@ -137,7 +138,8 @@ public:
SendChannelMixingParametersToStream();
}
struct InputNode {
struct InputNode final
{
~InputNode()
{
if (mStreamPort) {

View File

@ -27,7 +27,8 @@ class AudioNodeStream;
* pointers can be different (e.g. if the buffers are contained inside
* some malloced object).
*/
class ThreadSharedFloatArrayBufferList : public ThreadSharedObject {
class ThreadSharedFloatArrayBufferList final : public ThreadSharedObject
{
public:
/**
* Construct with null data.
@ -37,7 +38,8 @@ public:
mContents.SetLength(aCount);
}
struct Storage {
struct Storage final
{
Storage() :
mDataToFree(nullptr),
mFree(nullptr),
@ -234,7 +236,8 @@ AudioBufferSumOfSquares(const float* aInput, uint32_t aLength);
* All methods of this class and its subclasses are called on the
* MediaStreamGraph thread.
*/
class AudioNodeEngine {
class AudioNodeEngine
{
public:
// This should be compatible with AudioNodeStream::OutputChunks.
typedef nsAutoTArray<AudioChunk, 1> OutputChunks;

View File

@ -18,14 +18,17 @@ namespace mozilla {
* input --- handling any number of audio tracks and handling blocking of
* the input MediaStream.
*/
class AudioNodeExternalInputStream : public AudioNodeStream {
class AudioNodeExternalInputStream final : public AudioNodeStream
{
public:
AudioNodeExternalInputStream(AudioNodeEngine* aEngine, TrackRate aSampleRate, uint32_t aContextId);
AudioNodeExternalInputStream(AudioNodeEngine* aEngine, TrackRate aSampleRate,
uint32_t aContextId);
protected:
~AudioNodeExternalInputStream();
public:
virtual void ProcessInput(GraphTime aFrom, GraphTime aTo, uint32_t aFlags) override;
virtual void ProcessInput(GraphTime aFrom, GraphTime aTo,
uint32_t aFlags) override;
private:
/**

View File

@ -95,13 +95,15 @@ void
AudioNodeStream::SetStreamTimeParameter(uint32_t aIndex, AudioContext* aContext,
double aStreamTime)
{
class Message : public ControlMessage {
class Message final : public ControlMessage
{
public:
Message(AudioNodeStream* aStream, uint32_t aIndex, MediaStream* aRelativeToStream,
double aStreamTime)
: ControlMessage(aStream), mStreamTime(aStreamTime),
mRelativeToStream(aRelativeToStream), mIndex(aIndex) {}
virtual void Run()
mRelativeToStream(aRelativeToStream), mIndex(aIndex)
{}
virtual void Run() override
{
static_cast<AudioNodeStream*>(mStream)->
SetStreamTimeParameterImpl(mIndex, mRelativeToStream, mStreamTime);
@ -127,11 +129,13 @@ AudioNodeStream::SetStreamTimeParameterImpl(uint32_t aIndex, MediaStream* aRelat
void
AudioNodeStream::SetDoubleParameter(uint32_t aIndex, double aValue)
{
class Message : public ControlMessage {
class Message final : public ControlMessage
{
public:
Message(AudioNodeStream* aStream, uint32_t aIndex, double aValue)
: ControlMessage(aStream), mValue(aValue), mIndex(aIndex) {}
virtual void Run()
: ControlMessage(aStream), mValue(aValue), mIndex(aIndex)
{}
virtual void Run() override
{
static_cast<AudioNodeStream*>(mStream)->Engine()->
SetDoubleParameter(mIndex, mValue);
@ -146,11 +150,13 @@ AudioNodeStream::SetDoubleParameter(uint32_t aIndex, double aValue)
void
AudioNodeStream::SetInt32Parameter(uint32_t aIndex, int32_t aValue)
{
class Message : public ControlMessage {
class Message final : public ControlMessage
{
public:
Message(AudioNodeStream* aStream, uint32_t aIndex, int32_t aValue)
: ControlMessage(aStream), mValue(aValue), mIndex(aIndex) {}
virtual void Run()
: ControlMessage(aStream), mValue(aValue), mIndex(aIndex)
{}
virtual void Run() override
{
static_cast<AudioNodeStream*>(mStream)->Engine()->
SetInt32Parameter(mIndex, mValue);
@ -166,15 +172,17 @@ void
AudioNodeStream::SetTimelineParameter(uint32_t aIndex,
const AudioParamTimeline& aValue)
{
class Message : public ControlMessage {
class Message final : public ControlMessage
{
public:
Message(AudioNodeStream* aStream, uint32_t aIndex,
const AudioParamTimeline& aValue)
: ControlMessage(aStream),
mValue(aValue),
mSampleRate(aStream->SampleRate()),
mIndex(aIndex) {}
virtual void Run()
mIndex(aIndex)
{}
virtual void Run() override
{
static_cast<AudioNodeStream*>(mStream)->Engine()->
SetTimelineParameter(mIndex, mValue, mSampleRate);
@ -189,11 +197,13 @@ AudioNodeStream::SetTimelineParameter(uint32_t aIndex,
void
AudioNodeStream::SetThreeDPointParameter(uint32_t aIndex, const ThreeDPoint& aValue)
{
class Message : public ControlMessage {
class Message final : public ControlMessage
{
public:
Message(AudioNodeStream* aStream, uint32_t aIndex, const ThreeDPoint& aValue)
: ControlMessage(aStream), mValue(aValue), mIndex(aIndex) {}
virtual void Run()
: ControlMessage(aStream), mValue(aValue), mIndex(aIndex)
{}
virtual void Run() override
{
static_cast<AudioNodeStream*>(mStream)->Engine()->
SetThreeDPointParameter(mIndex, mValue);
@ -208,12 +218,14 @@ AudioNodeStream::SetThreeDPointParameter(uint32_t aIndex, const ThreeDPoint& aVa
void
AudioNodeStream::SetBuffer(already_AddRefed<ThreadSharedFloatArrayBufferList>&& aBuffer)
{
class Message : public ControlMessage {
class Message final : public ControlMessage
{
public:
Message(AudioNodeStream* aStream,
already_AddRefed<ThreadSharedFloatArrayBufferList>& aBuffer)
: ControlMessage(aStream), mBuffer(aBuffer) {}
virtual void Run()
: ControlMessage(aStream), mBuffer(aBuffer)
{}
virtual void Run() override
{
static_cast<AudioNodeStream*>(mStream)->Engine()->
SetBuffer(mBuffer.forget());
@ -227,7 +239,8 @@ AudioNodeStream::SetBuffer(already_AddRefed<ThreadSharedFloatArrayBufferList>&&
void
AudioNodeStream::SetRawArrayData(nsTArray<float>& aData)
{
class Message : public ControlMessage {
class Message final : public ControlMessage
{
public:
Message(AudioNodeStream* aStream,
nsTArray<float>& aData)
@ -235,7 +248,7 @@ AudioNodeStream::SetRawArrayData(nsTArray<float>& aData)
{
mData.SwapElements(aData);
}
virtual void Run()
virtual void Run() override
{
static_cast<AudioNodeStream*>(mStream)->Engine()->SetRawArrayData(mData);
}
@ -250,7 +263,8 @@ AudioNodeStream::SetChannelMixingParameters(uint32_t aNumberOfChannels,
ChannelCountMode aChannelCountMode,
ChannelInterpretation aChannelInterpretation)
{
class Message : public ControlMessage {
class Message final : public ControlMessage
{
public:
Message(AudioNodeStream* aStream,
uint32_t aNumberOfChannels,
@ -261,7 +275,7 @@ AudioNodeStream::SetChannelMixingParameters(uint32_t aNumberOfChannels,
mChannelCountMode(aChannelCountMode),
mChannelInterpretation(aChannelInterpretation)
{}
virtual void Run()
virtual void Run() override
{
static_cast<AudioNodeStream*>(mStream)->
SetChannelMixingParametersImpl(mNumberOfChannels, mChannelCountMode,
@ -280,11 +294,13 @@ AudioNodeStream::SetChannelMixingParameters(uint32_t aNumberOfChannels,
void
AudioNodeStream::SetPassThrough(bool aPassThrough)
{
class Message : public ControlMessage {
class Message final : public ControlMessage
{
public:
Message(AudioNodeStream* aStream, bool aPassThrough)
: ControlMessage(aStream), mPassThrough(aPassThrough) {}
virtual void Run()
: ControlMessage(aStream), mPassThrough(aPassThrough)
{}
virtual void Run() override
{
static_cast<AudioNodeStream*>(mStream)->mPassThrough = mPassThrough;
}

View File

@ -31,7 +31,8 @@ class AudioNodeEngine;
* actual audio processing. AudioNodeStream contains the glue code that
* integrates audio processing with the MediaStreamGraph.
*/
class AudioNodeStream : public ProcessedMediaStream {
class AudioNodeStream : public ProcessedMediaStream
{
typedef dom::ChannelCountMode ChannelCountMode;
typedef dom::ChannelInterpretation ChannelInterpretation;

View File

@ -14,7 +14,7 @@
namespace mozilla {
namespace dom {
class AudioProcessingEvent : public Event
class AudioProcessingEvent final : public Event
{
public:
AudioProcessingEvent(ScriptProcessorNode* aOwner,

View File

@ -73,7 +73,7 @@ SetParamsOnBiquad(WebCore::Biquad& aBiquad,
}
}
class BiquadFilterNodeEngine : public AudioNodeEngine
class BiquadFilterNodeEngine final : public AudioNodeEngine
{
public:
BiquadFilterNodeEngine(AudioNode* aNode, AudioDestinationNode* aDestination)

View File

@ -16,7 +16,7 @@ namespace dom {
class AudioContext;
class BiquadFilterNode : public AudioNode
class BiquadFilterNode final : public AudioNode
{
public:
explicit BiquadFilterNode(AudioContext* aContext);

View File

@ -18,7 +18,7 @@ namespace mozilla {
* This class provides a decoder object which decodes a media file that lives in
* a memory buffer.
*/
class BufferDecoder : public AbstractMediaDecoder
class BufferDecoder final : public AbstractMediaDecoder
{
public:
// This class holds a weak pointer to MediaResource. It's the responsibility

View File

@ -14,7 +14,7 @@ namespace dom {
NS_IMPL_ISUPPORTS_INHERITED0(ChannelMergerNode, AudioNode)
class ChannelMergerNodeEngine : public AudioNodeEngine
class ChannelMergerNodeEngine final : public AudioNodeEngine
{
public:
explicit ChannelMergerNodeEngine(ChannelMergerNode* aNode)

View File

@ -14,7 +14,7 @@ namespace dom {
class AudioContext;
class ChannelMergerNode : public AudioNode
class ChannelMergerNode final : public AudioNode
{
public:
ChannelMergerNode(AudioContext* aContext,

View File

@ -14,7 +14,7 @@ namespace dom {
NS_IMPL_ISUPPORTS_INHERITED0(ChannelSplitterNode, AudioNode)
class ChannelSplitterNodeEngine : public AudioNodeEngine
class ChannelSplitterNodeEngine final : public AudioNodeEngine
{
public:
explicit ChannelSplitterNodeEngine(ChannelSplitterNode* aNode)

View File

@ -14,7 +14,7 @@ namespace dom {
class AudioContext;
class ChannelSplitterNode : public AudioNode
class ChannelSplitterNode final : public AudioNode
{
public:
ChannelSplitterNode(AudioContext* aContext,

View File

@ -22,7 +22,7 @@ NS_INTERFACE_MAP_END_INHERITING(AudioNode)
NS_IMPL_ADDREF_INHERITED(ConvolverNode, AudioNode)
NS_IMPL_RELEASE_INHERITED(ConvolverNode, AudioNode)
class ConvolverNodeEngine : public AudioNodeEngine
class ConvolverNodeEngine final : public AudioNodeEngine
{
typedef PlayingRefChangeHandler PlayingRefChanged;
public:

View File

@ -13,7 +13,7 @@
namespace mozilla {
namespace dom {
class ConvolverNode : public AudioNode
class ConvolverNode final : public AudioNode
{
public:
explicit ConvolverNode(AudioContext* aContext);

View File

@ -13,7 +13,8 @@
namespace mozilla {
class DelayBuffer {
class DelayBuffer final
{
typedef dom::ChannelInterpretation ChannelInterpretation;
public:

View File

@ -25,7 +25,7 @@ NS_INTERFACE_MAP_END_INHERITING(AudioNode)
NS_IMPL_ADDREF_INHERITED(DelayNode, AudioNode)
NS_IMPL_RELEASE_INHERITED(DelayNode, AudioNode)
class DelayNodeEngine : public AudioNodeEngine
class DelayNodeEngine final : public AudioNodeEngine
{
typedef PlayingRefChangeHandler PlayingRefChanged;
public:

View File

@ -15,7 +15,7 @@ namespace dom {
class AudioContext;
class DelayNode : public AudioNode
class DelayNode final : public AudioNode
{
public:
DelayNode(AudioContext* aContext, double aMaxDelay);

View File

@ -30,7 +30,7 @@ NS_INTERFACE_MAP_END_INHERITING(AudioNode)
NS_IMPL_ADDREF_INHERITED(DynamicsCompressorNode, AudioNode)
NS_IMPL_RELEASE_INHERITED(DynamicsCompressorNode, AudioNode)
class DynamicsCompressorNodeEngine : public AudioNodeEngine
class DynamicsCompressorNodeEngine final : public AudioNodeEngine
{
public:
explicit DynamicsCompressorNodeEngine(AudioNode* aNode,
@ -151,7 +151,7 @@ private:
{
MOZ_ASSERT(!NS_IsMainThread());
class Command : public nsRunnable
class Command final : public nsRunnable
{
public:
Command(AudioNodeStream* aStream, float aReduction)
@ -160,7 +160,7 @@ private:
{
}
NS_IMETHODIMP Run()
NS_IMETHOD Run() override
{
nsRefPtr<DynamicsCompressorNode> node;
{

View File

@ -15,7 +15,7 @@ namespace dom {
class AudioContext;
class DynamicsCompressorNode : public AudioNode
class DynamicsCompressorNode final : public AudioNode
{
public:
explicit DynamicsCompressorNode(AudioContext* aContext);

View File

@ -16,7 +16,8 @@ namespace mozilla {
// This class defines an FFT block, loosely modeled after Blink's FFTFrame
// class to make sharing code with Blink easy.
// Currently it's implemented on top of KissFFT on all platforms.
class FFTBlock {
class FFTBlock final
{
public:
explicit FFTBlock(uint32_t aFFTSize)
: mFFT(nullptr)

View File

@ -23,7 +23,7 @@ NS_INTERFACE_MAP_END_INHERITING(AudioNode)
NS_IMPL_ADDREF_INHERITED(GainNode, AudioNode)
NS_IMPL_RELEASE_INHERITED(GainNode, AudioNode)
class GainNodeEngine : public AudioNodeEngine
class GainNodeEngine final : public AudioNodeEngine
{
public:
GainNodeEngine(AudioNode* aNode, AudioDestinationNode* aDestination)

View File

@ -15,7 +15,7 @@ namespace dom {
class AudioContext;
class GainNode : public AudioNode
class GainNode final : public AudioNode
{
public:
explicit GainNode(AudioContext* aContext);

View File

@ -50,7 +50,7 @@ NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebAudioDecodeJob, Release)
using namespace dom;
class ReportResultTask : public nsRunnable
class ReportResultTask final : public nsRunnable
{
public:
ReportResultTask(WebAudioDecodeJob& aDecodeJob,
@ -82,13 +82,14 @@ private:
WebAudioDecodeJob::ErrorCode mErrorCode;
};
enum class PhaseEnum : int {
enum class PhaseEnum : int
{
Decode,
AllocateBuffer,
Done
};
class MediaDecodeTask : public nsRunnable
class MediaDecodeTask final : public nsRunnable
{
public:
MediaDecodeTask(const char* aContentType, uint8_t* aBuffer,
@ -214,7 +215,8 @@ MediaDecodeTask::CreateReader()
return true;
}
class AutoResampler {
class AutoResampler final
{
public:
AutoResampler()
: mResampler(nullptr)

View File

@ -12,7 +12,7 @@
namespace mozilla {
namespace dom {
class MediaElementAudioSourceNode : public MediaStreamAudioSourceNode
class MediaElementAudioSourceNode final : public MediaStreamAudioSourceNode
{
public:
MediaElementAudioSourceNode(AudioContext* aContext,

View File

@ -12,7 +12,7 @@
namespace mozilla {
namespace dom {
class MediaStreamAudioDestinationNode : public AudioNode
class MediaStreamAudioDestinationNode final : public AudioNode
{
public:
explicit MediaStreamAudioDestinationNode(AudioContext* aContext);

View File

@ -15,7 +15,7 @@ namespace mozilla {
namespace dom {
class MediaStreamAudioSourceNodeEngine : public AudioNodeEngine
class MediaStreamAudioSourceNodeEngine final : public AudioNodeEngine
{
public:
explicit MediaStreamAudioSourceNodeEngine(AudioNode* aNode)

View File

@ -15,7 +15,7 @@ namespace dom {
class AudioContext;
class OfflineAudioCompletionEvent : public Event
class OfflineAudioCompletionEvent final : public Event
{
public:
OfflineAudioCompletionEvent(AudioContext* aOwner,

View File

@ -23,7 +23,7 @@ NS_INTERFACE_MAP_END_INHERITING(AudioNode)
NS_IMPL_ADDREF_INHERITED(OscillatorNode, AudioNode)
NS_IMPL_RELEASE_INHERITED(OscillatorNode, AudioNode)
class OscillatorNodeEngine : public AudioNodeEngine
class OscillatorNodeEngine final : public AudioNodeEngine
{
public:
OscillatorNodeEngine(AudioNode* aNode, AudioDestinationNode* aDestination)
@ -515,12 +515,12 @@ void
OscillatorNode::NotifyMainThreadStateChanged()
{
if (mStream->IsFinished()) {
class EndedEventDispatcher : public nsRunnable
class EndedEventDispatcher final : public nsRunnable
{
public:
explicit EndedEventDispatcher(OscillatorNode* aNode)
: mNode(aNode) {}
NS_IMETHODIMP Run()
NS_IMETHOD Run() override
{
// If it's not safe to run scripts right now, schedule this to run later
if (!nsContentUtils::IsSafeToRunScript()) {

View File

@ -18,8 +18,8 @@ namespace dom {
class AudioContext;
class OscillatorNode : public AudioNode,
public MainThreadMediaStreamListener
class OscillatorNode final : public AudioNode,
public MainThreadMediaStreamListener
{
public:
explicit OscillatorNode(AudioContext* aContext);

View File

@ -39,7 +39,7 @@ NS_INTERFACE_MAP_END_INHERITING(AudioNode)
NS_IMPL_ADDREF_INHERITED(PannerNode, AudioNode)
NS_IMPL_RELEASE_INHERITED(PannerNode, AudioNode)
class PannerNodeEngine : public AudioNodeEngine
class PannerNodeEngine final : public AudioNodeEngine
{
public:
explicit PannerNodeEngine(AudioNode* aNode)

View File

@ -21,8 +21,8 @@ namespace dom {
class AudioContext;
class AudioBufferSourceNode;
class PannerNode : public AudioNode,
public SupportsWeakPtr<PannerNode>
class PannerNode final : public AudioNode,
public SupportsWeakPtr<PannerNode>
{
public:
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(PannerNode)

View File

@ -13,7 +13,7 @@
namespace mozilla {
namespace dom {
class PlayingRefChangeHandler : public nsRunnable
class PlayingRefChangeHandler final : public nsRunnable
{
public:
enum ChangeType { ADDREF, RELEASE };

View File

@ -12,7 +12,7 @@
namespace mozilla {
class ReportDecodeResultTask : public nsRunnable
class ReportDecodeResultTask final : public nsRunnable
{
public:
ReportDecodeResultTask(DecodeJob& aDecodeJob,

View File

@ -28,10 +28,10 @@ NS_IMPL_ISUPPORTS_INHERITED0(ScriptProcessorNode, AudioNode)
// This class manages a queue of output buffers shared between
// the main thread and the Media Stream Graph thread.
class SharedBuffers
class SharedBuffers final
{
private:
class OutputQueue
class OutputQueue final
{
public:
explicit OutputQueue(const char* aName)
@ -237,7 +237,7 @@ private:
bool mDroppingBuffers;
};
class ScriptProcessorNodeEngine : public AudioNodeEngine
class ScriptProcessorNodeEngine final : public AudioNodeEngine
{
public:
typedef nsAutoTArray<nsAutoArrayPtr<float>, 2> InputChannels;
@ -361,7 +361,7 @@ private:
double playbackTime =
mSource->DestinationTimeFromTicks(mDestination, playbackTick);
class Command : public nsRunnable
class Command final : public nsRunnable
{
public:
Command(AudioNodeStream* aStream,
@ -380,7 +380,7 @@ private:
}
}
NS_IMETHODIMP Run()
NS_IMETHOD Run() override
{
nsRefPtr<ScriptProcessorNode> node = static_cast<ScriptProcessorNode*>
(mStream->Engine()->NodeMainThread());

View File

@ -16,7 +16,7 @@ namespace dom {
class AudioContext;
class SharedBuffers;
class ScriptProcessorNode : public AudioNode
class ScriptProcessorNode final : public AudioNode
{
public:
ScriptProcessorNode(AudioContext* aContext,

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