diff --git a/.cron.yml b/.cron.yml index 696cfe67f424..faef2cc8e4d3 100644 --- a/.cron.yml +++ b/.cron.yml @@ -46,12 +46,7 @@ jobs: run-on-projects: - mozilla-central - date - when: - by-project: - # Match buildbot starts for now - date: [{hour: 15, minute: 0}] - mozilla-central: [{hour: 10, minute: 0}] - # No default + when: [] # never (hook only) - name: nightly-android job: diff --git a/browser/base/content/tab-content.js b/browser/base/content/tab-content.js index 460c8847d657..92861d38eb57 100644 --- a/browser/base/content/tab-content.js +++ b/browser/base/content/tab-content.js @@ -911,7 +911,6 @@ var RefreshBlocker = { this._filter = Cc["@mozilla.org/appshell/component/browser-status-filter;1"] .createInstance(Ci.nsIWebProgress); this._filter.addProgressListener(this, Ci.nsIWebProgress.NOTIFY_ALL); - this._filter.target = tabEventTarget; let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIWebProgress); diff --git a/browser/base/content/test/performance/browser.ini b/browser/base/content/test/performance/browser.ini index 4a9e65c4ca02..37fdf51937aa 100644 --- a/browser/base/content/test/performance/browser.ini +++ b/browser/base/content/test/performance/browser.ini @@ -14,8 +14,6 @@ skip-if = !debug [browser_tabopen_squeeze_reflows.js] [browser_tabswitch_reflows.js] [browser_toolbariconcolor_restyles.js] -[browser_urlbar_search_reflows.js] -skip-if = os == 'mac' && !debug # Disabled due to frequent failures. Bug 1384582 [browser_windowclose_reflows.js] [browser_windowopen_reflows.js] skip-if = os == 'linux' # Disabled due to frequent failures. Bug 1380465. diff --git a/browser/base/content/test/performance/browser_appmenu_reflows.js b/browser/base/content/test/performance/browser_appmenu_reflows.js index 51e79e4ec958..61b0fd5206b2 100644 --- a/browser/base/content/test/performance/browser_appmenu_reflows.js +++ b/browser/base/content/test/performance/browser_appmenu_reflows.js @@ -10,49 +10,68 @@ * for tips on how to do that. */ const EXPECTED_APPMENU_OPEN_REFLOWS = [ - { - stack: [ - "openPopup@chrome://global/content/bindings/popup.xml", - "show/ { - return URLBar.controller.searchStatus >= - Ci.nsIAutoCompleteController.STATUS_COMPLETE_NO_MATCH; - }); - let matchCount = URLBar.popup._matchCount; - await BrowserTestUtils.waitForCondition(() => { - return URLBar.popup.richlistbox.childNodes.length == matchCount; - }); - - URLBar.controller.stopSearch(); - // There are several setTimeout(fn, 0); calls inside autocomplete.xml - // that we need to wait for. Since those have higher priority than - // idle callbacks, we can be sure they will have run once this - // idle callback is called. The timeout seems to be required in - // automation - presumably because the machines can be pretty busy - // especially if it's GC'ing from previous tests. - await new Promise(resolve => win.requestIdleCallback(resolve, { timeout: 1000 })); - - let hiddenPromise = BrowserTestUtils.waitForEvent(URLBar.popup, "popuphidden"); - EventUtils.synthesizeKey("VK_ESCAPE", {}, win); - await hiddenPromise; -} - -const SEARCH_TERM = "urlbar-reflows"; - -add_task(async function setup() { - const NUM_VISITS = 10; - let visits = []; - - for (let i = 0; i < NUM_VISITS; ++i) { - visits.push({ - uri: `http://example.com/urlbar-reflows-${i}`, - title: `Reflow test for URL bar entry #${i}`, - }); - } - - await PlacesTestUtils.addVisits(visits); - - registerCleanupFunction(async function() { - await PlacesTestUtils.clearHistory(); - }); -}); - -/** - * This test ensures that there are no unexpected - * uninterruptible reflows when typing into the URL bar - * with the default values in Places. - */ -add_task(async function() { - let win = await BrowserTestUtils.openNewBrowserWindow(); - await ensureNoPreloadedBrowser(win); - - let URLBar = win.gURLBar; - let popup = URLBar.popup; - - URLBar.focus(); - URLBar.value = SEARCH_TERM; - let testFn = async function(dirtyFrameFn) { - let oldInvalidate = popup.invalidate.bind(popup); - let oldResultsAdded = popup.onResultsAdded.bind(popup); - - // We need to invalidate the frame tree outside of the normal - // mechanism since invalidations and result additions to the - // URL bar occur without firing JS events (which is how we - // normally know to dirty the frame tree). - popup.invalidate = (reason) => { - dirtyFrameFn(); - oldInvalidate(reason); - }; - - popup.onResultsAdded = () => { - dirtyFrameFn(); - oldResultsAdded(); - }; - - await promiseAutocompleteResultPopup(win); - }; - - await withReflowObserver(testFn, EXPECTED_REFLOWS_FIRST_OPEN, win); - - await withReflowObserver(testFn, EXPECTED_REFLOWS_SECOND_OPEN, win); - - await BrowserTestUtils.closeWindow(win); -}); diff --git a/browser/base/content/test/performance/browser_windowopen_reflows.js b/browser/base/content/test/performance/browser_windowopen_reflows.js index 9019e5306ef7..f00ef85dc659 100644 --- a/browser/base/content/test/performance/browser_windowopen_reflows.js +++ b/browser/base/content/test/performance/browser_windowopen_reflows.js @@ -13,94 +13,114 @@ * for tips on how to do that. */ const EXPECTED_REFLOWS = [ - { - stack: [ - "select@chrome://global/content/bindings/textbox.xml", - "focusAndSelectUrlBar@chrome://browser/content/browser.js", - "_delayedStartup@chrome://browser/content/browser.js", - ], - }, + [ + "select@chrome://global/content/bindings/textbox.xml", + "focusAndSelectUrlBar@chrome://browser/content/browser.js", + "_delayedStartup@chrome://browser/content/browser.js", + ], ]; if (Services.appinfo.OS == "Linux") { if (gMultiProcessBrowser) { - EXPECTED_REFLOWS.push({ - stack: [ + EXPECTED_REFLOWS.push( + [ "handleEvent@chrome://browser/content/tabbrowser.xml", "EventListener.handleEvent*tabbrowser-tabs_XBL_Constructor@chrome://browser/content/tabbrowser.xml", ], - }); + ); } else { - EXPECTED_REFLOWS.push({ - stack: [ + EXPECTED_REFLOWS.push( + [ "handleEvent@chrome://browser/content/tabbrowser.xml", "inferFromText@chrome://browser/content/browser.js", "handleEvent@chrome://browser/content/browser.js", ], - }); + ); } } if (Services.appinfo.OS == "Darwin") { - EXPECTED_REFLOWS.push({ - stack: [ + EXPECTED_REFLOWS.push( + [ "handleEvent@chrome://browser/content/tabbrowser.xml", "inferFromText@chrome://browser/content/browser.js", "handleEvent@chrome://browser/content/browser.js", ], - }); + ); } if (Services.appinfo.OS == "WINNT") { EXPECTED_REFLOWS.push( - { - stack: [ - "verticalMargins@chrome://browser/content/browser-tabsintitlebar.js", - "_update@chrome://browser/content/browser-tabsintitlebar.js", - "updateAppearance@chrome://browser/content/browser-tabsintitlebar.js", - "handleEvent@chrome://browser/content/tabbrowser.xml", - ], - times: 2, // This number should only ever go down - never up. - }, + [ + "verticalMargins@chrome://browser/content/browser-tabsintitlebar.js", + "_update@chrome://browser/content/browser-tabsintitlebar.js", + "updateAppearance@chrome://browser/content/browser-tabsintitlebar.js", + "handleEvent@chrome://browser/content/tabbrowser.xml", + ], - { - stack: [ - "handleEvent@chrome://browser/content/tabbrowser.xml", - "inferFromText@chrome://browser/content/browser.js", - "handleEvent@chrome://browser/content/browser.js", - ], - }, + [ + "verticalMargins@chrome://browser/content/browser-tabsintitlebar.js", + "_update@chrome://browser/content/browser-tabsintitlebar.js", + "updateAppearance@chrome://browser/content/browser-tabsintitlebar.js", + "handleEvent@chrome://browser/content/tabbrowser.xml", + ], - { - stack: [ - "handleEvent@chrome://browser/content/tabbrowser.xml", - "EventListener.handleEvent*tabbrowser-tabs_XBL_Constructor@chrome://browser/content/tabbrowser.xml", - ], - } + [ + "handleEvent@chrome://browser/content/tabbrowser.xml", + "inferFromText@chrome://browser/content/browser.js", + "handleEvent@chrome://browser/content/browser.js", + ], + + [ + "handleEvent@chrome://browser/content/tabbrowser.xml", + "EventListener.handleEvent*tabbrowser-tabs_XBL_Constructor@chrome://browser/content/tabbrowser.xml", + ], ); } if (Services.appinfo.OS == "WINNT" || Services.appinfo.OS == "Darwin") { EXPECTED_REFLOWS.push( - { - stack: [ - "rect@chrome://browser/content/browser-tabsintitlebar.js", - "_update@chrome://browser/content/browser-tabsintitlebar.js", - "updateAppearance@chrome://browser/content/browser-tabsintitlebar.js", - "handleEvent@chrome://browser/content/tabbrowser.xml", - ], - times: 4, // This number should only ever go down - never up. - }, + [ + "rect@chrome://browser/content/browser-tabsintitlebar.js", + "_update@chrome://browser/content/browser-tabsintitlebar.js", + "updateAppearance@chrome://browser/content/browser-tabsintitlebar.js", + "handleEvent@chrome://browser/content/tabbrowser.xml", + ], - { - stack: [ - "verticalMargins@chrome://browser/content/browser-tabsintitlebar.js", - "_update@chrome://browser/content/browser-tabsintitlebar.js", - "updateAppearance@chrome://browser/content/browser-tabsintitlebar.js", - "handleEvent@chrome://browser/content/tabbrowser.xml", - ], - times: 2, // This number should only ever go down - never up. - } + [ + "rect@chrome://browser/content/browser-tabsintitlebar.js", + "_update@chrome://browser/content/browser-tabsintitlebar.js", + "updateAppearance@chrome://browser/content/browser-tabsintitlebar.js", + "handleEvent@chrome://browser/content/tabbrowser.xml", + ], + + [ + "rect@chrome://browser/content/browser-tabsintitlebar.js", + "_update@chrome://browser/content/browser-tabsintitlebar.js", + "updateAppearance@chrome://browser/content/browser-tabsintitlebar.js", + "handleEvent@chrome://browser/content/tabbrowser.xml", + ], + + [ + "rect@chrome://browser/content/browser-tabsintitlebar.js", + "_update@chrome://browser/content/browser-tabsintitlebar.js", + "updateAppearance@chrome://browser/content/browser-tabsintitlebar.js", + "handleEvent@chrome://browser/content/tabbrowser.xml", + ], + + [ + "verticalMargins@chrome://browser/content/browser-tabsintitlebar.js", + "_update@chrome://browser/content/browser-tabsintitlebar.js", + "updateAppearance@chrome://browser/content/browser-tabsintitlebar.js", + "handleEvent@chrome://browser/content/tabbrowser.xml", + ], + + [ + "verticalMargins@chrome://browser/content/browser-tabsintitlebar.js", + "_update@chrome://browser/content/browser-tabsintitlebar.js", + "updateAppearance@chrome://browser/content/browser-tabsintitlebar.js", + "handleEvent@chrome://browser/content/tabbrowser.xml", + ], ); } diff --git a/browser/base/content/test/performance/head.js b/browser/base/content/test/performance/head.js index 07a8488dd1df..32198cb9146a 100644 --- a/browser/base/content/test/performance/head.js +++ b/browser/base/content/test/performance/head.js @@ -2,42 +2,59 @@ * Async utility function for ensuring that no unexpected uninterruptible * reflows occur during some period of time in a window. * + * The helper works by running a JS function before each event is + * dispatched that attempts to dirty the layout tree - the idea being + * that this puts us in the "worst case scenario" so that any JS + * that attempts to query for layout or style information will cause + * a reflow to fire. We also dirty the layout tree after each reflow + * occurs, for good measure. + * + * This sounds good in theory, but it's trickier in practice due to + * various optimizations in our Layout engine. The default function + * for dirtying the layout tree adds a margin to the first element + * child it finds in the window to a maximum of 3px, and then goes + * back to 0px again and loops. + * + * This is not sufficient for reflows that we expect to happen within + * scrollable frames, as Gecko is able to side-step reflowing the + * contents of a scrollable frame if outer frames are dirtied. Because + * of this, it's currently possible to override the default node to + * dirty with one more appropriate for the test. + * + * It is also theoretically possible for enough events to fire between + * reflows such that the before and after state of the layout tree is + * exactly the same, meaning that no reflow is required, which opens + * us up to missing expected reflows. This seems to be possible in + * theory, but hasn't yet shown up in practice - it's just something + * to be aware of. + * + * Bug 1363361 has been filed for a more reliable way of dirtying layout. + * * @param testFn (async function) * The async function that will exercise the browser activity that is * being tested for reflows. - * - * The testFn will be passed a single argument, which is a frame dirtying - * function that can be called if the test needs to trigger frame - * dirtying outside of the normal mechanism. - * @param expectedReflows (Array, optional) - * An Array of Objects representing reflows. + * @param expectedStacks (Array, optional) + * An Array of Arrays representing stacks. * * Example: * * [ - * { - * // This reflow is caused by lorem ipsum - * stack: [ - * "select@chrome://global/content/bindings/textbox.xml", - * "focusAndSelectUrlBar@chrome://browser/content/browser.js", - * "openLinkIn@chrome://browser/content/utilityOverlay.js", - * "openUILinkIn@chrome://browser/content/utilityOverlay.js", - * "BrowserOpenTab@chrome://browser/content/browser.js", - * ], - * // We expect this particular reflow to happen 2 times - * times: 2, - * }, + * // This reflow is caused by lorem ipsum + * [ + * "select@chrome://global/content/bindings/textbox.xml", + * "focusAndSelectUrlBar@chrome://browser/content/browser.js", + * "openLinkIn@chrome://browser/content/utilityOverlay.js", + * "openUILinkIn@chrome://browser/content/utilityOverlay.js", + * "BrowserOpenTab@chrome://browser/content/browser.js", + * ], * - * { - * // This reflow is caused by lorem ipsum. We expect this reflow - * // to only happen once, so we can omit the "times" property. - * stack: [ - * "get_scrollPosition@chrome://global/content/bindings/scrollbox.xml", - * "_fillTrailingGap@chrome://browser/content/tabbrowser.xml", - * "_handleNewTab@chrome://browser/content/tabbrowser.xml", - * "onxbltransitionend@chrome://browser/content/tabbrowser.xml", - * ], - * } + * // This reflow is caused by lorem ipsum + * [ + * "get_scrollPosition@chrome://global/content/bindings/scrollbox.xml", + * "_fillTrailingGap@chrome://browser/content/tabbrowser.xml", + * "_handleNewTab@chrome://browser/content/tabbrowser.xml", + * "onxbltransitionend@chrome://browser/content/tabbrowser.xml", + * ], * * ] * @@ -49,7 +66,7 @@ * @param window (browser window, optional) * The browser window to monitor. Defaults to the current window. */ -async function withReflowObserver(testFn, expectedReflows = [], win = window) { +async function withReflowObserver(testFn, expectedStacks = [], win = window) { let dwu = win.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIDOMWindowUtils); let dirtyFrameFn = () => { @@ -64,14 +81,9 @@ async function withReflowObserver(testFn, expectedReflows = [], win = window) { let els = Cc["@mozilla.org/eventlistenerservice;1"] .getService(Ci.nsIEventListenerService); - // We're going to remove the reflows one by one as we see them so that + // We're going to remove the stacks one by one as we see them so that // we can check for expected, unseen reflows, so let's clone the array. - // While we're at it, for reflows that omit the "times" property, default - // it to 1. - expectedReflows = expectedReflows.slice(0); - expectedReflows.forEach(r => { - r.times = r.times || 1; - }); + expectedStacks = expectedStacks.slice(0); let observer = { reflow(start, end) { @@ -92,14 +104,12 @@ async function withReflowObserver(testFn, expectedReflows = [], win = window) { return; } - let index = expectedReflows.findIndex(reflow => path.startsWith(reflow.stack.join("|"))); + let index = expectedStacks.findIndex(stack => path.startsWith(stack.join("|"))); if (index != -1) { Assert.ok(true, "expected uninterruptible reflow: '" + JSON.stringify(pathWithLineNumbers, null, "\t") + "'"); - if (--expectedReflows[index].times == 0) { - expectedReflows.splice(index, 1); - } + expectedStacks.splice(index, 1); } else { Assert.ok(false, "unexpected uninterruptible reflow \n" + JSON.stringify(pathWithLineNumbers, null, "\t") + "\n"); @@ -125,16 +135,16 @@ async function withReflowObserver(testFn, expectedReflows = [], win = window) { try { dirtyFrameFn(); - await testFn(dirtyFrameFn); + await testFn(); } finally { - for (let remainder of expectedReflows) { + for (let remainder of expectedStacks) { Assert.ok(false, - `Unused expected reflow: ${JSON.stringify(remainder.stack, null, "\t")}\n` + - `This reflow was supposed to be hit ${remainder.times} more time(s).\n` + + `Unused expected reflow: ${JSON.stringify(remainder, null, "\t")}.\n` + "This is probably a good thing - just remove it from the " + "expected list."); } + els.removeListenerForAllEvents(win, dirtyFrameFn, true); docShell.removeWeakReflowObserver(observer); } diff --git a/browser/components/customizableui/test/browser_1008559_anchor_undo_restore.js b/browser/components/customizableui/test/browser_1008559_anchor_undo_restore.js index 94f3fd1493b9..1e9525c80d5b 100644 --- a/browser/components/customizableui/test/browser_1008559_anchor_undo_restore.js +++ b/browser/components/customizableui/test/browser_1008559_anchor_undo_restore.js @@ -17,9 +17,7 @@ add_task(async function() { "Button (" + button.id + ") starts out with correct anchor"); let navbar = document.getElementById("nav-bar").customizationTarget; - let onMouseUp = BrowserTestUtils.waitForEvent(navbar, "mouseup"); simulateItemDrag(button, navbar); - await onMouseUp; is(CustomizableUI.getPlacementOfWidget(button.id).area, "nav-bar", "Button (" + button.id + ") ends up in nav-bar"); @@ -57,9 +55,7 @@ add_task(async function() { "Button (" + button.id + ") has no anchor in toolbar"); let panel = document.getElementById("PanelUI-contents"); - let onMouseUp = BrowserTestUtils.waitForEvent(panel, "mouseup"); simulateItemDrag(button, panel); - await onMouseUp; is(CustomizableUI.getPlacementOfWidget(button.id).area, "PanelUI-contents", "Button (" + button.id + ") ends up in panel"); is(button.getAttribute(kAnchorAttribute), "PanelUI-menu-button", diff --git a/devtools/client/framework/test/browser_toolbox_races.js b/devtools/client/framework/test/browser_toolbox_races.js index e184e2953929..2dca65e94a2f 100644 --- a/devtools/client/framework/test/browser_toolbox_races.js +++ b/devtools/client/framework/test/browser_toolbox_races.js @@ -11,7 +11,6 @@ requestLongerTimeout(2); // Test toggling the toolbox quickly and see if there is any race breaking it. const URL = "data:text/html;charset=utf-8,Toggling devtools quickly"; -const {gDevToolsBrowser} = require("devtools/client/framework/devtools-browser"); add_task(function* () { // Make sure this test starts with the selectedTool pref cleared. Previous @@ -81,10 +80,5 @@ add_task(function* () { }); function toggle() { - // When enabling the input event prioritization, we'll reserve some time to - // process input events in each frame. In that case, the synthesized input - // events may delay the normal events. Replace synthesized key events by - // toggleToolboxCommand to prevent the synthesized input events jam the - // content process and cause the test timeout. - gDevToolsBrowser.toggleToolboxCommand(window.gBrowser); + EventUtils.synthesizeKey("VK_F12", {}); } diff --git a/devtools/client/inspector/test/browser_inspector_highlighter-eyedropper-events.js b/devtools/client/inspector/test/browser_inspector_highlighter-eyedropper-events.js index 2dfed4c3552b..49543b5cebdd 100644 --- a/devtools/client/inspector/test/browser_inspector_highlighter-eyedropper-events.js +++ b/devtools/client/inspector/test/browser_inspector_highlighter-eyedropper-events.js @@ -113,7 +113,7 @@ function* respondsToMoveEvents(helper, testActor) { yield mouse.move(x, y); } else if (type === "keyboard") { let options = shift ? {shiftKey: true} : {}; - yield EventUtils.synthesizeAndWaitKey(key, options); + yield EventUtils.synthesizeKey(key, options); } yield checkPosition(expected, helper); } @@ -128,14 +128,14 @@ function* checkPosition({x, y}, {getElementAttribute}) { function* respondsToReturnAndEscape({isElementHidden, show}) { info("Simulating return to select the color and hide the eyedropper"); - yield EventUtils.synthesizeAndWaitKey("VK_RETURN", {}); + yield EventUtils.synthesizeKey("VK_RETURN", {}); let hidden = yield isElementHidden("root"); ok(hidden, "The eyedropper has been hidden"); info("Showing the eyedropper again and simulating escape to hide it"); yield show("html"); - yield EventUtils.synthesizeAndWaitKey("VK_ESCAPE", {}); + yield EventUtils.synthesizeKey("VK_ESCAPE", {}); hidden = yield isElementHidden("root"); ok(hidden, "The eyedropper has been hidden again"); } diff --git a/dom/base/TabGroup.h b/dom/base/TabGroup.h index 385c27ba0804..0a9d640ac746 100644 --- a/dom/base/TabGroup.h +++ b/dom/base/TabGroup.h @@ -7,7 +7,6 @@ #ifndef TabGroup_h #define TabGroup_h -#include "nsHashKeys.h" #include "nsISupportsImpl.h" #include "nsIPrincipal.h" #include "nsTHashtable.h" @@ -44,7 +43,6 @@ class TabChild; // window.opener. A DocGroup is a member of exactly one TabGroup. class DocGroup; -class TabChild; class TabGroup final : public SchedulerGroup { diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 5ec63503384b..133b6f15ae62 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -175,30 +175,6 @@ private: nsSize mSize; }; -namespace { - -class NativeInputRunnable final : public PrioritizableRunnable -{ - explicit NativeInputRunnable(already_AddRefed&& aEvent); - ~NativeInputRunnable() {} -public: - static already_AddRefed Create(already_AddRefed&& aEvent); -}; - -NativeInputRunnable::NativeInputRunnable(already_AddRefed&& aEvent) - : PrioritizableRunnable(Move(aEvent), nsIRunnablePriority::PRIORITY_INPUT) -{ -} - -/* static */ already_AddRefed -NativeInputRunnable::Create(already_AddRefed&& aEvent) -{ - nsCOMPtr event(new NativeInputRunnable(Move(aEvent))); - return event.forget(); -} - -} // unnamed namespace - LinkedList OldWindowSize::sList; NS_INTERFACE_MAP_BEGIN(nsDOMWindowUtils) @@ -1144,7 +1120,7 @@ nsDOMWindowUtils::SendNativeKeyEvent(int32_t aNativeKeyboardLayout, if (!widget) return NS_ERROR_FAILURE; - NS_DispatchToMainThread(NativeInputRunnable::Create( + NS_DispatchToMainThread( NewRunnableMethod( "nsIWidget::SynthesizeNativeMouseEvent", widget, @@ -1183,7 +1159,7 @@ nsDOMWindowUtils::SendNativeMouseEvent(int32_t aScreenX, LayoutDeviceIntPoint(aScreenX, aScreenY), aNativeMessage, aModifierFlags, - aObserver))); + aObserver)); return NS_OK; } @@ -1198,13 +1174,12 @@ nsDOMWindowUtils::SendNativeMouseMove(int32_t aScreenX, if (!widget) return NS_ERROR_FAILURE; - NS_DispatchToMainThread(NativeInputRunnable::Create( - NewRunnableMethod( - "nsIWidget::SynthesizeNativeMouseMove", - widget, - &nsIWidget::SynthesizeNativeMouseMove, - LayoutDeviceIntPoint(aScreenX, aScreenY), - aObserver))); + NS_DispatchToMainThread(NewRunnableMethod( + "nsIWidget::SynthesizeNativeMouseMove", + widget, + &nsIWidget::SynthesizeNativeMouseMove, + LayoutDeviceIntPoint(aScreenX, aScreenY), + aObserver)); return NS_OK; } @@ -1226,26 +1201,25 @@ nsDOMWindowUtils::SendNativeMouseScrollEvent(int32_t aScreenX, return NS_ERROR_FAILURE; } - NS_DispatchToMainThread(NativeInputRunnable::Create( - NewRunnableMethod( - "nsIWidget::SynthesizeNativeMouseScrollEvent", - widget, - &nsIWidget::SynthesizeNativeMouseScrollEvent, - LayoutDeviceIntPoint(aScreenX, aScreenY), - aNativeMessage, - aDeltaX, - aDeltaY, - aDeltaZ, - aModifierFlags, - aAdditionalFlags, - aObserver))); + NS_DispatchToMainThread(NewRunnableMethod( + "nsIWidget::SynthesizeNativeMouseScrollEvent", + widget, + &nsIWidget::SynthesizeNativeMouseScrollEvent, + LayoutDeviceIntPoint(aScreenX, aScreenY), + aNativeMessage, + aDeltaX, + aDeltaY, + aDeltaZ, + aModifierFlags, + aAdditionalFlags, + aObserver)); return NS_OK; } @@ -1267,7 +1241,7 @@ nsDOMWindowUtils::SendNativeTouchPoint(uint32_t aPointerId, return NS_ERROR_INVALID_ARG; } - NS_DispatchToMainThread(NativeInputRunnable::Create( + NS_DispatchToMainThread( NewRunnableMethod( "nsIWidget::SynthesizeNativeTouchTap", widget, &nsIWidget::SynthesizeNativeTouchTap, LayoutDeviceIntPoint(aScreenX, aScreenY), aLongTap, - aObserver))); + aObserver)); return NS_OK; } @@ -1325,11 +1299,11 @@ nsDOMWindowUtils::ClearNativeTouchSequence(nsIObserver* aObserver) return NS_ERROR_FAILURE; } - NS_DispatchToMainThread(NativeInputRunnable::Create( + NS_DispatchToMainThread( NewRunnableMethod("nsIWidget::ClearNativeTouchSequence", widget, &nsIWidget::ClearNativeTouchSequence, - aObserver))); + aObserver)); return NS_OK; } diff --git a/dom/base/nsFrameMessageManager.cpp b/dom/base/nsFrameMessageManager.cpp index 393e62affa29..a4ac1ad34069 100644 --- a/dom/base/nsFrameMessageManager.cpp +++ b/dom/base/nsFrameMessageManager.cpp @@ -849,13 +849,6 @@ nsFrameMessageManager::GetDocShell(nsIDocShell** aDocShell) return NS_OK; } -NS_IMETHODIMP -nsFrameMessageManager::GetTabEventTarget(nsIEventTarget** aTarget) -{ - *aTarget = nullptr; - return NS_OK; -} - NS_IMETHODIMP nsFrameMessageManager::Btoa(const nsAString& aBinaryData, nsAString& aAsciiBase64String) diff --git a/dom/base/nsIMessageManager.idl b/dom/base/nsIMessageManager.idl index 88eca0748c36..605f26d5738c 100644 --- a/dom/base/nsIMessageManager.idl +++ b/dom/base/nsIMessageManager.idl @@ -8,7 +8,6 @@ interface mozIDOMWindowProxy; interface nsIDocShell; interface nsIContent; -interface nsIEventTarget; interface nsIFrameLoader; interface nsIPrincipal; @@ -399,12 +398,6 @@ interface nsIContentFrameMessageManager : nsIMessageManagerGlobal * The top level docshell or null. */ readonly attribute nsIDocShell docShell; - - /** - * Returns the SchedulerEventTarget corresponding to the TabGroup - * for this frame. - */ - readonly attribute nsIEventTarget tabEventTarget; }; [uuid(b39a3324-b574-4f85-8cdb-274d04f807ef)] diff --git a/dom/base/nsInProcessTabChildGlobal.cpp b/dom/base/nsInProcessTabChildGlobal.cpp index 2835cd52b9a6..ad80392b05cc 100644 --- a/dom/base/nsInProcessTabChildGlobal.cpp +++ b/dom/base/nsInProcessTabChildGlobal.cpp @@ -199,14 +199,6 @@ nsInProcessTabChildGlobal::GetDocShell(nsIDocShell** aDocShell) return NS_OK; } -NS_IMETHODIMP -nsInProcessTabChildGlobal::GetTabEventTarget(nsIEventTarget** aTarget) -{ - nsCOMPtr target = GetMainThreadEventTarget(); - target.forget(aTarget); - return NS_OK; -} - void nsInProcessTabChildGlobal::FireUnloadEvent() { diff --git a/dom/base/nsInProcessTabChildGlobal.h b/dom/base/nsInProcessTabChildGlobal.h index 454d14eb4d4f..6e760a772c91 100644 --- a/dom/base/nsInProcessTabChildGlobal.h +++ b/dom/base/nsInProcessTabChildGlobal.h @@ -77,7 +77,6 @@ public: } NS_IMETHOD GetContent(mozIDOMWindowProxy** aContent) override; NS_IMETHOD GetDocShell(nsIDocShell** aDocShell) override; - NS_IMETHOD GetTabEventTarget(nsIEventTarget** aTarget) override; NS_DECL_NSIINPROCESSCONTENTFRAMEMESSAGEMANAGER diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp index a7dbb5d8898f..0dfff8e7d74a 100644 --- a/dom/events/EventStateManager.cpp +++ b/dom/events/EventStateManager.cpp @@ -2867,7 +2867,6 @@ NodeAllowsClickThrough(nsINode* aNode) void EventStateManager::PostHandleKeyboardEvent(WidgetKeyboardEvent* aKeyboardEvent, - nsIFrame* aTargetFrame, nsEventStatus& aStatus) { if (aStatus == nsEventStatus_eConsumeNoDefault) { @@ -2875,24 +2874,6 @@ EventStateManager::PostHandleKeyboardEvent(WidgetKeyboardEvent* aKeyboardEvent, } if (!aKeyboardEvent->HasBeenPostedToRemoteProcess()) { - if (aKeyboardEvent->IsWaitingReplyFromRemoteProcess()) { - RefPtr remote = aTargetFrame ? - TabParent::GetFrom(aTargetFrame->GetContent()) : nullptr; - if (remote && !remote->IsReadyToHandleInputEvents()) { - // We need to dispatch the event to the browser element again if we were - // waiting for the key reply but the event wasn't sent to the content - // process due to the remote browser wasn't ready. - WidgetKeyboardEvent keyEvent(*aKeyboardEvent); - aKeyboardEvent->MarkAsHandledInRemoteProcess(); - EventDispatcher::Dispatch(remote->GetOwnerElement(), mPresContext, - &keyEvent); - if (keyEvent.DefaultPrevented()) { - aKeyboardEvent->PreventDefault(!keyEvent.DefaultPreventedByContent()); - aStatus = nsEventStatus_eConsumeNoDefault; - return; - } - } - } // The widget expects a reply for every keyboard event. If the event wasn't // dispatched to a content process (non-e10s or no content process // running), we need to short-circuit here. Otherwise, we need to wait for @@ -3544,7 +3525,7 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext, case eKeyPress: { WidgetKeyboardEvent* keyEvent = aEvent->AsKeyboardEvent(); - PostHandleKeyboardEvent(keyEvent, mCurrentTarget, *aStatus); + PostHandleKeyboardEvent(keyEvent, *aStatus); } break; diff --git a/dom/events/EventStateManager.h b/dom/events/EventStateManager.h index 888e4aeda6d2..f4e148af9b95 100644 --- a/dom/events/EventStateManager.h +++ b/dom/events/EventStateManager.h @@ -109,7 +109,7 @@ public: nsEventStatus* aStatus); void PostHandleKeyboardEvent(WidgetKeyboardEvent* aKeyboardEvent, - nsIFrame* aTargetFrame, nsEventStatus& aStatus); + nsEventStatus& aStatus); /** * DispatchLegacyMouseScrollEvents() dispatches eLegacyMouseLineOrPageScroll diff --git a/dom/events/test/window_wheel_default_action.html b/dom/events/test/window_wheel_default_action.html index e19e59a54e00..94b0b0e3da43 100644 --- a/dom/events/test/window_wheel_default_action.html +++ b/dom/events/test/window_wheel_default_action.html @@ -1141,51 +1141,27 @@ function doTestZoom(aSettings, aCallback) var scrollTop = gScrollableElement.scrollTop; var scrollLeft = gScrollableElement.scrollLeft; - fullZoomChangePromise = new Promise(resolve => { - if (currentTest.expected & (kNegative | kPositive)) { - SpecialPowers.addChromeEventListener("FullZoomChange", function onFullZoomChange() { - if (SpecialPowers.getFullZoom(window) != 1) { - SpecialPowers.removeChromeEventListener("FullZoomChange", onFullZoomChange) - setTimeout(() => resolve(), 0); - } - }); - } else { - resolve(); - } - }); - sendWheelAndWait(10, 10, event, function () { is(gScrollableElement.scrollTop, scrollTop, description + "scrolled vertical"); is(gScrollableElement.scrollLeft, scrollLeft, description + "scrolled horizontal"); - - fullZoomChangePromise.then(() => { - // When input event prioritization is enabled, the wheel event may be - // dispatched to the content process before the message 'FullZoom' to - // zoom in/out. Waiting for the event 'FullZoomChange' and then check - // the result. - if (!(currentTest.expected & (kNegative | kPositive))) { - is(SpecialPowers.getFullZoom(window), 1.0, description + "zoomed"); + if (!(currentTest.expected & (kNegative | kPositive))) { + is(SpecialPowers.getFullZoom(window), 1.0, description + "zoomed"); + } else { + var isReverted = (currentTest.expected & kUseX) ? isXReverted : + (currentTest.expected & kUseY) ? isYReverted : false; + if ((!isReverted && (currentTest.expected & kNegative)) || + (isReverted && (currentTest.expected & kPositive))) { + ok(SpecialPowers.getFullZoom(window) > 1.0, + description + "not zoomed in, got " + SpecialPowers.getFullZoom(window)); } else { - var isReverted = (currentTest.expected & kUseX) ? isXReverted : - (currentTest.expected & kUseY) ? isYReverted : false; - if ((!isReverted && (currentTest.expected & kNegative)) || - (isReverted && (currentTest.expected & kPositive))) { - ok(SpecialPowers.getFullZoom(window) > 1.0, - description + "not zoomed in, got " + SpecialPowers.getFullZoom(window)); - } else { - ok(SpecialPowers.getFullZoom(window) < 1.0, - description + "not zoomed out, got " + SpecialPowers.getFullZoom(window)); - } + ok(SpecialPowers.getFullZoom(window) < 1.0, + description + "not zoomed out, got " + SpecialPowers.getFullZoom(window)); } - if (SpecialPowers.getFullZoom(window) != 1) { - // Only synthesizes key event to reset zoom when necessary to avoid - // triggering the next test before the key event is handled. In that - // case, the key event may break the next test. - synthesizeKey("0", { accelKey: true }); - } - onZoomReset(function () { - hitEventLoop(doNextTest, 20); - }); + } + + synthesizeKey("0", { accelKey: true }); + onZoomReset(function () { + hitEventLoop(doNextTest, 20); }); }); } diff --git a/dom/html/test/test_bug1261673.html b/dom/html/test/test_bug1261673.html index d0ffd95a72f3..123189bc3200 100644 --- a/dom/html/test/test_bug1261673.html +++ b/dom/html/test/test_bug1261673.html @@ -8,7 +8,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1261673 Test for Bug 1261673 - @@ -55,15 +54,21 @@ function runTests() { (p["focus"]) ? input.focus() : input.blur(); expectChange = p["valueChanged"] == 0 ? expectChange : expectChange + 1; result += parseInt(p["valueChanged"]); - sendWheelAndPaint(input, 1, 1, { deltaY: p["deltaY"], deltaMode: p["deltaMode"] }, () => { + synthesizeWheel(input, 1, 1, { deltaY: p["deltaY"], deltaMode: p["deltaMode"] }); + window.postMessage("finished", "http://mochi.test:8888"); + testIdx++; + } + + window.addEventListener("message", event => { + if (event.data == "finished") { ok(input.value == result, "Handle wheel in number input test-" + testIdx + " expect " + result + " get " + input.value); ok(numberChange == expectChange, "UA should fire change event when input's value changed, expect " + expectChange + " get " + numberChange); - (++testIdx >= params.length) ? SimpleTest.finish() : runNext(); - }); - } + (testIdx >= params.length) ? SimpleTest.finish() : runNext(); + } + }); runNext(); } diff --git a/dom/ipc/ContentBridgeParent.cpp b/dom/ipc/ContentBridgeParent.cpp index 72778807a149..4cbc78f51545 100644 --- a/dom/ipc/ContentBridgeParent.cpp +++ b/dom/ipc/ContentBridgeParent.cpp @@ -171,24 +171,6 @@ ContentBridgeParent::DeallocPBrowserParent(PBrowserParent* aParent) return nsIContentParent::DeallocPBrowserParent(aParent); } -mozilla::ipc::IPCResult -ContentBridgeParent::RecvPBrowserConstructor(PBrowserParent* actor, - const TabId& tabId, - const TabId& sameTabGroupAs, - const IPCTabContext& context, - const uint32_t& chromeFlags, - const ContentParentId& cpId, - const bool& isForBrowser) -{ - return nsIContentParent::RecvPBrowserConstructor(actor, - tabId, - sameTabGroupAs, - context, - chromeFlags, - cpId, - isForBrowser); -} - void ContentBridgeParent::NotifyTabDestroyed() { diff --git a/dom/ipc/ContentBridgeParent.h b/dom/ipc/ContentBridgeParent.h index cf5d96daac20..03a975bb0c04 100644 --- a/dom/ipc/ContentBridgeParent.h +++ b/dom/ipc/ContentBridgeParent.h @@ -138,15 +138,6 @@ protected: virtual bool DeallocPBrowserParent(PBrowserParent*) override; - virtual mozilla::ipc::IPCResult - RecvPBrowserConstructor(PBrowserParent* actor, - const TabId& tabId, - const TabId& sameTabGroupAs, - const IPCTabContext& context, - const uint32_t& chromeFlags, - const ContentParentId& cpId, - const bool& isForBrowser) override; - virtual PIPCBlobInputStreamParent* SendPIPCBlobInputStreamConstructor(PIPCBlobInputStreamParent* aActor, const nsID& aID, diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index 6b721c01847c..c2c85b8bd389 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -1176,9 +1176,6 @@ ContentChild::InitXPCOM(const XPCOMInitData& aXPCOMInit, GfxInfoBase::SetFeatureStatus(aXPCOMInit.gfxFeatureStatus()); DataStorage::SetCachedStorageEntries(aXPCOMInit.dataStorage()); - - // Enable input event prioritization. - nsThreadManager::get().EnableMainThreadEventPrioritization(); } mozilla::ipc::IPCResult diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index c9cacb617808..c91daea85aee 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -2877,24 +2877,6 @@ ContentParent::DeallocPBrowserParent(PBrowserParent* frame) return nsIContentParent::DeallocPBrowserParent(frame); } -mozilla::ipc::IPCResult -ContentParent::RecvPBrowserConstructor(PBrowserParent* actor, - const TabId& tabId, - const TabId& sameTabGroupAs, - const IPCTabContext& context, - const uint32_t& chromeFlags, - const ContentParentId& cpId, - const bool& isForBrowser) -{ - return nsIContentParent::RecvPBrowserConstructor(actor, - tabId, - sameTabGroupAs, - context, - chromeFlags, - cpId, - isForBrowser); -} - PIPCBlobInputStreamParent* ContentParent::AllocPIPCBlobInputStreamParent(const nsID& aID, const uint64_t& aSize) diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index b7c9c5ce33c9..e15b733be2b9 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -845,15 +845,6 @@ private: virtual bool DeallocPBrowserParent(PBrowserParent* frame) override; - virtual mozilla::ipc::IPCResult - RecvPBrowserConstructor(PBrowserParent* actor, - const TabId& tabId, - const TabId& sameTabGroupAs, - const IPCTabContext& context, - const uint32_t& chromeFlags, - const ContentParentId& cpId, - const bool& isForBrowser) override; - virtual PIPCBlobInputStreamParent* SendPIPCBlobInputStreamConstructor(PIPCBlobInputStreamParent* aActor, const nsID& aID, diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index 7f5ba5f08eeb..5525931e914f 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -542,12 +542,6 @@ parent: */ async RemotePaintIsReady(); - /** - * Child informs the parent that the content is ready to handle input - * events. This is sent when the TabChild is created. - */ - async RemoteIsReadyToHandleInputEvents(); - /** * Child informs the parent that the layer tree is already available. */ @@ -651,9 +645,7 @@ child: * When two consecutive mouse move events would be added to the message queue, * they are 'compressed' by dumping the oldest one. */ - prio(input) async RealMouseMoveEvent(WidgetMouseEvent event, - ScrollableLayerGuid aGuid, - uint64_t aInputBlockId) compress; + async RealMouseMoveEvent(WidgetMouseEvent event, ScrollableLayerGuid aGuid, uint64_t aInputBlockId) compress; /** * Mouse move events with |reason == eSynthesized| are sent via a separate * message because they do not generate DOM 'mousemove' events, and the @@ -661,29 +653,21 @@ child: * |reason == eReal| event being dropped in favour of an |eSynthesized| * event, and thus a DOM 'mousemove' event to be lost. */ - prio(input) async SynthMouseMoveEvent(WidgetMouseEvent event, - ScrollableLayerGuid aGuid, - uint64_t aInputBlockId); - prio(input) async RealMouseButtonEvent(WidgetMouseEvent event, - ScrollableLayerGuid aGuid, - uint64_t aInputBlockId); - prio(input) async RealKeyEvent(WidgetKeyboardEvent event); - prio(input) async MouseWheelEvent(WidgetWheelEvent event, - ScrollableLayerGuid aGuid, - uint64_t aInputBlockId); - prio(input) async RealTouchEvent(WidgetTouchEvent aEvent, - ScrollableLayerGuid aGuid, - uint64_t aInputBlockId, - nsEventStatus aApzResponse); - prio(input) async HandleTap(TapType aType, LayoutDevicePoint point, - Modifiers aModifiers, ScrollableLayerGuid aGuid, - uint64_t aInputBlockId); - prio(input) async RealTouchMoveEvent(WidgetTouchEvent aEvent, - ScrollableLayerGuid aGuid, - uint64_t aInputBlockId, - nsEventStatus aApzResponse); - prio(input) async RealDragEvent(WidgetDragEvent aEvent, - uint32_t aDragAction, uint32_t aDropEffect); + async SynthMouseMoveEvent(WidgetMouseEvent event, ScrollableLayerGuid aGuid, uint64_t aInputBlockId); + async RealMouseButtonEvent(WidgetMouseEvent event, ScrollableLayerGuid aGuid, uint64_t aInputBlockId); + async RealKeyEvent(WidgetKeyboardEvent event); + async MouseWheelEvent(WidgetWheelEvent event, ScrollableLayerGuid aGuid, uint64_t aInputBlockId); + async RealTouchEvent(WidgetTouchEvent aEvent, + ScrollableLayerGuid aGuid, + uint64_t aInputBlockId, + nsEventStatus aApzResponse); + async HandleTap(TapType aType, LayoutDevicePoint point, Modifiers aModifiers, + ScrollableLayerGuid aGuid, uint64_t aInputBlockId); + async RealTouchMoveEvent(WidgetTouchEvent aEvent, + ScrollableLayerGuid aGuid, + uint64_t aInputBlockId, + nsEventStatus aApzResponse); + async RealDragEvent(WidgetDragEvent aEvent, uint32_t aDragAction, uint32_t aDropEffect); async PluginEvent(WidgetPluginEvent aEvent); /** diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index 40360e1015c7..5e1226d0a381 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -90,7 +90,6 @@ #include "nsPIWindowRoot.h" #include "nsLayoutUtils.h" #include "nsPrintfCString.h" -#include "nsThreadManager.h" #include "nsThreadUtils.h" #include "nsViewManager.h" #include "nsWeakReference.h" @@ -322,19 +321,7 @@ private: { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(mTabChild); - // When enabling input event prioritization, we reserve limited time - // to process input events. We may handle the rest in the next frame - // when running out of time of the current frame. In that case, input - // events may be dispatched after ActorDestroy. Delay - // DelayedDeleteRunnable to avoid it to happen. - nsThread* thread = nsThreadManager::get().GetCurrentThread(); - MOZ_ASSERT(thread); - bool eventPrioritizationEnabled = false; - thread->IsEventPrioritizationEnabled(&eventPrioritizationEnabled); - if (eventPrioritizationEnabled && thread->HasPendingInputEvents()) { - MOZ_ALWAYS_SUCCEEDS(NS_DispatchToCurrentThread(this)); - return NS_OK; - } + // Check in case ActorDestroy was called after RecvDestroy message. if (mTabChild->IPCOpen()) { Unused << PBrowserChild::Send__delete__(mTabChild); @@ -3520,14 +3507,6 @@ TabChildGlobal::GetDocShell(nsIDocShell** aDocShell) return NS_OK; } -NS_IMETHODIMP -TabChildGlobal::GetTabEventTarget(nsIEventTarget** aTarget) -{ - nsCOMPtr target = EventTargetFor(TaskCategory::Other); - target.forget(aTarget); - return NS_OK; -} - nsIPrincipal* TabChildGlobal::GetPrincipal() { diff --git a/dom/ipc/TabChild.h b/dom/ipc/TabChild.h index af01a50542ac..5b1015e21f00 100644 --- a/dom/ipc/TabChild.h +++ b/dom/ipc/TabChild.h @@ -114,7 +114,6 @@ public: } NS_IMETHOD GetContent(mozIDOMWindowProxy** aContent) override; NS_IMETHOD GetDocShell(nsIDocShell** aDocShell) override; - NS_IMETHOD GetTabEventTarget(nsIEventTarget** aTarget) override; nsresult AddEventListener(const nsAString& aType, nsIDOMEventListener* aListener, diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index fbb18893231e..d6c0f6ea303a 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -172,8 +172,6 @@ TabParent::TabParent(nsIContentParent* aManager, , mPreserveLayers(false) , mHasPresented(false) , mHasBeforeUnload(false) - , mIsReadyToHandleInputEvents(false) - , mIsMouseEnterIntoWidgetEventSuppressed(false) { MOZ_ASSERT(aManager); } @@ -1083,7 +1081,7 @@ TabParent::SendKeyEvent(const nsAString& aType, int32_t aModifiers, bool aPreventDefault) { - if (mIsDestroyed || !mIsReadyToHandleInputEvents) { + if (mIsDestroyed) { return; } Unused << PBrowserParent::SendKeyEvent(nsString(aType), aKeyCode, aCharCode, @@ -1114,33 +1112,11 @@ TabParent::SendRealMouseEvent(WidgetMouseEvent& aEvent) mTabSetsCursor = false; } } - if (!mIsReadyToHandleInputEvents) { - if (eMouseEnterIntoWidget == aEvent.mMessage) { - MOZ_ASSERT(!mIsMouseEnterIntoWidgetEventSuppressed); - mIsMouseEnterIntoWidgetEventSuppressed = true; - } else if (eMouseExitFromWidget == aEvent.mMessage) { - MOZ_ASSERT(mIsMouseEnterIntoWidgetEventSuppressed); - mIsMouseEnterIntoWidgetEventSuppressed = false; - } - return; - } ScrollableLayerGuid guid; uint64_t blockId; ApzAwareEventRoutingToChild(&guid, &blockId, nullptr); - if (mIsMouseEnterIntoWidgetEventSuppressed) { - // In the case that the TabParent suppressed the eMouseEnterWidget event due - // to its corresponding TabChild wasn't ready to handle it, we have to - // resend it when the TabChild is ready. - mIsMouseEnterIntoWidgetEventSuppressed = false; - WidgetMouseEvent localEvent(aEvent); - localEvent.mMessage = eMouseEnterIntoWidget; - DebugOnly ret = SendRealMouseButtonEvent(localEvent, guid, blockId); - NS_WARNING_ASSERTION(ret, "SendRealMouseButtonEvent(eMouseEnterIntoWidget) failed"); - MOZ_ASSERT(!ret || localEvent.HasBeenPostedToRemoteProcess()); - } - if (eMouseMove == aEvent.mMessage) { if (aEvent.mReason == WidgetMouseEvent::eSynthesized) { DebugOnly ret = SendSynthMouseMoveEvent(aEvent, guid, blockId); @@ -1175,7 +1151,7 @@ void TabParent::SendRealDragEvent(WidgetDragEvent& aEvent, uint32_t aDragAction, uint32_t aDropEffect) { - if (mIsDestroyed || !mIsReadyToHandleInputEvents) { + if (mIsDestroyed) { return; } aEvent.mRefPoint += GetChildProcessOffset(); @@ -1194,7 +1170,7 @@ TabParent::AdjustTapToChildWidget(const LayoutDevicePoint& aPoint) void TabParent::SendMouseWheelEvent(WidgetWheelEvent& aEvent) { - if (mIsDestroyed || !mIsReadyToHandleInputEvents) { + if (mIsDestroyed) { return; } @@ -1473,7 +1449,7 @@ TabParent::RecvClearNativeTouchSequence(const uint64_t& aObserverId) void TabParent::SendRealKeyEvent(WidgetKeyboardEvent& aEvent) { - if (mIsDestroyed || !mIsReadyToHandleInputEvents) { + if (mIsDestroyed) { return; } aEvent.mRefPoint += GetChildProcessOffset(); @@ -1494,7 +1470,7 @@ TabParent::SendRealKeyEvent(WidgetKeyboardEvent& aEvent) void TabParent::SendRealTouchEvent(WidgetTouchEvent& aEvent) { - if (mIsDestroyed || !mIsReadyToHandleInputEvents) { + if (mIsDestroyed) { return; } @@ -1555,7 +1531,7 @@ TabParent::SendHandleTap(TapType aType, const ScrollableLayerGuid& aGuid, uint64_t aInputBlockId) { - if (mIsDestroyed || !mIsReadyToHandleInputEvents) { + if (mIsDestroyed) { return false; } if ((aType == TapType::eSingleTap || aType == TapType::eSecondTap) && @@ -2960,18 +2936,6 @@ TabParent::RecvRemotePaintIsReady() return IPC_OK(); } -mozilla::ipc::IPCResult -TabParent::RecvRemoteIsReadyToHandleInputEvents() -{ - // When enabling input event prioritization, input events may preempt other - // normal priority IPC messages. To prevent the input events preempt - // PBrowserConstructor, we use an IPC 'RemoteIsReadyToHandleInputEvents' to - // notify the parent that TabChild is created and ready to handle input - // events. - SetReadyToHandleInputEvents(); - return IPC_OK(); -} - mozilla::plugins::PPluginWidgetParent* TabParent::AllocPPluginWidgetParent() { diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index d5958cd95eda..1f75d188d92e 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -603,9 +603,6 @@ public: void LiveResizeStarted() override; void LiveResizeStopped() override; - void SetReadyToHandleInputEvents() { mIsReadyToHandleInputEvents = true; } - bool IsReadyToHandleInputEvents() { return mIsReadyToHandleInputEvents; } - protected: bool ReceiveMessage(const nsString& aMessage, bool aSync, @@ -631,8 +628,6 @@ protected: virtual mozilla::ipc::IPCResult RecvRemotePaintIsReady() override; - virtual mozilla::ipc::IPCResult RecvRemoteIsReadyToHandleInputEvents() override; - virtual mozilla::ipc::IPCResult RecvForcePaintNoOp(const uint64_t& aLayerObserverEpoch) override; virtual mozilla::ipc::IPCResult RecvSetDimensions(const uint32_t& aFlags, @@ -783,14 +778,6 @@ private: // beforeunload event listener. bool mHasBeforeUnload; - // True when the remote browser is created and ready to handle input events. - bool mIsReadyToHandleInputEvents; - - // True if we suppress the eMouseEnterIntoWidget event due to the TabChild was - // not ready to handle it. We will resend it when the next time we fire a - // mouse event and the TabChild is ready. - bool mIsMouseEnterIntoWidgetEventSuppressed; - public: static TabParent* GetTabParentFromLayersId(uint64_t aLayersId); }; diff --git a/dom/ipc/nsIContentChild.cpp b/dom/ipc/nsIContentChild.cpp index b73f4e9569c0..dafe8bc5bea0 100644 --- a/dom/ipc/nsIContentChild.cpp +++ b/dom/ipc/nsIContentChild.cpp @@ -102,8 +102,7 @@ nsIContentChild::RecvPBrowserConstructor(PBrowserChild* aActor, if (os) { os->NotifyObservers(static_cast(tabChild), "tab-child-created", nullptr); } - // Notify parent that we are ready to handle input events. - tabChild->SendRemoteIsReadyToHandleInputEvents(); + return IPC_OK(); } diff --git a/dom/ipc/nsIContentParent.cpp b/dom/ipc/nsIContentParent.cpp index ba59f02ce2a2..2b531abef548 100644 --- a/dom/ipc/nsIContentParent.cpp +++ b/dom/ipc/nsIContentParent.cpp @@ -206,25 +206,6 @@ nsIContentParent::DeallocPBrowserParent(PBrowserParent* aFrame) return true; } -mozilla::ipc::IPCResult -nsIContentParent::RecvPBrowserConstructor(PBrowserParent* actor, - const TabId& tabId, - const TabId& sameTabGroupAs, - const IPCTabContext& context, - const uint32_t& chromeFlags, - const ContentParentId& cpId, - const bool& isForBrowser) -{ - TabParent* parent = TabParent::GetFrom(actor); - // When enabling input event prioritization, input events may preempt other - // normal priority IPC messages. To prevent the input events preempt - // PBrowserConstructor, we use an IPC 'RemoteIsReadyToHandleInputEvents' to - // notify parent that TabChild is created. In this case, PBrowser is initiated - // from content so that we can set TabParent as ready to handle input events. - parent->SetReadyToHandleInputEvents(); - return IPC_OK(); -} - PIPCBlobInputStreamParent* nsIContentParent::AllocPIPCBlobInputStreamParent(const nsID& aID, const uint64_t& aSize) diff --git a/dom/ipc/nsIContentParent.h b/dom/ipc/nsIContentParent.h index f27f59da7f30..be690861f72f 100644 --- a/dom/ipc/nsIContentParent.h +++ b/dom/ipc/nsIContentParent.h @@ -117,15 +117,6 @@ protected: // IPDL methods const bool& aIsForBrowser); virtual bool DeallocPBrowserParent(PBrowserParent* frame); - virtual mozilla::ipc::IPCResult - RecvPBrowserConstructor(PBrowserParent* actor, - const TabId& tabId, - const TabId& sameTabGroupAs, - const IPCTabContext& context, - const uint32_t& chromeFlags, - const ContentParentId& cpId, - const bool& isForBrowser); - virtual mozilla::ipc::PIPCBlobInputStreamParent* AllocPIPCBlobInputStreamParent(const nsID& aID, const uint64_t& aSize); diff --git a/dom/tests/browser/browser_bug1316330.js b/dom/tests/browser/browser_bug1316330.js index 27b9cc4e46e8..de7be419d025 100644 --- a/dom/tests/browser/browser_bug1316330.js +++ b/dom/tests/browser/browser_bug1316330.js @@ -18,14 +18,14 @@ add_task(async function() { let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, URL); let browser = tab.linkedBrowser; - await EventUtils.synthesizeAndWaitKey("d", { code: "KeyD", repeat: 3 }); + EventUtils.synthesizeKey("d", { code: "KeyD", repeat: 3 }); await ContentTask.spawn(browser, null, async function() { is(content.document.body.getAttribute("data-down"), "2", "Correct number of events"); is(content.document.body.getAttribute("data-press"), "2", "Correct number of events"); }); - await EventUtils.synthesizeAndWaitKey("p", { code: "KeyP", repeat: 3 }); + EventUtils.synthesizeKey("p", { code: "KeyP", repeat: 3 }); await ContentTask.spawn(browser, null, async function() { is(content.document.body.getAttribute("data-down"), "4", "Correct number of events"); diff --git a/editor/libeditor/tests/browser_bug629172.js b/editor/libeditor/tests/browser_bug629172.js index 5f1bc5f43a83..f06f7f77c9d3 100644 --- a/editor/libeditor/tests/browser_bug629172.js +++ b/editor/libeditor/tests/browser_bug629172.js @@ -43,10 +43,11 @@ add_task(async function() { // but in non-e10s it is handled by the browser UI code and hence won't // reach the web page. As a result, we need to observe the event in // the content process only in e10s mode. - if (gMultiProcessBrowser) { - return EventUtils.synthesizeAndWaitKey("x", {accelKey: true, shiftKey: true}); - } + var waitForKeypressContent = BrowserTestUtils.waitForContentEvent(aBrowser, "keypress"); EventUtils.synthesizeKey("x", {accelKey: true, shiftKey: true}); + if (gMultiProcessBrowser) { + return waitForKeypressContent; + } return Promise.resolve(); } diff --git a/gfx/layers/apz/test/mochitest/helper_touch_action_regions.html b/gfx/layers/apz/test/mochitest/helper_touch_action_regions.html index 647e3fc0088a..0d1e90d7f5fa 100644 --- a/gfx/layers/apz/test/mochitest/helper_touch_action_regions.html +++ b/gfx/layers/apz/test/mochitest/helper_touch_action_regions.html @@ -93,11 +93,6 @@ function waitFor(eventType, count) { return true; } -function RunAfterProcessedQueuedInputEvents(aCallback) { - let tm = SpecialPowers.Services.tm; - tm.dispatchToMainThread(aCallback, SpecialPowers.Ci.nsIRunnablePriority.PRIORITY_INPUT); -} - function* test(testDriver) { // The main part of this test should run completely before the child process' // main-thread deals with the touch event, so check to make sure that happens. @@ -144,8 +139,8 @@ function* test(testDriver) { // scrolling even though we know we haven't yet processed the DOM touch events // in the child process yet. // - // Note that the "async callback" we use here is SpecialPowers.tm.dispatchToMainThread - // with priority = input, because nothing else does exactly what we want: + // Note that the "async callback" we use here is SpecialPowers.executeSoon, + // because nothing else does exactly what we want: // - setTimeout(..., 0) does not maintain ordering, because it respects the // time delta provided (i.e. the callback can jump the queue to meet its // deadline). @@ -154,9 +149,6 @@ function* test(testDriver) { // round-trip time. // - SimpleTest.executeSoon has a codepath that delegates to setTimeout, so // is less reliable if it ever decides to switch to that codepath. - // - SpecialPowers.executeSoon dispatches a task to main thread. However, - // normal runnables may be preempted by input events and be executed in an - // unexpected order. // The other problem we need to deal with is the asynchronicity in the chrome // process. That is, we might request a snapshot before the chrome process has @@ -177,13 +169,13 @@ function* test(testDriver) { // Set up the child process events and callbacks var scroller = document.getElementById('scroller'); synthesizeNativeTouch(scroller, 10, 110, SpecialPowers.DOMWindowUtils.TOUCH_CONTACT, null, 0); - RunAfterProcessedQueuedInputEvents(testDriver); + SpecialPowers.executeSoon(testDriver); for (var i = 1; i < 10; i++) { synthesizeNativeTouch(scroller, 10, 110 - (i * 10), SpecialPowers.DOMWindowUtils.TOUCH_CONTACT, null, 0); - RunAfterProcessedQueuedInputEvents(testDriver); + SpecialPowers.executeSoon(testDriver); } synthesizeNativeTouch(scroller, 10, 10, SpecialPowers.DOMWindowUtils.TOUCH_REMOVE, null, 0); - RunAfterProcessedQueuedInputEvents(testDriver); + SpecialPowers.executeSoon(testDriver); ok(true, "Finished setting up event queue"); // Get our baseline snapshot diff --git a/ipc/chromium/src/chrome/common/ipc_message.cc b/ipc/chromium/src/chrome/common/ipc_message.cc index 413a946edc4f..eeaa57de1d12 100644 --- a/ipc/chromium/src/chrome/common/ipc_message.cc +++ b/ipc/chromium/src/chrome/common/ipc_message.cc @@ -67,7 +67,8 @@ Message::Message(int32_t routing_id, header()->routing = routing_id; header()->type = type; header()->flags = nestedLevel; - set_priority(priority); + if (priority == HIGH_PRIORITY) + header()->flags |= PRIO_BIT; if (compression == COMPRESSION_ENABLED) header()->flags |= COMPRESS_BIT; else if (compression == COMPRESSION_ALL) diff --git a/ipc/chromium/src/chrome/common/ipc_message.h b/ipc/chromium/src/chrome/common/ipc_message.h index 1752210f9e44..efb430237036 100644 --- a/ipc/chromium/src/chrome/common/ipc_message.h +++ b/ipc/chromium/src/chrome/common/ipc_message.h @@ -46,9 +46,8 @@ class Message : public Pickle { }; enum PriorityValue { - NORMAL_PRIORITY = 0, - INPUT_PRIORITY = 1, - HIGH_PRIORITY = 2, + NORMAL_PRIORITY, + HIGH_PRIORITY, }; enum MessageCompression { @@ -92,12 +91,17 @@ class Message : public Pickle { } PriorityValue priority() const { - return static_cast((header()->flags & PRIO_MASK) >> 2); + if (header()->flags & PRIO_BIT) { + return HIGH_PRIORITY; + } + return NORMAL_PRIORITY; } void set_priority(PriorityValue prio) { - DCHECK(((prio << 2) & ~PRIO_MASK) == 0); - header()->flags = (header()->flags & ~PRIO_MASK) | (prio << 2); + header()->flags &= ~PRIO_BIT; + if (prio == HIGH_PRIORITY) { + header()->flags |= PRIO_BIT; + } } bool is_constructor() const { @@ -311,16 +315,16 @@ class Message : public Pickle { // flags enum { NESTED_MASK = 0x0003, - PRIO_MASK = 0x000C, - SYNC_BIT = 0x0010, - REPLY_BIT = 0x0020, - REPLY_ERROR_BIT = 0x0040, - INTERRUPT_BIT = 0x0080, - COMPRESS_BIT = 0x0100, - COMPRESSALL_BIT = 0x0200, - CONSTRUCTOR_BIT = 0x0400, + PRIO_BIT = 0x0004, + SYNC_BIT = 0x0008, + REPLY_BIT = 0x0010, + REPLY_ERROR_BIT = 0x0020, + INTERRUPT_BIT = 0x0040, + COMPRESS_BIT = 0x0080, + COMPRESSALL_BIT = 0x0100, + CONSTRUCTOR_BIT = 0x0200, #ifdef MOZ_TASK_TRACER - TASKTRACER_BIT = 0x0800, + TASKTRACER_BIT = 0x0400, #endif }; diff --git a/ipc/glue/MessageChannel.cpp b/ipc/glue/MessageChannel.cpp index 6007c64c5c82..104639920e9c 100644 --- a/ipc/glue/MessageChannel.cpp +++ b/ipc/glue/MessageChannel.cpp @@ -1976,20 +1976,8 @@ MessageChannel::MessageTask::Clear() NS_IMETHODIMP MessageChannel::MessageTask::GetPriority(uint32_t* aPriority) { - switch (mMessage.priority()) { - case Message::NORMAL_PRIORITY: - *aPriority = PRIORITY_NORMAL; - break; - case Message::INPUT_PRIORITY: - *aPriority = PRIORITY_INPUT; - break; - case Message::HIGH_PRIORITY: - *aPriority = PRIORITY_HIGH; - break; - default: - MOZ_ASSERT(false); - break; - } + *aPriority = mMessage.priority() == Message::HIGH_PRIORITY ? + PRIORITY_HIGH : PRIORITY_NORMAL; return NS_OK; } diff --git a/ipc/ipdl/ipdl/ast.py b/ipc/ipdl/ipdl/ast.py index f21df2aa331b..451df44c1b08 100644 --- a/ipc/ipdl/ipdl/ast.py +++ b/ipc/ipdl/ipdl/ast.py @@ -9,8 +9,7 @@ INSIDE_SYNC_NESTED = 2 INSIDE_CPOW_NESTED = 3 NORMAL_PRIORITY = 1 -INPUT_PRIORITY = 2 -HIGH_PRIORITY = 3 +HIGH_PRIORITY = 2 class Visitor: def defaultVisit(self, node): diff --git a/ipc/ipdl/ipdl/lower.py b/ipc/ipdl/ipdl/lower.py index dba82b29fbd1..28a77651e309 100644 --- a/ipc/ipdl/ipdl/lower.py +++ b/ipc/ipdl/ipdl/lower.py @@ -1727,9 +1727,8 @@ def _generateMessageConstructor(clsname, msgid, segmentSize, nested, prio, prett if prio == ipdl.ast.NORMAL_PRIORITY: prioEnum = 'IPC::Message::NORMAL_PRIORITY' - elif prio == ipdl.ast.INPUT_PRIORITY: - prioEnum = 'IPC::Message::INPUT_PRIORITY' else: + assert prio == ipdl.ast.HIGH_PRIORITY prioEnum = 'IPC::Message::HIGH_PRIORITY' func.addstmt( diff --git a/ipc/ipdl/ipdl/parser.py b/ipc/ipdl/ipdl/parser.py index da03a94a5b75..7ba8f810dbd5 100644 --- a/ipc/ipdl/ipdl/parser.py +++ b/ipc/ipdl/ipdl/parser.py @@ -503,8 +503,7 @@ def p_Nested(p): def p_Priority(p): """Priority : ID""" kinds = {'normal': 1, - 'input': 2, - 'high': 3} + 'high': 2} if p[1] not in kinds: _error(locFromTok(p, 1), "Expected normal or high for prio()") diff --git a/ipc/ipdl/test/cxx/PTestPriority.ipdl b/ipc/ipdl/test/cxx/PTestPriority.ipdl index c9bc3d3aa75e..edb98365b7ca 100644 --- a/ipc/ipdl/test/cxx/PTestPriority.ipdl +++ b/ipc/ipdl/test/cxx/PTestPriority.ipdl @@ -3,14 +3,11 @@ namespace _ipdltest { sync protocol PTestPriority { parent: - prio(input) async PMsg1(); - prio(input) sync PMsg2(); - prio(high) async PMsg3(); - prio(high) sync PMsg4(); + prio(high) async Msg1(); + prio(high) sync Msg2(); child: - prio(input) async CMsg1(); - prio(high) async CMsg2(); + prio(high) async Msg3(); }; } // namespace _ipdltest diff --git a/layout/base/nsRefreshDriver.cpp b/layout/base/nsRefreshDriver.cpp index ebe7a933a791..3b226ecd055a 100644 --- a/layout/base/nsRefreshDriver.cpp +++ b/layout/base/nsRefreshDriver.cpp @@ -255,13 +255,6 @@ public: return idleEnd < aDefault ? idleEnd : aDefault; } - Maybe GetNextTickHint() - { - MOZ_ASSERT(NS_IsMainThread()); - TimeStamp nextTick = MostRecentRefresh() + GetTimerRate(); - return nextTick < TimeStamp::Now() ? Nothing() : Some(nextTick); - } - protected: virtual void StartTimer() = 0; virtual void StopTimer() = 0; @@ -2409,17 +2402,6 @@ nsRefreshDriver::GetIdleDeadlineHint(TimeStamp aDefault) return sRegularRateTimer->GetIdleDeadlineHint(aDefault); } -/* static */ Maybe -nsRefreshDriver::GetNextTickHint() -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (!sRegularRateTimer) { - return Nothing(); - } - return sRegularRateTimer->GetNextTickHint(); -} - void nsRefreshDriver::Disconnect() { diff --git a/layout/base/nsRefreshDriver.h b/layout/base/nsRefreshDriver.h index 095dd94fcb80..159a1b7804cc 100644 --- a/layout/base/nsRefreshDriver.h +++ b/layout/base/nsRefreshDriver.h @@ -345,12 +345,6 @@ public: */ static mozilla::TimeStamp GetIdleDeadlineHint(mozilla::TimeStamp aDefault); - /** - * It returns the expected timestamp of the next tick or nothing if the next - * tick is missed. - */ - static mozilla::Maybe GetNextTickHint(); - static void DispatchIdleRunnableAfterTick(nsIRunnable* aRunnable, uint32_t aDelay); static void CancelIdleRunnable(nsIRunnable* aRunnable); diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 6a00697aa80b..d5138fecc21f 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -3123,26 +3123,6 @@ pref("dom.idle_period.throttled_length", 10000); // The amount of idle time (milliseconds) reserved for a long idle period pref("idle_queue.long_period", 50); -// Control the event prioritization on content main thread -#ifdef NIGHTLY_BUILD -pref("prioritized_input_events.enabled", true); -#else -pref("prioritized_input_events.enabled", false); -#endif - -// The maximum and minimum time (milliseconds) we reserve for handling input -// events in each frame. -pref("prioritized_input_events.duration.max", 8); -pref("prioritized_input_events.duration.min", 1); - -// The default amount of time (milliseconds) required for handling a input -// event. -pref("prioritized_input_events.default_duration_per_event", 1); - -// The number of processed input events we use to predict the amount of time -// required to process the following input events. -pref("prioritized_input_events.count_for_prediction", 9); - // The minimum amount of time (milliseconds) required for an idle // period to be scheduled on the main thread. N.B. that // layout.idle_period.time_limit adds padding at the end of the idle diff --git a/testing/mochitest/tests/SimpleTest/EventUtils.js b/testing/mochitest/tests/SimpleTest/EventUtils.js index 100f663cb966..cad43966d91d 100644 --- a/testing/mochitest/tests/SimpleTest/EventUtils.js +++ b/testing/mochitest/tests/SimpleTest/EventUtils.js @@ -678,44 +678,6 @@ function synthesizeNativeMouseMove(aTarget, aOffsetX, aOffsetY, aCallback, aWind utils.sendNativeMouseMove(x * scale, y * scale, null, observer); } -/** - * This is a wrapper around synthesizeNativeMouseMove that waits for the mouse - * event to be dispatched to the target content. - * - * This API is supposed to be used in those test cases that synthesize some - * input events to chrome process and have some checks in content. - */ -function synthesizeAndWaitNativeMouseMove(aTarget, aOffsetX, aOffsetY, - aCallback, aWindow = window) { - let browser = gBrowser.selectedTab.linkedBrowser; - let mm = browser.messageManager; - let ContentTask = - _EU_Cu.import("resource://testing-common/ContentTask.jsm", null).ContentTask; - - let eventRegisteredPromise = new Promise(resolve => { - mm.addMessageListener("Test:MouseMoveRegistered", function processed(message) { - mm.removeMessageListener("Test:MouseMoveRegistered", processed); - resolve(); - }); - }); - let eventReceivedPromise = ContentTask.spawn(browser, [aOffsetX, aOffsetY], - ([clientX, clientY]) => { - return new Promise(resolve => { - addEventListener("mousemove", function onMouseMoveEvent(e) { - if (e.clientX == clientX && e.clientY == clientY) { - removeEventListener("mousemove", onMouseMoveEvent); - resolve(); - } - }); - sendAsyncMessage("Test:MouseMoveRegistered"); - }); - }); - eventRegisteredPromise.then(() => { - synthesizeNativeMouseMove(aTarget, aOffsetX, aOffsetY, null, aWindow); - }); - return eventReceivedPromise; -} - function _computeKeyCodeFromChar(aChar) { if (aChar.length != 1) { @@ -867,51 +829,6 @@ function synthesizeKey(aKey, aEvent, aWindow = window, aCallback) } } -/** - * This is a wrapper around synthesizeKey that waits for the key event to be - * dispatched to the target content. It returns a promise which is resolved - * when the content receives the key event. - * - * This API is supposed to be used in those test cases that synthesize some - * input events to chrome process and have some checks in content. - */ -function synthesizeAndWaitKey(aKey, aEvent, aWindow = window, - checkBeforeSynthesize, checkAfterSynthesize) -{ - let browser = gBrowser.selectedTab.linkedBrowser; - let mm = browser.messageManager; - let keyCode = _createKeyboardEventDictionary(aKey, aEvent, aWindow).dictionary.keyCode; - let ContentTask = _EU_Cu.import("resource://testing-common/ContentTask.jsm", null).ContentTask; - - let keyRegisteredPromise = new Promise(resolve => { - mm.addMessageListener("Test:KeyRegistered", function processed(message) { - mm.removeMessageListener("Test:KeyRegistered", processed); - resolve(); - }); - }); - let keyReceivedPromise = ContentTask.spawn(browser, keyCode, (keyCode) => { - return new Promise(resolve => { - addEventListener("keyup", function onKeyEvent(e) { - if (e.keyCode == keyCode) { - removeEventListener("keyup", onKeyEvent); - resolve(); - } - }); - sendAsyncMessage("Test:KeyRegistered"); - }); - }); - keyRegisteredPromise.then(() => { - if (checkBeforeSynthesize) { - checkBeforeSynthesize(); - } - synthesizeKey(aKey, aEvent, aWindow); - if (checkAfterSynthesize) { - checkAfterSynthesize(); - } - }); - return keyReceivedPromise; -} - function _parseNativeModifiers(aModifiers, aWindow = window) { var navigator = _getNavigator(aWindow); diff --git a/toolkit/components/statusfilter/nsBrowserStatusFilter.cpp b/toolkit/components/statusfilter/nsBrowserStatusFilter.cpp index fc03f2b5837a..8491c962fa31 100644 --- a/toolkit/components/statusfilter/nsBrowserStatusFilter.cpp +++ b/toolkit/components/statusfilter/nsBrowserStatusFilter.cpp @@ -9,7 +9,6 @@ #include "nsITimer.h" #include "nsIServiceManager.h" #include "nsString.h" -#include "nsThreadUtils.h" using namespace mozilla; @@ -18,8 +17,7 @@ using namespace mozilla; //----------------------------------------------------------------------------- nsBrowserStatusFilter::nsBrowserStatusFilter() - : mTarget(GetMainThreadEventTarget()) - , mCurProgress(0) + : mCurProgress(0) , mMaxProgress(0) , mStatusIsDirty(true) , mCurrentPercentage(0) @@ -114,21 +112,6 @@ nsBrowserStatusFilter::GetLoadType(uint32_t *aLoadType) return NS_ERROR_NOT_IMPLEMENTED; } -NS_IMETHODIMP -nsBrowserStatusFilter::GetTarget(nsIEventTarget** aTarget) -{ - nsCOMPtr target = mTarget; - target.forget(aTarget); - return NS_OK; -} - -NS_IMETHODIMP -nsBrowserStatusFilter::SetTarget(nsIEventTarget* aTarget) -{ - mTarget = aTarget; - return NS_OK; -} - //----------------------------------------------------------------------------- // nsBrowserStatusFilter::nsIWebProgressListener //----------------------------------------------------------------------------- @@ -379,7 +362,9 @@ nsBrowserStatusFilter::StartDelayTimer() if (!mTimer) return NS_ERROR_FAILURE; - mTimer->SetTarget(mTarget); + // Use the system group. The browser status filter is always used by chrome + // code. + mTimer->SetTarget(SystemGroup::EventTargetFor(TaskCategory::Other)); return mTimer->InitWithNamedFuncCallback( TimeoutHandler, this, 160, nsITimer::TYPE_ONE_SHOT, "nsBrowserStatusFilter::TimeoutHandler"); diff --git a/toolkit/components/statusfilter/nsBrowserStatusFilter.h b/toolkit/components/statusfilter/nsBrowserStatusFilter.h index 63ad1be46820..d48ed99afe77 100644 --- a/toolkit/components/statusfilter/nsBrowserStatusFilter.h +++ b/toolkit/components/statusfilter/nsBrowserStatusFilter.h @@ -46,7 +46,6 @@ private: private: nsCOMPtr mListener; - nsCOMPtr mTarget; nsCOMPtr mTimer; // delayed values diff --git a/toolkit/components/tooltiptext/tests/browser_input_file_tooltips.js b/toolkit/components/tooltiptext/tests/browser_input_file_tooltips.js index 0651abb6b279..0fe45da7e96a 100644 --- a/toolkit/components/tooltiptext/tests/browser_input_file_tooltips.js +++ b/toolkit/components/tooltiptext/tests/browser_input_file_tooltips.js @@ -34,7 +34,9 @@ async function do_test(test) { let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser); info("Moving mouse out of the way."); - await EventUtils.synthesizeAndWaitNativeMouseMove(tab.linkedBrowser, 300, 300); + await new Promise(resolve => { + EventUtils.synthesizeNativeMouseMove(tab.linkedBrowser, 300, 300, resolve); + }); info("creating input field"); await ContentTask.spawn(tab.linkedBrowser, test, async function(test) { @@ -90,11 +92,15 @@ async function do_test(test) { }, {once: true}); }); info("Initial mouse move"); - await EventUtils.synthesizeAndWaitNativeMouseMove(tab.linkedBrowser, 50, 5); + await new Promise(resolve => { + EventUtils.synthesizeNativeMouseMove(tab.linkedBrowser, 50, 5, resolve); + }); info("Waiting"); await new Promise(resolve => setTimeout(resolve, 400)); info("Second mouse move"); - await EventUtils.synthesizeAndWaitNativeMouseMove(tab.linkedBrowser, 70, 5); + await new Promise(resolve => { + EventUtils.synthesizeNativeMouseMove(tab.linkedBrowser, 70, 5, resolve); + }); info("Waiting for tooltip to open"); let tooltip = await awaitTooltipOpen; diff --git a/toolkit/content/browser-child.js b/toolkit/content/browser-child.js index 50880cfd0ea6..2aa1dd7e9d44 100644 --- a/toolkit/content/browser-child.js +++ b/toolkit/content/browser-child.js @@ -33,7 +33,6 @@ var WebProgressListener = { this._filter = Cc["@mozilla.org/appshell/component/browser-status-filter;1"] .createInstance(Ci.nsIWebProgress); this._filter.addProgressListener(this, Ci.nsIWebProgress.NOTIFY_ALL); - this._filter.target = tabEventTarget; let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIWebProgress); diff --git a/toolkit/content/tests/browser/browser_findbar.js b/toolkit/content/tests/browser/browser_findbar.js index fd5c001cb751..7b1f8fb3750f 100644 --- a/toolkit/content/tests/browser/browser_findbar.js +++ b/toolkit/content/tests/browser/browser_findbar.js @@ -175,11 +175,7 @@ add_task(async function() { let findBar = gFindBar; let initialValue = findBar._findField.value; - await EventUtils.synthesizeAndWaitKey("f", { accelKey: true }, window, null, - () => { - isnot(document.activeElement, findBar._findField.inputField, - "findbar is not yet focused"); - }); + EventUtils.synthesizeKey("f", { accelKey: true }, window); let promises = [ BrowserTestUtils.sendChar("a", browser), @@ -187,6 +183,8 @@ add_task(async function() { BrowserTestUtils.sendChar("c", browser) ]; + isnot(document.activeElement, findBar._findField.inputField, + "findbar is not yet focused"); is(findBar._findField.value, initialValue, "still has initial find query"); await Promise.all(promises); diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/environments/frame-script.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/environments/frame-script.js index 92fe9330d294..e3d188bfcc5c 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/lib/environments/frame-script.js +++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/environments/frame-script.js @@ -22,7 +22,6 @@ module.exports = { removeWeakMessageListener: false, sendAsyncMessage: false, sendSyncMessage: false, - sendRpcMessage: false, - tabEventTarget: false + sendRpcMessage: false } }; diff --git a/uriloader/base/nsDocLoader.cpp b/uriloader/base/nsDocLoader.cpp index ac61f5b6bacd..10a245b8ea0a 100644 --- a/uriloader/base/nsDocLoader.cpp +++ b/uriloader/base/nsDocLoader.cpp @@ -4,7 +4,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nspr.h" -#include "mozilla/dom/TabGroup.h" #include "mozilla/Logging.h" #include "mozilla/IntegerPrintfMacros.h" @@ -981,27 +980,6 @@ nsDocLoader::GetLoadType(uint32_t *aLoadType) return NS_ERROR_NOT_IMPLEMENTED; } -NS_IMETHODIMP -nsDocLoader::GetTarget(nsIEventTarget** aTarget) -{ - nsCOMPtr window; - nsresult rv = GetDOMWindow(getter_AddRefs(window)); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr piwindow = nsPIDOMWindowOuter::From(window); - NS_ENSURE_STATE(piwindow); - - nsCOMPtr target = piwindow->TabGroup()->EventTargetFor(mozilla::TaskCategory::Other); - target.forget(aTarget); - return NS_OK; -} - -NS_IMETHODIMP -nsDocLoader::SetTarget(nsIEventTarget* aTarget) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - int64_t nsDocLoader::GetMaxTotalProgress() { int64_t newMaxTotal = 0; diff --git a/uriloader/base/nsIWebProgress.idl b/uriloader/base/nsIWebProgress.idl index 0549f32e1e36..135a92d97615 100644 --- a/uriloader/base/nsIWebProgress.idl +++ b/uriloader/base/nsIWebProgress.idl @@ -7,7 +7,6 @@ #include "nsISupports.idl" interface mozIDOMWindowProxy; -interface nsIEventTarget; interface nsIWebProgressListener; /** @@ -152,11 +151,4 @@ interface nsIWebProgress : nsISupports * nsIDocShellLoadInfo.idl. */ readonly attribute unsigned long loadType; - - /** - * Main thread event target to which progress updates should be - * dispatched. This typically will be a SchedulerEventTarget - * corresponding to the tab requesting updates. - */ - attribute nsIEventTarget target; }; diff --git a/widget/tests/test_assign_event_data.html b/widget/tests/test_assign_event_data.html index 016c26a13a43..557d6e77e3e8 100644 --- a/widget/tests/test_assign_event_data.html +++ b/widget/tests/test_assign_event_data.html @@ -100,16 +100,6 @@ function onEvent(aEvent) setTimeout(gCallback, 0); } -function observeKeyUpOnContent(aKeyCode, aCallback) -{ - document.addEventListener("keyup", function keyUp(ev) { - if (ev.keyCode == aKeyCode) { - document.removeEventListener("keyup", keyUp); - SimpleTest.executeSoon(aCallback); - } - }); -} - const kTests = [ { description: "InternalScrollPortEvent (overflow, vertical)", targetID: "scrollable-div", eventType: "overflow", @@ -160,8 +150,6 @@ const kTests = [ document.getElementById(this.targetID).focus(); synthesizeNativeKey(KEYBOARD_LAYOUT_EN_US, kIsWin ? WIN_VK_A : MAC_VK_ANSI_A, {}, "a", "a"); - observeKeyUpOnContent(KeyboardEvent.DOM_VK_A, runNextTest); - return true; }, canRun: function () { return (kIsMac || kIsWin); @@ -175,8 +163,6 @@ const kTests = [ document.getElementById(this.targetID).focus(); synthesizeNativeKey(KEYBOARD_LAYOUT_EN_US, kIsWin ? WIN_VK_A : MAC_VK_ANSI_A, {}, "a", "a"); - observeKeyUpOnContent(KeyboardEvent.DOM_VK_A, runNextTest); - return true; }, canRun: function () { return (kIsMac || kIsWin); @@ -190,8 +176,6 @@ const kTests = [ document.getElementById(this.targetID).focus(); synthesizeNativeKey(KEYBOARD_LAYOUT_EN_US, kIsWin ? WIN_VK_B : MAC_VK_ANSI_B, { shiftKey: true }, "B", "B"); - observeKeyUpOnContent(KeyboardEvent.DOM_VK_B, runNextTest); - return true; }, canRun: function () { return (kIsMac || kIsWin); @@ -205,14 +189,6 @@ const kTests = [ document.getElementById(this.targetID).focus(); synthesizeNativeKey(KEYBOARD_LAYOUT_EN_US, kIsWin ? WIN_VK_C : MAC_VK_ANSI_C, { accelKey: true }, kIsWin ? "\u0003" : "c", "c"); - - // On Windows, synthesizeNativeKey will also fire keyup for accelKey - // (control key on Windows). We have to wait for it to prevent the key - // event break the next test case. - let waitKeyCode = _EU_isWin(window) ? KeyboardEvent.DOM_VK_CONTROL : - KeyboardEvent.DOM_VK_C; - observeKeyUpOnContent(waitKeyCode, runNextTest); - return true; }, canRun: function () { return (kIsMac || kIsWin); @@ -349,8 +325,6 @@ const kTests = [ document.getElementById(this.targetID).focus(); synthesizeNativeKey(KEYBOARD_LAYOUT_EN_US, kIsWin ? WIN_VK_B : MAC_VK_ANSI_B, { shiftKey: true }, "B", "B"); - observeKeyUpOnContent(KeyboardEvent.DOM_VK_B, runNextTest); - return true; }, canRun: function () { return (kIsMac || kIsWin); diff --git a/xpcom/threads/InputEventStatistics.cpp b/xpcom/threads/InputEventStatistics.cpp deleted file mode 100644 index 84426fa9ce45..000000000000 --- a/xpcom/threads/InputEventStatistics.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* -*- 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 "InputEventStatistics.h" - -#include "nsRefreshDriver.h" - -namespace mozilla { - -TimeDuration -InputEventStatistics::TimeDurationCircularBuffer::GetMean() -{ - return mTotal / (int64_t)mSize; -} - -InputEventStatistics::InputEventStatistics() - : mEnable(false) -{ - MOZ_ASSERT(Preferences::IsServiceAvailable()); - uint32_t inputDuration = - Preferences::GetUint("prioritized_input_events.default_duration_per_event", - sDefaultInputDuration); - - TimeDuration defaultDuration = TimeDuration::FromMilliseconds(inputDuration); - - uint32_t count = - Preferences::GetUint("prioritized_input_events.count_for_prediction", - sInputCountForPrediction); - - mLastInputDurations = - MakeUnique(count, defaultDuration); - - uint32_t maxDuration = - Preferences::GetUint("prioritized_input_events.duration.max", - sMaxReservedTimeForHandlingInput); - - uint32_t minDuration = - Preferences::GetUint("prioritized_input_events.duration.min", - sMinReservedTimeForHandlingInput); - - mMaxInputDuration = TimeDuration::FromMilliseconds(maxDuration); - mMinInputDuration = TimeDuration::FromMilliseconds(minDuration); -} - -TimeStamp -InputEventStatistics::GetInputHandlingStartTime(uint32_t aInputCount) -{ - MOZ_ASSERT(mEnable); - Maybe nextTickHint = nsRefreshDriver::GetNextTickHint(); - - if (nextTickHint.isNothing()) { - // Return a past time to process input events immediately. - return TimeStamp::Now() - TimeDuration::FromMilliseconds(1); - } - TimeDuration inputCost = mLastInputDurations->GetMean() * aInputCount; - inputCost = inputCost > mMaxInputDuration - ? mMaxInputDuration - : inputCost < mMinInputDuration - ? mMinInputDuration - : inputCost; - - return nextTickHint.value() - inputCost; -} - -} // namespace mozilla diff --git a/xpcom/threads/InputEventStatistics.h b/xpcom/threads/InputEventStatistics.h deleted file mode 100644 index 4c2a60b3a243..000000000000 --- a/xpcom/threads/InputEventStatistics.h +++ /dev/null @@ -1,114 +0,0 @@ -/* -*- 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/. */ - -#if !defined(InputEventStatistics_h_) -#define InputEventStatistics_h_ - -#include "mozilla/Maybe.h" -#include "mozilla/Preferences.h" -#include "mozilla/TimeStamp.h" - -namespace mozilla { - -class InputEventStatistics -{ - // The default amount of time (milliseconds) required for handling a input - // event. - static const uint16_t sDefaultInputDuration = 1; - - // The number of processed input events we use to predict the amount of time - // required to process the following input events. - static const uint16_t sInputCountForPrediction = 9; - - // The default maximum and minimum time (milliseconds) we reserve for handling - // input events in each frame. - static const uint16_t sMaxReservedTimeForHandlingInput = 8; - static const uint16_t sMinReservedTimeForHandlingInput = 1; - - class TimeDurationCircularBuffer - { - int16_t mSize; - int16_t mCurrentIndex; - nsTArray mBuffer; - TimeDuration mTotal; - - public: - TimeDurationCircularBuffer(uint32_t aSize, TimeDuration& aDefaultValue) - : mSize(aSize) - , mCurrentIndex(0) - { - mSize = mSize == 0 ? sInputCountForPrediction : mSize; - for (int16_t index = 0; index < mSize; ++index) { - mBuffer.AppendElement(aDefaultValue); - mTotal += aDefaultValue; - } - } - - void Insert(TimeDuration& aDuration) - { - mTotal += (aDuration - mBuffer[mCurrentIndex]); - mBuffer[mCurrentIndex++] = aDuration; - if (mCurrentIndex == mSize) { - mCurrentIndex = 0; - } - } - - TimeDuration GetMean(); - }; - - UniquePtr mLastInputDurations; - TimeDuration mMaxInputDuration; - TimeDuration mMinInputDuration; - bool mEnable; - - InputEventStatistics(); - ~InputEventStatistics() - { - } - -public: - static InputEventStatistics& Get() - { - static InputEventStatistics sInstance; - return sInstance; - } - - void UpdateInputDuration(TimeDuration aDuration) - { - if (!mEnable) { - return; - } - mLastInputDurations->Insert(aDuration); - } - - TimeStamp GetInputHandlingStartTime(uint32_t aInputCount); - - void SetEnable(bool aEnable) - { - mEnable = aEnable; - } -}; - -class MOZ_RAII AutoTimeDurationHelper final -{ -public: - AutoTimeDurationHelper() - { - mStartTime = TimeStamp::Now(); - } - - ~AutoTimeDurationHelper() - { - InputEventStatistics::Get().UpdateInputDuration(TimeStamp::Now() - mStartTime); - } - -private: - TimeStamp mStartTime; -}; - -} // namespace mozilla - -#endif // InputEventStatistics_h_ diff --git a/xpcom/threads/LazyIdleThread.cpp b/xpcom/threads/LazyIdleThread.cpp index c91fbc824d89..bb7e3841ce20 100644 --- a/xpcom/threads/LazyIdleThread.cpp +++ b/xpcom/threads/LazyIdleThread.cpp @@ -513,18 +513,6 @@ LazyIdleThread::IdleDispatch(already_AddRefed aEvent) return NS_ERROR_NOT_IMPLEMENTED; } -NS_IMETHODIMP -LazyIdleThread::EnableEventPrioritization() -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -LazyIdleThread::IsEventPrioritizationEnabled(bool* aResult) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - NS_IMETHODIMP LazyIdleThread::RegisterIdlePeriod(already_AddRefed aIdlePeriod) { diff --git a/xpcom/threads/SchedulerGroup.cpp b/xpcom/threads/SchedulerGroup.cpp index 31c0a99d7521..6eed0f646cc5 100644 --- a/xpcom/threads/SchedulerGroup.cpp +++ b/xpcom/threads/SchedulerGroup.cpp @@ -364,17 +364,8 @@ SchedulerGroup::Runnable::Run() return result; } -NS_IMETHODIMP -SchedulerGroup::Runnable::GetPriority(uint32_t* aPriority) -{ - *aPriority = nsIRunnablePriority::PRIORITY_NORMAL; - nsCOMPtr runnablePrio = do_QueryInterface(mRunnable); - return runnablePrio ? runnablePrio->GetPriority(aPriority) : NS_OK; -} - NS_IMPL_ISUPPORTS_INHERITED(SchedulerGroup::Runnable, mozilla::Runnable, - nsIRunnablePriority, SchedulerGroup::Runnable) SchedulerGroup::AutoProcessEvent::AutoProcessEvent() diff --git a/xpcom/threads/SchedulerGroup.h b/xpcom/threads/SchedulerGroup.h index 843f619959ad..a803f0d1f9c9 100644 --- a/xpcom/threads/SchedulerGroup.h +++ b/xpcom/threads/SchedulerGroup.h @@ -81,7 +81,7 @@ public: MOZ_ASSERT(IsSafeToRun()); } - class Runnable final : public mozilla::Runnable, public nsIRunnablePriority + class Runnable final : public mozilla::Runnable { public: Runnable(already_AddRefed&& aRunnable, @@ -95,7 +95,6 @@ public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIRUNNABLE - NS_DECL_NSIRUNNABLEPRIORITY NS_DECLARE_STATIC_IID_ACCESSOR(NS_SCHEDULERGROUPRUNNABLE_IID); diff --git a/xpcom/threads/TimerThread.h b/xpcom/threads/TimerThread.h index f65c501c50e8..9446bbe3b621 100644 --- a/xpcom/threads/TimerThread.h +++ b/xpcom/threads/TimerThread.h @@ -19,7 +19,6 @@ #include "mozilla/Atomics.h" #include "mozilla/Attributes.h" #include "mozilla/Monitor.h" -#include "mozilla/UniquePtr.h" #include @@ -111,8 +110,7 @@ private: } static bool - UniquePtrLessThan(mozilla::UniquePtr& aLeft, - mozilla::UniquePtr& aRight) + UniquePtrLessThan(UniquePtr& aLeft, UniquePtr& aRight) { // This is reversed because std::push_heap() sorts the "largest" to // the front of the heap. We want that to be the earliest timer. @@ -125,7 +123,7 @@ private: } }; - nsTArray> mTimers; + nsTArray> mTimers; uint32_t mAllowedEarlyFiringMicroseconds; }; diff --git a/xpcom/threads/moz.build b/xpcom/threads/moz.build index 3ded2058980e..87f9fa6583e5 100644 --- a/xpcom/threads/moz.build +++ b/xpcom/threads/moz.build @@ -43,7 +43,6 @@ EXPORTS.mozilla += [ 'DeadlockDetector.h', 'HangAnnotations.h', 'HangMonitor.h', - 'InputEventStatistics.h', 'LazyIdleThread.h', 'MainThreadIdlePeriod.h', 'Monitor.h', @@ -70,7 +69,6 @@ UNIFIED_SOURCES += [ 'BlockingResourceBase.cpp', 'HangAnnotations.cpp', 'HangMonitor.cpp', - 'InputEventStatistics.cpp', 'LazyIdleThread.cpp', 'MainThreadIdlePeriod.cpp', 'nsEnvironment.cpp', diff --git a/xpcom/threads/nsIRunnable.idl b/xpcom/threads/nsIRunnable.idl index df5f642cc1bb..4d26f72d913c 100644 --- a/xpcom/threads/nsIRunnable.idl +++ b/xpcom/threads/nsIRunnable.idl @@ -18,11 +18,10 @@ interface nsIRunnable : nsISupports void run(); }; -[scriptable, uuid(e75aa42a-80a9-11e6-afb5-e89d87348e2c)] +[uuid(e75aa42a-80a9-11e6-afb5-e89d87348e2c)] interface nsIRunnablePriority : nsISupports { const unsigned short PRIORITY_NORMAL = 0; - const unsigned short PRIORITY_INPUT = 1; - const unsigned short PRIORITY_HIGH = 2; + const unsigned short PRIORITY_HIGH = 1; readonly attribute unsigned long priority; }; diff --git a/xpcom/threads/nsIThread.idl b/xpcom/threads/nsIThread.idl index f49f7d605972..618051f3be19 100644 --- a/xpcom/threads/nsIThread.idl +++ b/xpcom/threads/nsIThread.idl @@ -152,9 +152,6 @@ interface nsIThread : nsISerialEventTarget */ [noscript] void idleDispatch(in alreadyAddRefed_nsIRunnable event); - [noscript] void enableEventPrioritization(); - [noscript] bool isEventPrioritizationEnabled(); - /** * Use this attribute to dispatch runnables to the thread. Eventually, the * eventTarget attribute will be the only way to dispatch events to a diff --git a/xpcom/threads/nsIThreadManager.idl b/xpcom/threads/nsIThreadManager.idl index 1e3479234213..177687406d3d 100644 --- a/xpcom/threads/nsIThreadManager.idl +++ b/xpcom/threads/nsIThreadManager.idl @@ -8,7 +8,6 @@ [ptr] native PRThread(PRThread); -interface nsIEventTarget; interface nsIRunnable; interface nsIThread; @@ -93,7 +92,7 @@ interface nsIThreadManager : nsISupports * .currentThread.dispatch(runnable, Ci.nsIEventTarget.DISPATCH_NORMAL); * C++ callers should instead use NS_DispatchToMainThread. */ - void dispatchToMainThread(in nsIRunnable event, [optional] in uint32_t priority); + void dispatchToMainThread(in nsIRunnable event); /** * This queues a runnable to the main thread's idle queue. @@ -127,9 +126,4 @@ interface nsIThreadManager : nsISupports * moving away from. */ void spinEventLoopUntilEmpty(); - - /** - * Return the SchedulerEventTarget for the SystemGroup. - */ - readonly attribute nsIEventTarget systemGroupEventTarget; }; diff --git a/xpcom/threads/nsThread.cpp b/xpcom/threads/nsThread.cpp index 8665511ed45f..0f07a2c6047d 100644 --- a/xpcom/threads/nsThread.cpp +++ b/xpcom/threads/nsThread.cpp @@ -41,7 +41,6 @@ #include "nsThreadSyncDispatch.h" #include "LeakRefPtr.h" #include "GeckoProfiler.h" -#include "InputEventStatistics.h" #ifdef MOZ_CRASHREPORTER #include "nsServiceManagerUtils.h" @@ -816,156 +815,45 @@ nsThread::DispatchInternal(already_AddRefed aEvent, uint32_t aFlags return PutEvent(event.take(), aTarget); } -NS_IMPL_ISUPPORTS(nsThread::nsChainedEventQueue::EnablePrioritizationRunnable, - nsIRunnable) - -void -nsThread::nsChainedEventQueue::EnablePrioritization(MutexAutoLock& aProofOfLock) -{ - MOZ_ASSERT(!mIsInputPrioritizationEnabled); - // When enabling event prioritization, there may be some pending events with - // different priorities in the normal queue. Create an event in the normal - // queue to consume all pending events in the time order to make sure we won't - // preempt a pending event (e.g. input) in the normal queue by another newly - // created event with the same priority. - mNormalQueue->PutEvent(new EnablePrioritizationRunnable(this), aProofOfLock); - mInputHandlingStartTime = TimeStamp(); - mIsInputPrioritizationEnabled = true; -} - bool -nsThread::nsChainedEventQueue:: -GetNormalOrInputOrHighPriorityEvent(bool aMayWait, nsIRunnable** aEvent, - unsigned short* aPriority, - MutexAutoLock& aProofOfLock) +nsThread::nsChainedEventQueue::GetEvent(bool aMayWait, nsIRunnable** aEvent, + unsigned short* aPriority, + mozilla::MutexAutoLock& aProofOfLock) { bool retVal = false; do { - // Use mProcessHighPriorityQueueRunnable to prevent the high priority events - // from consuming all cpu time and causing starvation. - if (mProcessHighPriorityQueueRunnable) { - MOZ_ASSERT(mHighQueue->HasPendingEvent(aProofOfLock)); - retVal = mHighQueue->GetEvent(false, aEvent, aProofOfLock); + if (mProcessSecondaryQueueRunnable) { + MOZ_ASSERT(mSecondaryQueue->HasPendingEvent(aProofOfLock)); + retVal = mSecondaryQueue->GetEvent(aMayWait, aEvent, aProofOfLock); MOZ_ASSERT(*aEvent); - SetPriorityIfNotNull(aPriority, nsIRunnablePriority::PRIORITY_HIGH); - mInputHandlingStartTime = TimeStamp(); - mProcessHighPriorityQueueRunnable = false; - return retVal; - } - mProcessHighPriorityQueueRunnable = - mHighQueue->HasPendingEvent(aProofOfLock); - - uint32_t pendingInputCount = mInputQueue->Count(aProofOfLock); - if (pendingInputCount > 0) { - if (mInputHandlingStartTime.IsNull()) { - mInputHandlingStartTime = - InputEventStatistics::Get() - .GetInputHandlingStartTime(mInputQueue->Count(aProofOfLock)); + if (aPriority) { + *aPriority = nsIRunnablePriority::PRIORITY_HIGH; } - if (TimeStamp::Now() > mInputHandlingStartTime) { - retVal = mInputQueue->GetEvent(false, aEvent, aProofOfLock); - MOZ_ASSERT(*aEvent); - SetPriorityIfNotNull(aPriority, nsIRunnablePriority::PRIORITY_INPUT); - return retVal; - } - } - - // We don't want to wait if there are some high priority events or input - // events in the queues. - bool reallyMayWait = aMayWait && !mProcessHighPriorityQueueRunnable && - pendingInputCount == 0; - - retVal = mNormalQueue->GetEvent(reallyMayWait, aEvent, aProofOfLock); - if (*aEvent) { - // We got an event, return early. - SetPriorityIfNotNull(aPriority, nsIRunnablePriority::PRIORITY_NORMAL); + mProcessSecondaryQueueRunnable = false; return retVal; } - if (pendingInputCount > 0 && !mProcessHighPriorityQueueRunnable) { - // Handle input events if we have time for them. - MOZ_ASSERT(mInputQueue->HasPendingEvent(aProofOfLock)); - retVal = mInputQueue->GetEvent(false, aEvent, aProofOfLock); - MOZ_ASSERT(*aEvent); - SetPriorityIfNotNull(aPriority, nsIRunnablePriority::PRIORITY_INPUT); - return retVal; - } - } while (aMayWait || mProcessHighPriorityQueueRunnable); - return retVal; -} -bool -nsThread::nsChainedEventQueue:: -GetNormalOrHighPriorityEvent(bool aMayWait, nsIRunnable** aEvent, - unsigned short* aPriority, - MutexAutoLock& aProofOfLock) -{ - bool retVal = false; - do { - // Use mProcessHighPriorityQueueRunnable to prevent the high priority events - // from consuming all cpu time and causing starvation. - if (mProcessHighPriorityQueueRunnable) { - MOZ_ASSERT(mHighQueue->HasPendingEvent(aProofOfLock)); - retVal = mHighQueue->GetEvent(false, aEvent, aProofOfLock); - MOZ_ASSERT(*aEvent); - SetPriorityIfNotNull(aPriority, nsIRunnablePriority::PRIORITY_HIGH); - mProcessHighPriorityQueueRunnable = false; - return retVal; + // We don't want to wait if mSecondaryQueue has some events. + bool reallyMayWait = + aMayWait && !mSecondaryQueue->HasPendingEvent(aProofOfLock); + retVal = + mNormalQueue->GetEvent(reallyMayWait, aEvent, aProofOfLock); + if (aPriority) { + *aPriority = nsIRunnablePriority::PRIORITY_NORMAL; } - mProcessHighPriorityQueueRunnable = - mHighQueue->HasPendingEvent(aProofOfLock); - // We don't want to wait if there are some events in the high priority + // Let's see if we should next time process an event from the secondary // queue. - bool reallyMayWait = aMayWait && !mProcessHighPriorityQueueRunnable; + mProcessSecondaryQueueRunnable = + mSecondaryQueue->HasPendingEvent(aProofOfLock); - retVal = mNormalQueue->GetEvent(reallyMayWait, aEvent, aProofOfLock); if (*aEvent) { // We got an event, return early. - SetPriorityIfNotNull(aPriority, nsIRunnablePriority::PRIORITY_NORMAL); return retVal; } - } while (aMayWait || mProcessHighPriorityQueueRunnable); - return retVal; -} + } while(aMayWait || mProcessSecondaryQueueRunnable); -void -nsThread::nsChainedEventQueue::PutEvent(already_AddRefed aEvent, - MutexAutoLock& aProofOfLock) -{ - RefPtr event(aEvent); - nsCOMPtr runnablePrio(do_QueryInterface(event)); - uint32_t prio = nsIRunnablePriority::PRIORITY_NORMAL; - if (runnablePrio) { - runnablePrio->GetPriority(&prio); - } - switch (prio) { - case nsIRunnablePriority::PRIORITY_NORMAL: - mNormalQueue->PutEvent(event.forget(), aProofOfLock); - break; - case nsIRunnablePriority::PRIORITY_INPUT: - if (mIsInputPrioritizationEnabled) { - mInputQueue->PutEvent(event.forget(), aProofOfLock); - } else { - mNormalQueue->PutEvent(event.forget(), aProofOfLock); - } - break; - case nsIRunnablePriority::PRIORITY_HIGH: - if (mIsInputPrioritizationEnabled) { - mHighQueue->PutEvent(event.forget(), aProofOfLock); - } else { - // During startup, ContentParent sends SetXPCOMProcessAttributes to - // initialize ContentChild and enable input event prioritization. After - // that, ContentParent sends PBrowserConstructor to create PBrowserChild. - // To prevent PBrowserConstructor preempt SetXPCOMProcessAttributes and - // cause problems, we have to put high priority events in mNormalQueue to - // keep the correct order of initialization. - mNormalQueue->PutEvent(event.forget(), aProofOfLock); - } - break; - default: - MOZ_ASSERT(false); - break; - } + return retVal; } //----------------------------------------------------------------------------- @@ -1277,24 +1165,6 @@ nsThread::IdleDispatch(already_AddRefed aEvent) return NS_OK; } -NS_IMETHODIMP -nsThread::EnableEventPrioritization() -{ - MOZ_ASSERT(NS_IsMainThread()); - MutexAutoLock lock(mLock); - // Only support event prioritization for main event queue. - mEventsRoot.EnablePrioritization(lock); - return NS_OK; -} - -NS_IMETHODIMP -nsThread::IsEventPrioritizationEnabled(bool* aResult) -{ - MOZ_ASSERT(NS_IsMainThread()); - *aResult = mEventsRoot.IsPrioritizationEnabled(); - return NS_OK; -} - #ifdef MOZ_CANARY void canary_alarm_handler(int signum); @@ -1572,10 +1442,7 @@ nsThread::ProcessNextEvent(bool aMayWait, bool* aResult) sMainThreadRunnableName[length] = '\0'; } #endif - Maybe timeDurationHelper; - if (priority == nsIRunnablePriority::PRIORITY_INPUT) { - timeDurationHelper.emplace(); - } + event->Run(); } else if (aMayWait) { MOZ_ASSERT(ShuttingDown(), diff --git a/xpcom/threads/nsThread.h b/xpcom/threads/nsThread.h index aee3cd83079f..9330df346bb5 100644 --- a/xpcom/threads/nsThread.h +++ b/xpcom/threads/nsThread.h @@ -97,16 +97,6 @@ public: static const uint32_t kRunnableNameBufSize = 1000; static mozilla::Array sMainThreadRunnableName; - // Query whether there are some pending input events in the queue. This method - // is supposed to be called on main thread with input event prioritization - // enabled. - bool HasPendingInputEvents() - { - MOZ_ASSERT(NS_IsMainThread()); - mozilla::MutexAutoLock lock(mLock); - return mEventsRoot.HasPendingEventsInInputQueue(lock); - } - private: void DoMainThreadSpecificProcessing(bool aReallyWait); @@ -152,43 +142,27 @@ protected: struct nsThreadShutdownContext* ShutdownInternal(bool aSync); - // Wrapper for nsEventQueue that supports chaining and prioritization. + // Wrapper for nsEventQueue that supports chaining. class nsChainedEventQueue { public: explicit nsChainedEventQueue(mozilla::Mutex& aLock) : mNext(nullptr) , mEventsAvailable(aLock, "[nsChainedEventQueue.mEventsAvailable]") - , mIsInputPrioritizationEnabled(false) - , mIsReadyToPrioritizeEvents(false) - , mProcessHighPriorityQueueRunnable(false) + , mProcessSecondaryQueueRunnable(false) { mNormalQueue = mozilla::MakeUnique(mEventsAvailable, nsEventQueue::eSharedCondVarQueue); - // All queues need to use the same CondVar! - mInputQueue = + // Both queues need to use the same CondVar! + mSecondaryQueue = mozilla::MakeUnique(mEventsAvailable, nsEventQueue::eSharedCondVarQueue); - mHighQueue = - mozilla::MakeUnique(mEventsAvailable, - nsEventQueue::eSharedCondVarQueue); - } - - void EnablePrioritization(mozilla::MutexAutoLock& aProofOfLock); - - bool IsPrioritizationEnabled() - { - return mIsInputPrioritizationEnabled; } bool GetEvent(bool aMayWait, nsIRunnable** aEvent, unsigned short* aPriority, - mozilla::MutexAutoLock& aProofOfLock) { - return mIsReadyToPrioritizeEvents - ? GetNormalOrInputOrHighPriorityEvent(aMayWait, aEvent, aPriority, aProofOfLock) - : GetNormalOrHighPriorityEvent(aMayWait, aEvent, aPriority, aProofOfLock); - } + mozilla::MutexAutoLock& aProofOfLock); void PutEvent(nsIRunnable* aEvent, mozilla::MutexAutoLock& aProofOfLock) { @@ -197,82 +171,43 @@ protected: } void PutEvent(already_AddRefed aEvent, - mozilla::MutexAutoLock& aProofOfLock); + mozilla::MutexAutoLock& aProofOfLock) + { + RefPtr event(aEvent); + nsCOMPtr runnablePrio = + do_QueryInterface(event); + uint32_t prio = nsIRunnablePriority::PRIORITY_NORMAL; + if (runnablePrio) { + runnablePrio->GetPriority(&prio); + } + MOZ_ASSERT(prio == nsIRunnablePriority::PRIORITY_NORMAL || + prio == nsIRunnablePriority::PRIORITY_HIGH); + if (prio == nsIRunnablePriority::PRIORITY_NORMAL) { + mNormalQueue->PutEvent(event.forget(), aProofOfLock); + } else { + mSecondaryQueue->PutEvent(event.forget(), aProofOfLock); + } + } bool HasPendingEvent(mozilla::MutexAutoLock& aProofOfLock) { return mNormalQueue->HasPendingEvent(aProofOfLock) || - mInputQueue->HasPendingEvent(aProofOfLock) || - mHighQueue->HasPendingEvent(aProofOfLock); - } - - bool HasPendingEventsInInputQueue(mozilla::MutexAutoLock& aProofOfLock) - { - MOZ_ASSERT(mIsInputPrioritizationEnabled); - return mInputQueue->HasPendingEvent(aProofOfLock); + mSecondaryQueue->HasPendingEvent(aProofOfLock); } nsChainedEventQueue* mNext; RefPtr mEventTarget; private: - bool GetNormalOrInputOrHighPriorityEvent(bool aMayWait, - nsIRunnable** aEvent, - unsigned short* aPriority, - mozilla::MutexAutoLock& aProofOfLock); - - bool GetNormalOrHighPriorityEvent(bool aMayWait, nsIRunnable** aEvent, - unsigned short* aPriority, - mozilla::MutexAutoLock& aProofOfLock); - - // This is used to flush pending events in nsChainedEventQueue::mNormalQueue - // before starting event prioritization. - class EnablePrioritizationRunnable final : public nsIRunnable - { - nsChainedEventQueue* mEventQueue; - - public: - NS_DECL_ISUPPORTS - - explicit EnablePrioritizationRunnable(nsChainedEventQueue* aQueue) - : mEventQueue(aQueue) - { - } - - NS_IMETHOD Run() override - { - mEventQueue->mIsReadyToPrioritizeEvents = true; - return NS_OK; - } - private: - ~EnablePrioritizationRunnable() - { - } - }; - - static void SetPriorityIfNotNull(unsigned short* aPriority, short aValue) - { - if (aPriority) { - *aPriority = aValue; - } - } mozilla::CondVar mEventsAvailable; - mozilla::TimeStamp mInputHandlingStartTime; mozilla::UniquePtr mNormalQueue; - mozilla::UniquePtr mInputQueue; - mozilla::UniquePtr mHighQueue; - bool mIsInputPrioritizationEnabled; + mozilla::UniquePtr mSecondaryQueue; - // When enabling input event prioritization, there may be some events in the - // queue. We have to process all of them before the new coming events to - // prevent the queued events are preempted by the newly ones with the same - // priority. - bool mIsReadyToPrioritizeEvents; // Try to process one high priority runnable after each normal // priority runnable. This gives the processing model HTML spec has for // 'Update the rendering' in the case only vsync messages are in the // secondary queue and prevents starving the normal queue. - bool mProcessHighPriorityQueueRunnable; + bool mProcessSecondaryQueueRunnable; }; class nsNestedEventTarget final : public nsIEventTarget diff --git a/xpcom/threads/nsThreadManager.cpp b/xpcom/threads/nsThreadManager.cpp index 8d56bc1ccda9..35b80970487e 100644 --- a/xpcom/threads/nsThreadManager.cpp +++ b/xpcom/threads/nsThreadManager.cpp @@ -11,10 +11,7 @@ #include "nsTArray.h" #include "nsAutoPtr.h" #include "mozilla/AbstractThread.h" -#include "mozilla/InputEventStatistics.h" -#include "mozilla/SystemGroup.h" #include "mozilla/ThreadLocal.h" -#include "mozilla/Preferences.h" #ifdef MOZ_CANARY #include #include @@ -330,7 +327,7 @@ NS_IMETHODIMP nsThreadManager::GetCurrentThread(nsIThread** aResult) { // Keep this functioning during Shutdown - if (!mMainThread) { + if (NS_WARN_IF(!mMainThread)) { return NS_ERROR_NOT_INITIALIZED; } *aResult = GetCurrentThread(); @@ -379,14 +376,6 @@ nsThreadManager::SpinEventLoopUntilEmpty() return NS_OK; } -NS_IMETHODIMP -nsThreadManager::GetSystemGroupEventTarget(nsIEventTarget** aTarget) -{ - nsCOMPtr target = SystemGroup::EventTargetFor(TaskCategory::Other); - target.forget(aTarget); - return NS_OK; -} - uint32_t nsThreadManager::GetHighestNumberOfThreads() { @@ -395,7 +384,7 @@ nsThreadManager::GetHighestNumberOfThreads() } NS_IMETHODIMP -nsThreadManager::DispatchToMainThread(nsIRunnable *aEvent, uint32_t aPriority) +nsThreadManager::DispatchToMainThread(nsIRunnable *aEvent) { // Note: C++ callers should instead use NS_DispatchToMainThread. MOZ_ASSERT(NS_IsMainThread()); @@ -404,33 +393,10 @@ nsThreadManager::DispatchToMainThread(nsIRunnable *aEvent, uint32_t aPriority) if (NS_WARN_IF(!mMainThread)) { return NS_ERROR_NOT_INITIALIZED; } - if (aPriority != nsIRunnablePriority::PRIORITY_NORMAL) { - nsCOMPtr event(aEvent); - return mMainThread->DispatchFromScript( - new PrioritizableRunnable(event.forget(), aPriority), 0); - } + return mMainThread->DispatchFromScript(aEvent, 0); } -void -nsThreadManager::EnableMainThreadEventPrioritization() -{ - static bool sIsInitialized = false; - if (sIsInitialized) { - return; - } - sIsInitialized = true; - MOZ_ASSERT(Preferences::IsServiceAvailable()); - bool enable = - Preferences::GetBool("prioritized_input_events.enabled", false); - - if (!enable) { - return; - } - InputEventStatistics::Get().SetEnable(true); - mMainThread->EnableEventPrioritization(); -} - NS_IMETHODIMP nsThreadManager::IdleDispatchToMainThread(nsIRunnable *aEvent, uint32_t aTimeout) { diff --git a/xpcom/threads/nsThreadManager.h b/xpcom/threads/nsThreadManager.h index da9e35578490..64ccc9bc946a 100644 --- a/xpcom/threads/nsThreadManager.h +++ b/xpcom/threads/nsThreadManager.h @@ -53,7 +53,6 @@ public: ~nsThreadManager() { } - void EnableMainThreadEventPrioritization(); private: nsThreadManager() diff --git a/xpcom/threads/nsThreadUtils.cpp b/xpcom/threads/nsThreadUtils.cpp index 2810f951eaed..26c25d12b6e1 100644 --- a/xpcom/threads/nsThreadUtils.cpp +++ b/xpcom/threads/nsThreadUtils.cpp @@ -88,47 +88,6 @@ already_AddRefed CreateTimer() } // namespace detail } // namespace mozilla -NS_IMPL_ISUPPORTS_INHERITED(PrioritizableRunnable, Runnable, - nsIRunnablePriority) - -PrioritizableRunnable::PrioritizableRunnable(already_AddRefed&& aRunnable, - uint32_t aPriority) - // Real runnable name is managed by overridding the GetName function. - : Runnable("PrioritizableRunnable") - , mRunnable(Move(aRunnable)) - , mPriority(aPriority) -{ -#if DEBUG - nsCOMPtr runnablePrio = do_QueryInterface(mRunnable); - MOZ_ASSERT(!runnablePrio); -#endif -} - -NS_IMETHODIMP -PrioritizableRunnable::GetName(nsACString& aName) -{ - // Try to get a name from the underlying runnable. - nsCOMPtr named = do_QueryInterface(mRunnable); - if (named) { - named->GetName(aName); - } - return NS_OK; -} - -NS_IMETHODIMP -PrioritizableRunnable::Run() -{ - MOZ_RELEASE_ASSERT(NS_IsMainThread()); - return mRunnable->Run(); -} - -NS_IMETHODIMP -PrioritizableRunnable::GetPriority(uint32_t* aPriority) -{ - *aPriority = mPriority; - return NS_OK; -} - #endif // XPCOM_GLUE_AVOID_NSPR //----------------------------------------------------------------------------- diff --git a/xpcom/threads/nsThreadUtils.h b/xpcom/threads/nsThreadUtils.h index 7f565c04bdb5..e8b11fde75f6 100644 --- a/xpcom/threads/nsThreadUtils.h +++ b/xpcom/threads/nsThreadUtils.h @@ -486,26 +486,6 @@ private: IdleRunnable& operator=(const IdleRunnable&&) = delete; }; -// This class is designed to be a wrapper of a real runnable to support event -// prioritizable. -class PrioritizableRunnable : public Runnable, public nsIRunnablePriority -{ -public: - PrioritizableRunnable(already_AddRefed&& aRunnable, - uint32_t aPriority); - - NS_IMETHOD GetName(nsACString& aName) override; - - NS_DECL_ISUPPORTS_INHERITED - NS_DECL_NSIRUNNABLE - NS_DECL_NSIRUNNABLEPRIORITY - -protected: - virtual ~PrioritizableRunnable() {}; - nsCOMPtr mRunnable; - uint32_t mPriority; -}; - namespace detail { // An event that can be used to call a C++11 functions or function objects, diff --git a/xpcom/threads/nsTimerImpl.h b/xpcom/threads/nsTimerImpl.h index 4b26cd21d80a..a6c80ef2fa98 100644 --- a/xpcom/threads/nsTimerImpl.h +++ b/xpcom/threads/nsTimerImpl.h @@ -132,7 +132,7 @@ public: nsresult InitCommon(uint32_t aDelayMS, uint32_t aType, Callback&& newCallback); - nsresult InitCommon(const mozilla::TimeDuration& aDelay, uint32_t aType, + nsresult InitCommon(const TimeDuration& aDelay, uint32_t aType, Callback&& newCallback); Callback& GetCallback() @@ -200,9 +200,9 @@ public: // Updated only after this timer has been removed from the timer thread. int32_t mGeneration; - mozilla::TimeDuration mDelay; + TimeDuration mDelay; // Updated only after this timer has been removed from the timer thread. - mozilla::TimeStamp mTimeout; + TimeStamp mTimeout; #ifdef MOZ_TASK_TRACER mozilla::tasktracer::TracedTaskCommon mTracedTask;