Skip to content

Commit

Permalink
Merge inbound to mozilla-central r=merge a=merge
Browse files Browse the repository at this point in the history
  • Loading branch information
elizabal committed Oct 31, 2017
2 parents 0e8b198 + f914612 commit 49e0956
Show file tree
Hide file tree
Showing 76 changed files with 353 additions and 1,020 deletions.
6 changes: 4 additions & 2 deletions accessible/windows/msaa/AccessibleWrap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1554,8 +1554,10 @@ AccessibleWrap::GetRemoteIAccessibleFor(const VARIANT& aVarChild)

RefPtr<IAccessible> result;

size_t docCount = remoteDocs->Length();
for (size_t i = 0; i < docCount; i++) {
// We intentionally leave the call to remoteDocs->Length() inside the loop
// condition because it is possible for reentry to occur in the call to
// GetProxiedAccessibleInSubtree() such that remoteDocs->Length() is mutated.
for (size_t i = 0; i < remoteDocs->Length(); i++) {
DocAccessibleParent* remoteDoc = remoteDocs->ElementAt(i);

uint32_t remoteDocMsaaId = WrapperFor(remoteDoc)->GetExistingID();
Expand Down
3 changes: 3 additions & 0 deletions browser/base/content/tabbrowser.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2565,6 +2565,9 @@
tab.removeAttribute("linkedpanel");
this._createLazyBrowser(tab);
let evt = new CustomEvent("TabBrowserDiscarded", { bubbles: true });
tab.dispatchEvent(evt);
]]>
</body>
</method>
Expand Down
15 changes: 15 additions & 0 deletions browser/components/extensions/ext-tabs.js
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,8 @@ this.tabs = class extends ExtensionAPI {
} else if (event.type == "TabBrowserInserted" &&
!event.detail.insertedOnTabCreation) {
needed.push("discarded");
} else if (event.type == "TabBrowserDiscarded") {
needed.push("discarded");
}

let tab = tabManager.getWrapper(event.originalTarget);
Expand Down Expand Up @@ -307,6 +309,7 @@ this.tabs = class extends ExtensionAPI {
windowTracker.addListener("TabPinned", listener);
windowTracker.addListener("TabUnpinned", listener);
windowTracker.addListener("TabBrowserInserted", listener);
windowTracker.addListener("TabBrowserDiscarded", listener);

tabTracker.on("tab-isarticle", isArticleChangeListener);

Expand All @@ -316,6 +319,7 @@ this.tabs = class extends ExtensionAPI {
windowTracker.removeListener("TabPinned", listener);
windowTracker.removeListener("TabUnpinned", listener);
windowTracker.removeListener("TabBrowserInserted", listener);
windowTracker.removeListener("TabBrowserDiscarded", listener);
tabTracker.off("tab-isarticle", isArticleChangeListener);
};
}).api(),
Expand Down Expand Up @@ -446,6 +450,17 @@ this.tabs = class extends ExtensionAPI {
}
},

async discard(tabIds) {
if (!Array.isArray(tabIds)) {
tabIds = [tabIds];
}
let tabs = tabIds.map(tabId => tabTracker.getTab(tabId));

for (let tab of tabs) {
tab.ownerGlobal.gBrowser.discardBrowser(tab.linkedBrowser);
}
},

async update(tabId, updateProperties) {
let nativeTab = getTabOrActive(tabId);

Expand Down
16 changes: 16 additions & 0 deletions browser/components/extensions/schemas/tabs.json
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,22 @@
}
]
},
{
"name": "discard",
"type": "function",
"description": "discards one or more tabs.",
"async": true,
"parameters": [
{
"name": "tabIds",
"description": "The tab or list of tabs to discard.",
"choices": [
{"type": "integer", "minimum": 0},
{"type": "array", "items": {"type": "integer", "minimum": 0}}
]
}
]
},
{
"name": "detectLanguage",
"type": "function",
Expand Down
2 changes: 2 additions & 0 deletions browser/components/extensions/test/browser/browser-common.ini
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ skip-if = !e10s || debug || asan
skip-if = os == "linux" && debug && bits == 32 # Bug 1350189
[browser_ext_tabs_create_invalid_url.js]
[browser_ext_tabs_detectLanguage.js]
[browser_ext_tabs_discard.js]
skip-if = !e10s
[browser_ext_tabs_discarded.js]
[browser_ext_tabs_duplicate.js]
[browser_ext_tabs_events.js]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
/* global gBrowser SessionStore */
"use strict";

add_task(async function test_discarded() {
let extension = ExtensionTestUtils.loadExtension({
manifest: {
"permissions": ["tabs"],
},

background: async function() {
let tabs = await browser.tabs.query({currentWindow: true});
tabs.sort((tab1, tab2) => tab1.index - tab2.index);

async function finishTest() {
try {
await browser.tabs.discard(tabs[0].id);
await browser.tabs.discard(tabs[2].id);
browser.test.succeed("attempting to discard an already discarded tab or the active tab should not throw error");
} catch (e) {
browser.test.fail("attempting to discard an already discarded tab or the active tab should not throw error");
}
let discardedTab = await browser.tabs.get(tabs[2].id);
browser.test.assertEq(false, discardedTab.discarded, "attempting to discard the active tab should not have succeeded");

await browser.test.assertRejects(browser.tabs.discard(999999999), /Invalid tab ID/, "attempt to discard invalid tabId should throw");
await browser.test.assertRejects(browser.tabs.discard([999999999, tabs[1].id]), /Invalid tab ID/, "attempt to discard a valid and invalid tabId should throw");
discardedTab = await browser.tabs.get(tabs[1].id);
browser.test.assertEq(false, discardedTab.discarded, "tab is still not discarded");

browser.test.notifyPass("test-finished");
}

browser.tabs.onUpdated.addListener(async function(tabId, updatedInfo) {
if ("discarded" in updatedInfo) {
browser.test.assertEq(tabId, tabs[0].id, "discarding tab triggered onUpdated");
let discardedTab = await browser.tabs.get(tabs[0].id);
browser.test.assertEq(true, discardedTab.discarded, "discarded tab discard property");

await finishTest();
}
});

browser.tabs.discard(tabs[0].id);
},
});

BrowserTestUtils.loadURI(gBrowser.browsers[0], "http://example.com");
await BrowserTestUtils.browserLoaded(gBrowser.browsers[0]);
let tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com");
let tab2 = await BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com");

await extension.startup();

await extension.awaitFinish("test-finished");
await extension.unload();

await BrowserTestUtils.removeTab(tab1);
await BrowserTestUtils.removeTab(tab2);
});

Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"tabs.create",
"tabs.detectLanguage",
"tabs.duplicate",
"tabs.discard",
"tabs.executeScript",
"tabs.get",
"tabs.getCurrent",
Expand Down
10 changes: 1 addition & 9 deletions browser/components/preferences/in-content/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -1341,15 +1341,7 @@ var gMainPane = {

// nsISupports

QueryInterface(aIID) {
if (aIID.equals(Ci.nsIObserver) ||
aIID.equals(Ci.nsIDOMEventListener ||
aIID.equals(Ci.nsISupports)))
return this;

throw Cr.NS_ERROR_NO_INTERFACE;
},

QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsIDOMEventListener]),

// nsIObserver

Expand Down
8 changes: 8 additions & 0 deletions dom/base/nsContentUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5829,6 +5829,14 @@ nsContentUtils::RunInMetastableState(already_AddRefed<nsIRunnable> aRunnable)
CycleCollectedJSContext::Get()->RunInMetastableState(Move(aRunnable));
}

/* static */
bool
nsContentUtils::IsInStableOrMetaStableState()
{
MOZ_ASSERT(CycleCollectedJSContext::Get(), "Must be on a script thread!");
return CycleCollectedJSContext::Get()->IsInStableOrMetaStableState();
}

/* static */
nsISerialEventTarget*
nsContentUtils::GetStableStateEventTarget()
Expand Down
5 changes: 5 additions & 0 deletions dom/base/nsContentUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -1972,6 +1972,11 @@ class nsContentUtils
*/
static void RunInMetastableState(already_AddRefed<nsIRunnable> aRunnable);

/**
* Returns true if we are doing StableState/MetastableState.
*/
static bool IsInStableOrMetaStableState();

/**
* Returns a nsISerialEventTarget which will run any event dispatched to it
* once the event loop has reached a "stable state". Runnables dispatched to
Expand Down
4 changes: 4 additions & 0 deletions dom/events/EventDispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,10 @@ EventDispatcher::Dispatch(nsISupports* aTarget,
NS_ENSURE_TRUE(aEvent->mMessage || !aDOMEvent || aTargets,
NS_ERROR_DOM_INVALID_STATE_ERR);

// Events shall not be fired while we are in stable state to prevent anything
// visible from the scripts.
MOZ_ASSERT(!nsContentUtils::IsInStableOrMetaStableState());

#ifdef MOZ_TASK_TRACER
if (MOZ_UNLIKELY(mozilla::tasktracer::IsStartLogging())) {
nsAutoCString eventType;
Expand Down
6 changes: 6 additions & 0 deletions dom/file/MutableBlobStorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,11 @@ MutableBlobStorage::Append(const void* aData, uint32_t aLength)
// If we are already in the temporaryFile mode, we have to dispatch a
// runnable.
if (mStorageState == eInTemporaryFile) {
// If a previous operation failed, let's return that error now.
if (NS_FAILED(mErrorResult)) {
return mErrorResult;
}

RefPtr<WriteRunnable> runnable =
WriteRunnable::CopyBuffer(this, aData, aLength);
if (NS_WARN_IF(!runnable)) {
Expand Down Expand Up @@ -590,6 +595,7 @@ MutableBlobStorage::TemporaryFileCreated(PRFileDesc* aFD)
}

mFD = aFD;
MOZ_ASSERT(NS_SUCCEEDED(mErrorResult));

// This runnable takes the ownership of mData and it will write this buffer
// into the temporary file.
Expand Down
12 changes: 4 additions & 8 deletions dom/ipc/ContentChild.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3121,8 +3121,7 @@ ContentChild::RecvSetAudioSessionData(const nsID& aId,
mozilla::widget::StartAudioSession();
return IPC_OK();
#else
NS_RUNTIMEABORT("Not Reached!");
return IPC_FAIL_NO_REASON(this);
MOZ_CRASH("Not Reached!");
#endif
}

Expand Down Expand Up @@ -3580,8 +3579,7 @@ ContentChild::RecvShareCodeCoverageMutex(const CrossProcessMutexHandle& aHandle)
CodeCoverageHandler::Init(aHandle);
return IPC_OK();
#else
NS_RUNTIMEABORT("Shouldn't receive this message in non-code coverage builds!");
return IPC_FAIL_NO_REASON(this);
MOZ_CRASH("Shouldn't receive this message in non-code coverage builds!");
#endif
}

Expand All @@ -3592,8 +3590,7 @@ ContentChild::RecvDumpCodeCoverageCounters()
CodeCoverageHandler::DumpCounters(0);
return IPC_OK();
#else
NS_RUNTIMEABORT("Shouldn't receive this message in non-code coverage builds!");
return IPC_FAIL_NO_REASON(this);
MOZ_CRASH("Shouldn't receive this message in non-code coverage builds!");
#endif
}

Expand All @@ -3604,8 +3601,7 @@ ContentChild::RecvResetCodeCoverageCounters()
CodeCoverageHandler::ResetCounters(0);
return IPC_OK();
#else
NS_RUNTIMEABORT("Shouldn't receive this message in non-code coverage builds!");
return IPC_FAIL_NO_REASON(this);
MOZ_CRASH("Shouldn't receive this message in non-code coverage builds!");
#endif
}

Expand Down
3 changes: 1 addition & 2 deletions dom/ipc/ContentParent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1063,8 +1063,7 @@ mozilla::ipc::IPCResult
ContentParent::RecvUngrabPointer(const uint32_t& aTime)
{
#if !defined(MOZ_WIDGET_GTK)
NS_RUNTIMEABORT("This message only makes sense on GTK platforms");
return IPC_OK();
MOZ_CRASH("This message only makes sense on GTK platforms");
#else
gdk_pointer_ungrab(aTime);
return IPC_OK();
Expand Down
26 changes: 24 additions & 2 deletions dom/media/MediaDecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,18 @@ class MediaDecoder::BackgroundVideoDecodingPermissionObserver final :
if (observerService) {
observerService->AddObserver(this, "unselected-tab-hover", false);
mIsRegisteredForEvent = true;
EnableEvent();
if (nsContentUtils::IsInStableOrMetaStableState()) {
// Events shall not be fired synchronously to prevent anything visible
// from the scripts while we are in stable state.
if (nsCOMPtr<nsIDocument> doc = GetOwnerDoc()) {
doc->Dispatch(TaskCategory::Other,
NewRunnableMethod(
"MediaDecoder::BackgroundVideoDecodingPermissionObserver::EnableEvent",
this, &MediaDecoder::BackgroundVideoDecodingPermissionObserver::EnableEvent));
}
} else {
EnableEvent();
}
}
}

Expand All @@ -170,7 +181,18 @@ class MediaDecoder::BackgroundVideoDecodingPermissionObserver final :
mIsRegisteredForEvent = false;
mDecoder->mIsBackgroundVideoDecodingAllowed = false;
mDecoder->UpdateVideoDecodeMode();
DisableEvent();
if (nsContentUtils::IsInStableOrMetaStableState()) {
// Events shall not be fired synchronously to prevent anything visible
// from the scripts while we are in stable state.
if (nsCOMPtr<nsIDocument> doc = GetOwnerDoc()) {
doc->Dispatch(TaskCategory::Other,
NewRunnableMethod(
"MediaDecoder::BackgroundVideoDecodingPermissionObserver::DisableEvent",
this, &MediaDecoder::BackgroundVideoDecodingPermissionObserver::DisableEvent));
}
} else {
DisableEvent();
}
}
}
private:
Expand Down
44 changes: 35 additions & 9 deletions dom/media/webspeech/synth/nsSpeechTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,18 +61,35 @@ class SynthStreamListener : public MediaStreamListener
switch (event) {
case MediaStreamGraphEvent::EVENT_FINISHED:
{
RefPtr<SynthStreamListener> self = this;
if (!mStarted) {
mStarted = true;
aGraph->DispatchToMainThreadAfterStreamStateUpdate(
NewRunnableMethod("dom::SynthStreamListener::DoNotifyStarted",
this,
&SynthStreamListener::DoNotifyStarted));
NS_NewRunnableFunction(
"dom::SynthStreamListener::NotifyEvent",
[self] {
// "start" event will be fired in DoNotifyStarted() which is
// not allowed in stable state, so we do it asynchronously in
// next run.
NS_DispatchToMainThread(NewRunnableMethod(
"dom::SynthStreamListener::DoNotifyStarted",
self,
&SynthStreamListener::DoNotifyStarted));
}));
}

aGraph->DispatchToMainThreadAfterStreamStateUpdate(
NewRunnableMethod("dom::SynthStreamListener::DoNotifyFinished",
this,
&SynthStreamListener::DoNotifyFinished));
NS_NewRunnableFunction(
"dom::SynthStreamListener::NotifyEvent",
[self] {
// "end" event will be fired in DoNotifyFinished() which is
// not allowed in stable state, so we do it asynchronously in
// next run.
NS_DispatchToMainThread(NewRunnableMethod(
"dom::SynthStreamListener::DoNotifyFinished",
self,
&SynthStreamListener::DoNotifyFinished));
}));
}
break;
case MediaStreamGraphEvent::EVENT_REMOVED:
Expand All @@ -89,10 +106,19 @@ class SynthStreamListener : public MediaStreamListener
{
if (aBlocked == MediaStreamListener::UNBLOCKED && !mStarted) {
mStarted = true;
RefPtr<SynthStreamListener> self = this;
aGraph->DispatchToMainThreadAfterStreamStateUpdate(
NewRunnableMethod("dom::SynthStreamListener::DoNotifyStarted",
this,
&SynthStreamListener::DoNotifyStarted));
NS_NewRunnableFunction(
"dom::SynthStreamListener::NotifyBlockingChanged",
[self] {
// "start" event will be fired in DoNotifyStarted() which is
// not allowed in stable state, so we do it asynchronously in
// next run.
NS_DispatchToMainThread(NewRunnableMethod(
"dom::SynthStreamListener::DoNotifyStarted",
self,
&SynthStreamListener::DoNotifyStarted));
}));
}
}

Expand Down
Loading

0 comments on commit 49e0956

Please sign in to comment.