From 55321532bcb760bb9422766f4aacd7b26cdf1ce3 Mon Sep 17 00:00:00 2001 From: Johan Lorenzo Date: Mon, 3 Sep 2018 06:09:04 +0000 Subject: [PATCH 01/61] Bug 1488127 - Make 52 -> 60 updates signed with the old mar scheme (instead of mar_384) r=tomprince a=release Make 52 -> 60 updates signed with the old mar scheme (instead of mar_384) Differential Revision: https://phabricator.services.mozilla.com/D4841 --HG-- extra : moz-landing-system : lando --- .../transforms/beetmover_repackage.py | 4 +-- .../taskgraph/transforms/partials_signing.py | 30 +++++++++++++++++-- taskcluster/taskgraph/util/partials.py | 5 +++- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/taskcluster/taskgraph/transforms/beetmover_repackage.py b/taskcluster/taskgraph/transforms/beetmover_repackage.py index 4289aeb72f43..66d99df7575c 100644 --- a/taskcluster/taskgraph/transforms/beetmover_repackage.py +++ b/taskcluster/taskgraph/transforms/beetmover_repackage.py @@ -334,8 +334,8 @@ def generate_partials_upstream_artifacts(job, artifacts, platform, locale=None): upstream_artifacts = [{ 'taskId': {'task-reference': ''}, 'taskType': 'signing', - 'paths': ["{}/{}".format(artifact_prefix, p) - for p in artifacts], + 'paths': ["{}/{}".format(artifact_prefix, path) + for path, _ in artifacts], 'locale': locale or 'en-US', }] diff --git a/taskcluster/taskgraph/transforms/partials_signing.py b/taskcluster/taskgraph/transforms/partials_signing.py index 4198a0ad938a..098b188139b0 100644 --- a/taskcluster/taskgraph/transforms/partials_signing.py +++ b/taskcluster/taskgraph/transforms/partials_signing.py @@ -33,14 +33,36 @@ def generate_upstream_artifacts(job, release_history, platform, locale=None): upstream_artifacts = [{ "taskId": {"task-reference": ''}, "taskType": 'partials', - "paths": ["{}/{}".format(artifact_prefix, p) - for p in artifacts], + "paths": [ + "{}/{}".format(artifact_prefix, path) + for path, version in artifacts + # TODO Use mozilla-version to avoid comparing strings. Otherwise Firefox 100 will be + # considered smaller than Firefox 56 + if version is None or version >= '56' + ], "formats": ["mar_sha384"], }] + old_mar_upstream_artifacts = { + "taskId": {"task-reference": ''}, + "taskType": 'partials', + "paths": [ + "{}/{}".format(artifact_prefix, path) + for path, version in artifacts + # TODO Use mozilla-version to avoid comparing strings. Otherwise Firefox 100 will be + # considered smaller than Firefox 56 + if version is not None and version < '56' + ], + "formats": ["mar"], + } + + if old_mar_upstream_artifacts["paths"]: + upstream_artifacts.append(old_mar_upstream_artifacts) + return upstream_artifacts + @transforms.add def make_task_description(config, jobs): for job in jobs: @@ -81,7 +103,11 @@ def make_task_description(config, jobs): signing_cert_scope = get_signing_cert_scope_per_platform( build_platform, is_nightly, config ) + scopes = [signing_cert_scope, 'project:releng:signing:format:mar_sha384'] + if any("mar" in upstream_details["formats"] for upstream_details in upstream_artifacts): + scopes.append('project:releng:signing:format:mar') + task = { 'label': label, 'description': "{} Partials".format( diff --git a/taskcluster/taskgraph/util/partials.py b/taskcluster/taskgraph/util/partials.py index 2c92fa5f641e..80f6cea5028a 100644 --- a/taskcluster/taskgraph/util/partials.py +++ b/taskcluster/taskgraph/util/partials.py @@ -91,7 +91,10 @@ def get_builds(release_history, platform, locale): def get_partials_artifacts(release_history, platform, locale): platform = _sanitize_platform(platform) - return release_history.get(platform, {}).get(locale, {}).keys() + return [ + (artifact, details.get('previousVersion', None)) + for artifact, details in release_history.get(platform, {}).get(locale, {}).items() + ] def get_partials_artifact_map(release_history, platform, locale): From afe6a56e8e1aac4ac32f43c660a38512146fd7a5 Mon Sep 17 00:00:00 2001 From: Johan Lorenzo Date: Mon, 3 Sep 2018 13:58:03 +0000 Subject: [PATCH 02/61] Bug 1488145 - Update bouncer to deliver esr60 by default now that esr52 is ended r=sfraser Update bouncer to deliver esr60 by default now that esr52 is ended Differential Revision: https://phabricator.services.mozilla.com/D4842 --HG-- extra : moz-landing-system : lando --- taskcluster/ci/release-bouncer-aliases/kind.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/taskcluster/ci/release-bouncer-aliases/kind.yml b/taskcluster/ci/release-bouncer-aliases/kind.yml index 1ff834acbb58..1ae4e0ab9e79 100644 --- a/taskcluster/ci/release-bouncer-aliases/kind.yml +++ b/taskcluster/ci/release-bouncer-aliases/kind.yml @@ -81,16 +81,15 @@ jobs: firefox-latest: installer firefox-stub: stub-installer mozilla-esr60: - # convert to firefox-esr-latest when ESR52 stops - firefox-esr-next-latest-ssl: installer-ssl - firefox-esr-next-latest: installer + firefox-esr-latest-ssl: installer-ssl + firefox-esr-latest: installer birch: firefox-latest-ssl: installer-ssl firefox-latest: installer firefox-stub: stub-installer jamun: - firefox-esr-next-latest-ssl: installer-ssl - firefox-esr-next-latest: installer + firefox-esr-latest-ssl: installer-ssl + firefox-esr-latest: installer maple: firefox-beta-latest-ssl: installer-ssl firefox-beta-latest: installer From ce3c80f96df5183b53fbca2890269278130a75b1 Mon Sep 17 00:00:00 2001 From: Mathieu Leplatre Date: Tue, 4 Sep 2018 09:26:11 +0000 Subject: [PATCH 03/61] Bug 1481348 - Prevent intermittent failures with fake RemoteSettings server r=glasserc Differential Revision: https://phabricator.services.mozilla.com/D3537 --HG-- extra : moz-landing-system : lando --- services/settings/remote-settings.js | 12 +++++++++--- .../settings/test/unit/test_remote_settings_poll.js | 13 +++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/services/settings/remote-settings.js b/services/settings/remote-settings.js index 35dd0f38da12..cfebc2f552fe 100644 --- a/services/settings/remote-settings.js +++ b/services/settings/remote-settings.js @@ -163,12 +163,18 @@ async function fetchLatestChanges(url, lastEtag) { } catch (e) { payload = e.message; } + if (!payload.hasOwnProperty("data")) { // If the server is failing, the JSON response might not contain the - // expected data (e.g. error response - Bug 1259145) - throw new Error(`Server error ${response.status} ${response.statusText}: ${JSON.stringify(payload)}`); + // expected data. For example, real server errors (Bug 1259145) + // or dummy local server for tests (Bug 1481348) + const is404FromCustomServer = response.status == 404 && Services.prefs.prefHasUserValue(PREF_SETTINGS_SERVER); + if (!is404FromCustomServer) { + throw new Error(`Server error ${response.status} ${response.statusText}: ${JSON.stringify(payload)}`); + } + } else { + changes = payload.data; } - changes = payload.data; } // The server should always return ETag. But we've had situations where the CDN // was interfering. diff --git a/services/settings/test/unit/test_remote_settings_poll.js b/services/settings/test/unit/test_remote_settings_poll.js index caec2d539f72..ce3834816186 100644 --- a/services/settings/test/unit/test_remote_settings_poll.js +++ b/services/settings/test/unit/test_remote_settings_poll.js @@ -261,6 +261,19 @@ add_task(async function test_server_bad_json() { add_task(clear_state); +add_task(async function test_server_404_response() { + function simulateDummy404(request, response) { + response.setHeader("Content-Type", "application/json; charset=UTF-8"); + response.write(""); + response.setStatusLine(null, 404, "OK"); + } + server.registerPathHandler(CHANGES_PATH, simulateDummy404); + + await RemoteSettings.pollChanges(); // Does not fail when running from tests. +}); +add_task(clear_state); + + add_task(async function test_server_error() { const startHistogram = getUptakeTelemetrySnapshot(TELEMETRY_HISTOGRAM_KEY); From f03acf2b721926a0fa91bd7bfceb925867454e97 Mon Sep 17 00:00:00 2001 From: shindli Date: Tue, 4 Sep 2018 13:07:35 +0300 Subject: [PATCH 04/61] Backed out changeset f9f5910f9c98 (bug 1488127) for linting failure in partials_signing.py --- .../transforms/beetmover_repackage.py | 4 +-- .../taskgraph/transforms/partials_signing.py | 30 ++----------------- taskcluster/taskgraph/util/partials.py | 5 +--- 3 files changed, 5 insertions(+), 34 deletions(-) diff --git a/taskcluster/taskgraph/transforms/beetmover_repackage.py b/taskcluster/taskgraph/transforms/beetmover_repackage.py index 66d99df7575c..4289aeb72f43 100644 --- a/taskcluster/taskgraph/transforms/beetmover_repackage.py +++ b/taskcluster/taskgraph/transforms/beetmover_repackage.py @@ -334,8 +334,8 @@ def generate_partials_upstream_artifacts(job, artifacts, platform, locale=None): upstream_artifacts = [{ 'taskId': {'task-reference': ''}, 'taskType': 'signing', - 'paths': ["{}/{}".format(artifact_prefix, path) - for path, _ in artifacts], + 'paths': ["{}/{}".format(artifact_prefix, p) + for p in artifacts], 'locale': locale or 'en-US', }] diff --git a/taskcluster/taskgraph/transforms/partials_signing.py b/taskcluster/taskgraph/transforms/partials_signing.py index 098b188139b0..4198a0ad938a 100644 --- a/taskcluster/taskgraph/transforms/partials_signing.py +++ b/taskcluster/taskgraph/transforms/partials_signing.py @@ -33,36 +33,14 @@ def generate_upstream_artifacts(job, release_history, platform, locale=None): upstream_artifacts = [{ "taskId": {"task-reference": ''}, "taskType": 'partials', - "paths": [ - "{}/{}".format(artifact_prefix, path) - for path, version in artifacts - # TODO Use mozilla-version to avoid comparing strings. Otherwise Firefox 100 will be - # considered smaller than Firefox 56 - if version is None or version >= '56' - ], + "paths": ["{}/{}".format(artifact_prefix, p) + for p in artifacts], "formats": ["mar_sha384"], }] - old_mar_upstream_artifacts = { - "taskId": {"task-reference": ''}, - "taskType": 'partials', - "paths": [ - "{}/{}".format(artifact_prefix, path) - for path, version in artifacts - # TODO Use mozilla-version to avoid comparing strings. Otherwise Firefox 100 will be - # considered smaller than Firefox 56 - if version is not None and version < '56' - ], - "formats": ["mar"], - } - - if old_mar_upstream_artifacts["paths"]: - upstream_artifacts.append(old_mar_upstream_artifacts) - return upstream_artifacts - @transforms.add def make_task_description(config, jobs): for job in jobs: @@ -103,11 +81,7 @@ def make_task_description(config, jobs): signing_cert_scope = get_signing_cert_scope_per_platform( build_platform, is_nightly, config ) - scopes = [signing_cert_scope, 'project:releng:signing:format:mar_sha384'] - if any("mar" in upstream_details["formats"] for upstream_details in upstream_artifacts): - scopes.append('project:releng:signing:format:mar') - task = { 'label': label, 'description': "{} Partials".format( diff --git a/taskcluster/taskgraph/util/partials.py b/taskcluster/taskgraph/util/partials.py index 80f6cea5028a..2c92fa5f641e 100644 --- a/taskcluster/taskgraph/util/partials.py +++ b/taskcluster/taskgraph/util/partials.py @@ -91,10 +91,7 @@ def get_builds(release_history, platform, locale): def get_partials_artifacts(release_history, platform, locale): platform = _sanitize_platform(platform) - return [ - (artifact, details.get('previousVersion', None)) - for artifact, details in release_history.get(platform, {}).get(locale, {}).items() - ] + return release_history.get(platform, {}).get(locale, {}).keys() def get_partials_artifact_map(release_history, platform, locale): From 0ba16ea654a3cf13d38be125284787a239af7faa Mon Sep 17 00:00:00 2001 From: Johann Hofmann Date: Tue, 4 Sep 2018 10:30:11 +0000 Subject: [PATCH 05/61] Bug 1488371 - Add a comma to a string on about:privatebrowsing. r=flod Differential Revision: https://phabricator.services.mozilla.com/D4919 --HG-- extra : moz-landing-system : lando --- browser/locales/en-US/chrome/browser/aboutPrivateBrowsing.dtd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/locales/en-US/chrome/browser/aboutPrivateBrowsing.dtd b/browser/locales/en-US/chrome/browser/aboutPrivateBrowsing.dtd index fa45ce582282..0adde4e1efdf 100644 --- a/browser/locales/en-US/chrome/browser/aboutPrivateBrowsing.dtd +++ b/browser/locales/en-US/chrome/browser/aboutPrivateBrowsing.dtd @@ -32,4 +32,4 @@ - + From eeb98454b6d3e8186bd570847ffa55ee70f98f90 Mon Sep 17 00:00:00 2001 From: James Teh Date: Tue, 4 Sep 2018 09:34:23 +0000 Subject: [PATCH 06/61] Bug 1200038: Don't use the system group for XUL tabbox keydown handlers. r=dao Bug 1008772 moved all key handlers related to browser tabs to the system group to prevent websites from stealing tab switching keys. However, this is only necessary for global tab switching keys; e.g. Control+Tab, Control+PageUp. It is not necessary for keys which only operate when the tab bar is focused; e.g. Up/DownArrow. This is because when the browser chrome is focused (including the tab bar), content key handlers can't intercept key presses. Furthermore, having these in the system group gives them precedence over XUL context menus. This causes tab switches to occur when the arrow keys are pressed while the context menu is open, which is highly undesirable. Moving these (non-global) keydown handlers into the normal group fixes this. Differential Revision: https://phabricator.services.mozilla.com/D4854 --HG-- extra : moz-landing-system : lando --- browser/base/content/test/tabs/browser.ini | 1 + .../tabs/browser_tabContextMenu_keyboard.js | 53 +++++++++++++++++++ toolkit/content/widgets/tabbox.xml | 12 ++--- 3 files changed, 60 insertions(+), 6 deletions(-) create mode 100644 browser/base/content/test/tabs/browser_tabContextMenu_keyboard.js diff --git a/browser/base/content/test/tabs/browser.ini b/browser/base/content/test/tabs/browser.ini index 0c0cc2df4c63..daf5103fd784 100644 --- a/browser/base/content/test/tabs/browser.ini +++ b/browser/base/content/test/tabs/browser.ini @@ -63,6 +63,7 @@ skip-if = (verify && (os == 'win' || os == 'mac')) [browser_reload_deleted_file.js] skip-if = (debug && os == 'mac') || (debug && os == 'linux' && bits == 64) #Bug 1421183, disabled on Linux/OSX for leaked windows [browser_tabCloseProbes.js] +[browser_tabContextMenu_keyboard.js] [browser_tabReorder_overflow.js] [browser_tabReorder.js] [browser_tabSpinnerProbe.js] diff --git a/browser/base/content/test/tabs/browser_tabContextMenu_keyboard.js b/browser/base/content/test/tabs/browser_tabContextMenu_keyboard.js new file mode 100644 index 000000000000..873b570be66e --- /dev/null +++ b/browser/base/content/test/tabs/browser_tabContextMenu_keyboard.js @@ -0,0 +1,53 @@ +/* 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/. */ + +async function openContextMenu() { + let contextMenu = document.getElementById("tabContextMenu"); + let popupShown = BrowserTestUtils.waitForEvent(contextMenu, "popupshown"); + EventUtils.synthesizeMouseAtCenter(gBrowser.selectedTab, {type: "contextmenu", button: 2}); + await popupShown; +} + +async function closeContextMenu() { + let contextMenu = document.getElementById("tabContextMenu"); + let popupHidden = BrowserTestUtils.waitForEvent(contextMenu, "popuphidden"); + EventUtils.synthesizeKey("KEY_Escape"); + await popupHidden; +} + +add_task(async function test() { + // Ensure tabs are focusable. + await SpecialPowers.pushPrefEnv({"set": [["accessibility.tabfocus", 7]]}); + + // There should be one tab when we start the test. + let tab1 = gBrowser.selectedTab; + let tab2 = BrowserTestUtils.addTab(gBrowser); + tab1.focus(); + is(document.activeElement, tab1, "tab1 should be focused"); + + // Ensure that DownArrow doesn't switch to tab2 while the context menu is open. + await openContextMenu(); + EventUtils.synthesizeKey("KEY_ArrowDown"); + await closeContextMenu(); + is(gBrowser.selectedTab, tab1, "tab1 should still be active"); + if (AppConstants.platform == "macosx") { + // On Mac, focus doesn't return to the tab after dismissing the context menu. + // Since we're not testing that here, work around it by just focusing again. + tab1.focus(); + } + is(document.activeElement, tab1, "tab1 should be focused"); + + // Switch to tab2 by pressing DownArrow. + await BrowserTestUtils.switchTab(gBrowser, + () => EventUtils.synthesizeKey("KEY_ArrowDown")); + is(gBrowser.selectedTab, tab2, "should have switched to tab2"); + is(document.activeElement, tab2, "tab2 should now be focused"); + // Ensure that UpArrow doesn't switch to tab1 while the context menu is open. + await openContextMenu(); + EventUtils.synthesizeKey("KEY_ArrowUp"); + await closeContextMenu(); + is(gBrowser.selectedTab, tab2, "tab2 should still be active"); + + gBrowser.removeTab(tab2); +}); diff --git a/toolkit/content/widgets/tabbox.xml b/toolkit/content/widgets/tabbox.xml index 72ad869b9e66..3367b6bd44ac 100644 --- a/toolkit/content/widgets/tabbox.xml +++ b/toolkit/content/widgets/tabbox.xml @@ -538,39 +538,39 @@ ]]> - + - + - + - + - + - + Date: Tue, 4 Sep 2018 11:05:54 +0000 Subject: [PATCH 07/61] Bug 1484921 - [Wayland] Delay commit to hidden surfaces, r=jhorak WindowSurfaceWayland::Commit() request may be called before associated GdkWindow is fully mapped. In that case the commit fails because we can't commit to hidden wl_surface. This patch delays the commit until the GdkWindow is fully visible and associated wl_surface is ready. Differential Revision: https://phabricator.services.mozilla.com/D3961 --HG-- extra : moz-landing-system : lando --- widget/gtk/WindowSurfaceWayland.cpp | 263 +++++++++++++++++----------- widget/gtk/WindowSurfaceWayland.h | 22 ++- 2 files changed, 177 insertions(+), 108 deletions(-) diff --git a/widget/gtk/WindowSurfaceWayland.cpp b/widget/gtk/WindowSurfaceWayland.cpp index 39b370520e60..fbb722277d09 100644 --- a/widget/gtk/WindowSurfaceWayland.cpp +++ b/widget/gtk/WindowSurfaceWayland.cpp @@ -524,7 +524,7 @@ WindowBackBuffer::Detach() } bool -WindowBackBuffer::SetImageDataFromBackBuffer( +WindowBackBuffer::SetImageDataFromBuffer( class WindowBackBuffer* aSourceBuffer) { if (!IsMatchingSize(aSourceBuffer)) { @@ -562,27 +562,39 @@ static const struct wl_callback_listener frame_listener = { WindowSurfaceWayland::WindowSurfaceWayland(nsWindow *aWindow) : mWindow(aWindow) , mWaylandDisplay(WaylandDisplayGet(aWindow->GetWaylandDisplay())) - , mFrontBuffer(nullptr) - , mBackBuffer(nullptr) + , mWaylandBuffer(nullptr) + , mBackupBuffer(nullptr) , mFrameCallback(nullptr) , mFrameCallbackSurface(nullptr) , mDisplayThreadMessageLoop(MessageLoop::current()) - , mDirectWlBufferDraw(true) - , mDelayedCommit(false) - , mFullScreenDamage(false) + , mDelayedCommitHandle(nullptr) + , mDrawToWaylandBufferDirectly(true) + , mPendingCommit(false) + , mWaylandBufferFullScreenDamage(false) , mIsMainThread(NS_IsMainThread()) { } WindowSurfaceWayland::~WindowSurfaceWayland() { - delete mFrontBuffer; - delete mBackBuffer; + if (mPendingCommit) { + NS_WARNING("Deleted WindowSurfaceWayland with a pending commit!"); + } + + if (mDelayedCommitHandle) { + // Delete reference to this to prevent WaylandBufferDelayCommitHandler() + // operate on released this. mDelayedCommitHandle itself will + // be released at WaylandBufferDelayCommitHandler(). + *mDelayedCommitHandle = nullptr; + } if (mFrameCallback) { wl_callback_destroy(mFrameCallback); } + delete mWaylandBuffer; + delete mBackupBuffer; + if (!mIsMainThread) { // We can be destroyed from main thread even though we was created/used // in compositor thread. We have to unref/delete WaylandDisplay in compositor @@ -600,69 +612,77 @@ void WindowSurfaceWayland::UpdateScaleFactor() { wl_surface* waylandSurface = mWindow->GetWaylandSurface(); - if (waylandSurface) { - wl_surface_set_buffer_scale(waylandSurface, mWindow->GdkScaleFactor()); + MOZ_ASSERT(waylandSurface, + "Missing Wayland wl_surface during wl_buffer switch!"); + if (!waylandSurface) { + // TODO: Set the scale factor properly later if we're missing wl_surface + // on wl_buffer request (Bug 1487763). + return; } + + wl_proxy_set_queue((struct wl_proxy *)waylandSurface, + mWaylandDisplay->GetEventQueue()); + wl_surface_set_buffer_scale(waylandSurface, mWindow->GdkScaleFactor()); } WindowBackBuffer* -WindowSurfaceWayland::GetFrontBufferToDraw(int aWidth, int aHeight) +WindowSurfaceWayland::GetWaylandBufferToDraw(int aWidth, int aHeight) { - if (!mFrontBuffer) { - mFrontBuffer = new WindowBackBuffer(mWaylandDisplay, aWidth, aHeight); - mBackBuffer = new WindowBackBuffer(mWaylandDisplay, aWidth, aHeight); - return mFrontBuffer; + if (!mWaylandBuffer) { + mWaylandBuffer = new WindowBackBuffer(mWaylandDisplay, aWidth, aHeight); + mBackupBuffer = new WindowBackBuffer(mWaylandDisplay, aWidth, aHeight); + return mWaylandBuffer; } - if (!mFrontBuffer->IsAttached()) { - if (!mFrontBuffer->IsMatchingSize(aWidth, aHeight)) { - mFrontBuffer->Resize(aWidth, aHeight); + if (!mWaylandBuffer->IsAttached()) { + if (!mWaylandBuffer->IsMatchingSize(aWidth, aHeight)) { + mWaylandBuffer->Resize(aWidth, aHeight); // There's a chance that scale factor has been changed // when buffer size changed UpdateScaleFactor(); } - return mFrontBuffer; + return mWaylandBuffer; } // Front buffer is used by compositor, draw to back buffer - if (mBackBuffer->IsAttached()) { + if (mBackupBuffer->IsAttached()) { NS_WARNING("No drawing buffer available"); return nullptr; } - MOZ_ASSERT(!mDelayedCommit, + MOZ_ASSERT(!mPendingCommit, "Uncommitted buffer switch, screen artifacts ahead."); - WindowBackBuffer *tmp = mFrontBuffer; - mFrontBuffer = mBackBuffer; - mBackBuffer = tmp; + WindowBackBuffer *tmp = mWaylandBuffer; + mWaylandBuffer = mBackupBuffer; + mBackupBuffer = tmp; - if (mBackBuffer->IsMatchingSize(aWidth, aHeight)) { + if (mBackupBuffer->IsMatchingSize(aWidth, aHeight)) { // Former front buffer has the same size as a requested one. // Gecko may expect a content already drawn on screen so copy // existing data to the new buffer. - mFrontBuffer->SetImageDataFromBackBuffer(mBackBuffer); + mWaylandBuffer->SetImageDataFromBuffer(mBackupBuffer); // When buffer switches we need to damage whole screen // (https://bugzilla.redhat.com/show_bug.cgi?id=1418260) - mFullScreenDamage = true; + mWaylandBufferFullScreenDamage = true; } else { // Former buffer has different size from the new request. Only resize // the new buffer and leave gecko to render new whole content. - mFrontBuffer->Resize(aWidth, aHeight); + mWaylandBuffer->Resize(aWidth, aHeight); } - return mFrontBuffer; + return mWaylandBuffer; } already_AddRefed -WindowSurfaceWayland::LockFrontBuffer(int aWidth, int aHeight) +WindowSurfaceWayland::LockWaylandBuffer(int aWidth, int aHeight) { - WindowBackBuffer* buffer = GetFrontBufferToDraw(aWidth, aHeight); + WindowBackBuffer* buffer = GetWaylandBufferToDraw(aWidth, aHeight); if (buffer) { return buffer->Lock(); } - NS_WARNING("WindowSurfaceWayland::LockFrontBuffer(): No buffer available"); + NS_WARNING("WindowSurfaceWayland::LockWaylandBuffer(): No buffer available"); return nullptr; } @@ -690,8 +710,8 @@ WindowSurfaceWayland::LockImageSurface(const gfx::IntSize& aLockSize) A) Lock() is called to whole surface. In that case we don't need to clip/buffer the drawing and we can return wl_buffer directly for drawing. - - mFrontBuffer is available - that's an ideal situation. - - mFrontBuffer is locked by compositor - flip buffers and draw. + - mWaylandBuffer is available - that's an ideal situation. + - mWaylandBuffer is locked by compositor - flip buffers and draw. - if we can't flip buffers - go B) B) Lock() is requested for part(s) of screen. We need to provide temporary @@ -707,30 +727,30 @@ WindowSurfaceWayland::Lock(const LayoutDeviceIntRegion& aRegion) gfx::IntSize lockSize(bounds.XMost(), bounds.YMost()); // Are we asked for entire nsWindow to draw? - mDirectWlBufferDraw = (aRegion.GetNumRects() == 1 && - bounds.x == 0 && bounds.y == 0 && - lockSize.width == screenRect.width && - lockSize.height == screenRect.height); + mDrawToWaylandBufferDirectly = (aRegion.GetNumRects() == 1 && + bounds.x == 0 && bounds.y == 0 && + lockSize.width == screenRect.width && + lockSize.height == screenRect.height); - if (mDirectWlBufferDraw) { - RefPtr dt = LockFrontBuffer(screenRect.width, - screenRect.height); + if (mDrawToWaylandBufferDirectly) { + RefPtr dt = LockWaylandBuffer(screenRect.width, + screenRect.height); if (dt) { return dt.forget(); } // We don't have any front buffer available. Try indirect drawing // to mImageSurface which is mirrored to front buffer at commit. - mDirectWlBufferDraw = false; + mDrawToWaylandBufferDirectly = false; } return LockImageSurface(lockSize); } bool -WindowSurfaceWayland::CommitImageSurface(const LayoutDeviceIntRegion& aRegion) +WindowSurfaceWayland::CommitImageSurfaceToWaylandBuffer(const LayoutDeviceIntRegion& aRegion) { - MOZ_ASSERT(!mDirectWlBufferDraw); + MOZ_ASSERT(!mDrawToWaylandBufferDirectly); LayoutDeviceIntRect screenRect = mWindow->GetBounds(); gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect(); @@ -740,8 +760,8 @@ WindowSurfaceWayland::CommitImageSurface(const LayoutDeviceIntRegion& aRegion) return false; } - RefPtr dt = LockFrontBuffer(screenRect.width, - screenRect.height); + RefPtr dt = LockWaylandBuffer(screenRect.width, + screenRect.height); RefPtr surf = gfx::Factory::CreateSourceSurfaceForCairoSurface(mImageSurface->CairoSurface(), mImageSurface->GetSize(), @@ -769,32 +789,70 @@ WindowSurfaceWayland::CommitImageSurface(const LayoutDeviceIntRegion& aRegion) return true; } -void -WindowSurfaceWayland::Commit(const LayoutDeviceIntRegion& aInvalidRegion) +static void +WaylandBufferDelayCommitHandler(WindowSurfaceWayland **aSurface) { - MOZ_ASSERT(mIsMainThread == NS_IsMainThread()); + if (*aSurface) { + (*aSurface)->DelayedCommitHandler(); + } else { + // Referenced WindowSurfaceWayland is already deleted. + // Do nothing but just release the mDelayedCommitHandle allocated at + // WindowSurfaceWayland::CommitWaylandBuffer(). + free(aSurface); + } +} + +void +WindowSurfaceWayland::CommitWaylandBuffer() +{ + MOZ_ASSERT(mPendingCommit, "Committing empty surface!"); wl_surface* waylandSurface = mWindow->GetWaylandSurface(); if (!waylandSurface) { - // Target window is already destroyed - don't bother to render there. - NS_WARNING("WindowSurfaceWayland::Commit(): parent wl_surface is already hidden/deleted."); + // Target window is not created yet - delay the commit. This can happen only + // when the window is newly created and there's no active + // frame callback pending. + MOZ_ASSERT(!mFrameCallback || waylandSurface != mFrameCallbackSurface, + "Missing wayland surface at frame callback!"); + + // Do nothing if there's already mDelayedCommitHandle pending. + if (!mDelayedCommitHandle) { + mDelayedCommitHandle = static_cast( + moz_xmalloc(sizeof(*mDelayedCommitHandle))); + *mDelayedCommitHandle = this; + + MessageLoop::current()->PostDelayedTask( + NewRunnableFunction("WaylandBackBufferCommit", + &WaylandBufferDelayCommitHandler, + mDelayedCommitHandle), + EVENT_LOOP_DELAY); + } return; } wl_proxy_set_queue((struct wl_proxy *)waylandSurface, mWaylandDisplay->GetEventQueue()); - if (!mDirectWlBufferDraw) { - // We have new content at mImageSurface - copy data to mFrontBuffer first. - CommitImageSurface(aInvalidRegion); + // We have an active frame callback request so handle it. + if (mFrameCallback) { + if (waylandSurface == mFrameCallbackSurface) { + // We have an active frame callback pending from our recent surface. + // It means we should defer the commit to FrameCallbackHandler(). + return; + } + // If our stored wl_surface does not match the actual one it means the frame + // callback is no longer active and we should release it. + wl_callback_destroy(mFrameCallback); + mFrameCallback = nullptr; + mFrameCallbackSurface = nullptr; } - if (mFullScreenDamage) { + if (mWaylandBufferFullScreenDamage) { LayoutDeviceIntRect rect = mWindow->GetBounds(); wl_surface_damage(waylandSurface, 0, 0, rect.width, rect.height); - mFullScreenDamage = false; + mWaylandBufferFullScreenDamage = false; } else { gint scaleFactor = mWindow->GdkScaleFactor(); - for (auto iter = aInvalidRegion.RectIter(); !iter.Done(); iter.Next()) { + for (auto iter = mWaylandBufferDamage.RectIter(); !iter.Done(); iter.Next()) { const mozilla::LayoutDeviceIntRect &r = iter.Get(); // We need to remove the scale factor because the wl_surface_damage // also multiplies by current scale factor. @@ -803,62 +861,69 @@ WindowSurfaceWayland::Commit(const LayoutDeviceIntRegion& aInvalidRegion) } } - // Frame callback is always connected to actual wl_surface. When the surface - // is unmapped/deleted the frame callback is never called. Unfortunatelly - // we don't know if the frame callback is not going to be called. - // But our mozcontainer code deletes wl_surface when the GdkWindow is hidden - // creates a new one when is visible. - if (mFrameCallback && mFrameCallbackSurface == waylandSurface) { - // Do nothing here - we have a valid wl_surface and the buffer will be - // commited to compositor in next frame callback event. - mDelayedCommit = true; - return; - } else { - if (mFrameCallback) { - // Delete frame callback connected to obsoleted wl_surface. - wl_callback_destroy(mFrameCallback); - } + // Clear all back buffer damage as we're committing + // all requested regions. + mWaylandBufferDamage.SetEmpty(); - mFrameCallback = wl_surface_frame(waylandSurface); - wl_callback_add_listener(mFrameCallback, &frame_listener, this); - mFrameCallbackSurface = waylandSurface; + mFrameCallback = wl_surface_frame(waylandSurface); + wl_callback_add_listener(mFrameCallback, &frame_listener, this); + mFrameCallbackSurface = waylandSurface; - // There's no pending frame callback so we can draw immediately - // and create frame callback for possible subsequent drawing. - mFrontBuffer->Attach(waylandSurface); - mDelayedCommit = false; + mWaylandBuffer->Attach(waylandSurface); + + // There's no pending commit, all changes are sent to compositor. + mPendingCommit = false; +} + +void +WindowSurfaceWayland::Commit(const LayoutDeviceIntRegion& aInvalidRegion) +{ + MOZ_ASSERT(mIsMainThread == NS_IsMainThread()); + + // We have new content at mImageSurface - copy data to mWaylandBuffer first. + if (!mDrawToWaylandBufferDirectly) { + CommitImageSurfaceToWaylandBuffer(aInvalidRegion); } + + // If we're not at fullscreen damage add drawing area from aInvalidRegion + if (!mWaylandBufferFullScreenDamage) { + mWaylandBufferDamage.OrWith(aInvalidRegion); + } + + // We're ready to commit. + mPendingCommit = true; + CommitWaylandBuffer(); } void WindowSurfaceWayland::FrameCallbackHandler() { MOZ_ASSERT(mIsMainThread == NS_IsMainThread()); + MOZ_ASSERT(mFrameCallback != nullptr, + "FrameCallbackHandler() called without valid frame callback!"); + MOZ_ASSERT(mFrameCallbackSurface != nullptr, + "FrameCallbackHandler() called without valid wl_surface!"); - if (mFrameCallback) { - wl_callback_destroy(mFrameCallback); - mFrameCallback = nullptr; - mFrameCallbackSurface = nullptr; + wl_callback_destroy(mFrameCallback); + mFrameCallback = nullptr; + mFrameCallbackSurface = nullptr; + + if (mPendingCommit) { + CommitWaylandBuffer(); } +} - if (mDelayedCommit) { - wl_surface* waylandSurface = mWindow->GetWaylandSurface(); - if (!waylandSurface) { - // Target window is already destroyed - don't bother to render there. - NS_WARNING("WindowSurfaceWayland::FrameCallbackHandler(): parent wl_surface is already hidden/deleted."); - return; - } - wl_proxy_set_queue((struct wl_proxy *)waylandSurface, - mWaylandDisplay->GetEventQueue()); +void +WindowSurfaceWayland::DelayedCommitHandler() +{ + MOZ_ASSERT(mDelayedCommitHandle != nullptr, "Missing mDelayedCommitHandle!"); - // Send pending surface to compositor and register frame callback - // for possible subsequent drawing. - mFrameCallback = wl_surface_frame(waylandSurface); - wl_callback_add_listener(mFrameCallback, &frame_listener, this); - mFrameCallbackSurface = waylandSurface; + *mDelayedCommitHandle = nullptr; + free(mDelayedCommitHandle); + mDelayedCommitHandle = nullptr; - mFrontBuffer->Attach(waylandSurface); - mDelayedCommit = false; + if (mPendingCommit) { + CommitWaylandBuffer(); } } diff --git a/widget/gtk/WindowSurfaceWayland.h b/widget/gtk/WindowSurfaceWayland.h index ff7c6711b615..d42e413ce241 100644 --- a/widget/gtk/WindowSurfaceWayland.h +++ b/widget/gtk/WindowSurfaceWayland.h @@ -74,7 +74,7 @@ public: bool IsAttached() { return mAttached; } bool Resize(int aWidth, int aHeight); - bool SetImageDataFromBackBuffer(class WindowBackBuffer* aSourceBuffer); + bool SetImageDataFromBuffer(class WindowBackBuffer* aSourceBuffer); bool IsMatchingSize(int aWidth, int aHeight) { @@ -111,27 +111,31 @@ public: already_AddRefed Lock(const LayoutDeviceIntRegion& aRegion) override; void Commit(const LayoutDeviceIntRegion& aInvalidRegion) final; void FrameCallbackHandler(); + void DelayedCommitHandler(); private: - WindowBackBuffer* GetFrontBufferToDraw(int aWidth, int aHeight); + WindowBackBuffer* GetWaylandBufferToDraw(int aWidth, int aHeight); void UpdateScaleFactor(); - already_AddRefed LockFrontBuffer(int aWidth, int aHeight); + already_AddRefed LockWaylandBuffer(int aWidth, int aHeight); already_AddRefed LockImageSurface(const gfx::IntSize& aLockSize); - bool CommitImageSurface(const LayoutDeviceIntRegion& aRegion); + bool CommitImageSurfaceToWaylandBuffer(const LayoutDeviceIntRegion& aRegion); + void CommitWaylandBuffer(); // TODO: Do we need to hold a reference to nsWindow object? nsWindow* mWindow; nsWaylandDisplay* mWaylandDisplay; - WindowBackBuffer* mFrontBuffer; - WindowBackBuffer* mBackBuffer; + WindowBackBuffer* mWaylandBuffer; + LayoutDeviceIntRegion mWaylandBufferDamage; + WindowBackBuffer* mBackupBuffer; RefPtr mImageSurface; wl_callback* mFrameCallback; wl_surface* mFrameCallbackSurface; MessageLoop* mDisplayThreadMessageLoop; - bool mDirectWlBufferDraw; - bool mDelayedCommit; - bool mFullScreenDamage; + WindowSurfaceWayland** mDelayedCommitHandle; + bool mDrawToWaylandBufferDirectly; + bool mPendingCommit; + bool mWaylandBufferFullScreenDamage; bool mIsMainThread; }; From dff40a3357c57b317378886107edcb75709c8e2a Mon Sep 17 00:00:00 2001 From: Tim Nguyen Date: Tue, 4 Sep 2018 11:42:13 +0000 Subject: [PATCH 08/61] Bug 1488118 - Fix sidebar border color when it's on the right. r=dao Differential Revision: https://phabricator.services.mozilla.com/D4837 --HG-- extra : moz-landing-system : lando --- browser/themes/shared/sidebar.inc.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/themes/shared/sidebar.inc.css b/browser/themes/shared/sidebar.inc.css index 32b3be49864b..48be552cc7a9 100644 --- a/browser/themes/shared/sidebar.inc.css +++ b/browser/themes/shared/sidebar.inc.css @@ -26,7 +26,7 @@ -moz-appearance: none; border: 0 solid; border-inline-end-width: 1px; - border-inline-end-color: var(--sidebar-border-color); + border-color: var(--sidebar-border-color); min-width: 1px; width: 4px; background-image: none !important; From 21e439aacfb9565b9963b5367115ac44052f0268 Mon Sep 17 00:00:00 2001 From: Rob Wu Date: Tue, 4 Sep 2018 12:12:01 +0000 Subject: [PATCH 09/61] Bug 1462121 - Improve reliability of context.contentWindow/active r=zombie - Register pagehide/pageshow events in the system group and ignore synthetic events to avoid interference from web pages. - Remove unused docShell member. - Fix memory leak in bfcached windows, by ensuring that BaseContext instances can be GC'd when an extension is unloaded, even if the context is associated with a page in the bfcache. - Ensure that context.contentWindow and context.active always have an accurate value. The latter is achieved by moving all contentWindow tracking logic in a new helper class "InnerWindowReference". Differential Revision: https://phabricator.services.mozilla.com/D4072 --HG-- extra : moz-landing-system : lando --- .../components/extensions/ExtensionCommon.jsm | 99 ++++++++---- .../test_ext_contentscript_context.js | 143 +++++++++++++++++- ...est_ext_contentscript_context_isolation.js | 123 +++++++++++++++ .../test/xpcshell/xpcshell-common.ini | 2 + 4 files changed, 334 insertions(+), 33 deletions(-) create mode 100644 toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context_isolation.js diff --git a/toolkit/components/extensions/ExtensionCommon.jsm b/toolkit/components/extensions/ExtensionCommon.jsm index f0a84395b6e3..57344c649789 100644 --- a/toolkit/components/extensions/ExtensionCommon.jsm +++ b/toolkit/components/extensions/ExtensionCommon.jsm @@ -353,6 +353,55 @@ class ExtensionAPI extends EventEmitter { } } +/** + * A wrapper around a window that returns the window iff the inner window + * matches the inner window at the construction of this wrapper. + * + * This wrapper should not be used after the inner window is destroyed. + **/ +class InnerWindowReference { + constructor(contentWindow, innerWindowID) { + this.contentWindow = contentWindow; + this.innerWindowID = innerWindowID; + this.needWindowIDCheck = false; + + contentWindow.addEventListener("pagehide", this, {mozSystemGroup: true}, false); + contentWindow.addEventListener("pageshow", this, {mozSystemGroup: true}, false); + } + + get() { + // If the pagehide event has fired, the inner window ID needs to be checked, + // in case the window ref is dereferenced in a pageshow listener (before our + // pageshow listener was dispatched) or during the unload event. + if (!this.needWindowIDCheck || getInnerWindowID(this.contentWindow) === this.innerWindowID) { + return this.contentWindow; + } + return null; + } + + invalidate() { + // If invalidate() is called while the inner window is in the bfcache, then + // we are unable to remove the event listener, and handleEvent will be + // called once more if the page is revived from the bfcache. + if (this.contentWindow) { + this.contentWindow.removeEventListener("pagehide", this, {mozSystemGroup: true}); + this.contentWindow.removeEventListener("pageshow", this, {mozSystemGroup: true}); + } + this.contentWindow = null; + this.needWindowIDCheck = false; + } + + handleEvent(event) { + if (this.contentWindow) { + this.needWindowIDCheck = event.type === "pagehide"; + } else { + // Remove listener when restoring from the bfcache - see invalidate(). + event.currentTarget.removeEventListener("pagehide", this, {mozSystemGroup: true}); + event.currentTarget.removeEventListener("pageshow", this, {mozSystemGroup: true}); + } + } +} + /** * This class contains the information we have about an individual * extension. It is never instantiated directly, instead subclasses @@ -373,16 +422,13 @@ class BaseContext { this.active = true; this.incognito = null; this.messageManager = null; - this.docShell = null; this.contentWindow = null; this.innerWindowID = 0; } setContentWindow(contentWindow) { - let {document, docShell} = contentWindow; - this.innerWindowID = getInnerWindowID(contentWindow); - this.messageManager = docShell.messageManager; + this.messageManager = contentWindow.docShell.messageManager; if (this.incognito == null) { this.incognito = PrivateBrowsingUtils.isContentWindowPrivate(contentWindow); @@ -390,34 +436,26 @@ class BaseContext { MessageChannel.setupMessageManagers([this.messageManager]); - let onPageShow = event => { - if (!event || event.target === document) { - this.docShell = docShell; - this.contentWindow = contentWindow; - this.active = true; - } - }; - let onPageHide = event => { - if (!event || event.target === document) { - // Put this off until the next tick. - Promise.resolve().then(() => { - this.docShell = null; - this.contentWindow = null; - this.active = false; - }); - } - }; - - onPageShow(); - contentWindow.addEventListener("pagehide", onPageHide, true); - contentWindow.addEventListener("pageshow", onPageShow, true); + let windowRef = new InnerWindowReference(contentWindow, this.innerWindowID); + Object.defineProperty(this, "active", { + configurable: true, + enumerable: true, + get: () => windowRef.get() !== null, + }); + Object.defineProperty(this, "contentWindow", { + configurable: true, + enumerable: true, + get: () => windowRef.get(), + }); this.callOnClose({ close: () => { - onPageHide(); - if (this.active) { - contentWindow.removeEventListener("pagehide", onPageHide, true); - contentWindow.removeEventListener("pageshow", onPageShow, true); - } + // Allow other "close" handlers to use these properties, until the next tick. + Promise.resolve().then(() => { + windowRef.invalidate(); + windowRef = null; + Object.defineProperty(this, "contentWindow", {value: null}); + Object.defineProperty(this, "active", {value: false}); + }); }, }); } @@ -732,6 +770,7 @@ class BaseContext { for (let obj of this.onClose) { obj.close(); } + this.onClose.clear(); } /** diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context.js b/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context.js index d7e161ee4da0..d2e81c3d8cd9 100644 --- a/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context.js +++ b/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context.js @@ -10,7 +10,7 @@ server.registerPathHandler("/dummy", (request, response) => { response.write(""); }); -add_task(async function test_contentscript_context() { +function loadExtension() { function contentScript() { browser.test.sendMessage("content-script-ready"); @@ -22,10 +22,10 @@ add_task(async function test_contentscript_context() { }); } - let extension = ExtensionTestUtils.loadExtension({ + return ExtensionTestUtils.loadExtension({ manifest: { content_scripts: [{ - "matches": ["http://example.com/dummy"], + "matches": ["http://example.com/dummy*"], "js": ["content_script.js"], "run_at": "document_start", }], @@ -35,7 +35,10 @@ add_task(async function test_contentscript_context() { "content_script.js": contentScript, }, }); +} +add_task(async function test_contentscript_context() { + let extension = loadExtension(); await extension.startup(); let contentPage = await ExtensionTestUtils.loadContentPage("http://example.com/dummy"); @@ -75,3 +78,137 @@ add_task(async function test_contentscript_context() { await extension.awaitMessage("content-script-hide"); await extension.unload(); }); + +add_task(async function test_contentscript_context_unload_while_in_bfcache() { + let contentPage = await ExtensionTestUtils.loadContentPage("http://example.com/dummy?first"); + let extension = loadExtension(); + await extension.startup(); + await extension.awaitMessage("content-script-ready"); + + // Get the content script context and check that it points to the correct window. + await contentPage.spawn(extension.id, async extensionId => { + let {DocumentManager} = ChromeUtils.import("resource://gre/modules/ExtensionContent.jsm", {}); + // Save context so we can verify that contentWindow is nulled after unload. + this.context = DocumentManager.getContext(extensionId, this.content); + + Assert.equal(this.context.contentWindow, this.content, "Context's contentWindow property is correct"); + + this.contextUnloadedPromise = new Promise(resolve => { + this.context.callOnClose({close: resolve}); + }); + this.pageshownPromise = new Promise(resolve => { + this.content.addEventListener("pageshow", () => { + // Yield to the event loop once more to ensure that all pageshow event + // handlers have been dispatched before fulfilling the promise. + let {setTimeout} = ChromeUtils.import("resource://gre/modules/Timer.jsm", {}); + setTimeout(resolve, 0); + }, {once: true, mozSystemGroup: true}); + }); + + // Navigate so that the content page is hidden in the bfcache. + this.content.location = "http://example.org/dummy?second"; + }); + + await extension.awaitMessage("content-script-hide"); + + await extension.unload(); + await contentPage.spawn(null, async () => { + await this.contextUnloadedPromise; + Assert.equal(this.context.unloaded, true, "Context has been unloaded"); + + // Normally, when a page is not in the bfcache, context.contentWindow is + // not null when the callOnClose handler is invoked (this is checked by the + // previous subtest). + // Now wait a little bit and check again to ensure that the contentWindow + // property is not somehow restored. + await new Promise(resolve => this.content.setTimeout(resolve, 0)); + Assert.equal(this.context.contentWindow, null, "Context's contentWindow property is null"); + + // Navigate back so the content page is resurrected from the bfcache. + this.content.history.back(); + + await this.pageshownPromise; + + Assert.equal(this.context.contentWindow, null, "Context's contentWindow property is null after restore from bfcache"); + }); + + await contentPage.close(); +}); + +add_task(async function test_contentscript_context_valid_during_execution() { + // This test does the following: + // - Load page + // - Load extension; inject content script. + // - Navigate page; pagehide triggered. + // - Navigate back; pageshow triggered. + // - Close page; pagehide, unload triggered. + // At each of these last four events, the validity of the context is checked. + + function contentScript() { + browser.test.sendMessage("content-script-ready"); + window.wrappedJSObject.checkContextIsValid("Context is valid on execution"); + + window.addEventListener("pagehide", () => { + window.wrappedJSObject.checkContextIsValid("Context is valid on pagehide"); + browser.test.sendMessage("content-script-hide"); + }, true); + window.addEventListener("pageshow", () => { + window.wrappedJSObject.checkContextIsValid("Context is valid on pageshow"); + + // This unload listener is registered after pageshow, to ensure that the + // page can be stored in the bfcache at the previous pagehide. + window.addEventListener("unload", () => { + window.wrappedJSObject.checkContextIsValid("Context is valid on unload"); + browser.test.sendMessage("content-script-unload"); + }); + + browser.test.sendMessage("content-script-show"); + }); + } + + let extension = ExtensionTestUtils.loadExtension({ + manifest: { + content_scripts: [{ + "matches": ["http://example.com/dummy*"], + "js": ["content_script.js"], + }], + }, + + files: { + "content_script.js": contentScript, + }, + }); + + let contentPage = await ExtensionTestUtils.loadContentPage("http://example.com/dummy?first"); + await contentPage.spawn(extension.id, async extensionId => { + let context; + let checkContextIsValid = (description) => { + if (!context) { + let {DocumentManager} = ChromeUtils.import("resource://gre/modules/ExtensionContent.jsm", {}); + context = DocumentManager.getContext(extensionId, this.content); + } + Assert.equal(context.contentWindow, this.content, `${description}: contentWindow`); + Assert.equal(context.active, true, `${description}: active`); + }; + Cu.exportFunction(checkContextIsValid, this.content, {defineAs: "checkContextIsValid"}); + }); + await extension.startup(); + await extension.awaitMessage("content-script-ready"); + + await contentPage.spawn(extension.id, async extensionId => { + // Navigate so that the content page is frozen in the bfcache. + this.content.location = "http://example.org/dummy?second"; + }); + + await extension.awaitMessage("content-script-hide"); + await contentPage.spawn(null, async () => { + // Navigate back so the content page is resurrected from the bfcache. + this.content.history.back(); + }); + + await extension.awaitMessage("content-script-show"); + await contentPage.close(); + await extension.awaitMessage("content-script-hide"); + await extension.awaitMessage("content-script-unload"); + await extension.unload(); +}); diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context_isolation.js b/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context_isolation.js new file mode 100644 index 000000000000..6f81730d66a2 --- /dev/null +++ b/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context_isolation.js @@ -0,0 +1,123 @@ +"use strict"; + +/* globals exportFunction */ +/* eslint-disable mozilla/balanced-listeners */ + +const server = createHttpServer({hosts: ["example.com", "example.org"]}); + +server.registerPathHandler("/dummy", (request, response) => { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "text/html", false); + response.write(""); +}); + +server.registerPathHandler("/bfcachetestpage", (request, response) => { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "text/html;charset=utf-8", false); + response.write(` +`); +}); + +add_task(async function test_contentscript_context_isolation() { + function contentScript() { + browser.test.sendMessage("content-script-ready"); + + exportFunction(browser.test.sendMessage, window, {defineAs: "browserTestSendMessage"}); + + window.addEventListener("pageshow", () => { + browser.test.fail("pageshow should have been suppressed by stopImmediatePropagation"); + }); + window.addEventListener("pagehide", () => { + browser.test.fail("pagehide should have been suppressed by stopImmediatePropagation"); + }, true); + } + + let extension = ExtensionTestUtils.loadExtension({ + manifest: { + content_scripts: [{ + "matches": ["http://example.com/bfcachetestpage"], + "js": ["content_script.js"], + }], + }, + + files: { + "content_script.js": contentScript, + }, + }); + + let contentPage = await ExtensionTestUtils.loadContentPage("http://example.com/bfcachetestpage"); + await extension.startup(); + await extension.awaitMessage("content-script-ready"); + + // Get the content script context and check that it points to the correct window. + await contentPage.spawn(extension.id, async extensionId => { + let {DocumentManager} = ChromeUtils.import("resource://gre/modules/ExtensionContent.jsm", {}); + this.context = DocumentManager.getContext(extensionId, this.content); + + Assert.ok(this.context, "Got content script context"); + + Assert.equal(this.context.contentWindow, this.content, "Context's contentWindow property is correct"); + + // Navigate so that the content page is hidden in the bfcache. + + this.content.location = "http://example.org/dummy?noscripthere1"; + }); + + await extension.awaitMessage("content-script-hide"); + + await contentPage.spawn(null, async () => { + Assert.equal(this.context.contentWindow, null, "Context's contentWindow property is null"); + Assert.ok(this.context.sandbox, "Context's sandbox exists"); + + // Navigate back so the content page is resurrected from the bfcache. + this.content.history.back(); + }); + + await extension.awaitMessage("content-script-show"); + + await contentPage.spawn(null, async () => { + Assert.equal(this.context.contentWindow, this.content, "Context's contentWindow property is correct"); + Assert.ok(this.context.sandbox, "Context's sandbox exists before unload"); + + let contextUnloadedPromise = new Promise(resolve => { + this.context.callOnClose({close: resolve}); + }); + + // Now add an "unload" event listener, which should prevent a page from entering the bfcache. + await new Promise((resolve) => { + this.content.addEventListener("unload", () => { + Assert.equal(this.context.contentWindow, this.content, "Context's contentWindow property should be non-null at unload"); + resolve(); + }); + this.content.location = "http://example.org/dummy?noscripthere2"; + }); + + await contextUnloadedPromise; + }); + + await extension.awaitMessage("content-script-unload"); + + await contentPage.spawn(null, async () => { + Assert.equal(this.context.sandbox, null, "Context's sandbox has been destroyed after unload"); + }); + + await contentPage.close(); + await extension.unload(); +}); diff --git a/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini b/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini index 4f3604138ceb..f0d69c6ecbb0 100644 --- a/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini +++ b/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini @@ -25,6 +25,7 @@ skip-if = appname == "thunderbird" || os == "android" [test_ext_contentscript_async_loading.js] skip-if = os == 'android' && debug # The generated script takes too long to load on Android debug [test_ext_contentscript_context.js] +[test_ext_contentscript_context_isolation.js] [test_ext_contentscript_create_iframe.js] [test_ext_contentscript_css.js] [test_ext_contentscript_exporthelpers.js] @@ -53,6 +54,7 @@ fail-if = appname == "thunderbird" [test_ext_extensionSettingsStore.js] [test_ext_extension_content_telemetry.js] skip-if = os == "android" # checking for telemetry needs to be updated: 1384923 +[test_ext_extension_page_context.js] [test_ext_extension_startup_telemetry.js] [test_ext_geturl.js] [test_ext_idle.js] From 8f250956ce7bd3adeae9528c516d921fa0482be6 Mon Sep 17 00:00:00 2001 From: Margareta Eliza Balazs Date: Tue, 4 Sep 2018 15:26:45 +0300 Subject: [PATCH 10/61] Backed out changeset e31d944d504b (bug 1462121) for mozbuild bustage in /builds/worker/workspace/build/src/toolkit/components/extensions/moz.build CLOSED TREE --- .../components/extensions/ExtensionCommon.jsm | 99 ++++-------- .../test_ext_contentscript_context.js | 143 +----------------- ...est_ext_contentscript_context_isolation.js | 123 --------------- .../test/xpcshell/xpcshell-common.ini | 2 - 4 files changed, 33 insertions(+), 334 deletions(-) delete mode 100644 toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context_isolation.js diff --git a/toolkit/components/extensions/ExtensionCommon.jsm b/toolkit/components/extensions/ExtensionCommon.jsm index 57344c649789..f0a84395b6e3 100644 --- a/toolkit/components/extensions/ExtensionCommon.jsm +++ b/toolkit/components/extensions/ExtensionCommon.jsm @@ -353,55 +353,6 @@ class ExtensionAPI extends EventEmitter { } } -/** - * A wrapper around a window that returns the window iff the inner window - * matches the inner window at the construction of this wrapper. - * - * This wrapper should not be used after the inner window is destroyed. - **/ -class InnerWindowReference { - constructor(contentWindow, innerWindowID) { - this.contentWindow = contentWindow; - this.innerWindowID = innerWindowID; - this.needWindowIDCheck = false; - - contentWindow.addEventListener("pagehide", this, {mozSystemGroup: true}, false); - contentWindow.addEventListener("pageshow", this, {mozSystemGroup: true}, false); - } - - get() { - // If the pagehide event has fired, the inner window ID needs to be checked, - // in case the window ref is dereferenced in a pageshow listener (before our - // pageshow listener was dispatched) or during the unload event. - if (!this.needWindowIDCheck || getInnerWindowID(this.contentWindow) === this.innerWindowID) { - return this.contentWindow; - } - return null; - } - - invalidate() { - // If invalidate() is called while the inner window is in the bfcache, then - // we are unable to remove the event listener, and handleEvent will be - // called once more if the page is revived from the bfcache. - if (this.contentWindow) { - this.contentWindow.removeEventListener("pagehide", this, {mozSystemGroup: true}); - this.contentWindow.removeEventListener("pageshow", this, {mozSystemGroup: true}); - } - this.contentWindow = null; - this.needWindowIDCheck = false; - } - - handleEvent(event) { - if (this.contentWindow) { - this.needWindowIDCheck = event.type === "pagehide"; - } else { - // Remove listener when restoring from the bfcache - see invalidate(). - event.currentTarget.removeEventListener("pagehide", this, {mozSystemGroup: true}); - event.currentTarget.removeEventListener("pageshow", this, {mozSystemGroup: true}); - } - } -} - /** * This class contains the information we have about an individual * extension. It is never instantiated directly, instead subclasses @@ -422,13 +373,16 @@ class BaseContext { this.active = true; this.incognito = null; this.messageManager = null; + this.docShell = null; this.contentWindow = null; this.innerWindowID = 0; } setContentWindow(contentWindow) { + let {document, docShell} = contentWindow; + this.innerWindowID = getInnerWindowID(contentWindow); - this.messageManager = contentWindow.docShell.messageManager; + this.messageManager = docShell.messageManager; if (this.incognito == null) { this.incognito = PrivateBrowsingUtils.isContentWindowPrivate(contentWindow); @@ -436,26 +390,34 @@ class BaseContext { MessageChannel.setupMessageManagers([this.messageManager]); - let windowRef = new InnerWindowReference(contentWindow, this.innerWindowID); - Object.defineProperty(this, "active", { - configurable: true, - enumerable: true, - get: () => windowRef.get() !== null, - }); - Object.defineProperty(this, "contentWindow", { - configurable: true, - enumerable: true, - get: () => windowRef.get(), - }); + let onPageShow = event => { + if (!event || event.target === document) { + this.docShell = docShell; + this.contentWindow = contentWindow; + this.active = true; + } + }; + let onPageHide = event => { + if (!event || event.target === document) { + // Put this off until the next tick. + Promise.resolve().then(() => { + this.docShell = null; + this.contentWindow = null; + this.active = false; + }); + } + }; + + onPageShow(); + contentWindow.addEventListener("pagehide", onPageHide, true); + contentWindow.addEventListener("pageshow", onPageShow, true); this.callOnClose({ close: () => { - // Allow other "close" handlers to use these properties, until the next tick. - Promise.resolve().then(() => { - windowRef.invalidate(); - windowRef = null; - Object.defineProperty(this, "contentWindow", {value: null}); - Object.defineProperty(this, "active", {value: false}); - }); + onPageHide(); + if (this.active) { + contentWindow.removeEventListener("pagehide", onPageHide, true); + contentWindow.removeEventListener("pageshow", onPageShow, true); + } }, }); } @@ -770,7 +732,6 @@ class BaseContext { for (let obj of this.onClose) { obj.close(); } - this.onClose.clear(); } /** diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context.js b/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context.js index d2e81c3d8cd9..d7e161ee4da0 100644 --- a/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context.js +++ b/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context.js @@ -10,7 +10,7 @@ server.registerPathHandler("/dummy", (request, response) => { response.write(""); }); -function loadExtension() { +add_task(async function test_contentscript_context() { function contentScript() { browser.test.sendMessage("content-script-ready"); @@ -22,10 +22,10 @@ function loadExtension() { }); } - return ExtensionTestUtils.loadExtension({ + let extension = ExtensionTestUtils.loadExtension({ manifest: { content_scripts: [{ - "matches": ["http://example.com/dummy*"], + "matches": ["http://example.com/dummy"], "js": ["content_script.js"], "run_at": "document_start", }], @@ -35,10 +35,7 @@ function loadExtension() { "content_script.js": contentScript, }, }); -} -add_task(async function test_contentscript_context() { - let extension = loadExtension(); await extension.startup(); let contentPage = await ExtensionTestUtils.loadContentPage("http://example.com/dummy"); @@ -78,137 +75,3 @@ add_task(async function test_contentscript_context() { await extension.awaitMessage("content-script-hide"); await extension.unload(); }); - -add_task(async function test_contentscript_context_unload_while_in_bfcache() { - let contentPage = await ExtensionTestUtils.loadContentPage("http://example.com/dummy?first"); - let extension = loadExtension(); - await extension.startup(); - await extension.awaitMessage("content-script-ready"); - - // Get the content script context and check that it points to the correct window. - await contentPage.spawn(extension.id, async extensionId => { - let {DocumentManager} = ChromeUtils.import("resource://gre/modules/ExtensionContent.jsm", {}); - // Save context so we can verify that contentWindow is nulled after unload. - this.context = DocumentManager.getContext(extensionId, this.content); - - Assert.equal(this.context.contentWindow, this.content, "Context's contentWindow property is correct"); - - this.contextUnloadedPromise = new Promise(resolve => { - this.context.callOnClose({close: resolve}); - }); - this.pageshownPromise = new Promise(resolve => { - this.content.addEventListener("pageshow", () => { - // Yield to the event loop once more to ensure that all pageshow event - // handlers have been dispatched before fulfilling the promise. - let {setTimeout} = ChromeUtils.import("resource://gre/modules/Timer.jsm", {}); - setTimeout(resolve, 0); - }, {once: true, mozSystemGroup: true}); - }); - - // Navigate so that the content page is hidden in the bfcache. - this.content.location = "http://example.org/dummy?second"; - }); - - await extension.awaitMessage("content-script-hide"); - - await extension.unload(); - await contentPage.spawn(null, async () => { - await this.contextUnloadedPromise; - Assert.equal(this.context.unloaded, true, "Context has been unloaded"); - - // Normally, when a page is not in the bfcache, context.contentWindow is - // not null when the callOnClose handler is invoked (this is checked by the - // previous subtest). - // Now wait a little bit and check again to ensure that the contentWindow - // property is not somehow restored. - await new Promise(resolve => this.content.setTimeout(resolve, 0)); - Assert.equal(this.context.contentWindow, null, "Context's contentWindow property is null"); - - // Navigate back so the content page is resurrected from the bfcache. - this.content.history.back(); - - await this.pageshownPromise; - - Assert.equal(this.context.contentWindow, null, "Context's contentWindow property is null after restore from bfcache"); - }); - - await contentPage.close(); -}); - -add_task(async function test_contentscript_context_valid_during_execution() { - // This test does the following: - // - Load page - // - Load extension; inject content script. - // - Navigate page; pagehide triggered. - // - Navigate back; pageshow triggered. - // - Close page; pagehide, unload triggered. - // At each of these last four events, the validity of the context is checked. - - function contentScript() { - browser.test.sendMessage("content-script-ready"); - window.wrappedJSObject.checkContextIsValid("Context is valid on execution"); - - window.addEventListener("pagehide", () => { - window.wrappedJSObject.checkContextIsValid("Context is valid on pagehide"); - browser.test.sendMessage("content-script-hide"); - }, true); - window.addEventListener("pageshow", () => { - window.wrappedJSObject.checkContextIsValid("Context is valid on pageshow"); - - // This unload listener is registered after pageshow, to ensure that the - // page can be stored in the bfcache at the previous pagehide. - window.addEventListener("unload", () => { - window.wrappedJSObject.checkContextIsValid("Context is valid on unload"); - browser.test.sendMessage("content-script-unload"); - }); - - browser.test.sendMessage("content-script-show"); - }); - } - - let extension = ExtensionTestUtils.loadExtension({ - manifest: { - content_scripts: [{ - "matches": ["http://example.com/dummy*"], - "js": ["content_script.js"], - }], - }, - - files: { - "content_script.js": contentScript, - }, - }); - - let contentPage = await ExtensionTestUtils.loadContentPage("http://example.com/dummy?first"); - await contentPage.spawn(extension.id, async extensionId => { - let context; - let checkContextIsValid = (description) => { - if (!context) { - let {DocumentManager} = ChromeUtils.import("resource://gre/modules/ExtensionContent.jsm", {}); - context = DocumentManager.getContext(extensionId, this.content); - } - Assert.equal(context.contentWindow, this.content, `${description}: contentWindow`); - Assert.equal(context.active, true, `${description}: active`); - }; - Cu.exportFunction(checkContextIsValid, this.content, {defineAs: "checkContextIsValid"}); - }); - await extension.startup(); - await extension.awaitMessage("content-script-ready"); - - await contentPage.spawn(extension.id, async extensionId => { - // Navigate so that the content page is frozen in the bfcache. - this.content.location = "http://example.org/dummy?second"; - }); - - await extension.awaitMessage("content-script-hide"); - await contentPage.spawn(null, async () => { - // Navigate back so the content page is resurrected from the bfcache. - this.content.history.back(); - }); - - await extension.awaitMessage("content-script-show"); - await contentPage.close(); - await extension.awaitMessage("content-script-hide"); - await extension.awaitMessage("content-script-unload"); - await extension.unload(); -}); diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context_isolation.js b/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context_isolation.js deleted file mode 100644 index 6f81730d66a2..000000000000 --- a/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context_isolation.js +++ /dev/null @@ -1,123 +0,0 @@ -"use strict"; - -/* globals exportFunction */ -/* eslint-disable mozilla/balanced-listeners */ - -const server = createHttpServer({hosts: ["example.com", "example.org"]}); - -server.registerPathHandler("/dummy", (request, response) => { - response.setStatusLine(request.httpVersion, 200, "OK"); - response.setHeader("Content-Type", "text/html", false); - response.write(""); -}); - -server.registerPathHandler("/bfcachetestpage", (request, response) => { - response.setStatusLine(request.httpVersion, 200, "OK"); - response.setHeader("Content-Type", "text/html;charset=utf-8", false); - response.write(` -`); -}); - -add_task(async function test_contentscript_context_isolation() { - function contentScript() { - browser.test.sendMessage("content-script-ready"); - - exportFunction(browser.test.sendMessage, window, {defineAs: "browserTestSendMessage"}); - - window.addEventListener("pageshow", () => { - browser.test.fail("pageshow should have been suppressed by stopImmediatePropagation"); - }); - window.addEventListener("pagehide", () => { - browser.test.fail("pagehide should have been suppressed by stopImmediatePropagation"); - }, true); - } - - let extension = ExtensionTestUtils.loadExtension({ - manifest: { - content_scripts: [{ - "matches": ["http://example.com/bfcachetestpage"], - "js": ["content_script.js"], - }], - }, - - files: { - "content_script.js": contentScript, - }, - }); - - let contentPage = await ExtensionTestUtils.loadContentPage("http://example.com/bfcachetestpage"); - await extension.startup(); - await extension.awaitMessage("content-script-ready"); - - // Get the content script context and check that it points to the correct window. - await contentPage.spawn(extension.id, async extensionId => { - let {DocumentManager} = ChromeUtils.import("resource://gre/modules/ExtensionContent.jsm", {}); - this.context = DocumentManager.getContext(extensionId, this.content); - - Assert.ok(this.context, "Got content script context"); - - Assert.equal(this.context.contentWindow, this.content, "Context's contentWindow property is correct"); - - // Navigate so that the content page is hidden in the bfcache. - - this.content.location = "http://example.org/dummy?noscripthere1"; - }); - - await extension.awaitMessage("content-script-hide"); - - await contentPage.spawn(null, async () => { - Assert.equal(this.context.contentWindow, null, "Context's contentWindow property is null"); - Assert.ok(this.context.sandbox, "Context's sandbox exists"); - - // Navigate back so the content page is resurrected from the bfcache. - this.content.history.back(); - }); - - await extension.awaitMessage("content-script-show"); - - await contentPage.spawn(null, async () => { - Assert.equal(this.context.contentWindow, this.content, "Context's contentWindow property is correct"); - Assert.ok(this.context.sandbox, "Context's sandbox exists before unload"); - - let contextUnloadedPromise = new Promise(resolve => { - this.context.callOnClose({close: resolve}); - }); - - // Now add an "unload" event listener, which should prevent a page from entering the bfcache. - await new Promise((resolve) => { - this.content.addEventListener("unload", () => { - Assert.equal(this.context.contentWindow, this.content, "Context's contentWindow property should be non-null at unload"); - resolve(); - }); - this.content.location = "http://example.org/dummy?noscripthere2"; - }); - - await contextUnloadedPromise; - }); - - await extension.awaitMessage("content-script-unload"); - - await contentPage.spawn(null, async () => { - Assert.equal(this.context.sandbox, null, "Context's sandbox has been destroyed after unload"); - }); - - await contentPage.close(); - await extension.unload(); -}); diff --git a/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini b/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini index f0d69c6ecbb0..4f3604138ceb 100644 --- a/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini +++ b/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini @@ -25,7 +25,6 @@ skip-if = appname == "thunderbird" || os == "android" [test_ext_contentscript_async_loading.js] skip-if = os == 'android' && debug # The generated script takes too long to load on Android debug [test_ext_contentscript_context.js] -[test_ext_contentscript_context_isolation.js] [test_ext_contentscript_create_iframe.js] [test_ext_contentscript_css.js] [test_ext_contentscript_exporthelpers.js] @@ -54,7 +53,6 @@ fail-if = appname == "thunderbird" [test_ext_extensionSettingsStore.js] [test_ext_extension_content_telemetry.js] skip-if = os == "android" # checking for telemetry needs to be updated: 1384923 -[test_ext_extension_page_context.js] [test_ext_extension_startup_telemetry.js] [test_ext_geturl.js] [test_ext_idle.js] From f8234320a3d5e2615cb7fbda0e7d2703e3db9063 Mon Sep 17 00:00:00 2001 From: Alessio Placitelli Date: Mon, 3 Sep 2018 10:15:21 +0000 Subject: [PATCH 11/61] Bug 1484611 - Re-organize the telemetry module layout. r=chutten,janerik This patch organizes the Telemetry files according to a new directory layout, which makes the top level dir less cluttered. For a comprehensive discussion about the new layout, see the bug comments. Additionally, the build script and a few Python and C++ files are adjusted for dealing with the new directory layout. Differential Revision: https://phabricator.services.mozilla.com/D4427 --HG-- rename : toolkit/components/telemetry/TelemetryArchive.jsm => toolkit/components/telemetry/app/TelemetryArchive.jsm rename : toolkit/components/telemetry/TelemetryController.jsm => toolkit/components/telemetry/app/TelemetryController.jsm rename : toolkit/components/telemetry/TelemetryEnvironment.jsm => toolkit/components/telemetry/app/TelemetryEnvironment.jsm rename : toolkit/components/telemetry/TelemetryReportingPolicy.jsm => toolkit/components/telemetry/app/TelemetryReportingPolicy.jsm rename : toolkit/components/telemetry/TelemetrySend.jsm => toolkit/components/telemetry/app/TelemetrySend.jsm rename : toolkit/components/telemetry/TelemetryStopwatch.jsm => toolkit/components/telemetry/app/TelemetryStopwatch.jsm rename : toolkit/components/telemetry/TelemetryStorage.jsm => toolkit/components/telemetry/app/TelemetryStorage.jsm rename : toolkit/components/telemetry/TelemetryTimestamps.jsm => toolkit/components/telemetry/app/TelemetryTimestamps.jsm rename : toolkit/components/telemetry/TelemetryUtils.jsm => toolkit/components/telemetry/app/TelemetryUtils.jsm rename : toolkit/components/telemetry/gen_event_data.py => toolkit/components/telemetry/build_scripts/gen_event_data.py rename : toolkit/components/telemetry/gen_event_enum.py => toolkit/components/telemetry/build_scripts/gen_event_enum.py rename : toolkit/components/telemetry/gen_histogram_data.py => toolkit/components/telemetry/build_scripts/gen_histogram_data.py rename : toolkit/components/telemetry/gen_histogram_enum.py => toolkit/components/telemetry/build_scripts/gen_histogram_enum.py rename : toolkit/components/telemetry/gen_histogram_phf.py => toolkit/components/telemetry/build_scripts/gen_histogram_phf.py rename : toolkit/components/telemetry/gen_process_data.py => toolkit/components/telemetry/build_scripts/gen_process_data.py rename : toolkit/components/telemetry/gen_process_enum.py => toolkit/components/telemetry/build_scripts/gen_process_enum.py rename : toolkit/components/telemetry/gen_scalar_data.py => toolkit/components/telemetry/build_scripts/gen_scalar_data.py rename : toolkit/components/telemetry/gen_scalar_enum.py => toolkit/components/telemetry/build_scripts/gen_scalar_enum.py rename : toolkit/components/telemetry/parse_events.py => toolkit/components/telemetry/build_scripts/parsers/parse_events.py rename : toolkit/components/telemetry/parse_histograms.py => toolkit/components/telemetry/build_scripts/parsers/parse_histograms.py rename : toolkit/components/telemetry/parse_scalars.py => toolkit/components/telemetry/build_scripts/parsers/parse_scalars.py rename : toolkit/components/telemetry/shared_telemetry_utils.py => toolkit/components/telemetry/build_scripts/parsers/shared_telemetry_utils.py rename : toolkit/components/telemetry/EventInfo.h => toolkit/components/telemetry/core/EventInfo.h rename : toolkit/components/telemetry/ScalarInfo.h => toolkit/components/telemetry/core/ScalarInfo.h rename : toolkit/components/telemetry/Telemetry.cpp => toolkit/components/telemetry/core/Telemetry.cpp rename : toolkit/components/telemetry/Telemetry.h => toolkit/components/telemetry/core/Telemetry.h rename : toolkit/components/telemetry/TelemetryCommon.cpp => toolkit/components/telemetry/core/TelemetryCommon.cpp rename : toolkit/components/telemetry/TelemetryCommon.h => toolkit/components/telemetry/core/TelemetryCommon.h rename : toolkit/components/telemetry/TelemetryEvent.cpp => toolkit/components/telemetry/core/TelemetryEvent.cpp rename : toolkit/components/telemetry/TelemetryEvent.h => toolkit/components/telemetry/core/TelemetryEvent.h rename : toolkit/components/telemetry/TelemetryHistogram.cpp => toolkit/components/telemetry/core/TelemetryHistogram.cpp rename : toolkit/components/telemetry/TelemetryHistogram.h => toolkit/components/telemetry/core/TelemetryHistogram.h rename : toolkit/components/telemetry/TelemetryScalar.cpp => toolkit/components/telemetry/core/TelemetryScalar.cpp rename : toolkit/components/telemetry/TelemetryScalar.h => toolkit/components/telemetry/core/TelemetryScalar.h rename : toolkit/components/telemetry/ipc/TelemetryComms.h => toolkit/components/telemetry/core/ipc/TelemetryComms.h rename : toolkit/components/telemetry/ipc/TelemetryIPC.cpp => toolkit/components/telemetry/core/ipc/TelemetryIPC.cpp rename : toolkit/components/telemetry/ipc/TelemetryIPC.h => toolkit/components/telemetry/core/ipc/TelemetryIPC.h rename : toolkit/components/telemetry/ipc/TelemetryIPCAccumulator.cpp => toolkit/components/telemetry/core/ipc/TelemetryIPCAccumulator.cpp rename : toolkit/components/telemetry/ipc/TelemetryIPCAccumulator.h => toolkit/components/telemetry/core/ipc/TelemetryIPCAccumulator.h rename : toolkit/components/telemetry/nsITelemetry.idl => toolkit/components/telemetry/core/nsITelemetry.idl rename : toolkit/components/telemetry/CombinedStacks.cpp => toolkit/components/telemetry/other/CombinedStacks.cpp rename : toolkit/components/telemetry/CombinedStacks.h => toolkit/components/telemetry/other/CombinedStacks.h rename : toolkit/components/telemetry/GCTelemetry.jsm => toolkit/components/telemetry/other/GCTelemetry.jsm rename : toolkit/components/telemetry/KeyedStackCapturer.cpp => toolkit/components/telemetry/other/KeyedStackCapturer.cpp rename : toolkit/components/telemetry/KeyedStackCapturer.h => toolkit/components/telemetry/other/KeyedStackCapturer.h rename : toolkit/components/telemetry/ProcessedStack.cpp => toolkit/components/telemetry/other/ProcessedStack.cpp rename : toolkit/components/telemetry/ProcessedStack.h => toolkit/components/telemetry/other/ProcessedStack.h rename : toolkit/components/telemetry/TelemetryIOInterposeObserver.cpp => toolkit/components/telemetry/other/TelemetryIOInterposeObserver.cpp rename : toolkit/components/telemetry/TelemetryIOInterposeObserver.h => toolkit/components/telemetry/other/TelemetryIOInterposeObserver.h rename : toolkit/components/telemetry/UITelemetry.jsm => toolkit/components/telemetry/other/UITelemetry.jsm rename : toolkit/components/telemetry/WebrtcTelemetry.cpp => toolkit/components/telemetry/other/WebrtcTelemetry.cpp rename : toolkit/components/telemetry/WebrtcTelemetry.h => toolkit/components/telemetry/other/WebrtcTelemetry.h rename : toolkit/components/telemetry/TelemetryEventPing.jsm => toolkit/components/telemetry/pings/EventPing.jsm rename : toolkit/components/telemetry/TelemetryHealthPing.jsm => toolkit/components/telemetry/pings/HealthPing.jsm rename : toolkit/components/telemetry/TelemetryModules.jsm => toolkit/components/telemetry/pings/ModulesPing.jsm rename : toolkit/components/telemetry/TelemetrySession.jsm => toolkit/components/telemetry/pings/TelemetrySession.jsm rename : toolkit/components/telemetry/UpdatePing.jsm => toolkit/components/telemetry/pings/UpdatePing.jsm extra : moz-landing-system : lando --- .../telemetry/{ => app}/TelemetryArchive.jsm | 0 .../{ => app}/TelemetryController.jsm | 0 .../{ => app}/TelemetryEnvironment.jsm | 0 .../{ => app}/TelemetryReportingPolicy.jsm | 0 .../telemetry/{ => app}/TelemetrySend.jsm | 0 .../{ => app}/TelemetryStopwatch.jsm | 0 .../telemetry/{ => app}/TelemetryStorage.jsm | 0 .../{ => app}/TelemetryTimestamps.jsm | 0 .../telemetry/{ => app}/TelemetryUtils.jsm | 0 .../{ => build_scripts}/gen_event_data.py | 6 +- .../{ => build_scripts}/gen_event_enum.py | 4 +- .../{ => build_scripts}/gen_histogram_data.py | 4 +- .../{ => build_scripts}/gen_histogram_enum.py | 4 +- .../{ => build_scripts}/gen_histogram_phf.py | 4 +- .../{ => build_scripts}/gen_process_data.py | 2 +- .../{ => build_scripts}/gen_process_enum.py | 2 +- .../{ => build_scripts}/gen_scalar_data.py | 6 +- .../{ => build_scripts}/gen_scalar_enum.py | 4 +- .../build_scripts/parsers/__init__.py | 0 .../parsers}/parse_events.py | 0 .../parsers}/parse_histograms.py | 9 +- .../parsers}/parse_scalars.py | 0 .../parsers}/shared_telemetry_utils.py | 0 .../telemetry/{ => core}/EventInfo.h | 0 .../telemetry/{ => core}/ScalarInfo.h | 0 .../telemetry/{ => core}/Telemetry.cpp | 8 +- .../telemetry/{ => core}/Telemetry.h | 0 .../telemetry/{ => core}/TelemetryCommon.cpp | 0 .../telemetry/{ => core}/TelemetryCommon.h | 0 .../telemetry/{ => core}/TelemetryEvent.cpp | 0 .../telemetry/{ => core}/TelemetryEvent.h | 0 .../{ => core}/TelemetryHistogram.cpp | 0 .../telemetry/{ => core}/TelemetryHistogram.h | 0 .../telemetry/{ => core}/TelemetryScalar.cpp | 0 .../telemetry/{ => core}/TelemetryScalar.h | 0 .../telemetry/{ => core}/ipc/TelemetryComms.h | 0 .../telemetry/{ => core}/ipc/TelemetryIPC.cpp | 0 .../telemetry/{ => core}/ipc/TelemetryIPC.h | 0 .../ipc/TelemetryIPCAccumulator.cpp | 4 +- .../{ => core}/ipc/TelemetryIPCAccumulator.h | 0 .../telemetry/{ => core}/nsITelemetry.idl | 0 .../TelemetryGeckoViewPersistence.cpp | 4 +- .../geckoview/TelemetryGeckoViewTesting.cpp | 2 +- .../geckoview/gtest/TestGeckoView.cpp | 4 +- .../telemetry/gen-histogram-bucket-ranges.py | 53 ----------- toolkit/components/telemetry/moz.build | 90 +++++++++---------- .../telemetry/{ => other}/CombinedStacks.cpp | 0 .../telemetry/{ => other}/CombinedStacks.h | 0 .../telemetry/{ => other}/GCTelemetry.jsm | 0 .../{ => other}/KeyedStackCapturer.cpp | 0 .../{ => other}/KeyedStackCapturer.h | 2 +- .../telemetry/{ => other}/ProcessedStack.cpp | 0 .../telemetry/{ => other}/ProcessedStack.h | 0 .../TelemetryIOInterposeObserver.cpp | 2 +- .../TelemetryIOInterposeObserver.h | 2 +- .../telemetry/{ => other}/UITelemetry.jsm | 0 .../telemetry/{ => other}/WebrtcTelemetry.cpp | 3 +- .../telemetry/{ => other}/WebrtcTelemetry.h | 2 +- .../EventPing.jsm} | 0 .../HealthPing.jsm} | 0 .../ModulesPing.jsm} | 0 .../{ => pings}/TelemetrySession.jsm | 0 .../telemetry/{ => pings}/UpdatePing.jsm | 0 .../telemetry/schemas/core.schema.json | 41 --------- .../tests/gtest/TelemetryTestHelpers.cpp | 2 +- .../tests/gtest/TestCombinedStacks.cpp | 4 +- .../telemetry/tests/gtest/TestCounters.cpp | 2 +- .../telemetry/tests/gtest/TestHistograms.cpp | 2 +- .../telemetry/tests/gtest/TestScalars.cpp | 4 +- 69 files changed, 93 insertions(+), 183 deletions(-) rename toolkit/components/telemetry/{ => app}/TelemetryArchive.jsm (100%) rename toolkit/components/telemetry/{ => app}/TelemetryController.jsm (100%) rename toolkit/components/telemetry/{ => app}/TelemetryEnvironment.jsm (100%) rename toolkit/components/telemetry/{ => app}/TelemetryReportingPolicy.jsm (100%) rename toolkit/components/telemetry/{ => app}/TelemetrySend.jsm (100%) rename toolkit/components/telemetry/{ => app}/TelemetryStopwatch.jsm (100%) rename toolkit/components/telemetry/{ => app}/TelemetryStorage.jsm (100%) rename toolkit/components/telemetry/{ => app}/TelemetryTimestamps.jsm (100%) rename toolkit/components/telemetry/{ => app}/TelemetryUtils.jsm (100%) rename toolkit/components/telemetry/{ => build_scripts}/gen_event_data.py (97%) rename toolkit/components/telemetry/{ => build_scripts}/gen_event_enum.py (96%) rename toolkit/components/telemetry/{ => build_scripts}/gen_histogram_data.py (98%) rename toolkit/components/telemetry/{ => build_scripts}/gen_histogram_enum.py (97%) rename toolkit/components/telemetry/{ => build_scripts}/gen_histogram_phf.py (94%) rename toolkit/components/telemetry/{ => build_scripts}/gen_process_data.py (97%) rename toolkit/components/telemetry/{ => build_scripts}/gen_process_enum.py (96%) rename toolkit/components/telemetry/{ => build_scripts}/gen_scalar_data.py (96%) rename toolkit/components/telemetry/{ => build_scripts}/gen_scalar_enum.py (94%) create mode 100644 toolkit/components/telemetry/build_scripts/parsers/__init__.py rename toolkit/components/telemetry/{ => build_scripts/parsers}/parse_events.py (100%) rename toolkit/components/telemetry/{ => build_scripts/parsers}/parse_histograms.py (98%) rename toolkit/components/telemetry/{ => build_scripts/parsers}/parse_scalars.py (100%) rename toolkit/components/telemetry/{ => build_scripts/parsers}/shared_telemetry_utils.py (100%) rename toolkit/components/telemetry/{ => core}/EventInfo.h (100%) rename toolkit/components/telemetry/{ => core}/ScalarInfo.h (100%) rename toolkit/components/telemetry/{ => core}/Telemetry.cpp (99%) rename toolkit/components/telemetry/{ => core}/Telemetry.h (100%) rename toolkit/components/telemetry/{ => core}/TelemetryCommon.cpp (100%) rename toolkit/components/telemetry/{ => core}/TelemetryCommon.h (100%) rename toolkit/components/telemetry/{ => core}/TelemetryEvent.cpp (100%) rename toolkit/components/telemetry/{ => core}/TelemetryEvent.h (100%) rename toolkit/components/telemetry/{ => core}/TelemetryHistogram.cpp (100%) rename toolkit/components/telemetry/{ => core}/TelemetryHistogram.h (100%) rename toolkit/components/telemetry/{ => core}/TelemetryScalar.cpp (100%) rename toolkit/components/telemetry/{ => core}/TelemetryScalar.h (100%) rename toolkit/components/telemetry/{ => core}/ipc/TelemetryComms.h (100%) rename toolkit/components/telemetry/{ => core}/ipc/TelemetryIPC.cpp (100%) rename toolkit/components/telemetry/{ => core}/ipc/TelemetryIPC.h (100%) rename toolkit/components/telemetry/{ => core}/ipc/TelemetryIPCAccumulator.cpp (99%) rename toolkit/components/telemetry/{ => core}/ipc/TelemetryIPCAccumulator.h (100%) rename toolkit/components/telemetry/{ => core}/nsITelemetry.idl (100%) delete mode 100644 toolkit/components/telemetry/gen-histogram-bucket-ranges.py rename toolkit/components/telemetry/{ => other}/CombinedStacks.cpp (100%) rename toolkit/components/telemetry/{ => other}/CombinedStacks.h (100%) rename toolkit/components/telemetry/{ => other}/GCTelemetry.jsm (100%) rename toolkit/components/telemetry/{ => other}/KeyedStackCapturer.cpp (100%) rename toolkit/components/telemetry/{ => other}/KeyedStackCapturer.h (98%) rename toolkit/components/telemetry/{ => other}/ProcessedStack.cpp (100%) rename toolkit/components/telemetry/{ => other}/ProcessedStack.h (100%) rename toolkit/components/telemetry/{ => other}/TelemetryIOInterposeObserver.cpp (99%) rename toolkit/components/telemetry/{ => other}/TelemetryIOInterposeObserver.h (99%) rename toolkit/components/telemetry/{ => other}/UITelemetry.jsm (100%) rename toolkit/components/telemetry/{ => other}/WebrtcTelemetry.cpp (98%) rename toolkit/components/telemetry/{ => other}/WebrtcTelemetry.h (97%) rename toolkit/components/telemetry/{TelemetryEventPing.jsm => pings/EventPing.jsm} (100%) rename toolkit/components/telemetry/{TelemetryHealthPing.jsm => pings/HealthPing.jsm} (100%) rename toolkit/components/telemetry/{TelemetryModules.jsm => pings/ModulesPing.jsm} (100%) rename toolkit/components/telemetry/{ => pings}/TelemetrySession.jsm (100%) rename toolkit/components/telemetry/{ => pings}/UpdatePing.jsm (100%) delete mode 100644 toolkit/components/telemetry/schemas/core.schema.json diff --git a/toolkit/components/telemetry/TelemetryArchive.jsm b/toolkit/components/telemetry/app/TelemetryArchive.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryArchive.jsm rename to toolkit/components/telemetry/app/TelemetryArchive.jsm diff --git a/toolkit/components/telemetry/TelemetryController.jsm b/toolkit/components/telemetry/app/TelemetryController.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryController.jsm rename to toolkit/components/telemetry/app/TelemetryController.jsm diff --git a/toolkit/components/telemetry/TelemetryEnvironment.jsm b/toolkit/components/telemetry/app/TelemetryEnvironment.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryEnvironment.jsm rename to toolkit/components/telemetry/app/TelemetryEnvironment.jsm diff --git a/toolkit/components/telemetry/TelemetryReportingPolicy.jsm b/toolkit/components/telemetry/app/TelemetryReportingPolicy.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryReportingPolicy.jsm rename to toolkit/components/telemetry/app/TelemetryReportingPolicy.jsm diff --git a/toolkit/components/telemetry/TelemetrySend.jsm b/toolkit/components/telemetry/app/TelemetrySend.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetrySend.jsm rename to toolkit/components/telemetry/app/TelemetrySend.jsm diff --git a/toolkit/components/telemetry/TelemetryStopwatch.jsm b/toolkit/components/telemetry/app/TelemetryStopwatch.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryStopwatch.jsm rename to toolkit/components/telemetry/app/TelemetryStopwatch.jsm diff --git a/toolkit/components/telemetry/TelemetryStorage.jsm b/toolkit/components/telemetry/app/TelemetryStorage.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryStorage.jsm rename to toolkit/components/telemetry/app/TelemetryStorage.jsm diff --git a/toolkit/components/telemetry/TelemetryTimestamps.jsm b/toolkit/components/telemetry/app/TelemetryTimestamps.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryTimestamps.jsm rename to toolkit/components/telemetry/app/TelemetryTimestamps.jsm diff --git a/toolkit/components/telemetry/TelemetryUtils.jsm b/toolkit/components/telemetry/app/TelemetryUtils.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryUtils.jsm rename to toolkit/components/telemetry/app/TelemetryUtils.jsm diff --git a/toolkit/components/telemetry/gen_event_data.py b/toolkit/components/telemetry/build_scripts/gen_event_data.py similarity index 97% rename from toolkit/components/telemetry/gen_event_data.py rename to toolkit/components/telemetry/build_scripts/gen_event_data.py index 85569245dc08..97dce90688f7 100644 --- a/toolkit/components/telemetry/gen_event_data.py +++ b/toolkit/components/telemetry/build_scripts/gen_event_data.py @@ -7,10 +7,10 @@ from __future__ import print_function from collections import OrderedDict -from shared_telemetry_utils import StringTable, static_assert, ParserError +from parsers.shared_telemetry_utils import StringTable, static_assert, ParserError +from parsers import parse_events import json -import parse_events import sys import itertools @@ -22,7 +22,7 @@ banner = """/* This file is auto-generated, only for internal use in TelemetryEv file_header = """\ #ifndef mozilla_TelemetryEventData_h #define mozilla_TelemetryEventData_h -#include "EventInfo.h" +#include "core/EventInfo.h" namespace { """ diff --git a/toolkit/components/telemetry/gen_event_enum.py b/toolkit/components/telemetry/build_scripts/gen_event_enum.py similarity index 96% rename from toolkit/components/telemetry/gen_event_enum.py rename to toolkit/components/telemetry/build_scripts/gen_event_enum.py index 786bcae3af2a..7b1f7d2fb76a 100644 --- a/toolkit/components/telemetry/gen_event_enum.py +++ b/toolkit/components/telemetry/build_scripts/gen_event_enum.py @@ -7,10 +7,10 @@ # The events are defined in files provided as command-line arguments. from __future__ import print_function -from shared_telemetry_utils import ParserError +from parsers.shared_telemetry_utils import ParserError +from parsers import parse_events import sys -import parse_events banner = """/* This file is auto-generated, see gen_event_enum.py. */ """ diff --git a/toolkit/components/telemetry/gen_histogram_data.py b/toolkit/components/telemetry/build_scripts/gen_histogram_data.py similarity index 98% rename from toolkit/components/telemetry/gen_histogram_data.py rename to toolkit/components/telemetry/build_scripts/gen_histogram_data.py index 7af76cc72e87..76a9cfaa6525 100644 --- a/toolkit/components/telemetry/gen_histogram_data.py +++ b/toolkit/components/telemetry/build_scripts/gen_histogram_data.py @@ -6,10 +6,10 @@ # in a file provided as a command-line argument. from __future__ import print_function -from shared_telemetry_utils import StringTable, static_assert, ParserError +from parsers.shared_telemetry_utils import StringTable, static_assert, ParserError +from parsers import parse_histograms import sys -import parse_histograms import buildconfig banner = """/* This file is auto-generated, see gen_histogram_data.py. */ diff --git a/toolkit/components/telemetry/gen_histogram_enum.py b/toolkit/components/telemetry/build_scripts/gen_histogram_enum.py similarity index 97% rename from toolkit/components/telemetry/gen_histogram_enum.py rename to toolkit/components/telemetry/build_scripts/gen_histogram_enum.py index 9a9fde03431f..75c4f7bcc3b7 100644 --- a/toolkit/components/telemetry/gen_histogram_enum.py +++ b/toolkit/components/telemetry/build_scripts/gen_histogram_enum.py @@ -13,9 +13,9 @@ # The histograms are defined in files provided as command-line arguments. from __future__ import print_function -from shared_telemetry_utils import ParserError +from parsers.shared_telemetry_utils import ParserError +from parsers import parse_histograms -import parse_histograms import itertools import sys import buildconfig diff --git a/toolkit/components/telemetry/gen_histogram_phf.py b/toolkit/components/telemetry/build_scripts/gen_histogram_phf.py similarity index 94% rename from toolkit/components/telemetry/gen_histogram_phf.py rename to toolkit/components/telemetry/build_scripts/gen_histogram_phf.py index f291f10f56dc..8918967f5e5c 100644 --- a/toolkit/components/telemetry/gen_histogram_phf.py +++ b/toolkit/components/telemetry/build_scripts/gen_histogram_phf.py @@ -3,12 +3,12 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from __future__ import print_function -from shared_telemetry_utils import ParserError +from parsers.shared_telemetry_utils import ParserError from perfecthash import PerfectHash PHFSIZE = 512 -import parse_histograms +from parsers import parse_histograms import sys import buildconfig diff --git a/toolkit/components/telemetry/gen_process_data.py b/toolkit/components/telemetry/build_scripts/gen_process_data.py similarity index 97% rename from toolkit/components/telemetry/gen_process_data.py rename to toolkit/components/telemetry/build_scripts/gen_process_data.py index 56842c640ea2..8bfe90fdf0c5 100644 --- a/toolkit/components/telemetry/gen_process_data.py +++ b/toolkit/components/telemetry/build_scripts/gen_process_data.py @@ -6,7 +6,7 @@ # in a file provided as a command-line argument. from __future__ import print_function -from shared_telemetry_utils import ParserError, load_yaml_file +from parsers.shared_telemetry_utils import ParserError, load_yaml_file import sys import collections diff --git a/toolkit/components/telemetry/gen_process_enum.py b/toolkit/components/telemetry/build_scripts/gen_process_enum.py similarity index 96% rename from toolkit/components/telemetry/gen_process_enum.py rename to toolkit/components/telemetry/build_scripts/gen_process_enum.py index d771e381c0bf..c70326b2b003 100644 --- a/toolkit/components/telemetry/gen_process_enum.py +++ b/toolkit/components/telemetry/build_scripts/gen_process_enum.py @@ -6,7 +6,7 @@ # in a file provided as a command-line argument. from __future__ import print_function -from shared_telemetry_utils import ParserError, load_yaml_file +from parsers.shared_telemetry_utils import ParserError, load_yaml_file import sys import collections diff --git a/toolkit/components/telemetry/gen_scalar_data.py b/toolkit/components/telemetry/build_scripts/gen_scalar_data.py similarity index 96% rename from toolkit/components/telemetry/gen_scalar_data.py rename to toolkit/components/telemetry/build_scripts/gen_scalar_data.py index ca4b8b462c7d..e86b30ecfdc6 100644 --- a/toolkit/components/telemetry/gen_scalar_data.py +++ b/toolkit/components/telemetry/build_scripts/gen_scalar_data.py @@ -7,10 +7,10 @@ from __future__ import print_function from collections import OrderedDict -from shared_telemetry_utils import StringTable, static_assert, ParserError +from parsers.shared_telemetry_utils import StringTable, static_assert, ParserError +from parsers import parse_scalars import json -import parse_scalars import sys # The banner/text at the top of the generated file. @@ -21,7 +21,7 @@ banner = """/* This file is auto-generated, only for internal use in TelemetrySc file_header = """\ #ifndef mozilla_TelemetryScalarData_h #define mozilla_TelemetryScalarData_h -#include "ScalarInfo.h" +#include "core/ScalarInfo.h" namespace { """ diff --git a/toolkit/components/telemetry/gen_scalar_enum.py b/toolkit/components/telemetry/build_scripts/gen_scalar_enum.py similarity index 94% rename from toolkit/components/telemetry/gen_scalar_enum.py rename to toolkit/components/telemetry/build_scripts/gen_scalar_enum.py index d84895a91595..4ae2ceeb6ba2 100644 --- a/toolkit/components/telemetry/gen_scalar_enum.py +++ b/toolkit/components/telemetry/build_scripts/gen_scalar_enum.py @@ -8,10 +8,10 @@ # The scalars are defined in files provided as command-line arguments. from __future__ import print_function -from shared_telemetry_utils import ParserError +from parsers.shared_telemetry_utils import ParserError +from parsers import parse_scalars import sys -import parse_scalars banner = """/* This file is auto-generated, see gen_scalar_enum.py. */ """ diff --git a/toolkit/components/telemetry/build_scripts/parsers/__init__.py b/toolkit/components/telemetry/build_scripts/parsers/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/toolkit/components/telemetry/parse_events.py b/toolkit/components/telemetry/build_scripts/parsers/parse_events.py similarity index 100% rename from toolkit/components/telemetry/parse_events.py rename to toolkit/components/telemetry/build_scripts/parsers/parse_events.py diff --git a/toolkit/components/telemetry/parse_histograms.py b/toolkit/components/telemetry/build_scripts/parsers/parse_histograms.py similarity index 98% rename from toolkit/components/telemetry/parse_histograms.py rename to toolkit/components/telemetry/build_scripts/parsers/parse_histograms.py index a552d75283cd..89987f7650c2 100755 --- a/toolkit/components/telemetry/parse_histograms.py +++ b/toolkit/components/telemetry/build_scripts/parsers/parse_histograms.py @@ -96,8 +96,13 @@ whitelists = None def load_whitelist(): global whitelists try: - whitelist_path = os.path.join(os.path.abspath(os.path.realpath(os.path.dirname(__file__))), - 'histogram-whitelists.json') + parsers_path = os.path.realpath(os.path.dirname(__file__)) + # The parsers live in build_scripts/parsers in the Telemetry module, while + # the histogram-whitelists file lives in the root of the module. Account + # for that when looking for the whitelist. + # NOTE: if the parsers are moved, this logic will need to be updated. + telemetry_module_path = os.path.abspath(os.path.join(parsers_path, os.pardir, os.pardir)) + whitelist_path = os.path.join(telemetry_module_path, 'histogram-whitelists.json') with open(whitelist_path, 'r') as f: try: whitelists = json.load(f) diff --git a/toolkit/components/telemetry/parse_scalars.py b/toolkit/components/telemetry/build_scripts/parsers/parse_scalars.py similarity index 100% rename from toolkit/components/telemetry/parse_scalars.py rename to toolkit/components/telemetry/build_scripts/parsers/parse_scalars.py diff --git a/toolkit/components/telemetry/shared_telemetry_utils.py b/toolkit/components/telemetry/build_scripts/parsers/shared_telemetry_utils.py similarity index 100% rename from toolkit/components/telemetry/shared_telemetry_utils.py rename to toolkit/components/telemetry/build_scripts/parsers/shared_telemetry_utils.py diff --git a/toolkit/components/telemetry/EventInfo.h b/toolkit/components/telemetry/core/EventInfo.h similarity index 100% rename from toolkit/components/telemetry/EventInfo.h rename to toolkit/components/telemetry/core/EventInfo.h diff --git a/toolkit/components/telemetry/ScalarInfo.h b/toolkit/components/telemetry/core/ScalarInfo.h similarity index 100% rename from toolkit/components/telemetry/ScalarInfo.h rename to toolkit/components/telemetry/core/ScalarInfo.h diff --git a/toolkit/components/telemetry/Telemetry.cpp b/toolkit/components/telemetry/core/Telemetry.cpp similarity index 99% rename from toolkit/components/telemetry/Telemetry.cpp rename to toolkit/components/telemetry/core/Telemetry.cpp index eef1463533c1..19a45c26a4be 100644 --- a/toolkit/components/telemetry/Telemetry.cpp +++ b/toolkit/components/telemetry/core/Telemetry.cpp @@ -24,7 +24,7 @@ #include "mozilla/Unused.h" #include "base/pickle.h" -#include "CombinedStacks.h" +#include "other/CombinedStacks.h" #include "nsIComponentManager.h" #include "nsIServiceManager.h" #include "nsThreadManager.h" @@ -52,11 +52,11 @@ #include "Telemetry.h" #include "TelemetryCommon.h" #include "TelemetryHistogram.h" -#include "TelemetryIOInterposeObserver.h" +#include "other/TelemetryIOInterposeObserver.h" #include "ipc/TelemetryIPCAccumulator.h" #include "TelemetryScalar.h" #include "TelemetryEvent.h" -#include "WebrtcTelemetry.h" +#include "other/WebrtcTelemetry.h" #include "nsTHashtable.h" #include "nsHashKeys.h" #include "nsBaseHashtable.h" @@ -91,7 +91,7 @@ #if defined(MOZ_GECKO_PROFILER) #include "shared-libraries.h" -#include "KeyedStackCapturer.h" +#include "other/KeyedStackCapturer.h" #endif // MOZ_GECKO_PROFILER #if defined(MOZ_TELEMETRY_GECKOVIEW) diff --git a/toolkit/components/telemetry/Telemetry.h b/toolkit/components/telemetry/core/Telemetry.h similarity index 100% rename from toolkit/components/telemetry/Telemetry.h rename to toolkit/components/telemetry/core/Telemetry.h diff --git a/toolkit/components/telemetry/TelemetryCommon.cpp b/toolkit/components/telemetry/core/TelemetryCommon.cpp similarity index 100% rename from toolkit/components/telemetry/TelemetryCommon.cpp rename to toolkit/components/telemetry/core/TelemetryCommon.cpp diff --git a/toolkit/components/telemetry/TelemetryCommon.h b/toolkit/components/telemetry/core/TelemetryCommon.h similarity index 100% rename from toolkit/components/telemetry/TelemetryCommon.h rename to toolkit/components/telemetry/core/TelemetryCommon.h diff --git a/toolkit/components/telemetry/TelemetryEvent.cpp b/toolkit/components/telemetry/core/TelemetryEvent.cpp similarity index 100% rename from toolkit/components/telemetry/TelemetryEvent.cpp rename to toolkit/components/telemetry/core/TelemetryEvent.cpp diff --git a/toolkit/components/telemetry/TelemetryEvent.h b/toolkit/components/telemetry/core/TelemetryEvent.h similarity index 100% rename from toolkit/components/telemetry/TelemetryEvent.h rename to toolkit/components/telemetry/core/TelemetryEvent.h diff --git a/toolkit/components/telemetry/TelemetryHistogram.cpp b/toolkit/components/telemetry/core/TelemetryHistogram.cpp similarity index 100% rename from toolkit/components/telemetry/TelemetryHistogram.cpp rename to toolkit/components/telemetry/core/TelemetryHistogram.cpp diff --git a/toolkit/components/telemetry/TelemetryHistogram.h b/toolkit/components/telemetry/core/TelemetryHistogram.h similarity index 100% rename from toolkit/components/telemetry/TelemetryHistogram.h rename to toolkit/components/telemetry/core/TelemetryHistogram.h diff --git a/toolkit/components/telemetry/TelemetryScalar.cpp b/toolkit/components/telemetry/core/TelemetryScalar.cpp similarity index 100% rename from toolkit/components/telemetry/TelemetryScalar.cpp rename to toolkit/components/telemetry/core/TelemetryScalar.cpp diff --git a/toolkit/components/telemetry/TelemetryScalar.h b/toolkit/components/telemetry/core/TelemetryScalar.h similarity index 100% rename from toolkit/components/telemetry/TelemetryScalar.h rename to toolkit/components/telemetry/core/TelemetryScalar.h diff --git a/toolkit/components/telemetry/ipc/TelemetryComms.h b/toolkit/components/telemetry/core/ipc/TelemetryComms.h similarity index 100% rename from toolkit/components/telemetry/ipc/TelemetryComms.h rename to toolkit/components/telemetry/core/ipc/TelemetryComms.h diff --git a/toolkit/components/telemetry/ipc/TelemetryIPC.cpp b/toolkit/components/telemetry/core/ipc/TelemetryIPC.cpp similarity index 100% rename from toolkit/components/telemetry/ipc/TelemetryIPC.cpp rename to toolkit/components/telemetry/core/ipc/TelemetryIPC.cpp diff --git a/toolkit/components/telemetry/ipc/TelemetryIPC.h b/toolkit/components/telemetry/core/ipc/TelemetryIPC.h similarity index 100% rename from toolkit/components/telemetry/ipc/TelemetryIPC.h rename to toolkit/components/telemetry/core/ipc/TelemetryIPC.h diff --git a/toolkit/components/telemetry/ipc/TelemetryIPCAccumulator.cpp b/toolkit/components/telemetry/core/ipc/TelemetryIPCAccumulator.cpp similarity index 99% rename from toolkit/components/telemetry/ipc/TelemetryIPCAccumulator.cpp rename to toolkit/components/telemetry/core/ipc/TelemetryIPCAccumulator.cpp index 4ca5bcd44640..71e0aa730032 100644 --- a/toolkit/components/telemetry/ipc/TelemetryIPCAccumulator.cpp +++ b/toolkit/components/telemetry/core/ipc/TelemetryIPCAccumulator.cpp @@ -16,8 +16,8 @@ #include "nsComponentManagerUtils.h" #include "nsITimer.h" #include "nsThreadUtils.h" -#include "TelemetryHistogram.h" -#include "TelemetryScalar.h" +#include "core/TelemetryHistogram.h" +#include "core/TelemetryScalar.h" using mozilla::StaticMutex; using mozilla::StaticMutexAutoLock; diff --git a/toolkit/components/telemetry/ipc/TelemetryIPCAccumulator.h b/toolkit/components/telemetry/core/ipc/TelemetryIPCAccumulator.h similarity index 100% rename from toolkit/components/telemetry/ipc/TelemetryIPCAccumulator.h rename to toolkit/components/telemetry/core/ipc/TelemetryIPCAccumulator.h diff --git a/toolkit/components/telemetry/nsITelemetry.idl b/toolkit/components/telemetry/core/nsITelemetry.idl similarity index 100% rename from toolkit/components/telemetry/nsITelemetry.idl rename to toolkit/components/telemetry/core/nsITelemetry.idl diff --git a/toolkit/components/telemetry/geckoview/TelemetryGeckoViewPersistence.cpp b/toolkit/components/telemetry/geckoview/TelemetryGeckoViewPersistence.cpp index d9fe8145ec99..97d6250adbb2 100644 --- a/toolkit/components/telemetry/geckoview/TelemetryGeckoViewPersistence.cpp +++ b/toolkit/components/telemetry/geckoview/TelemetryGeckoViewPersistence.cpp @@ -29,8 +29,8 @@ #include "nsXULAppAPI.h" #include "prenv.h" #include "prio.h" -#include "TelemetryScalar.h" -#include "TelemetryHistogram.h" +#include "core/TelemetryScalar.h" +#include "core/TelemetryHistogram.h" #include "xpcpublic.h" using mozilla::GetErrorName; diff --git a/toolkit/components/telemetry/geckoview/TelemetryGeckoViewTesting.cpp b/toolkit/components/telemetry/geckoview/TelemetryGeckoViewTesting.cpp index dcafc92fa473..7c2cd4ecece9 100644 --- a/toolkit/components/telemetry/geckoview/TelemetryGeckoViewTesting.cpp +++ b/toolkit/components/telemetry/geckoview/TelemetryGeckoViewTesting.cpp @@ -4,7 +4,7 @@ #include "TelemetryGeckoViewTesting.h" #include "TelemetryGeckoViewPersistence.h" -#include "TelemetryScalar.h" +#include "core/TelemetryScalar.h" namespace TelemetryGeckoViewTesting { // This is defined in TelemetryGeckoViewPersistence.cpp diff --git a/toolkit/components/telemetry/geckoview/gtest/TestGeckoView.cpp b/toolkit/components/telemetry/geckoview/gtest/TestGeckoView.cpp index 38c50ebbe6db..3c1e888439fe 100644 --- a/toolkit/components/telemetry/geckoview/gtest/TestGeckoView.cpp +++ b/toolkit/components/telemetry/geckoview/gtest/TestGeckoView.cpp @@ -15,10 +15,10 @@ #include "nsThreadUtils.h" #include "nsPrintfCString.h" #include "prenv.h" -#include "Telemetry.h" +#include "mozilla/Telemetry.h" #include "TelemetryFixture.h" #include "TelemetryGeckoViewPersistence.h" -#include "TelemetryScalar.h" +#include "core/TelemetryScalar.h" #include "TelemetryTestHelpers.h" using namespace mozilla; diff --git a/toolkit/components/telemetry/gen-histogram-bucket-ranges.py b/toolkit/components/telemetry/gen-histogram-bucket-ranges.py deleted file mode 100644 index 7a2f1b697867..000000000000 --- a/toolkit/components/telemetry/gen-histogram-bucket-ranges.py +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env python -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Write out detailed histogram information, including the ranges of the -# buckets specified by each histogram. - -import sys -import parse_histograms -import json - -from collections import OrderedDict - - -def main(argv): - filenames = argv - - all_histograms = OrderedDict() - - for histogram in parse_histograms.from_files(filenames): - name = histogram.name() - parameters = OrderedDict() - table = { - 'boolean': '2', - 'flag': '3', - 'enumerated': '1', - 'linear': '1', - 'exponential': '0', - 'count': '4', - } - # Use __setitem__ because Python lambdas are so limited. - parse_histograms.table_dispatch(histogram.kind(), table, - lambda k: parameters.__setitem__('kind', k)) - if histogram.low() == 0: - parameters['min'] = 1 - else: - parameters['min'] = histogram.low() - - try: - buckets = histogram.ranges() - parameters['buckets'] = buckets - parameters['max'] = buckets[-1] - parameters['bucket_count'] = len(buckets) - except parse_histograms.DefinitionException: - continue - - all_histograms.update({name: parameters}) - - print json.dumps({'histograms': all_histograms}) - - -main(sys.argv[1:]) diff --git a/toolkit/components/telemetry/moz.build b/toolkit/components/telemetry/moz.build index 2bda9795ab40..489334d0a829 100644 --- a/toolkit/components/telemetry/moz.build +++ b/toolkit/components/telemetry/moz.build @@ -44,7 +44,7 @@ XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini'] BROWSER_CHROME_MANIFESTS += ['tests/browser/browser.ini'] XPIDL_SOURCES += [ - 'nsITelemetry.idl', + 'core/nsITelemetry.idl', ] XPIDL_MODULE = 'telemetry' @@ -54,32 +54,32 @@ EXPORTS.mozilla += [ '!TelemetryHistogramEnums.h', '!TelemetryProcessEnums.h', '!TelemetryScalarEnums.h', - 'CombinedStacks.h', - 'ipc/TelemetryComms.h', - 'ipc/TelemetryIPC.h', - 'ProcessedStack.h', - 'Telemetry.h', + 'core/ipc/TelemetryComms.h', + 'core/ipc/TelemetryIPC.h', + 'core/Telemetry.h', + 'other/CombinedStacks.h', + 'other/ProcessedStack.h', ] SOURCES += [ - 'CombinedStacks.cpp', + 'core/ipc/TelemetryIPC.cpp', + 'core/ipc/TelemetryIPCAccumulator.cpp', + 'core/Telemetry.cpp', + 'core/TelemetryCommon.cpp', + 'core/TelemetryEvent.cpp', + 'core/TelemetryHistogram.cpp', + 'core/TelemetryScalar.cpp', 'geckoview/TelemetryGeckoViewPersistence.cpp', - 'ipc/TelemetryIPC.cpp', - 'ipc/TelemetryIPCAccumulator.cpp', - 'ProcessedStack.cpp', - 'Telemetry.cpp', - 'TelemetryCommon.cpp', - 'TelemetryEvent.cpp', - 'TelemetryHistogram.cpp', - 'TelemetryIOInterposeObserver.cpp', - 'TelemetryScalar.cpp', - 'WebrtcTelemetry.cpp', + 'other/CombinedStacks.cpp', + 'other/ProcessedStack.cpp', + 'other/TelemetryIOInterposeObserver.cpp', + 'other/WebrtcTelemetry.cpp', ] # KeyedStackCapturer entirely relies on profiler to be enabled. if CONFIG['MOZ_GECKO_PROFILER']: SOURCES += [ - 'KeyedStackCapturer.cpp' + 'other/KeyedStackCapturer.cpp' ] EXTRA_COMPONENTS += [ @@ -88,22 +88,22 @@ EXTRA_COMPONENTS += [ ] EXTRA_JS_MODULES += [ - 'GCTelemetry.jsm', - 'TelemetryArchive.jsm', - 'TelemetryController.jsm', - 'TelemetryEnvironment.jsm', - 'TelemetryEventPing.jsm', - 'TelemetryHealthPing.jsm', - 'TelemetryModules.jsm', - 'TelemetryReportingPolicy.jsm', - 'TelemetrySend.jsm', - 'TelemetrySession.jsm', - 'TelemetryStopwatch.jsm', - 'TelemetryStorage.jsm', - 'TelemetryTimestamps.jsm', - 'TelemetryUtils.jsm', - 'UITelemetry.jsm', - 'UpdatePing.jsm', + 'app/TelemetryArchive.jsm', + 'app/TelemetryController.jsm', + 'app/TelemetryEnvironment.jsm', + 'app/TelemetryReportingPolicy.jsm', + 'app/TelemetrySend.jsm', + 'app/TelemetryStopwatch.jsm', + 'app/TelemetryStorage.jsm', + 'app/TelemetryTimestamps.jsm', + 'app/TelemetryUtils.jsm', + 'other/GCTelemetry.jsm', + 'other/UITelemetry.jsm', + 'pings/EventPing.jsm', + 'pings/HealthPing.jsm', + 'pings/ModulesPing.jsm', + 'pings/TelemetrySession.jsm', + 'pings/UpdatePing.jsm', ] TESTING_JS_MODULES += [ @@ -136,15 +136,15 @@ histogram_files = [ ] data = GENERATED_FILES['TelemetryHistogramData.inc'] -data.script = 'gen_histogram_data.py' +data.script = 'build_scripts/gen_histogram_data.py' data.inputs = histogram_files enums = GENERATED_FILES['TelemetryHistogramEnums.h'] -enums.script = 'gen_histogram_enum.py' +enums.script = 'build_scripts/gen_histogram_enum.py' enums.inputs = histogram_files data = GENERATED_FILES['TelemetryHistogramNameMap.h'] -data.script = 'gen_histogram_phf.py' +data.script = 'build_scripts/gen_histogram_phf.py' data.inputs = histogram_files # Generate scalar files. @@ -153,17 +153,17 @@ scalar_files = [ ] scalar_data = GENERATED_FILES['TelemetryScalarData.h'] -scalar_data.script = 'gen_scalar_data.py' +scalar_data.script = 'build_scripts/gen_scalar_data.py' scalar_data.inputs = scalar_files scalar_enums = GENERATED_FILES['TelemetryScalarEnums.h'] -scalar_enums.script = 'gen_scalar_enum.py' +scalar_enums.script = 'build_scripts/gen_scalar_enum.py' scalar_enums.inputs = scalar_files # Generate the JSON scalar definitions. They will only be # used in artifact or "build faster" builds. scalar_json_data = GENERATED_FILES['ScalarArtifactDefinitions.json'] -scalar_json_data.script = 'gen_scalar_data.py:generate_JSON_definitions' +scalar_json_data.script = 'build_scripts/gen_scalar_data.py:generate_JSON_definitions' scalar_json_data.inputs = scalar_files # Move the scalars JSON file to the directory where the Firefox binary is. @@ -175,17 +175,17 @@ event_files = [ ] event_data = GENERATED_FILES['TelemetryEventData.h'] -event_data.script = 'gen_event_data.py' +event_data.script = 'build_scripts/gen_event_data.py' event_data.inputs = event_files event_enums = GENERATED_FILES['TelemetryEventEnums.h'] -event_enums.script = 'gen_event_enum.py' +event_enums.script = 'build_scripts/gen_event_enum.py' event_enums.inputs = event_files # Generate the JSON event definitions. They will only be # used in artifact or "build faster" builds. event_json_data = GENERATED_FILES['EventArtifactDefinitions.json'] -event_json_data.script = 'gen_event_data.py:generate_JSON_definitions' +event_json_data.script = 'build_scripts/gen_event_data.py:generate_JSON_definitions' event_json_data.inputs = event_files # Move the events JSON file to the directory where the Firefox binary is. @@ -197,11 +197,11 @@ processes_files = [ ] processes_enum = GENERATED_FILES['TelemetryProcessEnums.h'] -processes_enum.script = 'gen_process_enum.py' +processes_enum.script = 'build_scripts/gen_process_enum.py' processes_enum.inputs = processes_files processes_data = GENERATED_FILES['TelemetryProcessData.h'] -processes_data.script = 'gen_process_data.py' +processes_data.script = 'build_scripts/gen_process_data.py' processes_data.inputs = processes_files # Add support for GeckoView: please note that building GeckoView diff --git a/toolkit/components/telemetry/CombinedStacks.cpp b/toolkit/components/telemetry/other/CombinedStacks.cpp similarity index 100% rename from toolkit/components/telemetry/CombinedStacks.cpp rename to toolkit/components/telemetry/other/CombinedStacks.cpp diff --git a/toolkit/components/telemetry/CombinedStacks.h b/toolkit/components/telemetry/other/CombinedStacks.h similarity index 100% rename from toolkit/components/telemetry/CombinedStacks.h rename to toolkit/components/telemetry/other/CombinedStacks.h diff --git a/toolkit/components/telemetry/GCTelemetry.jsm b/toolkit/components/telemetry/other/GCTelemetry.jsm similarity index 100% rename from toolkit/components/telemetry/GCTelemetry.jsm rename to toolkit/components/telemetry/other/GCTelemetry.jsm diff --git a/toolkit/components/telemetry/KeyedStackCapturer.cpp b/toolkit/components/telemetry/other/KeyedStackCapturer.cpp similarity index 100% rename from toolkit/components/telemetry/KeyedStackCapturer.cpp rename to toolkit/components/telemetry/other/KeyedStackCapturer.cpp diff --git a/toolkit/components/telemetry/KeyedStackCapturer.h b/toolkit/components/telemetry/other/KeyedStackCapturer.h similarity index 98% rename from toolkit/components/telemetry/KeyedStackCapturer.h rename to toolkit/components/telemetry/other/KeyedStackCapturer.h index 6c3438265a6b..f6632b8fe29e 100644 --- a/toolkit/components/telemetry/KeyedStackCapturer.h +++ b/toolkit/components/telemetry/other/KeyedStackCapturer.h @@ -6,7 +6,7 @@ #ifndef KeyedStackCapturer_h__ #define KeyedStackCapturer_h__ -#include "Telemetry.h" +#include "mozilla/Telemetry.h" #include "nsString.h" #include "nsClassHashtable.h" #include "mozilla/Mutex.h" diff --git a/toolkit/components/telemetry/ProcessedStack.cpp b/toolkit/components/telemetry/other/ProcessedStack.cpp similarity index 100% rename from toolkit/components/telemetry/ProcessedStack.cpp rename to toolkit/components/telemetry/other/ProcessedStack.cpp diff --git a/toolkit/components/telemetry/ProcessedStack.h b/toolkit/components/telemetry/other/ProcessedStack.h similarity index 100% rename from toolkit/components/telemetry/ProcessedStack.h rename to toolkit/components/telemetry/other/ProcessedStack.h diff --git a/toolkit/components/telemetry/TelemetryIOInterposeObserver.cpp b/toolkit/components/telemetry/other/TelemetryIOInterposeObserver.cpp similarity index 99% rename from toolkit/components/telemetry/TelemetryIOInterposeObserver.cpp rename to toolkit/components/telemetry/other/TelemetryIOInterposeObserver.cpp index 411437fdb123..76ba444abc8c 100644 --- a/toolkit/components/telemetry/TelemetryIOInterposeObserver.cpp +++ b/toolkit/components/telemetry/other/TelemetryIOInterposeObserver.cpp @@ -5,7 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "TelemetryIOInterposeObserver.h" -#include "TelemetryCommon.h" +#include "core/TelemetryCommon.h" namespace mozilla { namespace Telemetry { diff --git a/toolkit/components/telemetry/TelemetryIOInterposeObserver.h b/toolkit/components/telemetry/other/TelemetryIOInterposeObserver.h similarity index 99% rename from toolkit/components/telemetry/TelemetryIOInterposeObserver.h rename to toolkit/components/telemetry/other/TelemetryIOInterposeObserver.h index f92881cfc224..efffe3ee19b9 100644 --- a/toolkit/components/telemetry/TelemetryIOInterposeObserver.h +++ b/toolkit/components/telemetry/other/TelemetryIOInterposeObserver.h @@ -20,7 +20,7 @@ #include "nsBaseHashtable.h" #include "nsClassHashtable.h" -#include "TelemetryCommon.h" +#include "core/TelemetryCommon.h" #include "mozilla/IOInterposer.h" namespace mozilla { diff --git a/toolkit/components/telemetry/UITelemetry.jsm b/toolkit/components/telemetry/other/UITelemetry.jsm similarity index 100% rename from toolkit/components/telemetry/UITelemetry.jsm rename to toolkit/components/telemetry/other/UITelemetry.jsm diff --git a/toolkit/components/telemetry/WebrtcTelemetry.cpp b/toolkit/components/telemetry/other/WebrtcTelemetry.cpp similarity index 98% rename from toolkit/components/telemetry/WebrtcTelemetry.cpp rename to toolkit/components/telemetry/other/WebrtcTelemetry.cpp index 8c03f3a99fb0..0bc166ef7f24 100644 --- a/toolkit/components/telemetry/WebrtcTelemetry.cpp +++ b/toolkit/components/telemetry/other/WebrtcTelemetry.cpp @@ -5,8 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "Telemetry.h" -#include "TelemetryCommon.h" +#include "mozilla/Telemetry.h" #include "WebrtcTelemetry.h" #include "jsapi.h" #include "nsPrintfCString.h" diff --git a/toolkit/components/telemetry/WebrtcTelemetry.h b/toolkit/components/telemetry/other/WebrtcTelemetry.h similarity index 97% rename from toolkit/components/telemetry/WebrtcTelemetry.h rename to toolkit/components/telemetry/other/WebrtcTelemetry.h index ed87c71073ff..6f7f9e192a16 100644 --- a/toolkit/components/telemetry/WebrtcTelemetry.h +++ b/toolkit/components/telemetry/other/WebrtcTelemetry.h @@ -9,7 +9,7 @@ #include "nsBaseHashtable.h" #include "nsHashKeys.h" -#include "TelemetryCommon.h" +#include "core/TelemetryCommon.h" class WebrtcTelemetry { public: diff --git a/toolkit/components/telemetry/TelemetryEventPing.jsm b/toolkit/components/telemetry/pings/EventPing.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryEventPing.jsm rename to toolkit/components/telemetry/pings/EventPing.jsm diff --git a/toolkit/components/telemetry/TelemetryHealthPing.jsm b/toolkit/components/telemetry/pings/HealthPing.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryHealthPing.jsm rename to toolkit/components/telemetry/pings/HealthPing.jsm diff --git a/toolkit/components/telemetry/TelemetryModules.jsm b/toolkit/components/telemetry/pings/ModulesPing.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryModules.jsm rename to toolkit/components/telemetry/pings/ModulesPing.jsm diff --git a/toolkit/components/telemetry/TelemetrySession.jsm b/toolkit/components/telemetry/pings/TelemetrySession.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetrySession.jsm rename to toolkit/components/telemetry/pings/TelemetrySession.jsm diff --git a/toolkit/components/telemetry/UpdatePing.jsm b/toolkit/components/telemetry/pings/UpdatePing.jsm similarity index 100% rename from toolkit/components/telemetry/UpdatePing.jsm rename to toolkit/components/telemetry/pings/UpdatePing.jsm diff --git a/toolkit/components/telemetry/schemas/core.schema.json b/toolkit/components/telemetry/schemas/core.schema.json deleted file mode 100644 index 327cdc298904..000000000000 --- a/toolkit/components/telemetry/schemas/core.schema.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "$schema" : "http://json-schema.org/draft-04/schema#", - "type" : "object", - "name" : "core", - "properties" : { - "arch" : { - "type" : "string" - }, - "clientId" : { - "type" : "string", - "pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$" - }, - "device" : { - "type" : "string" - }, - "experiments" : { - "type" : "array", - "items" : { - "type" : "string" - } - }, - "locale" : { - "type" : "string" - }, - "os" : { - "type" : "string" - }, - "osversion" : { - "type" : "string" - }, - "seq" : { - "type" : "integer", - "minimum": 0 - }, - "v" : { - "type" : "integer", - "enum" : [ 1 ] - } - }, - "required" : ["arch", "clientId", "device", "locale", "os", "osversion", "seq", "v"] -} diff --git a/toolkit/components/telemetry/tests/gtest/TelemetryTestHelpers.cpp b/toolkit/components/telemetry/tests/gtest/TelemetryTestHelpers.cpp index da4fe71c9775..bd1db74c1c92 100644 --- a/toolkit/components/telemetry/tests/gtest/TelemetryTestHelpers.cpp +++ b/toolkit/components/telemetry/tests/gtest/TelemetryTestHelpers.cpp @@ -6,7 +6,7 @@ #include "gtest/gtest.h" #include "mozilla/CycleCollectedJSContext.h" -#include "TelemetryCommon.h" +#include "core/TelemetryCommon.h" #include "mozilla/Unused.h" using namespace mozilla; diff --git a/toolkit/components/telemetry/tests/gtest/TestCombinedStacks.cpp b/toolkit/components/telemetry/tests/gtest/TestCombinedStacks.cpp index 27225beb13e8..fa75ea5ace43 100644 --- a/toolkit/components/telemetry/tests/gtest/TestCombinedStacks.cpp +++ b/toolkit/components/telemetry/tests/gtest/TestCombinedStacks.cpp @@ -2,8 +2,8 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ -#include "CombinedStacks.h" -#include "ProcessedStack.h" +#include "other/CombinedStacks.h" +#include "other/ProcessedStack.h" using namespace mozilla::Telemetry; using namespace TelemetryTestHelpers; diff --git a/toolkit/components/telemetry/tests/gtest/TestCounters.cpp b/toolkit/components/telemetry/tests/gtest/TestCounters.cpp index eefe4f6f090e..0df7879b17ce 100644 --- a/toolkit/components/telemetry/tests/gtest/TestCounters.cpp +++ b/toolkit/components/telemetry/tests/gtest/TestCounters.cpp @@ -6,7 +6,7 @@ #include "gtest/gtest.h" #include "js/Conversions.h" #include "nsITelemetry.h" -#include "Telemetry.h" +#include "mozilla/Telemetry.h" #include "TelemetryFixture.h" #include "TelemetryTestHelpers.h" diff --git a/toolkit/components/telemetry/tests/gtest/TestHistograms.cpp b/toolkit/components/telemetry/tests/gtest/TestHistograms.cpp index bfc53da43303..dee74f1ee609 100644 --- a/toolkit/components/telemetry/tests/gtest/TestHistograms.cpp +++ b/toolkit/components/telemetry/tests/gtest/TestHistograms.cpp @@ -6,7 +6,7 @@ #include "gtest/gtest.h" #include "js/Conversions.h" #include "nsITelemetry.h" -#include "Telemetry.h" +#include "mozilla/Telemetry.h" #include "TelemetryFixture.h" #include "TelemetryTestHelpers.h" diff --git a/toolkit/components/telemetry/tests/gtest/TestScalars.cpp b/toolkit/components/telemetry/tests/gtest/TestScalars.cpp index f5cc7f523529..e8a808a77314 100644 --- a/toolkit/components/telemetry/tests/gtest/TestScalars.cpp +++ b/toolkit/components/telemetry/tests/gtest/TestScalars.cpp @@ -10,10 +10,10 @@ #include "nsJSUtils.h" // nsAutoJSString #include "nsITelemetry.h" #include "nsThreadUtils.h" -#include "Telemetry.h" +#include "mozilla/Telemetry.h" #include "mozilla/TelemetryProcessEnums.h" #include "TelemetryFixture.h" -#include "TelemetryScalar.h" +#include "core/TelemetryScalar.h" #include "TelemetryTestHelpers.h" using namespace mozilla; From f5298ed4fe2454f8103876200776e801ae099048 Mon Sep 17 00:00:00 2001 From: Alessio Placitelli Date: Mon, 3 Sep 2018 10:15:26 +0000 Subject: [PATCH 12/61] Bug 1484611 - Rename and fixup test files. r=chutten,janerik We settled on a new naming scheme for ping implementation: {name}Ping.jsm. This changes the test filenames as well and fixup the path used to reference the JSM files. Depends on D4427 Differential Revision: https://phabricator.services.mozilla.com/D4428 --HG-- rename : toolkit/components/telemetry/tests/unit/test_TelemetryEventPing.js => toolkit/components/telemetry/tests/unit/test_EventPing.js rename : toolkit/components/telemetry/tests/unit/test_TelemetryEventPing_disabled.js => toolkit/components/telemetry/tests/unit/test_EventPing_disabled.js rename : toolkit/components/telemetry/tests/unit/test_TelemetryHealthPing.js => toolkit/components/telemetry/tests/unit/test_HealthPing.js rename : toolkit/components/telemetry/tests/unit/test_TelemetryModules.js => toolkit/components/telemetry/tests/unit/test_ModulesPing.js extra : moz-landing-system : lando --- toolkit/components/telemetry/app/TelemetryController.jsm | 6 +++--- toolkit/components/telemetry/app/TelemetrySend.jsm | 2 +- toolkit/components/telemetry/app/TelemetryStorage.jsm | 2 +- .../telemetry/tests/python/test_gen_event_data_json.py | 3 +++ .../telemetry/tests/python/test_gen_scalar_data_json.py | 2 ++ .../tests/python/test_histogramtools_non_strict.py | 5 ++++- .../telemetry/tests/python/test_histogramtools_strict.py | 7 +++++-- .../telemetry/tests/python/test_parse_scalars.py | 7 +++++-- .../{test_TelemetryEventPing.js => test_EventPing.js} | 4 ++-- ...ryEventPing_disabled.js => test_EventPing_disabled.js} | 2 +- .../{test_TelemetryHealthPing.js => test_HealthPing.js} | 4 ++-- .../{test_TelemetryModules.js => test_ModulesPing.js} | 2 +- .../components/telemetry/tests/unit/test_TelemetrySend.js | 2 +- toolkit/components/telemetry/tests/unit/xpcshell.ini | 8 ++++---- 14 files changed, 35 insertions(+), 21 deletions(-) rename toolkit/components/telemetry/tests/unit/{test_TelemetryEventPing.js => test_EventPing.js} (98%) rename toolkit/components/telemetry/tests/unit/{test_TelemetryEventPing_disabled.js => test_EventPing_disabled.js} (94%) rename toolkit/components/telemetry/tests/unit/{test_TelemetryHealthPing.js => test_HealthPing.js} (98%) rename toolkit/components/telemetry/tests/unit/{test_TelemetryModules.js => test_ModulesPing.js} (99%) diff --git a/toolkit/components/telemetry/app/TelemetryController.jsm b/toolkit/components/telemetry/app/TelemetryController.jsm index 2cca9957a7a4..f7fefe2f1e9b 100644 --- a/toolkit/components/telemetry/app/TelemetryController.jsm +++ b/toolkit/components/telemetry/app/TelemetryController.jsm @@ -59,10 +59,10 @@ XPCOMUtils.defineLazyModuleGetters(this, { TelemetrySession: "resource://gre/modules/TelemetrySession.jsm", TelemetrySend: "resource://gre/modules/TelemetrySend.jsm", TelemetryReportingPolicy: "resource://gre/modules/TelemetryReportingPolicy.jsm", - TelemetryModules: "resource://gre/modules/TelemetryModules.jsm", + TelemetryModules: "resource://gre/modules/ModulesPing.jsm", UpdatePing: "resource://gre/modules/UpdatePing.jsm", - TelemetryHealthPing: "resource://gre/modules/TelemetryHealthPing.jsm", - TelemetryEventPing: "resource://gre/modules/TelemetryEventPing.jsm", + TelemetryHealthPing: "resource://gre/modules/HealthPing.jsm", + TelemetryEventPing: "resource://gre/modules/EventPing.jsm", OS: "resource://gre/modules/osfile.jsm", }); diff --git a/toolkit/components/telemetry/app/TelemetrySend.jsm b/toolkit/components/telemetry/app/TelemetrySend.jsm index b319d416feb1..de1b1e85dcb4 100644 --- a/toolkit/components/telemetry/app/TelemetrySend.jsm +++ b/toolkit/components/telemetry/app/TelemetrySend.jsm @@ -35,7 +35,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "Telemetry", "@mozilla.org/base/telemetry;1", "nsITelemetry"); ChromeUtils.defineModuleGetter(this, "TelemetryHealthPing", - "resource://gre/modules/TelemetryHealthPing.jsm"); + "resource://gre/modules/HealthPing.jsm"); const Utils = TelemetryUtils; diff --git a/toolkit/components/telemetry/app/TelemetryStorage.jsm b/toolkit/components/telemetry/app/TelemetryStorage.jsm index 765d645b9c0a..3c2251b83c6b 100644 --- a/toolkit/components/telemetry/app/TelemetryStorage.jsm +++ b/toolkit/components/telemetry/app/TelemetryStorage.jsm @@ -39,7 +39,7 @@ XPCOMUtils.defineLazyGetter(this, "gAbortedSessionFilePath", function() { ChromeUtils.defineModuleGetter(this, "CommonUtils", "resource://services-common/utils.js"); ChromeUtils.defineModuleGetter(this, "TelemetryHealthPing", - "resource://gre/modules/TelemetryHealthPing.jsm"); + "resource://gre/modules/HealthPing.jsm"); // Maxmimum time, in milliseconds, archive pings should be retained. const MAX_ARCHIVED_PINGS_RETENTION_MS = 60 * 24 * 60 * 60 * 1000; // 60 days diff --git a/toolkit/components/telemetry/tests/python/test_gen_event_data_json.py b/toolkit/components/telemetry/tests/python/test_gen_event_data_json.py index afc673786c80..a8ddd6f6df0f 100644 --- a/toolkit/components/telemetry/tests/python/test_gen_event_data_json.py +++ b/toolkit/components/telemetry/tests/python/test_gen_event_data_json.py @@ -13,6 +13,9 @@ from os import path TELEMETRY_ROOT_PATH = path.abspath(path.join(path.dirname(__file__), path.pardir, path.pardir)) sys.path.append(TELEMETRY_ROOT_PATH) +# The generators live in "build_scripts", account for that. +# NOTE: if the generators are moved, this logic will need to be updated. +sys.path.append(path.join(TELEMETRY_ROOT_PATH, "build_scripts")) import gen_event_data # noqa: E402 diff --git a/toolkit/components/telemetry/tests/python/test_gen_scalar_data_json.py b/toolkit/components/telemetry/tests/python/test_gen_scalar_data_json.py index 56178b5092cc..e52831daeab9 100644 --- a/toolkit/components/telemetry/tests/python/test_gen_scalar_data_json.py +++ b/toolkit/components/telemetry/tests/python/test_gen_scalar_data_json.py @@ -13,6 +13,8 @@ from os import path TELEMETRY_ROOT_PATH = path.abspath(path.join(path.dirname(__file__), path.pardir, path.pardir)) sys.path.append(TELEMETRY_ROOT_PATH) +# The generators live in "build_scripts", account for that. +sys.path.append(path.join(TELEMETRY_ROOT_PATH, "build_scripts")) import gen_scalar_data # noqa: E402 diff --git a/toolkit/components/telemetry/tests/python/test_histogramtools_non_strict.py b/toolkit/components/telemetry/tests/python/test_histogramtools_non_strict.py index 3951e29ba5e4..193d84659096 100644 --- a/toolkit/components/telemetry/tests/python/test_histogramtools_non_strict.py +++ b/toolkit/components/telemetry/tests/python/test_histogramtools_non_strict.py @@ -10,7 +10,10 @@ from os import path TELEMETRY_ROOT_PATH = path.abspath(path.join(path.dirname(__file__), path.pardir, path.pardir)) sys.path.append(TELEMETRY_ROOT_PATH) -import parse_histograms # noqa: E402 +# The parsers live in a subdirectory of "build_scripts", account for that. +# NOTE: if the parsers are moved, this logic will need to be updated. +sys.path.append(path.join(TELEMETRY_ROOT_PATH, "build_scripts")) +from parsers import parse_histograms # noqa: E402 def load_histogram(histograms): diff --git a/toolkit/components/telemetry/tests/python/test_histogramtools_strict.py b/toolkit/components/telemetry/tests/python/test_histogramtools_strict.py index d9a3fe63b0c9..2c557667339c 100644 --- a/toolkit/components/telemetry/tests/python/test_histogramtools_strict.py +++ b/toolkit/components/telemetry/tests/python/test_histogramtools_strict.py @@ -10,8 +10,11 @@ from test_histogramtools_non_strict import load_histogram TELEMETRY_ROOT_PATH = path.abspath(path.join(path.dirname(__file__), path.pardir, path.pardir)) sys.path.append(TELEMETRY_ROOT_PATH) -from shared_telemetry_utils import ParserError -import parse_histograms +# The parsers live in a subdirectory of "build_scripts", account for that. +# NOTE: if the parsers are moved, this logic will need to be updated. +sys.path.append(path.join(TELEMETRY_ROOT_PATH, "build_scripts")) +from parsers.shared_telemetry_utils import ParserError +from parsers import parse_histograms class TestParser(unittest.TestCase): diff --git a/toolkit/components/telemetry/tests/python/test_parse_scalars.py b/toolkit/components/telemetry/tests/python/test_parse_scalars.py index a6d47ac28447..ce3a22821d49 100644 --- a/toolkit/components/telemetry/tests/python/test_parse_scalars.py +++ b/toolkit/components/telemetry/tests/python/test_parse_scalars.py @@ -10,8 +10,11 @@ from os import path TELEMETRY_ROOT_PATH = path.abspath(path.join(path.dirname(__file__), path.pardir, path.pardir)) sys.path.append(TELEMETRY_ROOT_PATH) -from shared_telemetry_utils import ParserError -import parse_scalars +# The parsers live in a subdirectory of "build_scripts", account for that. +# NOTE: if the parsers are moved, this logic will need to be updated. +sys.path.append(path.join(TELEMETRY_ROOT_PATH, "build_scripts")) +from parsers.shared_telemetry_utils import ParserError +from parsers import parse_scalars def load_scalar(scalar): diff --git a/toolkit/components/telemetry/tests/unit/test_TelemetryEventPing.js b/toolkit/components/telemetry/tests/unit/test_EventPing.js similarity index 98% rename from toolkit/components/telemetry/tests/unit/test_TelemetryEventPing.js rename to toolkit/components/telemetry/tests/unit/test_EventPing.js index ae3f42d5c501..06fe61f9fa28 100644 --- a/toolkit/components/telemetry/tests/unit/test_TelemetryEventPing.js +++ b/toolkit/components/telemetry/tests/unit/test_EventPing.js @@ -12,7 +12,7 @@ ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", this); ChromeUtils.import("resource://testing-common/TelemetryArchiveTesting.jsm", this); ChromeUtils.defineModuleGetter(this, "TelemetryEventPing", - "resource://gre/modules/TelemetryEventPing.jsm"); + "resource://gre/modules/EventPing.jsm"); function checkPingStructure(type, payload, options) { Assert.equal(type, TelemetryEventPing.EVENT_PING_TYPE, "Should be an event ping."); @@ -26,7 +26,7 @@ function checkPingStructure(type, payload, options) { } function fakePolicy(set, clear, send) { - let mod = ChromeUtils.import("resource://gre/modules/TelemetryEventPing.jsm", {}); + let mod = ChromeUtils.import("resource://gre/modules/EventPing.jsm", {}); mod.Policy.setTimeout = set; mod.Policy.clearTimeout = clear; mod.Policy.sendPing = send; diff --git a/toolkit/components/telemetry/tests/unit/test_TelemetryEventPing_disabled.js b/toolkit/components/telemetry/tests/unit/test_EventPing_disabled.js similarity index 94% rename from toolkit/components/telemetry/tests/unit/test_TelemetryEventPing_disabled.js rename to toolkit/components/telemetry/tests/unit/test_EventPing_disabled.js index 7a08fd409f14..af86a1e64e92 100644 --- a/toolkit/components/telemetry/tests/unit/test_TelemetryEventPing_disabled.js +++ b/toolkit/components/telemetry/tests/unit/test_EventPing_disabled.js @@ -12,7 +12,7 @@ ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", this); ChromeUtils.import("resource://testing-common/TelemetryArchiveTesting.jsm", this); ChromeUtils.defineModuleGetter(this, "TelemetryEventPing", - "resource://gre/modules/TelemetryEventPing.jsm"); + "resource://gre/modules/EventPing.jsm"); const OPTIN = Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN; diff --git a/toolkit/components/telemetry/tests/unit/test_TelemetryHealthPing.js b/toolkit/components/telemetry/tests/unit/test_HealthPing.js similarity index 98% rename from toolkit/components/telemetry/tests/unit/test_TelemetryHealthPing.js rename to toolkit/components/telemetry/tests/unit/test_HealthPing.js index 93a0724fd211..5293f11bd000 100644 --- a/toolkit/components/telemetry/tests/unit/test_TelemetryHealthPing.js +++ b/toolkit/components/telemetry/tests/unit/test_HealthPing.js @@ -14,7 +14,7 @@ ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", this); ChromeUtils.import("resource://testing-common/TelemetryArchiveTesting.jsm", this); ChromeUtils.defineModuleGetter(this, "TelemetryHealthPing", - "resource://gre/modules/TelemetryHealthPing.jsm"); + "resource://gre/modules/HealthPing.jsm"); function checkHealthPingStructure(ping, expectedFailuresDict) { let payload = ping.payload; @@ -26,7 +26,7 @@ function checkHealthPingStructure(ping, expectedFailuresDict) { } function fakeHealthSchedulerTimer(set, clear) { - let telemetryHealthPing = ChromeUtils.import("resource://gre/modules/TelemetryHealthPing.jsm", {}); + let telemetryHealthPing = ChromeUtils.import("resource://gre/modules/HealthPing.jsm", {}); telemetryHealthPing.Policy.setSchedulerTickTimeout = set; telemetryHealthPing.Policy.clearSchedulerTickTimeout = clear; } diff --git a/toolkit/components/telemetry/tests/unit/test_TelemetryModules.js b/toolkit/components/telemetry/tests/unit/test_ModulesPing.js similarity index 99% rename from toolkit/components/telemetry/tests/unit/test_TelemetryModules.js rename to toolkit/components/telemetry/tests/unit/test_ModulesPing.js index 111131f07856..f8f2a271d7ac 100644 --- a/toolkit/components/telemetry/tests/unit/test_TelemetryModules.js +++ b/toolkit/components/telemetry/tests/unit/test_ModulesPing.js @@ -3,7 +3,7 @@ "use strict"; -ChromeUtils.import("resource://gre/modules/TelemetryModules.jsm"); +ChromeUtils.import("resource://gre/modules/ModulesPing.jsm"); ChromeUtils.import("resource://gre/modules/AppConstants.jsm"); ChromeUtils.import("resource://gre/modules/Preferences.jsm"); ChromeUtils.import("resource://gre/modules/ctypes.jsm"); diff --git a/toolkit/components/telemetry/tests/unit/test_TelemetrySend.js b/toolkit/components/telemetry/tests/unit/test_TelemetrySend.js index bdf3e3b99f13..b6278104965f 100644 --- a/toolkit/components/telemetry/tests/unit/test_TelemetrySend.js +++ b/toolkit/components/telemetry/tests/unit/test_TelemetrySend.js @@ -20,7 +20,7 @@ ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", this); ChromeUtils.import("resource://gre/modules/TelemetryStopwatch.jsm", this); ChromeUtils.defineModuleGetter(this, "TelemetryHealthPing", - "resource://gre/modules/TelemetryHealthPing.jsm"); + "resource://gre/modules/HealthPing.jsm"); XPCOMUtils.defineLazyServiceGetter(Services, "cookies", "@mozilla.org/cookieService;1", "nsICookieService"); diff --git a/toolkit/components/telemetry/tests/unit/xpcshell.ini b/toolkit/components/telemetry/tests/unit/xpcshell.ini index 5e4fa9d2ab4a..fa19989ccd96 100644 --- a/toolkit/components/telemetry/tests/unit/xpcshell.ini +++ b/toolkit/components/telemetry/tests/unit/xpcshell.ini @@ -45,7 +45,7 @@ skip-if = os == "android" [test_TelemetryLateWrites.js] [test_TelemetryLockCount.js] [test_TelemetryController.js] -[test_TelemetryHealthPing.js] +[test_HealthPing.js] skip-if = (verify && (os == 'win')) tags = addons [test_TelemetryController_idle.js] @@ -82,11 +82,11 @@ skip-if = os == "android" # Disabled due to crashes (see bug 1331366) [test_TelemetryEvents_buildFaster.js] [test_ChildEvents.js] skip-if = os == "android" # Disabled due to crashes (see bug 1331366) -[test_TelemetryModules.js] +[test_ModulesPing.js] [test_PingSender.js] skip-if = (os == "android") || (os == "linux" && bits == 32) [test_TelemetryGC.js] [test_TelemetryAndroidEnvironment.js] [test_TelemetryUtils.js] -[test_TelemetryEventPing.js] -[test_TelemetryEventPing_disabled.js] +[test_EventPing.js] +[test_EventPing_disabled.js] From ac3702bff23fdea8ed1780e1c457c2c9d1899c43 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 30 Aug 2018 00:35:08 +0000 Subject: [PATCH 13/61] Bug 1487091 - remove an unused element from a graphics IPDL union; r=aosmond Differential Revision: https://phabricator.services.mozilla.com/D4543 --HG-- extra : moz-landing-system : lando --- gfx/layers/ipc/LayersSurfaces.ipdlh | 1 - 1 file changed, 1 deletion(-) diff --git a/gfx/layers/ipc/LayersSurfaces.ipdlh b/gfx/layers/ipc/LayersSurfaces.ipdlh index 0615d92d5a4f..984d926597fd 100644 --- a/gfx/layers/ipc/LayersSurfaces.ipdlh +++ b/gfx/layers/ipc/LayersSurfaces.ipdlh @@ -151,7 +151,6 @@ union SurfaceDescriptor { SurfaceDescriptorMacIOSurface; SurfaceDescriptorSharedGLTexture; SurfaceDescriptorGPUVideo; - SurfaceDescriptorShared; null_t; }; From d7e758ca6e5800260e72358e3856235477f7f19b Mon Sep 17 00:00:00 2001 From: Rob Wu Date: Tue, 4 Sep 2018 13:17:10 +0000 Subject: [PATCH 14/61] Bug 1462121 - Improve reliability of context.contentWindow/active r=zombie - Register pagehide/pageshow events in the system group and ignore synthetic events to avoid interference from web pages. - Remove unused docShell member. - Fix memory leak in bfcached windows, by ensuring that BaseContext instances can be GC'd when an extension is unloaded, even if the context is associated with a page in the bfcache. - Ensure that context.contentWindow and context.active always have an accurate value. The latter is achieved by moving all contentWindow tracking logic in a new helper class "InnerWindowReference". Differential Revision: https://phabricator.services.mozilla.com/D4072 --HG-- extra : moz-landing-system : lando --- .../components/extensions/ExtensionCommon.jsm | 99 ++++++++---- .../test_ext_contentscript_context.js | 143 +++++++++++++++++- ...est_ext_contentscript_context_isolation.js | 123 +++++++++++++++ .../test/xpcshell/xpcshell-common.ini | 1 + 4 files changed, 333 insertions(+), 33 deletions(-) create mode 100644 toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context_isolation.js diff --git a/toolkit/components/extensions/ExtensionCommon.jsm b/toolkit/components/extensions/ExtensionCommon.jsm index f0a84395b6e3..57344c649789 100644 --- a/toolkit/components/extensions/ExtensionCommon.jsm +++ b/toolkit/components/extensions/ExtensionCommon.jsm @@ -353,6 +353,55 @@ class ExtensionAPI extends EventEmitter { } } +/** + * A wrapper around a window that returns the window iff the inner window + * matches the inner window at the construction of this wrapper. + * + * This wrapper should not be used after the inner window is destroyed. + **/ +class InnerWindowReference { + constructor(contentWindow, innerWindowID) { + this.contentWindow = contentWindow; + this.innerWindowID = innerWindowID; + this.needWindowIDCheck = false; + + contentWindow.addEventListener("pagehide", this, {mozSystemGroup: true}, false); + contentWindow.addEventListener("pageshow", this, {mozSystemGroup: true}, false); + } + + get() { + // If the pagehide event has fired, the inner window ID needs to be checked, + // in case the window ref is dereferenced in a pageshow listener (before our + // pageshow listener was dispatched) or during the unload event. + if (!this.needWindowIDCheck || getInnerWindowID(this.contentWindow) === this.innerWindowID) { + return this.contentWindow; + } + return null; + } + + invalidate() { + // If invalidate() is called while the inner window is in the bfcache, then + // we are unable to remove the event listener, and handleEvent will be + // called once more if the page is revived from the bfcache. + if (this.contentWindow) { + this.contentWindow.removeEventListener("pagehide", this, {mozSystemGroup: true}); + this.contentWindow.removeEventListener("pageshow", this, {mozSystemGroup: true}); + } + this.contentWindow = null; + this.needWindowIDCheck = false; + } + + handleEvent(event) { + if (this.contentWindow) { + this.needWindowIDCheck = event.type === "pagehide"; + } else { + // Remove listener when restoring from the bfcache - see invalidate(). + event.currentTarget.removeEventListener("pagehide", this, {mozSystemGroup: true}); + event.currentTarget.removeEventListener("pageshow", this, {mozSystemGroup: true}); + } + } +} + /** * This class contains the information we have about an individual * extension. It is never instantiated directly, instead subclasses @@ -373,16 +422,13 @@ class BaseContext { this.active = true; this.incognito = null; this.messageManager = null; - this.docShell = null; this.contentWindow = null; this.innerWindowID = 0; } setContentWindow(contentWindow) { - let {document, docShell} = contentWindow; - this.innerWindowID = getInnerWindowID(contentWindow); - this.messageManager = docShell.messageManager; + this.messageManager = contentWindow.docShell.messageManager; if (this.incognito == null) { this.incognito = PrivateBrowsingUtils.isContentWindowPrivate(contentWindow); @@ -390,34 +436,26 @@ class BaseContext { MessageChannel.setupMessageManagers([this.messageManager]); - let onPageShow = event => { - if (!event || event.target === document) { - this.docShell = docShell; - this.contentWindow = contentWindow; - this.active = true; - } - }; - let onPageHide = event => { - if (!event || event.target === document) { - // Put this off until the next tick. - Promise.resolve().then(() => { - this.docShell = null; - this.contentWindow = null; - this.active = false; - }); - } - }; - - onPageShow(); - contentWindow.addEventListener("pagehide", onPageHide, true); - contentWindow.addEventListener("pageshow", onPageShow, true); + let windowRef = new InnerWindowReference(contentWindow, this.innerWindowID); + Object.defineProperty(this, "active", { + configurable: true, + enumerable: true, + get: () => windowRef.get() !== null, + }); + Object.defineProperty(this, "contentWindow", { + configurable: true, + enumerable: true, + get: () => windowRef.get(), + }); this.callOnClose({ close: () => { - onPageHide(); - if (this.active) { - contentWindow.removeEventListener("pagehide", onPageHide, true); - contentWindow.removeEventListener("pageshow", onPageShow, true); - } + // Allow other "close" handlers to use these properties, until the next tick. + Promise.resolve().then(() => { + windowRef.invalidate(); + windowRef = null; + Object.defineProperty(this, "contentWindow", {value: null}); + Object.defineProperty(this, "active", {value: false}); + }); }, }); } @@ -732,6 +770,7 @@ class BaseContext { for (let obj of this.onClose) { obj.close(); } + this.onClose.clear(); } /** diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context.js b/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context.js index d7e161ee4da0..d2e81c3d8cd9 100644 --- a/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context.js +++ b/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context.js @@ -10,7 +10,7 @@ server.registerPathHandler("/dummy", (request, response) => { response.write(""); }); -add_task(async function test_contentscript_context() { +function loadExtension() { function contentScript() { browser.test.sendMessage("content-script-ready"); @@ -22,10 +22,10 @@ add_task(async function test_contentscript_context() { }); } - let extension = ExtensionTestUtils.loadExtension({ + return ExtensionTestUtils.loadExtension({ manifest: { content_scripts: [{ - "matches": ["http://example.com/dummy"], + "matches": ["http://example.com/dummy*"], "js": ["content_script.js"], "run_at": "document_start", }], @@ -35,7 +35,10 @@ add_task(async function test_contentscript_context() { "content_script.js": contentScript, }, }); +} +add_task(async function test_contentscript_context() { + let extension = loadExtension(); await extension.startup(); let contentPage = await ExtensionTestUtils.loadContentPage("http://example.com/dummy"); @@ -75,3 +78,137 @@ add_task(async function test_contentscript_context() { await extension.awaitMessage("content-script-hide"); await extension.unload(); }); + +add_task(async function test_contentscript_context_unload_while_in_bfcache() { + let contentPage = await ExtensionTestUtils.loadContentPage("http://example.com/dummy?first"); + let extension = loadExtension(); + await extension.startup(); + await extension.awaitMessage("content-script-ready"); + + // Get the content script context and check that it points to the correct window. + await contentPage.spawn(extension.id, async extensionId => { + let {DocumentManager} = ChromeUtils.import("resource://gre/modules/ExtensionContent.jsm", {}); + // Save context so we can verify that contentWindow is nulled after unload. + this.context = DocumentManager.getContext(extensionId, this.content); + + Assert.equal(this.context.contentWindow, this.content, "Context's contentWindow property is correct"); + + this.contextUnloadedPromise = new Promise(resolve => { + this.context.callOnClose({close: resolve}); + }); + this.pageshownPromise = new Promise(resolve => { + this.content.addEventListener("pageshow", () => { + // Yield to the event loop once more to ensure that all pageshow event + // handlers have been dispatched before fulfilling the promise. + let {setTimeout} = ChromeUtils.import("resource://gre/modules/Timer.jsm", {}); + setTimeout(resolve, 0); + }, {once: true, mozSystemGroup: true}); + }); + + // Navigate so that the content page is hidden in the bfcache. + this.content.location = "http://example.org/dummy?second"; + }); + + await extension.awaitMessage("content-script-hide"); + + await extension.unload(); + await contentPage.spawn(null, async () => { + await this.contextUnloadedPromise; + Assert.equal(this.context.unloaded, true, "Context has been unloaded"); + + // Normally, when a page is not in the bfcache, context.contentWindow is + // not null when the callOnClose handler is invoked (this is checked by the + // previous subtest). + // Now wait a little bit and check again to ensure that the contentWindow + // property is not somehow restored. + await new Promise(resolve => this.content.setTimeout(resolve, 0)); + Assert.equal(this.context.contentWindow, null, "Context's contentWindow property is null"); + + // Navigate back so the content page is resurrected from the bfcache. + this.content.history.back(); + + await this.pageshownPromise; + + Assert.equal(this.context.contentWindow, null, "Context's contentWindow property is null after restore from bfcache"); + }); + + await contentPage.close(); +}); + +add_task(async function test_contentscript_context_valid_during_execution() { + // This test does the following: + // - Load page + // - Load extension; inject content script. + // - Navigate page; pagehide triggered. + // - Navigate back; pageshow triggered. + // - Close page; pagehide, unload triggered. + // At each of these last four events, the validity of the context is checked. + + function contentScript() { + browser.test.sendMessage("content-script-ready"); + window.wrappedJSObject.checkContextIsValid("Context is valid on execution"); + + window.addEventListener("pagehide", () => { + window.wrappedJSObject.checkContextIsValid("Context is valid on pagehide"); + browser.test.sendMessage("content-script-hide"); + }, true); + window.addEventListener("pageshow", () => { + window.wrappedJSObject.checkContextIsValid("Context is valid on pageshow"); + + // This unload listener is registered after pageshow, to ensure that the + // page can be stored in the bfcache at the previous pagehide. + window.addEventListener("unload", () => { + window.wrappedJSObject.checkContextIsValid("Context is valid on unload"); + browser.test.sendMessage("content-script-unload"); + }); + + browser.test.sendMessage("content-script-show"); + }); + } + + let extension = ExtensionTestUtils.loadExtension({ + manifest: { + content_scripts: [{ + "matches": ["http://example.com/dummy*"], + "js": ["content_script.js"], + }], + }, + + files: { + "content_script.js": contentScript, + }, + }); + + let contentPage = await ExtensionTestUtils.loadContentPage("http://example.com/dummy?first"); + await contentPage.spawn(extension.id, async extensionId => { + let context; + let checkContextIsValid = (description) => { + if (!context) { + let {DocumentManager} = ChromeUtils.import("resource://gre/modules/ExtensionContent.jsm", {}); + context = DocumentManager.getContext(extensionId, this.content); + } + Assert.equal(context.contentWindow, this.content, `${description}: contentWindow`); + Assert.equal(context.active, true, `${description}: active`); + }; + Cu.exportFunction(checkContextIsValid, this.content, {defineAs: "checkContextIsValid"}); + }); + await extension.startup(); + await extension.awaitMessage("content-script-ready"); + + await contentPage.spawn(extension.id, async extensionId => { + // Navigate so that the content page is frozen in the bfcache. + this.content.location = "http://example.org/dummy?second"; + }); + + await extension.awaitMessage("content-script-hide"); + await contentPage.spawn(null, async () => { + // Navigate back so the content page is resurrected from the bfcache. + this.content.history.back(); + }); + + await extension.awaitMessage("content-script-show"); + await contentPage.close(); + await extension.awaitMessage("content-script-hide"); + await extension.awaitMessage("content-script-unload"); + await extension.unload(); +}); diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context_isolation.js b/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context_isolation.js new file mode 100644 index 000000000000..6f81730d66a2 --- /dev/null +++ b/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context_isolation.js @@ -0,0 +1,123 @@ +"use strict"; + +/* globals exportFunction */ +/* eslint-disable mozilla/balanced-listeners */ + +const server = createHttpServer({hosts: ["example.com", "example.org"]}); + +server.registerPathHandler("/dummy", (request, response) => { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "text/html", false); + response.write(""); +}); + +server.registerPathHandler("/bfcachetestpage", (request, response) => { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "text/html;charset=utf-8", false); + response.write(` +`); +}); + +add_task(async function test_contentscript_context_isolation() { + function contentScript() { + browser.test.sendMessage("content-script-ready"); + + exportFunction(browser.test.sendMessage, window, {defineAs: "browserTestSendMessage"}); + + window.addEventListener("pageshow", () => { + browser.test.fail("pageshow should have been suppressed by stopImmediatePropagation"); + }); + window.addEventListener("pagehide", () => { + browser.test.fail("pagehide should have been suppressed by stopImmediatePropagation"); + }, true); + } + + let extension = ExtensionTestUtils.loadExtension({ + manifest: { + content_scripts: [{ + "matches": ["http://example.com/bfcachetestpage"], + "js": ["content_script.js"], + }], + }, + + files: { + "content_script.js": contentScript, + }, + }); + + let contentPage = await ExtensionTestUtils.loadContentPage("http://example.com/bfcachetestpage"); + await extension.startup(); + await extension.awaitMessage("content-script-ready"); + + // Get the content script context and check that it points to the correct window. + await contentPage.spawn(extension.id, async extensionId => { + let {DocumentManager} = ChromeUtils.import("resource://gre/modules/ExtensionContent.jsm", {}); + this.context = DocumentManager.getContext(extensionId, this.content); + + Assert.ok(this.context, "Got content script context"); + + Assert.equal(this.context.contentWindow, this.content, "Context's contentWindow property is correct"); + + // Navigate so that the content page is hidden in the bfcache. + + this.content.location = "http://example.org/dummy?noscripthere1"; + }); + + await extension.awaitMessage("content-script-hide"); + + await contentPage.spawn(null, async () => { + Assert.equal(this.context.contentWindow, null, "Context's contentWindow property is null"); + Assert.ok(this.context.sandbox, "Context's sandbox exists"); + + // Navigate back so the content page is resurrected from the bfcache. + this.content.history.back(); + }); + + await extension.awaitMessage("content-script-show"); + + await contentPage.spawn(null, async () => { + Assert.equal(this.context.contentWindow, this.content, "Context's contentWindow property is correct"); + Assert.ok(this.context.sandbox, "Context's sandbox exists before unload"); + + let contextUnloadedPromise = new Promise(resolve => { + this.context.callOnClose({close: resolve}); + }); + + // Now add an "unload" event listener, which should prevent a page from entering the bfcache. + await new Promise((resolve) => { + this.content.addEventListener("unload", () => { + Assert.equal(this.context.contentWindow, this.content, "Context's contentWindow property should be non-null at unload"); + resolve(); + }); + this.content.location = "http://example.org/dummy?noscripthere2"; + }); + + await contextUnloadedPromise; + }); + + await extension.awaitMessage("content-script-unload"); + + await contentPage.spawn(null, async () => { + Assert.equal(this.context.sandbox, null, "Context's sandbox has been destroyed after unload"); + }); + + await contentPage.close(); + await extension.unload(); +}); diff --git a/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini b/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini index 4f3604138ceb..38d714eb8245 100644 --- a/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini +++ b/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini @@ -25,6 +25,7 @@ skip-if = appname == "thunderbird" || os == "android" [test_ext_contentscript_async_loading.js] skip-if = os == 'android' && debug # The generated script takes too long to load on Android debug [test_ext_contentscript_context.js] +[test_ext_contentscript_context_isolation.js] [test_ext_contentscript_create_iframe.js] [test_ext_contentscript_css.js] [test_ext_contentscript_exporthelpers.js] From 7d53ec126f15ffc3c9ced98d011f8ed9bcac712e Mon Sep 17 00:00:00 2001 From: shindli Date: Tue, 4 Sep 2018 16:24:35 +0300 Subject: [PATCH 15/61] Backed out changeset f7c41ba8b88d (bug 1484611) for bustages in /builds/worker/workspace/build/src/toolkit/components/telemetry/tests/python/test_gen_scalar_data_json.py on a CLOSED TREE --HG-- rename : toolkit/components/telemetry/other/CombinedStacks.cpp => toolkit/components/telemetry/CombinedStacks.cpp rename : toolkit/components/telemetry/other/CombinedStacks.h => toolkit/components/telemetry/CombinedStacks.h rename : toolkit/components/telemetry/core/EventInfo.h => toolkit/components/telemetry/EventInfo.h rename : toolkit/components/telemetry/other/GCTelemetry.jsm => toolkit/components/telemetry/GCTelemetry.jsm rename : toolkit/components/telemetry/other/KeyedStackCapturer.cpp => toolkit/components/telemetry/KeyedStackCapturer.cpp rename : toolkit/components/telemetry/other/KeyedStackCapturer.h => toolkit/components/telemetry/KeyedStackCapturer.h rename : toolkit/components/telemetry/other/ProcessedStack.cpp => toolkit/components/telemetry/ProcessedStack.cpp rename : toolkit/components/telemetry/other/ProcessedStack.h => toolkit/components/telemetry/ProcessedStack.h rename : toolkit/components/telemetry/core/ScalarInfo.h => toolkit/components/telemetry/ScalarInfo.h rename : toolkit/components/telemetry/core/Telemetry.cpp => toolkit/components/telemetry/Telemetry.cpp rename : toolkit/components/telemetry/core/Telemetry.h => toolkit/components/telemetry/Telemetry.h rename : toolkit/components/telemetry/app/TelemetryArchive.jsm => toolkit/components/telemetry/TelemetryArchive.jsm rename : toolkit/components/telemetry/core/TelemetryCommon.cpp => toolkit/components/telemetry/TelemetryCommon.cpp rename : toolkit/components/telemetry/core/TelemetryCommon.h => toolkit/components/telemetry/TelemetryCommon.h rename : toolkit/components/telemetry/app/TelemetryController.jsm => toolkit/components/telemetry/TelemetryController.jsm rename : toolkit/components/telemetry/app/TelemetryEnvironment.jsm => toolkit/components/telemetry/TelemetryEnvironment.jsm rename : toolkit/components/telemetry/core/TelemetryEvent.cpp => toolkit/components/telemetry/TelemetryEvent.cpp rename : toolkit/components/telemetry/core/TelemetryEvent.h => toolkit/components/telemetry/TelemetryEvent.h rename : toolkit/components/telemetry/pings/EventPing.jsm => toolkit/components/telemetry/TelemetryEventPing.jsm rename : toolkit/components/telemetry/pings/HealthPing.jsm => toolkit/components/telemetry/TelemetryHealthPing.jsm rename : toolkit/components/telemetry/core/TelemetryHistogram.cpp => toolkit/components/telemetry/TelemetryHistogram.cpp rename : toolkit/components/telemetry/core/TelemetryHistogram.h => toolkit/components/telemetry/TelemetryHistogram.h rename : toolkit/components/telemetry/other/TelemetryIOInterposeObserver.cpp => toolkit/components/telemetry/TelemetryIOInterposeObserver.cpp rename : toolkit/components/telemetry/other/TelemetryIOInterposeObserver.h => toolkit/components/telemetry/TelemetryIOInterposeObserver.h rename : toolkit/components/telemetry/pings/ModulesPing.jsm => toolkit/components/telemetry/TelemetryModules.jsm rename : toolkit/components/telemetry/app/TelemetryReportingPolicy.jsm => toolkit/components/telemetry/TelemetryReportingPolicy.jsm rename : toolkit/components/telemetry/core/TelemetryScalar.cpp => toolkit/components/telemetry/TelemetryScalar.cpp rename : toolkit/components/telemetry/core/TelemetryScalar.h => toolkit/components/telemetry/TelemetryScalar.h rename : toolkit/components/telemetry/app/TelemetrySend.jsm => toolkit/components/telemetry/TelemetrySend.jsm rename : toolkit/components/telemetry/pings/TelemetrySession.jsm => toolkit/components/telemetry/TelemetrySession.jsm rename : toolkit/components/telemetry/app/TelemetryStopwatch.jsm => toolkit/components/telemetry/TelemetryStopwatch.jsm rename : toolkit/components/telemetry/app/TelemetryStorage.jsm => toolkit/components/telemetry/TelemetryStorage.jsm rename : toolkit/components/telemetry/app/TelemetryTimestamps.jsm => toolkit/components/telemetry/TelemetryTimestamps.jsm rename : toolkit/components/telemetry/app/TelemetryUtils.jsm => toolkit/components/telemetry/TelemetryUtils.jsm rename : toolkit/components/telemetry/other/UITelemetry.jsm => toolkit/components/telemetry/UITelemetry.jsm rename : toolkit/components/telemetry/pings/UpdatePing.jsm => toolkit/components/telemetry/UpdatePing.jsm rename : toolkit/components/telemetry/other/WebrtcTelemetry.cpp => toolkit/components/telemetry/WebrtcTelemetry.cpp rename : toolkit/components/telemetry/other/WebrtcTelemetry.h => toolkit/components/telemetry/WebrtcTelemetry.h rename : toolkit/components/telemetry/build_scripts/gen_event_data.py => toolkit/components/telemetry/gen_event_data.py rename : toolkit/components/telemetry/build_scripts/gen_event_enum.py => toolkit/components/telemetry/gen_event_enum.py rename : toolkit/components/telemetry/build_scripts/gen_histogram_data.py => toolkit/components/telemetry/gen_histogram_data.py rename : toolkit/components/telemetry/build_scripts/gen_histogram_enum.py => toolkit/components/telemetry/gen_histogram_enum.py rename : toolkit/components/telemetry/build_scripts/gen_histogram_phf.py => toolkit/components/telemetry/gen_histogram_phf.py rename : toolkit/components/telemetry/build_scripts/gen_process_data.py => toolkit/components/telemetry/gen_process_data.py rename : toolkit/components/telemetry/build_scripts/gen_process_enum.py => toolkit/components/telemetry/gen_process_enum.py rename : toolkit/components/telemetry/build_scripts/gen_scalar_data.py => toolkit/components/telemetry/gen_scalar_data.py rename : toolkit/components/telemetry/build_scripts/gen_scalar_enum.py => toolkit/components/telemetry/gen_scalar_enum.py rename : toolkit/components/telemetry/core/ipc/TelemetryComms.h => toolkit/components/telemetry/ipc/TelemetryComms.h rename : toolkit/components/telemetry/core/ipc/TelemetryIPC.cpp => toolkit/components/telemetry/ipc/TelemetryIPC.cpp rename : toolkit/components/telemetry/core/ipc/TelemetryIPC.h => toolkit/components/telemetry/ipc/TelemetryIPC.h rename : toolkit/components/telemetry/core/ipc/TelemetryIPCAccumulator.cpp => toolkit/components/telemetry/ipc/TelemetryIPCAccumulator.cpp rename : toolkit/components/telemetry/core/ipc/TelemetryIPCAccumulator.h => toolkit/components/telemetry/ipc/TelemetryIPCAccumulator.h rename : toolkit/components/telemetry/core/nsITelemetry.idl => toolkit/components/telemetry/nsITelemetry.idl rename : toolkit/components/telemetry/build_scripts/parsers/parse_events.py => toolkit/components/telemetry/parse_events.py rename : toolkit/components/telemetry/build_scripts/parsers/parse_histograms.py => toolkit/components/telemetry/parse_histograms.py rename : toolkit/components/telemetry/build_scripts/parsers/parse_scalars.py => toolkit/components/telemetry/parse_scalars.py rename : toolkit/components/telemetry/build_scripts/parsers/shared_telemetry_utils.py => toolkit/components/telemetry/shared_telemetry_utils.py --- .../telemetry/{other => }/CombinedStacks.cpp | 0 .../telemetry/{other => }/CombinedStacks.h | 0 .../telemetry/{core => }/EventInfo.h | 0 .../telemetry/{other => }/GCTelemetry.jsm | 0 .../{other => }/KeyedStackCapturer.cpp | 0 .../{other => }/KeyedStackCapturer.h | 2 +- .../telemetry/{other => }/ProcessedStack.cpp | 0 .../telemetry/{other => }/ProcessedStack.h | 0 .../telemetry/{core => }/ScalarInfo.h | 0 .../telemetry/{core => }/Telemetry.cpp | 8 +- .../telemetry/{core => }/Telemetry.h | 0 .../telemetry/{app => }/TelemetryArchive.jsm | 0 .../telemetry/{core => }/TelemetryCommon.cpp | 0 .../telemetry/{core => }/TelemetryCommon.h | 0 .../{app => }/TelemetryController.jsm | 0 .../{app => }/TelemetryEnvironment.jsm | 0 .../telemetry/{core => }/TelemetryEvent.cpp | 0 .../telemetry/{core => }/TelemetryEvent.h | 0 .../EventPing.jsm => TelemetryEventPing.jsm} | 0 ...HealthPing.jsm => TelemetryHealthPing.jsm} | 0 .../{core => }/TelemetryHistogram.cpp | 0 .../telemetry/{core => }/TelemetryHistogram.h | 0 .../TelemetryIOInterposeObserver.cpp | 2 +- .../TelemetryIOInterposeObserver.h | 2 +- .../ModulesPing.jsm => TelemetryModules.jsm} | 0 .../{app => }/TelemetryReportingPolicy.jsm | 0 .../telemetry/{core => }/TelemetryScalar.cpp | 0 .../telemetry/{core => }/TelemetryScalar.h | 0 .../telemetry/{app => }/TelemetrySend.jsm | 0 .../{pings => }/TelemetrySession.jsm | 0 .../{app => }/TelemetryStopwatch.jsm | 0 .../telemetry/{app => }/TelemetryStorage.jsm | 0 .../{app => }/TelemetryTimestamps.jsm | 0 .../telemetry/{app => }/TelemetryUtils.jsm | 0 .../telemetry/{other => }/UITelemetry.jsm | 0 .../telemetry/{pings => }/UpdatePing.jsm | 0 .../telemetry/{other => }/WebrtcTelemetry.cpp | 3 +- .../telemetry/{other => }/WebrtcTelemetry.h | 2 +- .../build_scripts/parsers/__init__.py | 0 .../TelemetryGeckoViewPersistence.cpp | 4 +- .../geckoview/TelemetryGeckoViewTesting.cpp | 2 +- .../geckoview/gtest/TestGeckoView.cpp | 4 +- .../telemetry/gen-histogram-bucket-ranges.py | 53 +++++++++++ .../{build_scripts => }/gen_event_data.py | 6 +- .../{build_scripts => }/gen_event_enum.py | 4 +- .../{build_scripts => }/gen_histogram_data.py | 4 +- .../{build_scripts => }/gen_histogram_enum.py | 4 +- .../{build_scripts => }/gen_histogram_phf.py | 4 +- .../{build_scripts => }/gen_process_data.py | 2 +- .../{build_scripts => }/gen_process_enum.py | 2 +- .../{build_scripts => }/gen_scalar_data.py | 6 +- .../{build_scripts => }/gen_scalar_enum.py | 4 +- .../telemetry/{core => }/ipc/TelemetryComms.h | 0 .../telemetry/{core => }/ipc/TelemetryIPC.cpp | 0 .../telemetry/{core => }/ipc/TelemetryIPC.h | 0 .../ipc/TelemetryIPCAccumulator.cpp | 4 +- .../{core => }/ipc/TelemetryIPCAccumulator.h | 0 toolkit/components/telemetry/moz.build | 90 +++++++++---------- .../telemetry/{core => }/nsITelemetry.idl | 0 .../parsers => }/parse_events.py | 0 .../parsers => }/parse_histograms.py | 9 +- .../parsers => }/parse_scalars.py | 0 .../telemetry/schemas/core.schema.json | 41 +++++++++ .../parsers => }/shared_telemetry_utils.py | 0 .../tests/gtest/TelemetryTestHelpers.cpp | 2 +- .../tests/gtest/TestCombinedStacks.cpp | 4 +- .../telemetry/tests/gtest/TestCounters.cpp | 2 +- .../telemetry/tests/gtest/TestHistograms.cpp | 2 +- .../telemetry/tests/gtest/TestScalars.cpp | 4 +- 69 files changed, 183 insertions(+), 93 deletions(-) rename toolkit/components/telemetry/{other => }/CombinedStacks.cpp (100%) rename toolkit/components/telemetry/{other => }/CombinedStacks.h (100%) rename toolkit/components/telemetry/{core => }/EventInfo.h (100%) rename toolkit/components/telemetry/{other => }/GCTelemetry.jsm (100%) rename toolkit/components/telemetry/{other => }/KeyedStackCapturer.cpp (100%) rename toolkit/components/telemetry/{other => }/KeyedStackCapturer.h (98%) rename toolkit/components/telemetry/{other => }/ProcessedStack.cpp (100%) rename toolkit/components/telemetry/{other => }/ProcessedStack.h (100%) rename toolkit/components/telemetry/{core => }/ScalarInfo.h (100%) rename toolkit/components/telemetry/{core => }/Telemetry.cpp (99%) rename toolkit/components/telemetry/{core => }/Telemetry.h (100%) rename toolkit/components/telemetry/{app => }/TelemetryArchive.jsm (100%) rename toolkit/components/telemetry/{core => }/TelemetryCommon.cpp (100%) rename toolkit/components/telemetry/{core => }/TelemetryCommon.h (100%) rename toolkit/components/telemetry/{app => }/TelemetryController.jsm (100%) rename toolkit/components/telemetry/{app => }/TelemetryEnvironment.jsm (100%) rename toolkit/components/telemetry/{core => }/TelemetryEvent.cpp (100%) rename toolkit/components/telemetry/{core => }/TelemetryEvent.h (100%) rename toolkit/components/telemetry/{pings/EventPing.jsm => TelemetryEventPing.jsm} (100%) rename toolkit/components/telemetry/{pings/HealthPing.jsm => TelemetryHealthPing.jsm} (100%) rename toolkit/components/telemetry/{core => }/TelemetryHistogram.cpp (100%) rename toolkit/components/telemetry/{core => }/TelemetryHistogram.h (100%) rename toolkit/components/telemetry/{other => }/TelemetryIOInterposeObserver.cpp (99%) rename toolkit/components/telemetry/{other => }/TelemetryIOInterposeObserver.h (99%) rename toolkit/components/telemetry/{pings/ModulesPing.jsm => TelemetryModules.jsm} (100%) rename toolkit/components/telemetry/{app => }/TelemetryReportingPolicy.jsm (100%) rename toolkit/components/telemetry/{core => }/TelemetryScalar.cpp (100%) rename toolkit/components/telemetry/{core => }/TelemetryScalar.h (100%) rename toolkit/components/telemetry/{app => }/TelemetrySend.jsm (100%) rename toolkit/components/telemetry/{pings => }/TelemetrySession.jsm (100%) rename toolkit/components/telemetry/{app => }/TelemetryStopwatch.jsm (100%) rename toolkit/components/telemetry/{app => }/TelemetryStorage.jsm (100%) rename toolkit/components/telemetry/{app => }/TelemetryTimestamps.jsm (100%) rename toolkit/components/telemetry/{app => }/TelemetryUtils.jsm (100%) rename toolkit/components/telemetry/{other => }/UITelemetry.jsm (100%) rename toolkit/components/telemetry/{pings => }/UpdatePing.jsm (100%) rename toolkit/components/telemetry/{other => }/WebrtcTelemetry.cpp (98%) rename toolkit/components/telemetry/{other => }/WebrtcTelemetry.h (97%) delete mode 100644 toolkit/components/telemetry/build_scripts/parsers/__init__.py create mode 100644 toolkit/components/telemetry/gen-histogram-bucket-ranges.py rename toolkit/components/telemetry/{build_scripts => }/gen_event_data.py (97%) rename toolkit/components/telemetry/{build_scripts => }/gen_event_enum.py (96%) rename toolkit/components/telemetry/{build_scripts => }/gen_histogram_data.py (98%) rename toolkit/components/telemetry/{build_scripts => }/gen_histogram_enum.py (97%) rename toolkit/components/telemetry/{build_scripts => }/gen_histogram_phf.py (94%) rename toolkit/components/telemetry/{build_scripts => }/gen_process_data.py (97%) rename toolkit/components/telemetry/{build_scripts => }/gen_process_enum.py (96%) rename toolkit/components/telemetry/{build_scripts => }/gen_scalar_data.py (96%) rename toolkit/components/telemetry/{build_scripts => }/gen_scalar_enum.py (94%) rename toolkit/components/telemetry/{core => }/ipc/TelemetryComms.h (100%) rename toolkit/components/telemetry/{core => }/ipc/TelemetryIPC.cpp (100%) rename toolkit/components/telemetry/{core => }/ipc/TelemetryIPC.h (100%) rename toolkit/components/telemetry/{core => }/ipc/TelemetryIPCAccumulator.cpp (99%) rename toolkit/components/telemetry/{core => }/ipc/TelemetryIPCAccumulator.h (100%) rename toolkit/components/telemetry/{core => }/nsITelemetry.idl (100%) rename toolkit/components/telemetry/{build_scripts/parsers => }/parse_events.py (100%) rename toolkit/components/telemetry/{build_scripts/parsers => }/parse_histograms.py (98%) rename toolkit/components/telemetry/{build_scripts/parsers => }/parse_scalars.py (100%) create mode 100644 toolkit/components/telemetry/schemas/core.schema.json rename toolkit/components/telemetry/{build_scripts/parsers => }/shared_telemetry_utils.py (100%) diff --git a/toolkit/components/telemetry/other/CombinedStacks.cpp b/toolkit/components/telemetry/CombinedStacks.cpp similarity index 100% rename from toolkit/components/telemetry/other/CombinedStacks.cpp rename to toolkit/components/telemetry/CombinedStacks.cpp diff --git a/toolkit/components/telemetry/other/CombinedStacks.h b/toolkit/components/telemetry/CombinedStacks.h similarity index 100% rename from toolkit/components/telemetry/other/CombinedStacks.h rename to toolkit/components/telemetry/CombinedStacks.h diff --git a/toolkit/components/telemetry/core/EventInfo.h b/toolkit/components/telemetry/EventInfo.h similarity index 100% rename from toolkit/components/telemetry/core/EventInfo.h rename to toolkit/components/telemetry/EventInfo.h diff --git a/toolkit/components/telemetry/other/GCTelemetry.jsm b/toolkit/components/telemetry/GCTelemetry.jsm similarity index 100% rename from toolkit/components/telemetry/other/GCTelemetry.jsm rename to toolkit/components/telemetry/GCTelemetry.jsm diff --git a/toolkit/components/telemetry/other/KeyedStackCapturer.cpp b/toolkit/components/telemetry/KeyedStackCapturer.cpp similarity index 100% rename from toolkit/components/telemetry/other/KeyedStackCapturer.cpp rename to toolkit/components/telemetry/KeyedStackCapturer.cpp diff --git a/toolkit/components/telemetry/other/KeyedStackCapturer.h b/toolkit/components/telemetry/KeyedStackCapturer.h similarity index 98% rename from toolkit/components/telemetry/other/KeyedStackCapturer.h rename to toolkit/components/telemetry/KeyedStackCapturer.h index f6632b8fe29e..6c3438265a6b 100644 --- a/toolkit/components/telemetry/other/KeyedStackCapturer.h +++ b/toolkit/components/telemetry/KeyedStackCapturer.h @@ -6,7 +6,7 @@ #ifndef KeyedStackCapturer_h__ #define KeyedStackCapturer_h__ -#include "mozilla/Telemetry.h" +#include "Telemetry.h" #include "nsString.h" #include "nsClassHashtable.h" #include "mozilla/Mutex.h" diff --git a/toolkit/components/telemetry/other/ProcessedStack.cpp b/toolkit/components/telemetry/ProcessedStack.cpp similarity index 100% rename from toolkit/components/telemetry/other/ProcessedStack.cpp rename to toolkit/components/telemetry/ProcessedStack.cpp diff --git a/toolkit/components/telemetry/other/ProcessedStack.h b/toolkit/components/telemetry/ProcessedStack.h similarity index 100% rename from toolkit/components/telemetry/other/ProcessedStack.h rename to toolkit/components/telemetry/ProcessedStack.h diff --git a/toolkit/components/telemetry/core/ScalarInfo.h b/toolkit/components/telemetry/ScalarInfo.h similarity index 100% rename from toolkit/components/telemetry/core/ScalarInfo.h rename to toolkit/components/telemetry/ScalarInfo.h diff --git a/toolkit/components/telemetry/core/Telemetry.cpp b/toolkit/components/telemetry/Telemetry.cpp similarity index 99% rename from toolkit/components/telemetry/core/Telemetry.cpp rename to toolkit/components/telemetry/Telemetry.cpp index 19a45c26a4be..eef1463533c1 100644 --- a/toolkit/components/telemetry/core/Telemetry.cpp +++ b/toolkit/components/telemetry/Telemetry.cpp @@ -24,7 +24,7 @@ #include "mozilla/Unused.h" #include "base/pickle.h" -#include "other/CombinedStacks.h" +#include "CombinedStacks.h" #include "nsIComponentManager.h" #include "nsIServiceManager.h" #include "nsThreadManager.h" @@ -52,11 +52,11 @@ #include "Telemetry.h" #include "TelemetryCommon.h" #include "TelemetryHistogram.h" -#include "other/TelemetryIOInterposeObserver.h" +#include "TelemetryIOInterposeObserver.h" #include "ipc/TelemetryIPCAccumulator.h" #include "TelemetryScalar.h" #include "TelemetryEvent.h" -#include "other/WebrtcTelemetry.h" +#include "WebrtcTelemetry.h" #include "nsTHashtable.h" #include "nsHashKeys.h" #include "nsBaseHashtable.h" @@ -91,7 +91,7 @@ #if defined(MOZ_GECKO_PROFILER) #include "shared-libraries.h" -#include "other/KeyedStackCapturer.h" +#include "KeyedStackCapturer.h" #endif // MOZ_GECKO_PROFILER #if defined(MOZ_TELEMETRY_GECKOVIEW) diff --git a/toolkit/components/telemetry/core/Telemetry.h b/toolkit/components/telemetry/Telemetry.h similarity index 100% rename from toolkit/components/telemetry/core/Telemetry.h rename to toolkit/components/telemetry/Telemetry.h diff --git a/toolkit/components/telemetry/app/TelemetryArchive.jsm b/toolkit/components/telemetry/TelemetryArchive.jsm similarity index 100% rename from toolkit/components/telemetry/app/TelemetryArchive.jsm rename to toolkit/components/telemetry/TelemetryArchive.jsm diff --git a/toolkit/components/telemetry/core/TelemetryCommon.cpp b/toolkit/components/telemetry/TelemetryCommon.cpp similarity index 100% rename from toolkit/components/telemetry/core/TelemetryCommon.cpp rename to toolkit/components/telemetry/TelemetryCommon.cpp diff --git a/toolkit/components/telemetry/core/TelemetryCommon.h b/toolkit/components/telemetry/TelemetryCommon.h similarity index 100% rename from toolkit/components/telemetry/core/TelemetryCommon.h rename to toolkit/components/telemetry/TelemetryCommon.h diff --git a/toolkit/components/telemetry/app/TelemetryController.jsm b/toolkit/components/telemetry/TelemetryController.jsm similarity index 100% rename from toolkit/components/telemetry/app/TelemetryController.jsm rename to toolkit/components/telemetry/TelemetryController.jsm diff --git a/toolkit/components/telemetry/app/TelemetryEnvironment.jsm b/toolkit/components/telemetry/TelemetryEnvironment.jsm similarity index 100% rename from toolkit/components/telemetry/app/TelemetryEnvironment.jsm rename to toolkit/components/telemetry/TelemetryEnvironment.jsm diff --git a/toolkit/components/telemetry/core/TelemetryEvent.cpp b/toolkit/components/telemetry/TelemetryEvent.cpp similarity index 100% rename from toolkit/components/telemetry/core/TelemetryEvent.cpp rename to toolkit/components/telemetry/TelemetryEvent.cpp diff --git a/toolkit/components/telemetry/core/TelemetryEvent.h b/toolkit/components/telemetry/TelemetryEvent.h similarity index 100% rename from toolkit/components/telemetry/core/TelemetryEvent.h rename to toolkit/components/telemetry/TelemetryEvent.h diff --git a/toolkit/components/telemetry/pings/EventPing.jsm b/toolkit/components/telemetry/TelemetryEventPing.jsm similarity index 100% rename from toolkit/components/telemetry/pings/EventPing.jsm rename to toolkit/components/telemetry/TelemetryEventPing.jsm diff --git a/toolkit/components/telemetry/pings/HealthPing.jsm b/toolkit/components/telemetry/TelemetryHealthPing.jsm similarity index 100% rename from toolkit/components/telemetry/pings/HealthPing.jsm rename to toolkit/components/telemetry/TelemetryHealthPing.jsm diff --git a/toolkit/components/telemetry/core/TelemetryHistogram.cpp b/toolkit/components/telemetry/TelemetryHistogram.cpp similarity index 100% rename from toolkit/components/telemetry/core/TelemetryHistogram.cpp rename to toolkit/components/telemetry/TelemetryHistogram.cpp diff --git a/toolkit/components/telemetry/core/TelemetryHistogram.h b/toolkit/components/telemetry/TelemetryHistogram.h similarity index 100% rename from toolkit/components/telemetry/core/TelemetryHistogram.h rename to toolkit/components/telemetry/TelemetryHistogram.h diff --git a/toolkit/components/telemetry/other/TelemetryIOInterposeObserver.cpp b/toolkit/components/telemetry/TelemetryIOInterposeObserver.cpp similarity index 99% rename from toolkit/components/telemetry/other/TelemetryIOInterposeObserver.cpp rename to toolkit/components/telemetry/TelemetryIOInterposeObserver.cpp index 76ba444abc8c..411437fdb123 100644 --- a/toolkit/components/telemetry/other/TelemetryIOInterposeObserver.cpp +++ b/toolkit/components/telemetry/TelemetryIOInterposeObserver.cpp @@ -5,7 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "TelemetryIOInterposeObserver.h" -#include "core/TelemetryCommon.h" +#include "TelemetryCommon.h" namespace mozilla { namespace Telemetry { diff --git a/toolkit/components/telemetry/other/TelemetryIOInterposeObserver.h b/toolkit/components/telemetry/TelemetryIOInterposeObserver.h similarity index 99% rename from toolkit/components/telemetry/other/TelemetryIOInterposeObserver.h rename to toolkit/components/telemetry/TelemetryIOInterposeObserver.h index efffe3ee19b9..f92881cfc224 100644 --- a/toolkit/components/telemetry/other/TelemetryIOInterposeObserver.h +++ b/toolkit/components/telemetry/TelemetryIOInterposeObserver.h @@ -20,7 +20,7 @@ #include "nsBaseHashtable.h" #include "nsClassHashtable.h" -#include "core/TelemetryCommon.h" +#include "TelemetryCommon.h" #include "mozilla/IOInterposer.h" namespace mozilla { diff --git a/toolkit/components/telemetry/pings/ModulesPing.jsm b/toolkit/components/telemetry/TelemetryModules.jsm similarity index 100% rename from toolkit/components/telemetry/pings/ModulesPing.jsm rename to toolkit/components/telemetry/TelemetryModules.jsm diff --git a/toolkit/components/telemetry/app/TelemetryReportingPolicy.jsm b/toolkit/components/telemetry/TelemetryReportingPolicy.jsm similarity index 100% rename from toolkit/components/telemetry/app/TelemetryReportingPolicy.jsm rename to toolkit/components/telemetry/TelemetryReportingPolicy.jsm diff --git a/toolkit/components/telemetry/core/TelemetryScalar.cpp b/toolkit/components/telemetry/TelemetryScalar.cpp similarity index 100% rename from toolkit/components/telemetry/core/TelemetryScalar.cpp rename to toolkit/components/telemetry/TelemetryScalar.cpp diff --git a/toolkit/components/telemetry/core/TelemetryScalar.h b/toolkit/components/telemetry/TelemetryScalar.h similarity index 100% rename from toolkit/components/telemetry/core/TelemetryScalar.h rename to toolkit/components/telemetry/TelemetryScalar.h diff --git a/toolkit/components/telemetry/app/TelemetrySend.jsm b/toolkit/components/telemetry/TelemetrySend.jsm similarity index 100% rename from toolkit/components/telemetry/app/TelemetrySend.jsm rename to toolkit/components/telemetry/TelemetrySend.jsm diff --git a/toolkit/components/telemetry/pings/TelemetrySession.jsm b/toolkit/components/telemetry/TelemetrySession.jsm similarity index 100% rename from toolkit/components/telemetry/pings/TelemetrySession.jsm rename to toolkit/components/telemetry/TelemetrySession.jsm diff --git a/toolkit/components/telemetry/app/TelemetryStopwatch.jsm b/toolkit/components/telemetry/TelemetryStopwatch.jsm similarity index 100% rename from toolkit/components/telemetry/app/TelemetryStopwatch.jsm rename to toolkit/components/telemetry/TelemetryStopwatch.jsm diff --git a/toolkit/components/telemetry/app/TelemetryStorage.jsm b/toolkit/components/telemetry/TelemetryStorage.jsm similarity index 100% rename from toolkit/components/telemetry/app/TelemetryStorage.jsm rename to toolkit/components/telemetry/TelemetryStorage.jsm diff --git a/toolkit/components/telemetry/app/TelemetryTimestamps.jsm b/toolkit/components/telemetry/TelemetryTimestamps.jsm similarity index 100% rename from toolkit/components/telemetry/app/TelemetryTimestamps.jsm rename to toolkit/components/telemetry/TelemetryTimestamps.jsm diff --git a/toolkit/components/telemetry/app/TelemetryUtils.jsm b/toolkit/components/telemetry/TelemetryUtils.jsm similarity index 100% rename from toolkit/components/telemetry/app/TelemetryUtils.jsm rename to toolkit/components/telemetry/TelemetryUtils.jsm diff --git a/toolkit/components/telemetry/other/UITelemetry.jsm b/toolkit/components/telemetry/UITelemetry.jsm similarity index 100% rename from toolkit/components/telemetry/other/UITelemetry.jsm rename to toolkit/components/telemetry/UITelemetry.jsm diff --git a/toolkit/components/telemetry/pings/UpdatePing.jsm b/toolkit/components/telemetry/UpdatePing.jsm similarity index 100% rename from toolkit/components/telemetry/pings/UpdatePing.jsm rename to toolkit/components/telemetry/UpdatePing.jsm diff --git a/toolkit/components/telemetry/other/WebrtcTelemetry.cpp b/toolkit/components/telemetry/WebrtcTelemetry.cpp similarity index 98% rename from toolkit/components/telemetry/other/WebrtcTelemetry.cpp rename to toolkit/components/telemetry/WebrtcTelemetry.cpp index 0bc166ef7f24..8c03f3a99fb0 100644 --- a/toolkit/components/telemetry/other/WebrtcTelemetry.cpp +++ b/toolkit/components/telemetry/WebrtcTelemetry.cpp @@ -5,7 +5,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "mozilla/Telemetry.h" +#include "Telemetry.h" +#include "TelemetryCommon.h" #include "WebrtcTelemetry.h" #include "jsapi.h" #include "nsPrintfCString.h" diff --git a/toolkit/components/telemetry/other/WebrtcTelemetry.h b/toolkit/components/telemetry/WebrtcTelemetry.h similarity index 97% rename from toolkit/components/telemetry/other/WebrtcTelemetry.h rename to toolkit/components/telemetry/WebrtcTelemetry.h index 6f7f9e192a16..ed87c71073ff 100644 --- a/toolkit/components/telemetry/other/WebrtcTelemetry.h +++ b/toolkit/components/telemetry/WebrtcTelemetry.h @@ -9,7 +9,7 @@ #include "nsBaseHashtable.h" #include "nsHashKeys.h" -#include "core/TelemetryCommon.h" +#include "TelemetryCommon.h" class WebrtcTelemetry { public: diff --git a/toolkit/components/telemetry/build_scripts/parsers/__init__.py b/toolkit/components/telemetry/build_scripts/parsers/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/toolkit/components/telemetry/geckoview/TelemetryGeckoViewPersistence.cpp b/toolkit/components/telemetry/geckoview/TelemetryGeckoViewPersistence.cpp index 97d6250adbb2..d9fe8145ec99 100644 --- a/toolkit/components/telemetry/geckoview/TelemetryGeckoViewPersistence.cpp +++ b/toolkit/components/telemetry/geckoview/TelemetryGeckoViewPersistence.cpp @@ -29,8 +29,8 @@ #include "nsXULAppAPI.h" #include "prenv.h" #include "prio.h" -#include "core/TelemetryScalar.h" -#include "core/TelemetryHistogram.h" +#include "TelemetryScalar.h" +#include "TelemetryHistogram.h" #include "xpcpublic.h" using mozilla::GetErrorName; diff --git a/toolkit/components/telemetry/geckoview/TelemetryGeckoViewTesting.cpp b/toolkit/components/telemetry/geckoview/TelemetryGeckoViewTesting.cpp index 7c2cd4ecece9..dcafc92fa473 100644 --- a/toolkit/components/telemetry/geckoview/TelemetryGeckoViewTesting.cpp +++ b/toolkit/components/telemetry/geckoview/TelemetryGeckoViewTesting.cpp @@ -4,7 +4,7 @@ #include "TelemetryGeckoViewTesting.h" #include "TelemetryGeckoViewPersistence.h" -#include "core/TelemetryScalar.h" +#include "TelemetryScalar.h" namespace TelemetryGeckoViewTesting { // This is defined in TelemetryGeckoViewPersistence.cpp diff --git a/toolkit/components/telemetry/geckoview/gtest/TestGeckoView.cpp b/toolkit/components/telemetry/geckoview/gtest/TestGeckoView.cpp index 3c1e888439fe..38c50ebbe6db 100644 --- a/toolkit/components/telemetry/geckoview/gtest/TestGeckoView.cpp +++ b/toolkit/components/telemetry/geckoview/gtest/TestGeckoView.cpp @@ -15,10 +15,10 @@ #include "nsThreadUtils.h" #include "nsPrintfCString.h" #include "prenv.h" -#include "mozilla/Telemetry.h" +#include "Telemetry.h" #include "TelemetryFixture.h" #include "TelemetryGeckoViewPersistence.h" -#include "core/TelemetryScalar.h" +#include "TelemetryScalar.h" #include "TelemetryTestHelpers.h" using namespace mozilla; diff --git a/toolkit/components/telemetry/gen-histogram-bucket-ranges.py b/toolkit/components/telemetry/gen-histogram-bucket-ranges.py new file mode 100644 index 000000000000..7a2f1b697867 --- /dev/null +++ b/toolkit/components/telemetry/gen-histogram-bucket-ranges.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Write out detailed histogram information, including the ranges of the +# buckets specified by each histogram. + +import sys +import parse_histograms +import json + +from collections import OrderedDict + + +def main(argv): + filenames = argv + + all_histograms = OrderedDict() + + for histogram in parse_histograms.from_files(filenames): + name = histogram.name() + parameters = OrderedDict() + table = { + 'boolean': '2', + 'flag': '3', + 'enumerated': '1', + 'linear': '1', + 'exponential': '0', + 'count': '4', + } + # Use __setitem__ because Python lambdas are so limited. + parse_histograms.table_dispatch(histogram.kind(), table, + lambda k: parameters.__setitem__('kind', k)) + if histogram.low() == 0: + parameters['min'] = 1 + else: + parameters['min'] = histogram.low() + + try: + buckets = histogram.ranges() + parameters['buckets'] = buckets + parameters['max'] = buckets[-1] + parameters['bucket_count'] = len(buckets) + except parse_histograms.DefinitionException: + continue + + all_histograms.update({name: parameters}) + + print json.dumps({'histograms': all_histograms}) + + +main(sys.argv[1:]) diff --git a/toolkit/components/telemetry/build_scripts/gen_event_data.py b/toolkit/components/telemetry/gen_event_data.py similarity index 97% rename from toolkit/components/telemetry/build_scripts/gen_event_data.py rename to toolkit/components/telemetry/gen_event_data.py index 97dce90688f7..85569245dc08 100644 --- a/toolkit/components/telemetry/build_scripts/gen_event_data.py +++ b/toolkit/components/telemetry/gen_event_data.py @@ -7,10 +7,10 @@ from __future__ import print_function from collections import OrderedDict -from parsers.shared_telemetry_utils import StringTable, static_assert, ParserError -from parsers import parse_events +from shared_telemetry_utils import StringTable, static_assert, ParserError import json +import parse_events import sys import itertools @@ -22,7 +22,7 @@ banner = """/* This file is auto-generated, only for internal use in TelemetryEv file_header = """\ #ifndef mozilla_TelemetryEventData_h #define mozilla_TelemetryEventData_h -#include "core/EventInfo.h" +#include "EventInfo.h" namespace { """ diff --git a/toolkit/components/telemetry/build_scripts/gen_event_enum.py b/toolkit/components/telemetry/gen_event_enum.py similarity index 96% rename from toolkit/components/telemetry/build_scripts/gen_event_enum.py rename to toolkit/components/telemetry/gen_event_enum.py index 7b1f7d2fb76a..786bcae3af2a 100644 --- a/toolkit/components/telemetry/build_scripts/gen_event_enum.py +++ b/toolkit/components/telemetry/gen_event_enum.py @@ -7,10 +7,10 @@ # The events are defined in files provided as command-line arguments. from __future__ import print_function -from parsers.shared_telemetry_utils import ParserError -from parsers import parse_events +from shared_telemetry_utils import ParserError import sys +import parse_events banner = """/* This file is auto-generated, see gen_event_enum.py. */ """ diff --git a/toolkit/components/telemetry/build_scripts/gen_histogram_data.py b/toolkit/components/telemetry/gen_histogram_data.py similarity index 98% rename from toolkit/components/telemetry/build_scripts/gen_histogram_data.py rename to toolkit/components/telemetry/gen_histogram_data.py index 76a9cfaa6525..7af76cc72e87 100644 --- a/toolkit/components/telemetry/build_scripts/gen_histogram_data.py +++ b/toolkit/components/telemetry/gen_histogram_data.py @@ -6,10 +6,10 @@ # in a file provided as a command-line argument. from __future__ import print_function -from parsers.shared_telemetry_utils import StringTable, static_assert, ParserError -from parsers import parse_histograms +from shared_telemetry_utils import StringTable, static_assert, ParserError import sys +import parse_histograms import buildconfig banner = """/* This file is auto-generated, see gen_histogram_data.py. */ diff --git a/toolkit/components/telemetry/build_scripts/gen_histogram_enum.py b/toolkit/components/telemetry/gen_histogram_enum.py similarity index 97% rename from toolkit/components/telemetry/build_scripts/gen_histogram_enum.py rename to toolkit/components/telemetry/gen_histogram_enum.py index 75c4f7bcc3b7..9a9fde03431f 100644 --- a/toolkit/components/telemetry/build_scripts/gen_histogram_enum.py +++ b/toolkit/components/telemetry/gen_histogram_enum.py @@ -13,9 +13,9 @@ # The histograms are defined in files provided as command-line arguments. from __future__ import print_function -from parsers.shared_telemetry_utils import ParserError -from parsers import parse_histograms +from shared_telemetry_utils import ParserError +import parse_histograms import itertools import sys import buildconfig diff --git a/toolkit/components/telemetry/build_scripts/gen_histogram_phf.py b/toolkit/components/telemetry/gen_histogram_phf.py similarity index 94% rename from toolkit/components/telemetry/build_scripts/gen_histogram_phf.py rename to toolkit/components/telemetry/gen_histogram_phf.py index 8918967f5e5c..f291f10f56dc 100644 --- a/toolkit/components/telemetry/build_scripts/gen_histogram_phf.py +++ b/toolkit/components/telemetry/gen_histogram_phf.py @@ -3,12 +3,12 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from __future__ import print_function -from parsers.shared_telemetry_utils import ParserError +from shared_telemetry_utils import ParserError from perfecthash import PerfectHash PHFSIZE = 512 -from parsers import parse_histograms +import parse_histograms import sys import buildconfig diff --git a/toolkit/components/telemetry/build_scripts/gen_process_data.py b/toolkit/components/telemetry/gen_process_data.py similarity index 97% rename from toolkit/components/telemetry/build_scripts/gen_process_data.py rename to toolkit/components/telemetry/gen_process_data.py index 8bfe90fdf0c5..56842c640ea2 100644 --- a/toolkit/components/telemetry/build_scripts/gen_process_data.py +++ b/toolkit/components/telemetry/gen_process_data.py @@ -6,7 +6,7 @@ # in a file provided as a command-line argument. from __future__ import print_function -from parsers.shared_telemetry_utils import ParserError, load_yaml_file +from shared_telemetry_utils import ParserError, load_yaml_file import sys import collections diff --git a/toolkit/components/telemetry/build_scripts/gen_process_enum.py b/toolkit/components/telemetry/gen_process_enum.py similarity index 96% rename from toolkit/components/telemetry/build_scripts/gen_process_enum.py rename to toolkit/components/telemetry/gen_process_enum.py index c70326b2b003..d771e381c0bf 100644 --- a/toolkit/components/telemetry/build_scripts/gen_process_enum.py +++ b/toolkit/components/telemetry/gen_process_enum.py @@ -6,7 +6,7 @@ # in a file provided as a command-line argument. from __future__ import print_function -from parsers.shared_telemetry_utils import ParserError, load_yaml_file +from shared_telemetry_utils import ParserError, load_yaml_file import sys import collections diff --git a/toolkit/components/telemetry/build_scripts/gen_scalar_data.py b/toolkit/components/telemetry/gen_scalar_data.py similarity index 96% rename from toolkit/components/telemetry/build_scripts/gen_scalar_data.py rename to toolkit/components/telemetry/gen_scalar_data.py index e86b30ecfdc6..ca4b8b462c7d 100644 --- a/toolkit/components/telemetry/build_scripts/gen_scalar_data.py +++ b/toolkit/components/telemetry/gen_scalar_data.py @@ -7,10 +7,10 @@ from __future__ import print_function from collections import OrderedDict -from parsers.shared_telemetry_utils import StringTable, static_assert, ParserError -from parsers import parse_scalars +from shared_telemetry_utils import StringTable, static_assert, ParserError import json +import parse_scalars import sys # The banner/text at the top of the generated file. @@ -21,7 +21,7 @@ banner = """/* This file is auto-generated, only for internal use in TelemetrySc file_header = """\ #ifndef mozilla_TelemetryScalarData_h #define mozilla_TelemetryScalarData_h -#include "core/ScalarInfo.h" +#include "ScalarInfo.h" namespace { """ diff --git a/toolkit/components/telemetry/build_scripts/gen_scalar_enum.py b/toolkit/components/telemetry/gen_scalar_enum.py similarity index 94% rename from toolkit/components/telemetry/build_scripts/gen_scalar_enum.py rename to toolkit/components/telemetry/gen_scalar_enum.py index 4ae2ceeb6ba2..d84895a91595 100644 --- a/toolkit/components/telemetry/build_scripts/gen_scalar_enum.py +++ b/toolkit/components/telemetry/gen_scalar_enum.py @@ -8,10 +8,10 @@ # The scalars are defined in files provided as command-line arguments. from __future__ import print_function -from parsers.shared_telemetry_utils import ParserError -from parsers import parse_scalars +from shared_telemetry_utils import ParserError import sys +import parse_scalars banner = """/* This file is auto-generated, see gen_scalar_enum.py. */ """ diff --git a/toolkit/components/telemetry/core/ipc/TelemetryComms.h b/toolkit/components/telemetry/ipc/TelemetryComms.h similarity index 100% rename from toolkit/components/telemetry/core/ipc/TelemetryComms.h rename to toolkit/components/telemetry/ipc/TelemetryComms.h diff --git a/toolkit/components/telemetry/core/ipc/TelemetryIPC.cpp b/toolkit/components/telemetry/ipc/TelemetryIPC.cpp similarity index 100% rename from toolkit/components/telemetry/core/ipc/TelemetryIPC.cpp rename to toolkit/components/telemetry/ipc/TelemetryIPC.cpp diff --git a/toolkit/components/telemetry/core/ipc/TelemetryIPC.h b/toolkit/components/telemetry/ipc/TelemetryIPC.h similarity index 100% rename from toolkit/components/telemetry/core/ipc/TelemetryIPC.h rename to toolkit/components/telemetry/ipc/TelemetryIPC.h diff --git a/toolkit/components/telemetry/core/ipc/TelemetryIPCAccumulator.cpp b/toolkit/components/telemetry/ipc/TelemetryIPCAccumulator.cpp similarity index 99% rename from toolkit/components/telemetry/core/ipc/TelemetryIPCAccumulator.cpp rename to toolkit/components/telemetry/ipc/TelemetryIPCAccumulator.cpp index 71e0aa730032..4ca5bcd44640 100644 --- a/toolkit/components/telemetry/core/ipc/TelemetryIPCAccumulator.cpp +++ b/toolkit/components/telemetry/ipc/TelemetryIPCAccumulator.cpp @@ -16,8 +16,8 @@ #include "nsComponentManagerUtils.h" #include "nsITimer.h" #include "nsThreadUtils.h" -#include "core/TelemetryHistogram.h" -#include "core/TelemetryScalar.h" +#include "TelemetryHistogram.h" +#include "TelemetryScalar.h" using mozilla::StaticMutex; using mozilla::StaticMutexAutoLock; diff --git a/toolkit/components/telemetry/core/ipc/TelemetryIPCAccumulator.h b/toolkit/components/telemetry/ipc/TelemetryIPCAccumulator.h similarity index 100% rename from toolkit/components/telemetry/core/ipc/TelemetryIPCAccumulator.h rename to toolkit/components/telemetry/ipc/TelemetryIPCAccumulator.h diff --git a/toolkit/components/telemetry/moz.build b/toolkit/components/telemetry/moz.build index 489334d0a829..2bda9795ab40 100644 --- a/toolkit/components/telemetry/moz.build +++ b/toolkit/components/telemetry/moz.build @@ -44,7 +44,7 @@ XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini'] BROWSER_CHROME_MANIFESTS += ['tests/browser/browser.ini'] XPIDL_SOURCES += [ - 'core/nsITelemetry.idl', + 'nsITelemetry.idl', ] XPIDL_MODULE = 'telemetry' @@ -54,32 +54,32 @@ EXPORTS.mozilla += [ '!TelemetryHistogramEnums.h', '!TelemetryProcessEnums.h', '!TelemetryScalarEnums.h', - 'core/ipc/TelemetryComms.h', - 'core/ipc/TelemetryIPC.h', - 'core/Telemetry.h', - 'other/CombinedStacks.h', - 'other/ProcessedStack.h', + 'CombinedStacks.h', + 'ipc/TelemetryComms.h', + 'ipc/TelemetryIPC.h', + 'ProcessedStack.h', + 'Telemetry.h', ] SOURCES += [ - 'core/ipc/TelemetryIPC.cpp', - 'core/ipc/TelemetryIPCAccumulator.cpp', - 'core/Telemetry.cpp', - 'core/TelemetryCommon.cpp', - 'core/TelemetryEvent.cpp', - 'core/TelemetryHistogram.cpp', - 'core/TelemetryScalar.cpp', + 'CombinedStacks.cpp', 'geckoview/TelemetryGeckoViewPersistence.cpp', - 'other/CombinedStacks.cpp', - 'other/ProcessedStack.cpp', - 'other/TelemetryIOInterposeObserver.cpp', - 'other/WebrtcTelemetry.cpp', + 'ipc/TelemetryIPC.cpp', + 'ipc/TelemetryIPCAccumulator.cpp', + 'ProcessedStack.cpp', + 'Telemetry.cpp', + 'TelemetryCommon.cpp', + 'TelemetryEvent.cpp', + 'TelemetryHistogram.cpp', + 'TelemetryIOInterposeObserver.cpp', + 'TelemetryScalar.cpp', + 'WebrtcTelemetry.cpp', ] # KeyedStackCapturer entirely relies on profiler to be enabled. if CONFIG['MOZ_GECKO_PROFILER']: SOURCES += [ - 'other/KeyedStackCapturer.cpp' + 'KeyedStackCapturer.cpp' ] EXTRA_COMPONENTS += [ @@ -88,22 +88,22 @@ EXTRA_COMPONENTS += [ ] EXTRA_JS_MODULES += [ - 'app/TelemetryArchive.jsm', - 'app/TelemetryController.jsm', - 'app/TelemetryEnvironment.jsm', - 'app/TelemetryReportingPolicy.jsm', - 'app/TelemetrySend.jsm', - 'app/TelemetryStopwatch.jsm', - 'app/TelemetryStorage.jsm', - 'app/TelemetryTimestamps.jsm', - 'app/TelemetryUtils.jsm', - 'other/GCTelemetry.jsm', - 'other/UITelemetry.jsm', - 'pings/EventPing.jsm', - 'pings/HealthPing.jsm', - 'pings/ModulesPing.jsm', - 'pings/TelemetrySession.jsm', - 'pings/UpdatePing.jsm', + 'GCTelemetry.jsm', + 'TelemetryArchive.jsm', + 'TelemetryController.jsm', + 'TelemetryEnvironment.jsm', + 'TelemetryEventPing.jsm', + 'TelemetryHealthPing.jsm', + 'TelemetryModules.jsm', + 'TelemetryReportingPolicy.jsm', + 'TelemetrySend.jsm', + 'TelemetrySession.jsm', + 'TelemetryStopwatch.jsm', + 'TelemetryStorage.jsm', + 'TelemetryTimestamps.jsm', + 'TelemetryUtils.jsm', + 'UITelemetry.jsm', + 'UpdatePing.jsm', ] TESTING_JS_MODULES += [ @@ -136,15 +136,15 @@ histogram_files = [ ] data = GENERATED_FILES['TelemetryHistogramData.inc'] -data.script = 'build_scripts/gen_histogram_data.py' +data.script = 'gen_histogram_data.py' data.inputs = histogram_files enums = GENERATED_FILES['TelemetryHistogramEnums.h'] -enums.script = 'build_scripts/gen_histogram_enum.py' +enums.script = 'gen_histogram_enum.py' enums.inputs = histogram_files data = GENERATED_FILES['TelemetryHistogramNameMap.h'] -data.script = 'build_scripts/gen_histogram_phf.py' +data.script = 'gen_histogram_phf.py' data.inputs = histogram_files # Generate scalar files. @@ -153,17 +153,17 @@ scalar_files = [ ] scalar_data = GENERATED_FILES['TelemetryScalarData.h'] -scalar_data.script = 'build_scripts/gen_scalar_data.py' +scalar_data.script = 'gen_scalar_data.py' scalar_data.inputs = scalar_files scalar_enums = GENERATED_FILES['TelemetryScalarEnums.h'] -scalar_enums.script = 'build_scripts/gen_scalar_enum.py' +scalar_enums.script = 'gen_scalar_enum.py' scalar_enums.inputs = scalar_files # Generate the JSON scalar definitions. They will only be # used in artifact or "build faster" builds. scalar_json_data = GENERATED_FILES['ScalarArtifactDefinitions.json'] -scalar_json_data.script = 'build_scripts/gen_scalar_data.py:generate_JSON_definitions' +scalar_json_data.script = 'gen_scalar_data.py:generate_JSON_definitions' scalar_json_data.inputs = scalar_files # Move the scalars JSON file to the directory where the Firefox binary is. @@ -175,17 +175,17 @@ event_files = [ ] event_data = GENERATED_FILES['TelemetryEventData.h'] -event_data.script = 'build_scripts/gen_event_data.py' +event_data.script = 'gen_event_data.py' event_data.inputs = event_files event_enums = GENERATED_FILES['TelemetryEventEnums.h'] -event_enums.script = 'build_scripts/gen_event_enum.py' +event_enums.script = 'gen_event_enum.py' event_enums.inputs = event_files # Generate the JSON event definitions. They will only be # used in artifact or "build faster" builds. event_json_data = GENERATED_FILES['EventArtifactDefinitions.json'] -event_json_data.script = 'build_scripts/gen_event_data.py:generate_JSON_definitions' +event_json_data.script = 'gen_event_data.py:generate_JSON_definitions' event_json_data.inputs = event_files # Move the events JSON file to the directory where the Firefox binary is. @@ -197,11 +197,11 @@ processes_files = [ ] processes_enum = GENERATED_FILES['TelemetryProcessEnums.h'] -processes_enum.script = 'build_scripts/gen_process_enum.py' +processes_enum.script = 'gen_process_enum.py' processes_enum.inputs = processes_files processes_data = GENERATED_FILES['TelemetryProcessData.h'] -processes_data.script = 'build_scripts/gen_process_data.py' +processes_data.script = 'gen_process_data.py' processes_data.inputs = processes_files # Add support for GeckoView: please note that building GeckoView diff --git a/toolkit/components/telemetry/core/nsITelemetry.idl b/toolkit/components/telemetry/nsITelemetry.idl similarity index 100% rename from toolkit/components/telemetry/core/nsITelemetry.idl rename to toolkit/components/telemetry/nsITelemetry.idl diff --git a/toolkit/components/telemetry/build_scripts/parsers/parse_events.py b/toolkit/components/telemetry/parse_events.py similarity index 100% rename from toolkit/components/telemetry/build_scripts/parsers/parse_events.py rename to toolkit/components/telemetry/parse_events.py diff --git a/toolkit/components/telemetry/build_scripts/parsers/parse_histograms.py b/toolkit/components/telemetry/parse_histograms.py similarity index 98% rename from toolkit/components/telemetry/build_scripts/parsers/parse_histograms.py rename to toolkit/components/telemetry/parse_histograms.py index 89987f7650c2..a552d75283cd 100755 --- a/toolkit/components/telemetry/build_scripts/parsers/parse_histograms.py +++ b/toolkit/components/telemetry/parse_histograms.py @@ -96,13 +96,8 @@ whitelists = None def load_whitelist(): global whitelists try: - parsers_path = os.path.realpath(os.path.dirname(__file__)) - # The parsers live in build_scripts/parsers in the Telemetry module, while - # the histogram-whitelists file lives in the root of the module. Account - # for that when looking for the whitelist. - # NOTE: if the parsers are moved, this logic will need to be updated. - telemetry_module_path = os.path.abspath(os.path.join(parsers_path, os.pardir, os.pardir)) - whitelist_path = os.path.join(telemetry_module_path, 'histogram-whitelists.json') + whitelist_path = os.path.join(os.path.abspath(os.path.realpath(os.path.dirname(__file__))), + 'histogram-whitelists.json') with open(whitelist_path, 'r') as f: try: whitelists = json.load(f) diff --git a/toolkit/components/telemetry/build_scripts/parsers/parse_scalars.py b/toolkit/components/telemetry/parse_scalars.py similarity index 100% rename from toolkit/components/telemetry/build_scripts/parsers/parse_scalars.py rename to toolkit/components/telemetry/parse_scalars.py diff --git a/toolkit/components/telemetry/schemas/core.schema.json b/toolkit/components/telemetry/schemas/core.schema.json new file mode 100644 index 000000000000..327cdc298904 --- /dev/null +++ b/toolkit/components/telemetry/schemas/core.schema.json @@ -0,0 +1,41 @@ +{ + "$schema" : "http://json-schema.org/draft-04/schema#", + "type" : "object", + "name" : "core", + "properties" : { + "arch" : { + "type" : "string" + }, + "clientId" : { + "type" : "string", + "pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$" + }, + "device" : { + "type" : "string" + }, + "experiments" : { + "type" : "array", + "items" : { + "type" : "string" + } + }, + "locale" : { + "type" : "string" + }, + "os" : { + "type" : "string" + }, + "osversion" : { + "type" : "string" + }, + "seq" : { + "type" : "integer", + "minimum": 0 + }, + "v" : { + "type" : "integer", + "enum" : [ 1 ] + } + }, + "required" : ["arch", "clientId", "device", "locale", "os", "osversion", "seq", "v"] +} diff --git a/toolkit/components/telemetry/build_scripts/parsers/shared_telemetry_utils.py b/toolkit/components/telemetry/shared_telemetry_utils.py similarity index 100% rename from toolkit/components/telemetry/build_scripts/parsers/shared_telemetry_utils.py rename to toolkit/components/telemetry/shared_telemetry_utils.py diff --git a/toolkit/components/telemetry/tests/gtest/TelemetryTestHelpers.cpp b/toolkit/components/telemetry/tests/gtest/TelemetryTestHelpers.cpp index bd1db74c1c92..da4fe71c9775 100644 --- a/toolkit/components/telemetry/tests/gtest/TelemetryTestHelpers.cpp +++ b/toolkit/components/telemetry/tests/gtest/TelemetryTestHelpers.cpp @@ -6,7 +6,7 @@ #include "gtest/gtest.h" #include "mozilla/CycleCollectedJSContext.h" -#include "core/TelemetryCommon.h" +#include "TelemetryCommon.h" #include "mozilla/Unused.h" using namespace mozilla; diff --git a/toolkit/components/telemetry/tests/gtest/TestCombinedStacks.cpp b/toolkit/components/telemetry/tests/gtest/TestCombinedStacks.cpp index fa75ea5ace43..27225beb13e8 100644 --- a/toolkit/components/telemetry/tests/gtest/TestCombinedStacks.cpp +++ b/toolkit/components/telemetry/tests/gtest/TestCombinedStacks.cpp @@ -2,8 +2,8 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ -#include "other/CombinedStacks.h" -#include "other/ProcessedStack.h" +#include "CombinedStacks.h" +#include "ProcessedStack.h" using namespace mozilla::Telemetry; using namespace TelemetryTestHelpers; diff --git a/toolkit/components/telemetry/tests/gtest/TestCounters.cpp b/toolkit/components/telemetry/tests/gtest/TestCounters.cpp index 0df7879b17ce..eefe4f6f090e 100644 --- a/toolkit/components/telemetry/tests/gtest/TestCounters.cpp +++ b/toolkit/components/telemetry/tests/gtest/TestCounters.cpp @@ -6,7 +6,7 @@ #include "gtest/gtest.h" #include "js/Conversions.h" #include "nsITelemetry.h" -#include "mozilla/Telemetry.h" +#include "Telemetry.h" #include "TelemetryFixture.h" #include "TelemetryTestHelpers.h" diff --git a/toolkit/components/telemetry/tests/gtest/TestHistograms.cpp b/toolkit/components/telemetry/tests/gtest/TestHistograms.cpp index dee74f1ee609..bfc53da43303 100644 --- a/toolkit/components/telemetry/tests/gtest/TestHistograms.cpp +++ b/toolkit/components/telemetry/tests/gtest/TestHistograms.cpp @@ -6,7 +6,7 @@ #include "gtest/gtest.h" #include "js/Conversions.h" #include "nsITelemetry.h" -#include "mozilla/Telemetry.h" +#include "Telemetry.h" #include "TelemetryFixture.h" #include "TelemetryTestHelpers.h" diff --git a/toolkit/components/telemetry/tests/gtest/TestScalars.cpp b/toolkit/components/telemetry/tests/gtest/TestScalars.cpp index e8a808a77314..f5cc7f523529 100644 --- a/toolkit/components/telemetry/tests/gtest/TestScalars.cpp +++ b/toolkit/components/telemetry/tests/gtest/TestScalars.cpp @@ -10,10 +10,10 @@ #include "nsJSUtils.h" // nsAutoJSString #include "nsITelemetry.h" #include "nsThreadUtils.h" -#include "mozilla/Telemetry.h" +#include "Telemetry.h" #include "mozilla/TelemetryProcessEnums.h" #include "TelemetryFixture.h" -#include "core/TelemetryScalar.h" +#include "TelemetryScalar.h" #include "TelemetryTestHelpers.h" using namespace mozilla; From 4f96f7f8d342735ca8974bd247397e670863e6c8 Mon Sep 17 00:00:00 2001 From: Alessio Placitelli Date: Tue, 4 Sep 2018 16:54:54 +0300 Subject: [PATCH 16/61] Bug 1484611 - Re-organize the telemetry module layout. r=chutten,janerik on a CLOSED TREE This patch organizes the Telemetry files according to a new directory layout, which makes the top level dir less cluttered. For a comprehensive discussion about the new layout, see the bug comments. Additionally, the build script and a few Python and C++ files are adjusted for dealing with the new directory layout. Differential Revision: https://phabricator.services.mozilla.com/D4427 --HG-- rename : toolkit/components/telemetry/TelemetryArchive.jsm => toolkit/components/telemetry/app/TelemetryArchive.jsm rename : toolkit/components/telemetry/TelemetryController.jsm => toolkit/components/telemetry/app/TelemetryController.jsm rename : toolkit/components/telemetry/TelemetryEnvironment.jsm => toolkit/components/telemetry/app/TelemetryEnvironment.jsm rename : toolkit/components/telemetry/TelemetryReportingPolicy.jsm => toolkit/components/telemetry/app/TelemetryReportingPolicy.jsm rename : toolkit/components/telemetry/TelemetrySend.jsm => toolkit/components/telemetry/app/TelemetrySend.jsm rename : toolkit/components/telemetry/TelemetryStopwatch.jsm => toolkit/components/telemetry/app/TelemetryStopwatch.jsm rename : toolkit/components/telemetry/TelemetryStorage.jsm => toolkit/components/telemetry/app/TelemetryStorage.jsm rename : toolkit/components/telemetry/TelemetryTimestamps.jsm => toolkit/components/telemetry/app/TelemetryTimestamps.jsm rename : toolkit/components/telemetry/TelemetryUtils.jsm => toolkit/components/telemetry/app/TelemetryUtils.jsm rename : toolkit/components/telemetry/gen_event_data.py => toolkit/components/telemetry/build_scripts/gen_event_data.py rename : toolkit/components/telemetry/gen_event_enum.py => toolkit/components/telemetry/build_scripts/gen_event_enum.py rename : toolkit/components/telemetry/gen_histogram_data.py => toolkit/components/telemetry/build_scripts/gen_histogram_data.py rename : toolkit/components/telemetry/gen_histogram_enum.py => toolkit/components/telemetry/build_scripts/gen_histogram_enum.py rename : toolkit/components/telemetry/gen_histogram_phf.py => toolkit/components/telemetry/build_scripts/gen_histogram_phf.py rename : toolkit/components/telemetry/gen_process_data.py => toolkit/components/telemetry/build_scripts/gen_process_data.py rename : toolkit/components/telemetry/gen_process_enum.py => toolkit/components/telemetry/build_scripts/gen_process_enum.py rename : toolkit/components/telemetry/gen_scalar_data.py => toolkit/components/telemetry/build_scripts/gen_scalar_data.py rename : toolkit/components/telemetry/gen_scalar_enum.py => toolkit/components/telemetry/build_scripts/gen_scalar_enum.py rename : toolkit/components/telemetry/parse_events.py => toolkit/components/telemetry/build_scripts/parsers/parse_events.py rename : toolkit/components/telemetry/parse_histograms.py => toolkit/components/telemetry/build_scripts/parsers/parse_histograms.py rename : toolkit/components/telemetry/parse_scalars.py => toolkit/components/telemetry/build_scripts/parsers/parse_scalars.py rename : toolkit/components/telemetry/shared_telemetry_utils.py => toolkit/components/telemetry/build_scripts/parsers/shared_telemetry_utils.py rename : toolkit/components/telemetry/EventInfo.h => toolkit/components/telemetry/core/EventInfo.h rename : toolkit/components/telemetry/ScalarInfo.h => toolkit/components/telemetry/core/ScalarInfo.h rename : toolkit/components/telemetry/Telemetry.cpp => toolkit/components/telemetry/core/Telemetry.cpp rename : toolkit/components/telemetry/Telemetry.h => toolkit/components/telemetry/core/Telemetry.h rename : toolkit/components/telemetry/TelemetryCommon.cpp => toolkit/components/telemetry/core/TelemetryCommon.cpp rename : toolkit/components/telemetry/TelemetryCommon.h => toolkit/components/telemetry/core/TelemetryCommon.h rename : toolkit/components/telemetry/TelemetryEvent.cpp => toolkit/components/telemetry/core/TelemetryEvent.cpp rename : toolkit/components/telemetry/TelemetryEvent.h => toolkit/components/telemetry/core/TelemetryEvent.h rename : toolkit/components/telemetry/TelemetryHistogram.cpp => toolkit/components/telemetry/core/TelemetryHistogram.cpp rename : toolkit/components/telemetry/TelemetryHistogram.h => toolkit/components/telemetry/core/TelemetryHistogram.h rename : toolkit/components/telemetry/TelemetryScalar.cpp => toolkit/components/telemetry/core/TelemetryScalar.cpp rename : toolkit/components/telemetry/TelemetryScalar.h => toolkit/components/telemetry/core/TelemetryScalar.h rename : toolkit/components/telemetry/ipc/TelemetryComms.h => toolkit/components/telemetry/core/ipc/TelemetryComms.h rename : toolkit/components/telemetry/ipc/TelemetryIPC.cpp => toolkit/components/telemetry/core/ipc/TelemetryIPC.cpp rename : toolkit/components/telemetry/ipc/TelemetryIPC.h => toolkit/components/telemetry/core/ipc/TelemetryIPC.h rename : toolkit/components/telemetry/ipc/TelemetryIPCAccumulator.cpp => toolkit/components/telemetry/core/ipc/TelemetryIPCAccumulator.cpp rename : toolkit/components/telemetry/ipc/TelemetryIPCAccumulator.h => toolkit/components/telemetry/core/ipc/TelemetryIPCAccumulator.h rename : toolkit/components/telemetry/nsITelemetry.idl => toolkit/components/telemetry/core/nsITelemetry.idl rename : toolkit/components/telemetry/CombinedStacks.cpp => toolkit/components/telemetry/other/CombinedStacks.cpp rename : toolkit/components/telemetry/CombinedStacks.h => toolkit/components/telemetry/other/CombinedStacks.h rename : toolkit/components/telemetry/GCTelemetry.jsm => toolkit/components/telemetry/other/GCTelemetry.jsm rename : toolkit/components/telemetry/KeyedStackCapturer.cpp => toolkit/components/telemetry/other/KeyedStackCapturer.cpp rename : toolkit/components/telemetry/KeyedStackCapturer.h => toolkit/components/telemetry/other/KeyedStackCapturer.h rename : toolkit/components/telemetry/ProcessedStack.cpp => toolkit/components/telemetry/other/ProcessedStack.cpp rename : toolkit/components/telemetry/ProcessedStack.h => toolkit/components/telemetry/other/ProcessedStack.h rename : toolkit/components/telemetry/TelemetryIOInterposeObserver.cpp => toolkit/components/telemetry/other/TelemetryIOInterposeObserver.cpp rename : toolkit/components/telemetry/TelemetryIOInterposeObserver.h => toolkit/components/telemetry/other/TelemetryIOInterposeObserver.h rename : toolkit/components/telemetry/UITelemetry.jsm => toolkit/components/telemetry/other/UITelemetry.jsm rename : toolkit/components/telemetry/WebrtcTelemetry.cpp => toolkit/components/telemetry/other/WebrtcTelemetry.cpp rename : toolkit/components/telemetry/WebrtcTelemetry.h => toolkit/components/telemetry/other/WebrtcTelemetry.h rename : toolkit/components/telemetry/TelemetryEventPing.jsm => toolkit/components/telemetry/pings/EventPing.jsm rename : toolkit/components/telemetry/TelemetryHealthPing.jsm => toolkit/components/telemetry/pings/HealthPing.jsm rename : toolkit/components/telemetry/TelemetryModules.jsm => toolkit/components/telemetry/pings/ModulesPing.jsm rename : toolkit/components/telemetry/TelemetrySession.jsm => toolkit/components/telemetry/pings/TelemetrySession.jsm rename : toolkit/components/telemetry/UpdatePing.jsm => toolkit/components/telemetry/pings/UpdatePing.jsm --- .../telemetry/{ => app}/TelemetryArchive.jsm | 0 .../{ => app}/TelemetryController.jsm | 0 .../{ => app}/TelemetryEnvironment.jsm | 0 .../{ => app}/TelemetryReportingPolicy.jsm | 0 .../telemetry/{ => app}/TelemetrySend.jsm | 0 .../{ => app}/TelemetryStopwatch.jsm | 0 .../telemetry/{ => app}/TelemetryStorage.jsm | 0 .../{ => app}/TelemetryTimestamps.jsm | 0 .../telemetry/{ => app}/TelemetryUtils.jsm | 0 .../{ => build_scripts}/gen_event_data.py | 6 +- .../{ => build_scripts}/gen_event_enum.py | 4 +- .../{ => build_scripts}/gen_histogram_data.py | 4 +- .../{ => build_scripts}/gen_histogram_enum.py | 4 +- .../{ => build_scripts}/gen_histogram_phf.py | 4 +- .../{ => build_scripts}/gen_process_data.py | 2 +- .../{ => build_scripts}/gen_process_enum.py | 2 +- .../{ => build_scripts}/gen_scalar_data.py | 6 +- .../{ => build_scripts}/gen_scalar_enum.py | 4 +- .../build_scripts/parsers/__init__.py | 0 .../parsers}/parse_events.py | 0 .../parsers}/parse_histograms.py | 9 +- .../parsers}/parse_scalars.py | 0 .../parsers}/shared_telemetry_utils.py | 0 .../telemetry/{ => core}/EventInfo.h | 0 .../telemetry/{ => core}/ScalarInfo.h | 0 .../telemetry/{ => core}/Telemetry.cpp | 8 +- .../telemetry/{ => core}/Telemetry.h | 0 .../telemetry/{ => core}/TelemetryCommon.cpp | 0 .../telemetry/{ => core}/TelemetryCommon.h | 0 .../telemetry/{ => core}/TelemetryEvent.cpp | 0 .../telemetry/{ => core}/TelemetryEvent.h | 0 .../{ => core}/TelemetryHistogram.cpp | 0 .../telemetry/{ => core}/TelemetryHistogram.h | 0 .../telemetry/{ => core}/TelemetryScalar.cpp | 0 .../telemetry/{ => core}/TelemetryScalar.h | 0 .../telemetry/{ => core}/ipc/TelemetryComms.h | 0 .../telemetry/{ => core}/ipc/TelemetryIPC.cpp | 0 .../telemetry/{ => core}/ipc/TelemetryIPC.h | 0 .../ipc/TelemetryIPCAccumulator.cpp | 4 +- .../{ => core}/ipc/TelemetryIPCAccumulator.h | 0 .../telemetry/{ => core}/nsITelemetry.idl | 0 .../TelemetryGeckoViewPersistence.cpp | 4 +- .../geckoview/TelemetryGeckoViewTesting.cpp | 2 +- .../geckoview/gtest/TestGeckoView.cpp | 4 +- .../telemetry/gen-histogram-bucket-ranges.py | 53 ----------- toolkit/components/telemetry/moz.build | 90 +++++++++---------- .../telemetry/{ => other}/CombinedStacks.cpp | 0 .../telemetry/{ => other}/CombinedStacks.h | 0 .../telemetry/{ => other}/GCTelemetry.jsm | 0 .../{ => other}/KeyedStackCapturer.cpp | 0 .../{ => other}/KeyedStackCapturer.h | 2 +- .../telemetry/{ => other}/ProcessedStack.cpp | 0 .../telemetry/{ => other}/ProcessedStack.h | 0 .../TelemetryIOInterposeObserver.cpp | 2 +- .../TelemetryIOInterposeObserver.h | 2 +- .../telemetry/{ => other}/UITelemetry.jsm | 0 .../telemetry/{ => other}/WebrtcTelemetry.cpp | 3 +- .../telemetry/{ => other}/WebrtcTelemetry.h | 2 +- .../EventPing.jsm} | 0 .../HealthPing.jsm} | 0 .../ModulesPing.jsm} | 0 .../{ => pings}/TelemetrySession.jsm | 0 .../telemetry/{ => pings}/UpdatePing.jsm | 0 .../telemetry/schemas/core.schema.json | 41 --------- .../tests/gtest/TelemetryTestHelpers.cpp | 2 +- .../tests/gtest/TestCombinedStacks.cpp | 4 +- .../telemetry/tests/gtest/TestCounters.cpp | 2 +- .../telemetry/tests/gtest/TestHistograms.cpp | 2 +- .../telemetry/tests/gtest/TestScalars.cpp | 4 +- 69 files changed, 93 insertions(+), 183 deletions(-) rename toolkit/components/telemetry/{ => app}/TelemetryArchive.jsm (100%) rename toolkit/components/telemetry/{ => app}/TelemetryController.jsm (100%) rename toolkit/components/telemetry/{ => app}/TelemetryEnvironment.jsm (100%) rename toolkit/components/telemetry/{ => app}/TelemetryReportingPolicy.jsm (100%) rename toolkit/components/telemetry/{ => app}/TelemetrySend.jsm (100%) rename toolkit/components/telemetry/{ => app}/TelemetryStopwatch.jsm (100%) rename toolkit/components/telemetry/{ => app}/TelemetryStorage.jsm (100%) rename toolkit/components/telemetry/{ => app}/TelemetryTimestamps.jsm (100%) rename toolkit/components/telemetry/{ => app}/TelemetryUtils.jsm (100%) rename toolkit/components/telemetry/{ => build_scripts}/gen_event_data.py (97%) rename toolkit/components/telemetry/{ => build_scripts}/gen_event_enum.py (96%) rename toolkit/components/telemetry/{ => build_scripts}/gen_histogram_data.py (98%) rename toolkit/components/telemetry/{ => build_scripts}/gen_histogram_enum.py (97%) rename toolkit/components/telemetry/{ => build_scripts}/gen_histogram_phf.py (94%) rename toolkit/components/telemetry/{ => build_scripts}/gen_process_data.py (97%) rename toolkit/components/telemetry/{ => build_scripts}/gen_process_enum.py (96%) rename toolkit/components/telemetry/{ => build_scripts}/gen_scalar_data.py (96%) rename toolkit/components/telemetry/{ => build_scripts}/gen_scalar_enum.py (94%) create mode 100644 toolkit/components/telemetry/build_scripts/parsers/__init__.py rename toolkit/components/telemetry/{ => build_scripts/parsers}/parse_events.py (100%) rename toolkit/components/telemetry/{ => build_scripts/parsers}/parse_histograms.py (98%) rename toolkit/components/telemetry/{ => build_scripts/parsers}/parse_scalars.py (100%) rename toolkit/components/telemetry/{ => build_scripts/parsers}/shared_telemetry_utils.py (100%) rename toolkit/components/telemetry/{ => core}/EventInfo.h (100%) rename toolkit/components/telemetry/{ => core}/ScalarInfo.h (100%) rename toolkit/components/telemetry/{ => core}/Telemetry.cpp (99%) rename toolkit/components/telemetry/{ => core}/Telemetry.h (100%) rename toolkit/components/telemetry/{ => core}/TelemetryCommon.cpp (100%) rename toolkit/components/telemetry/{ => core}/TelemetryCommon.h (100%) rename toolkit/components/telemetry/{ => core}/TelemetryEvent.cpp (100%) rename toolkit/components/telemetry/{ => core}/TelemetryEvent.h (100%) rename toolkit/components/telemetry/{ => core}/TelemetryHistogram.cpp (100%) rename toolkit/components/telemetry/{ => core}/TelemetryHistogram.h (100%) rename toolkit/components/telemetry/{ => core}/TelemetryScalar.cpp (100%) rename toolkit/components/telemetry/{ => core}/TelemetryScalar.h (100%) rename toolkit/components/telemetry/{ => core}/ipc/TelemetryComms.h (100%) rename toolkit/components/telemetry/{ => core}/ipc/TelemetryIPC.cpp (100%) rename toolkit/components/telemetry/{ => core}/ipc/TelemetryIPC.h (100%) rename toolkit/components/telemetry/{ => core}/ipc/TelemetryIPCAccumulator.cpp (99%) rename toolkit/components/telemetry/{ => core}/ipc/TelemetryIPCAccumulator.h (100%) rename toolkit/components/telemetry/{ => core}/nsITelemetry.idl (100%) delete mode 100644 toolkit/components/telemetry/gen-histogram-bucket-ranges.py rename toolkit/components/telemetry/{ => other}/CombinedStacks.cpp (100%) rename toolkit/components/telemetry/{ => other}/CombinedStacks.h (100%) rename toolkit/components/telemetry/{ => other}/GCTelemetry.jsm (100%) rename toolkit/components/telemetry/{ => other}/KeyedStackCapturer.cpp (100%) rename toolkit/components/telemetry/{ => other}/KeyedStackCapturer.h (98%) rename toolkit/components/telemetry/{ => other}/ProcessedStack.cpp (100%) rename toolkit/components/telemetry/{ => other}/ProcessedStack.h (100%) rename toolkit/components/telemetry/{ => other}/TelemetryIOInterposeObserver.cpp (99%) rename toolkit/components/telemetry/{ => other}/TelemetryIOInterposeObserver.h (99%) rename toolkit/components/telemetry/{ => other}/UITelemetry.jsm (100%) rename toolkit/components/telemetry/{ => other}/WebrtcTelemetry.cpp (98%) rename toolkit/components/telemetry/{ => other}/WebrtcTelemetry.h (97%) rename toolkit/components/telemetry/{TelemetryEventPing.jsm => pings/EventPing.jsm} (100%) rename toolkit/components/telemetry/{TelemetryHealthPing.jsm => pings/HealthPing.jsm} (100%) rename toolkit/components/telemetry/{TelemetryModules.jsm => pings/ModulesPing.jsm} (100%) rename toolkit/components/telemetry/{ => pings}/TelemetrySession.jsm (100%) rename toolkit/components/telemetry/{ => pings}/UpdatePing.jsm (100%) delete mode 100644 toolkit/components/telemetry/schemas/core.schema.json diff --git a/toolkit/components/telemetry/TelemetryArchive.jsm b/toolkit/components/telemetry/app/TelemetryArchive.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryArchive.jsm rename to toolkit/components/telemetry/app/TelemetryArchive.jsm diff --git a/toolkit/components/telemetry/TelemetryController.jsm b/toolkit/components/telemetry/app/TelemetryController.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryController.jsm rename to toolkit/components/telemetry/app/TelemetryController.jsm diff --git a/toolkit/components/telemetry/TelemetryEnvironment.jsm b/toolkit/components/telemetry/app/TelemetryEnvironment.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryEnvironment.jsm rename to toolkit/components/telemetry/app/TelemetryEnvironment.jsm diff --git a/toolkit/components/telemetry/TelemetryReportingPolicy.jsm b/toolkit/components/telemetry/app/TelemetryReportingPolicy.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryReportingPolicy.jsm rename to toolkit/components/telemetry/app/TelemetryReportingPolicy.jsm diff --git a/toolkit/components/telemetry/TelemetrySend.jsm b/toolkit/components/telemetry/app/TelemetrySend.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetrySend.jsm rename to toolkit/components/telemetry/app/TelemetrySend.jsm diff --git a/toolkit/components/telemetry/TelemetryStopwatch.jsm b/toolkit/components/telemetry/app/TelemetryStopwatch.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryStopwatch.jsm rename to toolkit/components/telemetry/app/TelemetryStopwatch.jsm diff --git a/toolkit/components/telemetry/TelemetryStorage.jsm b/toolkit/components/telemetry/app/TelemetryStorage.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryStorage.jsm rename to toolkit/components/telemetry/app/TelemetryStorage.jsm diff --git a/toolkit/components/telemetry/TelemetryTimestamps.jsm b/toolkit/components/telemetry/app/TelemetryTimestamps.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryTimestamps.jsm rename to toolkit/components/telemetry/app/TelemetryTimestamps.jsm diff --git a/toolkit/components/telemetry/TelemetryUtils.jsm b/toolkit/components/telemetry/app/TelemetryUtils.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryUtils.jsm rename to toolkit/components/telemetry/app/TelemetryUtils.jsm diff --git a/toolkit/components/telemetry/gen_event_data.py b/toolkit/components/telemetry/build_scripts/gen_event_data.py similarity index 97% rename from toolkit/components/telemetry/gen_event_data.py rename to toolkit/components/telemetry/build_scripts/gen_event_data.py index 85569245dc08..97dce90688f7 100644 --- a/toolkit/components/telemetry/gen_event_data.py +++ b/toolkit/components/telemetry/build_scripts/gen_event_data.py @@ -7,10 +7,10 @@ from __future__ import print_function from collections import OrderedDict -from shared_telemetry_utils import StringTable, static_assert, ParserError +from parsers.shared_telemetry_utils import StringTable, static_assert, ParserError +from parsers import parse_events import json -import parse_events import sys import itertools @@ -22,7 +22,7 @@ banner = """/* This file is auto-generated, only for internal use in TelemetryEv file_header = """\ #ifndef mozilla_TelemetryEventData_h #define mozilla_TelemetryEventData_h -#include "EventInfo.h" +#include "core/EventInfo.h" namespace { """ diff --git a/toolkit/components/telemetry/gen_event_enum.py b/toolkit/components/telemetry/build_scripts/gen_event_enum.py similarity index 96% rename from toolkit/components/telemetry/gen_event_enum.py rename to toolkit/components/telemetry/build_scripts/gen_event_enum.py index 786bcae3af2a..7b1f7d2fb76a 100644 --- a/toolkit/components/telemetry/gen_event_enum.py +++ b/toolkit/components/telemetry/build_scripts/gen_event_enum.py @@ -7,10 +7,10 @@ # The events are defined in files provided as command-line arguments. from __future__ import print_function -from shared_telemetry_utils import ParserError +from parsers.shared_telemetry_utils import ParserError +from parsers import parse_events import sys -import parse_events banner = """/* This file is auto-generated, see gen_event_enum.py. */ """ diff --git a/toolkit/components/telemetry/gen_histogram_data.py b/toolkit/components/telemetry/build_scripts/gen_histogram_data.py similarity index 98% rename from toolkit/components/telemetry/gen_histogram_data.py rename to toolkit/components/telemetry/build_scripts/gen_histogram_data.py index 7af76cc72e87..76a9cfaa6525 100644 --- a/toolkit/components/telemetry/gen_histogram_data.py +++ b/toolkit/components/telemetry/build_scripts/gen_histogram_data.py @@ -6,10 +6,10 @@ # in a file provided as a command-line argument. from __future__ import print_function -from shared_telemetry_utils import StringTable, static_assert, ParserError +from parsers.shared_telemetry_utils import StringTable, static_assert, ParserError +from parsers import parse_histograms import sys -import parse_histograms import buildconfig banner = """/* This file is auto-generated, see gen_histogram_data.py. */ diff --git a/toolkit/components/telemetry/gen_histogram_enum.py b/toolkit/components/telemetry/build_scripts/gen_histogram_enum.py similarity index 97% rename from toolkit/components/telemetry/gen_histogram_enum.py rename to toolkit/components/telemetry/build_scripts/gen_histogram_enum.py index 9a9fde03431f..75c4f7bcc3b7 100644 --- a/toolkit/components/telemetry/gen_histogram_enum.py +++ b/toolkit/components/telemetry/build_scripts/gen_histogram_enum.py @@ -13,9 +13,9 @@ # The histograms are defined in files provided as command-line arguments. from __future__ import print_function -from shared_telemetry_utils import ParserError +from parsers.shared_telemetry_utils import ParserError +from parsers import parse_histograms -import parse_histograms import itertools import sys import buildconfig diff --git a/toolkit/components/telemetry/gen_histogram_phf.py b/toolkit/components/telemetry/build_scripts/gen_histogram_phf.py similarity index 94% rename from toolkit/components/telemetry/gen_histogram_phf.py rename to toolkit/components/telemetry/build_scripts/gen_histogram_phf.py index f291f10f56dc..8918967f5e5c 100644 --- a/toolkit/components/telemetry/gen_histogram_phf.py +++ b/toolkit/components/telemetry/build_scripts/gen_histogram_phf.py @@ -3,12 +3,12 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. from __future__ import print_function -from shared_telemetry_utils import ParserError +from parsers.shared_telemetry_utils import ParserError from perfecthash import PerfectHash PHFSIZE = 512 -import parse_histograms +from parsers import parse_histograms import sys import buildconfig diff --git a/toolkit/components/telemetry/gen_process_data.py b/toolkit/components/telemetry/build_scripts/gen_process_data.py similarity index 97% rename from toolkit/components/telemetry/gen_process_data.py rename to toolkit/components/telemetry/build_scripts/gen_process_data.py index 56842c640ea2..8bfe90fdf0c5 100644 --- a/toolkit/components/telemetry/gen_process_data.py +++ b/toolkit/components/telemetry/build_scripts/gen_process_data.py @@ -6,7 +6,7 @@ # in a file provided as a command-line argument. from __future__ import print_function -from shared_telemetry_utils import ParserError, load_yaml_file +from parsers.shared_telemetry_utils import ParserError, load_yaml_file import sys import collections diff --git a/toolkit/components/telemetry/gen_process_enum.py b/toolkit/components/telemetry/build_scripts/gen_process_enum.py similarity index 96% rename from toolkit/components/telemetry/gen_process_enum.py rename to toolkit/components/telemetry/build_scripts/gen_process_enum.py index d771e381c0bf..c70326b2b003 100644 --- a/toolkit/components/telemetry/gen_process_enum.py +++ b/toolkit/components/telemetry/build_scripts/gen_process_enum.py @@ -6,7 +6,7 @@ # in a file provided as a command-line argument. from __future__ import print_function -from shared_telemetry_utils import ParserError, load_yaml_file +from parsers.shared_telemetry_utils import ParserError, load_yaml_file import sys import collections diff --git a/toolkit/components/telemetry/gen_scalar_data.py b/toolkit/components/telemetry/build_scripts/gen_scalar_data.py similarity index 96% rename from toolkit/components/telemetry/gen_scalar_data.py rename to toolkit/components/telemetry/build_scripts/gen_scalar_data.py index ca4b8b462c7d..e86b30ecfdc6 100644 --- a/toolkit/components/telemetry/gen_scalar_data.py +++ b/toolkit/components/telemetry/build_scripts/gen_scalar_data.py @@ -7,10 +7,10 @@ from __future__ import print_function from collections import OrderedDict -from shared_telemetry_utils import StringTable, static_assert, ParserError +from parsers.shared_telemetry_utils import StringTable, static_assert, ParserError +from parsers import parse_scalars import json -import parse_scalars import sys # The banner/text at the top of the generated file. @@ -21,7 +21,7 @@ banner = """/* This file is auto-generated, only for internal use in TelemetrySc file_header = """\ #ifndef mozilla_TelemetryScalarData_h #define mozilla_TelemetryScalarData_h -#include "ScalarInfo.h" +#include "core/ScalarInfo.h" namespace { """ diff --git a/toolkit/components/telemetry/gen_scalar_enum.py b/toolkit/components/telemetry/build_scripts/gen_scalar_enum.py similarity index 94% rename from toolkit/components/telemetry/gen_scalar_enum.py rename to toolkit/components/telemetry/build_scripts/gen_scalar_enum.py index d84895a91595..4ae2ceeb6ba2 100644 --- a/toolkit/components/telemetry/gen_scalar_enum.py +++ b/toolkit/components/telemetry/build_scripts/gen_scalar_enum.py @@ -8,10 +8,10 @@ # The scalars are defined in files provided as command-line arguments. from __future__ import print_function -from shared_telemetry_utils import ParserError +from parsers.shared_telemetry_utils import ParserError +from parsers import parse_scalars import sys -import parse_scalars banner = """/* This file is auto-generated, see gen_scalar_enum.py. */ """ diff --git a/toolkit/components/telemetry/build_scripts/parsers/__init__.py b/toolkit/components/telemetry/build_scripts/parsers/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/toolkit/components/telemetry/parse_events.py b/toolkit/components/telemetry/build_scripts/parsers/parse_events.py similarity index 100% rename from toolkit/components/telemetry/parse_events.py rename to toolkit/components/telemetry/build_scripts/parsers/parse_events.py diff --git a/toolkit/components/telemetry/parse_histograms.py b/toolkit/components/telemetry/build_scripts/parsers/parse_histograms.py similarity index 98% rename from toolkit/components/telemetry/parse_histograms.py rename to toolkit/components/telemetry/build_scripts/parsers/parse_histograms.py index a552d75283cd..89987f7650c2 100755 --- a/toolkit/components/telemetry/parse_histograms.py +++ b/toolkit/components/telemetry/build_scripts/parsers/parse_histograms.py @@ -96,8 +96,13 @@ whitelists = None def load_whitelist(): global whitelists try: - whitelist_path = os.path.join(os.path.abspath(os.path.realpath(os.path.dirname(__file__))), - 'histogram-whitelists.json') + parsers_path = os.path.realpath(os.path.dirname(__file__)) + # The parsers live in build_scripts/parsers in the Telemetry module, while + # the histogram-whitelists file lives in the root of the module. Account + # for that when looking for the whitelist. + # NOTE: if the parsers are moved, this logic will need to be updated. + telemetry_module_path = os.path.abspath(os.path.join(parsers_path, os.pardir, os.pardir)) + whitelist_path = os.path.join(telemetry_module_path, 'histogram-whitelists.json') with open(whitelist_path, 'r') as f: try: whitelists = json.load(f) diff --git a/toolkit/components/telemetry/parse_scalars.py b/toolkit/components/telemetry/build_scripts/parsers/parse_scalars.py similarity index 100% rename from toolkit/components/telemetry/parse_scalars.py rename to toolkit/components/telemetry/build_scripts/parsers/parse_scalars.py diff --git a/toolkit/components/telemetry/shared_telemetry_utils.py b/toolkit/components/telemetry/build_scripts/parsers/shared_telemetry_utils.py similarity index 100% rename from toolkit/components/telemetry/shared_telemetry_utils.py rename to toolkit/components/telemetry/build_scripts/parsers/shared_telemetry_utils.py diff --git a/toolkit/components/telemetry/EventInfo.h b/toolkit/components/telemetry/core/EventInfo.h similarity index 100% rename from toolkit/components/telemetry/EventInfo.h rename to toolkit/components/telemetry/core/EventInfo.h diff --git a/toolkit/components/telemetry/ScalarInfo.h b/toolkit/components/telemetry/core/ScalarInfo.h similarity index 100% rename from toolkit/components/telemetry/ScalarInfo.h rename to toolkit/components/telemetry/core/ScalarInfo.h diff --git a/toolkit/components/telemetry/Telemetry.cpp b/toolkit/components/telemetry/core/Telemetry.cpp similarity index 99% rename from toolkit/components/telemetry/Telemetry.cpp rename to toolkit/components/telemetry/core/Telemetry.cpp index eef1463533c1..19a45c26a4be 100644 --- a/toolkit/components/telemetry/Telemetry.cpp +++ b/toolkit/components/telemetry/core/Telemetry.cpp @@ -24,7 +24,7 @@ #include "mozilla/Unused.h" #include "base/pickle.h" -#include "CombinedStacks.h" +#include "other/CombinedStacks.h" #include "nsIComponentManager.h" #include "nsIServiceManager.h" #include "nsThreadManager.h" @@ -52,11 +52,11 @@ #include "Telemetry.h" #include "TelemetryCommon.h" #include "TelemetryHistogram.h" -#include "TelemetryIOInterposeObserver.h" +#include "other/TelemetryIOInterposeObserver.h" #include "ipc/TelemetryIPCAccumulator.h" #include "TelemetryScalar.h" #include "TelemetryEvent.h" -#include "WebrtcTelemetry.h" +#include "other/WebrtcTelemetry.h" #include "nsTHashtable.h" #include "nsHashKeys.h" #include "nsBaseHashtable.h" @@ -91,7 +91,7 @@ #if defined(MOZ_GECKO_PROFILER) #include "shared-libraries.h" -#include "KeyedStackCapturer.h" +#include "other/KeyedStackCapturer.h" #endif // MOZ_GECKO_PROFILER #if defined(MOZ_TELEMETRY_GECKOVIEW) diff --git a/toolkit/components/telemetry/Telemetry.h b/toolkit/components/telemetry/core/Telemetry.h similarity index 100% rename from toolkit/components/telemetry/Telemetry.h rename to toolkit/components/telemetry/core/Telemetry.h diff --git a/toolkit/components/telemetry/TelemetryCommon.cpp b/toolkit/components/telemetry/core/TelemetryCommon.cpp similarity index 100% rename from toolkit/components/telemetry/TelemetryCommon.cpp rename to toolkit/components/telemetry/core/TelemetryCommon.cpp diff --git a/toolkit/components/telemetry/TelemetryCommon.h b/toolkit/components/telemetry/core/TelemetryCommon.h similarity index 100% rename from toolkit/components/telemetry/TelemetryCommon.h rename to toolkit/components/telemetry/core/TelemetryCommon.h diff --git a/toolkit/components/telemetry/TelemetryEvent.cpp b/toolkit/components/telemetry/core/TelemetryEvent.cpp similarity index 100% rename from toolkit/components/telemetry/TelemetryEvent.cpp rename to toolkit/components/telemetry/core/TelemetryEvent.cpp diff --git a/toolkit/components/telemetry/TelemetryEvent.h b/toolkit/components/telemetry/core/TelemetryEvent.h similarity index 100% rename from toolkit/components/telemetry/TelemetryEvent.h rename to toolkit/components/telemetry/core/TelemetryEvent.h diff --git a/toolkit/components/telemetry/TelemetryHistogram.cpp b/toolkit/components/telemetry/core/TelemetryHistogram.cpp similarity index 100% rename from toolkit/components/telemetry/TelemetryHistogram.cpp rename to toolkit/components/telemetry/core/TelemetryHistogram.cpp diff --git a/toolkit/components/telemetry/TelemetryHistogram.h b/toolkit/components/telemetry/core/TelemetryHistogram.h similarity index 100% rename from toolkit/components/telemetry/TelemetryHistogram.h rename to toolkit/components/telemetry/core/TelemetryHistogram.h diff --git a/toolkit/components/telemetry/TelemetryScalar.cpp b/toolkit/components/telemetry/core/TelemetryScalar.cpp similarity index 100% rename from toolkit/components/telemetry/TelemetryScalar.cpp rename to toolkit/components/telemetry/core/TelemetryScalar.cpp diff --git a/toolkit/components/telemetry/TelemetryScalar.h b/toolkit/components/telemetry/core/TelemetryScalar.h similarity index 100% rename from toolkit/components/telemetry/TelemetryScalar.h rename to toolkit/components/telemetry/core/TelemetryScalar.h diff --git a/toolkit/components/telemetry/ipc/TelemetryComms.h b/toolkit/components/telemetry/core/ipc/TelemetryComms.h similarity index 100% rename from toolkit/components/telemetry/ipc/TelemetryComms.h rename to toolkit/components/telemetry/core/ipc/TelemetryComms.h diff --git a/toolkit/components/telemetry/ipc/TelemetryIPC.cpp b/toolkit/components/telemetry/core/ipc/TelemetryIPC.cpp similarity index 100% rename from toolkit/components/telemetry/ipc/TelemetryIPC.cpp rename to toolkit/components/telemetry/core/ipc/TelemetryIPC.cpp diff --git a/toolkit/components/telemetry/ipc/TelemetryIPC.h b/toolkit/components/telemetry/core/ipc/TelemetryIPC.h similarity index 100% rename from toolkit/components/telemetry/ipc/TelemetryIPC.h rename to toolkit/components/telemetry/core/ipc/TelemetryIPC.h diff --git a/toolkit/components/telemetry/ipc/TelemetryIPCAccumulator.cpp b/toolkit/components/telemetry/core/ipc/TelemetryIPCAccumulator.cpp similarity index 99% rename from toolkit/components/telemetry/ipc/TelemetryIPCAccumulator.cpp rename to toolkit/components/telemetry/core/ipc/TelemetryIPCAccumulator.cpp index 4ca5bcd44640..71e0aa730032 100644 --- a/toolkit/components/telemetry/ipc/TelemetryIPCAccumulator.cpp +++ b/toolkit/components/telemetry/core/ipc/TelemetryIPCAccumulator.cpp @@ -16,8 +16,8 @@ #include "nsComponentManagerUtils.h" #include "nsITimer.h" #include "nsThreadUtils.h" -#include "TelemetryHistogram.h" -#include "TelemetryScalar.h" +#include "core/TelemetryHistogram.h" +#include "core/TelemetryScalar.h" using mozilla::StaticMutex; using mozilla::StaticMutexAutoLock; diff --git a/toolkit/components/telemetry/ipc/TelemetryIPCAccumulator.h b/toolkit/components/telemetry/core/ipc/TelemetryIPCAccumulator.h similarity index 100% rename from toolkit/components/telemetry/ipc/TelemetryIPCAccumulator.h rename to toolkit/components/telemetry/core/ipc/TelemetryIPCAccumulator.h diff --git a/toolkit/components/telemetry/nsITelemetry.idl b/toolkit/components/telemetry/core/nsITelemetry.idl similarity index 100% rename from toolkit/components/telemetry/nsITelemetry.idl rename to toolkit/components/telemetry/core/nsITelemetry.idl diff --git a/toolkit/components/telemetry/geckoview/TelemetryGeckoViewPersistence.cpp b/toolkit/components/telemetry/geckoview/TelemetryGeckoViewPersistence.cpp index d9fe8145ec99..97d6250adbb2 100644 --- a/toolkit/components/telemetry/geckoview/TelemetryGeckoViewPersistence.cpp +++ b/toolkit/components/telemetry/geckoview/TelemetryGeckoViewPersistence.cpp @@ -29,8 +29,8 @@ #include "nsXULAppAPI.h" #include "prenv.h" #include "prio.h" -#include "TelemetryScalar.h" -#include "TelemetryHistogram.h" +#include "core/TelemetryScalar.h" +#include "core/TelemetryHistogram.h" #include "xpcpublic.h" using mozilla::GetErrorName; diff --git a/toolkit/components/telemetry/geckoview/TelemetryGeckoViewTesting.cpp b/toolkit/components/telemetry/geckoview/TelemetryGeckoViewTesting.cpp index dcafc92fa473..7c2cd4ecece9 100644 --- a/toolkit/components/telemetry/geckoview/TelemetryGeckoViewTesting.cpp +++ b/toolkit/components/telemetry/geckoview/TelemetryGeckoViewTesting.cpp @@ -4,7 +4,7 @@ #include "TelemetryGeckoViewTesting.h" #include "TelemetryGeckoViewPersistence.h" -#include "TelemetryScalar.h" +#include "core/TelemetryScalar.h" namespace TelemetryGeckoViewTesting { // This is defined in TelemetryGeckoViewPersistence.cpp diff --git a/toolkit/components/telemetry/geckoview/gtest/TestGeckoView.cpp b/toolkit/components/telemetry/geckoview/gtest/TestGeckoView.cpp index 38c50ebbe6db..3c1e888439fe 100644 --- a/toolkit/components/telemetry/geckoview/gtest/TestGeckoView.cpp +++ b/toolkit/components/telemetry/geckoview/gtest/TestGeckoView.cpp @@ -15,10 +15,10 @@ #include "nsThreadUtils.h" #include "nsPrintfCString.h" #include "prenv.h" -#include "Telemetry.h" +#include "mozilla/Telemetry.h" #include "TelemetryFixture.h" #include "TelemetryGeckoViewPersistence.h" -#include "TelemetryScalar.h" +#include "core/TelemetryScalar.h" #include "TelemetryTestHelpers.h" using namespace mozilla; diff --git a/toolkit/components/telemetry/gen-histogram-bucket-ranges.py b/toolkit/components/telemetry/gen-histogram-bucket-ranges.py deleted file mode 100644 index 7a2f1b697867..000000000000 --- a/toolkit/components/telemetry/gen-histogram-bucket-ranges.py +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env python -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Write out detailed histogram information, including the ranges of the -# buckets specified by each histogram. - -import sys -import parse_histograms -import json - -from collections import OrderedDict - - -def main(argv): - filenames = argv - - all_histograms = OrderedDict() - - for histogram in parse_histograms.from_files(filenames): - name = histogram.name() - parameters = OrderedDict() - table = { - 'boolean': '2', - 'flag': '3', - 'enumerated': '1', - 'linear': '1', - 'exponential': '0', - 'count': '4', - } - # Use __setitem__ because Python lambdas are so limited. - parse_histograms.table_dispatch(histogram.kind(), table, - lambda k: parameters.__setitem__('kind', k)) - if histogram.low() == 0: - parameters['min'] = 1 - else: - parameters['min'] = histogram.low() - - try: - buckets = histogram.ranges() - parameters['buckets'] = buckets - parameters['max'] = buckets[-1] - parameters['bucket_count'] = len(buckets) - except parse_histograms.DefinitionException: - continue - - all_histograms.update({name: parameters}) - - print json.dumps({'histograms': all_histograms}) - - -main(sys.argv[1:]) diff --git a/toolkit/components/telemetry/moz.build b/toolkit/components/telemetry/moz.build index 2bda9795ab40..489334d0a829 100644 --- a/toolkit/components/telemetry/moz.build +++ b/toolkit/components/telemetry/moz.build @@ -44,7 +44,7 @@ XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini'] BROWSER_CHROME_MANIFESTS += ['tests/browser/browser.ini'] XPIDL_SOURCES += [ - 'nsITelemetry.idl', + 'core/nsITelemetry.idl', ] XPIDL_MODULE = 'telemetry' @@ -54,32 +54,32 @@ EXPORTS.mozilla += [ '!TelemetryHistogramEnums.h', '!TelemetryProcessEnums.h', '!TelemetryScalarEnums.h', - 'CombinedStacks.h', - 'ipc/TelemetryComms.h', - 'ipc/TelemetryIPC.h', - 'ProcessedStack.h', - 'Telemetry.h', + 'core/ipc/TelemetryComms.h', + 'core/ipc/TelemetryIPC.h', + 'core/Telemetry.h', + 'other/CombinedStacks.h', + 'other/ProcessedStack.h', ] SOURCES += [ - 'CombinedStacks.cpp', + 'core/ipc/TelemetryIPC.cpp', + 'core/ipc/TelemetryIPCAccumulator.cpp', + 'core/Telemetry.cpp', + 'core/TelemetryCommon.cpp', + 'core/TelemetryEvent.cpp', + 'core/TelemetryHistogram.cpp', + 'core/TelemetryScalar.cpp', 'geckoview/TelemetryGeckoViewPersistence.cpp', - 'ipc/TelemetryIPC.cpp', - 'ipc/TelemetryIPCAccumulator.cpp', - 'ProcessedStack.cpp', - 'Telemetry.cpp', - 'TelemetryCommon.cpp', - 'TelemetryEvent.cpp', - 'TelemetryHistogram.cpp', - 'TelemetryIOInterposeObserver.cpp', - 'TelemetryScalar.cpp', - 'WebrtcTelemetry.cpp', + 'other/CombinedStacks.cpp', + 'other/ProcessedStack.cpp', + 'other/TelemetryIOInterposeObserver.cpp', + 'other/WebrtcTelemetry.cpp', ] # KeyedStackCapturer entirely relies on profiler to be enabled. if CONFIG['MOZ_GECKO_PROFILER']: SOURCES += [ - 'KeyedStackCapturer.cpp' + 'other/KeyedStackCapturer.cpp' ] EXTRA_COMPONENTS += [ @@ -88,22 +88,22 @@ EXTRA_COMPONENTS += [ ] EXTRA_JS_MODULES += [ - 'GCTelemetry.jsm', - 'TelemetryArchive.jsm', - 'TelemetryController.jsm', - 'TelemetryEnvironment.jsm', - 'TelemetryEventPing.jsm', - 'TelemetryHealthPing.jsm', - 'TelemetryModules.jsm', - 'TelemetryReportingPolicy.jsm', - 'TelemetrySend.jsm', - 'TelemetrySession.jsm', - 'TelemetryStopwatch.jsm', - 'TelemetryStorage.jsm', - 'TelemetryTimestamps.jsm', - 'TelemetryUtils.jsm', - 'UITelemetry.jsm', - 'UpdatePing.jsm', + 'app/TelemetryArchive.jsm', + 'app/TelemetryController.jsm', + 'app/TelemetryEnvironment.jsm', + 'app/TelemetryReportingPolicy.jsm', + 'app/TelemetrySend.jsm', + 'app/TelemetryStopwatch.jsm', + 'app/TelemetryStorage.jsm', + 'app/TelemetryTimestamps.jsm', + 'app/TelemetryUtils.jsm', + 'other/GCTelemetry.jsm', + 'other/UITelemetry.jsm', + 'pings/EventPing.jsm', + 'pings/HealthPing.jsm', + 'pings/ModulesPing.jsm', + 'pings/TelemetrySession.jsm', + 'pings/UpdatePing.jsm', ] TESTING_JS_MODULES += [ @@ -136,15 +136,15 @@ histogram_files = [ ] data = GENERATED_FILES['TelemetryHistogramData.inc'] -data.script = 'gen_histogram_data.py' +data.script = 'build_scripts/gen_histogram_data.py' data.inputs = histogram_files enums = GENERATED_FILES['TelemetryHistogramEnums.h'] -enums.script = 'gen_histogram_enum.py' +enums.script = 'build_scripts/gen_histogram_enum.py' enums.inputs = histogram_files data = GENERATED_FILES['TelemetryHistogramNameMap.h'] -data.script = 'gen_histogram_phf.py' +data.script = 'build_scripts/gen_histogram_phf.py' data.inputs = histogram_files # Generate scalar files. @@ -153,17 +153,17 @@ scalar_files = [ ] scalar_data = GENERATED_FILES['TelemetryScalarData.h'] -scalar_data.script = 'gen_scalar_data.py' +scalar_data.script = 'build_scripts/gen_scalar_data.py' scalar_data.inputs = scalar_files scalar_enums = GENERATED_FILES['TelemetryScalarEnums.h'] -scalar_enums.script = 'gen_scalar_enum.py' +scalar_enums.script = 'build_scripts/gen_scalar_enum.py' scalar_enums.inputs = scalar_files # Generate the JSON scalar definitions. They will only be # used in artifact or "build faster" builds. scalar_json_data = GENERATED_FILES['ScalarArtifactDefinitions.json'] -scalar_json_data.script = 'gen_scalar_data.py:generate_JSON_definitions' +scalar_json_data.script = 'build_scripts/gen_scalar_data.py:generate_JSON_definitions' scalar_json_data.inputs = scalar_files # Move the scalars JSON file to the directory where the Firefox binary is. @@ -175,17 +175,17 @@ event_files = [ ] event_data = GENERATED_FILES['TelemetryEventData.h'] -event_data.script = 'gen_event_data.py' +event_data.script = 'build_scripts/gen_event_data.py' event_data.inputs = event_files event_enums = GENERATED_FILES['TelemetryEventEnums.h'] -event_enums.script = 'gen_event_enum.py' +event_enums.script = 'build_scripts/gen_event_enum.py' event_enums.inputs = event_files # Generate the JSON event definitions. They will only be # used in artifact or "build faster" builds. event_json_data = GENERATED_FILES['EventArtifactDefinitions.json'] -event_json_data.script = 'gen_event_data.py:generate_JSON_definitions' +event_json_data.script = 'build_scripts/gen_event_data.py:generate_JSON_definitions' event_json_data.inputs = event_files # Move the events JSON file to the directory where the Firefox binary is. @@ -197,11 +197,11 @@ processes_files = [ ] processes_enum = GENERATED_FILES['TelemetryProcessEnums.h'] -processes_enum.script = 'gen_process_enum.py' +processes_enum.script = 'build_scripts/gen_process_enum.py' processes_enum.inputs = processes_files processes_data = GENERATED_FILES['TelemetryProcessData.h'] -processes_data.script = 'gen_process_data.py' +processes_data.script = 'build_scripts/gen_process_data.py' processes_data.inputs = processes_files # Add support for GeckoView: please note that building GeckoView diff --git a/toolkit/components/telemetry/CombinedStacks.cpp b/toolkit/components/telemetry/other/CombinedStacks.cpp similarity index 100% rename from toolkit/components/telemetry/CombinedStacks.cpp rename to toolkit/components/telemetry/other/CombinedStacks.cpp diff --git a/toolkit/components/telemetry/CombinedStacks.h b/toolkit/components/telemetry/other/CombinedStacks.h similarity index 100% rename from toolkit/components/telemetry/CombinedStacks.h rename to toolkit/components/telemetry/other/CombinedStacks.h diff --git a/toolkit/components/telemetry/GCTelemetry.jsm b/toolkit/components/telemetry/other/GCTelemetry.jsm similarity index 100% rename from toolkit/components/telemetry/GCTelemetry.jsm rename to toolkit/components/telemetry/other/GCTelemetry.jsm diff --git a/toolkit/components/telemetry/KeyedStackCapturer.cpp b/toolkit/components/telemetry/other/KeyedStackCapturer.cpp similarity index 100% rename from toolkit/components/telemetry/KeyedStackCapturer.cpp rename to toolkit/components/telemetry/other/KeyedStackCapturer.cpp diff --git a/toolkit/components/telemetry/KeyedStackCapturer.h b/toolkit/components/telemetry/other/KeyedStackCapturer.h similarity index 98% rename from toolkit/components/telemetry/KeyedStackCapturer.h rename to toolkit/components/telemetry/other/KeyedStackCapturer.h index 6c3438265a6b..f6632b8fe29e 100644 --- a/toolkit/components/telemetry/KeyedStackCapturer.h +++ b/toolkit/components/telemetry/other/KeyedStackCapturer.h @@ -6,7 +6,7 @@ #ifndef KeyedStackCapturer_h__ #define KeyedStackCapturer_h__ -#include "Telemetry.h" +#include "mozilla/Telemetry.h" #include "nsString.h" #include "nsClassHashtable.h" #include "mozilla/Mutex.h" diff --git a/toolkit/components/telemetry/ProcessedStack.cpp b/toolkit/components/telemetry/other/ProcessedStack.cpp similarity index 100% rename from toolkit/components/telemetry/ProcessedStack.cpp rename to toolkit/components/telemetry/other/ProcessedStack.cpp diff --git a/toolkit/components/telemetry/ProcessedStack.h b/toolkit/components/telemetry/other/ProcessedStack.h similarity index 100% rename from toolkit/components/telemetry/ProcessedStack.h rename to toolkit/components/telemetry/other/ProcessedStack.h diff --git a/toolkit/components/telemetry/TelemetryIOInterposeObserver.cpp b/toolkit/components/telemetry/other/TelemetryIOInterposeObserver.cpp similarity index 99% rename from toolkit/components/telemetry/TelemetryIOInterposeObserver.cpp rename to toolkit/components/telemetry/other/TelemetryIOInterposeObserver.cpp index 411437fdb123..76ba444abc8c 100644 --- a/toolkit/components/telemetry/TelemetryIOInterposeObserver.cpp +++ b/toolkit/components/telemetry/other/TelemetryIOInterposeObserver.cpp @@ -5,7 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "TelemetryIOInterposeObserver.h" -#include "TelemetryCommon.h" +#include "core/TelemetryCommon.h" namespace mozilla { namespace Telemetry { diff --git a/toolkit/components/telemetry/TelemetryIOInterposeObserver.h b/toolkit/components/telemetry/other/TelemetryIOInterposeObserver.h similarity index 99% rename from toolkit/components/telemetry/TelemetryIOInterposeObserver.h rename to toolkit/components/telemetry/other/TelemetryIOInterposeObserver.h index f92881cfc224..efffe3ee19b9 100644 --- a/toolkit/components/telemetry/TelemetryIOInterposeObserver.h +++ b/toolkit/components/telemetry/other/TelemetryIOInterposeObserver.h @@ -20,7 +20,7 @@ #include "nsBaseHashtable.h" #include "nsClassHashtable.h" -#include "TelemetryCommon.h" +#include "core/TelemetryCommon.h" #include "mozilla/IOInterposer.h" namespace mozilla { diff --git a/toolkit/components/telemetry/UITelemetry.jsm b/toolkit/components/telemetry/other/UITelemetry.jsm similarity index 100% rename from toolkit/components/telemetry/UITelemetry.jsm rename to toolkit/components/telemetry/other/UITelemetry.jsm diff --git a/toolkit/components/telemetry/WebrtcTelemetry.cpp b/toolkit/components/telemetry/other/WebrtcTelemetry.cpp similarity index 98% rename from toolkit/components/telemetry/WebrtcTelemetry.cpp rename to toolkit/components/telemetry/other/WebrtcTelemetry.cpp index 8c03f3a99fb0..0bc166ef7f24 100644 --- a/toolkit/components/telemetry/WebrtcTelemetry.cpp +++ b/toolkit/components/telemetry/other/WebrtcTelemetry.cpp @@ -5,8 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "Telemetry.h" -#include "TelemetryCommon.h" +#include "mozilla/Telemetry.h" #include "WebrtcTelemetry.h" #include "jsapi.h" #include "nsPrintfCString.h" diff --git a/toolkit/components/telemetry/WebrtcTelemetry.h b/toolkit/components/telemetry/other/WebrtcTelemetry.h similarity index 97% rename from toolkit/components/telemetry/WebrtcTelemetry.h rename to toolkit/components/telemetry/other/WebrtcTelemetry.h index ed87c71073ff..6f7f9e192a16 100644 --- a/toolkit/components/telemetry/WebrtcTelemetry.h +++ b/toolkit/components/telemetry/other/WebrtcTelemetry.h @@ -9,7 +9,7 @@ #include "nsBaseHashtable.h" #include "nsHashKeys.h" -#include "TelemetryCommon.h" +#include "core/TelemetryCommon.h" class WebrtcTelemetry { public: diff --git a/toolkit/components/telemetry/TelemetryEventPing.jsm b/toolkit/components/telemetry/pings/EventPing.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryEventPing.jsm rename to toolkit/components/telemetry/pings/EventPing.jsm diff --git a/toolkit/components/telemetry/TelemetryHealthPing.jsm b/toolkit/components/telemetry/pings/HealthPing.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryHealthPing.jsm rename to toolkit/components/telemetry/pings/HealthPing.jsm diff --git a/toolkit/components/telemetry/TelemetryModules.jsm b/toolkit/components/telemetry/pings/ModulesPing.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetryModules.jsm rename to toolkit/components/telemetry/pings/ModulesPing.jsm diff --git a/toolkit/components/telemetry/TelemetrySession.jsm b/toolkit/components/telemetry/pings/TelemetrySession.jsm similarity index 100% rename from toolkit/components/telemetry/TelemetrySession.jsm rename to toolkit/components/telemetry/pings/TelemetrySession.jsm diff --git a/toolkit/components/telemetry/UpdatePing.jsm b/toolkit/components/telemetry/pings/UpdatePing.jsm similarity index 100% rename from toolkit/components/telemetry/UpdatePing.jsm rename to toolkit/components/telemetry/pings/UpdatePing.jsm diff --git a/toolkit/components/telemetry/schemas/core.schema.json b/toolkit/components/telemetry/schemas/core.schema.json deleted file mode 100644 index 327cdc298904..000000000000 --- a/toolkit/components/telemetry/schemas/core.schema.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "$schema" : "http://json-schema.org/draft-04/schema#", - "type" : "object", - "name" : "core", - "properties" : { - "arch" : { - "type" : "string" - }, - "clientId" : { - "type" : "string", - "pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$" - }, - "device" : { - "type" : "string" - }, - "experiments" : { - "type" : "array", - "items" : { - "type" : "string" - } - }, - "locale" : { - "type" : "string" - }, - "os" : { - "type" : "string" - }, - "osversion" : { - "type" : "string" - }, - "seq" : { - "type" : "integer", - "minimum": 0 - }, - "v" : { - "type" : "integer", - "enum" : [ 1 ] - } - }, - "required" : ["arch", "clientId", "device", "locale", "os", "osversion", "seq", "v"] -} diff --git a/toolkit/components/telemetry/tests/gtest/TelemetryTestHelpers.cpp b/toolkit/components/telemetry/tests/gtest/TelemetryTestHelpers.cpp index da4fe71c9775..bd1db74c1c92 100644 --- a/toolkit/components/telemetry/tests/gtest/TelemetryTestHelpers.cpp +++ b/toolkit/components/telemetry/tests/gtest/TelemetryTestHelpers.cpp @@ -6,7 +6,7 @@ #include "gtest/gtest.h" #include "mozilla/CycleCollectedJSContext.h" -#include "TelemetryCommon.h" +#include "core/TelemetryCommon.h" #include "mozilla/Unused.h" using namespace mozilla; diff --git a/toolkit/components/telemetry/tests/gtest/TestCombinedStacks.cpp b/toolkit/components/telemetry/tests/gtest/TestCombinedStacks.cpp index 27225beb13e8..fa75ea5ace43 100644 --- a/toolkit/components/telemetry/tests/gtest/TestCombinedStacks.cpp +++ b/toolkit/components/telemetry/tests/gtest/TestCombinedStacks.cpp @@ -2,8 +2,8 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ -#include "CombinedStacks.h" -#include "ProcessedStack.h" +#include "other/CombinedStacks.h" +#include "other/ProcessedStack.h" using namespace mozilla::Telemetry; using namespace TelemetryTestHelpers; diff --git a/toolkit/components/telemetry/tests/gtest/TestCounters.cpp b/toolkit/components/telemetry/tests/gtest/TestCounters.cpp index eefe4f6f090e..0df7879b17ce 100644 --- a/toolkit/components/telemetry/tests/gtest/TestCounters.cpp +++ b/toolkit/components/telemetry/tests/gtest/TestCounters.cpp @@ -6,7 +6,7 @@ #include "gtest/gtest.h" #include "js/Conversions.h" #include "nsITelemetry.h" -#include "Telemetry.h" +#include "mozilla/Telemetry.h" #include "TelemetryFixture.h" #include "TelemetryTestHelpers.h" diff --git a/toolkit/components/telemetry/tests/gtest/TestHistograms.cpp b/toolkit/components/telemetry/tests/gtest/TestHistograms.cpp index bfc53da43303..dee74f1ee609 100644 --- a/toolkit/components/telemetry/tests/gtest/TestHistograms.cpp +++ b/toolkit/components/telemetry/tests/gtest/TestHistograms.cpp @@ -6,7 +6,7 @@ #include "gtest/gtest.h" #include "js/Conversions.h" #include "nsITelemetry.h" -#include "Telemetry.h" +#include "mozilla/Telemetry.h" #include "TelemetryFixture.h" #include "TelemetryTestHelpers.h" diff --git a/toolkit/components/telemetry/tests/gtest/TestScalars.cpp b/toolkit/components/telemetry/tests/gtest/TestScalars.cpp index f5cc7f523529..e8a808a77314 100644 --- a/toolkit/components/telemetry/tests/gtest/TestScalars.cpp +++ b/toolkit/components/telemetry/tests/gtest/TestScalars.cpp @@ -10,10 +10,10 @@ #include "nsJSUtils.h" // nsAutoJSString #include "nsITelemetry.h" #include "nsThreadUtils.h" -#include "Telemetry.h" +#include "mozilla/Telemetry.h" #include "mozilla/TelemetryProcessEnums.h" #include "TelemetryFixture.h" -#include "TelemetryScalar.h" +#include "core/TelemetryScalar.h" #include "TelemetryTestHelpers.h" using namespace mozilla; From 8c1deadfbf2a7d0054608f05340f67442312a977 Mon Sep 17 00:00:00 2001 From: Paul Adenot Date: Tue, 4 Sep 2018 13:50:15 +0000 Subject: [PATCH 17/61] Bug 1488242 - Throw the correct error type in {ConstantSourceNode,AudioBufferSourceNode}.{Start,Stop}. r=karlt Differential Revision: https://phabricator.services.mozilla.com/D4881 --HG-- extra : moz-landing-system : lando --- dom/bindings/Errors.msg | 1 + dom/media/webaudio/AudioBufferSourceNode.cpp | 15 +++++++++++---- dom/media/webaudio/ConstantSourceNode.cpp | 4 ++-- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/dom/bindings/Errors.msg b/dom/bindings/Errors.msg index 4d9eb79d7f0e..ea05fddcf3ca 100644 --- a/dom/bindings/Errors.msg +++ b/dom/bindings/Errors.msg @@ -111,3 +111,4 @@ MSG_DEF(MSG_INVALID_AUDIOPARAM_METHOD_START_TIME_ERROR, 0, JSEXN_RANGEERR, "The MSG_DEF(MSG_INVALID_AUDIOPARAM_METHOD_END_TIME_ERROR, 0, JSEXN_RANGEERR, "The end time for an AudioParam method must be positive.") MSG_DEF(MSG_INVALID_AUDIOPARAM_EXPONENTIAL_VALUE_ERROR, 0, JSEXN_RANGEERR, "The value passed to exponentialCurveToValueAtTime must be positive.") MSG_DEF(MSG_INVALID_AUDIOPARAM_EXPONENTIAL_CONSTANT_ERROR, 0, JSEXN_RANGEERR, "The exponential constant passed to setTargetAtTime must be positive.") +MSG_DEF(MSG_VALUE_OUT_OF_RANGE, 1, JSEXN_RANGEERR, "The value for the {0} is outside the valid range.") diff --git a/dom/media/webaudio/AudioBufferSourceNode.cpp b/dom/media/webaudio/AudioBufferSourceNode.cpp index 614bfe98fccb..67046dfe3422 100644 --- a/dom/media/webaudio/AudioBufferSourceNode.cpp +++ b/dom/media/webaudio/AudioBufferSourceNode.cpp @@ -699,9 +699,16 @@ void AudioBufferSourceNode::Start(double aWhen, double aOffset, const Optional& aDuration, ErrorResult& aRv) { - if (!WebAudioUtils::IsTimeValid(aWhen) || aOffset < 0 || - (aDuration.WasPassed() && !WebAudioUtils::IsTimeValid(aDuration.Value()))) { - aRv.Throw(NS_ERROR_RANGE_ERR); + if (!WebAudioUtils::IsTimeValid(aWhen)) { + aRv.ThrowRangeError(NS_LITERAL_STRING("start time")); + return; + } + if (aOffset < 0) { + aRv.ThrowRangeError(NS_LITERAL_STRING("offset")); + return; + } + if (aDuration.WasPassed() && !WebAudioUtils::IsTimeValid(aDuration.Value())) { + aRv.ThrowRangeError(NS_LITERAL_STRING("duration")); return; } @@ -802,7 +809,7 @@ void AudioBufferSourceNode::Stop(double aWhen, ErrorResult& aRv) { if (!WebAudioUtils::IsTimeValid(aWhen)) { - aRv.Throw(NS_ERROR_RANGE_ERR); + aRv.ThrowRangeError(NS_LITERAL_STRING("stop time")); return; } diff --git a/dom/media/webaudio/ConstantSourceNode.cpp b/dom/media/webaudio/ConstantSourceNode.cpp index 35272b19324d..0814fcb41e18 100644 --- a/dom/media/webaudio/ConstantSourceNode.cpp +++ b/dom/media/webaudio/ConstantSourceNode.cpp @@ -228,7 +228,7 @@ void ConstantSourceNode::Start(double aWhen, ErrorResult& aRv) { if (!WebAudioUtils::IsTimeValid(aWhen)) { - aRv.Throw(NS_ERROR_RANGE_ERR); + aRv.ThrowRangeError(NS_LITERAL_STRING("start time")); return; } @@ -252,7 +252,7 @@ void ConstantSourceNode::Stop(double aWhen, ErrorResult& aRv) { if (!WebAudioUtils::IsTimeValid(aWhen)) { - aRv.Throw(NS_ERROR_RANGE_ERR); + aRv.ThrowRangeError(NS_LITERAL_STRING("stop time")); return; } From f39692c1fe4c6186ff222ccddec5c0d75fd662e2 Mon Sep 17 00:00:00 2001 From: "Abdoulaye O. Ly" Date: Tue, 4 Sep 2018 14:36:05 +0000 Subject: [PATCH 18/61] Bug 1470555 - Implement ability to send a selection of tabs. r=flod,jaws Differential Revision: https://phabricator.services.mozilla.com/D3126 --HG-- extra : moz-landing-system : lando --- browser/base/content/browser-context.inc | 2 +- browser/base/content/browser-pageActions.js | 17 +++++-- browser/base/content/browser-sync.js | 46 +++++++++++++++---- browser/base/content/browser.xul | 9 ++-- .../locales/en-US/chrome/browser/browser.dtd | 3 -- .../en-US/chrome/browser/browser.properties | 13 ++++++ 6 files changed, 68 insertions(+), 22 deletions(-) diff --git a/browser/base/content/browser-context.inc b/browser/base/content/browser-context.inc index b5df23b0ee28..99133e49f64c 100644 --- a/browser/base/content/browser-context.inc +++ b/browser/base/content/browser-context.inc @@ -267,7 +267,7 @@ accesskey="&sendPageToDevice.accesskey;" hidden="true"> + onpopupshowing="(() => { gSync.populateSendTabToDevicesMenu(event.target, gBrowser.selectedTab); })()"/> { + gSync.populateSendTabToDevicesMenu(bodyNode, gBrowser.selectedTab, (clientId, name, clientType, lastModified) => { if (!name) { return document.createXULElement("toolbarseparator"); } diff --git a/browser/base/content/browser-sync.js b/browser/base/content/browser-sync.js index d8c92c36487b..60ac6fab2ee9 100644 --- a/browser/base/content/browser-sync.js +++ b/browser/base/content/browser-sync.js @@ -361,7 +361,7 @@ var gSync = { } }, - populateSendTabToDevicesMenu(devicesPopup, url, title, createDeviceNodeFn) { + populateSendTabToDevicesMenu(devicesPopup, aTab, createDeviceNodeFn) { if (!createDeviceNodeFn) { createDeviceNodeFn = (clientId, name, clientType, lastModified) => { let eltName = name ? "menuitem" : "menuseparator"; @@ -386,7 +386,7 @@ var gSync = { const state = UIState.get(); if (state.status == UIState.STATUS_SIGNED_IN && this.remoteClients.length > 0) { - this._appendSendTabDeviceList(fragment, createDeviceNodeFn, url, title); + this._appendSendTabDeviceList(fragment, createDeviceNodeFn, aTab); } else if (state.status == UIState.STATUS_SIGNED_IN) { this._appendSendTabSingleDevice(fragment, createDeviceNodeFn); } else if (state.status == UIState.STATUS_NOT_VERIFIED || @@ -402,14 +402,27 @@ var gSync = { // TODO: once our transition from the old-send tab world is complete, // this list should be built using the FxA device list instead of the client // collection. - _appendSendTabDeviceList(fragment, createDeviceNodeFn, url, title) { + _appendSendTabDeviceList(fragment, createDeviceNodeFn, tab) { + let tabsToSend = tab.multiselected ? gBrowser.selectedTabs : [tab]; + + function getTabUrl(t) { + return t.linkedBrowser.currentURI.spec; + } + function getTabTitle(t) { + return t.linkedBrowser.contentTitle; + } + const onSendAllCommand = (event) => { - this.sendTabToDevice(url, this.remoteClients, title); + for (let t of tabsToSend) { + this.sendTabToDevice(getTabUrl(t), this.remoteClients, getTabTitle(t)); + } }; const onTargetDeviceCommand = (event) => { const clientId = event.target.getAttribute("clientId"); const client = this.remoteClients.find(c => c.id == clientId); - this.sendTabToDevice(url, [client], title); + for (let t of tabsToSend) { + this.sendTabToDevice(getTabUrl(t), [client], getTabTitle(t)); + } }; function addTargetDevice(clientId, name, clientType, lastModified) { @@ -516,14 +529,31 @@ var gSync = { // "Send Tab to Device" menu item updateTabContextMenu(aPopupMenu, aTargetTab) { + // We may get here before initialisation. This situation + // can lead to a empty label for 'Send To Device' Menu. + this.init(); + if (!this.SYNC_ENABLED) { // These items are hidden in onSyncDisabled(). No need to do anything. return; } - const enabled = !this.syncConfiguredAndLoading && - this.isSendableURI(aTargetTab.linkedBrowser.currentURI.spec); + let hasASendableURI = false; + for (let tab of aTargetTab.multiselected ? gBrowser.selectedTabs : [aTargetTab]) { + if (this.isSendableURI(tab.linkedBrowser.currentURI.spec)) { + hasASendableURI = true; + break; + } + } + const enabled = !this.syncConfiguredAndLoading && hasASendableURI; - document.getElementById("context_sendTabToDevice").disabled = !enabled; + let sendTabsToDevice = document.getElementById("context_sendTabToDevice"); + sendTabsToDevice.disabled = !enabled; + + let tabCount = aTargetTab.multiselected ? gBrowser.multiSelectedTabsCount : 1; + sendTabsToDevice.label = PluralForm.get(tabCount, + gNavigatorBundle.getString("sendTabsToDevice.label")) + .replace("#1", tabCount.toLocaleString()); + sendTabsToDevice.accessKey = gNavigatorBundle.getString("sendTabsToDevice.accesskey"); }, // "Send Page to Device" and "Send Link to Device" menu items diff --git a/browser/base/content/browser.xul b/browser/base/content/browser.xul index 7201f03355c2..b0981cd3a4c8 100644 --- a/browser/base/content/browser.xul +++ b/browser/base/content/browser.xul @@ -142,11 +142,10 @@ xmlns="http://www.w3.org/1999/xhtml" tbattr="tabbrowser-multiple" oncommand="gBrowser.replaceTabsWithWindow(TabContextMenu.contextTab);"/> - + + onpopupshowing="gSync.populateSendTabToDevicesMenu(event.target, TabContextMenu.contextTab);"/> diff --git a/browser/locales/en-US/chrome/browser/browser.dtd b/browser/locales/en-US/chrome/browser/browser.dtd index e581373a159a..ab5be96a261c 100644 --- a/browser/locales/en-US/chrome/browser/browser.dtd +++ b/browser/locales/en-US/chrome/browser/browser.dtd @@ -61,8 +61,6 @@ can reach it easily. --> - - @@ -1088,7 +1086,6 @@ you can use these alternative items. Otherwise, their values should be empty. - - diff --git a/browser/locales/en-US/chrome/browser/browser.properties b/browser/locales/en-US/chrome/browser/browser.properties index 72b1e13875ea..0207ca1582fb 100644 --- a/browser/locales/en-US/chrome/browser/browser.properties +++ b/browser/locales/en-US/chrome/browser/browser.properties @@ -905,6 +905,19 @@ unmuteSelectedTabs.accesskey = b playTabs.label = Play Tabs playTabs.accesskey = y +# LOCALIZATION NOTE (sendTabsToDevice.label): +# Semi-colon list of plural forms. +# See: https://developer.mozilla.org/en/docs/Localization_and_Plurals +# #1 is the number of tabs sent to the device. +sendTabsToDevice.label = Send Tab to Device;Send #1 Tabs to Device +sendTabsToDevice.accesskey = n + +# LOCALIZATION NOTE (pageAction.sendTabsToDevice.label): +# Semi-colon list of plural forms. +# See: https://developer.mozilla.org/en/docs/Localization_and_Plurals +# #1 is the number of tabs sent to the device. +pageAction.sendTabsToDevice.label = Send Tab to Device;Send #1 Tabs to Device + # LOCALIZATION NOTE (certErrorDetails*.label): These are text strings that # appear in the about:certerror page, so that the user can copy and send them to # the server administrators for troubleshooting. From 818df08a5ba50c4df5da2f5dfc335ac61ebc466e Mon Sep 17 00:00:00 2001 From: Henri Sivonen Date: Tue, 4 Sep 2018 14:48:39 +0000 Subject: [PATCH 19/61] Bug 1487050 - Remove CountCharInReadable() as dead code. r=froydnj MozReview-Commit-ID: DpRxyOgO85X Differential Revision: https://phabricator.services.mozilla.com/D4941 --HG-- extra : moz-landing-system : lando --- xpcom/string/nsReadableUtils.cpp | 38 -------------------------------- xpcom/string/nsReadableUtils.h | 8 ------- 2 files changed, 46 deletions(-) diff --git a/xpcom/string/nsReadableUtils.cpp b/xpcom/string/nsReadableUtils.cpp index ae9f19bdedaa..fe0d7b2cfa72 100644 --- a/xpcom/string/nsReadableUtils.cpp +++ b/xpcom/string/nsReadableUtils.cpp @@ -459,44 +459,6 @@ FindCharInReadable(char aChar, nsACString::const_iterator& aSearchStart, return false; } -uint32_t -CountCharInReadable(const nsAString& aStr, char16_t aChar) -{ - uint32_t count = 0; - nsAString::const_iterator begin, end; - - aStr.BeginReading(begin); - aStr.EndReading(end); - - while (begin != end) { - if (*begin == aChar) { - ++count; - } - ++begin; - } - - return count; -} - -uint32_t -CountCharInReadable(const nsACString& aStr, char aChar) -{ - uint32_t count = 0; - nsACString::const_iterator begin, end; - - aStr.BeginReading(begin); - aStr.EndReading(end); - - while (begin != end) { - if (*begin == aChar) { - ++count; - } - ++begin; - } - - return count; -} - bool StringBeginsWith(const nsAString& aSource, const nsAString& aSubstring) { diff --git a/xpcom/string/nsReadableUtils.h b/xpcom/string/nsReadableUtils.h index 0523f2fcbbbf..d4eed2fe7d44 100644 --- a/xpcom/string/nsReadableUtils.h +++ b/xpcom/string/nsReadableUtils.h @@ -782,14 +782,6 @@ bool FindCharInReadable(char16_t aChar, nsAString::const_iterator& aSearchStart, bool FindCharInReadable(char aChar, nsACString::const_iterator& aSearchStart, const nsACString::const_iterator& aSearchEnd); -/** -* Finds the number of occurences of |aChar| in the string |aStr| -*/ -uint32_t CountCharInReadable(const nsAString& aStr, - char16_t aChar); -uint32_t CountCharInReadable(const nsACString& aStr, - char aChar); - bool StringBeginsWith(const nsAString& aSource, const nsAString& aSubstring); bool StringBeginsWith(const nsAString& aSource, const nsAString& aSubstring, const nsStringComparator& aComparator); From 493804981075f515957bb9c15ba549dec14415ee Mon Sep 17 00:00:00 2001 From: Miko Mynttinen Date: Tue, 4 Sep 2018 14:53:18 +0000 Subject: [PATCH 20/61] Bug 1413546 - Fix e10s logic in nsLayoutUtils::AreRetainedDisplayListsEnabled() and set layout.display-list.retain.chrome to true r=mattwoodrow Differential Revision: https://phabricator.services.mozilla.com/D2953 --HG-- extra : moz-landing-system : lando --- layout/base/nsLayoutUtils.cpp | 7 ++++++- modules/libpref/init/all.js | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index a97c113f86b9..87e9c46e712a 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -469,9 +469,14 @@ nsLayoutUtils::AreRetainedDisplayListsEnabled() { if (XRE_IsContentProcess()) { return gfxPrefs::LayoutRetainDisplayList(); - } else { + } + + if (XRE_IsE10sParentProcess()) { return gfxPrefs::LayoutRetainDisplayListChrome(); } + + // Retained display lists require e10s. + return false; } bool diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 71419bacb826..761c2edc22ba 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -3115,10 +3115,10 @@ pref("layout.display-list.dump-parent", false); // Toggle retaining display lists between paints #if !defined(ANDROID) pref("layout.display-list.retain", true); +pref("layout.display-list.retain.chrome", true); #else pref("layout.display-list.retain", false); #endif -pref("layout.display-list.retain.chrome", false); // Set the maximum amount of modified frames allowed before doing a full // display list rebuild. From 58aaba43c4b25917be8cfc3d26acd28385248af0 Mon Sep 17 00:00:00 2001 From: "Francesco Lodolo (:flod)" Date: Tue, 4 Sep 2018 14:54:02 +0000 Subject: [PATCH 21/61] Bug 1488398 - Fix a few nits in policies descriptions, add localization comments r=Felipe,Pike Differential Revision: https://phabricator.services.mozilla.com/D4937 --HG-- extra : moz-landing-system : lando --- .../enterprisepolicies/content/aboutPolicies.js | 9 ++++++++- .../browser/policies/policies-descriptions.ftl | 14 +++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/browser/components/enterprisepolicies/content/aboutPolicies.js b/browser/components/enterprisepolicies/content/aboutPolicies.js index d6dbd8cd32c3..826699e8aea1 100644 --- a/browser/components/enterprisepolicies/content/aboutPolicies.js +++ b/browser/components/enterprisepolicies/content/aboutPolicies.js @@ -229,6 +229,12 @@ function generateDocumentation() { let new_cont = document.getElementById("documentationContent"); new_cont.setAttribute("id", "documentationContent"); + // map specific policies to a different string ID, to allow updates to + // existing descriptions + let string_mapping = { + "DisableSetDesktopBackground": "DisableSetAsDesktopBackground", + }; + for (let policyName in schema.properties) { let main_tbody = document.createElement("tbody"); main_tbody.classList.add("collapsible"); @@ -244,7 +250,8 @@ function generateDocumentation() { row.appendChild(col(policyName)); } let descriptionColumn = col(""); - descriptionColumn.setAttribute("data-l10n-id", `policy-${policyName}`); + let stringID = string_mapping[policyName] || policyName; + descriptionColumn.setAttribute("data-l10n-id", `policy-${stringID}`); row.appendChild(descriptionColumn); main_tbody.appendChild(row); let sec_tbody = document.createElement("tbody"); diff --git a/browser/locales/en-US/browser/policies/policies-descriptions.ftl b/browser/locales/en-US/browser/policies/policies-descriptions.ftl index e21d33652bf4..813240677264 100644 --- a/browser/locales/en-US/browser/policies/policies-descriptions.ftl +++ b/browser/locales/en-US/browser/policies/policies-descriptions.ftl @@ -60,26 +60,32 @@ policy-DisableSafeMode = Disable the feature to restart in Safe Mode. Note: the policy-DisableSecurityBypass = Prevent the user from bypassing certain security warnings. -policy-DisableSetDesktopBackground = Disable the menu command Set Image as Desktop Background. +policy-DisableSetAsDesktopBackground = Disable the menu command Set as Desktop Background for images. policy-DisableSystemAddonUpdate = Prevent the browser from installing and updating system add-ons. policy-DisableTelemetry = Turn off Telemetry. -policy-DisplayBookmarksToolbar = Display the Bookmark Toolbar by default. +policy-DisplayBookmarksToolbar = Display the Bookmarks Toolbar by default. policy-DisplayMenuBar = Display the Menu Bar by default. policy-DontCheckDefaultBrowser = Disable check for default browser on startup. +# “lock” means that the user won’t be able to change this setting policy-EnableTrackingProtection = Enable or disable Content Blocking and optionally lock it. +# A “locked” extension can’t be disabled or removed by the user. This policy +# takes 3 keys (“Install”, ”Uninstall”, ”Locked”), you can either keep them in +# English or translate them as verbs. See also: +# https://github.com/mozilla/policy-templates/blob/master/README.md#extensions-machine-only policy-Extensions = Install, uninstall or lock extensions. The Install option takes URLs or paths as parameters. The Uninstall and Locked options take extension IDs. policy-FlashPlugin = Allow or deny usage of the Flash plugin. policy-HardwareAcceleration = If false, turn off hardware acceleration. +# “lock” means that the user won’t be able to change this setting policy-Homepage = Set and optionally lock the homepage. policy-InstallAddonsPermission = Allow certain websites to install add-ons. @@ -90,7 +96,7 @@ policy-OfferToSaveLogins = Enforce the setting to allow { -brand-short-name } to policy-OverrideFirstRunPage = Override the first run page. Set this policy to blank if you want to disable the first run page. -policy-OverridePostUpdatePage = Override the post-update "What’s New" page. Set this policy to blank if you want to disable the post-update page. +policy-OverridePostUpdatePage = Override the post-update “What’s New” page. Set this policy to blank if you want to disable the post-update page. policy-Permissions = Configure permissions for camera, microphone, location and notifications. @@ -104,4 +110,6 @@ policy-SearchBar = Set the default location of the search bar. The user is still policy-SearchEngines = Configure search engine settings. This policy is only available on the Extended Support Release (ESR) version. +# “format” refers to the format used for the value of this policy. See also: +# https://github.com/mozilla/policy-templates/blob/master/README.md#websitefilter-machine-only policy-WebsiteFilter = Block websites from being visited. See documentation for more details on the format. From 3213f7d4b14ab38d15c800463575d8bbc58e91f3 Mon Sep 17 00:00:00 2001 From: Ted Mielczarek Date: Tue, 4 Sep 2018 06:17:17 +0000 Subject: [PATCH 22/61] bug 1476604 - update the version of sccache in CI to fix an issue with clang-cl. r=glandium Differential Revision: https://phabricator.services.mozilla.com/D4431 --HG-- extra : moz-landing-system : lando --- taskcluster/ci/toolchain/linux.yml | 1 + taskcluster/scripts/misc/build-sccache.sh | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/taskcluster/ci/toolchain/linux.yml b/taskcluster/ci/toolchain/linux.yml index b70bbda6a6fa..d837e555fa47 100755 --- a/taskcluster/ci/toolchain/linux.yml +++ b/taskcluster/ci/toolchain/linux.yml @@ -574,6 +574,7 @@ linux64-sccache: toolchain-artifact: public/build/sccache2.tar.xz toolchains: - linux64-rust-1.28 + - linux64-binutils linux64-cbindgen: description: "cbindgen toolchain build" diff --git a/taskcluster/scripts/misc/build-sccache.sh b/taskcluster/scripts/misc/build-sccache.sh index dfb72ec6ca15..7a97471338fb 100755 --- a/taskcluster/scripts/misc/build-sccache.sh +++ b/taskcluster/scripts/misc/build-sccache.sh @@ -1,8 +1,8 @@ #!/bin/bash set -x -e -v -# 0.2.7 + --coverage suppport -SCCACHE_REVISION=1ab9a33e8d328941acc23c74c949b765f975f309 +# 0.2.7 + a number of changes +SCCACHE_REVISION=476d807a0b3c1c31314ea165feea83521d87a17f # This script is for building sccache @@ -11,6 +11,7 @@ Linux) WORKSPACE=$HOME/workspace UPLOAD_DIR=$HOME/artifacts COMPRESS_EXT=xz + PATH="$WORKSPACE/build/src/binutils/bin:$PATH" ;; MINGW*) WORKSPACE=$PWD From 46971a64924526c2a67fc77e3f6762433705fe7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Tue, 4 Sep 2018 15:17:04 +0000 Subject: [PATCH 23/61] Bug 1488403 - Make sticky legend reftest not depend on groove border antialising. r=nical This reftest fails with my changes from https://github.com/servo/webrender/pull/3010. I tried to debug locally but it passes here. The reason it fails is because WebRender does distance AA between the segments of a ridge / groove border, and there's a subpixel difference so we get the AA slightly different in the test. Gecko on the other hand represents these borders as different composed solid segments, so it can't have this problem, since it doesn't do AA across the segments. We may want to change that, but it's not clear to me it's wanted, since rounded corners for these look much better on WR, for example. Rather than fuzzing the test or something like that, make the test not rely on that, given it's testing the position of the legend. Differential Revision: https://phabricator.services.mozilla.com/D4934 --HG-- extra : moz-landing-system : lando --- layout/reftests/forms/fieldset/reftest.list | 2 +- layout/reftests/forms/fieldset/sticky-legend-1-ref.html | 2 +- layout/reftests/forms/fieldset/sticky-legend-1.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/layout/reftests/forms/fieldset/reftest.list b/layout/reftests/forms/fieldset/reftest.list index 9399c5c054a9..65b64e6bc8b1 100644 --- a/layout/reftests/forms/fieldset/reftest.list +++ b/layout/reftests/forms/fieldset/reftest.list @@ -10,7 +10,7 @@ fuzzy-if(winWidget&&!layersGPUAccelerated,0-142,0-276) == positioned-container-1 == relpos-legend-2.html relpos-legend-2-ref.html == relpos-legend-3.html relpos-legend-3-ref.html == relpos-legend-4.html relpos-legend-4-ref.html -fuzzy-if(webrender,17-19,1217-2452) == sticky-legend-1.html sticky-legend-1-ref.html +== sticky-legend-1.html sticky-legend-1-ref.html fuzzy-if(skiaContent,0-1,0-40768) == abs-pos-child-sizing.html abs-pos-child-sizing-ref.html == overflow-hidden.html overflow-hidden-ref.html == legend-rtl.html legend-rtl-ref.html diff --git a/layout/reftests/forms/fieldset/sticky-legend-1-ref.html b/layout/reftests/forms/fieldset/sticky-legend-1-ref.html index 892fa4c29f14..6557d8125802 100644 --- a/layout/reftests/forms/fieldset/sticky-legend-1-ref.html +++ b/layout/reftests/forms/fieldset/sticky-legend-1-ref.html @@ -1,7 +1,7 @@ -
+
diff --git a/layout/reftests/forms/fieldset/sticky-legend-1.html b/layout/reftests/forms/fieldset/sticky-legend-1.html index 588ea521ff68..719c18eb8b78 100644 --- a/layout/reftests/forms/fieldset/sticky-legend-1.html +++ b/layout/reftests/forms/fieldset/sticky-legend-1.html @@ -1,7 +1,7 @@ -
+
From 4de49466e8d67da46370742d61556830d174c198 Mon Sep 17 00:00:00 2001 From: Raphael Pierzina Date: Tue, 4 Sep 2018 15:01:55 +0000 Subject: [PATCH 24/61] Update treeherder symbol for telemetry-tests-client suite (Bug 1487800) r=Dexter,whimboo Update treeherder symbol for telemetry-tests-client suite. Differential Revision: https://phabricator.services.mozilla.com/D4918 --HG-- extra : moz-landing-system : lando --- taskcluster/ci/config.yml | 4 ++-- taskcluster/ci/test/misc.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/taskcluster/ci/config.yml b/taskcluster/ci/config.yml index 200b9dca9531..a7eec9569f32 100755 --- a/taskcluster/ci/config.yml +++ b/taskcluster/ci/config.yml @@ -30,8 +30,8 @@ treeherder: 'Tsd-e10s': 'Talos performance tests with e10s, Stylo disabled' 'Tss-e10s': 'Talos performance tests with e10s, Stylo sequential' 'T-P-e10s': 'Talos performance tests with e10s and gecko profiling' - 'tt-c': 'Telemetry client marionette tests' - 'tt-c-e10s': 'Telemetry client marionette tests with e10s' + 'tt': 'Telemetry tests' + 'tt-e10s': 'Telemetry tests with e10s' 'SY-e10s': 'Are we slim yet tests by TaskCluster with e10s' 'SYsd-e10s': 'Are we slim yet tests by TaskCluster with e10s, Stylo disabled' 'SYss-e10s': 'Are we slim yet tests by TaskCluster with e10s, Stylo sequential' diff --git a/taskcluster/ci/test/misc.yml b/taskcluster/ci/test/misc.yml index b1961e9c7699..7f9968ca7c36 100644 --- a/taskcluster/ci/test/misc.yml +++ b/taskcluster/ci/test/misc.yml @@ -83,7 +83,7 @@ robocop: telemetry-tests-client: description: "Telemetry tests client run" suite: telemetry-tests-client - treeherder-symbol: tt-c() + treeherder-symbol: tt(c) max-run-time: 5400 checkout: true tier: 3 From b356998aeba95d97ae511c09b9f8e1cf415dbeb8 Mon Sep 17 00:00:00 2001 From: Gabriele Svelto Date: Tue, 4 Sep 2018 15:04:35 +0000 Subject: [PATCH 25/61] Bug 1463048 - Invoke the minidump generation callback asynchronsouly r=ted Differential Revision: https://phabricator.services.mozilla.com/D3837 --HG-- extra : moz-landing-system : lando --- toolkit/crashreporter/nsExceptionHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolkit/crashreporter/nsExceptionHandler.cpp b/toolkit/crashreporter/nsExceptionHandler.cpp index 6f924a7917cf..dbeecefcf7b0 100644 --- a/toolkit/crashreporter/nsExceptionHandler.cpp +++ b/toolkit/crashreporter/nsExceptionHandler.cpp @@ -3873,7 +3873,7 @@ NotifyDumpResult(bool aResult, MOZ_ASSERT(!!aCallbackThread); Unused << aCallbackThread->Dispatch(NS_NewRunnableFunction("CrashReporter::InvokeCallback", std::move(runnable)), - NS_DISPATCH_SYNC); + NS_DISPATCH_NORMAL); } else { runnable(); } From 80313e0e6af7c188b02ce58470ae18b139b20df6 Mon Sep 17 00:00:00 2001 From: Razvan Caliman Date: Tue, 4 Sep 2018 16:21:20 +0000 Subject: [PATCH 26/61] Bug 1488419 - Re-attach listener for Rule view change after writing new value. r=gl Differential Revision: https://phabricator.services.mozilla.com/D4931 --HG-- extra : moz-landing-system : lando --- devtools/client/inspector/fonts/fonts.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/devtools/client/inspector/fonts/fonts.js b/devtools/client/inspector/fonts/fonts.js index 73fbaa966183..e1df23d0b07c 100644 --- a/devtools/client/inspector/fonts/fonts.js +++ b/devtools/client/inspector/fonts/fonts.js @@ -85,7 +85,7 @@ class FontInspector { this.onNewNode = this.onNewNode.bind(this); this.onPreviewTextChange = debounce(this.onPreviewTextChange, 100, this); this.onPropertyChange = this.onPropertyChange.bind(this); - this.onRulePropertyUpdated = debounce(this.onRulePropertyUpdated, 100, this); + this.onRulePropertyUpdated = debounce(this.onRulePropertyUpdated, 300, this); this.onToggleFontHighlight = this.onToggleFontHighlight.bind(this); this.onThemeChanged = this.onThemeChanged.bind(this); this.update = this.update.bind(this); @@ -598,22 +598,23 @@ class FontInspector { * @param {String} value * CSS property value */ - syncChanges(name, value) { + async syncChanges(name, value) { const textProperty = this.getTextProperty(name, value); if (textProperty) { - // This method may be called after the connection to the page style actor is closed. - // For example, during teardown of automated tests. Here, we catch any failure that - // may occur because of that. We're not interested in handling the error. - textProperty.setValue(value).catch(error => { + try { + await textProperty.setValue(value, "", true); + this.ruleView.on("property-value-updated", this.onRulePropertyUpdated); + } catch (error) { + // Because setValue() does an asynchronous call to the server, there is a chance + // the font editor was destroyed while we were waiting. If that happened, just + // bail out silently. if (!this.document) { return; } throw error; - }); + } } - - this.ruleView.on("property-value-updated", this.onRulePropertyUpdated); } /** From d5b262e43dad283052ab725d3f7aaf165c426cf8 Mon Sep 17 00:00:00 2001 From: Zibi Braniecki Date: Thu, 30 Aug 2018 18:00:35 +0000 Subject: [PATCH 27/61] Bug 1483038 - Optimize L10nRegistry generator to early exit on missing resources. r=mossop Optimize L10nRegistry generator to early exit on missing resources. Differential Revision: https://phabricator.services.mozilla.com/D3394 --HG-- extra : moz-landing-system : lando --- intl/l10n/L10nRegistry.jsm | 78 +++++++++++++++++++++----------------- intl/l10n/Localization.jsm | 7 ++-- intl/l10n/l10n.js | 6 ++- 3 files changed, 51 insertions(+), 40 deletions(-) diff --git a/intl/l10n/L10nRegistry.jsm b/intl/l10n/L10nRegistry.jsm index a3292a72f4fe..432a3e0fec8d 100644 --- a/intl/l10n/L10nRegistry.jsm +++ b/intl/l10n/L10nRegistry.jsm @@ -95,26 +95,18 @@ const L10nRegistry = { const sourcesOrder = Array.from(this.sources.keys()).reverse(); const pseudoNameFromPref = Services.prefs.getStringPref("intl.l10n.pseudo", ""); for (const locale of requestedLangs) { - for (const fetchPromises of generateResourceSetsForLocale(locale, sourcesOrder, resourceIds)) { - const ctx = await Promise.all(fetchPromises).then( - dataSets => { - const ctx = new MessageContext(locale, { - ...MSG_CONTEXT_OPTIONS, - transform: PSEUDO_STRATEGIES[pseudoNameFromPref], - }); - for (const data of dataSets) { - if (data === null) { - return null; - } - ctx.addResource(data); - } - return ctx; - }, - () => null - ); - if (ctx !== null) { - yield ctx; + for await (const dataSets of generateResourceSetsForLocale(locale, sourcesOrder, resourceIds)) { + const ctx = new MessageContext(locale, { + ...MSG_CONTEXT_OPTIONS, + transform: PSEUDO_STRATEGIES[pseudoNameFromPref], + }); + for (const data of dataSets) { + if (data === null) { + return null; + } + ctx.addResource(data); } + yield ctx; } } }, @@ -190,7 +182,7 @@ const L10nRegistry = { * @param {Array} [resolvedOrder] * @returns {AsyncIterator} */ -function* generateResourceSetsForLocale(locale, sourcesOrder, resourceIds, resolvedOrder = []) { +async function* generateResourceSetsForLocale(locale, sourcesOrder, resourceIds, resolvedOrder = []) { const resolvedLength = resolvedOrder.length; const resourcesLength = resourceIds.length; @@ -200,18 +192,36 @@ function* generateResourceSetsForLocale(locale, sourcesOrder, resourceIds, resol for (const sourceName of sourcesOrder) { const order = resolvedOrder.concat(sourceName); - // We bail only if the hasFile returns a strict false here, - // because for FileSource it may also return undefined, which means - // that we simply don't know if the source contains the file and we'll - // have to perform the I/O to learn. - if (L10nRegistry.sources.get(sourceName).hasFile(locale, resourceIds[resolvedOrder.length]) === false) { - continue; + // We want to bail out early if we know that any of + // the (res)x(source) combinations in the permutation + // are unavailable. + // The combination may have been `undefined` when we + // stepped into this branch, and now is resolved to + // `false`. + // + // If the combination resolved to `false` is the last + // in the resolvedOrder, we want to continue in this + // loop, but if it's somewhere in the middle, we can + // safely bail from the whole branch. + for (let [idx, sourceName] of order.entries()) { + if (L10nRegistry.sources.get(sourceName).hasFile(locale, resourceIds[idx]) === false) { + if (idx === order.length - 1) { + continue; + } else { + return; + } + } } // If the number of resolved sources equals the number of resources, // create the right context and return it if it loads. if (resolvedLength + 1 === resourcesLength) { - yield generateResourceSet(locale, order, resourceIds); + let dataSet = await generateResourceSet(locale, order, resourceIds); + // Here we check again to see if the newly resolved + // resources returned `false` on any position. + if (!dataSet.includes(false)) { + yield dataSet; + } } else if (resolvedLength < resourcesLength) { // otherwise recursively load another generator that walks over the // partially resolved list of sources. @@ -346,10 +356,10 @@ const PSEUDO_STRATEGIES = { * @param {Array} resourceIds * @returns {Promise} */ -function generateResourceSet(locale, sourcesOrder, resourceIds) { - return resourceIds.map((resourceId, i) => { +async function generateResourceSet(locale, sourcesOrder, resourceIds) { + return Promise.all(resourceIds.map((resourceId, i) => { return L10nRegistry.sources.get(sourcesOrder[i]).fetchFile(locale, resourceId); - }); + })); } /** @@ -420,14 +430,14 @@ class FileSource { fetchFile(locale, path) { if (!this.locales.includes(locale)) { - return Promise.reject(`The source has no resources for locale "${locale}"`); + return false; } const fullPath = this.getPath(locale, path); if (this.cache.hasOwnProperty(fullPath)) { if (this.cache[fullPath] === false) { - return Promise.reject(`The source has no resources for path "${fullPath}"`); + return false; } // `true` means that the file is indexed, but hasn't // been fetched yet. @@ -435,7 +445,7 @@ class FileSource { return this.cache[fullPath]; } } else if (this.indexed) { - return Promise.reject(`The source has no resources for path "${fullPath}"`); + return false; } return this.cache[fullPath] = L10nRegistry.load(fullPath).then( data => { @@ -443,7 +453,7 @@ class FileSource { }, err => { this.cache[fullPath] = false; - return Promise.reject(err); + return false; } ); } diff --git a/intl/l10n/Localization.jsm b/intl/l10n/Localization.jsm index 8aa0722f20d8..1d453578134a 100644 --- a/intl/l10n/Localization.jsm +++ b/intl/l10n/Localization.jsm @@ -97,7 +97,7 @@ class CachedAsyncIterable extends CachedIterable { return { async next() { if (cached.length <= cur) { - cached.push(await cached.iterator.next()); + cached.push(cached.iterator.next()); } return cached[cur++]; } @@ -114,10 +114,10 @@ class CachedAsyncIterable extends CachedIterable { let idx = 0; while (idx++ < count) { const last = this[this.length - 1]; - if (last && last.done) { + if (last && await (last).done) { break; } - this.push(await this.iterator.next()); + this.push(this.iterator.next()); } // Return the last cached {value, done} object to allow the calling // code to decide if it needs to call touchNext again. @@ -322,7 +322,6 @@ class Localization { onChange() { this.ctxs = CachedAsyncIterable.from( this.generateMessages(this.resourceIds)); - this.ctxs.touchNext(2); } } diff --git a/intl/l10n/l10n.js b/intl/l10n/l10n.js index ad6c914b3219..1afb8f7ee00d 100644 --- a/intl/l10n/l10n.js +++ b/intl/l10n/l10n.js @@ -1,6 +1,7 @@ { const { DOMLocalization } = ChromeUtils.import("resource://gre/modules/DOMLocalization.jsm", {}); + const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm", {}); /** * Polyfill for document.ready polyfill. @@ -46,8 +47,9 @@ document.l10n = new DOMLocalization(resourceIds); - // Trigger the first two contexts to be loaded eagerly. - document.l10n.ctxs.touchNext(2); + const appLocales = Services.locale.getAppLocalesAsBCP47(); + const prefetchCount = appLocales.length > 1 ? 2 : 1; + document.l10n.ctxs.touchNext(prefetchCount); document.l10n.ready = documentReady().then(() => { document.l10n.registerObservers(); From 561c1777fb6f6388eda914a244f8dc4b39adff65 Mon Sep 17 00:00:00 2001 From: shindli Date: Tue, 4 Sep 2018 19:25:19 +0300 Subject: [PATCH 28/61] Backed out changeset 8d6a57caa626 (bug 1462121) for bc16 failures in browser_ext_getViews.js --- .../components/extensions/ExtensionCommon.jsm | 99 ++++-------- .../test_ext_contentscript_context.js | 143 +----------------- ...est_ext_contentscript_context_isolation.js | 123 --------------- .../test/xpcshell/xpcshell-common.ini | 1 - 4 files changed, 33 insertions(+), 333 deletions(-) delete mode 100644 toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context_isolation.js diff --git a/toolkit/components/extensions/ExtensionCommon.jsm b/toolkit/components/extensions/ExtensionCommon.jsm index 57344c649789..f0a84395b6e3 100644 --- a/toolkit/components/extensions/ExtensionCommon.jsm +++ b/toolkit/components/extensions/ExtensionCommon.jsm @@ -353,55 +353,6 @@ class ExtensionAPI extends EventEmitter { } } -/** - * A wrapper around a window that returns the window iff the inner window - * matches the inner window at the construction of this wrapper. - * - * This wrapper should not be used after the inner window is destroyed. - **/ -class InnerWindowReference { - constructor(contentWindow, innerWindowID) { - this.contentWindow = contentWindow; - this.innerWindowID = innerWindowID; - this.needWindowIDCheck = false; - - contentWindow.addEventListener("pagehide", this, {mozSystemGroup: true}, false); - contentWindow.addEventListener("pageshow", this, {mozSystemGroup: true}, false); - } - - get() { - // If the pagehide event has fired, the inner window ID needs to be checked, - // in case the window ref is dereferenced in a pageshow listener (before our - // pageshow listener was dispatched) or during the unload event. - if (!this.needWindowIDCheck || getInnerWindowID(this.contentWindow) === this.innerWindowID) { - return this.contentWindow; - } - return null; - } - - invalidate() { - // If invalidate() is called while the inner window is in the bfcache, then - // we are unable to remove the event listener, and handleEvent will be - // called once more if the page is revived from the bfcache. - if (this.contentWindow) { - this.contentWindow.removeEventListener("pagehide", this, {mozSystemGroup: true}); - this.contentWindow.removeEventListener("pageshow", this, {mozSystemGroup: true}); - } - this.contentWindow = null; - this.needWindowIDCheck = false; - } - - handleEvent(event) { - if (this.contentWindow) { - this.needWindowIDCheck = event.type === "pagehide"; - } else { - // Remove listener when restoring from the bfcache - see invalidate(). - event.currentTarget.removeEventListener("pagehide", this, {mozSystemGroup: true}); - event.currentTarget.removeEventListener("pageshow", this, {mozSystemGroup: true}); - } - } -} - /** * This class contains the information we have about an individual * extension. It is never instantiated directly, instead subclasses @@ -422,13 +373,16 @@ class BaseContext { this.active = true; this.incognito = null; this.messageManager = null; + this.docShell = null; this.contentWindow = null; this.innerWindowID = 0; } setContentWindow(contentWindow) { + let {document, docShell} = contentWindow; + this.innerWindowID = getInnerWindowID(contentWindow); - this.messageManager = contentWindow.docShell.messageManager; + this.messageManager = docShell.messageManager; if (this.incognito == null) { this.incognito = PrivateBrowsingUtils.isContentWindowPrivate(contentWindow); @@ -436,26 +390,34 @@ class BaseContext { MessageChannel.setupMessageManagers([this.messageManager]); - let windowRef = new InnerWindowReference(contentWindow, this.innerWindowID); - Object.defineProperty(this, "active", { - configurable: true, - enumerable: true, - get: () => windowRef.get() !== null, - }); - Object.defineProperty(this, "contentWindow", { - configurable: true, - enumerable: true, - get: () => windowRef.get(), - }); + let onPageShow = event => { + if (!event || event.target === document) { + this.docShell = docShell; + this.contentWindow = contentWindow; + this.active = true; + } + }; + let onPageHide = event => { + if (!event || event.target === document) { + // Put this off until the next tick. + Promise.resolve().then(() => { + this.docShell = null; + this.contentWindow = null; + this.active = false; + }); + } + }; + + onPageShow(); + contentWindow.addEventListener("pagehide", onPageHide, true); + contentWindow.addEventListener("pageshow", onPageShow, true); this.callOnClose({ close: () => { - // Allow other "close" handlers to use these properties, until the next tick. - Promise.resolve().then(() => { - windowRef.invalidate(); - windowRef = null; - Object.defineProperty(this, "contentWindow", {value: null}); - Object.defineProperty(this, "active", {value: false}); - }); + onPageHide(); + if (this.active) { + contentWindow.removeEventListener("pagehide", onPageHide, true); + contentWindow.removeEventListener("pageshow", onPageShow, true); + } }, }); } @@ -770,7 +732,6 @@ class BaseContext { for (let obj of this.onClose) { obj.close(); } - this.onClose.clear(); } /** diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context.js b/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context.js index d2e81c3d8cd9..d7e161ee4da0 100644 --- a/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context.js +++ b/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context.js @@ -10,7 +10,7 @@ server.registerPathHandler("/dummy", (request, response) => { response.write(""); }); -function loadExtension() { +add_task(async function test_contentscript_context() { function contentScript() { browser.test.sendMessage("content-script-ready"); @@ -22,10 +22,10 @@ function loadExtension() { }); } - return ExtensionTestUtils.loadExtension({ + let extension = ExtensionTestUtils.loadExtension({ manifest: { content_scripts: [{ - "matches": ["http://example.com/dummy*"], + "matches": ["http://example.com/dummy"], "js": ["content_script.js"], "run_at": "document_start", }], @@ -35,10 +35,7 @@ function loadExtension() { "content_script.js": contentScript, }, }); -} -add_task(async function test_contentscript_context() { - let extension = loadExtension(); await extension.startup(); let contentPage = await ExtensionTestUtils.loadContentPage("http://example.com/dummy"); @@ -78,137 +75,3 @@ add_task(async function test_contentscript_context() { await extension.awaitMessage("content-script-hide"); await extension.unload(); }); - -add_task(async function test_contentscript_context_unload_while_in_bfcache() { - let contentPage = await ExtensionTestUtils.loadContentPage("http://example.com/dummy?first"); - let extension = loadExtension(); - await extension.startup(); - await extension.awaitMessage("content-script-ready"); - - // Get the content script context and check that it points to the correct window. - await contentPage.spawn(extension.id, async extensionId => { - let {DocumentManager} = ChromeUtils.import("resource://gre/modules/ExtensionContent.jsm", {}); - // Save context so we can verify that contentWindow is nulled after unload. - this.context = DocumentManager.getContext(extensionId, this.content); - - Assert.equal(this.context.contentWindow, this.content, "Context's contentWindow property is correct"); - - this.contextUnloadedPromise = new Promise(resolve => { - this.context.callOnClose({close: resolve}); - }); - this.pageshownPromise = new Promise(resolve => { - this.content.addEventListener("pageshow", () => { - // Yield to the event loop once more to ensure that all pageshow event - // handlers have been dispatched before fulfilling the promise. - let {setTimeout} = ChromeUtils.import("resource://gre/modules/Timer.jsm", {}); - setTimeout(resolve, 0); - }, {once: true, mozSystemGroup: true}); - }); - - // Navigate so that the content page is hidden in the bfcache. - this.content.location = "http://example.org/dummy?second"; - }); - - await extension.awaitMessage("content-script-hide"); - - await extension.unload(); - await contentPage.spawn(null, async () => { - await this.contextUnloadedPromise; - Assert.equal(this.context.unloaded, true, "Context has been unloaded"); - - // Normally, when a page is not in the bfcache, context.contentWindow is - // not null when the callOnClose handler is invoked (this is checked by the - // previous subtest). - // Now wait a little bit and check again to ensure that the contentWindow - // property is not somehow restored. - await new Promise(resolve => this.content.setTimeout(resolve, 0)); - Assert.equal(this.context.contentWindow, null, "Context's contentWindow property is null"); - - // Navigate back so the content page is resurrected from the bfcache. - this.content.history.back(); - - await this.pageshownPromise; - - Assert.equal(this.context.contentWindow, null, "Context's contentWindow property is null after restore from bfcache"); - }); - - await contentPage.close(); -}); - -add_task(async function test_contentscript_context_valid_during_execution() { - // This test does the following: - // - Load page - // - Load extension; inject content script. - // - Navigate page; pagehide triggered. - // - Navigate back; pageshow triggered. - // - Close page; pagehide, unload triggered. - // At each of these last four events, the validity of the context is checked. - - function contentScript() { - browser.test.sendMessage("content-script-ready"); - window.wrappedJSObject.checkContextIsValid("Context is valid on execution"); - - window.addEventListener("pagehide", () => { - window.wrappedJSObject.checkContextIsValid("Context is valid on pagehide"); - browser.test.sendMessage("content-script-hide"); - }, true); - window.addEventListener("pageshow", () => { - window.wrappedJSObject.checkContextIsValid("Context is valid on pageshow"); - - // This unload listener is registered after pageshow, to ensure that the - // page can be stored in the bfcache at the previous pagehide. - window.addEventListener("unload", () => { - window.wrappedJSObject.checkContextIsValid("Context is valid on unload"); - browser.test.sendMessage("content-script-unload"); - }); - - browser.test.sendMessage("content-script-show"); - }); - } - - let extension = ExtensionTestUtils.loadExtension({ - manifest: { - content_scripts: [{ - "matches": ["http://example.com/dummy*"], - "js": ["content_script.js"], - }], - }, - - files: { - "content_script.js": contentScript, - }, - }); - - let contentPage = await ExtensionTestUtils.loadContentPage("http://example.com/dummy?first"); - await contentPage.spawn(extension.id, async extensionId => { - let context; - let checkContextIsValid = (description) => { - if (!context) { - let {DocumentManager} = ChromeUtils.import("resource://gre/modules/ExtensionContent.jsm", {}); - context = DocumentManager.getContext(extensionId, this.content); - } - Assert.equal(context.contentWindow, this.content, `${description}: contentWindow`); - Assert.equal(context.active, true, `${description}: active`); - }; - Cu.exportFunction(checkContextIsValid, this.content, {defineAs: "checkContextIsValid"}); - }); - await extension.startup(); - await extension.awaitMessage("content-script-ready"); - - await contentPage.spawn(extension.id, async extensionId => { - // Navigate so that the content page is frozen in the bfcache. - this.content.location = "http://example.org/dummy?second"; - }); - - await extension.awaitMessage("content-script-hide"); - await contentPage.spawn(null, async () => { - // Navigate back so the content page is resurrected from the bfcache. - this.content.history.back(); - }); - - await extension.awaitMessage("content-script-show"); - await contentPage.close(); - await extension.awaitMessage("content-script-hide"); - await extension.awaitMessage("content-script-unload"); - await extension.unload(); -}); diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context_isolation.js b/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context_isolation.js deleted file mode 100644 index 6f81730d66a2..000000000000 --- a/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_context_isolation.js +++ /dev/null @@ -1,123 +0,0 @@ -"use strict"; - -/* globals exportFunction */ -/* eslint-disable mozilla/balanced-listeners */ - -const server = createHttpServer({hosts: ["example.com", "example.org"]}); - -server.registerPathHandler("/dummy", (request, response) => { - response.setStatusLine(request.httpVersion, 200, "OK"); - response.setHeader("Content-Type", "text/html", false); - response.write(""); -}); - -server.registerPathHandler("/bfcachetestpage", (request, response) => { - response.setStatusLine(request.httpVersion, 200, "OK"); - response.setHeader("Content-Type", "text/html;charset=utf-8", false); - response.write(` -`); -}); - -add_task(async function test_contentscript_context_isolation() { - function contentScript() { - browser.test.sendMessage("content-script-ready"); - - exportFunction(browser.test.sendMessage, window, {defineAs: "browserTestSendMessage"}); - - window.addEventListener("pageshow", () => { - browser.test.fail("pageshow should have been suppressed by stopImmediatePropagation"); - }); - window.addEventListener("pagehide", () => { - browser.test.fail("pagehide should have been suppressed by stopImmediatePropagation"); - }, true); - } - - let extension = ExtensionTestUtils.loadExtension({ - manifest: { - content_scripts: [{ - "matches": ["http://example.com/bfcachetestpage"], - "js": ["content_script.js"], - }], - }, - - files: { - "content_script.js": contentScript, - }, - }); - - let contentPage = await ExtensionTestUtils.loadContentPage("http://example.com/bfcachetestpage"); - await extension.startup(); - await extension.awaitMessage("content-script-ready"); - - // Get the content script context and check that it points to the correct window. - await contentPage.spawn(extension.id, async extensionId => { - let {DocumentManager} = ChromeUtils.import("resource://gre/modules/ExtensionContent.jsm", {}); - this.context = DocumentManager.getContext(extensionId, this.content); - - Assert.ok(this.context, "Got content script context"); - - Assert.equal(this.context.contentWindow, this.content, "Context's contentWindow property is correct"); - - // Navigate so that the content page is hidden in the bfcache. - - this.content.location = "http://example.org/dummy?noscripthere1"; - }); - - await extension.awaitMessage("content-script-hide"); - - await contentPage.spawn(null, async () => { - Assert.equal(this.context.contentWindow, null, "Context's contentWindow property is null"); - Assert.ok(this.context.sandbox, "Context's sandbox exists"); - - // Navigate back so the content page is resurrected from the bfcache. - this.content.history.back(); - }); - - await extension.awaitMessage("content-script-show"); - - await contentPage.spawn(null, async () => { - Assert.equal(this.context.contentWindow, this.content, "Context's contentWindow property is correct"); - Assert.ok(this.context.sandbox, "Context's sandbox exists before unload"); - - let contextUnloadedPromise = new Promise(resolve => { - this.context.callOnClose({close: resolve}); - }); - - // Now add an "unload" event listener, which should prevent a page from entering the bfcache. - await new Promise((resolve) => { - this.content.addEventListener("unload", () => { - Assert.equal(this.context.contentWindow, this.content, "Context's contentWindow property should be non-null at unload"); - resolve(); - }); - this.content.location = "http://example.org/dummy?noscripthere2"; - }); - - await contextUnloadedPromise; - }); - - await extension.awaitMessage("content-script-unload"); - - await contentPage.spawn(null, async () => { - Assert.equal(this.context.sandbox, null, "Context's sandbox has been destroyed after unload"); - }); - - await contentPage.close(); - await extension.unload(); -}); diff --git a/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini b/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini index 38d714eb8245..4f3604138ceb 100644 --- a/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini +++ b/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini @@ -25,7 +25,6 @@ skip-if = appname == "thunderbird" || os == "android" [test_ext_contentscript_async_loading.js] skip-if = os == 'android' && debug # The generated script takes too long to load on Android debug [test_ext_contentscript_context.js] -[test_ext_contentscript_context_isolation.js] [test_ext_contentscript_create_iframe.js] [test_ext_contentscript_css.js] [test_ext_contentscript_exporthelpers.js] From 5eaeb69af24bb9283af3de60d0d69f0be5641abb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tarek=20Ziad=C3=A9?= Date: Tue, 4 Sep 2018 16:05:05 +0000 Subject: [PATCH 29/61] Bug 1483164 - move the timer test from onload - r=jmaher Moves the test to try to fix an intermittent failure on linux64-asan Differential Revision: https://phabricator.services.mozilla.com/D4908 --HG-- extra : moz-landing-system : lando --- dom/tests/browser/perfmetrics/setinterval.html | 4 ++-- dom/tests/browser/perfmetrics/settimeout.html | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/dom/tests/browser/perfmetrics/setinterval.html b/dom/tests/browser/perfmetrics/setinterval.html index bf309638e28e..4c3e7264ca30 100644 --- a/dom/tests/browser/perfmetrics/setinterval.html +++ b/dom/tests/browser/perfmetrics/setinterval.html @@ -10,10 +10,10 @@ clearInterval(interval); } - interval = setInterval(doSomething, 10); + interval = setInterval(doSomething, 1); -

A page with setInterval() calls

+

A page with a setInterval() call

diff --git a/dom/tests/browser/perfmetrics/settimeout.html b/dom/tests/browser/perfmetrics/settimeout.html index 24178500a8cd..01f632caf510 100644 --- a/dom/tests/browser/perfmetrics/settimeout.html +++ b/dom/tests/browser/perfmetrics/settimeout.html @@ -8,9 +8,10 @@ console.log("We are doing something here"); } + setTimeout(doSomething, 1); - -

A page with setInterval() calls

+ +

A page with a setTimeout() call

From 4ce2d4adcad3f613e66f9f96ef81f9a02a1a2233 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Tue, 4 Sep 2018 16:06:17 +0000 Subject: [PATCH 30/61] Bug 1488472 - Fix the condition for CSS border tests. r=jgraham We should also try to re-enable them in linux32 but... Differential Revision: https://phabricator.services.mozilla.com/D4949 --HG-- extra : moz-landing-system : lando --- testing/web-platform/meta/css/CSS2/borders/__dir__.ini | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/testing/web-platform/meta/css/CSS2/borders/__dir__.ini b/testing/web-platform/meta/css/CSS2/borders/__dir__.ini index 26f80a3ebe4d..d300f06aa8ff 100644 --- a/testing/web-platform/meta/css/CSS2/borders/__dir__.ini +++ b/testing/web-platform/meta/css/CSS2/borders/__dir__.ini @@ -1 +1,2 @@ -disabled: if not debug && (os == "linux") && (bits == 32): https://bugzilla.mozilla.org/show_bug.cgi?id=1445834 +disabled: + if not debug and (os == "linux") and (bits == 32): https://bugzilla.mozilla.org/show_bug.cgi?id=1445834 From d9c00611985ed74ceb8e72672cd4732621ab4756 Mon Sep 17 00:00:00 2001 From: Bas Schouten Date: Tue, 4 Sep 2018 00:18:11 +0000 Subject: [PATCH 31/61] Bug 1486875: Make it possible to skip composition or painting using environment variables. r=mstange Differential Revision: https://phabricator.services.mozilla.com/D4526 --HG-- extra : moz-landing-system : lando --- gfx/layers/client/ClientPaintedLayer.cpp | 17 ++++++++++------- gfx/layers/composite/LayerManagerComposite.cpp | 6 ++++++ gfx/layers/mlgpu/LayerManagerMLGPU.cpp | 5 +++++ gfx/thebes/gfxEnv.h | 6 ++++++ 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/gfx/layers/client/ClientPaintedLayer.cpp b/gfx/layers/client/ClientPaintedLayer.cpp index f2841237d780..274c3ca40d71 100644 --- a/gfx/layers/client/ClientPaintedLayer.cpp +++ b/gfx/layers/client/ClientPaintedLayer.cpp @@ -11,6 +11,7 @@ #include "client/ClientLayerManager.h" // for ClientLayerManager, etc #include "gfxContext.h" // for gfxContext #include "gfx2DGlue.h" +#include "gfxEnv.h" // for gfxEnv #include "gfxRect.h" // for gfxRect #include "gfxPrefs.h" // for gfxPrefs #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc @@ -155,13 +156,15 @@ ClientPaintedLayer::RenderLayerWithReadback(ReadbackProcessor *aReadback) RefPtr ctx = gfxContext::CreatePreservingTransformOrNull(target); MOZ_ASSERT(ctx); // already checked the target above - ClientManager()->GetPaintedLayerCallback()(this, - ctx, - iter.mDrawRegion, - iter.mDrawRegion, - state.mClip, - state.mRegionToInvalidate, - ClientManager()->GetPaintedLayerCallbackData()); + if (!gfxEnv::SkipRasterization()) { + ClientManager()->GetPaintedLayerCallback()(this, + ctx, + iter.mDrawRegion, + iter.mDrawRegion, + state.mClip, + state.mRegionToInvalidate, + ClientManager()->GetPaintedLayerCallbackData()); + } ctx = nullptr; mContentClient->ReturnDrawTarget(target); diff --git a/gfx/layers/composite/LayerManagerComposite.cpp b/gfx/layers/composite/LayerManagerComposite.cpp index 5827405defeb..ee6ad9c52af8 100644 --- a/gfx/layers/composite/LayerManagerComposite.cpp +++ b/gfx/layers/composite/LayerManagerComposite.cpp @@ -24,6 +24,7 @@ #include "Units.h" // for ScreenIntRect #include "UnitTransforms.h" // for ViewAs #include "apz/src/AsyncPanZoomController.h" // for AsyncPanZoomController +#include "gfxEnv.h" // for gfxEnv #include "gfxPrefs.h" // for gfxPrefs #ifdef XP_MACOSX #include "gfxPlatformMac.h" @@ -477,6 +478,11 @@ LayerManagerComposite::EndTransaction(const TimeStamp& aTimeStamp, void LayerManagerComposite::UpdateAndRender() { + if (gfxEnv::SkipComposition()) { + mInvalidRegion.SetEmpty(); + return; + } + nsIntRegion invalid; // The results of our drawing always go directly into a pixel buffer, // so we don't need to pass any global transform here. diff --git a/gfx/layers/mlgpu/LayerManagerMLGPU.cpp b/gfx/layers/mlgpu/LayerManagerMLGPU.cpp index 8b26a2633959..e2b986600d91 100644 --- a/gfx/layers/mlgpu/LayerManagerMLGPU.cpp +++ b/gfx/layers/mlgpu/LayerManagerMLGPU.cpp @@ -10,6 +10,7 @@ #include "ImageLayerMLGPU.h" #include "CanvasLayerMLGPU.h" #include "GeckoProfiler.h" // for profiler_* +#include "gfxEnv.h" // for gfxEnv #include "MLGDevice.h" #include "RenderPassMLGPU.h" #include "RenderViewMLGPU.h" @@ -276,6 +277,10 @@ LayerManagerMLGPU::EndTransaction(const TimeStamp& aTimeStamp, EndTransactionFla void LayerManagerMLGPU::Composite() { + if (gfxEnv::SkipComposition()) { + return; + } + AUTO_PROFILER_LABEL("LayerManagerMLGPU::Composite", GRAPHICS); // Don't composite if we're minimized/hidden, or if there is nothing to draw. diff --git a/gfx/thebes/gfxEnv.h b/gfx/thebes/gfxEnv.h index ee0628ab7ab2..7a02833e8cdf 100644 --- a/gfx/thebes/gfxEnv.h +++ b/gfx/thebes/gfxEnv.h @@ -101,6 +101,12 @@ public: // Offscreen GL context for main layer manager DECL_GFX_ENV("MOZ_LAYERS_PREFER_OFFSCREEN", LayersPreferOffscreen); + // Skip final window composition + DECL_GFX_ENV("MOZ_SKIPCOMPOSITION", SkipComposition); + + // Skip rasterizing painted layer contents + DECL_GFX_ENV("MOZ_SKIPRASTERIZATION", SkipRasterization); + // Stop the VR rendering DECL_GFX_ENV("NO_VR_RENDERING", NoVRRendering); From f4e5219ee3beb813676a6f8691be7a7cb4129e0a Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Tue, 4 Sep 2018 16:40:22 +0000 Subject: [PATCH 32/61] Bug 1451527 - Move sync's TPS tests into a webextension r=markh Differential Revision: https://phabricator.services.mozilla.com/D4486 --HG-- extra : moz-landing-system : lando --- services/sync/tps/extensions/tps/api.js | 72 ++++++++++++ services/sync/tps/extensions/tps/bootstrap.js | 104 ------------------ services/sync/tps/extensions/tps/install.rdf | 30 ----- .../sync/tps/extensions/tps/manifest.json | 23 ++++ .../tps/resource/auth/fxaccounts.jsm | 2 +- .../tps/resource/modules/formautofill.jsm | 8 +- services/sync/tps/extensions/tps/schema.json | 1 + testing/tps/tps/phase.py | 21 ++-- testing/tps/tps/testrunner.py | 3 +- 9 files changed, 118 insertions(+), 146 deletions(-) create mode 100644 services/sync/tps/extensions/tps/api.js delete mode 100644 services/sync/tps/extensions/tps/bootstrap.js delete mode 100644 services/sync/tps/extensions/tps/install.rdf create mode 100644 services/sync/tps/extensions/tps/manifest.json create mode 100644 services/sync/tps/extensions/tps/schema.json diff --git a/services/sync/tps/extensions/tps/api.js b/services/sync/tps/extensions/tps/api.js new file mode 100644 index 000000000000..5e2439fe9fd8 --- /dev/null +++ b/services/sync/tps/extensions/tps/api.js @@ -0,0 +1,72 @@ +/* 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/. */ + +ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); +ChromeUtils.import("resource://gre/modules/Services.jsm"); +ChromeUtils.import("resource://gre/modules/FileUtils.jsm"); +ChromeUtils.import("resource://gre/modules/Timer.jsm"); + +XPCOMUtils.defineLazyServiceGetter(this, "resProto", + "@mozilla.org/network/protocol;1?name=resource", + "nsISubstitutingProtocolHandler"); + +async function tpsStartup() { + try { + ChromeUtils.import("resource://tps/tps.jsm"); + ChromeUtils.import("resource://tps/quit.js", TPS); + + let testFile = Services.prefs.getStringPref("testing.tps.testFile", ""); + let testPhase = Services.prefs.getStringPref("testing.tps.testPhase", ""); + if (!testFile || !testPhase) { + // Note: this quits. + TPS.DumpError("TPS no longer takes arguments from the command line. " + + "instead you need to pass preferences `testing.tps.{testFile,testPhase}` " + + "and optionally `testing.tps.{logFile,ignoreUnusedEngines}`.\n"); + } + + let logFile = Services.prefs.getStringPref("testing.tps.logFile", ""); + let ignoreUnusedEngines = Services.prefs.getBoolPref("testing.tps.ignoreUnusedEngines", false); + let options = { ignoreUnusedEngines }; + let testFileUri = Services.io.newFileURI(new FileUtils.File(testFile)).spec; + + try { + await TPS.RunTestPhase(testFileUri, testPhase, logFile, options) + } catch (err) { + TPS.DumpError("TestPhase failed", err); + } + } catch (e) { + if (typeof TPS != "undefined") { + // Note: This calls quit() under the hood + TPS.DumpError("Test initialization failed", err); + } + // Try and quit right away, no reason to wait around for python + // to kill us if initialization failed. + Services.startup.quit(Ci.nsIAppStartup.eForceQuit); + } +} + +function onStartupFinished() { + return new Promise(resolve => { + const onStartupFinished = () => { + Services.obs.removeObserver(onStartupFinished, "browser-delayed-startup-finished"); + resolve(); + }; + Services.obs.addObserver(onStartupFinished, "browser-delayed-startup-finished"); + }); +} + +this.tps = class extends ExtensionAPI { + onStartup() { + resProto.setSubstitution("tps", + Services.io.newURI("resource/", null, this.extension.rootURI)); + /* Ignore the platform's online/offline status while running tests. */ + Services.io.manageOfflineStatus = false; + Services.io.offline = false; + tpsStartup(); + } + + onShutdown() { + resProto.setSubstitution("tps", null); + } +}; diff --git a/services/sync/tps/extensions/tps/bootstrap.js b/services/sync/tps/extensions/tps/bootstrap.js deleted file mode 100644 index 7f126d069f8a..000000000000 --- a/services/sync/tps/extensions/tps/bootstrap.js +++ /dev/null @@ -1,104 +0,0 @@ -/* 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/. */ - - -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); -ChromeUtils.import("resource://gre/modules/Services.jsm"); -ChromeUtils.import("resource://gre/modules/osfile.jsm"); - -XPCOMUtils.defineLazyServiceGetter(this, "resProto", - "@mozilla.org/network/protocol;1?name=resource", - "nsISubstitutingProtocolHandler"); - -const Cm = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); - -const CATMAN_CONTRACTID = "@mozilla.org/categorymanager;1"; - -const CATEGORY_NAME = "command-line-handler"; -const CATEGORY_ENTRY = "m-tps"; - -function TPSCmdLine() {} - -TPSCmdLine.prototype = { - factory: XPCOMUtils._getFactory(TPSCmdLine), - classDescription: "TPSCmdLine", - classID: Components.ID("{4e5bd3f0-41d3-11df-9879-0800200c9a66}"), - contractID: "@mozilla.org/commandlinehandler/general-startup;1?type=tps", - - QueryInterface: ChromeUtils.generateQI([Ci.nsICommandLineHandler]), - - register() { - Cm.registerFactory(this.classID, this.classDescription, - this.contractID, this.factory); - - Services.catMan.addCategoryEntry(CATEGORY_NAME, CATEGORY_ENTRY, - this.contractID, false, true); - }, - - unregister() { - Services.catMan.deleteCategoryEntry(CATEGORY_NAME, CATEGORY_ENTRY, - this.contractID, false); - - Cm.unregisterFactory(this.classID, this.factory); - }, - - /* nsICmdLineHandler */ - commandLineArgument: "-tps", - prefNameForStartup: "general.startup.tps", - helpText: "Run TPS tests with the given test file.", - handlesArgs: true, - defaultArgs: "", - openWindowWithArgs: true, - - /* nsICommandLineHandler */ - handle: function handler_handle(cmdLine) { - let options = {}; - - let uristr = cmdLine.handleFlagWithParam("tps", false); - if (uristr == null) { - return; - } - let phase = cmdLine.handleFlagWithParam("tpsphase", false); - if (phase == null) { - throw Error("must specify --tpsphase with --tps"); - } - let logfile = cmdLine.handleFlagWithParam("tpslogfile", false); - if (logfile == null) { - logfile = ""; - } - - options.ignoreUnusedEngines = cmdLine.handleFlag("ignore-unused-engines", - false); - let uri = cmdLine.resolveURI(OS.Path.normalize(uristr)).spec; - - const onStartupFinished = () => { - Services.obs.removeObserver(onStartupFinished, "browser-delayed-startup-finished"); - /* Ignore the platform's online/offline status while running tests. */ - Services.io.manageOfflineStatus = false; - Services.io.offline = false; - ChromeUtils.import("resource://tps/tps.jsm"); - ChromeUtils.import("resource://tps/quit.js", TPS); - TPS.RunTestPhase(uri, phase, logfile, options).catch(err => TPS.DumpError("TestPhase failed", err)); - }; - Services.obs.addObserver(onStartupFinished, "browser-delayed-startup-finished"); - }, - - helpInfo: " --tps Run TPS tests with the given test file.\n" + - " --tpsphase Run the specified phase in the TPS test.\n" + - " --tpslogfile Logfile for TPS output.\n" + - " --ignore-unused-engines Don't load engines not used in tests.\n", -}; - -function startup(data, reason) { - TPSCmdLine.prototype.register(); - resProto.setSubstitution("tps", Services.io.newURI("resource/", null, data.resourceURI)); -} - -function shutdown(data, reason) { - resProto.setSubstitution("tps", null); - TPSCmdLine.prototype.unregister(); -} - -function install(data, reason) {} -function uninstall(data, reason) {} diff --git a/services/sync/tps/extensions/tps/install.rdf b/services/sync/tps/extensions/tps/install.rdf deleted file mode 100644 index f9f060af129d..000000000000 --- a/services/sync/tps/extensions/tps/install.rdf +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - tps@mozilla.org - 0.5 - true - - - - - {ec8030f7-c20a-464f-9b0e-13a3a9e97384} - 24.0.* - * - - - - - TPS - Sync test extension - Jonathan Griffin - Henrik Skupin - https://developer.mozilla.org/en-US/docs/TPS - true - - diff --git a/services/sync/tps/extensions/tps/manifest.json b/services/sync/tps/extensions/tps/manifest.json new file mode 100644 index 000000000000..2de6e902c689 --- /dev/null +++ b/services/sync/tps/extensions/tps/manifest.json @@ -0,0 +1,23 @@ +{ + "manifest_version": 2, + "name": "TPS", + "version": "1.0", + + "applications": { + "gecko": { + "id": "tps@mozilla.org" + } + }, + + "experiment_apis": { + "tps": { + "schema": "schema.json", + "parent": { + "scopes": ["addon_parent"], + "script": "api.js", + "paths": [["tps"]], + "events": ["startup"] + } + } + } +} diff --git a/services/sync/tps/extensions/tps/resource/auth/fxaccounts.jsm b/services/sync/tps/extensions/tps/resource/auth/fxaccounts.jsm index 0f58459a8586..aff0ec141ab9 100644 --- a/services/sync/tps/extensions/tps/resource/auth/fxaccounts.jsm +++ b/services/sync/tps/extensions/tps/resource/auth/fxaccounts.jsm @@ -64,7 +64,7 @@ var Authentication = { async _openVerificationPage(uri) { let mainWindow = Services.wm.getMostRecentWindow("navigator:browser"); - let newtab = mainWindow.getBrowser().addTab(uri); + let newtab = mainWindow.getBrowser().addWebTab(uri); let win = mainWindow.getBrowser().getBrowserForTab(newtab); await new Promise(resolve => { win.addEventListener("loadend", resolve, { once: true }); diff --git a/services/sync/tps/extensions/tps/resource/modules/formautofill.jsm b/services/sync/tps/extensions/tps/resource/modules/formautofill.jsm index 23feb3f8027d..60a022159b2b 100644 --- a/services/sync/tps/extensions/tps/resource/modules/formautofill.jsm +++ b/services/sync/tps/extensions/tps/resource/modules/formautofill.jsm @@ -10,8 +10,12 @@ var EXPORTED_SYMBOLS = ["Address", "CreditCard", "DumpAddresses", "DumpCreditCards"]; ChromeUtils.import("resource://tps/logger.jsm"); -ChromeUtils.import("resource://formautofill/FormAutofillStorage.jsm"); -ChromeUtils.import("resource://formautofill/MasterPassword.jsm"); + +ChromeUtils.defineModuleGetter(this, "formAutofillStorage", + "resource://formautofill/FormAutofillStorage.jsm"); + +ChromeUtils.defineModuleGetter(this, "MasterPassword", + "resource://formautofill/MasterPassword.jsm"); class FormAutofillBase { constructor(props, subStorageName, fields) { diff --git a/services/sync/tps/extensions/tps/schema.json b/services/sync/tps/extensions/tps/schema.json new file mode 100644 index 000000000000..0637a088a01e --- /dev/null +++ b/services/sync/tps/extensions/tps/schema.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/testing/tps/tps/phase.py b/testing/tps/tps/phase.py index 397c90796297..85a9e23d2485 100644 --- a/testing/tps/tps/phase.py +++ b/testing/tps/tps/phase.py @@ -3,6 +3,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. import re +import os.path class TPSTestPhase(object): @@ -29,17 +30,21 @@ class TPSTestPhase(object): def run(self): # launch Firefox - args = [ '-tps', self.testpath, - '-tpsphase', self.phase, - '-tpslogfile', self.logfile ] - if self.ignore_unused_engines: - args.append('--ignore-unused-engines') + prefs = { + "testing.tps.testFile": os.path.abspath(self.testpath), + "testing.tps.testPhase": self.phase, + "testing.tps.logFile": self.logfile, + "testing.tps.ignoreUnusedEngines": self.ignore_unused_engines + } + + self.profile.set_preferences(prefs); + + self.log('\nLaunching Firefox for phase %s with prefs %s\n' % + (self.phase, str(prefs))) - self.log('\nLaunching Firefox for phase %s with args %s\n' % - (self.phase, str(args))) self.firefoxRunner.run(env=self.env, - args=args, + args=[], profile=self.profile) # parse the logfile and look for results from the current test phase diff --git a/testing/tps/tps/testrunner.py b/testing/tps/tps/testrunner.py index 12cad820038b..1640794e1bf5 100644 --- a/testing/tps/tps/testrunner.py +++ b/testing/tps/tps/testrunner.py @@ -235,7 +235,7 @@ class TPSTestRunner(object): # create the profile if necessary if not profilename in profiles: - profiles[profilename] = Profile(preferences = self.preferences, + profiles[profilename] = Profile(preferences = self.preferences.copy(), addons = self.extensions) # create the test phase @@ -262,6 +262,7 @@ class TPSTestRunner(object): break; for profilename in profiles: + print "### Cleanup Profile ", profilename cleanup_phase = TPSTestPhase( 'cleanup-' + profilename, profiles[profilename], testname, From 72702be2ca5bafbe504b5d7ecd1282b5db62746c Mon Sep 17 00:00:00 2001 From: shindli Date: Tue, 4 Sep 2018 19:45:06 +0300 Subject: [PATCH 33/61] Backed out changeset 6cd626758796 (bug 1483038) for ES lint failure in L10nRegistry --- intl/l10n/L10nRegistry.jsm | 78 +++++++++++++++++--------------------- intl/l10n/Localization.jsm | 7 ++-- intl/l10n/l10n.js | 6 +-- 3 files changed, 40 insertions(+), 51 deletions(-) diff --git a/intl/l10n/L10nRegistry.jsm b/intl/l10n/L10nRegistry.jsm index 432a3e0fec8d..a3292a72f4fe 100644 --- a/intl/l10n/L10nRegistry.jsm +++ b/intl/l10n/L10nRegistry.jsm @@ -95,18 +95,26 @@ const L10nRegistry = { const sourcesOrder = Array.from(this.sources.keys()).reverse(); const pseudoNameFromPref = Services.prefs.getStringPref("intl.l10n.pseudo", ""); for (const locale of requestedLangs) { - for await (const dataSets of generateResourceSetsForLocale(locale, sourcesOrder, resourceIds)) { - const ctx = new MessageContext(locale, { - ...MSG_CONTEXT_OPTIONS, - transform: PSEUDO_STRATEGIES[pseudoNameFromPref], - }); - for (const data of dataSets) { - if (data === null) { - return null; - } - ctx.addResource(data); + for (const fetchPromises of generateResourceSetsForLocale(locale, sourcesOrder, resourceIds)) { + const ctx = await Promise.all(fetchPromises).then( + dataSets => { + const ctx = new MessageContext(locale, { + ...MSG_CONTEXT_OPTIONS, + transform: PSEUDO_STRATEGIES[pseudoNameFromPref], + }); + for (const data of dataSets) { + if (data === null) { + return null; + } + ctx.addResource(data); + } + return ctx; + }, + () => null + ); + if (ctx !== null) { + yield ctx; } - yield ctx; } } }, @@ -182,7 +190,7 @@ const L10nRegistry = { * @param {Array} [resolvedOrder] * @returns {AsyncIterator} */ -async function* generateResourceSetsForLocale(locale, sourcesOrder, resourceIds, resolvedOrder = []) { +function* generateResourceSetsForLocale(locale, sourcesOrder, resourceIds, resolvedOrder = []) { const resolvedLength = resolvedOrder.length; const resourcesLength = resourceIds.length; @@ -192,36 +200,18 @@ async function* generateResourceSetsForLocale(locale, sourcesOrder, resourceIds, for (const sourceName of sourcesOrder) { const order = resolvedOrder.concat(sourceName); - // We want to bail out early if we know that any of - // the (res)x(source) combinations in the permutation - // are unavailable. - // The combination may have been `undefined` when we - // stepped into this branch, and now is resolved to - // `false`. - // - // If the combination resolved to `false` is the last - // in the resolvedOrder, we want to continue in this - // loop, but if it's somewhere in the middle, we can - // safely bail from the whole branch. - for (let [idx, sourceName] of order.entries()) { - if (L10nRegistry.sources.get(sourceName).hasFile(locale, resourceIds[idx]) === false) { - if (idx === order.length - 1) { - continue; - } else { - return; - } - } + // We bail only if the hasFile returns a strict false here, + // because for FileSource it may also return undefined, which means + // that we simply don't know if the source contains the file and we'll + // have to perform the I/O to learn. + if (L10nRegistry.sources.get(sourceName).hasFile(locale, resourceIds[resolvedOrder.length]) === false) { + continue; } // If the number of resolved sources equals the number of resources, // create the right context and return it if it loads. if (resolvedLength + 1 === resourcesLength) { - let dataSet = await generateResourceSet(locale, order, resourceIds); - // Here we check again to see if the newly resolved - // resources returned `false` on any position. - if (!dataSet.includes(false)) { - yield dataSet; - } + yield generateResourceSet(locale, order, resourceIds); } else if (resolvedLength < resourcesLength) { // otherwise recursively load another generator that walks over the // partially resolved list of sources. @@ -356,10 +346,10 @@ const PSEUDO_STRATEGIES = { * @param {Array} resourceIds * @returns {Promise} */ -async function generateResourceSet(locale, sourcesOrder, resourceIds) { - return Promise.all(resourceIds.map((resourceId, i) => { +function generateResourceSet(locale, sourcesOrder, resourceIds) { + return resourceIds.map((resourceId, i) => { return L10nRegistry.sources.get(sourcesOrder[i]).fetchFile(locale, resourceId); - })); + }); } /** @@ -430,14 +420,14 @@ class FileSource { fetchFile(locale, path) { if (!this.locales.includes(locale)) { - return false; + return Promise.reject(`The source has no resources for locale "${locale}"`); } const fullPath = this.getPath(locale, path); if (this.cache.hasOwnProperty(fullPath)) { if (this.cache[fullPath] === false) { - return false; + return Promise.reject(`The source has no resources for path "${fullPath}"`); } // `true` means that the file is indexed, but hasn't // been fetched yet. @@ -445,7 +435,7 @@ class FileSource { return this.cache[fullPath]; } } else if (this.indexed) { - return false; + return Promise.reject(`The source has no resources for path "${fullPath}"`); } return this.cache[fullPath] = L10nRegistry.load(fullPath).then( data => { @@ -453,7 +443,7 @@ class FileSource { }, err => { this.cache[fullPath] = false; - return false; + return Promise.reject(err); } ); } diff --git a/intl/l10n/Localization.jsm b/intl/l10n/Localization.jsm index 1d453578134a..8aa0722f20d8 100644 --- a/intl/l10n/Localization.jsm +++ b/intl/l10n/Localization.jsm @@ -97,7 +97,7 @@ class CachedAsyncIterable extends CachedIterable { return { async next() { if (cached.length <= cur) { - cached.push(cached.iterator.next()); + cached.push(await cached.iterator.next()); } return cached[cur++]; } @@ -114,10 +114,10 @@ class CachedAsyncIterable extends CachedIterable { let idx = 0; while (idx++ < count) { const last = this[this.length - 1]; - if (last && await (last).done) { + if (last && last.done) { break; } - this.push(this.iterator.next()); + this.push(await this.iterator.next()); } // Return the last cached {value, done} object to allow the calling // code to decide if it needs to call touchNext again. @@ -322,6 +322,7 @@ class Localization { onChange() { this.ctxs = CachedAsyncIterable.from( this.generateMessages(this.resourceIds)); + this.ctxs.touchNext(2); } } diff --git a/intl/l10n/l10n.js b/intl/l10n/l10n.js index 1afb8f7ee00d..ad6c914b3219 100644 --- a/intl/l10n/l10n.js +++ b/intl/l10n/l10n.js @@ -1,7 +1,6 @@ { const { DOMLocalization } = ChromeUtils.import("resource://gre/modules/DOMLocalization.jsm", {}); - const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm", {}); /** * Polyfill for document.ready polyfill. @@ -47,9 +46,8 @@ document.l10n = new DOMLocalization(resourceIds); - const appLocales = Services.locale.getAppLocalesAsBCP47(); - const prefetchCount = appLocales.length > 1 ? 2 : 1; - document.l10n.ctxs.touchNext(prefetchCount); + // Trigger the first two contexts to be loaded eagerly. + document.l10n.ctxs.touchNext(2); document.l10n.ready = documentReady().then(() => { document.l10n.registerObservers(); From 08c332030da7959857519dcbfb26b558171e362b Mon Sep 17 00:00:00 2001 From: ffxbld Date: Tue, 4 Sep 2018 16:45:07 +0000 Subject: [PATCH 34/61] No Bug, taskcluster/docker/funsize-update-generator pipfile-update. r=bhearsum Differential Revision: https://phabricator.services.mozilla.com/D4844 --HG-- extra : moz-landing-system : lando --- .../funsize-update-generator/Pipfile.lock | 63 ++++++++++--------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/taskcluster/docker/funsize-update-generator/Pipfile.lock b/taskcluster/docker/funsize-update-generator/Pipfile.lock index cb16c4ccd5ce..777107f2edf8 100644 --- a/taskcluster/docker/funsize-update-generator/Pipfile.lock +++ b/taskcluster/docker/funsize-update-generator/Pipfile.lock @@ -18,31 +18,31 @@ "default": { "aiohttp": { "hashes": [ - "sha256:01a2059a0505460828854d218cf090d80db277033b8e6906144ab9bd4677fc82", - "sha256:01bcaf83911c5a88f74629f116540a1b80391e6e496e6fb8708bb2987b60da63", - "sha256:199ea4a9c424904f04a86563a8e9e2759d49e3a0bf789496714253237f16015f", - "sha256:229975cb8ff6056c8ef581383a653e7110480d52c9f46eaf560113f8d5005510", - "sha256:2bb4224e3a3d7dd2ee18f6c42c1925c3200cd46fe18ec9f293b9bc88644c4878", - "sha256:2ddf47c31048efad5a566d82822194bbb680fc1be852915c2949eb69891b5d5a", - "sha256:3bc9c87845962f583d6929f837b02b80d2544920be65daf0d0a1306ad1a2089b", - "sha256:3f88a3428f40c788321cf5b8191f9dd9e002145545fa0cefc023b4b11e17aaa7", - "sha256:4785935328facee0878c29d46f02b12f1e8e8db1cd3d9ec9af666eb163418a64", - "sha256:48e8d1973ba62a952f19a7916e54a7155f4b14505507432fc0559d8b5b0e5cad", - "sha256:5cd8662ddd7c95e99010e30cc52e20a092939844e8e8a4f37abf1866231f1880", - "sha256:6880406a0c776fbff63c0d9eb8a2d96d8134b17fafeeea01180b58ab8ff0f6f5", - "sha256:6a8e447742fc45791ffea0b3ce308f1476a9f4707fb6525a2f23b43d4b26cfb3", - "sha256:81456c04c54288928da4e7e1893314c8e74d5e9f33163e39aa47c26c5e5c7911", - "sha256:9b15efa7411dcf3b59c1f4766eb16ba1aba4531a33e54d469ee22106eabce460", - "sha256:a6132db365def76145084041cede574a0c8ed53aa1a680a3027e41ee8f291bd4", - "sha256:ddee38858a9ef52ca33cb5dd1607d07d0fb99e2efe523ecb437b1758c49622a5", - "sha256:de703f333381864dce788dbfa1a49ef4551e8f082b607a943b94b239d97965cc", - "sha256:e08cacfede41291c05b4668c3178d303d078417c013bc3d5287b2b0d0e6a3aa7", - "sha256:e4c37c7ec1e1157ae4af73fd1d7f201accebf6ed2222120bc660fd002c45cbac", - "sha256:e4f9fc91d617d2e54bda97bc1db9814918691fe799e037ccf973fda434fd2c18", - "sha256:f6f73c812c1830a06de76ccbea10a4ebb1fd46230a80f280362e84578e4932a2" + "sha256:04087c38e45da5aa1a8b2345441b821bf270436f7954eba1a7e36cc55fed81f8", + "sha256:07f025ea9fbc904f46cde7ba1e16c4085687cf8b6cabb6b815a8b5962605a743", + "sha256:0fae84267df30e27b072da1a09835616e6872f7cc82cfc3eb260a52e9b6de340", + "sha256:17b105bfeefe7c1d122d5948f7fe20adb5eae83cbbf6c7b5a787176c883fc0ea", + "sha256:21ec794275615fcf9b0715266ce6709eb40045560c75431a1439fb1ed0fb0241", + "sha256:2421ca89978a037f0ed1cc77fc5678561cc416c2047aad2e1dd8259bce1192b3", + "sha256:26e996559c8f723c19a638f5c315716c258d9e2e2e5fa31ef76cc62a4d676c99", + "sha256:540c02599fb3f913121fe5767506f2ce36d0ff9bda6f0cf3f4fe978d68f9a8f8", + "sha256:5e452185e23f4a30208b057932b4ca5d528f4c4fdcc58028809e9f763fa52f36", + "sha256:613bc9d4513df36f76faf19f1010430c0cea45cc9db4af0df96d237e5fd42800", + "sha256:6f35399afb09427523f97d6a6a000fb6562e9ed2d3560c2fdfb9d874beb46ecf", + "sha256:72f9ba7f4767a5e75aeb68f0441ddd3856f7129cbd0d188420e770d17e3b100a", + "sha256:74dc560e074a8a56ef3722bd87fc06acc38eaccba6b35afc39345782eeb41a42", + "sha256:8de492b8c8d5acb60c30cf2275f36d0fb21d71e0a462bbed61f099a98264c635", + "sha256:97e3f198da96d5833200d814812ee03dbf1b2ba5a85ea4751e5da1360fe9a7cd", + "sha256:bb2af48882b6d351ffe17423d19a1a51f0850ead5b7e7237b663a4e880e8d5b7", + "sha256:d50047664a199eab5e596e4a18f09781fcdc1ad43b3203c5585dc65cf4c57592", + "sha256:d65a3942bce7717a1dc730927f583308e100a94375ed81fa06bcb02127e4c3ae", + "sha256:e59bcc461b6523b8c9105032f7664bd918f9c3be5f96462b814e6bf1c915c32e", + "sha256:f1958340035221643c0c27326fecf24e49265ba21c709e42163bc8b16cb2e0c7", + "sha256:f4cba665391bd31b3807277de3c73fd80cc17a0d280f11485fe9e58e228b6c5c", + "sha256:f54001b0504f808a88aa786749af6c52e6ca00b5b7350fbe84d6274e537e7485" ], "index": "pypi", - "version": "==3.4.0" + "version": "==3.4.2" }, "arrow": { "hashes": [ @@ -67,10 +67,10 @@ }, "attrs": { "hashes": [ - "sha256:4b90b09eeeb9b88c35bc642cbac057e45a5fd85367b985bd2809c62b7b939265", - "sha256:e0d0eb91441a3b53dab4d9b743eafc1ac44476296a2053b6ca3af0b139faf87b" + "sha256:10cbf6e27dbce8c30807caf056c8eb50917e0eaafe86347671b57254006c3e69", + "sha256:ca4be454458f9dec299268d472aaa5a11f67a4ff70093396e1ceae9c76cf4bbb" ], - "version": "==18.1.0" + "version": "==18.2.0" }, "backports.lzma": { "hashes": [ @@ -328,11 +328,11 @@ }, "scriptworker": { "hashes": [ - "sha256:2b02449c521f1aefbf58ca80305b434205d48c0ff2dae5c0853fe74dc959e555", - "sha256:dd71c060d7e187eeba06d54577fa288c423a5a89bc788b30d779d39a666186ba" + "sha256:063b0442bdbde23afbd2828408c43cdc0f411c9250ea8571655ccba6d2f8d61c", + "sha256:a940358870f5423ba07051ec696a8347c6d5459ad6b2c5823d3fd44a8449d1c0" ], "index": "pypi", - "version": "==15.0.0" + "version": "==15.0.2" }, "sh": { "hashes": [ @@ -386,7 +386,7 @@ "sha256:a68ac5e15e76e7e5dd2b8f94007233e01effe3e50e8daddf69acfd81cb686baf", "sha256:b5725a0bd4ba422ab0e66e89e030c806576753ea3ee08554382c14e685d117b5" ], - "markers": "python_version < '4' and python_version >= '2.6' and python_version != '3.2.*' and python_version != '3.1.*' and python_version != '3.3.*' and python_version != '3.0.*'", + "markers": "python_version != '3.2.*' and python_version != '3.1.*' and python_version >= '2.6' and python_version < '4' and python_version != '3.0.*' and python_version != '3.3.*'", "version": "==1.23" }, "virtualenv": { @@ -394,7 +394,7 @@ "sha256:2ce32cd126117ce2c539f0134eb89de91a8413a29baac49cbab3eb50e2026669", "sha256:ca07b4c0b54e14a91af9f34d0919790b016923d157afda5efdde55c96718f752" ], - "markers": "python_version != '3.1.*' and python_version >= '2.7' and python_version != '3.0.*' and python_version != '3.2.*'", + "markers": "python_version != '3.1.*' and python_version != '3.0.*' and python_version >= '2.7' and python_version != '3.2.*'", "version": "==16.0.0" }, "yarl": { @@ -409,6 +409,7 @@ "sha256:f17495e6fe3d377e3faac68121caef6f974fcb9e046bc075bcff40d8e5cc69a4", "sha256:f85900b9cca0c67767bb61b2b9bd53208aaa7373dae633dbe25d179b4bf38aa7" ], + "markers": "python_version >= '3.4.1'", "version": "==1.2.6" } }, From 895d91f1f8dd352589c4da473b7975aef482f20e Mon Sep 17 00:00:00 2001 From: shindli Date: Tue, 4 Sep 2018 19:48:57 +0300 Subject: [PATCH 35/61] Backed out changeset e41e158793a1 (bug 1476604) for bustages in AccessibleHandler.dll --- taskcluster/ci/toolchain/linux.yml | 1 - taskcluster/scripts/misc/build-sccache.sh | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/taskcluster/ci/toolchain/linux.yml b/taskcluster/ci/toolchain/linux.yml index d837e555fa47..b70bbda6a6fa 100755 --- a/taskcluster/ci/toolchain/linux.yml +++ b/taskcluster/ci/toolchain/linux.yml @@ -574,7 +574,6 @@ linux64-sccache: toolchain-artifact: public/build/sccache2.tar.xz toolchains: - linux64-rust-1.28 - - linux64-binutils linux64-cbindgen: description: "cbindgen toolchain build" diff --git a/taskcluster/scripts/misc/build-sccache.sh b/taskcluster/scripts/misc/build-sccache.sh index 7a97471338fb..dfb72ec6ca15 100755 --- a/taskcluster/scripts/misc/build-sccache.sh +++ b/taskcluster/scripts/misc/build-sccache.sh @@ -1,8 +1,8 @@ #!/bin/bash set -x -e -v -# 0.2.7 + a number of changes -SCCACHE_REVISION=476d807a0b3c1c31314ea165feea83521d87a17f +# 0.2.7 + --coverage suppport +SCCACHE_REVISION=1ab9a33e8d328941acc23c74c949b765f975f309 # This script is for building sccache @@ -11,7 +11,6 @@ Linux) WORKSPACE=$HOME/workspace UPLOAD_DIR=$HOME/artifacts COMPRESS_EXT=xz - PATH="$WORKSPACE/build/src/binutils/bin:$PATH" ;; MINGW*) WORKSPACE=$PWD From 1d21d7489fe3b208955883fa113ae572accdae64 Mon Sep 17 00:00:00 2001 From: Thi Huynh Date: Sat, 25 Aug 2018 08:37:55 +0000 Subject: [PATCH 36/61] Bug 1483962 - Move helpers of LocalTime UTC TimeZoneComment functions to DateTimeHelper. r=jwalden Differential Revision: https://phabricator.services.mozilla.com/D3901 --HG-- extra : moz-landing-system : lando --- js/src/jsdate.cpp | 123 +++++++++++++++++++++++++++++++--------------- 1 file changed, 84 insertions(+), 39 deletions(-) diff --git a/js/src/jsdate.cpp b/js/src/jsdate.cpp index bc7851fa7626..7ad3b9b8b0d2 100644 --- a/js/src/jsdate.cpp +++ b/js/src/jsdate.cpp @@ -123,6 +123,33 @@ static Atomic sReduceMicros * hashCode */ +namespace +{ + +class DateTimeHelper +{ + private: +#if ENABLE_INTL_API && !MOZ_SYSTEM_ICU + static double localTZA(double t, DateTimeInfo::TimeZoneOffset offset); +#else + static int equivalentYearForDST(int year); + static bool isRepresentableAsTime32(double t); + static double daylightSavingTA(double t); + static double adjustTime(double date); + static PRMJTime toPRMJTime(double localTime, double utcTime); +#endif + + public: + static double localTime(double t); + static double UTC(double t); + static JSString* timeZoneComment(JSContext* cx, double utcTime, double localTime); +#if !ENABLE_INTL_API || MOZ_SYSTEM_ICU + static size_t formatTime(char* buf, size_t buflen, const char* fmt, double utcTime, double localTime); +#endif +}; + +} + // ES2019 draft rev 0ceb728a1adbffe42b26972a6541fd7f398b1557 // 5.2.5 Mathematical Operations static inline double @@ -440,8 +467,8 @@ JS::SetTimeResolutionUsec(uint32_t resolution, bool jitter) #if ENABLE_INTL_API && !MOZ_SYSTEM_ICU // ES2019 draft rev 0ceb728a1adbffe42b26972a6541fd7f398b1557 // 20.3.1.7 LocalTZA ( t, isUTC ) -static double -LocalTZA(double t, DateTimeInfo::TimeZoneOffset offset) +double +DateTimeHelper::localTZA(double t, DateTimeInfo::TimeZoneOffset offset) { MOZ_ASSERT(IsFinite(t)); @@ -452,20 +479,20 @@ LocalTZA(double t, DateTimeInfo::TimeZoneOffset offset) // ES2019 draft rev 0ceb728a1adbffe42b26972a6541fd7f398b1557 // 20.3.1.8 LocalTime ( t ) -static double -LocalTime(double t) +double +DateTimeHelper::localTime(double t) { if (!IsFinite(t)) return GenericNaN(); MOZ_ASSERT(StartOfTime <= t && t <= EndOfTime); - return t + LocalTZA(t, DateTimeInfo::TimeZoneOffset::UTC); + return t + localTZA(t, DateTimeInfo::TimeZoneOffset::UTC); } // ES2019 draft rev 0ceb728a1adbffe42b26972a6541fd7f398b1557 // 20.3.1.9 UTC ( t ) -static double -UTC(double t) +double +DateTimeHelper::UTC(double t) { if (!IsFinite(t)) return GenericNaN(); @@ -473,7 +500,7 @@ UTC(double t) if (t < (StartOfTime - msPerDay) || t > (EndOfTime + msPerDay)) return GenericNaN(); - return t - LocalTZA(t, DateTimeInfo::TimeZoneOffset::Local); + return t - localTZA(t, DateTimeInfo::TimeZoneOffset::Local); } #else /* @@ -483,8 +510,8 @@ UTC(double t) * for determining DST; it hasn't been proven not to produce an * incorrect year for times near year boundaries. */ -static int -EquivalentYearForDST(int year) +int +DateTimeHelper::equivalentYearForDST(int year) { /* * Years and leap years on which Jan 1 is a Sunday, Monday, etc. @@ -517,15 +544,15 @@ EquivalentYearForDST(int year) // Return true if |t| is representable as a 32-bit time_t variable, that means // the year is in [1970, 2038). -static bool -IsRepresentableAsTime32(double t) +bool +DateTimeHelper::isRepresentableAsTime32(double t) { return 0.0 <= t && t < 2145916800000.0; } /* ES5 15.9.1.8. */ -static double -DaylightSavingTA(double t) +double +DateTimeHelper::daylightSavingTA(double t) { if (!IsFinite(t)) return GenericNaN(); @@ -534,8 +561,8 @@ DaylightSavingTA(double t) * If earlier than 1970 or after 2038, potentially beyond the ken of * many OSes, map it to an equivalent year before asking. */ - if (!IsRepresentableAsTime32(t)) { - int year = EquivalentYearForDST(int(YearFromTime(t))); + if (!isRepresentableAsTime32(t)) { + int year = equivalentYearForDST(int(YearFromTime(t))); double day = MakeDay(year, MonthFromTime(t), DateFromTime(t)); t = MakeDate(day, TimeWithinDay(t)); } @@ -545,24 +572,24 @@ DaylightSavingTA(double t) return static_cast(offsetMilliseconds); } -static double -AdjustTime(double date) +double +DateTimeHelper::adjustTime(double date) { double localTZA = DateTimeInfo::localTZA(); - double t = DaylightSavingTA(date) + localTZA; + double t = daylightSavingTA(date) + localTZA; t = (localTZA >= 0) ? fmod(t, msPerDay) : -fmod(msPerDay - t, msPerDay); return t; } /* ES5 15.9.1.9. */ -static double -LocalTime(double t) +double +DateTimeHelper::localTime(double t) { - return t + AdjustTime(t); + return t + adjustTime(t); } -static double -UTC(double t) +double +DateTimeHelper::UTC(double t) { // Following the ES2017 specification creates undesirable results at DST // transitions. For example when transitioning from PST to PDT, @@ -571,10 +598,22 @@ UTC(double t) // V8 and subtract one hour before computing the offset. // Spec bug: https://bugs.ecmascript.org/show_bug.cgi?id=4007 - return t - AdjustTime(t - DateTimeInfo::localTZA() - msPerHour); + return t - adjustTime(t - DateTimeInfo::localTZA() - msPerHour); } #endif /* ENABLE_INTL_API && !MOZ_SYSTEM_ICU */ +static double +LocalTime(double t) +{ + return DateTimeHelper::localTime(t); +} + +static double +UTC(double t) +{ + return DateTimeHelper::UTC(t); +} + /* ES5 15.9.1.10. */ static double HourFromTime(double t) @@ -2712,8 +2751,8 @@ date_toJSON(JSContext* cx, unsigned argc, Value* vp) } #if ENABLE_INTL_API && !MOZ_SYSTEM_ICU -static JSString* -TimeZoneComment(JSContext* cx, double utcTime, double localTime) +JSString* +DateTimeHelper::timeZoneComment(JSContext* cx, double utcTime, double localTime) { const char* locale = cx->runtime()->getDefaultLocale(); if (!locale) { @@ -2747,8 +2786,8 @@ TimeZoneComment(JSContext* cx, double utcTime, double localTime) } #else /* Interface to PRMJTime date struct. */ -static PRMJTime -ToPRMJTime(double localTime, double utcTime) +PRMJTime +DateTimeHelper::toPRMJTime(double localTime, double utcTime) { double year = YearFromTime(localTime); @@ -2762,33 +2801,33 @@ ToPRMJTime(double localTime, double utcTime) prtm.tm_wday = int8_t(WeekDay(localTime)); prtm.tm_year = year; prtm.tm_yday = int16_t(DayWithinYear(localTime, year)); - prtm.tm_isdst = (DaylightSavingTA(utcTime) != 0); + prtm.tm_isdst = (daylightSavingTA(utcTime) != 0); return prtm; } -static size_t -FormatTime(char* buf, size_t buflen, const char* fmt, double utcTime, double localTime) +size_t +DateTimeHelper::formatTime(char* buf, size_t buflen, const char* fmt, double utcTime, double localTime) { - PRMJTime prtm = ToPRMJTime(localTime, utcTime); + PRMJTime prtm = toPRMJTime(localTime, utcTime); // If an equivalent year was used to compute the date/time components, use // the same equivalent year to determine the time zone name and offset in // PRMJ_FormatTime(...). - int timeZoneYear = IsRepresentableAsTime32(utcTime) + int timeZoneYear = isRepresentableAsTime32(utcTime) ? prtm.tm_year - : EquivalentYearForDST(prtm.tm_year); + : equivalentYearForDST(prtm.tm_year); int offsetInSeconds = (int) floor((localTime - utcTime) / msPerSecond); return PRMJ_FormatTime(buf, buflen, fmt, &prtm, timeZoneYear, offsetInSeconds); } -static JSString* -TimeZoneComment(JSContext* cx, double utcTime, double localTime) +JSString* +DateTimeHelper::timeZoneComment(JSContext* cx, double utcTime, double localTime) { char tzbuf[100]; - size_t tzlen = FormatTime(tzbuf, sizeof tzbuf, " (%Z)", utcTime, localTime); + size_t tzlen = formatTime(tzbuf, sizeof tzbuf, " (%Z)", utcTime, localTime); if (tzlen != 0) { // Decide whether to use the resulting time zone string. // @@ -2816,6 +2855,12 @@ TimeZoneComment(JSContext* cx, double utcTime, double localTime) } #endif /* ENABLE_INTL_API && !MOZ_SYSTEM_ICU */ +static JSString* +TimeZoneComment(JSContext* cx, double utcTime, double localTime) +{ + return DateTimeHelper::timeZoneComment(cx, utcTime, localTime); +} + enum class FormatSpec { DateTime, Date, @@ -2924,7 +2969,7 @@ ToLocaleFormatHelper(JSContext* cx, HandleObject obj, const char* format, Mutabl double localTime = LocalTime(utcTime); /* Let PRMJTime format it. */ - size_t result_len = FormatTime(buf, sizeof buf, format, utcTime, localTime); + size_t result_len = DateTimeHelper::formatTime(buf, sizeof buf, format, utcTime, localTime); /* If it failed, default to toString. */ if (result_len == 0) From 98ff61cc446d53ff68a35a1ad8e074d9e377944b Mon Sep 17 00:00:00 2001 From: Valentin Gosu Date: Tue, 4 Sep 2018 16:40:57 +0000 Subject: [PATCH 37/61] Bug 1476996 - Implement cross process redirection in Http on the parent process r=bagder,nika This patch builds the foundation for the ability to relocate HTTP channels from one content process to another in order to ensure that origins are properly isolated. This relocation would normally occur when the response to an HTTP request is a redirect to a different origin. The patch merely adds the mechanism for relocating the channel, rather than the logic of doing so. This will be provided in a follow-up patch by a specialized service. Right now that functionality is mocked in the test. How this works: In nsHttpChannel::OnStartRequest we will query the service that decides whether we need to direct the response to another process. If so, it will return a promise that resolves to a TabParent. When the promise resolves, in HttpChannelParentListener::TriggerCrossProcessRedirect we call NeckoParent::SendCrossProcessRedirect passing along the required information to recreate the channel in the new process. The NeckoChild in the new process will then instantiate a new channel, call ConnectParent() which creates the associated parent channel, and connects it with the existing nsHttpChannel. A listener in the new process is then notified of the existence of the new channel. It is required to call completeRedirectSetup on the channel, passing an nsIStreamListener to the call. We then finish the entire operation with a call to HttpChannelChild::SendCrossProcessRedirectDone which causes us to close the old HttpChannelChild in the previous process and to resume the nsHttpChannel in the main process. Differential Revision: https://phabricator.services.mozilla.com/D2958 --HG-- rename : netwerk/test/browser/browser_cookie_sync_across_tabs.js => netwerk/test/browser/browser_cross_process_redirect.js rename : dom/media/test/redirect.sjs => netwerk/test/browser/redirect.sjs extra : moz-landing-system : lando --- ipc/glue/URIUtils.h | 2 +- netwerk/ipc/NeckoChild.cpp | 70 ++++++ netwerk/ipc/NeckoChild.h | 9 + netwerk/ipc/PNecko.ipdl | 12 + netwerk/protocol/http/HttpChannelChild.cpp | 18 ++ netwerk/protocol/http/HttpChannelChild.h | 12 + netwerk/protocol/http/HttpChannelParent.cpp | 54 ++++- netwerk/protocol/http/HttpChannelParent.h | 4 + .../http/HttpChannelParentListener.cpp | 95 +++++++- .../protocol/http/HttpChannelParentListener.h | 4 + netwerk/protocol/http/PHttpChannel.ipdl | 9 + netwerk/protocol/http/moz.build | 1 + netwerk/protocol/http/nsHttpChannel.cpp | 99 +++++++++ netwerk/protocol/http/nsHttpChannel.h | 12 + .../http/nsIRedirectProcessChooser.idl | 45 ++++ netwerk/test/browser/browser.ini | 2 + .../browser/browser_cross_process_redirect.js | 210 ++++++++++++++++++ netwerk/test/browser/redirect.sjs | 7 + 18 files changed, 651 insertions(+), 14 deletions(-) create mode 100644 netwerk/protocol/http/nsIRedirectProcessChooser.idl create mode 100644 netwerk/test/browser/browser_cross_process_redirect.js create mode 100644 netwerk/test/browser/redirect.sjs diff --git a/ipc/glue/URIUtils.h b/ipc/glue/URIUtils.h index edf35ef61d4c..cc52c3e79e62 100644 --- a/ipc/glue/URIUtils.h +++ b/ipc/glue/URIUtils.h @@ -39,7 +39,7 @@ struct IPDLParamTraits WriteIPDLParam(aMsg, aActor, params); } - static bool Read(IPC::Message* aMsg, PickleIterator* aIter, + static bool Read(const IPC::Message* aMsg, PickleIterator* aIter, IProtocol* aActor, RefPtr* aResult) { OptionalURIParams params; diff --git a/netwerk/ipc/NeckoChild.cpp b/netwerk/ipc/NeckoChild.cpp index 8c6ff2d0ea2c..4698b8d559c3 100644 --- a/netwerk/ipc/NeckoChild.cpp +++ b/netwerk/ipc/NeckoChild.cpp @@ -33,6 +33,8 @@ #include "nsINetworkPredictor.h" #include "nsINetworkPredictorVerifier.h" #include "nsINetworkLinkService.h" +#include "nsIRedirectProcessChooser.h" +#include "nsQueryObject.h" #include "mozilla/ipc/URIUtils.h" #include "nsNetUtil.h" @@ -371,6 +373,74 @@ NeckoChild::DeallocPTransportProviderChild(PTransportProviderChild* aActor) return true; } +mozilla::ipc::IPCResult +NeckoChild::RecvCrossProcessRedirect( + const uint32_t& aRegistrarId, + nsIURI* aURI, + const uint32_t& aNewLoadFlags, + const OptionalLoadInfoArgs& aLoadInfo, + const uint64_t& aChannelId, + nsIURI* aOriginalURI, + const uint64_t& aIdentifier) +{ + nsCOMPtr loadInfo; + nsresult rv = ipc::LoadInfoArgsToLoadInfo(aLoadInfo, getter_AddRefs(loadInfo)); + if (NS_FAILED(rv)) { + MOZ_DIAGNOSTIC_ASSERT(false, "LoadInfoArgsToLoadInfo failed"); + return IPC_OK(); + } + + nsCOMPtr newChannel; + rv = NS_NewChannelInternal(getter_AddRefs(newChannel), + aURI, + loadInfo, + nullptr, // PerformanceStorage + nullptr, // aLoadGroup + nullptr, // aCallbacks + aNewLoadFlags); + + // We are sure this is a HttpChannelChild because the parent + // is always a HTTP channel. + RefPtr httpChild = do_QueryObject(newChannel); + if (NS_FAILED(rv) || !httpChild) { + MOZ_DIAGNOSTIC_ASSERT(false, "NS_NewChannelInternal failed"); + return IPC_OK(); + } + + // This is used to report any errors back to the parent by calling + // CrossProcessRedirectFinished. + auto scopeExit = MakeScopeExit([&]() { + httpChild->CrossProcessRedirectFinished(rv); + }); + + rv = httpChild->SetChannelId(aChannelId); + if (NS_FAILED(rv)) { + return IPC_OK(); + } + + rv = httpChild->SetOriginalURI(aOriginalURI); + if (NS_FAILED(rv)) { + return IPC_OK(); + } + + // connect parent. + rv = httpChild->ConnectParent(aRegistrarId); // creates parent channel + if (NS_FAILED(rv)) { + return IPC_OK(); + } + + nsCOMPtr processListener = + do_GetClassObject("@mozilla.org/network/childProcessChannelListener"); + // The listener will call completeRedirectSetup on the channel. + rv = processListener->OnChannelReady(httpChild, aIdentifier); + if (NS_FAILED(rv)) { + return IPC_OK(); + } + + // scopeExit will call CrossProcessRedirectFinished(rv) here + return IPC_OK(); +} + mozilla::ipc::IPCResult NeckoChild::RecvAsyncAuthPromptForNestedFrame(const TabId& aNestedFrameId, const nsCString& aUri, diff --git a/netwerk/ipc/NeckoChild.h b/netwerk/ipc/NeckoChild.h index d2210077f082..7e9f8d2bcd90 100644 --- a/netwerk/ipc/NeckoChild.h +++ b/netwerk/ipc/NeckoChild.h @@ -96,6 +96,15 @@ protected: virtual mozilla::ipc::IPCResult RecvSpeculativeConnectRequest() override; virtual mozilla::ipc::IPCResult RecvNetworkChangeNotification(nsCString const& type) override; + + virtual mozilla::ipc::IPCResult RecvCrossProcessRedirect( + const uint32_t& aRegistrarId, + nsIURI* aURI, + const uint32_t& aNewLoadFlags, + const OptionalLoadInfoArgs& aLoadInfoForwarder, + const uint64_t& aChannelId, + nsIURI* aOriginalURI, + const uint64_t& aIdentifier) override; }; /** diff --git a/netwerk/ipc/PNecko.ipdl b/netwerk/ipc/PNecko.ipdl index 7ddf9d7afe74..175da26c24e2 100644 --- a/netwerk/ipc/PNecko.ipdl +++ b/netwerk/ipc/PNecko.ipdl @@ -37,6 +37,7 @@ using class IPC::SerializedLoadContext from "SerializedLoadContext.h"; using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h"; using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h"; using refcounted class nsIInputStream from "mozilla/ipc/IPCStreamUtils.h"; +using refcounted class nsIURI from "mozilla/ipc/URIUtils.h"; namespace mozilla { namespace net { @@ -153,6 +154,17 @@ child: async PTransportProvider(); + // This message is sent to PNecko and triggers the creation of a new + // HttpChannelChild that will be connected to the parent channel represented + // by registrarId. + async CrossProcessRedirect(uint32_t aRegistrarId, + nsIURI aURI, + uint32_t aNewLoadFlags, + OptionalLoadInfoArgs aLoadInfo, + uint64_t aChannelId, + nsIURI aOriginalURI, + uint64_t aIdentifier); + both: // Actually we need PTCPSocket() for parent. But ipdl disallows us having different // signatures on parent and child. So when constructing the parent side object, we just diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp index 26156458cac6..5b29489914e9 100644 --- a/netwerk/protocol/http/HttpChannelChild.cpp +++ b/netwerk/protocol/http/HttpChannelChild.cpp @@ -297,6 +297,7 @@ NS_INTERFACE_MAP_BEGIN(HttpChannelChild) NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAssociatedContentSecurity, GetAssociatedContentSecurity()) NS_INTERFACE_MAP_ENTRY(nsIDivertableChannel) NS_INTERFACE_MAP_ENTRY(nsIThreadRetargetableRequest) + NS_INTERFACE_MAP_ENTRY_CONCRETE(HttpChannelChild) NS_INTERFACE_MAP_END_INHERITING(HttpBaseChannel) //----------------------------------------------------------------------------- @@ -2159,6 +2160,13 @@ HttpChannelChild::Redirect3Complete(OverrideRunnable* aRunnable) return false; } +mozilla::ipc::IPCResult +HttpChannelChild::RecvCancelRedirected() +{ + CleanupRedirectingChannel(NS_BINDING_REDIRECTED); + return IPC_OK(); +} + void HttpChannelChild::CleanupRedirectingChannel(nsresult rv) { @@ -4126,5 +4134,15 @@ HttpChannelChild::MaybeCallSynthesizedCallback() mSynthesizedCallback = nullptr; } +nsresult +HttpChannelChild::CrossProcessRedirectFinished(nsresult aStatus) +{ + if (!mIPCOpen) { + return NS_BINDING_FAILED; + } + Unused << SendCrossProcessRedirectDone(aStatus); + return NS_OK; +} + } // namespace net } // namespace mozilla diff --git a/netwerk/protocol/http/HttpChannelChild.h b/netwerk/protocol/http/HttpChannelChild.h index 6907b294e332..b02104112e95 100644 --- a/netwerk/protocol/http/HttpChannelChild.h +++ b/netwerk/protocol/http/HttpChannelChild.h @@ -41,6 +41,10 @@ class nsIEventTarget; class nsInputStreamPump; class nsIInterceptedBodyCallback; +#define HTTP_CHANNEL_CHILD_IID \ +{ 0x321bd99e, 0x2242, 0x4dc6, \ + { 0xbb, 0xec, 0xd5, 0x06, 0x29, 0x7c, 0x39, 0x83 } } + namespace mozilla { namespace net { @@ -76,6 +80,7 @@ public: NS_DECL_NSIHTTPCHANNELCHILD NS_DECL_NSIDIVERTABLECHANNEL NS_DECL_NSITHREADRETARGETABLEREQUEST + NS_DECLARE_STATIC_IID_ACCESSOR(HTTP_CHANNEL_CHILD_IID) HttpChannelChild(); @@ -127,6 +132,8 @@ public: // Callback while background channel is destroyed. void OnBackgroundChildDestroyed(HttpBackgroundChannelChild* aBgChild); + nsresult CrossProcessRedirectFinished(nsresult aStatus); + protected: mozilla::ipc::IPCResult RecvOnStartRequest(const nsresult& channelStatus, const nsHttpResponseHead& responseHead, @@ -176,6 +183,8 @@ protected: mozilla::ipc::IPCResult RecvCancelDiversion() override; + mozilla::ipc::IPCResult RecvCancelRedirected() override; + virtual void ActorDestroy(ActorDestroyReason aWhy) override; MOZ_MUST_USE bool @@ -517,6 +526,9 @@ private: friend class NeckoTargetChannelEvent; }; +NS_DEFINE_STATIC_IID_ACCESSOR(HttpChannelChild, + HTTP_CHANNEL_CHILD_IID) + // A stream listener interposed between the nsInputStreamPump used for intercepted channels // and this channel's original listener. This is only used to ensure the original listener // sees the channel as the request object, and to synthesize OnStatus and OnProgress notifications. diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp index 58b528cce800..d3b0a25da276 100644 --- a/netwerk/protocol/http/HttpChannelParent.cpp +++ b/netwerk/protocol/http/HttpChannelParent.cpp @@ -83,6 +83,7 @@ HttpChannelParent::HttpChannelParent(const PBrowserOrId& iframeEmbedding, , mCacheNeedFlowControlInitialized(false) , mNeedFlowControl(true) , mSuspendedForFlowControl(false) + , mDoingCrossProcessRedirect(false) { LOG(("Creating HttpChannelParent [this=%p]\n", this)); @@ -313,7 +314,8 @@ NS_IMETHODIMP HttpChannelParent::GetInterface(const nsIID& aIID, void **result) { if (aIID.Equals(NS_GET_IID(nsIAuthPromptProvider)) || - aIID.Equals(NS_GET_IID(nsISecureBrowserUI))) { + aIID.Equals(NS_GET_IID(nsISecureBrowserUI)) || + aIID.Equals(NS_GET_IID(nsITabParent))) { if (mTabParent) { return mTabParent->QueryInterface(aIID, result); } @@ -1322,6 +1324,45 @@ HttpChannelParent::MaybeFlushPendingDiversion() } +static void +FinishCrossProcessRedirect(nsHttpChannel *channel, nsresult status) +{ + if (NS_SUCCEEDED(status)) { + nsCOMPtr controller; + NS_QueryNotificationCallbacks(channel, controller); + RefPtr parentListener = do_QueryObject(controller); + MOZ_ASSERT(parentListener); + + // This updates HttpChannelParentListener to point to this parent and at + // the same time cancels the old channel. + parentListener->OnRedirectResult(status == NS_OK); + } + + channel->OnRedirectVerifyCallback(status); +} + +mozilla::ipc::IPCResult +HttpChannelParent::RecvCrossProcessRedirectDone(const nsresult& aResult) +{ + RefPtr chan = do_QueryObject(mChannel); + if (!mBgParent) { + RefPtr promise = WaitForBgParent(); + RefPtr self = this; + promise->Then(GetMainThreadSerialEventTarget(), __func__, + [self, chan, aResult]() { + FinishCrossProcessRedirect(chan, aResult); + }, + [self, chan](const nsresult& aRejectionRv) { + MOZ_ASSERT(NS_FAILED(aRejectionRv), "This should be an error code"); + FinishCrossProcessRedirect(chan, aRejectionRv); + }); + } else { + FinishCrossProcessRedirect(chan, aResult); + } + + return IPC_OK(); +} + void HttpChannelParent::ResponseSynthesized() { @@ -2003,6 +2044,15 @@ HttpChannelParent::CompleteRedirect(bool succeeded) LOG(("HttpChannelParent::CompleteRedirect [this=%p succeeded=%d]\n", this, succeeded)); + // The channel was redirected to another process, and the channel parent + // is about to be deleted. We send a CancelRedirected message in order to + // inform the listener that this child is going away. + if (mDoingCrossProcessRedirect && !mIPCClosed) { + MOZ_ASSERT(!mRedirectChannel); + Unused << SendCancelRedirected(); + return NS_OK; + } + // If this was an internal redirect for a service worker interception then // we will not have a redirecting channel here. Hide this redirect from // the child. @@ -2421,7 +2471,7 @@ HttpChannelParent::IssueWarning(uint32_t aWarning, bool aAsError) NS_IMETHODIMP HttpChannelParent::ReadyToVerify(nsresult aResult) { - LOG(("HttpChannelParent::RecvRedirect2Verify [this=%p result=%" PRIx32 "]\n", + LOG(("HttpChannelParent::ReadyToVerify [this=%p result=%" PRIx32 "]\n", this, static_cast(aResult))); MOZ_ASSERT(NS_IsMainThread()); diff --git a/netwerk/protocol/http/HttpChannelParent.h b/netwerk/protocol/http/HttpChannelParent.h index 8cc32537302b..013e770292a4 100644 --- a/netwerk/protocol/http/HttpChannelParent.h +++ b/netwerk/protocol/http/HttpChannelParent.h @@ -123,6 +123,8 @@ public: base::ProcessId OtherPid() const override; + void SetCrossProcessRedirect() { mDoingCrossProcessRedirect = true; } + protected: // used to connect redirected-to channel in parent with just created // ChildChannel. Used during redirects. @@ -207,6 +209,7 @@ protected: const uint32_t& count) override; virtual mozilla::ipc::IPCResult RecvDivertOnStopRequest(const nsresult& statusCode) override; virtual mozilla::ipc::IPCResult RecvDivertComplete() override; + virtual mozilla::ipc::IPCResult RecvCrossProcessRedirectDone(const nsresult& aResult) override; virtual mozilla::ipc::IPCResult RecvRemoveCorsPreflightCacheEntry(const URIParams& uri, const mozilla::ipc::PrincipalInfo& requestingPrincipal) override; virtual mozilla::ipc::IPCResult RecvBytesRead(const int32_t& aCount) override; @@ -340,6 +343,7 @@ private: uint8_t mCacheNeedFlowControlInitialized : 1; uint8_t mNeedFlowControl : 1; uint8_t mSuspendedForFlowControl : 1; + uint8_t mDoingCrossProcessRedirect : 1; // Number of events to wait before actually invoking AsyncOpen on the main // channel. For each asynchronous step required before InvokeAsyncOpen, should diff --git a/netwerk/protocol/http/HttpChannelParentListener.cpp b/netwerk/protocol/http/HttpChannelParentListener.cpp index 0ab01cb98887..e4278d2db8d5 100644 --- a/netwerk/protocol/http/HttpChannelParentListener.cpp +++ b/netwerk/protocol/http/HttpChannelParentListener.cpp @@ -11,15 +11,18 @@ #include "mozilla/dom/ServiceWorkerInterceptController.h" #include "mozilla/dom/ServiceWorkerUtils.h" #include "mozilla/net/HttpChannelParent.h" +#include "mozilla/net/RedirectChannelRegistrar.h" #include "mozilla/Unused.h" #include "nsIAuthPrompt.h" #include "nsIAuthPrompt2.h" #include "nsIHttpHeaderVisitor.h" -#include "mozilla/net/RedirectChannelRegistrar.h" +#include "nsIRedirectProcessChooser.h" +#include "nsITabParent.h" #include "nsIPromptFactory.h" #include "nsIWindowWatcher.h" #include "nsQueryObject.h" + using mozilla::Unused; using mozilla::dom::ServiceWorkerInterceptController; using mozilla::dom::ServiceWorkerParentInterceptEnabled; @@ -156,16 +159,86 @@ HttpChannelParentListener::GetInterface(const nsIID& aIID, void **result) //----------------------------------------------------------------------------- // HttpChannelParentListener::nsIChannelEventSink //----------------------------------------------------------------------------- +nsresult +HttpChannelParentListener::TriggerCrossProcessRedirect(nsIChannel *aChannel, + nsILoadInfo *aLoadInfo, + uint64_t aIdentifier) +{ + RefPtr channelParent = do_QueryObject(mNextListener); + MOZ_ASSERT(channelParent); + channelParent->SetCrossProcessRedirect(); + + nsCOMPtr channel = aChannel; + RefPtr httpChannel = do_QueryObject(channel); + RefPtr p = httpChannel->TakeRedirectTabPromise(); + nsCOMPtr loadInfo = aLoadInfo; + + RefPtr self = this; + p->Then(GetMainThreadSerialEventTarget(), __func__, + [=](nsCOMPtr tp) { + nsresult rv; + + // Register the new channel and obtain id for it + nsCOMPtr registrar = + RedirectChannelRegistrar::GetOrCreate(); + MOZ_ASSERT(registrar); + rv = registrar->RegisterChannel(channel, &self->mRedirectChannelId); + NS_ENSURE_SUCCESS(rv, rv); + + LOG(("Registered %p channel under id=%d", channel.get(), self->mRedirectChannelId)); + + OptionalLoadInfoArgs loadInfoArgs; + MOZ_ALWAYS_SUCCEEDS(LoadInfoToLoadInfoArgs(loadInfo, &loadInfoArgs)); + + uint32_t newLoadFlags = nsIRequest::LOAD_NORMAL; + MOZ_ALWAYS_SUCCEEDS(channel->GetLoadFlags(&newLoadFlags)); + + nsCOMPtr uri; + channel->GetURI(getter_AddRefs(uri)); + + nsCOMPtr originalURI; + channel->GetOriginalURI(getter_AddRefs(originalURI)); + + uint64_t channelId; + MOZ_ALWAYS_SUCCEEDS(httpChannel->GetChannelId(&channelId)); + + dom::TabParent* tabParent = dom::TabParent::GetFrom(tp); + ContentParent* cp = tabParent->Manager()->AsContentParent(); + PNeckoParent* neckoParent = SingleManagedOrNull(cp->ManagedPNeckoParent()); + + RefPtr channelParent = do_QueryObject(self->mNextListener); + MOZ_ASSERT(channelParent); + channelParent->SetCrossProcessRedirect(); + + auto result = neckoParent->SendCrossProcessRedirect(self->mRedirectChannelId, + uri, + newLoadFlags, + loadInfoArgs, + channelId, + originalURI, + aIdentifier); + + MOZ_ASSERT(result, "SendCrossProcessRedirect failed"); + + return NS_OK; + }, + [httpChannel](nsresult aStatus) { + MOZ_ASSERT(NS_FAILED(aStatus), "Status should be error"); + httpChannel->OnRedirectVerifyCallback(aStatus); + }); + + return NS_OK; +} NS_IMETHODIMP HttpChannelParentListener::AsyncOnChannelRedirect( - nsIChannel *oldChannel, - nsIChannel *newChannel, - uint32_t redirectFlags, - nsIAsyncVerifyRedirectCallback* callback) + nsIChannel *aOldChannel, + nsIChannel *aNewChannel, + uint32_t aRedirectFlags, + nsIAsyncVerifyRedirectCallback* aCallback) { LOG(("HttpChannelParentListener::AsyncOnChannelRedirect [this=%p, old=%p, new=%p, flags=%u]", - this, oldChannel, newChannel, redirectFlags)); + this, aOldChannel, aNewChannel, aRedirectFlags)); nsresult rv; @@ -182,15 +255,15 @@ HttpChannelParentListener::AsyncOnChannelRedirect( RedirectChannelRegistrar::GetOrCreate(); MOZ_ASSERT(registrar); - rv = registrar->RegisterChannel(newChannel, &mRedirectChannelId); + rv = registrar->RegisterChannel(aNewChannel, &mRedirectChannelId); NS_ENSURE_SUCCESS(rv, rv); - LOG(("Registered %p channel under id=%d", newChannel, mRedirectChannelId)); + LOG(("Registered %p channel under id=%d", aNewChannel, mRedirectChannelId)); return activeRedirectingChannel->StartRedirect(mRedirectChannelId, - newChannel, - redirectFlags, - callback); + aNewChannel, + aRedirectFlags, + aCallback); } //----------------------------------------------------------------------------- diff --git a/netwerk/protocol/http/HttpChannelParentListener.h b/netwerk/protocol/http/HttpChannelParentListener.h index c6dc5a785e93..5fd5041e7ace 100644 --- a/netwerk/protocol/http/HttpChannelParentListener.h +++ b/netwerk/protocol/http/HttpChannelParentListener.h @@ -54,6 +54,10 @@ public: void SetupInterceptionAfterRedirect(bool aShouldIntercept); void ClearInterceptedChannel(nsIStreamListener* aListener); + nsresult TriggerCrossProcessRedirect(nsIChannel *oldChannel, + nsILoadInfo *aLoadInfo, + uint64_t aIdentifier); + private: virtual ~HttpChannelParentListener() = default; diff --git a/netwerk/protocol/http/PHttpChannel.ipdl b/netwerk/protocol/http/PHttpChannel.ipdl index f6698e9420d7..76d287b6f859 100644 --- a/netwerk/protocol/http/PHttpChannel.ipdl +++ b/netwerk/protocol/http/PHttpChannel.ipdl @@ -51,6 +51,10 @@ parent: OptionalCorsPreflightArgs corsPreflightArgs, bool chooseAppcache); + // Sent to the parent in order signal that the child side listeners have been + // set up and the parent side of the channel can be opened. + async CrossProcessRedirectDone(nsresult result); + // For document loads we keep this protocol open after child's // OnStopRequest, and send this msg (instead of __delete__) to allow // partial cleanup on parent. @@ -146,6 +150,11 @@ child: // channel. async ReportSecurityMessage(nsString messageTag, nsString messageCategory); + // This message is sent to a child that has been redirected to another process. + // As a consequence, it should cleanup the channel listeners and remove the + // request from the loadGroup. + async CancelRedirected(); + // Tell child to delete channel (all IPDL deletes must be done from child to // avoid races: see bug 591708). async DeleteSelf(); diff --git a/netwerk/protocol/http/moz.build b/netwerk/protocol/http/moz.build index e02c78ff1f3a..20dffb5967ea 100644 --- a/netwerk/protocol/http/moz.build +++ b/netwerk/protocol/http/moz.build @@ -20,6 +20,7 @@ XPIDL_SOURCES += [ 'nsIHttpHeaderVisitor.idl', 'nsIHttpProtocolHandler.idl', 'nsIRaceCacheWithNetwork.idl', + 'nsIRedirectProcessChooser.idl', 'nsIWellKnownOpportunisticUtils.idl', ] diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index 3d4c506cdfeb..af78f92bef46 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -116,6 +116,8 @@ #include "nsIMultiplexInputStream.h" #include "../../cache2/CacheFileUtils.h" #include "nsINetworkLinkService.h" +#include "mozilla/dom/PromiseNativeHandler.h" +#include "mozilla/dom/Promise.h" #ifdef MOZ_TASK_TRACER #include "GeckoTaskTracer.h" @@ -7103,6 +7105,77 @@ nsHttpChannel::GetRequestMethod(nsACString& aMethod) // nsHttpChannel::nsIRequestObserver //----------------------------------------------------------------------------- +// This class is used to convert from a DOM promise to a MozPromise. +// Once we have a native implementation of nsIRedirectProcessChooser we can +// remove it and use MozPromises directly. +class DomPromiseListener final + : dom::PromiseNativeHandler +{ + NS_DECL_ISUPPORTS + + static RefPtr + Create(dom::Promise* aDOMPromise) + { + MOZ_ASSERT(aDOMPromise); + RefPtr handler = new DomPromiseListener(); + RefPtr promise = handler->mPromiseHolder.Ensure(__func__); + aDOMPromise->AppendNativeHandler(handler); + return promise; + } + + virtual void + ResolvedCallback(JSContext* aCx, JS::Handle aValue) override + { + nsCOMPtr tabParent; + JS::Rooted obj(aCx, &aValue.toObject()); + nsresult rv = UnwrapArg(aCx, obj, getter_AddRefs(tabParent)); + if (NS_FAILED(rv)) { + mPromiseHolder.Reject(rv, __func__); + return; + } + mPromiseHolder.Resolve(tabParent, __func__); + } + + virtual void + RejectedCallback(JSContext* aCx, JS::Handle aValue) override + { + if (!aValue.isInt32()) { + mPromiseHolder.Reject(NS_ERROR_DOM_NOT_NUMBER_ERR, __func__); + return; + } + mPromiseHolder.Reject((nsresult) aValue.toInt32(), __func__); + } + +private: + DomPromiseListener() = default; + ~DomPromiseListener() = default; + MozPromiseHolder mPromiseHolder; +}; + +NS_IMPL_ISUPPORTS0(DomPromiseListener) + +nsresult +nsHttpChannel::StartCrossProcessRedirect() +{ + nsresult rv = CheckRedirectLimit(nsIChannelEventSink::REDIRECT_INTERNAL); + NS_ENSURE_SUCCESS(rv, rv); + + RefPtr listener = do_QueryObject(mCallbacks); + MOZ_ASSERT(listener); + + nsCOMPtr redirectLoadInfo = + CloneLoadInfoForRedirect(mURI, nsIChannelEventSink::REDIRECT_INTERNAL); + + listener->TriggerCrossProcessRedirect(this, + redirectLoadInfo, + mCrossProcessRedirectIdentifier); + + // This will suspend the channel + rv = WaitForRedirectCallback(); + + return rv; +} + NS_IMETHODIMP nsHttpChannel::OnStartRequest(nsIRequest *request, nsISupports *ctxt) { @@ -7208,6 +7281,32 @@ nsHttpChannel::OnStartRequest(nsIRequest *request, nsISupports *ctxt) return NS_OK; } + // Check if the channel should be redirected to another process. + // If so, trigger a redirect, and the HttpChannelParentListener will + // redirect to the correct process + nsCOMPtr requestChooser = + do_GetClassObject("@mozilla.org/network/processChooser"); + if (requestChooser) { + nsCOMPtr tp; + nsCOMPtr parentChannel; + NS_QueryNotificationCallbacks(this, parentChannel); + + RefPtr tabPromise; + rv = requestChooser->GetChannelRedirectTarget(this, parentChannel, &mCrossProcessRedirectIdentifier, getter_AddRefs(tabPromise)); + + if (NS_SUCCEEDED(rv) && tabPromise) { + // The promise will be handled in AsyncOnChannelRedirect. + mRedirectTabPromise = DomPromiseListener::Create(tabPromise); + + PushRedirectAsyncFunc(&nsHttpChannel::ContinueOnStartRequest3); + rv = StartCrossProcessRedirect(); + if (NS_SUCCEEDED(rv)) { + return NS_OK; + } + PopRedirectAsyncFunc(&nsHttpChannel::ContinueOnStartRequest3); + } + } + // avoid crashing if mListener happens to be null... if (!mListener) { MOZ_ASSERT_UNREACHABLE("mListener is null"); diff --git a/netwerk/protocol/http/nsHttpChannel.h b/netwerk/protocol/http/nsHttpChannel.h index 32eadd0bbd64..af47e2d31b18 100644 --- a/netwerk/protocol/http/nsHttpChannel.h +++ b/netwerk/protocol/http/nsHttpChannel.h @@ -32,6 +32,7 @@ #include "nsIRaceCacheWithNetwork.h" #include "mozilla/extensions/PStreamFilterParent.h" #include "mozilla/Mutex.h" +#include "nsITabParent.h" class nsDNSPrefetch; class nsICancelable; @@ -278,6 +279,10 @@ public: void SetTransactionObserver(TransactionObserver *arg) { mTransactionObserver = arg; } TransactionObserver *GetTransactionObserver() { return mTransactionObserver; } + typedef MozPromise, nsresult, false> TabPromise; + already_AddRefed TakeRedirectTabPromise() { return mRedirectTabPromise.forget(); } + uint64_t CrossProcessRedirectIdentifier() { return mCrossProcessRedirectIdentifier; } + protected: virtual ~nsHttpChannel(); @@ -347,6 +352,7 @@ private: virtual MOZ_MUST_USE nsresult SetupReplacementChannel(nsIURI *, nsIChannel *, bool preserveMethod, uint32_t redirectFlags) override; + nsresult StartCrossProcessRedirect(); // proxy specific methods MOZ_MUST_USE nsresult ProxyFailover(); @@ -507,6 +513,12 @@ private: nsCOMPtr mRedirectChannel; nsCOMPtr mPreflightChannel; + // The associated childChannel is getting relocated to another process. + // This promise will be resolved when that process is set up. + RefPtr mRedirectTabPromise; + // This identifier is passed to the childChannel in order to identify it. + uint64_t mCrossProcessRedirectIdentifier = 0; + // nsChannelClassifier checks this channel's URI against // the URI classifier service. // nsChannelClassifier will be invoked twice in InitLocalBlockList() and diff --git a/netwerk/protocol/http/nsIRedirectProcessChooser.idl b/netwerk/protocol/http/nsIRedirectProcessChooser.idl new file mode 100644 index 000000000000..9047dc3e53fc --- /dev/null +++ b/netwerk/protocol/http/nsIRedirectProcessChooser.idl @@ -0,0 +1,45 @@ +/* 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 "nsISupports.idl" + +interface nsIRequest; +interface nsITabParent; +interface nsIChannel; +interface nsIParentChannel; +interface nsIChildChannel; + +[scriptable, uuid(cd7166de-e221-485f-8172-f1d05f97c6a8)] +interface nsIRedirectProcessChooser : nsISupports +{ + /** + * @param aChannel - channel which may need to be redirected to other process. + * @param aParentChannel - parent channel associated with aChannel; + * may be null when aChannel is main process only. + * @param aIdentifier - returned by the process chooser when a decision is + * made to redirect the channel. The identifier is used + * to track the new channel in the other process. + * @return - promise that resolves with a nsITabParent or rejects with nsresult. + * @throws NS_ERROR_NOT_AVAILABLE when redirection is not necessary. + */ + Promise getChannelRedirectTarget(in nsIChannel aChannel, + in nsIParentChannel aParentChannel, + inout unsigned long long aIdentifier); +}; + +[scriptable, uuid(50af805f-e4db-40d9-9dd8-1ae9ab12bdc2)] +interface nsIChildProcessChannelListener : nsISupports +{ + /** + * @param aChildChannel - new child channel + * @param aIdentifier - returned by call to getChannelRedirectTarget. Used to + identify the new channel. + * + * This method has to call aChildChannel->completeRedirectSetup(listener, context) + * in order to be ready for content; listener is a class that implements + * nsIStreamListener. + */ + void onChannelReady(in nsIChildChannel aChildChannel, in unsigned long long aIdentifier); +}; + diff --git a/netwerk/test/browser/browser.ini b/netwerk/test/browser/browser.ini index ad53f17fe91b..6eb2acdebd52 100644 --- a/netwerk/test/browser/browser.ini +++ b/netwerk/test/browser/browser.ini @@ -2,6 +2,7 @@ support-files = dummy.html ioactivity.html + redirect.sjs [browser_about_cache.js] [browser_NetUtil.js] @@ -13,3 +14,4 @@ skip-if = e10s # protocol handler and channel does not work in content process [browser_resource_navigation.js] [browser_test_io_activity.js] [browser_cookie_sync_across_tabs.js] +[browser_cross_process_redirect.js] diff --git a/netwerk/test/browser/browser_cross_process_redirect.js b/netwerk/test/browser/browser_cross_process_redirect.js new file mode 100644 index 000000000000..1d8e4d46ec71 --- /dev/null +++ b/netwerk/test/browser/browser_cross_process_redirect.js @@ -0,0 +1,210 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +"use strict"; + +const gRegistrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); + +let gLoadedInProcess2Promise = null; + +function _createProcessChooser(tabParent, from, to, rejectPromise = false) { + let processChooser = new ProcessChooser(tabParent, "example.com", "example.org", rejectPromise); + processChooser.onComplete = () => { + gRegistrar.unregisterFactory(processChooser.classID, processChooser); + }; + gRegistrar.registerFactory(processChooser.classID, "", + "@mozilla.org/network/processChooser", + processChooser); + registerCleanupFunction(function() { + if (processChooser.onComplete) { + processChooser.onComplete(); + } + }); +} + +function ProcessChooser(tabParent, from, to, rejectPromise = false) { + this.tabParent = tabParent; + this.fromDomain = from; + this.toDomain = to; + this.rejectPromise = rejectPromise; +} + +ProcessChooser.prototype = { + // nsIRedirectProcessChooser + getChannelRedirectTarget: function(aChannel, aParentChannel, aIdentifier) { + // Don't report failure when returning NS_ERROR_NOT_AVAILABLE + expectUncaughtException(true); + + // let tabParent = aParentChannel.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsITabParent); + if (this.channel && this.channel != aChannel) { + // Hack: this is just so we don't get redirected multiple times. + info("same channel. give null"); + throw Cr.NS_ERROR_NOT_AVAILABLE; + } + + if (aChannel.URI.host != this.toDomain) { + info("wrong host for channel " + aChannel.URI.host); + throw Cr.NS_ERROR_NOT_AVAILABLE; + } + + let redirects = aChannel.loadInfo.redirectChain; + if (redirects[redirects.length - 1].principal.URI.host != this.fromDomain) { + info("didn't find redirect"); + throw Cr.NS_ERROR_NOT_AVAILABLE; + } + + info("returning promise"); + this.channel = aChannel; + let self = this; + + expectUncaughtException(false); + if (this.onComplete) { + this.onComplete(); + this.onComplete = null; + } + aIdentifier.value = 42; + return new Promise((resolve, reject) => { + if (self.rejectPromise) { + info("rejecting"); + reject(Cr.NS_ERROR_NOT_AVAILABLE); + return; + } + // Can asyncly create a tab, or can resolve with a tab that was + // previously created. + info("resolving"); + resolve(self.tabParent); + }); + }, + + // nsIFactory + createInstance: function(aOuter, aIID) { + if (aOuter) { + throw Cr.NS_ERROR_NO_AGGREGATION; + } + return this.QueryInterface(aIID); + }, + lockFactory: function() {}, + + // nsISupports + QueryInterface: ChromeUtils.generateQI([Ci.nsIRedirectProcessChooser, Ci.nsIFactory]), + classID: Components.ID("{62561fa8-c091-4c9f-8897-b59ae18b0979}") +} + +add_task(async function() { + info("Check that a redirect in process A may be correctly handled in process B"); + + const kRoot1 = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", + "https://example.com/"); + const kRoot2 = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", + "https://example.org/"); + const kRoot3 = getRootDirectory(gTestPath); + + // This process will attempt to load the page that redirects to a different origin + let tab1 = await BrowserTestUtils.openNewForegroundTab({ gBrowser, url: kRoot1 + "dummy.html", forceNewProcess: true }); + // This process will eventually receive the redirected channel. + let tab2 = await BrowserTestUtils.openNewForegroundTab({ gBrowser, url: kRoot2 + "dummy.html", forceNewProcess: true }); + + let browser1 = gBrowser.getBrowserForTab(tab1); + let browser2 = gBrowser.getBrowserForTab(tab2); + + // This is for testing purposes only. + // This "process chooser" will direct the channel to be opened in the second + // tab, and thus in the second parent. + let processChooser = _createProcessChooser(browser2.frameLoader.tabParent, "example.com", "example.org"); + + info("Loading redirected URL"); + // Open the URL in the first process. We expect it to wind up in the second + // process. + + // Define the child listener in the new channel. + await ContentTask.spawn(browser2, null, async function(arg) { + function ChannelListener(childListener) { this.childListener = childListener; } + ChannelListener.prototype = { + onStartRequest: function(aRequest, aContext) { + info("onStartRequest"); + let channel = aRequest.QueryInterface(Ci.nsIChannel); + Assert.equal(channel.URI.spec, this.childListener.URI, "Make sure the channel has the proper URI"); + Assert.equal(channel.originalURI.spec, this.childListener.originalURI, "Make sure the originalURI is correct"); + }, + onStopRequest: function(aRequest, aContext, aStatusCode) { + info("onStopRequest"); + Assert.equal(aStatusCode, Cr.NS_OK, "Check the status code"); + Assert.equal(this.gotData, true, "Check that the channel received data"); + if (this.childListener.onComplete) { + this.childListener.onComplete(); + } + this.childListener.resolve(); + }, + onDataAvailable: function(aRequest, aContext, aInputStream, + aOffset, aCount) { + this.gotData = true; + info("onDataAvailable"); + }, + QueryInterface: ChromeUtils.generateQI([Ci.nsIStreamListener, + Ci.nsIRequestObserver]) + }; + + function ChildListener(uri, originalURI, resolve) { this.URI = uri; this.originalURI = originalURI; this.resolve = resolve;} + ChildListener.prototype = { + // nsIChildProcessChannelListener + onChannelReady: function(aChildChannel, aIdentifier) { + Assert.equal(aIdentifier, 42, "Check the status code"); + info("onChannelReady"); + aChildChannel.completeRedirectSetup(new ChannelListener(this), null); + }, + // nsIFactory + createInstance: function(aOuter, aIID) { + if (aOuter) { + throw Cr.NS_ERROR_NO_AGGREGATION; + } + return this.QueryInterface(aIID); + }, + lockFactory: function() {}, + // nsISupports + QueryInterface: ChromeUtils.generateQI([Ci.nsIChildProcessChannelListener, Ci.nsIFactory]), + classID: Components.ID("{a6c142a9-eb38-4a09-a940-b71cdad479e1}") + } + + content.window.ChildListener = ChildListener; + }); + + // This promise instantiates a ChildListener and is resolved when the redirected + // channel is completed. + let loadedInProcess2Promise = ContentTask.spawn(browser2, { URI: kRoot2 + "dummy.html", originalURI: kRoot1 + "redirect.sjs?" + kRoot2 + "dummy.html"}, async function(arg) { + // We register the listener in process no. 2 + return new Promise(resolve => { + var childListener = new content.window.ChildListener(arg.URI, arg.originalURI, resolve); + var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); + childListener.onComplete = () => { + registrar.unregisterFactory(childListener.classID, childListener); + } + registrar.registerFactory(childListener.classID, "", + "@mozilla.org/network/childProcessChannelListener", + childListener); + }); + }); + + let browser1LoadHasStopped = BrowserTestUtils.browserStopped(browser1); + + await BrowserTestUtils.loadURI(browser1, kRoot1 + "redirect.sjs?" + kRoot2 + "dummy.html"); + + // Check that the channel was delivered to process no. 2 + await loadedInProcess2Promise; + info("channel has loaded in second process"); + // This is to check that the old channel was cancelled. + await browser1LoadHasStopped; + + // check that a rejected promise also works. + processChooser = _createProcessChooser(browser2.frameLoader.tabParent, "example.com", "example.org", true); + let browser1LoadHasStoppedAgain = BrowserTestUtils.browserStopped(browser1); + await BrowserTestUtils.loadURI(browser1, kRoot1 + "redirect.sjs?" + kRoot2 + "dummy.html"); + await browser1LoadHasStoppedAgain; + info("this is done now"); + + BrowserTestUtils.removeTab(tab1); + BrowserTestUtils.removeTab(tab2); + + ok(true, "Got to the end of the test!"); +}); diff --git a/netwerk/test/browser/redirect.sjs b/netwerk/test/browser/redirect.sjs new file mode 100644 index 000000000000..7599fe33fb50 --- /dev/null +++ b/netwerk/test/browser/redirect.sjs @@ -0,0 +1,7 @@ +function handleRequest(request, response) +{ + response.setStatusLine(request.httpVersion, 301, "Moved Permanently"); + let location = request.queryString; + response.setHeader("Location", location, false); + response.write("Hello world!"); +} From dd951567399dc37ecf5f81c7f11303fe0cae85b3 Mon Sep 17 00:00:00 2001 From: Bogdan Tara Date: Tue, 4 Sep 2018 20:16:21 +0300 Subject: [PATCH 38/61] Backed out changeset b886f2cf9d89 (bug 1451527) for eslint failure on extensions/tps/api.js:34 CLOSED TREE --- services/sync/tps/extensions/tps/api.js | 72 ------------ services/sync/tps/extensions/tps/bootstrap.js | 104 ++++++++++++++++++ services/sync/tps/extensions/tps/install.rdf | 30 +++++ .../sync/tps/extensions/tps/manifest.json | 23 ---- .../tps/resource/auth/fxaccounts.jsm | 2 +- .../tps/resource/modules/formautofill.jsm | 8 +- services/sync/tps/extensions/tps/schema.json | 1 - testing/tps/tps/phase.py | 21 ++-- testing/tps/tps/testrunner.py | 3 +- 9 files changed, 146 insertions(+), 118 deletions(-) delete mode 100644 services/sync/tps/extensions/tps/api.js create mode 100644 services/sync/tps/extensions/tps/bootstrap.js create mode 100644 services/sync/tps/extensions/tps/install.rdf delete mode 100644 services/sync/tps/extensions/tps/manifest.json delete mode 100644 services/sync/tps/extensions/tps/schema.json diff --git a/services/sync/tps/extensions/tps/api.js b/services/sync/tps/extensions/tps/api.js deleted file mode 100644 index 5e2439fe9fd8..000000000000 --- a/services/sync/tps/extensions/tps/api.js +++ /dev/null @@ -1,72 +0,0 @@ -/* 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/. */ - -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); -ChromeUtils.import("resource://gre/modules/Services.jsm"); -ChromeUtils.import("resource://gre/modules/FileUtils.jsm"); -ChromeUtils.import("resource://gre/modules/Timer.jsm"); - -XPCOMUtils.defineLazyServiceGetter(this, "resProto", - "@mozilla.org/network/protocol;1?name=resource", - "nsISubstitutingProtocolHandler"); - -async function tpsStartup() { - try { - ChromeUtils.import("resource://tps/tps.jsm"); - ChromeUtils.import("resource://tps/quit.js", TPS); - - let testFile = Services.prefs.getStringPref("testing.tps.testFile", ""); - let testPhase = Services.prefs.getStringPref("testing.tps.testPhase", ""); - if (!testFile || !testPhase) { - // Note: this quits. - TPS.DumpError("TPS no longer takes arguments from the command line. " + - "instead you need to pass preferences `testing.tps.{testFile,testPhase}` " + - "and optionally `testing.tps.{logFile,ignoreUnusedEngines}`.\n"); - } - - let logFile = Services.prefs.getStringPref("testing.tps.logFile", ""); - let ignoreUnusedEngines = Services.prefs.getBoolPref("testing.tps.ignoreUnusedEngines", false); - let options = { ignoreUnusedEngines }; - let testFileUri = Services.io.newFileURI(new FileUtils.File(testFile)).spec; - - try { - await TPS.RunTestPhase(testFileUri, testPhase, logFile, options) - } catch (err) { - TPS.DumpError("TestPhase failed", err); - } - } catch (e) { - if (typeof TPS != "undefined") { - // Note: This calls quit() under the hood - TPS.DumpError("Test initialization failed", err); - } - // Try and quit right away, no reason to wait around for python - // to kill us if initialization failed. - Services.startup.quit(Ci.nsIAppStartup.eForceQuit); - } -} - -function onStartupFinished() { - return new Promise(resolve => { - const onStartupFinished = () => { - Services.obs.removeObserver(onStartupFinished, "browser-delayed-startup-finished"); - resolve(); - }; - Services.obs.addObserver(onStartupFinished, "browser-delayed-startup-finished"); - }); -} - -this.tps = class extends ExtensionAPI { - onStartup() { - resProto.setSubstitution("tps", - Services.io.newURI("resource/", null, this.extension.rootURI)); - /* Ignore the platform's online/offline status while running tests. */ - Services.io.manageOfflineStatus = false; - Services.io.offline = false; - tpsStartup(); - } - - onShutdown() { - resProto.setSubstitution("tps", null); - } -}; diff --git a/services/sync/tps/extensions/tps/bootstrap.js b/services/sync/tps/extensions/tps/bootstrap.js new file mode 100644 index 000000000000..7f126d069f8a --- /dev/null +++ b/services/sync/tps/extensions/tps/bootstrap.js @@ -0,0 +1,104 @@ +/* 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/. */ + + +ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); +ChromeUtils.import("resource://gre/modules/Services.jsm"); +ChromeUtils.import("resource://gre/modules/osfile.jsm"); + +XPCOMUtils.defineLazyServiceGetter(this, "resProto", + "@mozilla.org/network/protocol;1?name=resource", + "nsISubstitutingProtocolHandler"); + +const Cm = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); + +const CATMAN_CONTRACTID = "@mozilla.org/categorymanager;1"; + +const CATEGORY_NAME = "command-line-handler"; +const CATEGORY_ENTRY = "m-tps"; + +function TPSCmdLine() {} + +TPSCmdLine.prototype = { + factory: XPCOMUtils._getFactory(TPSCmdLine), + classDescription: "TPSCmdLine", + classID: Components.ID("{4e5bd3f0-41d3-11df-9879-0800200c9a66}"), + contractID: "@mozilla.org/commandlinehandler/general-startup;1?type=tps", + + QueryInterface: ChromeUtils.generateQI([Ci.nsICommandLineHandler]), + + register() { + Cm.registerFactory(this.classID, this.classDescription, + this.contractID, this.factory); + + Services.catMan.addCategoryEntry(CATEGORY_NAME, CATEGORY_ENTRY, + this.contractID, false, true); + }, + + unregister() { + Services.catMan.deleteCategoryEntry(CATEGORY_NAME, CATEGORY_ENTRY, + this.contractID, false); + + Cm.unregisterFactory(this.classID, this.factory); + }, + + /* nsICmdLineHandler */ + commandLineArgument: "-tps", + prefNameForStartup: "general.startup.tps", + helpText: "Run TPS tests with the given test file.", + handlesArgs: true, + defaultArgs: "", + openWindowWithArgs: true, + + /* nsICommandLineHandler */ + handle: function handler_handle(cmdLine) { + let options = {}; + + let uristr = cmdLine.handleFlagWithParam("tps", false); + if (uristr == null) { + return; + } + let phase = cmdLine.handleFlagWithParam("tpsphase", false); + if (phase == null) { + throw Error("must specify --tpsphase with --tps"); + } + let logfile = cmdLine.handleFlagWithParam("tpslogfile", false); + if (logfile == null) { + logfile = ""; + } + + options.ignoreUnusedEngines = cmdLine.handleFlag("ignore-unused-engines", + false); + let uri = cmdLine.resolveURI(OS.Path.normalize(uristr)).spec; + + const onStartupFinished = () => { + Services.obs.removeObserver(onStartupFinished, "browser-delayed-startup-finished"); + /* Ignore the platform's online/offline status while running tests. */ + Services.io.manageOfflineStatus = false; + Services.io.offline = false; + ChromeUtils.import("resource://tps/tps.jsm"); + ChromeUtils.import("resource://tps/quit.js", TPS); + TPS.RunTestPhase(uri, phase, logfile, options).catch(err => TPS.DumpError("TestPhase failed", err)); + }; + Services.obs.addObserver(onStartupFinished, "browser-delayed-startup-finished"); + }, + + helpInfo: " --tps Run TPS tests with the given test file.\n" + + " --tpsphase Run the specified phase in the TPS test.\n" + + " --tpslogfile Logfile for TPS output.\n" + + " --ignore-unused-engines Don't load engines not used in tests.\n", +}; + +function startup(data, reason) { + TPSCmdLine.prototype.register(); + resProto.setSubstitution("tps", Services.io.newURI("resource/", null, data.resourceURI)); +} + +function shutdown(data, reason) { + resProto.setSubstitution("tps", null); + TPSCmdLine.prototype.unregister(); +} + +function install(data, reason) {} +function uninstall(data, reason) {} diff --git a/services/sync/tps/extensions/tps/install.rdf b/services/sync/tps/extensions/tps/install.rdf new file mode 100644 index 000000000000..f9f060af129d --- /dev/null +++ b/services/sync/tps/extensions/tps/install.rdf @@ -0,0 +1,30 @@ + + + + + + tps@mozilla.org + 0.5 + true + + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 24.0.* + * + + + + + TPS + Sync test extension + Jonathan Griffin + Henrik Skupin + https://developer.mozilla.org/en-US/docs/TPS + true + + diff --git a/services/sync/tps/extensions/tps/manifest.json b/services/sync/tps/extensions/tps/manifest.json deleted file mode 100644 index 2de6e902c689..000000000000 --- a/services/sync/tps/extensions/tps/manifest.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "manifest_version": 2, - "name": "TPS", - "version": "1.0", - - "applications": { - "gecko": { - "id": "tps@mozilla.org" - } - }, - - "experiment_apis": { - "tps": { - "schema": "schema.json", - "parent": { - "scopes": ["addon_parent"], - "script": "api.js", - "paths": [["tps"]], - "events": ["startup"] - } - } - } -} diff --git a/services/sync/tps/extensions/tps/resource/auth/fxaccounts.jsm b/services/sync/tps/extensions/tps/resource/auth/fxaccounts.jsm index aff0ec141ab9..0f58459a8586 100644 --- a/services/sync/tps/extensions/tps/resource/auth/fxaccounts.jsm +++ b/services/sync/tps/extensions/tps/resource/auth/fxaccounts.jsm @@ -64,7 +64,7 @@ var Authentication = { async _openVerificationPage(uri) { let mainWindow = Services.wm.getMostRecentWindow("navigator:browser"); - let newtab = mainWindow.getBrowser().addWebTab(uri); + let newtab = mainWindow.getBrowser().addTab(uri); let win = mainWindow.getBrowser().getBrowserForTab(newtab); await new Promise(resolve => { win.addEventListener("loadend", resolve, { once: true }); diff --git a/services/sync/tps/extensions/tps/resource/modules/formautofill.jsm b/services/sync/tps/extensions/tps/resource/modules/formautofill.jsm index 60a022159b2b..23feb3f8027d 100644 --- a/services/sync/tps/extensions/tps/resource/modules/formautofill.jsm +++ b/services/sync/tps/extensions/tps/resource/modules/formautofill.jsm @@ -10,12 +10,8 @@ var EXPORTED_SYMBOLS = ["Address", "CreditCard", "DumpAddresses", "DumpCreditCards"]; ChromeUtils.import("resource://tps/logger.jsm"); - -ChromeUtils.defineModuleGetter(this, "formAutofillStorage", - "resource://formautofill/FormAutofillStorage.jsm"); - -ChromeUtils.defineModuleGetter(this, "MasterPassword", - "resource://formautofill/MasterPassword.jsm"); +ChromeUtils.import("resource://formautofill/FormAutofillStorage.jsm"); +ChromeUtils.import("resource://formautofill/MasterPassword.jsm"); class FormAutofillBase { constructor(props, subStorageName, fields) { diff --git a/services/sync/tps/extensions/tps/schema.json b/services/sync/tps/extensions/tps/schema.json deleted file mode 100644 index 0637a088a01e..000000000000 --- a/services/sync/tps/extensions/tps/schema.json +++ /dev/null @@ -1 +0,0 @@ -[] \ No newline at end of file diff --git a/testing/tps/tps/phase.py b/testing/tps/tps/phase.py index 85a9e23d2485..397c90796297 100644 --- a/testing/tps/tps/phase.py +++ b/testing/tps/tps/phase.py @@ -3,7 +3,6 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. import re -import os.path class TPSTestPhase(object): @@ -30,21 +29,17 @@ class TPSTestPhase(object): def run(self): # launch Firefox + args = [ '-tps', self.testpath, + '-tpsphase', self.phase, + '-tpslogfile', self.logfile ] - prefs = { - "testing.tps.testFile": os.path.abspath(self.testpath), - "testing.tps.testPhase": self.phase, - "testing.tps.logFile": self.logfile, - "testing.tps.ignoreUnusedEngines": self.ignore_unused_engines - } - - self.profile.set_preferences(prefs); - - self.log('\nLaunching Firefox for phase %s with prefs %s\n' % - (self.phase, str(prefs))) + if self.ignore_unused_engines: + args.append('--ignore-unused-engines') + self.log('\nLaunching Firefox for phase %s with args %s\n' % + (self.phase, str(args))) self.firefoxRunner.run(env=self.env, - args=[], + args=args, profile=self.profile) # parse the logfile and look for results from the current test phase diff --git a/testing/tps/tps/testrunner.py b/testing/tps/tps/testrunner.py index 1640794e1bf5..12cad820038b 100644 --- a/testing/tps/tps/testrunner.py +++ b/testing/tps/tps/testrunner.py @@ -235,7 +235,7 @@ class TPSTestRunner(object): # create the profile if necessary if not profilename in profiles: - profiles[profilename] = Profile(preferences = self.preferences.copy(), + profiles[profilename] = Profile(preferences = self.preferences, addons = self.extensions) # create the test phase @@ -262,7 +262,6 @@ class TPSTestRunner(object): break; for profilename in profiles: - print "### Cleanup Profile ", profilename cleanup_phase = TPSTestPhase( 'cleanup-' + profilename, profiles[profilename], testname, From 56ca0b122a5a5666429f0b561b97f32f4c6fd2cd Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Tue, 4 Sep 2018 14:07:28 +0000 Subject: [PATCH 39/61] Bug 1487238 - Do realm checks instead of compartment checks in the expression decompiler code. r=luke Another option is to allow same-compartment realms here, but this seems simpler and safer (to ensure we don't leak any information in document.domain cases or if we ever change from CPO to something else). A principals check is probably not worth the complexity. Differential Revision: https://phabricator.services.mozilla.com/D4868 --HG-- extra : moz-landing-system : lando --- js/src/jit-test/tests/realms/bug1487238.js | 3 +++ js/src/vm/BytecodeUtil.cpp | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 js/src/jit-test/tests/realms/bug1487238.js diff --git a/js/src/jit-test/tests/realms/bug1487238.js b/js/src/jit-test/tests/realms/bug1487238.js new file mode 100644 index 000000000000..dc0f9710a919 --- /dev/null +++ b/js/src/jit-test/tests/realms/bug1487238.js @@ -0,0 +1,3 @@ +// |jit-test| error: TypeError +var x = newGlobal({sameCompartmentAs: this}); +x instanceof x.Map.prototype.set; diff --git a/js/src/vm/BytecodeUtil.cpp b/js/src/vm/BytecodeUtil.cpp index 369a6b0ca1c3..778aa6aeb7ad 100644 --- a/js/src/vm/BytecodeUtil.cpp +++ b/js/src/vm/BytecodeUtil.cpp @@ -2262,7 +2262,7 @@ DecompileExpressionFromStack(JSContext* cx, int spindex, int skipStackHits, Hand FrameIter frameIter(cx); - if (frameIter.done() || !frameIter.hasScript() || frameIter.compartment() != cx->compartment()) + if (frameIter.done() || !frameIter.hasScript() || frameIter.realm() != cx->realm()) return true; /* @@ -2352,7 +2352,7 @@ DecompileArgumentFromStack(JSContext* cx, int formalIndex, UniqueChars* res) if (frameIter.done() || !frameIter.hasScript() || frameIter.script()->selfHosted() || - frameIter.compartment() != cx->compartment()) + frameIter.realm() != cx->realm()) { return true; } From 53f1370b5f58683636a07d5f8432a62cba04c8ec Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Tue, 4 Sep 2018 16:59:56 +0000 Subject: [PATCH 40/61] Bug 1267297 - Use AutoEntryScript for script activity bookkeeping instead of the request machinery. r=bholley Differential Revision: https://phabricator.services.mozilla.com/D4085 --HG-- extra : moz-landing-system : lando --- dom/script/ScriptSettings.cpp | 20 +++++--- dom/script/ScriptSettings.h | 14 ++++-- js/xpconnect/src/XPCJSContext.cpp | 49 +++++++++++++------ js/xpconnect/src/XPCShellImpl.cpp | 16 ++++-- js/xpconnect/src/xpcprivate.h | 11 ++++- js/xpconnect/src/xpcpublic.h | 10 +++- .../tests/unit/test_watchdog_hibernate.js | 10 ++-- xpcom/threads/nsThreadUtils.h | 10 ++++ 8 files changed, 100 insertions(+), 40 deletions(-) diff --git a/dom/script/ScriptSettings.cpp b/dom/script/ScriptSettings.cpp index 6a8c3c871f3d..adc3645cdd1f 100644 --- a/dom/script/ScriptSettings.cpp +++ b/dom/script/ScriptSettings.cpp @@ -662,8 +662,11 @@ AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject, { MOZ_ASSERT(aGlobalObject); - if (aIsMainThread && gRunToCompletionListeners > 0) { - mDocShellEntryMonitor.emplace(cx(), aReason); + if (aIsMainThread) { + if (gRunToCompletionListeners > 0) { + mDocShellEntryMonitor.emplace(cx(), aReason); + } + mScriptActivity.emplace(true); } } @@ -815,11 +818,12 @@ AutoSafeJSContext::AutoSafeJSContext(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMP } AutoSlowOperation::AutoSlowOperation(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL) - : AutoJSAPI() + : mIsMainThread(NS_IsMainThread()) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; - - Init(); + if (mIsMainThread) { + mScriptActivity.emplace(true); + } } void @@ -828,8 +832,10 @@ AutoSlowOperation::CheckForInterrupt() // For now we support only main thread! if (mIsMainThread) { // JS_CheckForInterrupt expects us to be in a realm. - JSAutoRealm ar(cx(), xpc::UnprivilegedJunkScope()); - JS_CheckForInterrupt(cx()); + AutoJSAPI jsapi; + if (jsapi.Init(xpc::UnprivilegedJunkScope())) { + JS_CheckForInterrupt(jsapi.cx()); + } } } diff --git a/dom/script/ScriptSettings.h b/dom/script/ScriptSettings.h index cce5607c3771..d69b7ed95967 100644 --- a/dom/script/ScriptSettings.h +++ b/dom/script/ScriptSettings.h @@ -12,6 +12,7 @@ #include "MainThreadUtils.h" #include "nsIGlobalObject.h" #include "nsIPrincipal.h" +#include "xpcpublic.h" #include "mozilla/Maybe.h" @@ -383,6 +384,7 @@ private: friend nsIPrincipal* GetWebIDLCallerPrincipal(); Maybe mDocShellEntryMonitor; + Maybe mScriptActivity; JS::AutoHideScriptedCaller mCallerOverride; #ifdef MOZ_GECKO_PROFILER AutoProfilerLabel mAutoProfilerLabel; @@ -455,17 +457,21 @@ private: * Use AutoSlowOperation when native side calls many JS callbacks in a row * and slow script dialog should be activated if too much time is spent going * through those callbacks. - * AutoSlowOperation puts a JSAutoRequest on the stack so that we don't continue - * to reset the watchdog and CheckForInterrupt can be then used to check whether - * JS execution should be interrupted. + * AutoSlowOperation puts an AutoScriptActivity on the stack so that we don't + * continue to reset the watchdog. CheckForInterrupt can then be used to check + * whether JS execution should be interrupted. + * This class (including CheckForInterrupt) is a no-op when used off the main + * thread. */ -class MOZ_RAII AutoSlowOperation : public dom::AutoJSAPI +class MOZ_RAII AutoSlowOperation { public: explicit AutoSlowOperation(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM); void CheckForInterrupt(); private: MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER + bool mIsMainThread; + Maybe mScriptActivity; }; /** diff --git a/js/xpconnect/src/XPCJSContext.cpp b/js/xpconnect/src/XPCJSContext.cpp index 47887d0c6926..cb82121f6997 100644 --- a/js/xpconnect/src/XPCJSContext.cpp +++ b/js/xpconnect/src/XPCJSContext.cpp @@ -551,28 +551,49 @@ XPCJSContext::GetWatchdogTimestamp(WatchdogTimestampCategory aCategory) mWatchdogManager->GetTimestamp(aCategory, lock); } -void -xpc::SimulateActivityCallback(bool aActive) -{ - XPCJSContext::ActivityCallback(XPCJSContext::Get(), aActive); -} - // static -void -XPCJSContext::ActivityCallback(void* arg, bool active) +bool +XPCJSContext::RecordScriptActivity(bool aActive) { + MOZ_ASSERT(NS_IsMainThread()); + + XPCJSContext* xpccx = XPCJSContext::Get(); + if (!xpccx) { + // mozilla::SpinEventLoopUntil may use AutoScriptActivity(false) after + // we destroyed the XPCJSContext. + MOZ_ASSERT(!aActive); + return false; + } + + bool oldValue = xpccx->SetHasScriptActivity(aActive); + if (aActive == oldValue) { + // Nothing to do. + return oldValue; + } + // Since the slow script dialog never activates if we are recording or // replaying, don't record/replay JS activity notifications. if (recordreplay::IsRecordingOrReplaying()) { - return; + return oldValue; } - if (!active) { + if (!aActive) { ProcessHangMonitor::ClearHang(); } + xpccx->mWatchdogManager->RecordContextActivity(xpccx, aActive); - XPCJSContext* self = static_cast(arg); - self->mWatchdogManager->RecordContextActivity(self, active); + return oldValue; +} + +AutoScriptActivity::AutoScriptActivity(bool aActive) + : mActive(aActive) + , mOldValue(XPCJSContext::RecordScriptActivity(aActive)) +{ +} + +AutoScriptActivity::~AutoScriptActivity() +{ + MOZ_ALWAYS_TRUE(mActive == XPCJSContext::RecordScriptActivity(mOldValue)); } // static @@ -890,8 +911,6 @@ XPCJSContext::~XPCJSContext() Preferences::UnregisterCallback(ReloadPrefsCallback, "fuzzing.enabled", this); #endif - js::SetActivityCallback(Context(), nullptr, nullptr); - // Clear any pending exception. It might be an XPCWrappedJS, and if we try // to destroy it later we will crash. SetPendingException(nullptr); @@ -926,6 +945,7 @@ XPCJSContext::XPCJSContext() mWatchdogManager(GetWatchdogManager()), mSlowScriptSecondHalf(false), mTimeoutAccumulated(false), + mHasScriptActivity(false), mPendingResult(NS_OK), mActive(CONTEXT_INACTIVE), mLastStateChange(PR_Now()) @@ -1140,7 +1160,6 @@ XPCJSContext::Initialize(XPCJSContext* aPrimaryContext) PROFILER_SET_JS_CONTEXT(cx); - js::SetActivityCallback(cx, ActivityCallback, this); JS_AddInterruptCallback(cx, InterruptCallback); if (!aPrimaryContext) { diff --git a/js/xpconnect/src/XPCShellImpl.cpp b/js/xpconnect/src/XPCShellImpl.cpp index 9082b82a5e9c..4917acecf6e3 100644 --- a/js/xpconnect/src/XPCShellImpl.cpp +++ b/js/xpconnect/src/XPCShellImpl.cpp @@ -590,15 +590,21 @@ SetInterruptCallback(JSContext* cx, unsigned argc, Value* vp) } static bool -SimulateActivityCallback(JSContext* cx, unsigned argc, Value* vp) +SimulateNoScriptActivity(JSContext* cx, unsigned argc, Value* vp) { // Sanity-check args. JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - if (args.length() != 1 || !args[0].isBoolean()) { - JS_ReportErrorASCII(cx, "Wrong number of arguments"); + if (args.length() != 1 || !args[0].isInt32() || args[0].toInt32() < 0) { + JS_ReportErrorASCII(cx, "Expected a positive integer argument"); return false; } - xpc::SimulateActivityCallback(args[0].toBoolean()); + + // This mimics mozilla::SpinEventLoopUntil but instead of spinning the + // event loop we sleep, to make sure we don't run script. + xpc::AutoScriptActivity asa(false); + PR_Sleep(PR_SecondsToInterval(args[0].toInt32())); + + args.rval().setUndefined(); return true; } @@ -665,7 +671,7 @@ static const JSFunctionSpec glob_functions[] = { JS_FN("atob", xpc::Atob, 1,0), JS_FN("btoa", xpc::Btoa, 1,0), JS_FN("setInterruptCallback", SetInterruptCallback, 1,0), - JS_FN("simulateActivityCallback", SimulateActivityCallback, 1,0), + JS_FN("simulateNoScriptActivity", SimulateNoScriptActivity, 1,0), JS_FN("registerAppManifest", RegisterAppManifest, 1, 0), #ifdef ENABLE_TESTS JS_FN("registerXPCTestComponents", RegisterXPCTestComponents, 0, 0), diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index 3051788c5c0f..13893e20b648 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -373,7 +373,14 @@ public: PRTime GetWatchdogTimestamp(WatchdogTimestampCategory aCategory); - static void ActivityCallback(void* arg, bool active); + static bool RecordScriptActivity(bool aActive); + + bool SetHasScriptActivity(bool aActive) { + bool oldValue = mHasScriptActivity; + mHasScriptActivity = aActive; + return oldValue; + } + static bool InterruptCallback(JSContext* cx); // Mapping of often used strings to jsid atoms that live 'forever'. @@ -461,6 +468,8 @@ private: mozilla::TimeDuration mSlowScriptActualWait; bool mTimeoutAccumulated; + bool mHasScriptActivity; + // mPendingResult is used to implement Components.returnCode. Only really // meaningful while calling through XPCWrappedJS. nsresult mPendingResult; diff --git a/js/xpconnect/src/xpcpublic.h b/js/xpconnect/src/xpcpublic.h index 8cbc87b0c7ca..e9455e554da2 100644 --- a/js/xpconnect/src/xpcpublic.h +++ b/js/xpconnect/src/xpcpublic.h @@ -550,8 +550,14 @@ WindowGlobalOrNull(JSObject* aObj); nsGlobalWindowInner* CurrentWindowOrNull(JSContext* cx); -void -SimulateActivityCallback(bool aActive); +class MOZ_RAII AutoScriptActivity +{ + bool mActive; + bool mOldValue; + public: + explicit AutoScriptActivity(bool aActive); + ~AutoScriptActivity(); +}; // This function may be used off-main-thread, in which case it is benignly // racey. diff --git a/js/xpconnect/tests/unit/test_watchdog_hibernate.js b/js/xpconnect/tests/unit/test_watchdog_hibernate.js index 1207e6ff5c98..5d4726eda977 100644 --- a/js/xpconnect/tests/unit/test_watchdog_hibernate.js +++ b/js/xpconnect/tests/unit/test_watchdog_hibernate.js @@ -23,13 +23,11 @@ async function testBody() { // scheduling, we should never have more than 3 seconds of inactivity without // hibernating. To add some padding for automation, we mandate that hibernation // must begin between 2 and 5 seconds from now. - await new Promise(resolve => { - var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - timer.initWithCallback(resolve, 10000, Ci.nsITimer.TYPE_ONE_SHOT); - simulateActivityCallback(false); - }); - simulateActivityCallback(true); + // Sleep for 10 seconds. Note: we don't use nsITimer here because then we may run + // arbitrary (idle) events involving script before it fires. + simulateNoScriptActivity(10); + busyWait(1000); // Give the watchdog time to wake up on the condvar. var stateChange = Cu.getWatchdogTimestamp("ContextStateChange"); startHibernation = Cu.getWatchdogTimestamp("WatchdogHibernateStart"); diff --git a/xpcom/threads/nsThreadUtils.h b/xpcom/threads/nsThreadUtils.h index 765fffe4d14e..962122aa85c7 100644 --- a/xpcom/threads/nsThreadUtils.h +++ b/xpcom/threads/nsThreadUtils.h @@ -21,8 +21,10 @@ #include "nsString.h" #include "nsCOMPtr.h" #include "nsAutoPtr.h" +#include "xpcpublic.h" #include "mozilla/Atomics.h" #include "mozilla/Likely.h" +#include "mozilla/Maybe.h" #include "mozilla/Move.h" #include "mozilla/TimeStamp.h" #include "mozilla/Tuple.h" @@ -320,6 +322,14 @@ SpinEventLoopUntil(Pred&& aPredicate, nsIThread* aThread = nullptr) { nsIThread* thread = aThread ? aThread : NS_GetCurrentThread(); + // From a latency perspective, spinning the event loop is like leaving script + // and returning to the event loop. Tell the watchdog we stopped running + // script (until we return). + mozilla::Maybe asa; + if (NS_IsMainThread()) { + asa.emplace(false); + } + while (!aPredicate()) { bool didSomething = NS_ProcessNextEvent(thread, true); From a7959b6272931c1ff61b8658c98ccbe6a6a92a24 Mon Sep 17 00:00:00 2001 From: Zibi Braniecki Date: Tue, 4 Sep 2018 16:57:52 +0000 Subject: [PATCH 41/61] Bug 1483038 - Optimize L10nRegistry generator to early exit on missing resources. r=mossop Optimize L10nRegistry generator to early exit on missing resources. Differential Revision: https://phabricator.services.mozilla.com/D3394 --HG-- extra : moz-landing-system : lando --- intl/l10n/L10nRegistry.jsm | 78 +++++++++++++++++++++----------------- intl/l10n/Localization.jsm | 7 ++-- intl/l10n/l10n.js | 6 ++- 3 files changed, 51 insertions(+), 40 deletions(-) diff --git a/intl/l10n/L10nRegistry.jsm b/intl/l10n/L10nRegistry.jsm index a3292a72f4fe..a429acaf5dbc 100644 --- a/intl/l10n/L10nRegistry.jsm +++ b/intl/l10n/L10nRegistry.jsm @@ -95,26 +95,18 @@ const L10nRegistry = { const sourcesOrder = Array.from(this.sources.keys()).reverse(); const pseudoNameFromPref = Services.prefs.getStringPref("intl.l10n.pseudo", ""); for (const locale of requestedLangs) { - for (const fetchPromises of generateResourceSetsForLocale(locale, sourcesOrder, resourceIds)) { - const ctx = await Promise.all(fetchPromises).then( - dataSets => { - const ctx = new MessageContext(locale, { - ...MSG_CONTEXT_OPTIONS, - transform: PSEUDO_STRATEGIES[pseudoNameFromPref], - }); - for (const data of dataSets) { - if (data === null) { - return null; - } - ctx.addResource(data); - } - return ctx; - }, - () => null - ); - if (ctx !== null) { - yield ctx; + for await (const dataSets of generateResourceSetsForLocale(locale, sourcesOrder, resourceIds)) { + const ctx = new MessageContext(locale, { + ...MSG_CONTEXT_OPTIONS, + transform: PSEUDO_STRATEGIES[pseudoNameFromPref], + }); + for (const data of dataSets) { + if (data === null) { + return; + } + ctx.addResource(data); } + yield ctx; } } }, @@ -190,7 +182,7 @@ const L10nRegistry = { * @param {Array} [resolvedOrder] * @returns {AsyncIterator} */ -function* generateResourceSetsForLocale(locale, sourcesOrder, resourceIds, resolvedOrder = []) { +async function* generateResourceSetsForLocale(locale, sourcesOrder, resourceIds, resolvedOrder = []) { const resolvedLength = resolvedOrder.length; const resourcesLength = resourceIds.length; @@ -200,18 +192,36 @@ function* generateResourceSetsForLocale(locale, sourcesOrder, resourceIds, resol for (const sourceName of sourcesOrder) { const order = resolvedOrder.concat(sourceName); - // We bail only if the hasFile returns a strict false here, - // because for FileSource it may also return undefined, which means - // that we simply don't know if the source contains the file and we'll - // have to perform the I/O to learn. - if (L10nRegistry.sources.get(sourceName).hasFile(locale, resourceIds[resolvedOrder.length]) === false) { - continue; + // We want to bail out early if we know that any of + // the (res)x(source) combinations in the permutation + // are unavailable. + // The combination may have been `undefined` when we + // stepped into this branch, and now is resolved to + // `false`. + // + // If the combination resolved to `false` is the last + // in the resolvedOrder, we want to continue in this + // loop, but if it's somewhere in the middle, we can + // safely bail from the whole branch. + for (let [idx, sourceName] of order.entries()) { + if (L10nRegistry.sources.get(sourceName).hasFile(locale, resourceIds[idx]) === false) { + if (idx === order.length - 1) { + continue; + } else { + return; + } + } } // If the number of resolved sources equals the number of resources, // create the right context and return it if it loads. if (resolvedLength + 1 === resourcesLength) { - yield generateResourceSet(locale, order, resourceIds); + let dataSet = await generateResourceSet(locale, order, resourceIds); + // Here we check again to see if the newly resolved + // resources returned `false` on any position. + if (!dataSet.includes(false)) { + yield dataSet; + } } else if (resolvedLength < resourcesLength) { // otherwise recursively load another generator that walks over the // partially resolved list of sources. @@ -346,10 +356,10 @@ const PSEUDO_STRATEGIES = { * @param {Array} resourceIds * @returns {Promise} */ -function generateResourceSet(locale, sourcesOrder, resourceIds) { - return resourceIds.map((resourceId, i) => { +async function generateResourceSet(locale, sourcesOrder, resourceIds) { + return Promise.all(resourceIds.map((resourceId, i) => { return L10nRegistry.sources.get(sourcesOrder[i]).fetchFile(locale, resourceId); - }); + })); } /** @@ -420,14 +430,14 @@ class FileSource { fetchFile(locale, path) { if (!this.locales.includes(locale)) { - return Promise.reject(`The source has no resources for locale "${locale}"`); + return false; } const fullPath = this.getPath(locale, path); if (this.cache.hasOwnProperty(fullPath)) { if (this.cache[fullPath] === false) { - return Promise.reject(`The source has no resources for path "${fullPath}"`); + return false; } // `true` means that the file is indexed, but hasn't // been fetched yet. @@ -435,7 +445,7 @@ class FileSource { return this.cache[fullPath]; } } else if (this.indexed) { - return Promise.reject(`The source has no resources for path "${fullPath}"`); + return false; } return this.cache[fullPath] = L10nRegistry.load(fullPath).then( data => { @@ -443,7 +453,7 @@ class FileSource { }, err => { this.cache[fullPath] = false; - return Promise.reject(err); + return false; } ); } diff --git a/intl/l10n/Localization.jsm b/intl/l10n/Localization.jsm index 8aa0722f20d8..1d453578134a 100644 --- a/intl/l10n/Localization.jsm +++ b/intl/l10n/Localization.jsm @@ -97,7 +97,7 @@ class CachedAsyncIterable extends CachedIterable { return { async next() { if (cached.length <= cur) { - cached.push(await cached.iterator.next()); + cached.push(cached.iterator.next()); } return cached[cur++]; } @@ -114,10 +114,10 @@ class CachedAsyncIterable extends CachedIterable { let idx = 0; while (idx++ < count) { const last = this[this.length - 1]; - if (last && last.done) { + if (last && await (last).done) { break; } - this.push(await this.iterator.next()); + this.push(this.iterator.next()); } // Return the last cached {value, done} object to allow the calling // code to decide if it needs to call touchNext again. @@ -322,7 +322,6 @@ class Localization { onChange() { this.ctxs = CachedAsyncIterable.from( this.generateMessages(this.resourceIds)); - this.ctxs.touchNext(2); } } diff --git a/intl/l10n/l10n.js b/intl/l10n/l10n.js index ad6c914b3219..1afb8f7ee00d 100644 --- a/intl/l10n/l10n.js +++ b/intl/l10n/l10n.js @@ -1,6 +1,7 @@ { const { DOMLocalization } = ChromeUtils.import("resource://gre/modules/DOMLocalization.jsm", {}); + const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm", {}); /** * Polyfill for document.ready polyfill. @@ -46,8 +47,9 @@ document.l10n = new DOMLocalization(resourceIds); - // Trigger the first two contexts to be loaded eagerly. - document.l10n.ctxs.touchNext(2); + const appLocales = Services.locale.getAppLocalesAsBCP47(); + const prefetchCount = appLocales.length > 1 ? 2 : 1; + document.l10n.ctxs.touchNext(prefetchCount); document.l10n.ready = documentReady().then(() => { document.l10n.registerObservers(); From dfbefcc19f6c3a050342cf8033793cfb8c91f39f Mon Sep 17 00:00:00 2001 From: Gurzau Raul Date: Tue, 4 Sep 2018 20:31:33 +0300 Subject: [PATCH 42/61] Backed out changeset 45605798ecfe (bug 1476996) for build bustage at netwerk/protocol/http/HttpChannelParentListener.cpp on a CLOSED TREE --- ipc/glue/URIUtils.h | 2 +- netwerk/ipc/NeckoChild.cpp | 70 ------ netwerk/ipc/NeckoChild.h | 9 - netwerk/ipc/PNecko.ipdl | 12 - netwerk/protocol/http/HttpChannelChild.cpp | 18 -- netwerk/protocol/http/HttpChannelChild.h | 12 - netwerk/protocol/http/HttpChannelParent.cpp | 54 +---- netwerk/protocol/http/HttpChannelParent.h | 4 - .../http/HttpChannelParentListener.cpp | 95 +------- .../protocol/http/HttpChannelParentListener.h | 4 - netwerk/protocol/http/PHttpChannel.ipdl | 9 - netwerk/protocol/http/moz.build | 1 - netwerk/protocol/http/nsHttpChannel.cpp | 99 --------- netwerk/protocol/http/nsHttpChannel.h | 12 - .../http/nsIRedirectProcessChooser.idl | 45 ---- netwerk/test/browser/browser.ini | 2 - .../browser/browser_cross_process_redirect.js | 210 ------------------ netwerk/test/browser/redirect.sjs | 7 - 18 files changed, 14 insertions(+), 651 deletions(-) delete mode 100644 netwerk/protocol/http/nsIRedirectProcessChooser.idl delete mode 100644 netwerk/test/browser/browser_cross_process_redirect.js delete mode 100644 netwerk/test/browser/redirect.sjs diff --git a/ipc/glue/URIUtils.h b/ipc/glue/URIUtils.h index cc52c3e79e62..edf35ef61d4c 100644 --- a/ipc/glue/URIUtils.h +++ b/ipc/glue/URIUtils.h @@ -39,7 +39,7 @@ struct IPDLParamTraits WriteIPDLParam(aMsg, aActor, params); } - static bool Read(const IPC::Message* aMsg, PickleIterator* aIter, + static bool Read(IPC::Message* aMsg, PickleIterator* aIter, IProtocol* aActor, RefPtr* aResult) { OptionalURIParams params; diff --git a/netwerk/ipc/NeckoChild.cpp b/netwerk/ipc/NeckoChild.cpp index 4698b8d559c3..8c6ff2d0ea2c 100644 --- a/netwerk/ipc/NeckoChild.cpp +++ b/netwerk/ipc/NeckoChild.cpp @@ -33,8 +33,6 @@ #include "nsINetworkPredictor.h" #include "nsINetworkPredictorVerifier.h" #include "nsINetworkLinkService.h" -#include "nsIRedirectProcessChooser.h" -#include "nsQueryObject.h" #include "mozilla/ipc/URIUtils.h" #include "nsNetUtil.h" @@ -373,74 +371,6 @@ NeckoChild::DeallocPTransportProviderChild(PTransportProviderChild* aActor) return true; } -mozilla::ipc::IPCResult -NeckoChild::RecvCrossProcessRedirect( - const uint32_t& aRegistrarId, - nsIURI* aURI, - const uint32_t& aNewLoadFlags, - const OptionalLoadInfoArgs& aLoadInfo, - const uint64_t& aChannelId, - nsIURI* aOriginalURI, - const uint64_t& aIdentifier) -{ - nsCOMPtr loadInfo; - nsresult rv = ipc::LoadInfoArgsToLoadInfo(aLoadInfo, getter_AddRefs(loadInfo)); - if (NS_FAILED(rv)) { - MOZ_DIAGNOSTIC_ASSERT(false, "LoadInfoArgsToLoadInfo failed"); - return IPC_OK(); - } - - nsCOMPtr newChannel; - rv = NS_NewChannelInternal(getter_AddRefs(newChannel), - aURI, - loadInfo, - nullptr, // PerformanceStorage - nullptr, // aLoadGroup - nullptr, // aCallbacks - aNewLoadFlags); - - // We are sure this is a HttpChannelChild because the parent - // is always a HTTP channel. - RefPtr httpChild = do_QueryObject(newChannel); - if (NS_FAILED(rv) || !httpChild) { - MOZ_DIAGNOSTIC_ASSERT(false, "NS_NewChannelInternal failed"); - return IPC_OK(); - } - - // This is used to report any errors back to the parent by calling - // CrossProcessRedirectFinished. - auto scopeExit = MakeScopeExit([&]() { - httpChild->CrossProcessRedirectFinished(rv); - }); - - rv = httpChild->SetChannelId(aChannelId); - if (NS_FAILED(rv)) { - return IPC_OK(); - } - - rv = httpChild->SetOriginalURI(aOriginalURI); - if (NS_FAILED(rv)) { - return IPC_OK(); - } - - // connect parent. - rv = httpChild->ConnectParent(aRegistrarId); // creates parent channel - if (NS_FAILED(rv)) { - return IPC_OK(); - } - - nsCOMPtr processListener = - do_GetClassObject("@mozilla.org/network/childProcessChannelListener"); - // The listener will call completeRedirectSetup on the channel. - rv = processListener->OnChannelReady(httpChild, aIdentifier); - if (NS_FAILED(rv)) { - return IPC_OK(); - } - - // scopeExit will call CrossProcessRedirectFinished(rv) here - return IPC_OK(); -} - mozilla::ipc::IPCResult NeckoChild::RecvAsyncAuthPromptForNestedFrame(const TabId& aNestedFrameId, const nsCString& aUri, diff --git a/netwerk/ipc/NeckoChild.h b/netwerk/ipc/NeckoChild.h index 7e9f8d2bcd90..d2210077f082 100644 --- a/netwerk/ipc/NeckoChild.h +++ b/netwerk/ipc/NeckoChild.h @@ -96,15 +96,6 @@ protected: virtual mozilla::ipc::IPCResult RecvSpeculativeConnectRequest() override; virtual mozilla::ipc::IPCResult RecvNetworkChangeNotification(nsCString const& type) override; - - virtual mozilla::ipc::IPCResult RecvCrossProcessRedirect( - const uint32_t& aRegistrarId, - nsIURI* aURI, - const uint32_t& aNewLoadFlags, - const OptionalLoadInfoArgs& aLoadInfoForwarder, - const uint64_t& aChannelId, - nsIURI* aOriginalURI, - const uint64_t& aIdentifier) override; }; /** diff --git a/netwerk/ipc/PNecko.ipdl b/netwerk/ipc/PNecko.ipdl index 175da26c24e2..7ddf9d7afe74 100644 --- a/netwerk/ipc/PNecko.ipdl +++ b/netwerk/ipc/PNecko.ipdl @@ -37,7 +37,6 @@ using class IPC::SerializedLoadContext from "SerializedLoadContext.h"; using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h"; using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h"; using refcounted class nsIInputStream from "mozilla/ipc/IPCStreamUtils.h"; -using refcounted class nsIURI from "mozilla/ipc/URIUtils.h"; namespace mozilla { namespace net { @@ -154,17 +153,6 @@ child: async PTransportProvider(); - // This message is sent to PNecko and triggers the creation of a new - // HttpChannelChild that will be connected to the parent channel represented - // by registrarId. - async CrossProcessRedirect(uint32_t aRegistrarId, - nsIURI aURI, - uint32_t aNewLoadFlags, - OptionalLoadInfoArgs aLoadInfo, - uint64_t aChannelId, - nsIURI aOriginalURI, - uint64_t aIdentifier); - both: // Actually we need PTCPSocket() for parent. But ipdl disallows us having different // signatures on parent and child. So when constructing the parent side object, we just diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp index 5b29489914e9..26156458cac6 100644 --- a/netwerk/protocol/http/HttpChannelChild.cpp +++ b/netwerk/protocol/http/HttpChannelChild.cpp @@ -297,7 +297,6 @@ NS_INTERFACE_MAP_BEGIN(HttpChannelChild) NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAssociatedContentSecurity, GetAssociatedContentSecurity()) NS_INTERFACE_MAP_ENTRY(nsIDivertableChannel) NS_INTERFACE_MAP_ENTRY(nsIThreadRetargetableRequest) - NS_INTERFACE_MAP_ENTRY_CONCRETE(HttpChannelChild) NS_INTERFACE_MAP_END_INHERITING(HttpBaseChannel) //----------------------------------------------------------------------------- @@ -2160,13 +2159,6 @@ HttpChannelChild::Redirect3Complete(OverrideRunnable* aRunnable) return false; } -mozilla::ipc::IPCResult -HttpChannelChild::RecvCancelRedirected() -{ - CleanupRedirectingChannel(NS_BINDING_REDIRECTED); - return IPC_OK(); -} - void HttpChannelChild::CleanupRedirectingChannel(nsresult rv) { @@ -4134,15 +4126,5 @@ HttpChannelChild::MaybeCallSynthesizedCallback() mSynthesizedCallback = nullptr; } -nsresult -HttpChannelChild::CrossProcessRedirectFinished(nsresult aStatus) -{ - if (!mIPCOpen) { - return NS_BINDING_FAILED; - } - Unused << SendCrossProcessRedirectDone(aStatus); - return NS_OK; -} - } // namespace net } // namespace mozilla diff --git a/netwerk/protocol/http/HttpChannelChild.h b/netwerk/protocol/http/HttpChannelChild.h index b02104112e95..6907b294e332 100644 --- a/netwerk/protocol/http/HttpChannelChild.h +++ b/netwerk/protocol/http/HttpChannelChild.h @@ -41,10 +41,6 @@ class nsIEventTarget; class nsInputStreamPump; class nsIInterceptedBodyCallback; -#define HTTP_CHANNEL_CHILD_IID \ -{ 0x321bd99e, 0x2242, 0x4dc6, \ - { 0xbb, 0xec, 0xd5, 0x06, 0x29, 0x7c, 0x39, 0x83 } } - namespace mozilla { namespace net { @@ -80,7 +76,6 @@ public: NS_DECL_NSIHTTPCHANNELCHILD NS_DECL_NSIDIVERTABLECHANNEL NS_DECL_NSITHREADRETARGETABLEREQUEST - NS_DECLARE_STATIC_IID_ACCESSOR(HTTP_CHANNEL_CHILD_IID) HttpChannelChild(); @@ -132,8 +127,6 @@ public: // Callback while background channel is destroyed. void OnBackgroundChildDestroyed(HttpBackgroundChannelChild* aBgChild); - nsresult CrossProcessRedirectFinished(nsresult aStatus); - protected: mozilla::ipc::IPCResult RecvOnStartRequest(const nsresult& channelStatus, const nsHttpResponseHead& responseHead, @@ -183,8 +176,6 @@ protected: mozilla::ipc::IPCResult RecvCancelDiversion() override; - mozilla::ipc::IPCResult RecvCancelRedirected() override; - virtual void ActorDestroy(ActorDestroyReason aWhy) override; MOZ_MUST_USE bool @@ -526,9 +517,6 @@ private: friend class NeckoTargetChannelEvent; }; -NS_DEFINE_STATIC_IID_ACCESSOR(HttpChannelChild, - HTTP_CHANNEL_CHILD_IID) - // A stream listener interposed between the nsInputStreamPump used for intercepted channels // and this channel's original listener. This is only used to ensure the original listener // sees the channel as the request object, and to synthesize OnStatus and OnProgress notifications. diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp index d3b0a25da276..58b528cce800 100644 --- a/netwerk/protocol/http/HttpChannelParent.cpp +++ b/netwerk/protocol/http/HttpChannelParent.cpp @@ -83,7 +83,6 @@ HttpChannelParent::HttpChannelParent(const PBrowserOrId& iframeEmbedding, , mCacheNeedFlowControlInitialized(false) , mNeedFlowControl(true) , mSuspendedForFlowControl(false) - , mDoingCrossProcessRedirect(false) { LOG(("Creating HttpChannelParent [this=%p]\n", this)); @@ -314,8 +313,7 @@ NS_IMETHODIMP HttpChannelParent::GetInterface(const nsIID& aIID, void **result) { if (aIID.Equals(NS_GET_IID(nsIAuthPromptProvider)) || - aIID.Equals(NS_GET_IID(nsISecureBrowserUI)) || - aIID.Equals(NS_GET_IID(nsITabParent))) { + aIID.Equals(NS_GET_IID(nsISecureBrowserUI))) { if (mTabParent) { return mTabParent->QueryInterface(aIID, result); } @@ -1324,45 +1322,6 @@ HttpChannelParent::MaybeFlushPendingDiversion() } -static void -FinishCrossProcessRedirect(nsHttpChannel *channel, nsresult status) -{ - if (NS_SUCCEEDED(status)) { - nsCOMPtr controller; - NS_QueryNotificationCallbacks(channel, controller); - RefPtr parentListener = do_QueryObject(controller); - MOZ_ASSERT(parentListener); - - // This updates HttpChannelParentListener to point to this parent and at - // the same time cancels the old channel. - parentListener->OnRedirectResult(status == NS_OK); - } - - channel->OnRedirectVerifyCallback(status); -} - -mozilla::ipc::IPCResult -HttpChannelParent::RecvCrossProcessRedirectDone(const nsresult& aResult) -{ - RefPtr chan = do_QueryObject(mChannel); - if (!mBgParent) { - RefPtr promise = WaitForBgParent(); - RefPtr self = this; - promise->Then(GetMainThreadSerialEventTarget(), __func__, - [self, chan, aResult]() { - FinishCrossProcessRedirect(chan, aResult); - }, - [self, chan](const nsresult& aRejectionRv) { - MOZ_ASSERT(NS_FAILED(aRejectionRv), "This should be an error code"); - FinishCrossProcessRedirect(chan, aRejectionRv); - }); - } else { - FinishCrossProcessRedirect(chan, aResult); - } - - return IPC_OK(); -} - void HttpChannelParent::ResponseSynthesized() { @@ -2044,15 +2003,6 @@ HttpChannelParent::CompleteRedirect(bool succeeded) LOG(("HttpChannelParent::CompleteRedirect [this=%p succeeded=%d]\n", this, succeeded)); - // The channel was redirected to another process, and the channel parent - // is about to be deleted. We send a CancelRedirected message in order to - // inform the listener that this child is going away. - if (mDoingCrossProcessRedirect && !mIPCClosed) { - MOZ_ASSERT(!mRedirectChannel); - Unused << SendCancelRedirected(); - return NS_OK; - } - // If this was an internal redirect for a service worker interception then // we will not have a redirecting channel here. Hide this redirect from // the child. @@ -2471,7 +2421,7 @@ HttpChannelParent::IssueWarning(uint32_t aWarning, bool aAsError) NS_IMETHODIMP HttpChannelParent::ReadyToVerify(nsresult aResult) { - LOG(("HttpChannelParent::ReadyToVerify [this=%p result=%" PRIx32 "]\n", + LOG(("HttpChannelParent::RecvRedirect2Verify [this=%p result=%" PRIx32 "]\n", this, static_cast(aResult))); MOZ_ASSERT(NS_IsMainThread()); diff --git a/netwerk/protocol/http/HttpChannelParent.h b/netwerk/protocol/http/HttpChannelParent.h index 013e770292a4..8cc32537302b 100644 --- a/netwerk/protocol/http/HttpChannelParent.h +++ b/netwerk/protocol/http/HttpChannelParent.h @@ -123,8 +123,6 @@ public: base::ProcessId OtherPid() const override; - void SetCrossProcessRedirect() { mDoingCrossProcessRedirect = true; } - protected: // used to connect redirected-to channel in parent with just created // ChildChannel. Used during redirects. @@ -209,7 +207,6 @@ protected: const uint32_t& count) override; virtual mozilla::ipc::IPCResult RecvDivertOnStopRequest(const nsresult& statusCode) override; virtual mozilla::ipc::IPCResult RecvDivertComplete() override; - virtual mozilla::ipc::IPCResult RecvCrossProcessRedirectDone(const nsresult& aResult) override; virtual mozilla::ipc::IPCResult RecvRemoveCorsPreflightCacheEntry(const URIParams& uri, const mozilla::ipc::PrincipalInfo& requestingPrincipal) override; virtual mozilla::ipc::IPCResult RecvBytesRead(const int32_t& aCount) override; @@ -343,7 +340,6 @@ private: uint8_t mCacheNeedFlowControlInitialized : 1; uint8_t mNeedFlowControl : 1; uint8_t mSuspendedForFlowControl : 1; - uint8_t mDoingCrossProcessRedirect : 1; // Number of events to wait before actually invoking AsyncOpen on the main // channel. For each asynchronous step required before InvokeAsyncOpen, should diff --git a/netwerk/protocol/http/HttpChannelParentListener.cpp b/netwerk/protocol/http/HttpChannelParentListener.cpp index e4278d2db8d5..0ab01cb98887 100644 --- a/netwerk/protocol/http/HttpChannelParentListener.cpp +++ b/netwerk/protocol/http/HttpChannelParentListener.cpp @@ -11,18 +11,15 @@ #include "mozilla/dom/ServiceWorkerInterceptController.h" #include "mozilla/dom/ServiceWorkerUtils.h" #include "mozilla/net/HttpChannelParent.h" -#include "mozilla/net/RedirectChannelRegistrar.h" #include "mozilla/Unused.h" #include "nsIAuthPrompt.h" #include "nsIAuthPrompt2.h" #include "nsIHttpHeaderVisitor.h" -#include "nsIRedirectProcessChooser.h" -#include "nsITabParent.h" +#include "mozilla/net/RedirectChannelRegistrar.h" #include "nsIPromptFactory.h" #include "nsIWindowWatcher.h" #include "nsQueryObject.h" - using mozilla::Unused; using mozilla::dom::ServiceWorkerInterceptController; using mozilla::dom::ServiceWorkerParentInterceptEnabled; @@ -159,86 +156,16 @@ HttpChannelParentListener::GetInterface(const nsIID& aIID, void **result) //----------------------------------------------------------------------------- // HttpChannelParentListener::nsIChannelEventSink //----------------------------------------------------------------------------- -nsresult -HttpChannelParentListener::TriggerCrossProcessRedirect(nsIChannel *aChannel, - nsILoadInfo *aLoadInfo, - uint64_t aIdentifier) -{ - RefPtr channelParent = do_QueryObject(mNextListener); - MOZ_ASSERT(channelParent); - channelParent->SetCrossProcessRedirect(); - - nsCOMPtr channel = aChannel; - RefPtr httpChannel = do_QueryObject(channel); - RefPtr p = httpChannel->TakeRedirectTabPromise(); - nsCOMPtr loadInfo = aLoadInfo; - - RefPtr self = this; - p->Then(GetMainThreadSerialEventTarget(), __func__, - [=](nsCOMPtr tp) { - nsresult rv; - - // Register the new channel and obtain id for it - nsCOMPtr registrar = - RedirectChannelRegistrar::GetOrCreate(); - MOZ_ASSERT(registrar); - rv = registrar->RegisterChannel(channel, &self->mRedirectChannelId); - NS_ENSURE_SUCCESS(rv, rv); - - LOG(("Registered %p channel under id=%d", channel.get(), self->mRedirectChannelId)); - - OptionalLoadInfoArgs loadInfoArgs; - MOZ_ALWAYS_SUCCEEDS(LoadInfoToLoadInfoArgs(loadInfo, &loadInfoArgs)); - - uint32_t newLoadFlags = nsIRequest::LOAD_NORMAL; - MOZ_ALWAYS_SUCCEEDS(channel->GetLoadFlags(&newLoadFlags)); - - nsCOMPtr uri; - channel->GetURI(getter_AddRefs(uri)); - - nsCOMPtr originalURI; - channel->GetOriginalURI(getter_AddRefs(originalURI)); - - uint64_t channelId; - MOZ_ALWAYS_SUCCEEDS(httpChannel->GetChannelId(&channelId)); - - dom::TabParent* tabParent = dom::TabParent::GetFrom(tp); - ContentParent* cp = tabParent->Manager()->AsContentParent(); - PNeckoParent* neckoParent = SingleManagedOrNull(cp->ManagedPNeckoParent()); - - RefPtr channelParent = do_QueryObject(self->mNextListener); - MOZ_ASSERT(channelParent); - channelParent->SetCrossProcessRedirect(); - - auto result = neckoParent->SendCrossProcessRedirect(self->mRedirectChannelId, - uri, - newLoadFlags, - loadInfoArgs, - channelId, - originalURI, - aIdentifier); - - MOZ_ASSERT(result, "SendCrossProcessRedirect failed"); - - return NS_OK; - }, - [httpChannel](nsresult aStatus) { - MOZ_ASSERT(NS_FAILED(aStatus), "Status should be error"); - httpChannel->OnRedirectVerifyCallback(aStatus); - }); - - return NS_OK; -} NS_IMETHODIMP HttpChannelParentListener::AsyncOnChannelRedirect( - nsIChannel *aOldChannel, - nsIChannel *aNewChannel, - uint32_t aRedirectFlags, - nsIAsyncVerifyRedirectCallback* aCallback) + nsIChannel *oldChannel, + nsIChannel *newChannel, + uint32_t redirectFlags, + nsIAsyncVerifyRedirectCallback* callback) { LOG(("HttpChannelParentListener::AsyncOnChannelRedirect [this=%p, old=%p, new=%p, flags=%u]", - this, aOldChannel, aNewChannel, aRedirectFlags)); + this, oldChannel, newChannel, redirectFlags)); nsresult rv; @@ -255,15 +182,15 @@ HttpChannelParentListener::AsyncOnChannelRedirect( RedirectChannelRegistrar::GetOrCreate(); MOZ_ASSERT(registrar); - rv = registrar->RegisterChannel(aNewChannel, &mRedirectChannelId); + rv = registrar->RegisterChannel(newChannel, &mRedirectChannelId); NS_ENSURE_SUCCESS(rv, rv); - LOG(("Registered %p channel under id=%d", aNewChannel, mRedirectChannelId)); + LOG(("Registered %p channel under id=%d", newChannel, mRedirectChannelId)); return activeRedirectingChannel->StartRedirect(mRedirectChannelId, - aNewChannel, - aRedirectFlags, - aCallback); + newChannel, + redirectFlags, + callback); } //----------------------------------------------------------------------------- diff --git a/netwerk/protocol/http/HttpChannelParentListener.h b/netwerk/protocol/http/HttpChannelParentListener.h index 5fd5041e7ace..c6dc5a785e93 100644 --- a/netwerk/protocol/http/HttpChannelParentListener.h +++ b/netwerk/protocol/http/HttpChannelParentListener.h @@ -54,10 +54,6 @@ public: void SetupInterceptionAfterRedirect(bool aShouldIntercept); void ClearInterceptedChannel(nsIStreamListener* aListener); - nsresult TriggerCrossProcessRedirect(nsIChannel *oldChannel, - nsILoadInfo *aLoadInfo, - uint64_t aIdentifier); - private: virtual ~HttpChannelParentListener() = default; diff --git a/netwerk/protocol/http/PHttpChannel.ipdl b/netwerk/protocol/http/PHttpChannel.ipdl index 76d287b6f859..f6698e9420d7 100644 --- a/netwerk/protocol/http/PHttpChannel.ipdl +++ b/netwerk/protocol/http/PHttpChannel.ipdl @@ -51,10 +51,6 @@ parent: OptionalCorsPreflightArgs corsPreflightArgs, bool chooseAppcache); - // Sent to the parent in order signal that the child side listeners have been - // set up and the parent side of the channel can be opened. - async CrossProcessRedirectDone(nsresult result); - // For document loads we keep this protocol open after child's // OnStopRequest, and send this msg (instead of __delete__) to allow // partial cleanup on parent. @@ -150,11 +146,6 @@ child: // channel. async ReportSecurityMessage(nsString messageTag, nsString messageCategory); - // This message is sent to a child that has been redirected to another process. - // As a consequence, it should cleanup the channel listeners and remove the - // request from the loadGroup. - async CancelRedirected(); - // Tell child to delete channel (all IPDL deletes must be done from child to // avoid races: see bug 591708). async DeleteSelf(); diff --git a/netwerk/protocol/http/moz.build b/netwerk/protocol/http/moz.build index 20dffb5967ea..e02c78ff1f3a 100644 --- a/netwerk/protocol/http/moz.build +++ b/netwerk/protocol/http/moz.build @@ -20,7 +20,6 @@ XPIDL_SOURCES += [ 'nsIHttpHeaderVisitor.idl', 'nsIHttpProtocolHandler.idl', 'nsIRaceCacheWithNetwork.idl', - 'nsIRedirectProcessChooser.idl', 'nsIWellKnownOpportunisticUtils.idl', ] diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index af78f92bef46..3d4c506cdfeb 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -116,8 +116,6 @@ #include "nsIMultiplexInputStream.h" #include "../../cache2/CacheFileUtils.h" #include "nsINetworkLinkService.h" -#include "mozilla/dom/PromiseNativeHandler.h" -#include "mozilla/dom/Promise.h" #ifdef MOZ_TASK_TRACER #include "GeckoTaskTracer.h" @@ -7105,77 +7103,6 @@ nsHttpChannel::GetRequestMethod(nsACString& aMethod) // nsHttpChannel::nsIRequestObserver //----------------------------------------------------------------------------- -// This class is used to convert from a DOM promise to a MozPromise. -// Once we have a native implementation of nsIRedirectProcessChooser we can -// remove it and use MozPromises directly. -class DomPromiseListener final - : dom::PromiseNativeHandler -{ - NS_DECL_ISUPPORTS - - static RefPtr - Create(dom::Promise* aDOMPromise) - { - MOZ_ASSERT(aDOMPromise); - RefPtr handler = new DomPromiseListener(); - RefPtr promise = handler->mPromiseHolder.Ensure(__func__); - aDOMPromise->AppendNativeHandler(handler); - return promise; - } - - virtual void - ResolvedCallback(JSContext* aCx, JS::Handle aValue) override - { - nsCOMPtr tabParent; - JS::Rooted obj(aCx, &aValue.toObject()); - nsresult rv = UnwrapArg(aCx, obj, getter_AddRefs(tabParent)); - if (NS_FAILED(rv)) { - mPromiseHolder.Reject(rv, __func__); - return; - } - mPromiseHolder.Resolve(tabParent, __func__); - } - - virtual void - RejectedCallback(JSContext* aCx, JS::Handle aValue) override - { - if (!aValue.isInt32()) { - mPromiseHolder.Reject(NS_ERROR_DOM_NOT_NUMBER_ERR, __func__); - return; - } - mPromiseHolder.Reject((nsresult) aValue.toInt32(), __func__); - } - -private: - DomPromiseListener() = default; - ~DomPromiseListener() = default; - MozPromiseHolder mPromiseHolder; -}; - -NS_IMPL_ISUPPORTS0(DomPromiseListener) - -nsresult -nsHttpChannel::StartCrossProcessRedirect() -{ - nsresult rv = CheckRedirectLimit(nsIChannelEventSink::REDIRECT_INTERNAL); - NS_ENSURE_SUCCESS(rv, rv); - - RefPtr listener = do_QueryObject(mCallbacks); - MOZ_ASSERT(listener); - - nsCOMPtr redirectLoadInfo = - CloneLoadInfoForRedirect(mURI, nsIChannelEventSink::REDIRECT_INTERNAL); - - listener->TriggerCrossProcessRedirect(this, - redirectLoadInfo, - mCrossProcessRedirectIdentifier); - - // This will suspend the channel - rv = WaitForRedirectCallback(); - - return rv; -} - NS_IMETHODIMP nsHttpChannel::OnStartRequest(nsIRequest *request, nsISupports *ctxt) { @@ -7281,32 +7208,6 @@ nsHttpChannel::OnStartRequest(nsIRequest *request, nsISupports *ctxt) return NS_OK; } - // Check if the channel should be redirected to another process. - // If so, trigger a redirect, and the HttpChannelParentListener will - // redirect to the correct process - nsCOMPtr requestChooser = - do_GetClassObject("@mozilla.org/network/processChooser"); - if (requestChooser) { - nsCOMPtr tp; - nsCOMPtr parentChannel; - NS_QueryNotificationCallbacks(this, parentChannel); - - RefPtr tabPromise; - rv = requestChooser->GetChannelRedirectTarget(this, parentChannel, &mCrossProcessRedirectIdentifier, getter_AddRefs(tabPromise)); - - if (NS_SUCCEEDED(rv) && tabPromise) { - // The promise will be handled in AsyncOnChannelRedirect. - mRedirectTabPromise = DomPromiseListener::Create(tabPromise); - - PushRedirectAsyncFunc(&nsHttpChannel::ContinueOnStartRequest3); - rv = StartCrossProcessRedirect(); - if (NS_SUCCEEDED(rv)) { - return NS_OK; - } - PopRedirectAsyncFunc(&nsHttpChannel::ContinueOnStartRequest3); - } - } - // avoid crashing if mListener happens to be null... if (!mListener) { MOZ_ASSERT_UNREACHABLE("mListener is null"); diff --git a/netwerk/protocol/http/nsHttpChannel.h b/netwerk/protocol/http/nsHttpChannel.h index af47e2d31b18..32eadd0bbd64 100644 --- a/netwerk/protocol/http/nsHttpChannel.h +++ b/netwerk/protocol/http/nsHttpChannel.h @@ -32,7 +32,6 @@ #include "nsIRaceCacheWithNetwork.h" #include "mozilla/extensions/PStreamFilterParent.h" #include "mozilla/Mutex.h" -#include "nsITabParent.h" class nsDNSPrefetch; class nsICancelable; @@ -279,10 +278,6 @@ public: void SetTransactionObserver(TransactionObserver *arg) { mTransactionObserver = arg; } TransactionObserver *GetTransactionObserver() { return mTransactionObserver; } - typedef MozPromise, nsresult, false> TabPromise; - already_AddRefed TakeRedirectTabPromise() { return mRedirectTabPromise.forget(); } - uint64_t CrossProcessRedirectIdentifier() { return mCrossProcessRedirectIdentifier; } - protected: virtual ~nsHttpChannel(); @@ -352,7 +347,6 @@ private: virtual MOZ_MUST_USE nsresult SetupReplacementChannel(nsIURI *, nsIChannel *, bool preserveMethod, uint32_t redirectFlags) override; - nsresult StartCrossProcessRedirect(); // proxy specific methods MOZ_MUST_USE nsresult ProxyFailover(); @@ -513,12 +507,6 @@ private: nsCOMPtr mRedirectChannel; nsCOMPtr mPreflightChannel; - // The associated childChannel is getting relocated to another process. - // This promise will be resolved when that process is set up. - RefPtr mRedirectTabPromise; - // This identifier is passed to the childChannel in order to identify it. - uint64_t mCrossProcessRedirectIdentifier = 0; - // nsChannelClassifier checks this channel's URI against // the URI classifier service. // nsChannelClassifier will be invoked twice in InitLocalBlockList() and diff --git a/netwerk/protocol/http/nsIRedirectProcessChooser.idl b/netwerk/protocol/http/nsIRedirectProcessChooser.idl deleted file mode 100644 index 9047dc3e53fc..000000000000 --- a/netwerk/protocol/http/nsIRedirectProcessChooser.idl +++ /dev/null @@ -1,45 +0,0 @@ -/* 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 "nsISupports.idl" - -interface nsIRequest; -interface nsITabParent; -interface nsIChannel; -interface nsIParentChannel; -interface nsIChildChannel; - -[scriptable, uuid(cd7166de-e221-485f-8172-f1d05f97c6a8)] -interface nsIRedirectProcessChooser : nsISupports -{ - /** - * @param aChannel - channel which may need to be redirected to other process. - * @param aParentChannel - parent channel associated with aChannel; - * may be null when aChannel is main process only. - * @param aIdentifier - returned by the process chooser when a decision is - * made to redirect the channel. The identifier is used - * to track the new channel in the other process. - * @return - promise that resolves with a nsITabParent or rejects with nsresult. - * @throws NS_ERROR_NOT_AVAILABLE when redirection is not necessary. - */ - Promise getChannelRedirectTarget(in nsIChannel aChannel, - in nsIParentChannel aParentChannel, - inout unsigned long long aIdentifier); -}; - -[scriptable, uuid(50af805f-e4db-40d9-9dd8-1ae9ab12bdc2)] -interface nsIChildProcessChannelListener : nsISupports -{ - /** - * @param aChildChannel - new child channel - * @param aIdentifier - returned by call to getChannelRedirectTarget. Used to - identify the new channel. - * - * This method has to call aChildChannel->completeRedirectSetup(listener, context) - * in order to be ready for content; listener is a class that implements - * nsIStreamListener. - */ - void onChannelReady(in nsIChildChannel aChildChannel, in unsigned long long aIdentifier); -}; - diff --git a/netwerk/test/browser/browser.ini b/netwerk/test/browser/browser.ini index 6eb2acdebd52..ad53f17fe91b 100644 --- a/netwerk/test/browser/browser.ini +++ b/netwerk/test/browser/browser.ini @@ -2,7 +2,6 @@ support-files = dummy.html ioactivity.html - redirect.sjs [browser_about_cache.js] [browser_NetUtil.js] @@ -14,4 +13,3 @@ skip-if = e10s # protocol handler and channel does not work in content process [browser_resource_navigation.js] [browser_test_io_activity.js] [browser_cookie_sync_across_tabs.js] -[browser_cross_process_redirect.js] diff --git a/netwerk/test/browser/browser_cross_process_redirect.js b/netwerk/test/browser/browser_cross_process_redirect.js deleted file mode 100644 index 1d8e4d46ec71..000000000000 --- a/netwerk/test/browser/browser_cross_process_redirect.js +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -"use strict"; - -const gRegistrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); - -let gLoadedInProcess2Promise = null; - -function _createProcessChooser(tabParent, from, to, rejectPromise = false) { - let processChooser = new ProcessChooser(tabParent, "example.com", "example.org", rejectPromise); - processChooser.onComplete = () => { - gRegistrar.unregisterFactory(processChooser.classID, processChooser); - }; - gRegistrar.registerFactory(processChooser.classID, "", - "@mozilla.org/network/processChooser", - processChooser); - registerCleanupFunction(function() { - if (processChooser.onComplete) { - processChooser.onComplete(); - } - }); -} - -function ProcessChooser(tabParent, from, to, rejectPromise = false) { - this.tabParent = tabParent; - this.fromDomain = from; - this.toDomain = to; - this.rejectPromise = rejectPromise; -} - -ProcessChooser.prototype = { - // nsIRedirectProcessChooser - getChannelRedirectTarget: function(aChannel, aParentChannel, aIdentifier) { - // Don't report failure when returning NS_ERROR_NOT_AVAILABLE - expectUncaughtException(true); - - // let tabParent = aParentChannel.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsITabParent); - if (this.channel && this.channel != aChannel) { - // Hack: this is just so we don't get redirected multiple times. - info("same channel. give null"); - throw Cr.NS_ERROR_NOT_AVAILABLE; - } - - if (aChannel.URI.host != this.toDomain) { - info("wrong host for channel " + aChannel.URI.host); - throw Cr.NS_ERROR_NOT_AVAILABLE; - } - - let redirects = aChannel.loadInfo.redirectChain; - if (redirects[redirects.length - 1].principal.URI.host != this.fromDomain) { - info("didn't find redirect"); - throw Cr.NS_ERROR_NOT_AVAILABLE; - } - - info("returning promise"); - this.channel = aChannel; - let self = this; - - expectUncaughtException(false); - if (this.onComplete) { - this.onComplete(); - this.onComplete = null; - } - aIdentifier.value = 42; - return new Promise((resolve, reject) => { - if (self.rejectPromise) { - info("rejecting"); - reject(Cr.NS_ERROR_NOT_AVAILABLE); - return; - } - // Can asyncly create a tab, or can resolve with a tab that was - // previously created. - info("resolving"); - resolve(self.tabParent); - }); - }, - - // nsIFactory - createInstance: function(aOuter, aIID) { - if (aOuter) { - throw Cr.NS_ERROR_NO_AGGREGATION; - } - return this.QueryInterface(aIID); - }, - lockFactory: function() {}, - - // nsISupports - QueryInterface: ChromeUtils.generateQI([Ci.nsIRedirectProcessChooser, Ci.nsIFactory]), - classID: Components.ID("{62561fa8-c091-4c9f-8897-b59ae18b0979}") -} - -add_task(async function() { - info("Check that a redirect in process A may be correctly handled in process B"); - - const kRoot1 = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", - "https://example.com/"); - const kRoot2 = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", - "https://example.org/"); - const kRoot3 = getRootDirectory(gTestPath); - - // This process will attempt to load the page that redirects to a different origin - let tab1 = await BrowserTestUtils.openNewForegroundTab({ gBrowser, url: kRoot1 + "dummy.html", forceNewProcess: true }); - // This process will eventually receive the redirected channel. - let tab2 = await BrowserTestUtils.openNewForegroundTab({ gBrowser, url: kRoot2 + "dummy.html", forceNewProcess: true }); - - let browser1 = gBrowser.getBrowserForTab(tab1); - let browser2 = gBrowser.getBrowserForTab(tab2); - - // This is for testing purposes only. - // This "process chooser" will direct the channel to be opened in the second - // tab, and thus in the second parent. - let processChooser = _createProcessChooser(browser2.frameLoader.tabParent, "example.com", "example.org"); - - info("Loading redirected URL"); - // Open the URL in the first process. We expect it to wind up in the second - // process. - - // Define the child listener in the new channel. - await ContentTask.spawn(browser2, null, async function(arg) { - function ChannelListener(childListener) { this.childListener = childListener; } - ChannelListener.prototype = { - onStartRequest: function(aRequest, aContext) { - info("onStartRequest"); - let channel = aRequest.QueryInterface(Ci.nsIChannel); - Assert.equal(channel.URI.spec, this.childListener.URI, "Make sure the channel has the proper URI"); - Assert.equal(channel.originalURI.spec, this.childListener.originalURI, "Make sure the originalURI is correct"); - }, - onStopRequest: function(aRequest, aContext, aStatusCode) { - info("onStopRequest"); - Assert.equal(aStatusCode, Cr.NS_OK, "Check the status code"); - Assert.equal(this.gotData, true, "Check that the channel received data"); - if (this.childListener.onComplete) { - this.childListener.onComplete(); - } - this.childListener.resolve(); - }, - onDataAvailable: function(aRequest, aContext, aInputStream, - aOffset, aCount) { - this.gotData = true; - info("onDataAvailable"); - }, - QueryInterface: ChromeUtils.generateQI([Ci.nsIStreamListener, - Ci.nsIRequestObserver]) - }; - - function ChildListener(uri, originalURI, resolve) { this.URI = uri; this.originalURI = originalURI; this.resolve = resolve;} - ChildListener.prototype = { - // nsIChildProcessChannelListener - onChannelReady: function(aChildChannel, aIdentifier) { - Assert.equal(aIdentifier, 42, "Check the status code"); - info("onChannelReady"); - aChildChannel.completeRedirectSetup(new ChannelListener(this), null); - }, - // nsIFactory - createInstance: function(aOuter, aIID) { - if (aOuter) { - throw Cr.NS_ERROR_NO_AGGREGATION; - } - return this.QueryInterface(aIID); - }, - lockFactory: function() {}, - // nsISupports - QueryInterface: ChromeUtils.generateQI([Ci.nsIChildProcessChannelListener, Ci.nsIFactory]), - classID: Components.ID("{a6c142a9-eb38-4a09-a940-b71cdad479e1}") - } - - content.window.ChildListener = ChildListener; - }); - - // This promise instantiates a ChildListener and is resolved when the redirected - // channel is completed. - let loadedInProcess2Promise = ContentTask.spawn(browser2, { URI: kRoot2 + "dummy.html", originalURI: kRoot1 + "redirect.sjs?" + kRoot2 + "dummy.html"}, async function(arg) { - // We register the listener in process no. 2 - return new Promise(resolve => { - var childListener = new content.window.ChildListener(arg.URI, arg.originalURI, resolve); - var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); - childListener.onComplete = () => { - registrar.unregisterFactory(childListener.classID, childListener); - } - registrar.registerFactory(childListener.classID, "", - "@mozilla.org/network/childProcessChannelListener", - childListener); - }); - }); - - let browser1LoadHasStopped = BrowserTestUtils.browserStopped(browser1); - - await BrowserTestUtils.loadURI(browser1, kRoot1 + "redirect.sjs?" + kRoot2 + "dummy.html"); - - // Check that the channel was delivered to process no. 2 - await loadedInProcess2Promise; - info("channel has loaded in second process"); - // This is to check that the old channel was cancelled. - await browser1LoadHasStopped; - - // check that a rejected promise also works. - processChooser = _createProcessChooser(browser2.frameLoader.tabParent, "example.com", "example.org", true); - let browser1LoadHasStoppedAgain = BrowserTestUtils.browserStopped(browser1); - await BrowserTestUtils.loadURI(browser1, kRoot1 + "redirect.sjs?" + kRoot2 + "dummy.html"); - await browser1LoadHasStoppedAgain; - info("this is done now"); - - BrowserTestUtils.removeTab(tab1); - BrowserTestUtils.removeTab(tab2); - - ok(true, "Got to the end of the test!"); -}); diff --git a/netwerk/test/browser/redirect.sjs b/netwerk/test/browser/redirect.sjs deleted file mode 100644 index 7599fe33fb50..000000000000 --- a/netwerk/test/browser/redirect.sjs +++ /dev/null @@ -1,7 +0,0 @@ -function handleRequest(request, response) -{ - response.setStatusLine(request.httpVersion, 301, "Moved Permanently"); - let location = request.queryString; - response.setHeader("Location", location, false); - response.write("Hello world!"); -} From fd954f186947a02e3c3187504cfc7f7d1d71b09f Mon Sep 17 00:00:00 2001 From: Gijs Kruitbosch Date: Tue, 4 Sep 2018 17:10:09 +0000 Subject: [PATCH 43/61] Bug 237027 - allow turning off URL canonization, remove shift support, and move the remainder from 'cmd' to 'ctrl' on mac, r=mak This avoids the conflict with cmd-enter/click to open links in new tabs on macOS. It also removes support for the use of `shift` to complete to '.net', and allows users to toggle a pref to turn off `ctrl` support on all OSes. Differential Revision: https://phabricator.services.mozilla.com/D2604 --HG-- extra : moz-landing-system : lando --- browser/app/profile/firefox.js | 6 ++ .../test/urlbar/browser_canonizeURL.js | 80 ++++++++++++++----- .../urlbar/browser_urlbarSearchSuggestions.js | 5 +- .../browser_urlbar_canonize_on_autofill.js | 14 +--- browser/base/content/urlbarBindings.xml | 62 +++++++------- 5 files changed, 96 insertions(+), 71 deletions(-) diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index c3c6ce724dad..48fe6662141d 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -271,6 +271,12 @@ pref("browser.urlbar.doubleClickSelectsAll", true); pref("browser.urlbar.doubleClickSelectsAll", false); #endif +// Whether using `ctrl` when hitting return/enter in the URL bar +// (or clicking 'go') should prefix 'www.' and suffix +// browser.fixup.alternate.suffix to the URL bar value prior to +// navigating. +pref("browser.urlbar.ctrlCanonizesURLs", true); + // Control autoFill behavior pref("browser.urlbar.autoFill", true); pref("browser.urlbar.speculativeConnect.enabled", true); diff --git a/browser/base/content/test/urlbar/browser_canonizeURL.js b/browser/base/content/test/urlbar/browser_canonizeURL.js index 0b848e36cb9e..c301589d40b1 100644 --- a/browser/base/content/test/urlbar/browser_canonizeURL.js +++ b/browser/base/content/test/urlbar/browser_canonizeURL.js @@ -1,29 +1,34 @@ -add_task(async function() { +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +const TEST_ENGINE_BASENAME = "searchSuggestionEngine.xml"; + +add_task(async function checkCtrlWorks() { let testcases = [ - ["example", "http://www.example.net/", { shiftKey: true }], + ["example", "http://www.example.com/", { ctrlKey: true }], // Check that a direct load is not overwritten by a previous canonization. ["http://example.com/test/", "http://example.com/test/", {}], - ["ex-ample", "http://www.ex-ample.net/", { shiftKey: true }], - [" example ", "http://www.example.net/", { shiftKey: true }], - [" example/foo ", "http://www.example.net/foo", { shiftKey: true }], - [" example/foo bar ", "http://www.example.net/foo%20bar", { shiftKey: true }], - ["example.net", "http://example.net/", { shiftKey: true }], - ["http://example", "http://example/", { shiftKey: true }], - ["example:8080", "http://example:8080/", { shiftKey: true }], - ["ex-ample.foo", "http://ex-ample.foo/", { shiftKey: true }], - ["example.foo/bar ", "http://example.foo/bar", { shiftKey: true }], - ["1.1.1.1", "http://1.1.1.1/", { shiftKey: true }], - ["ftp://example", "ftp://example/", { shiftKey: true }], - ["ftp.example.bar", "http://ftp.example.bar/", { shiftKey: true }], - ["ex ample", Services.search.defaultEngine.getSubmission("ex ample", null, "keyword").uri.spec, { shiftKey: true }], + + ["ex-ample", "http://www.ex-ample.com/", { ctrlKey: true }], + [" example ", "http://www.example.com/", { ctrlKey: true }], + [" example/foo ", "http://www.example.com/foo", { ctrlKey: true }], + [" example/foo bar ", "http://www.example.com/foo%20bar", { ctrlKey: true }], + ["example.net", "http://example.net/", { ctrlKey: true }], + ["http://example", "http://example/", { ctrlKey: true }], + ["example:8080", "http://example:8080/", { ctrlKey: true }], + ["ex-ample.foo", "http://ex-ample.foo/", { ctrlKey: true }], + ["example.foo/bar ", "http://example.foo/bar", { ctrlKey: true }], + ["1.1.1.1", "http://1.1.1.1/", { ctrlKey: true }], + ["ftp://example", "ftp://example/", { ctrlKey: true }], + ["ftp.example.bar", "http://ftp.example.bar/", { ctrlKey: true }], + ["ex ample", Services.search.defaultEngine.getSubmission("ex ample", null, "keyword").uri.spec, { ctrlKey: true }], ]; // Disable autoFill for this test, since it could mess up the results. - let autoFill = Preferences.get("browser.urlbar.autoFill"); - Preferences.set("browser.urlbar.autoFill", false); - registerCleanupFunction(() => { - Preferences.set("browser.urlbar.autoFill", autoFill); - }); + await SpecialPowers.pushPrefEnv({set: [ + ["browser.urlbar.autoFill", false], + ["browser.urlbar.ctrlCanonizesURLs", true], + ]}); for (let [inputValue, expectedURL, options] of testcases) { let promiseLoad = waitForDocLoadAndStopIt(expectedURL); @@ -40,3 +45,38 @@ add_task(async function() { await promiseLoad; } }); + +add_task(async function checkPrefTurnsOffCanonize() { + // Add a dummy search engine to avoid hitting the network. + let engine = await SearchTestUtils.promiseNewSearchEngine( + getRootDirectory(gTestPath) + TEST_ENGINE_BASENAME); + let oldCurrentEngine = Services.search.currentEngine; + Services.search.currentEngine = engine; + registerCleanupFunction(() => { Services.search.currentEngine = oldCurrentEngine; }); + + let tabsToClose = []; + // Ensure we don't end up loading something in the current tab becuase it's empty: + if (isTabEmpty(gBrowser.selectedTab)) { + tabsToClose.push(await BrowserTestUtils.openNewForegroundTab({gBrowser, opening: "about:mozilla"})); + } + let initialTabURL = gBrowser.selectedBrowser.currentURI.spec; + let initialTab = gBrowser.selectedTab; + await SpecialPowers.pushPrefEnv({set: [["browser.urlbar.ctrlCanonizesURLs", false]]}); + + let promiseTabOpened = BrowserTestUtils.waitForNewTab(gBrowser); + + gURLBar.focus(); + gURLBar.selectionStart = gURLBar.selectionEnd = + gURLBar.inputField.value.length; + gURLBar.inputField.value = "exampl"; + EventUtils.sendString("e"); + EventUtils.synthesizeKey("KEY_Enter", AppConstants.platform == "macosx" ? + {metaKey: true} : {ctrlKey: true}); + + tabsToClose.push(await promiseTabOpened); + is(initialTab.linkedBrowser.currentURI.spec, initialTabURL, + "Original tab shouldn't have navigated"); + for (let t of tabsToClose) { + gBrowser.removeTab(t); + } +}); diff --git a/browser/base/content/test/urlbar/browser_urlbarSearchSuggestions.js b/browser/base/content/test/urlbar/browser_urlbarSearchSuggestions.js index 895ffbbba57b..740f1fe84386 100644 --- a/browser/base/content/test/urlbar/browser_urlbarSearchSuggestions.js +++ b/browser/base/content/test/urlbar/browser_urlbarSearchSuggestions.js @@ -70,10 +70,7 @@ add_task(async function plainEnterOnSuggestion() { }); add_task(async function ctrlEnterOnSuggestion() { - await testPressEnterOnSuggestion("http://www.foofoo.com/", - AppConstants.platform === "macosx" ? - { metaKey: true } : - { ctrlKey: true }); + await testPressEnterOnSuggestion("http://www.foofoo.com/", { ctrlKey: true }); }); add_task(async function copySuggestionText() { diff --git a/browser/base/content/test/urlbar/browser_urlbar_canonize_on_autofill.js b/browser/base/content/test/urlbar/browser_urlbar_canonize_on_autofill.js index 5061ee35136a..a7168a8c858b 100644 --- a/browser/base/content/test/urlbar/browser_urlbar_canonize_on_autofill.js +++ b/browser/base/content/test/urlbar/browser_urlbar_canonize_on_autofill.js @@ -1,7 +1,7 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ -/* This test ensures that pressing ctrl/shift+enter bypasses the autoFilled +/* This test ensures that pressing ctrl+enter bypasses the autoFilled * value, and only considers what the user typed (but not just enter). */ @@ -49,16 +49,6 @@ add_task(async function() { autofilled: "example.com/", modified: "www.exam.com", waitForUrl: "http://www.exam.com/", - keys: [["KEY_Enter", AppConstants.platform === "macosx" ? - {metaKey: true} : - {ctrlKey: true}]], - }); - - await test_autocomplete({ desc: "SHIFT+ENTER on the autofilled part should bypass autofill", - typed: "exam", - autofilled: "example.com/", - modified: "www.exam.net", - waitForUrl: "http://www.exam.net/", - keys: [["KEY_Enter", {shiftKey: true}]], + keys: [["KEY_Enter", {ctrlKey: true}]], }); }); diff --git a/browser/base/content/urlbarBindings.xml b/browser/base/content/urlbarBindings.xml index a537e48901fb..53984e06dc6e 100644 --- a/browser/base/content/urlbarBindings.xml +++ b/browser/base/content/urlbarBindings.xml @@ -85,6 +85,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/. this._formattingEnabled = this._prefs.getBoolPref("formatting.enabled"); this._mayTrimURLs = this._prefs.getBoolPref("trimURLs"); this._adoptIntoActiveWindow = this._prefs.getBoolPref("switchTabs.adoptIntoActiveWindow"); + this._ctrlCanonizesURLs = this._prefs.getBoolPref("ctrlCanonizesURLs"); this.inputField.controllers.insertControllerAt(0, this._copyCutController); this.inputField.addEventListener("paste", this); this.inputField.addEventListener("mousedown", this); @@ -713,11 +714,16 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/. let isMouseEvent = event instanceof MouseEvent; let reuseEmpty = !isMouseEvent; let where = undefined; - if (isMouseEvent) { - where = whereToOpenLink(event, false, false); + if (!isMouseEvent && event && event.altKey) { + // We support using 'alt' to open in a tab, because ctrl/shift + // might be used for canonizing URLs: + where = event.shiftKey ? "tabshifted" : "tab"; + } else if (!isMouseEvent && this._ctrlCanonizesURLs && event && event.ctrlKey) { + // If we're allowing canonization, and this is a key event with ctrl + // pressed, open in current tab to allow ctrl-enter to canonize URL. + where = "current"; } else { - let altEnter = event && event.altKey; - where = altEnter ? "tab" : "current"; + where = whereToOpenLink(event, false, false); } if (this.openInTab) { if (where == "current") { @@ -848,6 +854,12 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/. } return; } + + // Once we get here, we got a switchtab action but the user + // bypassed it by pressing shift/meta/ctrl. Those modifiers + // might otherwise affect where we open - we always want to + // open in the current tab. + where = "current"; break; case "searchengine": if (selectedOneOff && selectedOneOff.engine) { @@ -1027,40 +1039,19 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/. // Only add the suffix when the URL bar value isn't already "URL-like", // and only if we get a keyboard event, to match user expectations. if (!/^\s*[^.:\/\s]+(?:\/.*|\s*)$/i.test(aUrl) || - !(aTriggeringEvent instanceof KeyboardEvent)) { + !this._ctrlCanonizesURLs || + !(aTriggeringEvent instanceof KeyboardEvent) || + !aTriggeringEvent.ctrlKey) { return; } - let url = aUrl; - let accel = AppConstants.platform == "macosx" ? - aTriggeringEvent.metaKey : - aTriggeringEvent.ctrlKey; - let shift = aTriggeringEvent.shiftKey; - let suffix = ""; - - switch (true) { - case (accel && shift): - suffix = ".org/"; - break; - case (shift): - suffix = ".net/"; - break; - case (accel): - try { - suffix = Services.prefs.getCharPref("browser.fixup.alternate.suffix"); - if (suffix.charAt(suffix.length - 1) != "/") - suffix += "/"; - } catch (e) { - suffix = ".com/"; - } - break; + let suffix = Services.prefs.getCharPref("browser.fixup.alternate.suffix", ".com/"); + if (!suffix.endsWith("/")) { + suffix += "/"; } - if (!suffix) - return; - // trim leading/trailing spaces (bug 233205) - url = url.trim(); + let url = aUrl.trim(); // Tack www. and suffix on. If user has appended directories, insert // suffix before them (bug 279035). Be careful not to get two slashes. @@ -1331,6 +1322,9 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/. case "formatting.enabled": this._formattingEnabled = this._prefs.getBoolPref(aData); break; + case "ctrlCanonizesURLs": + this._ctrlCanonizesURLs = this._prefs.getBoolPref(aData); + break; case "speculativeConnect.enabled": this.speculativeConnectEnabled = this._prefs.getBoolPref(aData); break; @@ -1657,9 +1651,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/. } let canonizeValue = this.value; - if (event.shiftKey || (AppConstants.platform === "macosx" ? - event.metaKey : - event.ctrlKey)) { + if (event.ctrlKey) { let action = this._parseActionUrl(canonizeValue); if (action && "searchSuggestion" in action.params) { canonizeValue = action.params.searchSuggestion; From 793280d394972d0bf6cd651a38dde76a55addb4b Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Tue, 4 Sep 2018 17:38:16 +0000 Subject: [PATCH 44/61] Bug 1451527 - Move sync's TPS tests into a webextension r=markh Differential Revision: https://phabricator.services.mozilla.com/D4486 --HG-- extra : moz-landing-system : lando --- services/sync/tps/extensions/tps/api.js | 74 +++++++++++++ services/sync/tps/extensions/tps/bootstrap.js | 104 ------------------ services/sync/tps/extensions/tps/install.rdf | 30 ----- .../sync/tps/extensions/tps/manifest.json | 23 ++++ .../tps/resource/auth/fxaccounts.jsm | 2 +- .../tps/resource/modules/formautofill.jsm | 8 +- services/sync/tps/extensions/tps/schema.json | 1 + testing/tps/tps/phase.py | 21 ++-- testing/tps/tps/testrunner.py | 3 +- 9 files changed, 120 insertions(+), 146 deletions(-) create mode 100644 services/sync/tps/extensions/tps/api.js delete mode 100644 services/sync/tps/extensions/tps/bootstrap.js delete mode 100644 services/sync/tps/extensions/tps/install.rdf create mode 100644 services/sync/tps/extensions/tps/manifest.json create mode 100644 services/sync/tps/extensions/tps/schema.json diff --git a/services/sync/tps/extensions/tps/api.js b/services/sync/tps/extensions/tps/api.js new file mode 100644 index 000000000000..265275aa35c0 --- /dev/null +++ b/services/sync/tps/extensions/tps/api.js @@ -0,0 +1,74 @@ +/* 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/. */ + +ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); +ChromeUtils.import("resource://gre/modules/Services.jsm"); +ChromeUtils.import("resource://gre/modules/FileUtils.jsm"); +ChromeUtils.import("resource://gre/modules/Timer.jsm"); + +/* globals ExtensionAPI */ + +XPCOMUtils.defineLazyServiceGetter(this, "resProto", + "@mozilla.org/network/protocol;1?name=resource", + "nsISubstitutingProtocolHandler"); + +async function tpsStartup() { + try { + ChromeUtils.import("resource://tps/tps.jsm"); + ChromeUtils.import("resource://tps/quit.js", TPS); + + let testFile = Services.prefs.getStringPref("testing.tps.testFile", ""); + let testPhase = Services.prefs.getStringPref("testing.tps.testPhase", ""); + if (!testFile || !testPhase) { + // Note: this quits. + TPS.DumpError("TPS no longer takes arguments from the command line. " + + "instead you need to pass preferences `testing.tps.{testFile,testPhase}` " + + "and optionally `testing.tps.{logFile,ignoreUnusedEngines}`.\n"); + } + + let logFile = Services.prefs.getStringPref("testing.tps.logFile", ""); + let ignoreUnusedEngines = Services.prefs.getBoolPref("testing.tps.ignoreUnusedEngines", false); + let options = { ignoreUnusedEngines }; + let testFileUri = Services.io.newFileURI(new FileUtils.File(testFile)).spec; + + try { + await TPS.RunTestPhase(testFileUri, testPhase, logFile, options); + } catch (err) { + TPS.DumpError("TestPhase failed", err); + } + } catch (e) { + if (typeof TPS != "undefined") { + // Note: This calls quit() under the hood + TPS.DumpError("Test initialization failed", e); + } + // Try and quit right away, no reason to wait around for python + // to kill us if initialization failed. + Services.startup.quit(Ci.nsIAppStartup.eForceQuit); + } +} + +function onStartupFinished() { + return new Promise(resolve => { + const onStartupFinished = () => { + Services.obs.removeObserver(onStartupFinished, "browser-delayed-startup-finished"); + resolve(); + }; + Services.obs.addObserver(onStartupFinished, "browser-delayed-startup-finished"); + }); +} + +this.tps = class extends ExtensionAPI { + onStartup() { + resProto.setSubstitution("tps", + Services.io.newURI("resource/", null, this.extension.rootURI)); + /* Ignore the platform's online/offline status while running tests. */ + Services.io.manageOfflineStatus = false; + Services.io.offline = false; + tpsStartup(); + } + + onShutdown() { + resProto.setSubstitution("tps", null); + } +}; diff --git a/services/sync/tps/extensions/tps/bootstrap.js b/services/sync/tps/extensions/tps/bootstrap.js deleted file mode 100644 index 7f126d069f8a..000000000000 --- a/services/sync/tps/extensions/tps/bootstrap.js +++ /dev/null @@ -1,104 +0,0 @@ -/* 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/. */ - - -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); -ChromeUtils.import("resource://gre/modules/Services.jsm"); -ChromeUtils.import("resource://gre/modules/osfile.jsm"); - -XPCOMUtils.defineLazyServiceGetter(this, "resProto", - "@mozilla.org/network/protocol;1?name=resource", - "nsISubstitutingProtocolHandler"); - -const Cm = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); - -const CATMAN_CONTRACTID = "@mozilla.org/categorymanager;1"; - -const CATEGORY_NAME = "command-line-handler"; -const CATEGORY_ENTRY = "m-tps"; - -function TPSCmdLine() {} - -TPSCmdLine.prototype = { - factory: XPCOMUtils._getFactory(TPSCmdLine), - classDescription: "TPSCmdLine", - classID: Components.ID("{4e5bd3f0-41d3-11df-9879-0800200c9a66}"), - contractID: "@mozilla.org/commandlinehandler/general-startup;1?type=tps", - - QueryInterface: ChromeUtils.generateQI([Ci.nsICommandLineHandler]), - - register() { - Cm.registerFactory(this.classID, this.classDescription, - this.contractID, this.factory); - - Services.catMan.addCategoryEntry(CATEGORY_NAME, CATEGORY_ENTRY, - this.contractID, false, true); - }, - - unregister() { - Services.catMan.deleteCategoryEntry(CATEGORY_NAME, CATEGORY_ENTRY, - this.contractID, false); - - Cm.unregisterFactory(this.classID, this.factory); - }, - - /* nsICmdLineHandler */ - commandLineArgument: "-tps", - prefNameForStartup: "general.startup.tps", - helpText: "Run TPS tests with the given test file.", - handlesArgs: true, - defaultArgs: "", - openWindowWithArgs: true, - - /* nsICommandLineHandler */ - handle: function handler_handle(cmdLine) { - let options = {}; - - let uristr = cmdLine.handleFlagWithParam("tps", false); - if (uristr == null) { - return; - } - let phase = cmdLine.handleFlagWithParam("tpsphase", false); - if (phase == null) { - throw Error("must specify --tpsphase with --tps"); - } - let logfile = cmdLine.handleFlagWithParam("tpslogfile", false); - if (logfile == null) { - logfile = ""; - } - - options.ignoreUnusedEngines = cmdLine.handleFlag("ignore-unused-engines", - false); - let uri = cmdLine.resolveURI(OS.Path.normalize(uristr)).spec; - - const onStartupFinished = () => { - Services.obs.removeObserver(onStartupFinished, "browser-delayed-startup-finished"); - /* Ignore the platform's online/offline status while running tests. */ - Services.io.manageOfflineStatus = false; - Services.io.offline = false; - ChromeUtils.import("resource://tps/tps.jsm"); - ChromeUtils.import("resource://tps/quit.js", TPS); - TPS.RunTestPhase(uri, phase, logfile, options).catch(err => TPS.DumpError("TestPhase failed", err)); - }; - Services.obs.addObserver(onStartupFinished, "browser-delayed-startup-finished"); - }, - - helpInfo: " --tps Run TPS tests with the given test file.\n" + - " --tpsphase Run the specified phase in the TPS test.\n" + - " --tpslogfile Logfile for TPS output.\n" + - " --ignore-unused-engines Don't load engines not used in tests.\n", -}; - -function startup(data, reason) { - TPSCmdLine.prototype.register(); - resProto.setSubstitution("tps", Services.io.newURI("resource/", null, data.resourceURI)); -} - -function shutdown(data, reason) { - resProto.setSubstitution("tps", null); - TPSCmdLine.prototype.unregister(); -} - -function install(data, reason) {} -function uninstall(data, reason) {} diff --git a/services/sync/tps/extensions/tps/install.rdf b/services/sync/tps/extensions/tps/install.rdf deleted file mode 100644 index f9f060af129d..000000000000 --- a/services/sync/tps/extensions/tps/install.rdf +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - tps@mozilla.org - 0.5 - true - - - - - {ec8030f7-c20a-464f-9b0e-13a3a9e97384} - 24.0.* - * - - - - - TPS - Sync test extension - Jonathan Griffin - Henrik Skupin - https://developer.mozilla.org/en-US/docs/TPS - true - - diff --git a/services/sync/tps/extensions/tps/manifest.json b/services/sync/tps/extensions/tps/manifest.json new file mode 100644 index 000000000000..2de6e902c689 --- /dev/null +++ b/services/sync/tps/extensions/tps/manifest.json @@ -0,0 +1,23 @@ +{ + "manifest_version": 2, + "name": "TPS", + "version": "1.0", + + "applications": { + "gecko": { + "id": "tps@mozilla.org" + } + }, + + "experiment_apis": { + "tps": { + "schema": "schema.json", + "parent": { + "scopes": ["addon_parent"], + "script": "api.js", + "paths": [["tps"]], + "events": ["startup"] + } + } + } +} diff --git a/services/sync/tps/extensions/tps/resource/auth/fxaccounts.jsm b/services/sync/tps/extensions/tps/resource/auth/fxaccounts.jsm index 0f58459a8586..aff0ec141ab9 100644 --- a/services/sync/tps/extensions/tps/resource/auth/fxaccounts.jsm +++ b/services/sync/tps/extensions/tps/resource/auth/fxaccounts.jsm @@ -64,7 +64,7 @@ var Authentication = { async _openVerificationPage(uri) { let mainWindow = Services.wm.getMostRecentWindow("navigator:browser"); - let newtab = mainWindow.getBrowser().addTab(uri); + let newtab = mainWindow.getBrowser().addWebTab(uri); let win = mainWindow.getBrowser().getBrowserForTab(newtab); await new Promise(resolve => { win.addEventListener("loadend", resolve, { once: true }); diff --git a/services/sync/tps/extensions/tps/resource/modules/formautofill.jsm b/services/sync/tps/extensions/tps/resource/modules/formautofill.jsm index 23feb3f8027d..60a022159b2b 100644 --- a/services/sync/tps/extensions/tps/resource/modules/formautofill.jsm +++ b/services/sync/tps/extensions/tps/resource/modules/formautofill.jsm @@ -10,8 +10,12 @@ var EXPORTED_SYMBOLS = ["Address", "CreditCard", "DumpAddresses", "DumpCreditCards"]; ChromeUtils.import("resource://tps/logger.jsm"); -ChromeUtils.import("resource://formautofill/FormAutofillStorage.jsm"); -ChromeUtils.import("resource://formautofill/MasterPassword.jsm"); + +ChromeUtils.defineModuleGetter(this, "formAutofillStorage", + "resource://formautofill/FormAutofillStorage.jsm"); + +ChromeUtils.defineModuleGetter(this, "MasterPassword", + "resource://formautofill/MasterPassword.jsm"); class FormAutofillBase { constructor(props, subStorageName, fields) { diff --git a/services/sync/tps/extensions/tps/schema.json b/services/sync/tps/extensions/tps/schema.json new file mode 100644 index 000000000000..0637a088a01e --- /dev/null +++ b/services/sync/tps/extensions/tps/schema.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/testing/tps/tps/phase.py b/testing/tps/tps/phase.py index 397c90796297..85a9e23d2485 100644 --- a/testing/tps/tps/phase.py +++ b/testing/tps/tps/phase.py @@ -3,6 +3,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. import re +import os.path class TPSTestPhase(object): @@ -29,17 +30,21 @@ class TPSTestPhase(object): def run(self): # launch Firefox - args = [ '-tps', self.testpath, - '-tpsphase', self.phase, - '-tpslogfile', self.logfile ] - if self.ignore_unused_engines: - args.append('--ignore-unused-engines') + prefs = { + "testing.tps.testFile": os.path.abspath(self.testpath), + "testing.tps.testPhase": self.phase, + "testing.tps.logFile": self.logfile, + "testing.tps.ignoreUnusedEngines": self.ignore_unused_engines + } + + self.profile.set_preferences(prefs); + + self.log('\nLaunching Firefox for phase %s with prefs %s\n' % + (self.phase, str(prefs))) - self.log('\nLaunching Firefox for phase %s with args %s\n' % - (self.phase, str(args))) self.firefoxRunner.run(env=self.env, - args=args, + args=[], profile=self.profile) # parse the logfile and look for results from the current test phase diff --git a/testing/tps/tps/testrunner.py b/testing/tps/tps/testrunner.py index 12cad820038b..1640794e1bf5 100644 --- a/testing/tps/tps/testrunner.py +++ b/testing/tps/tps/testrunner.py @@ -235,7 +235,7 @@ class TPSTestRunner(object): # create the profile if necessary if not profilename in profiles: - profiles[profilename] = Profile(preferences = self.preferences, + profiles[profilename] = Profile(preferences = self.preferences.copy(), addons = self.extensions) # create the test phase @@ -262,6 +262,7 @@ class TPSTestRunner(object): break; for profilename in profiles: + print "### Cleanup Profile ", profilename cleanup_phase = TPSTestPhase( 'cleanup-' + profilename, profiles[profilename], testname, From 8d537bb798a80eeb2ec42cc4e47b5446a1b25742 Mon Sep 17 00:00:00 2001 From: Yura Zenevich Date: Tue, 4 Sep 2018 17:21:44 +0000 Subject: [PATCH 45/61] Bug 1488508 - update help icon to use Photon style system. r=gl MozReview-Commit-ID: 75efDzRq187 Differential Revision: https://phabricator.services.mozilla.com/D4958 --HG-- extra : moz-landing-system : lando --- devtools/client/aboutdebugging/aboutdebugging.css | 1 - devtools/client/accessibility/accessibility.css | 1 + devtools/client/debugger/new/dist/debugger.css | 1 + devtools/client/shared/components/MdnLink.css | 1 + devtools/client/themes/images/help.svg | 5 +++-- 5 files changed, 6 insertions(+), 3 deletions(-) diff --git a/devtools/client/aboutdebugging/aboutdebugging.css b/devtools/client/aboutdebugging/aboutdebugging.css index e65c3f71e561..e7db2894705c 100644 --- a/devtools/client/aboutdebugging/aboutdebugging.css +++ b/devtools/client/aboutdebugging/aboutdebugging.css @@ -227,7 +227,6 @@ button { height: 24px; background-image: url(chrome://devtools/skin/images/help.svg); background-repeat: no-repeat; - background-size: 24px; flex-shrink: 0; margin-inline-end: 8px; } diff --git a/devtools/client/accessibility/accessibility.css b/devtools/client/accessibility/accessibility.css index 8d09c24e6228..623249dc5d39 100644 --- a/devtools/client/accessibility/accessibility.css +++ b/devtools/client/accessibility/accessibility.css @@ -116,6 +116,7 @@ body { width: 16px; height: 16px; mask: url("chrome://devtools/skin/images/help.svg") no-repeat; + mask-size: contain; } .devtools-toolbar .help:focus { diff --git a/devtools/client/debugger/new/dist/debugger.css b/devtools/client/debugger/new/dist/debugger.css index a00e5f595274..e1d3a693c9f8 100644 --- a/devtools/client/debugger/new/dist/debugger.css +++ b/devtools/client/debugger/new/dist/debugger.css @@ -3766,6 +3766,7 @@ img.skipPausing { .command-bar img.shortcuts { mask: url("chrome://devtools/skin/images/help.svg") no-repeat; + mask-size: contain; } .command-bar .replay-inactive { diff --git a/devtools/client/shared/components/MdnLink.css b/devtools/client/shared/components/MdnLink.css index e80583e65fdd..6f231f6518d4 100644 --- a/devtools/client/shared/components/MdnLink.css +++ b/devtools/client/shared/components/MdnLink.css @@ -6,6 +6,7 @@ .network-monitor .learn-more-link::before { background-image: url(chrome://devtools/skin/images/help.svg); + background-size: contain; } .network-monitor .tree-container .treeTable tr .learn-more-link { diff --git a/devtools/client/themes/images/help.svg b/devtools/client/themes/images/help.svg index 737218ce1781..9dc7e80c1f8e 100644 --- a/devtools/client/themes/images/help.svg +++ b/devtools/client/themes/images/help.svg @@ -1,6 +1,7 @@ - - + + + From 1a098a6537f40714a2c6d7e2764d7314652dd6b5 Mon Sep 17 00:00:00 2001 From: egao Date: Tue, 4 Sep 2018 14:15:42 +0000 Subject: [PATCH 46/61] Bug 1484238 - Add an 'adb_reverse' command to mozdevice.ADBAndroid r=gbrown,bc Differential Revision: https://phabricator.services.mozilla.com/D4775 --HG-- extra : moz-landing-system : lando --- testing/mozbase/mozdevice/mozdevice/adb.py | 117 ++++++++++++++++----- testing/mozbase/mozdevice/setup.py | 2 +- 2 files changed, 94 insertions(+), 25 deletions(-) diff --git a/testing/mozbase/mozdevice/mozdevice/adb.py b/testing/mozbase/mozdevice/mozdevice/adb.py index 3e164829fd65..2082ea0e075c 100644 --- a/testing/mozbase/mozdevice/mozdevice/adb.py +++ b/testing/mozbase/mozdevice/mozdevice/adb.py @@ -529,6 +529,9 @@ class ADBDevice(ADBCommand): """ __metaclass__ = ABCMeta + SOCKET_DIRECTON_REVERSE = "reverse" + SOCKET_DIRECTON_FORWARD = "forward" + def __init__(self, device=None, adb='adb', @@ -962,7 +965,7 @@ class ADBDevice(ADBCommand): device_serial=self._device_serial, timeout=timeout) - # Port forwarding methods + # Networking methods def _validate_port(self, port, is_local=True): """Validate a port forwarding specifier. Raises ValueError on failure. @@ -977,22 +980,24 @@ class ADBDevice(ADBCommand): parts = port.split(":", 1) if len(parts) != 2 or parts[0] not in prefixes: - raise ValueError("Invalid forward specifier %s" % port) + raise ValueError("Invalid port specifier %s" % port) - def forward(self, local, remote, allow_rebind=True, timeout=None): - """Forward a local port to a specific port on the device. + def _validate_direction(self, direction): + """Validate direction of the socket connection. Raises ValueError on failure. - Ports are specified in the form: - tcp: - localabstract: - localreserved: - localfilesystem: - dev: - jdwp: (remote only) + :param str direction: The socket direction specifier to validate + :raises: * ValueError + """ + if direction not in [self.SOCKET_DIRECTON_FORWARD, self.SOCKET_DIRECTON_REVERSE]: + raise ValueError('Invalid direction specifier {}'.format(direction)) - :param str local: Local port to forward - :param str remote: Remote port to which to forward - :param bool allow_rebind: Don't error if the local port is already forwarded + def create_socket_connection(self, direction, local, remote, allow_rebind=True, timeout=None): + """Sets up a socket connection in the specified direction. + + :param str direction: Direction of the socket connection + :param str local: Local port + :param str remote: Remote port + :param bool allow_rebind: Do not fail if port is already bound :param timeout: The maximum time in seconds for any spawned adb process to complete before throwing an ADBTimeoutError. If it is not specified, the value @@ -1002,34 +1007,46 @@ class ADBDevice(ADBCommand): * ADBTimeoutError * ADBError """ - + # validate socket direction, and local and remote port formatting. + self._validate_direction(direction) for port, is_local in [(local, True), (remote, False)]: self._validate_port(port, is_local=is_local) - cmd = ["forward", local, remote] + cmd = [direction, local, remote] + if not allow_rebind: cmd.insert(1, "--no-rebind") + + # execute commands to establish socket connection. self.command_output(cmd, timeout=timeout) - def list_forwards(self, timeout=None): - """Return a list of tuples specifying active forwards + def list_socket_connections(self, direction, timeout=None): + """Return a list of tuples specifying active socket connectionss. Return values are of the form (device, local, remote). + :param str direction: 'forward' to list forward socket connections + 'reverse' to list reverse socket connections :param timeout: The maximum time in seconds for any spawned adb process to complete before throwing an ADBTimeoutError. If it is not specified, the value set in the ADBDevice constructor is used. :type timeout: integer or None - :raises: * ADBTimeoutError + :raises: * ValueError + * ADBTimeoutError * ADBError """ - forwards = self.command_output(["forward", "--list"], timeout=timeout) - return [tuple(line.split(" ")) for line in forwards.splitlines() if line.strip()] + self._validate_direction(direction) - def remove_forwards(self, local=None, timeout=None): - """Remove existing port forwards. + cmd = [direction, "--list"] + output = self.command_output(cmd, timeout=timeout) + return [tuple(line.split(" ")) for line in output.splitlines() if line.strip()] + def remove_socket_connections(self, direction, local=None, timeout=None): + """Remove existing socket connections for a given direction. + + :param str direction: 'forward' to remove forward socket connection + 'reverse' to remove reverse socket connection :param local: local port specifier as for ADBDevice.forward. If local is not specified removes all forwards. :type local: str or None @@ -1042,7 +1059,10 @@ class ADBDevice(ADBCommand): * ADBTimeoutError * ADBError """ - cmd = ["forward"] + self._validate_direction(direction) + + cmd = [direction] + if local is None: cmd.extend(["--remove-all"]) else: @@ -1051,6 +1071,55 @@ class ADBDevice(ADBCommand): self.command_output(cmd, timeout=timeout) + # Legacy port forward methods + + def forward(self, local, remote, allow_rebind=True, timeout=None): + """Forward a local port to a specific port on the device. + + See `ADBDevice.create_socket_connection`. + """ + self.create_socket_connection(self.SOCKET_DIRECTON_FORWARD, + local, remote, allow_rebind, timeout) + + def list_forwards(self, timeout=None): + """Return a list of tuples specifying active forwards. + + See `ADBDevice.list_socket_connection`. + """ + return self.list_socket_connections(self.SOCKET_DIRECTON_FORWARD, timeout) + + def remove_forwards(self, local=None, timeout=None): + """Remove existing port forwards. + + See `ADBDevice.remove_socket_connection`. + """ + self.remove_socket_connections(self.SOCKET_DIRECTON_FORWARD, local, timeout) + + # Legacy port reverse methods + + def reverse(self, local, remote, allow_rebind=True, timeout=None): + """Sets up a reverse socket connection from device to host. + + See `ADBDevice.create_socket_connection`. + """ + self.create_socket_connection(self.SOCKET_DIRECTON_REVERSE, + local, remote, allow_rebind, timeout) + + def list_reverses(self, timeout=None): + """Returns a list of tuples showing active reverse socket connections. + + See `ADBDevice.list_socket_connection`. + """ + return self.list_socket_connections(self.SOCKET_DIRECTON_REVERSE, timeout) + + def remove_reverses(self, local=None, timeout=None): + """Remove existing reverse socket connections. + + See `ADBDevice.remove_socket_connection`. + """ + self.remove_socket_connections(self.SOCKET_DIRECTON_REVERSE, + local, timeout) + # Device Shell methods def shell(self, cmd, env=None, cwd=None, timeout=None, root=False, diff --git a/testing/mozbase/mozdevice/setup.py b/testing/mozbase/mozdevice/setup.py index e0e31c0b3064..2064c4c95b92 100644 --- a/testing/mozbase/mozdevice/setup.py +++ b/testing/mozbase/mozdevice/setup.py @@ -8,7 +8,7 @@ from __future__ import absolute_import from setuptools import setup PACKAGE_NAME = 'mozdevice' -PACKAGE_VERSION = '1.1.0' +PACKAGE_VERSION = '1.1.1' deps = ['mozfile >= 1.0', 'mozlog >= 3.0', From a74f45da4bb3dd72187a8b4142a120ffa43b8473 Mon Sep 17 00:00:00 2001 From: Sebastian Hengst Date: Tue, 4 Sep 2018 18:21:03 +0300 Subject: [PATCH 47/61] Backed out changeset d8ff6c1c6f3a (bug 1471764) for failing devtools' browser_markup_flex_display_badge.js in beta simulations. a=backout --- devtools/.eslintrc.mochitests.js | 1 - .../client/inspector/computed/computed.js | 23 +-- devtools/client/inspector/flexbox/flexbox.js | 159 ++++++++++-------- .../client/inspector/grids/grid-inspector.js | 11 +- .../client/inspector/grids/test/.eslintrc.js | 3 + .../client/inspector/markup/test/.eslintrc.js | 2 +- .../client/inspector/markup/test/browser.ini | 3 - .../test/browser_markup_flex_display_badge.js | 56 ------ .../test/browser_markup_grid_display_badge.js | 60 ------- devtools/client/inspector/markup/test/head.js | 6 +- devtools/client/inspector/rules/rules.js | 21 +-- devtools/client/inspector/test/shared-head.js | 13 +- .../shared/redux/middleware/test/.eslintrc.js | 1 + 13 files changed, 129 insertions(+), 230 deletions(-) delete mode 100644 devtools/client/inspector/markup/test/browser_markup_flex_display_badge.js delete mode 100644 devtools/client/inspector/markup/test/browser_markup_grid_display_badge.js diff --git a/devtools/.eslintrc.mochitests.js b/devtools/.eslintrc.mochitests.js index 3b93729cc0c3..7268ed6b705d 100644 --- a/devtools/.eslintrc.mochitests.js +++ b/devtools/.eslintrc.mochitests.js @@ -11,7 +11,6 @@ module.exports = { "synthesizeKeyFromKeyTag": true, "TargetFactory": true, "waitForTick": true, - "waitUntilState": true, }, "parserOptions": { diff --git a/devtools/client/inspector/computed/computed.js b/devtools/client/inspector/computed/computed.js index f9933022e906..4ea826f4fbe4 100644 --- a/devtools/client/inspector/computed/computed.js +++ b/devtools/client/inspector/computed/computed.js @@ -6,11 +6,10 @@ "use strict"; -const promise = require("promise"); -const flags = require("devtools/shared/flags"); const ToolDefinitions = require("devtools/client/definitions").Tools; const CssLogic = require("devtools/shared/inspector/css-logic"); const {ELEMENT_STYLE} = require("devtools/shared/specs/styles"); +const promise = require("promise"); const OutputParser = require("devtools/client/shared/output-parser"); const {PrefObserver} = require("devtools/client/shared/prefs"); const {createChild} = require("devtools/client/inspector/shared/utils"); @@ -184,20 +183,14 @@ function CssComputedView(inspector, document, pageStyle) { this.styleDocument.addEventListener("mousedown", this.focusWindow); this.element.addEventListener("click", this._onClick); this.element.addEventListener("contextmenu", this._onContextMenu); + this.element.addEventListener("mousemove", () => { + this.addHighlightersToView(); + }, { once: true }); this.searchField.addEventListener("input", this._onFilterStyles); this.searchClearButton.addEventListener("click", this._onClearSearch); this.includeBrowserStylesCheckbox.addEventListener("input", this._onIncludeBrowserStyles); - if (flags.testing) { - // In tests, we start listening immediately to avoid having to simulate a mousemove. - this.highlighters.addToView(this); - } else { - this.element.addEventListener("mousemove", () => { - this.highlighters.addToView(this); - }, { once: true }); - } - this.searchClearButton.hidden = true; // No results text. @@ -739,6 +732,14 @@ CssComputedView.prototype = { } }, + /** + * Adds the highlighters overlay to the computed view. This is called by the "mousemove" + * event handler and in shared-head.js when opening and selecting the computed view. + */ + addHighlightersToView() { + this.highlighters.addToView(this); + }, + /** * Destructor for CssComputedView. */ diff --git a/devtools/client/inspector/flexbox/flexbox.js b/devtools/client/inspector/flexbox/flexbox.js index 60ba8d5b2022..b5d669c89432 100644 --- a/devtools/client/inspector/flexbox/flexbox.js +++ b/devtools/client/inspector/flexbox/flexbox.js @@ -5,7 +5,6 @@ "use strict"; const { throttle } = require("devtools/client/inspector/shared/utils"); -const flags = require("devtools/shared/flags"); const { clearFlexbox, @@ -63,16 +62,10 @@ class FlexboxInspector { return; } - if (flags.testing) { - // In tests, we start listening immediately to avoid having to simulate a mousemove. + this.document.addEventListener("mousemove", () => { this.highlighters.on("flexbox-highlighter-hidden", this.onHighlighterHidden); this.highlighters.on("flexbox-highlighter-shown", this.onHighlighterShown); - } else { - this.document.addEventListener("mousemove", () => { - this.highlighters.on("flexbox-highlighter-hidden", this.onHighlighterHidden); - this.highlighters.on("flexbox-highlighter-shown", this.onHighlighterShown); - }, { once: true }); - } + }, { once: true }); this.inspector.sidebar.on("select", this.onSidebarSelect); @@ -311,77 +304,99 @@ class FlexboxInspector { async update(flexboxFront) { // Stop refreshing if the inspector or store is already destroyed or no node is // selected. - if (!this.inspector || - !this.store || - !this.inspector.selection.nodeFront || - !this.hasGetCurrentFlexbox) { + if (!this.inspector || !this.store || !this.inspector.selection.nodeFront) { return; } - try { - // Fetch the current flexbox if no flexbox front was passed into this update. - if (!flexboxFront) { - flexboxFront = await this.layoutInspector.getCurrentFlexbox( - this.inspector.selection.nodeFront); - } - - // Clear the flexbox panel if there is no flex container for the current node - // selection. - if (!flexboxFront) { - this.store.dispatch(clearFlexbox()); - return; - } - - // If the FlexboxFront doesn't yet have access to the NodeFront for its container, - // then get it from the walker. This happens when the walker hasn't seen this - // particular DOM Node in the tree yet or when we are connected to an older server. - let containerNodeFront = flexboxFront.containerNodeFront; - if (!containerNodeFront) { - containerNodeFront = await this.walker.getNodeFromActor(flexboxFront.actorID, - ["containerEl"]); - } - - // Fetch the flex items for the given flex container and the flex item NodeFronts. - const flexItems = []; - const flexItemFronts = await flexboxFront.getFlexItems(); - - for (const flexItemFront of flexItemFronts) { - let itemNodeFront = flexItemFront.nodeFront; - if (!itemNodeFront) { - itemNodeFront = await this.walker.getNodeFromActor(flexItemFront.actorID, - ["element"]); + // Fetch the current flexbox if no flexbox front was passed into this update. + if (!flexboxFront) { + try { + if (!this.hasGetCurrentFlexbox) { + return; } - flexItems.push({ - actorID: flexItemFront.actorID, - shown: false, - flexItemSizing: flexItemFront.flexItemSizing, - nodeFront: itemNodeFront, - properties: flexItemFront.properties, - }); + flexboxFront = await this.layoutInspector.getCurrentFlexbox( + this.inspector.selection.nodeFront); + } catch (e) { + // This call might fail if called asynchrously after the toolbox is finished + // closing. + return; + } + } + + // Clear the flexbox panel if there is no flex container for the current node + // selection. + if (!flexboxFront) { + try { + this.store.dispatch(clearFlexbox()); + } catch (e) { + // This call might fail if called asynchrously after the toolbox is finished + // closing. + } + return; + } + + let containerNodeFront = flexboxFront.containerNodeFront; + + // If the FlexboxFront doesn't yet have access to the NodeFront for its container, + // then get it from the walker. This happens when the walker hasn't seen this + // particular DOM Node in the tree yet or when we are connected to an older server. + if (!containerNodeFront) { + try { + containerNodeFront = await this.walker.getNodeFromActor(flexboxFront.actorID, + ["containerEl"]); + } catch (e) { + // This call might fail if called asynchrously after the toolbox is finished + // closing. + return; + } + } + + const highlighted = this._highlighters && + containerNodeFront == this.highlighters.flexboxHighlighterShown; + + // Fetch the flex items for the given flex container and the flex item NodeFronts. + const flexItems = []; + const flexItemFronts = await flexboxFront.getFlexItems(); + + for (const flexItemFront of flexItemFronts) { + let itemNodeFront = flexItemFront.nodeFront; + + if (!itemNodeFront) { + try { + itemNodeFront = await this.walker.getNodeFromActor(flexItemFront.actorID, + ["element"]); + } catch (e) { + // This call might fail if called asynchrously after the toolbox is finished + // closing. + return; + } } - const highlighted = this._highlighters && - containerNodeFront == this.highlighters.flexboxHighlighterShown; - const currentUrl = this.inspector.target.url; - // Get the hostname, if there is no hostname, fall back on protocol - // ex: `data:` uri, and `about:` pages - const hostname = parseURL(currentUrl).hostname || parseURL(currentUrl).protocol; - const customColors = await this.getCustomFlexboxColors(); - const color = customColors[hostname] ? customColors[hostname] : FLEXBOX_COLOR; - - this.store.dispatch(updateFlexbox({ - actorID: flexboxFront.actorID, - color, - flexItems, - highlighted, - nodeFront: containerNodeFront, - properties: flexboxFront.properties, - })); - } catch (e) { - // This call might fail if called asynchrously after the toolbox is finished - // closing. + flexItems.push({ + actorID: flexItemFront.actorID, + shown: false, + flexItemSizing: flexItemFront.flexItemSizing, + nodeFront: itemNodeFront, + properties: flexItemFront.properties, + }); } + + const currentUrl = this.inspector.target.url; + // Get the hostname, if there is no hostname, fall back on protocol + // ex: `data:` uri, and `about:` pages + const hostname = parseURL(currentUrl).hostname || parseURL(currentUrl).protocol; + const customColors = await this.getCustomFlexboxColors(); + const color = customColors[hostname] ? customColors[hostname] : FLEXBOX_COLOR; + + this.store.dispatch(updateFlexbox({ + actorID: flexboxFront.actorID, + color, + flexItems, + highlighted, + nodeFront: containerNodeFront, + properties: flexboxFront.properties, + })); } } diff --git a/devtools/client/inspector/grids/grid-inspector.js b/devtools/client/inspector/grids/grid-inspector.js index a76ec8ca3091..bc426b96204a 100644 --- a/devtools/client/inspector/grids/grid-inspector.js +++ b/devtools/client/inspector/grids/grid-inspector.js @@ -6,7 +6,6 @@ const Services = require("Services"); const { throttle } = require("devtools/client/inspector/shared/utils"); -const flags = require("devtools/shared/flags"); const { updateGridColor, @@ -98,16 +97,10 @@ class GridInspector { return; } - if (flags.testing) { - // In tests, we start listening immediately to avoid having to simulate a mousemove. + this.document.addEventListener("mousemove", () => { this.highlighters.on("grid-highlighter-hidden", this.onHighlighterHidden); this.highlighters.on("grid-highlighter-shown", this.onHighlighterShown); - } else { - this.document.addEventListener("mousemove", () => { - this.highlighters.on("grid-highlighter-hidden", this.onHighlighterHidden); - this.highlighters.on("grid-highlighter-shown", this.onHighlighterShown); - }, { once: true }); - } + }, { once: true }); this.inspector.sidebar.on("select", this.onSidebarSelect); this.inspector.on("new-root", this.onNavigate); diff --git a/devtools/client/inspector/grids/test/.eslintrc.js b/devtools/client/inspector/grids/test/.eslintrc.js index ed1e234b39bc..b63e8411e3b7 100644 --- a/devtools/client/inspector/grids/test/.eslintrc.js +++ b/devtools/client/inspector/grids/test/.eslintrc.js @@ -3,4 +3,7 @@ module.exports = { // Extend from the shared list of defined globals for mochitests. "extends": "../../../../.eslintrc.mochitests.js", + "globals": { + "waitUntilState": true + } }; diff --git a/devtools/client/inspector/markup/test/.eslintrc.js b/devtools/client/inspector/markup/test/.eslintrc.js index ed1e234b39bc..698ae9181a0a 100644 --- a/devtools/client/inspector/markup/test/.eslintrc.js +++ b/devtools/client/inspector/markup/test/.eslintrc.js @@ -2,5 +2,5 @@ module.exports = { // Extend from the shared list of defined globals for mochitests. - "extends": "../../../../.eslintrc.mochitests.js", + "extends": "../../../../.eslintrc.mochitests.js" }; diff --git a/devtools/client/inspector/markup/test/browser.ini b/devtools/client/inspector/markup/test/browser.ini index 8fb39cdf965a..aa1b198c2ad8 100644 --- a/devtools/client/inspector/markup/test/browser.ini +++ b/devtools/client/inspector/markup/test/browser.ini @@ -73,7 +73,6 @@ support-files = !/devtools/client/inspector/test/head.js !/devtools/client/inspector/test/shared-head.js !/devtools/client/shared/test/shared-head.js - !/devtools/client/shared/test/shared-redux-head.js !/devtools/client/shared/test/telemetry-test-helpers.js !/devtools/client/shared/test/test-actor.js !/devtools/client/shared/test/test-actor-registry.js @@ -131,8 +130,6 @@ skip-if = true # Bug 1177550 [browser_markup_events_react_production_16.2.0_jsx.js] [browser_markup_events_source_map.js] [browser_markup_events-windowed-host.js] -[browser_markup_flex_display_badge.js] -[browser_markup_grid_display_badge.js] [browser_markup_links_01.js] [browser_markup_links_02.js] [browser_markup_links_03.js] diff --git a/devtools/client/inspector/markup/test/browser_markup_flex_display_badge.js b/devtools/client/inspector/markup/test/browser_markup_flex_display_badge.js deleted file mode 100644 index 68f44fbd041b..000000000000 --- a/devtools/client/inspector/markup/test/browser_markup_flex_display_badge.js +++ /dev/null @@ -1,56 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -// Tests that the flex display badge toggles on the flexbox highlighter. - -const TEST_URI = ` - -
-`; - -const HIGHLIGHTER_TYPE = "FlexboxHighlighter"; - -add_task(async function() { - await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI)); - const { inspector } = await openLayoutView(); - const { highlighters, store } = inspector; - - info("Check the flex display badge is shown and not active."); - await selectNode("#flex", inspector); - const flexContainer = await getContainerForSelector("#flex", inspector); - const flexDisplayBadge = flexContainer.elt.querySelector(".markup-badge[data-display]"); - ok(!flexDisplayBadge.classList.contains("active"), "flex display badge is not active."); - - info("Check the initial state of the flex highlighter."); - ok(!highlighters.highlighters[HIGHLIGHTER_TYPE], - "No flexbox highlighter exists in the highlighters overlay."); - ok(!highlighters.flexboxHighlighterShown, "No flexbox highlighter is shown."); - - info("Toggling ON the flexbox highlighter from the flex display badge."); - const onHighlighterShown = highlighters.once("flexbox-highlighter-shown"); - let onCheckboxChange = waitUntilState(store, state => state.flexbox.highlighted); - flexDisplayBadge.click(); - await onHighlighterShown; - await onCheckboxChange; - - info("Check the flexbox highlighter is created and flex display badge state."); - ok(highlighters.highlighters[HIGHLIGHTER_TYPE], - "Flexbox highlighter is created in the highlighters overlay."); - ok(highlighters.flexboxHighlighterShown, "Flexbox highlighter is shown."); - ok(flexDisplayBadge.classList.contains("active"), "flex display badge is active."); - - info("Toggling OFF the flexbox highlighter from the flex display badge."); - const onHighlighterHidden = highlighters.once("flexbox-highlighter-hidden"); - onCheckboxChange = waitUntilState(store, state => !state.flexbox.highlighted); - flexDisplayBadge.click(); - await onHighlighterHidden; - await onCheckboxChange; - - ok(!flexDisplayBadge.classList.contains("active"), "flex display badge is not active."); -}); diff --git a/devtools/client/inspector/markup/test/browser_markup_grid_display_badge.js b/devtools/client/inspector/markup/test/browser_markup_grid_display_badge.js deleted file mode 100644 index 353131e3b379..000000000000 --- a/devtools/client/inspector/markup/test/browser_markup_grid_display_badge.js +++ /dev/null @@ -1,60 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -// Tests that the grid display badge toggles on the grid highlighter. - -const TEST_URI = ` - -
-`; - -const HIGHLIGHTER_TYPE = "CssGridHighlighter"; - -add_task(async function() { - await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI)); - const { inspector } = await openLayoutView(); - const { highlighters, store } = inspector; - - info("Check the grid display badge is shown and not active."); - await selectNode("#grid", inspector); - const gridContainer = await getContainerForSelector("#grid", inspector); - const gridDisplayBadge = gridContainer.elt.querySelector(".markup-badge[data-display]"); - ok(!gridDisplayBadge.classList.contains("active"), "grid display badge is not active."); - - info("Check the initial state of the grid highlighter."); - ok(!highlighters.highlighters[HIGHLIGHTER_TYPE], - "No CSS grid highlighter exists in the highlighters overlay."); - ok(!highlighters.gridHighlighterShown, "No CSS grid highlighter is shown."); - - info("Toggling ON the CSS grid highlighter from the grid display badge."); - const onHighlighterShown = highlighters.once("grid-highlighter-shown"); - let onCheckboxChange = waitUntilState(store, state => - state.grids.length === 1 && - state.grids[0].highlighted); - gridDisplayBadge.click(); - await onHighlighterShown; - await onCheckboxChange; - - info("Check the CSS grid highlighter is created and grid display badge state."); - ok(highlighters.highlighters[HIGHLIGHTER_TYPE], - "CSS grid highlighter is created in the highlighters overlay."); - ok(highlighters.gridHighlighterShown, "CSS grid highlighter is shown."); - ok(gridDisplayBadge.classList.contains("active"), "grid display badge is active."); - - info("Toggling OFF the CSS grid highlighter from the grid display badge."); - const onHighlighterHidden = highlighters.once("grid-highlighter-hidden"); - onCheckboxChange = waitUntilState(store, state => - state.grids.length == 1 && - !state.grids[0].highlighted); - gridDisplayBadge.click(); - await onHighlighterHidden; - await onCheckboxChange; - - ok(!gridDisplayBadge.classList.contains("active"), "grid display badge is not active."); -}); diff --git a/devtools/client/inspector/markup/test/head.js b/devtools/client/inspector/markup/test/head.js index ab7f1c97ee8f..e21a77d033aa 100644 --- a/devtools/client/inspector/markup/test/head.js +++ b/devtools/client/inspector/markup/test/head.js @@ -1,3 +1,4 @@ + /* 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/. */ @@ -10,11 +11,6 @@ Services.scriptloader.loadSubScript( "chrome://mochitests/content/browser/devtools/client/inspector/test/head.js", this); -// Load the shared Redux helpers into this compartment. -Services.scriptloader.loadSubScript( - "chrome://mochitests/content/browser/devtools/client/shared/test/shared-redux-head.js", - this); - var {getInplaceEditorForSpan: inplaceEditor} = require("devtools/client/shared/inplace-editor"); var clipboard = require("devtools/shared/platform/clipboard"); diff --git a/devtools/client/inspector/rules/rules.js b/devtools/client/inspector/rules/rules.js index 6871850cb207..9424871708ab 100644 --- a/devtools/client/inspector/rules/rules.js +++ b/devtools/client/inspector/rules/rules.js @@ -8,7 +8,6 @@ const promise = require("promise"); const Services = require("Services"); -const flags = require("devtools/shared/flags"); const {l10n} = require("devtools/shared/inspector/css-logic"); const {ELEMENT_STYLE} = require("devtools/shared/specs/styles"); const OutputParser = require("devtools/client/shared/output-parser"); @@ -152,6 +151,9 @@ function CssRuleView(inspector, document, store, pageStyle) { this.shortcuts.on("CmdOrCtrl+F", event => this._onShortcut("CmdOrCtrl+F", event)); this.element.addEventListener("copy", this._onCopy); this.element.addEventListener("contextmenu", this._onContextMenu); + this.element.addEventListener("mousemove", () => { + this.addHighlightersToView(); + }, { once: true }); this.addRuleButton.addEventListener("click", this._onAddRule); this.searchField.addEventListener("input", this._onFilterStyles); this.searchClearButton.addEventListener("click", this._onClearSearch); @@ -161,15 +163,6 @@ function CssRuleView(inspector, document, store, pageStyle) { this.activeCheckbox.addEventListener("click", this._onTogglePseudoClass); this.focusCheckbox.addEventListener("click", this._onTogglePseudoClass); - if (flags.testing) { - // In tests, we start listening immediately to avoid having to simulate a mousemove. - this.highlighters.addToView(this); - } else { - this.element.addEventListener("mousemove", () => { - this.highlighters.addToView(this); - }, { once: true }); - } - this._handlePrefChange = this._handlePrefChange.bind(this); this._handleUAStylePrefChange = this._handleUAStylePrefChange.bind(this); this._handleDefaultColorUnitPrefChange = @@ -1644,6 +1637,14 @@ CssRuleView.prototype = { event.stopPropagation(); } }, + + /** + * Adds the highlighters overlay to the rule view. This is called by the "mousemove" + * event handler and in shared-head.js when opening and selecting the rule view. + */ + addHighlightersToView() { + this.highlighters.addToView(this); + }, }; /** diff --git a/devtools/client/inspector/test/shared-head.js b/devtools/client/inspector/test/shared-head.js index f0f1a63df668..911d753aee0a 100644 --- a/devtools/client/inspector/test/shared-head.js +++ b/devtools/client/inspector/test/shared-head.js @@ -91,6 +91,9 @@ function openRuleView() { // through an additional ".flush()" property. view.debounce = manualDebounce(); + // Adds the highlighters overlay in the rule view. + view.addHighlightersToView(); + return { toolbox: data.toolbox, inspector: data.inspector, @@ -110,6 +113,8 @@ function openRuleView() { function openComputedView() { return openInspectorSidebarTab("computedview").then(data => { const view = data.inspector.getPanel("computedview").computedView; + // Adds the highlighters overlay in the computed view. + view.addHighlightersToView(); return { toolbox: data.toolbox, @@ -160,7 +165,9 @@ function openLayoutView() { * @return {CssRuleView} the rule view */ function selectRuleView(inspector) { - return inspector.getPanel("ruleview").view; + const view = inspector.getPanel("ruleview").view; + view.addHighlightersToView(); + return view; } /** @@ -172,7 +179,9 @@ function selectRuleView(inspector) { */ function selectComputedView(inspector) { inspector.sidebar.select("computedview"); - return inspector.getPanel("computedview").computedView; + const view = inspector.getPanel("computedview").computedView; + view.addHighlightersToView(); + return view; } /** diff --git a/devtools/client/shared/redux/middleware/test/.eslintrc.js b/devtools/client/shared/redux/middleware/test/.eslintrc.js index f7f2df049299..0d12cd9a34b1 100644 --- a/devtools/client/shared/redux/middleware/test/.eslintrc.js +++ b/devtools/client/shared/redux/middleware/test/.eslintrc.js @@ -8,6 +8,7 @@ module.exports = { "run_next_test": true, "equal": true, "do_print": true, + "waitUntilState": true }, "rules": { // Stop giving errors for run_test From 24f1a63b5e8f8a8896ea9f7fccca2a7555f4bab3 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Tue, 4 Sep 2018 11:39:01 -0400 Subject: [PATCH 48/61] Bug 1488013 follow-up: Make sure the test doesn't set prefs that would affect the tests following it; a=Aryx --- .../tests/browser_contentblocking.js | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/browser/components/preferences/in-content/tests/browser_contentblocking.js b/browser/components/preferences/in-content/tests/browser_contentblocking.js index 8639dc73e972..9017a5c1ff29 100644 --- a/browser/components/preferences/in-content/tests/browser_contentblocking.js +++ b/browser/components/preferences/in-content/tests/browser_contentblocking.js @@ -60,12 +60,26 @@ add_task(async function testContentBlockingToggle() { add_task(async function testContentBlockingMainCategory() { SpecialPowers.pushPrefEnv({set: [ [CB_UI_PREF, true], + ]}); + + let prefs = [ [CB_PREF, true], [FB_PREF, true], [TP_PREF, false], [TP_PBM_PREF, true], [NCB_PREF, Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER], - ]}); + ]; + + for (let pref of prefs) { + switch (typeof pref[1]) { + case "boolean": + SpecialPowers.setBoolPref(pref[0], pref[1]); + break; + case "number": + SpecialPowers.setIntPref(pref[0], pref[1]); + break; + } + } let checkboxes = [ "#contentBlockingFastBlockCheckbox", @@ -115,6 +129,10 @@ add_task(async function testContentBlockingMainCategory() { checkControlStateWorker(doc, alwaysEnabledControls, true); gBrowser.removeCurrentTab(); + + for (let pref of prefs) { + SpecialPowers.clearUserPref(pref[0]); + } }); // Tests that the content blocking "Restore Defaults" button does what it's supposed to. From 9f7f6bcc8e7f1d03c380e578877b378e0a8e0e02 Mon Sep 17 00:00:00 2001 From: Mark Banner Date: Tue, 4 Sep 2018 17:57:35 +0000 Subject: [PATCH 49/61] Bug 1488246 - Cleanup .eslintignore for removed directories/files. r=mossop Differential Revision: https://phabricator.services.mozilla.com/D4882 --HG-- extra : moz-landing-system : lando --- .eslintignore | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/.eslintignore b/.eslintignore index 26d524fc3134..44fe00ba15e9 100644 --- a/.eslintignore +++ b/.eslintignore @@ -22,7 +22,6 @@ gfx/layers/** gfx/tests/browser/** gfx/tests/chrome/** gfx/tests/mochitest/** -gfx/tests/unit/** image/** layout/** memory/replace/dmd/test/** @@ -38,7 +37,6 @@ netwerk/test/mochitests/** netwerk/test/unit*/** netwerk/wifi/** parser/** -rdf/** tools/update-packaging/** uriloader/exthandler/** uriloader/exthandler/tests/mochitest/** @@ -57,7 +55,6 @@ mfbt/** mozglue/** nsprpub/** other-licenses/** -probes/** startupcache/** xpfe/** @@ -104,8 +101,6 @@ devtools/client/performance/components/test/test_jit_optimizations_01.html devtools/client/responsive.html/test/browser/touch.html devtools/client/shared/components/test/mochitest/*.html !devtools/client/shared/components/test/mochitest/test_stack-trace.html -devtools/client/shared/shim/test/test_*.html -devtools/client/shared/test/browser_toolbar_webconsole_errors_count.html devtools/client/storage/test/*.html !devtools/client/storage/test/storage-cookies.html !devtools/client/storage/test/storage-overflow.html @@ -176,7 +171,6 @@ devtools/server/tests/unit/xpcshell_debugging_script.js # dom/ exclusions dom/abort/** dom/animation/** -dom/archivereader/** dom/asmjscache/** dom/audiochannel/** dom/base/** @@ -190,7 +184,6 @@ dom/canvas/** dom/commandhandler/** dom/console/** dom/crypto/** -dom/devicestorage/** dom/encoding/** dom/events/** dom/fetch/** @@ -198,7 +191,6 @@ dom/file/** dom/filehandle/** dom/filesystem/** dom/flex/** -dom/flyweb/** dom/gamepad/** dom/geolocation/** dom/grid/** @@ -206,7 +198,6 @@ dom/html/** dom/imptests/** dom/interfaces/** dom/ipc/** -dom/json/** dom/jsurl/** dom/locales/** dom/manifest/** @@ -233,12 +224,9 @@ dom/promise/** dom/push/** dom/quota/** dom/res/** -dom/secureelement/** -dom/security/test/contentverifier/** dom/security/test/cors/** dom/security/test/csp/** dom/security/test/general/** -dom/security/test/hsts/** dom/security/test/mixedcontentblocker/** dom/security/test/sri/** dom/security/test/unit/** @@ -252,7 +240,6 @@ dom/tests/html/** dom/tests/js/** dom/tests/mochitest/** dom/tests/unit/** -dom/time/** dom/u2f/** dom/url/** dom/vr/** @@ -353,7 +340,6 @@ testing/mozbase/mozprofile/tests/files/prefs_with_comments.js testing/talos/talos/scripts/jszip.min.js testing/talos/talos/startup_test/sessionrestore/profile/sessionstore.js testing/talos/talos/startup_test/sessionrestore/profile-manywindows/sessionstore.js -testing/talos/talos/tests/canvasmark/** testing/talos/talos/tests/devtools/addon/content/pages/** testing/talos/talos/tests/dromaeo/** testing/talos/talos/tests/v8_7/** @@ -371,9 +357,6 @@ services/common/kinto-offline-client.js # toolkit/ exclusions -# Not part of the default build -toolkit/components/help/** - # Intentionally invalid JS toolkit/components/workerloader/tests/moduleF-syntax-error.js From 56437d9aed868992571b2030f8624d1efed6be1d Mon Sep 17 00:00:00 2001 From: Mark Banner Date: Tue, 4 Sep 2018 18:08:41 +0000 Subject: [PATCH 50/61] Bug 1488445 - Change the ESLint configuration to extend from eslint:recommended. r=mossop This enables the following extra rules over the current configuration: - for-direction - no-compare-neg-zero - no-new-symbol - no-this-before-super Other rules that are in eslint:recommended but not in our configuration are turned off for now. Differential Revision: https://phabricator.services.mozilla.com/D4944 --HG-- extra : moz-landing-system : lando --- devtools/client/memory/utils.js | 1 + js/src/builtin/Array.js | 1 + .../lib/configs/recommended.js | 132 ++++++------------ 3 files changed, 47 insertions(+), 87 deletions(-) diff --git a/devtools/client/memory/utils.js b/devtools/client/memory/utils.js index ed94b4ad6044..d0135fb6b878 100644 --- a/devtools/client/memory/utils.js +++ b/devtools/client/memory/utils.js @@ -453,6 +453,7 @@ exports.openFilePicker = function({ title, filters, defaultName, mode }) { */ exports.formatNumber = function(number, showSign = false) { const rounded = Math.round(number); + // eslint-disable-next-line no-compare-neg-zero if (rounded === 0 || rounded === -0) { return "0"; } diff --git a/js/src/builtin/Array.js b/js/src/builtin/Array.js index 9c76980df240..9a048f19fb9a 100644 --- a/js/src/builtin/Array.js +++ b/js/src/builtin/Array.js @@ -971,6 +971,7 @@ function ArraySpeciesCreate(originalArray, length) { assert(length >= 0, "length should be a non-negative number"); // Step 2. + // eslint-disable-next-line no-compare-neg-zero if (length === -0) length = 0; diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js index 3471f39300cc..c2df082736c0 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js +++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js @@ -1,11 +1,22 @@ "use strict"; +/** + * The configuration is based on eslint:recommended config. The details for all + * the ESLint rules, and which ones are in the recommended configuration can + * be found here: + * + * https://eslint.org/docs/rules/ + */ module.exports = { "env": { "browser": true, "es6": true }, + "extends": [ + "eslint:recommended" + ], + "globals": { "AddonManagerPermissions": false, "BroadcastChannel": false, @@ -135,6 +146,10 @@ module.exports = { // Functions must always return something or nothing "consistent-return": "error", + // XXX This rule line should be removed to enable it. See bug 1487642. + // Require super() calls in constructors + "constructor-super": "off", + // Require braces around blocks that start a new line // Note that this rule is likely to be overridden on a per-directory basis // very frequently. @@ -152,6 +167,10 @@ module.exports = { // Require function* name() "generator-star-spacing": ["error", {"after": true, "before": false}], + // XXX This rule line should be removed to enable it. See bug 1487642. + // Enforce return statements in getters + "getter-return": "off", + // Two space indent // "indent": ["error", 2, { "SwitchCase": 1 }], @@ -201,74 +220,47 @@ module.exports = { // Disallow use of arguments.caller or arguments.callee. "no-caller": "error", - // Disallow modifying variables of class declarations. - "no-class-assign": "error", + // XXX Bug 1487642 - decide if we want to enable this or not. + // Disallow lexical declarations in case clauses + "no-case-declarations": "off", - // Disallow assignment operators in conditional statements - "no-cond-assign": "error", + // XXX Bug 1487642 - decide if we want to enable this or not. + // Disallow the use of console + "no-console": "off", - // Disallow modifying variables that are declared using const. - "no-const-assign": "error", - - // Disallow control characters in regular expressions. - "no-control-regex": "error", - - // Disallow the use of debugger - "no-debugger": "error", - - // Disallow deleting variables - "no-delete-var": "error", - - // No duplicate arguments in function declarations - "no-dupe-args": "error", - - // Disallow duplicate class members. - "no-dupe-class-members": "error", + // XXX Bug 1487642 - decide if we want to enable this or not. + // Disallow constant expressions in conditions + "no-constant-condition": "off", // No duplicate keys in object declarations "no-dupe-keys": "error", - // No duplicate cases in switch statements - "no-duplicate-case": "error", - // If an if block ends with a return no need for an else block "no-else-return": "error", // No empty statements "no-empty": ["error", {"allowEmptyCatch": true}], - // No empty character classes in regex - "no-empty-character-class": "error", - - // Disallow empty destructuring - "no-empty-pattern": "error", - // Disallow eval and setInteral/setTimeout with strings "no-eval": "error", - // No assigning to exception variable - "no-ex-assign": "error", - // Disallow unnecessary calls to .bind() "no-extra-bind": "error", - // No using !! where casting to boolean is already happening - "no-extra-boolean-cast": "error", + // XXX Bug 1487642 - decide if we want to enable this or not. + // Disallow fallthrough of case statements + "no-fallthrough": "off", - // No double semicolon - "no-extra-semi": "error", - - // No overwriting defined functions - "no-func-assign": "error", + // XXX Bug 1487642 - decide if we want to enable this or not. + // Disallow assignments to native objects or read-only global variables + "no-global-assign": "off", // Disallow eval and setInteral/setTimeout with strings "no-implied-eval": "error", - // No invalid regular expressions - "no-invalid-regexp": "error", - - // No odd whitespace characters - "no-irregular-whitespace": "error", + // This has been superseded since we're using ES6. + // Disallow variable or function declarations in nested blocks + "no-inner-declarations": "off", // Disallow the use of the __iterator__ property "no-iterator": "error", @@ -282,9 +274,6 @@ module.exports = { // No single if block inside an else block "no-lonely-if": "error", - // no-tabs disallows tabs completely. - // "no-mixed-spaces-and-tabs": "error", - // No unnecessary spacing "no-multi-spaces": ["error", { exceptions: { "ArrayExpression": true, @@ -305,24 +294,9 @@ module.exports = { // Dissallow use of new wrappers "no-new-wrappers": "error", - // No Math() or JSON() - "no-obj-calls": "error", - - // No octal literals - "no-octal": "error", - - // No redeclaring variables - "no-redeclare": "error", - - // Disallow multiple spaces in regular expressions - "no-regex-spaces": "error", - // Disallows unnecessary `return await ...`. "no-return-await": "error", - // Disallow assignments where both sides are exactly the same - "no-self-assign": "error", - // No unnecessary comparisons "no-self-compare": "error", @@ -335,33 +309,15 @@ module.exports = { // No declaring variables that hide things like arguments "no-shadow-restricted-names": "error", - // Disallow sparse arrays - "no-sparse-arrays": "error", - // Disallow tabs. "no-tabs": "error", // No trailing whitespace "no-trailing-spaces": "error", - // No using undeclared variables - "no-undef": "error", - - // Error on newline where a semicolon is needed - "no-unexpected-multiline": "error", - // Disallow the use of Boolean literals in conditional expressions. "no-unneeded-ternary": "error", - // No unreachable statements - "no-unreachable": "error", - - // Disallow control flow statements in finally blocks - "no-unsafe-finally": "error", - - // No (!foo in bar) or (!object instanceof Class) - "no-unsafe-negation": "error", - // No unsanitized use of innerHTML=, document.write() etc. // cf. https://github.com/mozilla/eslint-plugin-no-unsanitized#rule-details "no-unsanitized/method": "error", @@ -383,6 +339,10 @@ module.exports = { // lines) "no-useless-concat": "error", + // XXX Bug 1487642 - decide if we want to enable this or not. + // Disallow unnecessary escape characters + "no-useless-escape": "off", + // Disallow redundant return statements "no-useless-return": "error", @@ -402,6 +362,10 @@ module.exports = { "avoidEscape": true }], + // XXX Bug 1487642 - decide if we want to enable this or not. + // Require generator functions to contain yield + "require-yield": "off", + // No spacing inside rest or spread expressions "rest-spread-spacing": "error", @@ -435,11 +399,5 @@ module.exports = { // Requires or disallows a whitespace (space or tab) beginning a comment "spaced-comment": "error", - - // No comparisons to NaN - "use-isnan": "error", - - // Only check typeof against valid results - "valid-typeof": "error" } }; From c6885f5391c0285f5eec85001951c3f0482dce12 Mon Sep 17 00:00:00 2001 From: Mark Banner Date: Tue, 4 Sep 2018 18:08:43 +0000 Subject: [PATCH 51/61] Bug 1488445 - Remove and replace obsolete ESLint rules. r=mossop This removes a number of references to rules that are now deprecated or removed from ESLint. - no-native-reassign is replaced with no-global-assign - no-spaced-func is replaced with func-call-spacing (where enabled) Depends on D4944 Differential Revision: https://phabricator.services.mozilla.com/D4946 --HG-- extra : moz-landing-system : lando --- accessible/tests/browser/.eslintrc.js | 10 ---------- chrome/test/unit/test_resolve_uris.js | 2 +- devtools/.eslintrc.js | 19 ++----------------- dom/indexedDB/test/helpers.js | 2 +- .../PresentationSessionFrameScript.js | 4 ++-- mobile/android/.eslintrc.js | 1 - .../tests/browser/robocop/robocop_head.js | 1 + .../readable-streams/patched-global.js | 3 --- .../transform-streams/patched-global.js | 3 --- toolkit/components/extensions/.eslintrc.js | 7 ------- toolkit/components/extensions/Schemas.jsm | 2 +- .../passwordmgr/test/pwmgr_common.js | 2 +- .../lib/configs/recommended.js | 6 +----- .../eslint-plugin-mozilla/package-lock.json | 2 +- .../eslint/eslint-plugin-mozilla/package.json | 2 +- 15 files changed, 12 insertions(+), 54 deletions(-) diff --git a/accessible/tests/browser/.eslintrc.js b/accessible/tests/browser/.eslintrc.js index b2189661238a..49dde63cd5b6 100644 --- a/accessible/tests/browser/.eslintrc.js +++ b/accessible/tests/browser/.eslintrc.js @@ -32,15 +32,12 @@ module.exports = { "new-cap": ["error", {"capIsNew": false}], "new-parens": "error", "no-bitwise": "off", - "no-catch-shadow": "error", - "no-comma-dangle": "off", "no-console": "off", "no-constant-condition": "off", "no-continue": "off", "no-div-regex": "off", "no-extend-native": "error", "no-extra-parens": "off", - "no-extra-strict": "off", "no-fallthrough": "error", "no-floating-decimal": "off", "no-inline-comments": "off", @@ -54,12 +51,10 @@ module.exports = { "no-process-env": "off", "no-process-exit": "off", "no-proto": "error", - "no-reserved-keys": "off", "no-restricted-modules": "off", "no-return-assign": "error", "no-script-url": "off", "no-shadow": "error", - "no-space-before-semi": "off", "no-sync": "off", "no-ternary": "off", "no-throw-literal": "error", @@ -76,9 +71,7 @@ module.exports = { "radix": "error", "semi-spacing": ["error", {"before": false, "after": true}], "sort-vars": "off", - "space-in-brackets": "off", "space-in-parens": ["error", "never"], - "space-unary-word-ops": "off", "strict": ["error", "global"], "valid-jsdoc": "off", "vars-on-top": "off", @@ -86,7 +79,6 @@ module.exports = { "wrap-regex": "off", "yoda": "error", "guard-for-in": "off", - "newline-after-var": "off", "no-alert": "off", "no-eq-null": "off", "no-func-assign": "off", @@ -98,7 +90,6 @@ module.exports = { "no-label-var": "off", "no-lone-blocks": "off", "no-loop-func": "off", - "no-negated-in-lhs": "off", "no-new": "off", "no-new-func": "off", "no-new-object": "off", @@ -108,7 +99,6 @@ module.exports = { "object-curly-spacing": "off", "no-unused-expressions": "off", "no-void": "off", - "no-wrap-func": "off", "operator-assignment": "off", "operator-linebreak": ["error", "after"] } diff --git a/chrome/test/unit/test_resolve_uris.js b/chrome/test/unit/test_resolve_uris.js index e1ee461e73d3..10aef2424fd7 100644 --- a/chrome/test/unit/test_resolve_uris.js +++ b/chrome/test/unit/test_resolve_uris.js @@ -82,7 +82,7 @@ function do_run_test() { } if (typeof run_test === "undefined") { - // eslint-disable-next-line no-native-reassign + // eslint-disable-next-line no-global-assign run_test = function() { do_run_test(); }; diff --git a/devtools/.eslintrc.js b/devtools/.eslintrc.js index 3c61df2b7031..98604f5e5bdc 100644 --- a/devtools/.eslintrc.js +++ b/devtools/.eslintrc.js @@ -253,6 +253,8 @@ module.exports = { // Allow using == instead of ===, in the interest of landing something since // the devtools codebase is split on convention here. "eqeqeq": "off", + // Disallow space between function identifier and application. + "func-call-spacing": "error", // Don't require function expressions to have a name. // This makes the code more verbose and hard to read. Our engine already // does a fantastic job assigning a name to the function, which includes @@ -288,9 +290,6 @@ module.exports = { "new-parens": "error", // Allow use of bitwise operators. "no-bitwise": "off", - // Disallow the catch clause parameter name being the same as a variable in - // the outer scope, to avoid confusion. - "no-catch-shadow": "error", // Allow using the console API. "no-console": "off", // Allow using constant expressions in conditions like while (true) @@ -341,8 +340,6 @@ module.exports = { "no-proto": "error", // Disallow multiple spaces in a regular expression literal. "no-regex-spaces": "off", - // Allow reserved words being used as object literal keys. - "no-reserved-keys": "off", // Don't restrict usage of specified node modules (not a node environment). "no-restricted-modules": "off", // Disallow use of assignment in return statement. It is preferable for a @@ -356,8 +353,6 @@ module.exports = { // random name. // Still, making this a warning can help people avoid being confused. "no-shadow": "error", - // Disallow space between function identifier and application. - "no-spaced-func": "error", // Allow use of synchronous methods (not a node environment). "no-sync": "off", // Allow the use of ternary operators. @@ -398,10 +393,6 @@ module.exports = { // Don't require to sort variables within the same declaration block. // Anyway, one-var is disabled. "sort-vars": "off", - // Disable the rule that checks if spaces inside {} and [] are there or not. - // Our code is split on conventions, and it'd be nice to have "error" rules - // instead, one for [] and one for {}. So, disabling until we write them. - "space-in-brackets": "off", // Disallow spaces inside parentheses. "space-in-parens": ["error", "never"], // Require spaces before/after unary operators (words on by default, @@ -433,8 +424,6 @@ module.exports = { "computed-property-spacing": "off", // Require for-in loops to have an if statement. "guard-for-in": "off", - // allow/disallow an empty newline after var statement - "newline-after-var": "off", // disallow the use of alert, confirm, and prompt "no-alert": "off", // disallow comparisons to null without a type-checking operator @@ -455,8 +444,6 @@ module.exports = { "no-lone-blocks": "off", // disallow creation of functions within loops "no-loop-func": "off", - // disallow negation of the left operand of an in expression - "no-negated-in-lhs": "off", // disallow use of new operator when not part of the assignment or // comparison "no-new": "off", @@ -480,8 +467,6 @@ module.exports = { "no-useless-concat": "off", // disallow use of void operator "no-void": "off", - // disallow wrapping of non-IIFE statements in parens - "no-wrap-func": "off", // require assignment operator shorthand where possible or prohibit it // entirely "operator-assignment": "off", diff --git a/dom/indexedDB/test/helpers.js b/dom/indexedDB/test/helpers.js index d4607fc39de7..5d6994347ac7 100644 --- a/dom/indexedDB/test/helpers.js +++ b/dom/indexedDB/test/helpers.js @@ -17,7 +17,7 @@ var testGenerator = testSteps(); // is whether the property is read-only or not. var c = Object.getOwnPropertyDescriptor(this, "Components"); if ((!c || !c.value || c.writable) && typeof SpecialPowers === "object") { - // eslint-disable-next-line no-native-reassign + // eslint-disable-next-line no-global-assign Components = SpecialPowers.wrap(SpecialPowers.Components); } diff --git a/dom/presentation/tests/mochitest/PresentationSessionFrameScript.js b/dom/presentation/tests/mochitest/PresentationSessionFrameScript.js index c9aaaf1c5348..2059e3475178 100644 --- a/dom/presentation/tests/mochitest/PresentationSessionFrameScript.js +++ b/dom/presentation/tests/mochitest/PresentationSessionFrameScript.js @@ -36,7 +36,7 @@ function loadPrivilegedScriptTest() { handlers[type].forEach(handler => handler.apply(null, args)); }; var handlers = {}; - /* eslint-disable-next-line no-native-reassign */ + /* eslint-disable-next-line no-global-assign */ addMessageListener = function(message, handler) { if (handlers.hasOwnProperty(message)) { handlers[message].push(handler); @@ -44,7 +44,7 @@ function loadPrivilegedScriptTest() { handlers[message] = [handler]; } }; - /* eslint-disable-next-line no-native-reassign */ + /* eslint-disable-next-line no-global-assign */ removeMessageListener = function(message, handler) { if (!handler || !handlers.hasOwnProperty(message)) { return; diff --git a/mobile/android/.eslintrc.js b/mobile/android/.eslintrc.js index 5c3b1a73ae68..593bf7ac488a 100644 --- a/mobile/android/.eslintrc.js +++ b/mobile/android/.eslintrc.js @@ -10,7 +10,6 @@ module.exports = { // re-enable these over time. "consistent-return": "off", "no-empty": "off", - "no-native-reassign": "off", "no-nested-ternary": "off", "no-new-object": "off", "no-octal": "off", diff --git a/mobile/android/tests/browser/robocop/robocop_head.js b/mobile/android/tests/browser/robocop/robocop_head.js index 6d1cae4ad68d..67e987cebcdd 100644 --- a/mobile/android/tests/browser/robocop/robocop_head.js +++ b/mobile/android/tests/browser/robocop/robocop_head.js @@ -15,6 +15,7 @@ { let c = Object.getOwnPropertyDescriptor(this, "Components"); if ((!c || !c.value || c.writable) && typeof SpecialPowers === "object") + // eslint-disable-next-line no-global-assign Components = SpecialPowers.wrap(SpecialPowers.Components); } diff --git a/testing/web-platform/tests/streams/readable-streams/patched-global.js b/testing/web-platform/tests/streams/readable-streams/patched-global.js index e8117c480484..c75b21e8c385 100644 --- a/testing/web-platform/tests/streams/readable-streams/patched-global.js +++ b/testing/web-platform/tests/streams/readable-streams/patched-global.js @@ -47,7 +47,6 @@ test(t => { const oldReadableStream = self.ReadableStream; - /* eslint-disable no-native-reassign */ self.ReadableStream = function() { throw new Error('ReadableStream called on global object'); }; @@ -60,8 +59,6 @@ test(t => { assert_true(isReadableStream(branch1), 'branch1 should be a ReadableStream'); assert_true(isReadableStream(branch2), 'branch2 should be a ReadableStream'); - - /* eslint-enable no-native-reassign */ }, 'ReadableStream tee() should not call the global ReadableStream'); done(); diff --git a/testing/web-platform/tests/streams/transform-streams/patched-global.js b/testing/web-platform/tests/streams/transform-streams/patched-global.js index d27b9cdd119e..f5d32c08ea73 100644 --- a/testing/web-platform/tests/streams/transform-streams/patched-global.js +++ b/testing/web-platform/tests/streams/transform-streams/patched-global.js @@ -21,8 +21,6 @@ test(() => { }, 'TransformStream constructor should not call setters for highWaterMark or size'); test(t => { - /* eslint-disable no-native-reassign */ - const oldReadableStream = ReadableStream; const oldWritableStream = WritableStream; const getReader = ReadableStream.prototype.getReader; @@ -47,7 +45,6 @@ test(t => { 'getReader should work when called on ts.readable'); assert_not_equals(getWriter.call(ts.writable), undefined, 'getWriter should work when called on ts.writable'); - /* eslint-enable no-native-reassign */ }, 'TransformStream should use the original value of ReadableStream and WritableStream'); done(); diff --git a/toolkit/components/extensions/.eslintrc.js b/toolkit/components/extensions/.eslintrc.js index 511d5d08e334..5d4f4e2a50de 100644 --- a/toolkit/components/extensions/.eslintrc.js +++ b/toolkit/components/extensions/.eslintrc.js @@ -159,10 +159,6 @@ module.exports = { // Allow use of bitwise operators. "no-bitwise": "off", - // Disallow the catch clause parameter name being the same as a variable in - // the outer scope, to avoid confusion. - "no-catch-shadow": "off", - // Disallow using the console API. "no-console": "error", @@ -217,9 +213,6 @@ module.exports = { // Disallow usage of __proto__ property. "no-proto": "error", - // Allow reserved words being used as object literal keys. - "no-reserved-keys": "off", - // Don't restrict usage of specified node modules (not a node environment). "no-restricted-modules": "off", diff --git a/toolkit/components/extensions/Schemas.jsm b/toolkit/components/extensions/Schemas.jsm index 7e6951167bdf..7fe2315d46c2 100644 --- a/toolkit/components/extensions/Schemas.jsm +++ b/toolkit/components/extensions/Schemas.jsm @@ -2396,7 +2396,7 @@ FunctionEntry = class FunctionEntry extends CallEntry { // // TODO Bug 1369722: we should be able to remove the eslint-disable-line that follows // once Bug 1369722 has been fixed. -Event = class Event extends CallEntry { // eslint-disable-line no-native-reassign +Event = class Event extends CallEntry { // eslint-disable-line no-global-assign static parseSchema(root, event, path) { let extraParameters = Array.from(event.extraParameters || [], param => ({ type: root.parseSchema(param, path, ["name", "optional", "default"]), diff --git a/toolkit/components/passwordmgr/test/pwmgr_common.js b/toolkit/components/passwordmgr/test/pwmgr_common.js index 973913b16063..238ba6563112 100644 --- a/toolkit/components/passwordmgr/test/pwmgr_common.js +++ b/toolkit/components/passwordmgr/test/pwmgr_common.js @@ -351,7 +351,7 @@ if (this.addMessageListener) { var SpecialPowers = { Cc, Ci, Cr, Cu }; var ok, is; // Ignore ok/is in commonInit since they aren't defined in a chrome script. - ok = is = () => {}; // eslint-disable-line no-native-reassign + ok = is = () => {}; ChromeUtils.import("resource://gre/modules/AppConstants.jsm"); ChromeUtils.import("resource://gre/modules/LoginHelper.jsm"); diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js index c2df082736c0..de27179d2b2f 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js +++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js @@ -251,9 +251,8 @@ module.exports = { // Disallow fallthrough of case statements "no-fallthrough": "off", - // XXX Bug 1487642 - decide if we want to enable this or not. // Disallow assignments to native objects or read-only global variables - "no-global-assign": "off", + "no-global-assign": "error", // Disallow eval and setInteral/setTimeout with strings "no-implied-eval": "error", @@ -282,9 +281,6 @@ module.exports = { "VariableDeclarator": true } }], - // No reassigning native JS objects - "no-native-reassign": "error", - // Nested ternary statements are confusing "no-nested-ternary": "error", diff --git a/tools/lint/eslint/eslint-plugin-mozilla/package-lock.json b/tools/lint/eslint/eslint-plugin-mozilla/package-lock.json index 3ec6e45eee4a..fd89bb068f93 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/package-lock.json +++ b/tools/lint/eslint/eslint-plugin-mozilla/package-lock.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-mozilla", - "version": "0.15.4", + "version": "0.16.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/tools/lint/eslint/eslint-plugin-mozilla/package.json b/tools/lint/eslint/eslint-plugin-mozilla/package.json index e563af8ff31b..33edfb865091 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/package.json +++ b/tools/lint/eslint/eslint-plugin-mozilla/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-mozilla", - "version": "0.15.4", + "version": "0.16.0", "description": "A collection of rules that help enforce JavaScript coding standard in the Mozilla project.", "keywords": [ "eslint", From 2c14b75a0721adfdce5c61e7239af6cad8d9f537 Mon Sep 17 00:00:00 2001 From: Tim Nguyen Date: Tue, 4 Sep 2018 18:49:15 +0000 Subject: [PATCH 52/61] Bug 1385518 - Update sidebar styling for dark theme. r=jaws Differential Revision: https://phabricator.services.mozilla.com/D4823 --HG-- extra : moz-landing-system : lando --- browser/components/nsBrowserGlue.js | 2 ++ browser/themes/osx/places/sidebar.css | 4 ++-- browser/themes/shared/places/sidebar.inc.css | 2 -- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/browser/components/nsBrowserGlue.js b/browser/components/nsBrowserGlue.js index 6753b550f73a..d0e555e32297 100644 --- a/browser/components/nsBrowserGlue.js +++ b/browser/components/nsBrowserGlue.js @@ -1045,6 +1045,8 @@ BrowserGlue.prototype = { toolbar_field_border: "rgba(249, 249, 250, 0.2)", ntp_background: "#2A2A2E", ntp_text: "rgb(249, 249, 250)", + sidebar: "#19191a", + sidebar_text: "rgb(249, 249, 250)", author: vendorShortName, }, { useInDarkMode: true, diff --git a/browser/themes/osx/places/sidebar.css b/browser/themes/osx/places/sidebar.css index de3029c17b18..786ec6531cdc 100644 --- a/browser/themes/osx/places/sidebar.css +++ b/browser/themes/osx/places/sidebar.css @@ -26,12 +26,12 @@ margin: 0 10px; } -.sidebar-placesTreechildren::-moz-tree-row(selected) { +.sidebar-panel:not([lwt-sidebar]) .sidebar-placesTreechildren::-moz-tree-row(selected) { -moz-appearance: -moz-mac-source-list-selection; -moz-font-smoothing-background-color: -moz-mac-source-list-selection; } -.sidebar-placesTreechildren::-moz-tree-row(selected,focus) { +.sidebar-panel:not([lwt-sidebar-highlight]) .sidebar-placesTreechildren::-moz-tree-row(selected,focus) { -moz-appearance: -moz-mac-active-source-list-selection; -moz-font-smoothing-background-color: -moz-mac-active-source-list-selection; } diff --git a/browser/themes/shared/places/sidebar.inc.css b/browser/themes/shared/places/sidebar.inc.css index a0f5df724ca2..cba955e0eedc 100644 --- a/browser/themes/shared/places/sidebar.inc.css +++ b/browser/themes/shared/places/sidebar.inc.css @@ -19,7 +19,6 @@ } .sidebar-panel[lwt-sidebar-brighttext] .sidebar-placesTreechildren::-moz-tree-row(selected) { - -moz-appearance: none; background-color: rgba(249,249,250,.1); } @@ -30,7 +29,6 @@ } .sidebar-panel[lwt-sidebar-highlight] .sidebar-placesTreechildren::-moz-tree-row(selected,focus) { - -moz-appearance: none; background-color: var(--lwt-sidebar-highlight-background-color); } From f691976c87ef20a5dd0bba5395a21fbfe614fdf4 Mon Sep 17 00:00:00 2001 From: Henri Sivonen Date: Tue, 4 Sep 2018 18:25:11 +0000 Subject: [PATCH 53/61] Bug 1487051 - Remove EnsureStringLength(). r=froydnj MozReview-Commit-ID: 4X4Rrs8xHTF Differential Revision: https://phabricator.services.mozilla.com/D4930 --HG-- extra : moz-landing-system : lando --- widget/cocoa/TextInputHandler.mm | 4 +++- xpcom/string/nsReadableUtils.h | 8 -------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/widget/cocoa/TextInputHandler.mm b/widget/cocoa/TextInputHandler.mm index 32184d2d34c2..ba7198f87767 100644 --- a/widget/cocoa/TextInputHandler.mm +++ b/widget/cocoa/TextInputHandler.mm @@ -381,7 +381,9 @@ TISInputSourceWrapper::TranslateToString(UInt32 aKeyCode, UInt32 aModifiers, if (len == 0) { return true; } - NS_ENSURE_TRUE(EnsureStringLength(aStr, len), false); + if (!aStr.SetLength(len, fallible)) { + return false; + } NS_ASSERTION(sizeof(char16_t) == sizeof(UniChar), "size of char16_t and size of UniChar are different"); memcpy(aStr.BeginWriting(), chars, len * sizeof(char16_t)); diff --git a/xpcom/string/nsReadableUtils.h b/xpcom/string/nsReadableUtils.h index d4eed2fe7d44..45cb85d4faf0 100644 --- a/xpcom/string/nsReadableUtils.h +++ b/xpcom/string/nsReadableUtils.h @@ -817,12 +817,4 @@ CompareUTF8toUTF16(const nsACString& aUTF8String, void AppendUCS4ToUTF16(const uint32_t aSource, nsAString& aDest); -template -inline bool -EnsureStringLength(T& aStr, uint32_t aLen) -{ - aStr.SetLength(aLen); - return (aStr.Length() == aLen); -} - #endif // !defined(nsReadableUtils_h___) From 34a614ae14a7dc7bebd524dcbfd15dc5c169a462 Mon Sep 17 00:00:00 2001 From: Henri Sivonen Date: Tue, 4 Sep 2018 18:24:52 +0000 Subject: [PATCH 54/61] Bug 1488186 - Avoid writing past the logical length of a string in Base64URLEncode. r=froydnj MozReview-Commit-ID: 4Sv7fHYIT9n Differential Revision: https://phabricator.services.mozilla.com/D4912 --HG-- extra : moz-landing-system : lando --- xpcom/io/Base64.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/xpcom/io/Base64.cpp b/xpcom/io/Base64.cpp index 69c34d02d30b..ccfa82a24f45 100644 --- a/xpcom/io/Base64.cpp +++ b/xpcom/io/Base64.cpp @@ -697,9 +697,9 @@ Base64URLEncode(uint32_t aBinaryLen, const uint8_t* aBinary, Base64URLEncodePaddingPolicy aPaddingPolicy, nsACString& aBase64) { + aBase64.Truncate(); // Don't encode empty strings. if (aBinaryLen == 0) { - aBase64.Truncate(); return NS_OK; } @@ -709,14 +709,15 @@ Base64URLEncode(uint32_t aBinaryLen, const uint8_t* aBinary, } // Allocate a buffer large enough to hold the encoded string with padding. - // Add one byte for null termination. uint32_t base64Len = ((aBinaryLen + 2) / 3) * 4; - if (NS_WARN_IF(!aBase64.SetCapacity(base64Len + 1, fallible))) { - aBase64.Truncate(); - return NS_ERROR_FAILURE; + + nsresult rv; + auto handle = aBase64.BulkWrite(base64Len, 0, false, rv); + if (NS_FAILED(rv)) { + return rv; } - char* base64 = aBase64.BeginWriting(); + char* base64 = handle.Elements(); uint32_t index = 0; for (; index + 3 <= aBinaryLen; index += 3) { @@ -739,7 +740,7 @@ Base64URLEncode(uint32_t aBinaryLen, const uint8_t* aBinary, *base64++ = kBase64URLAlphabet[((aBinary[index + 1] & 0xf) << 2)]; } - uint32_t length = base64 - aBase64.BeginWriting(); + uint32_t length = base64 - handle.Elements(); if (aPaddingPolicy == Base64URLEncodePaddingPolicy::Include) { if (length % 4 == 2) { *base64++ = '='; @@ -754,10 +755,7 @@ Base64URLEncode(uint32_t aBinaryLen, const uint8_t* aBinary, "Invalid encode padding policy"); } - // Null terminate and truncate to the actual number of characters. - *base64 = '\0'; - aBase64.SetLength(length); - + handle.Finish(length, false); return NS_OK; } From 9d274b2d2fd1185b200c204f1d1c140d68927c3f Mon Sep 17 00:00:00 2001 From: Gijs Kruitbosch Date: Tue, 4 Sep 2018 17:55:05 +0000 Subject: [PATCH 55/61] Bug 1337794 - remove obsolete pagehide handling hacks from browser.js r=mconley The pagehide handler has been as dead as a doornail for a while now, but the side-effect of forcing the creation of an about:blank document in non-remote windows was implicitly relied upon by some tests. This removes the dead code and fixes up some tests. Differential Revision: https://phabricator.services.mozilla.com/D4962 --HG-- extra : moz-landing-system : lando --- browser/base/content/browser.js | 26 -------- .../test/popups/browser_popup_frames.js | 2 +- .../base/tests/test_reftests_with_caret.html | 7 ++- .../aboutmemory/tests/test_aboutmemory4.xul | 61 ++++++++++--------- 4 files changed, 39 insertions(+), 57 deletions(-) diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 4fbd988b85e7..406c98e6d017 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -5313,32 +5313,6 @@ var TabsProgressListener = { TelemetryStopwatch.cancel("FX_PAGE_LOAD_MS", aBrowser); } } - - // We used to listen for clicks in the browser here, but when that - // became unnecessary, removing the code below caused focus issues. - // This code should be removed. Tracked in bug 1337794. - let isRemoteBrowser = aBrowser.isRemoteBrowser; - // We check isRemoteBrowser here to avoid requesting the doc CPOW - let doc = isRemoteBrowser ? null : aWebProgress.DOMWindow.document; - - if (!isRemoteBrowser && - aStateFlags & Ci.nsIWebProgressListener.STATE_STOP && - Components.isSuccessCode(aStatus) && - doc.documentURI.startsWith("about:") && - !doc.documentURI.toLowerCase().startsWith("about:blank") && - !doc.documentURI.toLowerCase().startsWith("about:home") && - !doc.documentElement.hasAttribute("hasBrowserHandlers")) { - // STATE_STOP may be received twice for documents, thus store an - // attribute to ensure handling it just once. - doc.documentElement.setAttribute("hasBrowserHandlers", "true"); - aBrowser.addEventListener("pagehide", function onPageHide(event) { - if (event.target.defaultView.frameElement) - return; - aBrowser.removeEventListener("pagehide", onPageHide, true); - if (event.target.documentElement) - event.target.documentElement.removeAttribute("hasBrowserHandlers"); - }, true); - } }, onLocationChange(aBrowser, aWebProgress, aRequest, aLocationURI, aFlags) { diff --git a/browser/base/content/test/popups/browser_popup_frames.js b/browser/base/content/test/popups/browser_popup_frames.js index 08fee2a92dd6..fd348caff58f 100644 --- a/browser/base/content/test/popups/browser_popup_frames.js +++ b/browser/base/content/test/popups/browser_popup_frames.js @@ -27,9 +27,9 @@ add_task(async function test_opening_blocked_popups() { await ContentTask.spawn(tab.linkedBrowser, baseURL, async function(uri) { let iframe = content.document.createElement("iframe"); - iframe.src = uri; let pageHideHappened = ContentTaskUtils.waitForEvent(this, "pagehide", true); content.document.body.appendChild(iframe); + iframe.src = uri; await pageHideHappened; }); diff --git a/layout/base/tests/test_reftests_with_caret.html b/layout/base/tests/test_reftests_with_caret.html index d25f70333207..fce22359fef5 100644 --- a/layout/base/tests/test_reftests_with_caret.html +++ b/layout/base/tests/test_reftests_with_caret.html @@ -61,11 +61,14 @@ const MAX_ITERATIONS = 1000; function createIframe(url,next) { var iframe = document.createElement("iframe"); - iframe.src = url; iframe.remotePageLoaded = remotePageLoaded; var me = this; var currentIteration = 0; function iframeLoadCompleted() { + let loc = iframe.contentWindow.location; + if (loc && loc.href == "about:blank") { + return; + } var docEl = iframe.contentDocument.documentElement; if (docEl.className.includes("reftest-wait")) { if (currentIteration++ > MAX_ITERATIONS) { @@ -84,6 +87,8 @@ function createIframe(url,next) { } iframe.addEventListener("load", iframeLoadCompleted); window.document.body.appendChild(iframe); + iframe.clientHeight; // flush layout. + iframe.src = url; iframe.focus(); }; diff --git a/toolkit/components/aboutmemory/tests/test_aboutmemory4.xul b/toolkit/components/aboutmemory/tests/test_aboutmemory4.xul index 8f470791e929..673c3f6b43c7 100644 --- a/toolkit/components/aboutmemory/tests/test_aboutmemory4.xul +++ b/toolkit/components/aboutmemory/tests/test_aboutmemory4.xul @@ -37,42 +37,45 @@ frame.height = 300; frame.src = "about:memory?file=" + makePathname(aFilename); document.documentElement.appendChild(frame); - frame.focus(); + frame.addEventListener("load", function onFrameLoad(e) { + frame.removeEventListener("load", onFrameLoad); + frame.focus(); - // Initialize the clipboard contents. - SpecialPowers.clipboardCopyString("initial clipboard value"); + // Initialize the clipboard contents. + SpecialPowers.clipboardCopyString("initial clipboard value"); - let numFailures = 0, maxFailures = 30; + let numFailures = 0, maxFailures = 30; - // Because the file load is async, we don't know when it will finish and - // the output will show up. So we poll. - function copyPasteAndCheck() { - // Copy and paste frame contents, and filter out non-deterministic - // differences. - synthesizeKey("A", {accelKey: true}); - synthesizeKey("C", {accelKey: true}); - let actual = SpecialPowers.getClipboardData("text/unicode"); - actual = actual.replace(/\(pid \d+\)/, "(pid NNN)"); + // Because the file load is async, we don't know when it will finish and + // the output will show up. So we poll. + function copyPasteAndCheck() { + // Copy and paste frame contents, and filter out non-deterministic + // differences. + synthesizeKey("A", {accelKey: true}); + synthesizeKey("C", {accelKey: true}); + let actual = SpecialPowers.getClipboardData("text/unicode"); + actual = actual.replace(/\(pid \d+\)/, "(pid NNN)"); - if (actual.trim() === aExpected.trim()) { - SimpleTest.ok(true, "Clipboard has the expected contents"); - aNext(); - } else { - numFailures++; - if (numFailures === maxFailures) { - ok(false, "pasted text doesn't match"); - dump("******EXPECTED******\n"); - dump(aExpected); - dump("*******ACTUAL*******\n"); - dump(actual); - dump("********************\n"); - SimpleTest.finish(); + if (actual.trim() === aExpected.trim()) { + SimpleTest.ok(true, "Clipboard has the expected contents"); + aNext(); } else { - setTimeout(copyPasteAndCheck, 100); + numFailures++; + if (numFailures === maxFailures) { + ok(false, "pasted text doesn't match"); + dump("******EXPECTED******\n"); + dump(aExpected); + dump("*******ACTUAL*******\n"); + dump(actual); + dump("********************\n"); + SimpleTest.finish(); + } else { + setTimeout(copyPasteAndCheck, 100); + } } } - } - copyPasteAndCheck(); + copyPasteAndCheck(); + }); } // Returns a function that chains together multiple test() calls. From bd0e3152bbf0c19f2dcab7d2174f1d47e1b2fff9 Mon Sep 17 00:00:00 2001 From: Aaron Klotz Date: Tue, 4 Sep 2018 19:55:53 +0000 Subject: [PATCH 56/61] Bug 1488547: Add flag to IsSafeModeRequested to skip keypress checks; r=mhowell Differential Revision: https://phabricator.services.mozilla.com/D4966 --HG-- extra : moz-landing-system : lando --- toolkit/xre/SafeMode.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/toolkit/xre/SafeMode.h b/toolkit/xre/SafeMode.h index 2c4aa978473b..5ac652be2d92 100644 --- a/toolkit/xre/SafeMode.h +++ b/toolkit/xre/SafeMode.h @@ -25,7 +25,8 @@ namespace mozilla { enum class SafeModeFlag : uint32_t { None = 0, - Unset = (1 << 0) + Unset = (1 << 0), + NoKeyPressCheck = (1 << 1), }; MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(SafeModeFlag) @@ -56,7 +57,8 @@ IsSafeModeRequested(int& aArgc, CharT* aArgv[], // order bit will be 1 if the key is pressed. By masking the returned short // with 0x8000 the result will be 0 if the key is not pressed and non-zero // otherwise. - if ((GetKeyState(VK_SHIFT) & 0x8000) && + if (!(aFlags & SafeModeFlag::NoKeyPressCheck) && + (GetKeyState(VK_SHIFT) & 0x8000) && !(GetKeyState(VK_CONTROL) & 0x8000) && !(GetKeyState(VK_MENU) & 0x8000) && !EnvHasValue("MOZ_DISABLE_SAFE_MODE_KEY")) { @@ -69,7 +71,8 @@ IsSafeModeRequested(int& aArgc, CharT* aArgv[], #endif // defined(XP_WIN) #if defined(XP_MACOSX) - if ((GetCurrentEventKeyModifiers() & optionKey) && + if (!(aFlags & SafeModeFlag::NoKeyPressCheck) && + (GetCurrentEventKeyModifiers() & optionKey) && !EnvHasValue("MOZ_DISABLE_SAFE_MODE_KEY")) { result = true; } From 63790f4fe34fca53fb746cd32957abb307c92502 Mon Sep 17 00:00:00 2001 From: Aaron Klotz Date: Tue, 4 Sep 2018 19:56:01 +0000 Subject: [PATCH 57/61] Bug 1488546: Disable safe mode key press checks in launcher process; r=mhowell Depends on D4966 Differential Revision: https://phabricator.services.mozilla.com/D4967 --HG-- extra : moz-landing-system : lando --- browser/app/winlauncher/LauncherProcessWin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/app/winlauncher/LauncherProcessWin.cpp b/browser/app/winlauncher/LauncherProcessWin.cpp index ff5bc72f8cf1..a3c571412c47 100644 --- a/browser/app/winlauncher/LauncherProcessWin.cpp +++ b/browser/app/winlauncher/LauncherProcessWin.cpp @@ -219,7 +219,7 @@ LauncherMain(int argc, wchar_t* argv[]) } const Maybe isSafeMode = IsSafeModeRequested(argc, argv, - SafeModeFlag::None); + SafeModeFlag::NoKeyPressCheck); if (!isSafeMode) { ShowError(ERROR_INVALID_PARAMETER); return 1; From 58f9cc4fc89ae39ea1a77c3bb6860b98fe53b316 Mon Sep 17 00:00:00 2001 From: Miko Mynttinen Date: Tue, 4 Sep 2018 16:25:54 +0000 Subject: [PATCH 58/61] Bug 1483659 - Ensure that child overflow areas are included in perspective frame overflow areas r=dbaron Differential Revision: https://phabricator.services.mozilla.com/D3515 --HG-- extra : moz-landing-system : lando --- layout/generic/nsFrame.cpp | 65 +++++++++++-------- .../perspective-overflow-1-ref.html | 28 ++++++++ .../transform-3d/perspective-overflow-1.html | 36 ++++++++++ layout/reftests/transform-3d/reftest.list | 1 + 4 files changed, 104 insertions(+), 26 deletions(-) create mode 100644 layout/reftests/transform-3d/perspective-overflow-1-ref.html create mode 100644 layout/reftests/transform-3d/perspective-overflow-1.html diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index e3d26d0f888a..2890f09b447f 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -9443,6 +9443,44 @@ nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas, #endif } + nsSize oldSize = mRect.Size(); + bool sizeChanged = ((aOldSize ? *aOldSize : oldSize) != aNewSize); + + // Our frame size may not have been computed and set yet, but code under + // functions such as ComputeEffectsRect (which we're about to call) use the + // values that are stored in our frame rect to compute their results. We + // need the results from those functions to be based on the frame size that + // we *will* have, so we temporarily set our frame size here before calling + // those functions. + // + // XXX Someone should document here why we revert the frame size before we + // return rather than just leaving it set. + // + // We pass false here to avoid invalidating display items for this temporary + // change. We sometimes reflow frames multiple times, with the final size being + // the same as the initial. The single call to SetSize after reflow is done + // will take care of invalidating display items if the size has actually + // changed. + SetSize(aNewSize, false); + + const bool applyOverflowClipping = + nsFrame::ShouldApplyOverflowClipping(this, disp); + + if (ChildrenHavePerspective(disp) && sizeChanged) { + RecomputePerspectiveChildrenOverflow(this); + + if (!applyOverflowClipping) { + aOverflowAreas.SetAllTo(bounds); + DebugOnly ok = ComputeCustomOverflow(aOverflowAreas); + + // ComputeCustomOverflow() should not return false, when + // FrameMaintainsOverflow() returns true. + MOZ_ASSERT(ok, "FrameMaintainsOverflow() != ComputeCustomOverflow()"); + + UnionChildOverflow(aOverflowAreas); + } + } + // This is now called FinishAndStoreOverflow() instead of // StoreOverflow() because frame-generic ways of adding overflow // can happen here, e.g. CSS2 outline and native theme. @@ -9467,7 +9505,7 @@ nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas, NS_ASSERTION((disp->mOverflowY == NS_STYLE_OVERFLOW_CLIP) == (disp->mOverflowX == NS_STYLE_OVERFLOW_CLIP), "If one overflow is clip, the other should be too"); - if (nsFrame::ShouldApplyOverflowClipping(this, disp)) { + if (applyOverflowClipping) { // The contents are actually clipped to the padding area aOverflowAreas.SetAllTo(bounds); } @@ -9501,26 +9539,6 @@ nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas, ComputeAndIncludeOutlineArea(this, aOverflowAreas, aNewSize); - nsSize oldSize = mRect.Size(); - bool sizeChanged = ((aOldSize ? *aOldSize : oldSize) != aNewSize); - - // Our frame size may not have been computed and set yet, but code under - // functions such as ComputeEffectsRect (which we're about to call) use the - // values that are stored in our frame rect to compute their results. We - // need the results from those functions to be based on the frame size that - // we *will* have, so we temporarily set our frame size here before calling - // those functions. - // - // XXX Someone should document here why we revert the frame size before we - // return rather than just leaving it set. - // - // We pass false here to avoid invalidating display items for this temporary - // change. We sometimes reflow frames multiple times, with the final size being - // the same as the initial. The single call to SetSize after reflow is done - // will take care of invalidating display items if the size has actually - // changed. - SetSize(aNewSize, false); - // Nothing in here should affect scrollable overflow. aOverflowAreas.VisualOverflow() = ComputeEffectsRect(this, aOverflowAreas.VisualOverflow(), aNewSize); @@ -9537,11 +9555,6 @@ nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas, } /* If we're transformed, transform the overflow rect by the current transformation. */ - if (ChildrenHavePerspective(disp) && sizeChanged) { - nsRect newBounds(nsPoint(0, 0), aNewSize); - RecomputePerspectiveChildrenOverflow(this); - } - if (hasTransform) { SetProperty(nsIFrame::PreTransformOverflowAreasProperty(), new nsOverflowAreas(aOverflowAreas)); diff --git a/layout/reftests/transform-3d/perspective-overflow-1-ref.html b/layout/reftests/transform-3d/perspective-overflow-1-ref.html new file mode 100644 index 000000000000..424a7993bb26 --- /dev/null +++ b/layout/reftests/transform-3d/perspective-overflow-1-ref.html @@ -0,0 +1,28 @@ + + + + +Testcase for bug 1483659 + + + +
+
+
+ + diff --git a/layout/reftests/transform-3d/perspective-overflow-1.html b/layout/reftests/transform-3d/perspective-overflow-1.html new file mode 100644 index 000000000000..178e3d2e2848 --- /dev/null +++ b/layout/reftests/transform-3d/perspective-overflow-1.html @@ -0,0 +1,36 @@ + + + + + +Testcase for bug 1483659 + + + +
+
+
+ + + diff --git a/layout/reftests/transform-3d/reftest.list b/layout/reftests/transform-3d/reftest.list index 00aed828126b..4e430f54a226 100644 --- a/layout/reftests/transform-3d/reftest.list +++ b/layout/reftests/transform-3d/reftest.list @@ -93,3 +93,4 @@ fuzzy-if(winWidget,0-150,0-120) fuzzy-if(webrender&&cocoaWidget,99-99,133-133) = == intermediate-1.html intermediate-1-ref.html == preserves3d-nested-filter-1.html preserves3d-nested-filter-1-ref.html != preserve3d-scale.html about:blank +== perspective-overflow-1.html perspective-overflow-1-ref.html From 5a18fb5aeeec99f1ca1c36a697082c221189a3b9 Mon Sep 17 00:00:00 2001 From: Sebastian Hengst Date: Tue, 4 Sep 2018 20:07:59 +0300 Subject: [PATCH 59/61] Backed out changeset c91d997687bf (bug 1487327) for busting beta. a=backout --- js/src/jit-test/lib/wasm-binary.js | 5 - js/src/jit-test/tests/wasm/binary.js | 6 +- .../wasm/gc/anyref-global-postbarrier.js | 3 - .../tests/wasm/gc/anyref-global-prebarrier.js | 1 - .../tests/wasm/gc/anyref-val-tracing.js | 1 - js/src/jit-test/tests/wasm/gc/anyref.js | 37 ++---- js/src/jit-test/tests/wasm/gc/binary.js | 5 +- js/src/jit-test/tests/wasm/gc/debugger.js | 3 +- js/src/jit-test/tests/wasm/gc/disabled.js | 18 +-- .../tests/wasm/gc/gc-feature-opt-in.js | 120 ------------------ js/src/jit-test/tests/wasm/gc/ref-global.js | 3 - js/src/jit-test/tests/wasm/gc/ref-restrict.js | 33 ----- js/src/jit-test/tests/wasm/gc/ref.js | 20 +-- js/src/jit-test/tests/wasm/gc/structs.js | 18 +-- js/src/wasm/WasmAST.h | 15 --- js/src/wasm/WasmBaselineCompile.cpp | 6 +- js/src/wasm/WasmBinaryConstants.h | 5 +- js/src/wasm/WasmCode.cpp | 10 +- js/src/wasm/WasmCode.h | 6 +- js/src/wasm/WasmCompile.cpp | 8 +- js/src/wasm/WasmCompile.h | 4 +- js/src/wasm/WasmGenerator.cpp | 2 +- js/src/wasm/WasmIonCompile.cpp | 2 +- js/src/wasm/WasmModule.cpp | 4 +- js/src/wasm/WasmOpIter.h | 8 +- js/src/wasm/WasmStubs.cpp | 20 +-- js/src/wasm/WasmStubs.h | 2 +- js/src/wasm/WasmTextToBinary.cpp | 62 --------- js/src/wasm/WasmValidate.cpp | 61 ++------- js/src/wasm/WasmValidate.h | 34 +---- 30 files changed, 83 insertions(+), 439 deletions(-) delete mode 100644 js/src/jit-test/tests/wasm/gc/gc-feature-opt-in.js diff --git a/js/src/jit-test/lib/wasm-binary.js b/js/src/jit-test/lib/wasm-binary.js index 7f1f2b0bc540..6bbefa1b3ba9 100644 --- a/js/src/jit-test/lib/wasm-binary.js +++ b/js/src/jit-test/lib/wasm-binary.js @@ -24,7 +24,6 @@ const startId = 8; const elemId = 9; const codeId = 10; const dataId = 11; -const gcFeatureOptInId = 42; // User-defined section names const nameName = "name"; @@ -178,10 +177,6 @@ function moduleWithSections(sectionArray) { return toU8(bytes); } -function gcFeatureOptInSection(version) { - return { name: gcFeatureOptInId, body: [ version & 0x7F ] } -} - function sigSection(sigs) { var body = []; body.push(...varU32(sigs.length)); diff --git a/js/src/jit-test/tests/wasm/binary.js b/js/src/jit-test/tests/wasm/binary.js index f7fb5aac083a..d86714094699 100644 --- a/js/src/jit-test/tests/wasm/binary.js +++ b/js/src/jit-test/tests/wasm/binary.js @@ -47,9 +47,9 @@ assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(codeId))), CompileError, assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(dataId))), CompileError, sectionError("data")); // unknown sections are unconditionally rejected -assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(37))), CompileError, unknownSection); -assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(37, 0))), CompileError, unknownSection); -assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(37, 1, 0))), CompileError, unknownSection); +assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(42))), CompileError, unknownSection); +assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(42, 0))), CompileError, unknownSection); +assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(42, 1, 0))), CompileError, unknownSection); // user sections have special rules assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(0))), CompileError, sectionError("custom")); // no length diff --git a/js/src/jit-test/tests/wasm/gc/anyref-global-postbarrier.js b/js/src/jit-test/tests/wasm/gc/anyref-global-postbarrier.js index dce81a3a50ec..14e9beb497a1 100644 --- a/js/src/jit-test/tests/wasm/gc/anyref-global-postbarrier.js +++ b/js/src/jit-test/tests/wasm/gc/anyref-global-postbarrier.js @@ -12,7 +12,6 @@ function Baguette(calories) { // Ensure the baseline compiler sync's before the postbarrier. (function() { wasmEvalText(`(module - (gc_feature_opt_in 1) (global (mut anyref) (ref.null anyref)) (func (export "f") get_global 0 @@ -24,7 +23,6 @@ function Baguette(calories) { })(); let exportsPlain = wasmEvalText(`(module - (gc_feature_opt_in 1) (global i32 (i32.const 42)) (global $g (mut anyref) (ref.null anyref)) (func (export "set") (param anyref) get_local 0 set_global $g) @@ -32,7 +30,6 @@ let exportsPlain = wasmEvalText(`(module )`).exports; let exportsObj = wasmEvalText(`(module - (gc_feature_opt_in 1) (global $g (export "g") (mut anyref) (ref.null anyref)) (func (export "set") (param anyref) get_local 0 set_global $g) (func (export "get") (result anyref) get_global $g) diff --git a/js/src/jit-test/tests/wasm/gc/anyref-global-prebarrier.js b/js/src/jit-test/tests/wasm/gc/anyref-global-prebarrier.js index 9c9f5f4b84d6..1b159a749c14 100644 --- a/js/src/jit-test/tests/wasm/gc/anyref-global-prebarrier.js +++ b/js/src/jit-test/tests/wasm/gc/anyref-global-prebarrier.js @@ -5,7 +5,6 @@ if (!wasmGcEnabled()) { const { startProfiling, endProfiling, assertEqPreciseStacks, isSingleStepProfilingEnabled } = WasmHelpers; let e = wasmEvalText(`(module - (gc_feature_opt_in 1) (global $g (mut anyref) (ref.null anyref)) (func (export "set") (param anyref) get_local 0 set_global $g) )`).exports; diff --git a/js/src/jit-test/tests/wasm/gc/anyref-val-tracing.js b/js/src/jit-test/tests/wasm/gc/anyref-val-tracing.js index d7fcce38683d..b1a689491881 100644 --- a/js/src/jit-test/tests/wasm/gc/anyref-val-tracing.js +++ b/js/src/jit-test/tests/wasm/gc/anyref-val-tracing.js @@ -4,7 +4,6 @@ if (!wasmGcEnabled()) { gczeal(14, 1); let { exports } = wasmEvalText(`(module - (gc_feature_opt_in 1) (global $anyref (import "glob" "anyref") anyref) (func (export "get") (result anyref) get_global $anyref) )`, { diff --git a/js/src/jit-test/tests/wasm/gc/anyref.js b/js/src/jit-test/tests/wasm/gc/anyref.js index d6dcb15772ff..3328144e905e 100644 --- a/js/src/jit-test/tests/wasm/gc/anyref.js +++ b/js/src/jit-test/tests/wasm/gc/anyref.js @@ -14,14 +14,12 @@ function Baguette(calories) { const { validate, CompileError } = WebAssembly; assertErrorMessage(() => wasmEvalText(`(module - (gc_feature_opt_in 1) (func (result anyref) i32.const 42 ) )`), CompileError, mismatchError('i32', 'anyref')); assertErrorMessage(() => wasmEvalText(`(module - (gc_feature_opt_in 1) (func (result anyref) i32.const 0 ref.null anyref @@ -31,7 +29,6 @@ assertErrorMessage(() => wasmEvalText(`(module )`), CompileError, /select operand types/); assertErrorMessage(() => wasmEvalText(`(module - (gc_feature_opt_in 1) (func (result i32) ref.null anyref if @@ -44,16 +41,16 @@ assertErrorMessage(() => wasmEvalText(`(module // Basic compilation tests. let simpleTests = [ - "(module (gc_feature_opt_in 1) (func (drop (ref.null anyref))))", - "(module (gc_feature_opt_in 1) (func $test (local anyref)))", - "(module (gc_feature_opt_in 1) (func $test (param anyref)))", - "(module (gc_feature_opt_in 1) (func $test (result anyref) (ref.null anyref)))", - "(module (gc_feature_opt_in 1) (func $test (block anyref (unreachable)) unreachable))", - "(module (gc_feature_opt_in 1) (func $test (local anyref) (result i32) (ref.is_null (get_local 0))))", - `(module (gc_feature_opt_in 1) (import "a" "b" (param anyref)))`, - `(module (gc_feature_opt_in 1) (import "a" "b" (result anyref)))`, - `(module (gc_feature_opt_in 1) (global anyref (ref.null anyref)))`, - `(module (gc_feature_opt_in 1) (global (mut anyref) (ref.null anyref)))`, + "(module (func (drop (ref.null anyref))))", + "(module (func $test (local anyref)))", + "(module (func $test (param anyref)))", + "(module (func $test (result anyref) (ref.null anyref)))", + "(module (func $test (block anyref (unreachable)) unreachable))", + "(module (func $test (local anyref) (result i32) (ref.is_null (get_local 0))))", + `(module (import "a" "b" (param anyref)))`, + `(module (import "a" "b" (result anyref)))`, + `(module (global anyref (ref.null anyref)))`, + `(module (global (mut anyref) (ref.null anyref)))`, ]; for (let src of simpleTests) { @@ -64,7 +61,6 @@ for (let src of simpleTests) { // Basic behavioral tests. let { exports } = wasmEvalText(`(module - (gc_feature_opt_in 1) (func (export "is_null") (result i32) ref.null anyref ref.is_null @@ -102,7 +98,6 @@ assertEq(exports.is_null_local(), 1); // Anyref param and result in wasm functions. exports = wasmEvalText(`(module - (gc_feature_opt_in 1) (func (export "is_null") (result i32) (param $ref anyref) get_local $ref ref.is_null @@ -160,7 +155,6 @@ assertEq(ref.calories, baguette.calories); // Make sure grow-memory isn't blocked by the lack of gc. (function() { assertEq(wasmEvalText(`(module - (gc_feature_opt_in 1) (memory 0 64) (func (export "f") (param anyref) (result i32) i32.const 10 @@ -176,7 +170,6 @@ assertEq(ref.calories, baguette.calories); function assertJoin(body) { let val = { i: -1 }; assertEq(wasmEvalText(`(module - (gc_feature_opt_in 1) (func (export "test") (param $ref anyref) (param $i i32) (result anyref) ${body} ) @@ -243,7 +236,6 @@ assertJoin(`(block $out anyref (block $unreachable anyref (loop $top let x = { i: 42 }, y = { f: 53 }; exports = wasmEvalText(`(module - (gc_feature_opt_in 1) (func (export "test") (param $lhs anyref) (param $rhs anyref) (param $i i32) (result anyref) get_local $lhs get_local $rhs @@ -298,7 +290,6 @@ let imports = { }; exports = wasmEvalText(`(module - (gc_feature_opt_in 1) (import $ret "funcs" "ret" (result anyref)) (import $param "funcs" "param" (param anyref)) @@ -327,7 +318,6 @@ assertEq(exports.ret(), imports.myBaguette); // Check lazy stubs generation. exports = wasmEvalText(`(module - (gc_feature_opt_in 1) (import $mirror "funcs" "mirror" (param anyref) (result anyref)) (import $augment "funcs" "augment" (param anyref) (result anyref)) @@ -411,15 +401,15 @@ assertEq(exports.count_g(), 1); // Anyref globals in wasm modules. -assertErrorMessage(() => wasmEvalText(`(module (gc_feature_opt_in 1) (global (import "glob" "anyref") anyref))`, { glob: { anyref: 42 } }), +assertErrorMessage(() => wasmEvalText(`(module (global (import "glob" "anyref") anyref))`, { glob: { anyref: 42 } }), WebAssembly.LinkError, /import object field 'anyref' is not a Object-or-null/); -assertErrorMessage(() => wasmEvalText(`(module (gc_feature_opt_in 1) (global (import "glob" "anyref") anyref))`, { glob: { anyref: new WebAssembly.Global({ value: 'i32' }, 42) } }), +assertErrorMessage(() => wasmEvalText(`(module (global (import "glob" "anyref") anyref))`, { glob: { anyref: new WebAssembly.Global({ value: 'i32' }, 42) } }), WebAssembly.LinkError, /imported global type mismatch/); -assertErrorMessage(() => wasmEvalText(`(module (gc_feature_opt_in 1) (global (import "glob" "i32") i32))`, { glob: { i32: {} } }), +assertErrorMessage(() => wasmEvalText(`(module (global (import "glob" "i32") i32))`, { glob: { i32: {} } }), WebAssembly.LinkError, /import object field 'i32' is not a Number/); @@ -433,7 +423,6 @@ imports = { }; exports = wasmEvalText(`(module - (gc_feature_opt_in 1) (global $g_imp_imm_null (import "constants" "imm_null") anyref) (global $g_imp_imm_bread (import "constants" "imm_bread") anyref) diff --git a/js/src/jit-test/tests/wasm/gc/binary.js b/js/src/jit-test/tests/wasm/gc/binary.js index 334d8b3f19d0..222a8e799a96 100644 --- a/js/src/jit-test/tests/wasm/gc/binary.js +++ b/js/src/jit-test/tests/wasm/gc/binary.js @@ -8,10 +8,7 @@ const v2vSig = {args:[], ret:VoidCode}; const v2vSigSection = sigSection([v2vSig]); function checkInvalid(body, errorMessage) { - assertErrorMessage(() => new WebAssembly.Module( - moduleWithSections([gcFeatureOptInSection(1), v2vSigSection, declSection([0]), bodySection([body])])), - WebAssembly.CompileError, - errorMessage); + assertErrorMessage(() => new WebAssembly.Module(moduleWithSections([v2vSigSection, declSection([0]), bodySection([body])])), WebAssembly.CompileError, errorMessage); } const invalidRefNullBody = funcBody({locals:[], body:[ diff --git a/js/src/jit-test/tests/wasm/gc/debugger.js b/js/src/jit-test/tests/wasm/gc/debugger.js index 494068d40d4e..96e79c43c20a 100644 --- a/js/src/jit-test/tests/wasm/gc/debugger.js +++ b/js/src/jit-test/tests/wasm/gc/debugger.js @@ -5,7 +5,7 @@ if (!wasmGcEnabled() || !wasmDebuggingIsSupported()) { (function() { let g = newGlobal(); let dbg = new Debugger(g); - g.eval(`o = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary('(module (gc_feature_opt_in 1) (func (result anyref) (param anyref) get_local 0) (export "" 0))')));`); + g.eval(`o = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary('(module (func (result anyref) (param anyref) get_local 0) (export "" 0))')));`); })(); (function() { @@ -14,7 +14,6 @@ if (!wasmGcEnabled() || !wasmDebuggingIsSupported()) { let src = ` (module - (gc_feature_opt_in 1) (func (export "func") (result anyref) (param $ref anyref) get_local $ref ) diff --git a/js/src/jit-test/tests/wasm/gc/disabled.js b/js/src/jit-test/tests/wasm/gc/disabled.js index 14768ee16eb1..f720b515ee32 100644 --- a/js/src/jit-test/tests/wasm/gc/disabled.js +++ b/js/src/jit-test/tests/wasm/gc/disabled.js @@ -4,21 +4,21 @@ if (wasmGcEnabled()) { const { CompileError, validate } = WebAssembly; -const UNRECOGNIZED_OPCODE_OR_BAD_TYPE = /unrecognized opcode|reference types not enabled|invalid inline block type/; +const UNRECOGNIZED_OPCODE_OR_BAD_TYPE = /(unrecognized opcode|bad type|invalid inline block type)/; function assertValidateError(text) { assertEq(validate(wasmTextToBinary(text)), false); } let simpleTests = [ - "(module (gc_feature_opt_in 1) (func (drop (ref.null anyref))))", - "(module (gc_feature_opt_in 1) (func $test (local anyref)))", - "(module (gc_feature_opt_in 1) (func $test (param anyref)))", - "(module (gc_feature_opt_in 1) (func $test (result anyref) (ref.null anyref)))", - "(module (gc_feature_opt_in 1) (func $test (block anyref (unreachable)) unreachable))", - "(module (gc_feature_opt_in 1) (func $test (local anyref) (result i32) (ref.is_null (get_local 0))))", - `(module (gc_feature_opt_in 1) (import "a" "b" (param anyref)))`, - `(module (gc_feature_opt_in 1) (import "a" "b" (result anyref)))`, + "(module (func (drop (ref.null anyref))))", + "(module (func $test (local anyref)))", + "(module (func $test (param anyref)))", + "(module (func $test (result anyref) (ref.null anyref)))", + "(module (func $test (block anyref (unreachable)) unreachable))", + "(module (func $test (local anyref) (result i32) (ref.is_null (get_local 0))))", + `(module (import "a" "b" (param anyref)))`, + `(module (import "a" "b" (result anyref)))`, ]; for (let src of simpleTests) { diff --git a/js/src/jit-test/tests/wasm/gc/gc-feature-opt-in.js b/js/src/jit-test/tests/wasm/gc/gc-feature-opt-in.js deleted file mode 100644 index 5cf5f3f0d4a0..000000000000 --- a/js/src/jit-test/tests/wasm/gc/gc-feature-opt-in.js +++ /dev/null @@ -1,120 +0,0 @@ -if (!wasmGcEnabled()) { - quit(0); -} - -// Encoding. If the section is present it must be first. - -var bad_order = - new Uint8Array([0x00, 0x61, 0x73, 0x6d, - 0x01, 0x00, 0x00, 0x00, - - 0x01, // Type section - 0x01, // Section size - 0x00, // Zero types - - 0x2a, // GcFeatureOptIn section - 0x01, // Section size - 0x01]); // Version - -assertErrorMessage(() => new WebAssembly.Module(bad_order), - WebAssembly.CompileError, - /expected custom section/); - -// Version numbers. Version 1 is good, version 2 is bad. - -new WebAssembly.Module(wasmTextToBinary( - `(module - (gc_feature_opt_in 1))`)); - -assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( - `(module - (gc_feature_opt_in 2))`)), - WebAssembly.CompileError, - /unsupported version of the gc feature/); - -// Struct types are only available if we opt in. - -new WebAssembly.Module(wasmTextToBinary( - `(module - (gc_feature_opt_in 1) - (type (struct (field i32))))`)); - -assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( - `(module - (type (struct (field i32))))`)), - WebAssembly.CompileError, - /Structure types not enabled/); - -// Parameters of ref type are only available if we opt in. - -new WebAssembly.Module(wasmTextToBinary( - `(module - (gc_feature_opt_in 1) - (type (func (param anyref))))`)); - -assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( - `(module - (type (func (param anyref))))`)), - WebAssembly.CompileError, - /reference types not enabled/); - -// Ditto returns - -new WebAssembly.Module(wasmTextToBinary( - `(module - (gc_feature_opt_in 1) - (type (func (result anyref))))`)); - -assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( - `(module - (type (func (result anyref))))`)), - WebAssembly.CompileError, - /reference types not enabled/); - -// Ditto locals - -new WebAssembly.Module(wasmTextToBinary( - `(module - (gc_feature_opt_in 1) - (func (result i32) - (local anyref) - (i32.const 0)))`)); - -assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( - `(module - (func (result i32) - (local anyref) - (i32.const 0)))`)), - WebAssembly.CompileError, - /reference types not enabled/); - -// Ditto globals - -new WebAssembly.Module(wasmTextToBinary( - `(module - (gc_feature_opt_in 1) - (global (mut anyref) (ref.null anyref)))`)); - -assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( - `(module - (global (mut anyref) (ref.null anyref)))`)), - WebAssembly.CompileError, - /reference types not enabled/); - -// Ref instructions are only available if we opt in. -// -// When testing these we need to avoid struct types or parameters, locals, -// returns, or globals of ref type, or guards on those will preempt the guards -// on the instructions. - -assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( - `(module - (func (ref.null anyref)))`)), - WebAssembly.CompileError, - /unrecognized opcode/); - -assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( - `(module - (func ref.is_null))`)), - WebAssembly.CompileError, - /unrecognized opcode/); diff --git a/js/src/jit-test/tests/wasm/gc/ref-global.js b/js/src/jit-test/tests/wasm/gc/ref-global.js index 0a64c9973bb3..9eb961c2c8f9 100644 --- a/js/src/jit-test/tests/wasm/gc/ref-global.js +++ b/js/src/jit-test/tests/wasm/gc/ref-global.js @@ -7,7 +7,6 @@ if (!wasmGcEnabled()) { let bin = wasmTextToBinary( `(module - (gc_feature_opt_in 1) (type $point (struct (field $x f64) @@ -43,7 +42,6 @@ if (!wasmGcEnabled()) { let bin = wasmTextToBinary( `(module - (gc_feature_opt_in 1) (type $box (struct (field $val i32))) (import "m" "g" (global (mut (ref $box)))))`); @@ -58,7 +56,6 @@ if (!wasmGcEnabled()) { let bin = wasmTextToBinary( `(module - (gc_feature_opt_in 1) (type $box (struct (field $val i32))) (global $boxg (export "box") (mut (ref $box)) (ref.null (ref $box))))`); diff --git a/js/src/jit-test/tests/wasm/gc/ref-restrict.js b/js/src/jit-test/tests/wasm/gc/ref-restrict.js index 9e1f5ce5025d..bb95ddef3897 100644 --- a/js/src/jit-test/tests/wasm/gc/ref-restrict.js +++ b/js/src/jit-test/tests/wasm/gc/ref-restrict.js @@ -52,7 +52,6 @@ function wasmCompile(text) { assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $x i32))) (func (export "f") (param (ref $box)) (unreachable)))`), WebAssembly.CompileError, @@ -60,7 +59,6 @@ assertErrorMessage(() => wasmCompile( assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (func (export "f") (param anyref) (unreachable)))`), "object"); @@ -68,7 +66,6 @@ assertEq(typeof wasmCompile( assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $x i32))) (func (export "f") (result (ref $box)) (ref.null (ref $box))))`), WebAssembly.CompileError, @@ -76,7 +73,6 @@ assertErrorMessage(() => wasmCompile( assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (func (export "f") (result anyref) (ref.null anyref)))`), "object"); @@ -84,7 +80,6 @@ assertEq(typeof wasmCompile( assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $x i32))) (import "m" "f" (param (ref $box))))`), WebAssembly.CompileError, @@ -92,7 +87,6 @@ assertErrorMessage(() => wasmCompile( assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (import "m" "f" (param anyref)))`), "object"); @@ -100,7 +94,6 @@ assertEq(typeof wasmCompile( assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $x i32))) (import "m" "f" (param i32) (result (ref $box))))`), WebAssembly.CompileError, @@ -108,7 +101,6 @@ assertErrorMessage(() => wasmCompile( assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (import "m" "f" (param i32) (result anyref)))`), "object"); @@ -116,7 +108,6 @@ assertEq(typeof wasmCompile( assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $val i32))) (import "m" "g" (global (mut (ref $box)))))`), WebAssembly.CompileError, @@ -124,7 +115,6 @@ assertErrorMessage(() => wasmCompile( assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $val i32))) (import "m" "g" (global (ref $box))))`), WebAssembly.CompileError, @@ -132,13 +122,11 @@ assertErrorMessage(() => wasmCompile( assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (import "m" "g" (global (mut anyref))))`), "object"); assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (import "m" "g" (global anyref)))`), "object"); @@ -146,7 +134,6 @@ assertEq(typeof wasmCompile( assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $val i32))) (global $boxg (export "box") (mut (ref $box)) (ref.null (ref $box))))`), WebAssembly.CompileError, @@ -154,7 +141,6 @@ assertErrorMessage(() => wasmCompile( assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $val i32))) (global $boxg (export "box") (ref $box) (ref.null (ref $box))))`), WebAssembly.CompileError, @@ -162,13 +148,11 @@ assertErrorMessage(() => wasmCompile( assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (global $boxg (export "box") (mut anyref) (ref.null anyref)))`), "object"); assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (global $boxg (export "box") anyref (ref.null anyref)))`), "object"); @@ -176,7 +160,6 @@ assertEq(typeof wasmCompile( assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $val i32))) (table (export "tbl") 1 anyfunc) (elem (i32.const 0) $f1) @@ -186,7 +169,6 @@ assertErrorMessage(() => wasmCompile( assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $val i32))) (table (export "tbl") 1 anyfunc) (elem (i32.const 0) $f1) @@ -196,7 +178,6 @@ assertErrorMessage(() => wasmCompile( assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (table (export "tbl") 1 anyfunc) (elem (i32.const 0) $f1) (func $f1 (param anyref) (unreachable)))`), @@ -204,7 +185,6 @@ assertEq(typeof wasmCompile( assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (table (export "tbl") 1 anyfunc) (elem (i32.const 0) $f1) (func $f1 (result anyref) (ref.null anyref)))`), @@ -214,7 +194,6 @@ assertEq(typeof wasmCompile( assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $val i32))) (import "m" "tbl" (table 1 anyfunc)) (elem (i32.const 0) $f1) @@ -224,7 +203,6 @@ assertErrorMessage(() => wasmCompile( assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $val i32))) (import "m" "tbl" (table 1 anyfunc)) (elem (i32.const 0) $f1) @@ -234,7 +212,6 @@ assertErrorMessage(() => wasmCompile( assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (import "m" "tbl" (table 1 anyfunc)) (elem (i32.const 0) $f1) (func $f1 (param anyref) (unreachable)))`), @@ -242,7 +219,6 @@ assertEq(typeof wasmCompile( assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (import "m" "tbl" (table 1 anyfunc)) (elem (i32.const 0) $f1) (func $f1 (result anyref) (ref.null anyref)))`), @@ -252,7 +228,6 @@ assertEq(typeof wasmCompile( assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $val i32))) (type $fn (func (param (ref $box)))) (table (export "tbl") 1 anyfunc) @@ -263,7 +238,6 @@ assertErrorMessage(() => wasmCompile( assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $val i32))) (type $fn (func (result (ref $box)))) (table (export "tbl") 1 anyfunc) @@ -274,7 +248,6 @@ assertErrorMessage(() => wasmCompile( assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (type $fn (func (param anyref))) (table (export "tbl") 1 anyfunc) (func (param i32) @@ -283,7 +256,6 @@ assertEq(typeof wasmCompile( assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (type $fn (func (result anyref))) (table (export "tbl") 1 anyfunc) (func (param i32) (result anyref) @@ -294,7 +266,6 @@ assertEq(typeof wasmCompile( assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $val i32))) (type $fn (func (param (ref $box)))) (import "m" "tbl" (table 1 anyfunc)) @@ -305,7 +276,6 @@ assertErrorMessage(() => wasmCompile( assertErrorMessage(() => wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $val i32))) (type $fn (func (result (ref $box)))) (import "m" "tbl" (table 1 anyfunc)) @@ -316,7 +286,6 @@ assertErrorMessage(() => wasmCompile( assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (type $fn (func (param anyref))) (import "m" "tbl" (table 1 anyfunc)) (func (param i32) @@ -325,7 +294,6 @@ assertEq(typeof wasmCompile( assertEq(typeof wasmCompile( `(module - (gc_feature_opt_in 1) (type $fn (func (result anyref))) (import "m" "tbl" (table 1 anyfunc)) (func (param i32) (result anyref) @@ -337,7 +305,6 @@ assertEq(typeof wasmCompile( { let m = wasmCompile( `(module - (gc_feature_opt_in 1) (type $box (struct (field $val i32))) (type $fn (func (param (ref $box)) (result i32))) (table 1 anyfunc) diff --git a/js/src/jit-test/tests/wasm/gc/ref.js b/js/src/jit-test/tests/wasm/gc/ref.js index 6638894b520c..1f087388ad69 100644 --- a/js/src/jit-test/tests/wasm/gc/ref.js +++ b/js/src/jit-test/tests/wasm/gc/ref.js @@ -1,6 +1,6 @@ if (!wasmGcEnabled()) { assertErrorMessage(() => wasmEvalText(`(module (func (param (ref 0)) (unreachable)))`), - WebAssembly.CompileError, /reference types not enabled/); + WebAssembly.CompileError, /bad type/); quit(0); } @@ -8,7 +8,6 @@ if (!wasmGcEnabled()) { var bin = wasmTextToBinary( `(module - (gc_feature_opt_in 1) (type $cons (struct (field $car i32) (field $cdr (ref $cons)))) @@ -68,7 +67,6 @@ assertEq(WebAssembly.validate(bin), true); new WebAssembly.Module(wasmTextToBinary(` (module - (gc_feature_opt_in 1) (type $s (struct)) (func $null (param (ref $s)) (result i32) (ref.is_null (get_local 0)))) @@ -78,7 +76,6 @@ new WebAssembly.Module(wasmTextToBinary(` new WebAssembly.Module(wasmTextToBinary(` (module - (gc_feature_opt_in 1) (type $s (struct (field i32))) (func $f (param (ref $s)) (call $g (get_local 0))) (func $g (param anyref) (unreachable))) @@ -88,8 +85,7 @@ new WebAssembly.Module(wasmTextToBinary(` assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) - (func (param (ref $odd)) (unreachable))) + (func (param (ref $odd)) (unreachable))) `), SyntaxError, /Type label.*not found/); @@ -98,7 +94,6 @@ SyntaxError, /Type label.*not found/); wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct (field i32))) (type $t (struct (field i32))) (func $f (param (ref $s)) (unreachable)) @@ -107,7 +102,6 @@ wasmEvalText(` assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct (field i32))) (type $t (struct (field f32))) ;; Incompatible type (func $f (param (ref $s)) (unreachable)) @@ -117,7 +111,6 @@ WebAssembly.CompileError, /expression has type ref.*but expected ref/); assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct (field i32))) (type $t (struct (field (mut i32)))) ;; Incompatible mutability (func $f (param (ref $s)) (unreachable)) @@ -130,7 +123,6 @@ WebAssembly.CompileError, /expression has type ref.*but expected ref/); wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct (field i32))) (type $t (struct (field i32))) (func $f (param (ref $s)) (local (ref $t)) (set_local 1 (get_local 0)))) @@ -138,7 +130,6 @@ wasmEvalText(` assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct (field i32))) (type $t (struct (field f32))) (func $f (param (ref $s)) (local (ref $t)) (set_local 1 (get_local 0)))) @@ -147,7 +138,6 @@ WebAssembly.CompileError, /expression has type ref.*but expected ref/); assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct (field i32))) (type $t (struct (field (mut i32)))) (func $f (param (ref $s)) (unreachable)) @@ -160,7 +150,6 @@ WebAssembly.CompileError, /expression has type ref.*but expected ref/); wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct (field i32))) (type $t (struct (field i32))) (func $f (param (ref $s)) (result (ref $t)) (get_local 0))) @@ -168,7 +157,6 @@ wasmEvalText(` assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct (field i32))) (type $t (struct (field f32))) (func $f (param (ref $s)) (result (ref $t)) (get_local 0))) @@ -177,7 +165,6 @@ WebAssembly.CompileError, /expression has type ref.*but expected ref/); assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct (field i32))) (type $t (struct (field (mut i32)))) (func $f (param (ref $s)) (result (ref $t)) (get_local 0))) @@ -188,7 +175,6 @@ WebAssembly.CompileError, /expression has type ref.*but expected ref/); assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type $x (func (param i32))) (func $f (param (ref $x)) (unreachable))) `), @@ -196,7 +182,6 @@ SyntaxError, /Type label.*not found/); assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type (func (param i32))) (func $f (param (ref 0)) (unreachable))) `), @@ -206,7 +191,6 @@ WebAssembly.CompileError, /does not reference a struct type/); assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct (field i32))) (func $f (param anyref) (call $g (get_local 0))) (func $g (param (ref $s)) (unreachable))) diff --git a/js/src/jit-test/tests/wasm/gc/structs.js b/js/src/jit-test/tests/wasm/gc/structs.js index 333fd1303612..a8e94518f3e6 100644 --- a/js/src/jit-test/tests/wasm/gc/structs.js +++ b/js/src/jit-test/tests/wasm/gc/structs.js @@ -1,14 +1,11 @@ if (!wasmGcEnabled()) { - assertErrorMessage(() => wasmEvalText(`(module - (gc_feature_opt_in 1) - (type $s (struct)))`), + assertErrorMessage(() => wasmEvalText(`(module (type $s (struct)))`), WebAssembly.CompileError, /Structure types not enabled/); quit(); } var bin = wasmTextToBinary( `(module - (gc_feature_opt_in 1) (table 2 anyfunc) (elem (i32.const 0) $doit $doitagain) @@ -76,7 +73,6 @@ assertEq(ins.x2(8), Math.PI) wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct (field i32)))) `) @@ -84,7 +80,6 @@ wasmEvalText(` wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct))) `) @@ -92,7 +87,6 @@ wasmEvalText(` assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct (field $x i32))) (type $s (struct (field $y i32)))) `), @@ -102,35 +96,30 @@ SyntaxError, /duplicate type name/); assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s)) `), SyntaxError, /parsing wasm text/); assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (field $x i32))) `), SyntaxError, /bad type definition/); assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct (field $x i31)))) `), SyntaxError, /parsing wasm text/); assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct (fjeld $x i32)))) `), SyntaxError, /parsing wasm text/); assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct abracadabra))) `), SyntaxError, /parsing wasm text/); @@ -139,7 +128,6 @@ SyntaxError, /parsing wasm text/); assertErrorMessage(() => wasmEvalText(` (module - (gc_feature_opt_in 1) (type $s (struct)) (type $f (func (param i32) (result i32))) (func (type 0) (param i32) (result i32) (unreachable))) @@ -151,10 +139,6 @@ WebAssembly.CompileError, /signature index references non-signature/); var bad = new Uint8Array([0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, - 0x2a, // GcFeatureOptIn section - 0x01, // Section size - 0x01, // Version - 0x01, // Type section 0x03, // Section size 0x01, // One type diff --git a/js/src/wasm/WasmAST.h b/js/src/wasm/WasmAST.h index 119b2d467bc2..b30e0e0bc9ba 100644 --- a/js/src/wasm/WasmAST.h +++ b/js/src/wasm/WasmAST.h @@ -1233,9 +1233,6 @@ class AstModule : public AstNode NameVector funcImportNames_; AstResizableVector tables_; AstResizableVector memories_; -#ifdef ENABLE_WASM_GC - uint32_t gcFeatureOptIn_; -#endif ExportVector exports_; Maybe startFunc_; FuncVector funcs_; @@ -1254,9 +1251,6 @@ class AstModule : public AstNode funcImportNames_(lifo), tables_(lifo), memories_(lifo), -#ifdef ENABLE_WASM_GC - gcFeatureOptIn_(0), -#endif exports_(lifo), funcs_(lifo), dataSegments_(lifo), @@ -1273,15 +1267,6 @@ class AstModule : public AstNode const AstResizableVector& memories() const { return memories_; } -#ifdef ENABLE_WASM_GC - bool addGcFeatureOptIn(uint32_t version) { - gcFeatureOptIn_ = version; - return true; - } - uint32_t gcFeatureOptIn() const { - return gcFeatureOptIn_; - } -#endif bool addTable(AstName name, const Limits& table) { return tables_.append(AstResizable(table, false, name)); } diff --git a/js/src/wasm/WasmBaselineCompile.cpp b/js/src/wasm/WasmBaselineCompile.cpp index ac38143eec95..350191905976 100644 --- a/js/src/wasm/WasmBaselineCompile.cpp +++ b/js/src/wasm/WasmBaselineCompile.cpp @@ -9967,12 +9967,12 @@ BaseCompiler::emitBody() #ifdef ENABLE_WASM_GC case uint16_t(Op::RefNull): - if (env_.gcTypesEnabled() == HasGcTypes::False) + if (env_.gcTypesEnabled == HasGcTypes::False) return iter_.unrecognizedOpcode(&op); CHECK_NEXT(emitRefNull()); break; case uint16_t(Op::RefIsNull): - if (env_.gcTypesEnabled() == HasGcTypes::False) + if (env_.gcTypesEnabled == HasGcTypes::False) return iter_.unrecognizedOpcode(&op); CHECK_NEXT(emitConversion(emitRefIsNull, ValType::AnyRef, ValType::I32)); break; @@ -10375,7 +10375,7 @@ js::wasm::BaselineCompileFunctions(const ModuleEnvironment& env, LifoAlloc& lifo ValTypeVector locals; if (!locals.appendAll(env.funcTypes[func.index]->args())) return false; - if (!DecodeLocalEntries(d, env.kind, env.types, env.gcTypesEnabled(), &locals)) + if (!DecodeLocalEntries(d, env.kind, env.types, env.gcTypesEnabled, &locals)) return false; // One-pass baseline compilation. diff --git a/js/src/wasm/WasmBinaryConstants.h b/js/src/wasm/WasmBinaryConstants.h index f84a8b2b7e77..8c9e03969e74 100644 --- a/js/src/wasm/WasmBinaryConstants.h +++ b/js/src/wasm/WasmBinaryConstants.h @@ -38,10 +38,7 @@ enum class SectionId Start = 8, Elem = 9, Code = 10, - Data = 11, -#ifdef ENABLE_WASM_GC - GcFeatureOptIn = 42 // Arbitrary, but fits in 7 bits -#endif + Data = 11 }; enum class TypeCode diff --git a/js/src/wasm/WasmCode.cpp b/js/src/wasm/WasmCode.cpp index da3f231e1de6..c18eaeeffe19 100644 --- a/js/src/wasm/WasmCode.cpp +++ b/js/src/wasm/WasmCode.cpp @@ -628,7 +628,7 @@ struct ProjectLazyFuncIndex static constexpr unsigned LAZY_STUB_LIFO_DEFAULT_CHUNK_SIZE = 8 * 1024; bool -LazyStubTier::createMany(HasGcTypes gcTypesConfigured, const Uint32Vector& funcExportIndices, +LazyStubTier::createMany(HasGcTypes gcTypesEnabled, const Uint32Vector& funcExportIndices, const CodeTier& codeTier, size_t* stubSegmentIndex) { MOZ_ASSERT(funcExportIndices.length()); @@ -652,7 +652,7 @@ LazyStubTier::createMany(HasGcTypes gcTypesConfigured, const Uint32Vector& funcE Maybe callee; callee.emplace(calleePtr, ImmPtr::NoCheckToken()); if (!GenerateEntryStubs(masm, funcExportIndex, fe, callee, /* asmjs */ false, - gcTypesConfigured, &codeRanges)) + gcTypesEnabled, &codeRanges)) { return false; } @@ -734,7 +734,7 @@ LazyStubTier::createOne(uint32_t funcExportIndex, const CodeTier& codeTier) return false; size_t stubSegmentIndex; - if (!createMany(codeTier.code().metadata().temporaryGcTypesConfigured, funcExportIndexes, codeTier, + if (!createMany(codeTier.code().metadata().temporaryHasGcTypes, funcExportIndexes, codeTier, &stubSegmentIndex)) { return false; @@ -761,14 +761,14 @@ LazyStubTier::createOne(uint32_t funcExportIndex, const CodeTier& codeTier) } bool -LazyStubTier::createTier2(HasGcTypes gcTypesConfigured, const Uint32Vector& funcExportIndices, +LazyStubTier::createTier2(HasGcTypes gcTypesEnabled, const Uint32Vector& funcExportIndices, const CodeTier& codeTier, Maybe* outStubSegmentIndex) { if (!funcExportIndices.length()) return true; size_t stubSegmentIndex; - if (!createMany(gcTypesConfigured, funcExportIndices, codeTier, &stubSegmentIndex)) + if (!createMany(gcTypesEnabled, funcExportIndices, codeTier, &stubSegmentIndex)) return false; outStubSegmentIndex->emplace(stubSegmentIndex); diff --git a/js/src/wasm/WasmCode.h b/js/src/wasm/WasmCode.h index eb4322885423..ad18996abd8e 100644 --- a/js/src/wasm/WasmCode.h +++ b/js/src/wasm/WasmCode.h @@ -368,7 +368,7 @@ struct MetadataCacheablePod { ModuleKind kind; MemoryUsage memoryUsage; - HasGcTypes temporaryGcTypesConfigured; + HasGcTypes temporaryHasGcTypes; uint32_t minMemoryLength; uint32_t globalDataLength; Maybe maxMemoryLength; @@ -379,7 +379,7 @@ struct MetadataCacheablePod explicit MetadataCacheablePod(ModuleKind kind) : kind(kind), memoryUsage(MemoryUsage::None), - temporaryGcTypesConfigured(HasGcTypes::False), + temporaryHasGcTypes(HasGcTypes::False), minMemoryLength(0), globalDataLength(0), filenameIsURL(false) @@ -576,7 +576,7 @@ class LazyStubTier // them in a single stub. Jit entries won't be used until // setJitEntries() is actually called, after the Code owner has committed // tier2. - bool createTier2(HasGcTypes gcTypesConfigured, const Uint32Vector& funcExportIndices, + bool createTier2(HasGcTypes gcTypesEnabled, const Uint32Vector& funcExportIndices, const CodeTier& codeTier, Maybe* stubSegmentIndex); void setJitEntries(const Maybe& stubSegmentIndex, const Code& code); diff --git a/js/src/wasm/WasmCompile.cpp b/js/src/wasm/WasmCompile.cpp index 7cbca17196a9..cf267b854b1a 100644 --- a/js/src/wasm/WasmCompile.cpp +++ b/js/src/wasm/WasmCompile.cpp @@ -96,7 +96,7 @@ CompileArgs::initFromContext(JSContext* cx, ScriptedCaller&& scriptedCaller) baselineEnabled = cx->options().wasmBaseline() || gcEnabled; ionEnabled = cx->options().wasmIon() && !gcEnabled; sharedMemoryEnabled = cx->realm()->creationOptions().getSharedMemoryAndAtomicsEnabled(); - gcTypesConfigured = gcEnabled ? HasGcTypes::True : HasGcTypes::False; + gcTypesEnabled = gcEnabled ? HasGcTypes::True : HasGcTypes::False; testTiering = (cx->options().testWasmAwaitTier2() || JitOptions.wasmDelayTier2) && !gcEnabled; // Debug information such as source view or debug traps will require @@ -432,7 +432,7 @@ wasm::CompileBuffer(const CompileArgs& args, const ShareableBytes& bytecode, Uni DebugEnabled debug; InitialCompileFlags(args, d, &mode, &tier, &debug); - ModuleEnvironment env(mode, tier, debug, args.gcTypesConfigured, + ModuleEnvironment env(mode, tier, debug, args.gcTypesEnabled, args.sharedMemoryEnabled ? Shareable::True : Shareable::False); if (!DecodeModuleEnvironment(d, &env)) return nullptr; @@ -458,7 +458,7 @@ wasm::CompileTier2(const CompileArgs& args, Module& module, Atomic* cancel UniqueChars error; Decoder d(module.bytecode().bytes, 0, &error); - MOZ_ASSERT(args.gcTypesConfigured == HasGcTypes::False, "can't ion-compile with gc types yet"); + MOZ_ASSERT(args.gcTypesEnabled == HasGcTypes::False, "can't ion-compile with gc types yet"); ModuleEnvironment env(CompileMode::Tier2, Tier::Ion, DebugEnabled::False, HasGcTypes::False, args.sharedMemoryEnabled ? Shareable::True : Shareable::False); @@ -587,7 +587,7 @@ wasm::CompileStreaming(const CompileArgs& args, DebugEnabled debug; InitialCompileFlags(args, d, &mode, &tier, &debug); - env.emplace(mode, tier, debug, args.gcTypesConfigured, + env.emplace(mode, tier, debug, args.gcTypesEnabled, args.sharedMemoryEnabled ? Shareable::True : Shareable::False); if (!DecodeModuleEnvironment(d, env.ptr())) return nullptr; diff --git a/js/src/wasm/WasmCompile.h b/js/src/wasm/WasmCompile.h index d13111f4e957..c0cf0b24a3c1 100644 --- a/js/src/wasm/WasmCompile.h +++ b/js/src/wasm/WasmCompile.h @@ -46,7 +46,7 @@ struct CompileArgs : ShareableBase bool debugEnabled; bool ionEnabled; bool sharedMemoryEnabled; - HasGcTypes gcTypesConfigured; + HasGcTypes gcTypesEnabled; bool testTiering; CompileArgs(Assumptions&& assumptions, ScriptedCaller&& scriptedCaller) @@ -56,7 +56,7 @@ struct CompileArgs : ShareableBase debugEnabled(false), ionEnabled(false), sharedMemoryEnabled(false), - gcTypesConfigured(HasGcTypes::False), + gcTypesEnabled(HasGcTypes::False), testTiering(false) {} diff --git a/js/src/wasm/WasmGenerator.cpp b/js/src/wasm/WasmGenerator.cpp index fbe72ce436c7..67725e4f64d3 100644 --- a/js/src/wasm/WasmGenerator.cpp +++ b/js/src/wasm/WasmGenerator.cpp @@ -832,7 +832,7 @@ ModuleGenerator::finishMetadata(const ShareableBytes& bytecode) // Copy over data from the ModuleEnvironment. metadata_->memoryUsage = env_->memoryUsage; - metadata_->temporaryGcTypesConfigured = env_->gcTypesConfigured; + metadata_->temporaryHasGcTypes = env_->gcTypesEnabled; metadata_->minMemoryLength = env_->minMemoryLength; metadata_->maxMemoryLength = env_->maxMemoryLength; metadata_->startFuncIndex = env_->startFuncIndex; diff --git a/js/src/wasm/WasmIonCompile.cpp b/js/src/wasm/WasmIonCompile.cpp index 8bee71b6b009..9a40a9133dad 100644 --- a/js/src/wasm/WasmIonCompile.cpp +++ b/js/src/wasm/WasmIonCompile.cpp @@ -3503,7 +3503,7 @@ wasm::IonCompileFunctions(const ModuleEnvironment& env, LifoAlloc& lifo, ValTypeVector locals; if (!locals.appendAll(env.funcTypes[func.index]->args())) return false; - if (!DecodeLocalEntries(d, env.kind, env.types, env.gcTypesEnabled(), &locals)) + if (!DecodeLocalEntries(d, env.kind, env.types, env.gcTypesEnabled, &locals)) return false; // Set up for Ion compilation. diff --git a/js/src/wasm/WasmModule.cpp b/js/src/wasm/WasmModule.cpp index 8f13d3801fd2..d688edd9b96a 100644 --- a/js/src/wasm/WasmModule.cpp +++ b/js/src/wasm/WasmModule.cpp @@ -254,11 +254,11 @@ Module::finishTier2(UniqueLinkDataTier linkData2, UniqueCodeTier tier2Arg, Modul return false; } - HasGcTypes gcTypesConfigured = code().metadata().temporaryGcTypesConfigured; + HasGcTypes gcTypesEnabled = code().metadata().temporaryHasGcTypes; const CodeTier& tier2 = code().codeTier(Tier::Ion); Maybe stub2Index; - if (!stubs2->createTier2(gcTypesConfigured, funcExportIndices, tier2, &stub2Index)) + if (!stubs2->createTier2(gcTypesEnabled, funcExportIndices, tier2, &stub2Index)) return false; // Now that we can't fail or otherwise abort tier2, make it live. diff --git a/js/src/wasm/WasmOpIter.h b/js/src/wasm/WasmOpIter.h index 23ab09e3ecd4..c91e70050878 100644 --- a/js/src/wasm/WasmOpIter.h +++ b/js/src/wasm/WasmOpIter.h @@ -632,7 +632,7 @@ OpIter::Unify(StackType observed, StackType expected, StackType* result) return true; } - if (env_.gcTypesEnabled() == HasGcTypes::True && observed.isRefOrAnyRef() && + if (env_.gcTypesEnabled == HasGcTypes::True && observed.isRefOrAnyRef() && expected.isRefOrAnyRef() && IsSubtypeOf(observed, expected)) { *result = expected; @@ -661,7 +661,7 @@ OpIter::Join(StackType one, StackType two, StackType* result) return true; } - if (env_.gcTypesEnabled() == HasGcTypes::True && one.isRefOrAnyRef() && two.isRefOrAnyRef()) { + if (env_.gcTypesEnabled == HasGcTypes::True && one.isRefOrAnyRef() && two.isRefOrAnyRef()) { if (IsSubtypeOf(two, one)) { *result = one; return true; @@ -901,12 +901,12 @@ OpIter::readBlockType(ExprType* type) known = true; break; case uint8_t(ExprType::Ref): - known = env_.gcTypesEnabled() == HasGcTypes::True && + known = env_.gcTypesEnabled == HasGcTypes::True && uncheckedRefTypeIndex < MaxTypes && uncheckedRefTypeIndex < env_.types.length(); break; case uint8_t(ExprType::AnyRef): - known = env_.gcTypesEnabled() == HasGcTypes::True; + known = env_.gcTypesEnabled == HasGcTypes::True; break; case uint8_t(ExprType::Limit): break; diff --git a/js/src/wasm/WasmStubs.cpp b/js/src/wasm/WasmStubs.cpp index 83ce430faa5c..bcac21b76430 100644 --- a/js/src/wasm/WasmStubs.cpp +++ b/js/src/wasm/WasmStubs.cpp @@ -297,7 +297,7 @@ CallFuncExport(MacroAssembler& masm, const FuncExport& fe, const Maybe& // must map from the ABI of ExportFuncPtr to the export's signature's ABI. static bool GenerateInterpEntry(MacroAssembler& masm, const FuncExport& fe, const Maybe& funcPtr, - HasGcTypes gcTypesConfigured, Offsets* offsets) + HasGcTypes gcTypesEnabled, Offsets* offsets) { AssertExpectedSP(masm); masm.haltingAlign(CodeAlignment); @@ -352,7 +352,7 @@ GenerateInterpEntry(MacroAssembler& masm, const FuncExport& fe, const Maybe& funcPtr, HasGcTypes gcTypesConfigured, Offsets* offsets) + const Maybe& funcPtr, HasGcTypes gcTypesEnabled, Offsets* offsets) { AssertExpectedSP(masm); @@ -732,7 +732,7 @@ GenerateJitEntry(MacroAssembler& masm, size_t funcExportIndex, const FuncExport& masm.loadWasmPinnedRegsFromTls(); #ifdef ENABLE_WASM_GC - if (gcTypesConfigured == HasGcTypes::True) { + if (gcTypesEnabled == HasGcTypes::True) { masm.storePtr(WasmTlsReg, Address(sp, savedTlsOffset)); SuppressGC(masm, 1, ScratchIonEntry); } @@ -745,7 +745,7 @@ GenerateJitEntry(MacroAssembler& masm, size_t funcExportIndex, const FuncExport& masm.assertStackAlignment(WasmStackAlignment); #ifdef ENABLE_WASM_GC - if (gcTypesConfigured == HasGcTypes::True) { + if (gcTypesEnabled == HasGcTypes::True) { masm.loadPtr(Address(sp, savedTlsOffset), WasmTlsReg); SuppressGC(masm, -1, WasmTlsReg); } @@ -1848,14 +1848,14 @@ GenerateDebugTrapStub(MacroAssembler& masm, Label* throwLabel, CallableOffsets* bool wasm::GenerateEntryStubs(MacroAssembler& masm, size_t funcExportIndex, const FuncExport& fe, - const Maybe& callee, bool isAsmJS, HasGcTypes gcTypesConfigured, + const Maybe& callee, bool isAsmJS, HasGcTypes gcTypesEnabled, CodeRangeVector* codeRanges) { MOZ_ASSERT(!callee == fe.hasEagerStubs()); MOZ_ASSERT_IF(isAsmJS, fe.hasEagerStubs()); Offsets offsets; - if (!GenerateInterpEntry(masm, fe, callee, gcTypesConfigured, &offsets)) + if (!GenerateInterpEntry(masm, fe, callee, gcTypesEnabled, &offsets)) return false; if (!codeRanges->emplaceBack(CodeRange::InterpEntry, fe.funcIndex(), offsets)) return false; @@ -1863,7 +1863,7 @@ wasm::GenerateEntryStubs(MacroAssembler& masm, size_t funcExportIndex, const Fun if (isAsmJS || fe.funcType().temporarilyUnsupportedAnyRef()) return true; - if (!GenerateJitEntry(masm, funcExportIndex, fe, callee, gcTypesConfigured, &offsets)) + if (!GenerateJitEntry(masm, funcExportIndex, fe, callee, gcTypesEnabled, &offsets)) return false; if (!codeRanges->emplaceBack(CodeRange::JitEntry, fe.funcIndex(), offsets)) return false; @@ -1914,7 +1914,7 @@ wasm::GenerateStubs(const ModuleEnvironment& env, const FuncImportVector& import if (!fe.hasEagerStubs()) continue; if (!GenerateEntryStubs(masm, i, fe, noAbsolute, env.isAsmJS(), - env.gcTypesConfigured, &code->codeRanges)) + env.gcTypesEnabled, &code->codeRanges)) { return false; } diff --git a/js/src/wasm/WasmStubs.h b/js/src/wasm/WasmStubs.h index 0990ae98b35d..20655577ec82 100644 --- a/js/src/wasm/WasmStubs.h +++ b/js/src/wasm/WasmStubs.h @@ -39,7 +39,7 @@ GenerateStubs(const ModuleEnvironment& env, const FuncImportVector& imports, extern bool GenerateEntryStubs(jit::MacroAssembler& masm, size_t funcExportIndex, const FuncExport& funcExport, const Maybe& callee, - bool isAsmJS, HasGcTypes gcTypesConfigured, CodeRangeVector* codeRanges); + bool isAsmJS, HasGcTypes gcTypesEnabled, CodeRangeVector* codeRanges); // An argument that will end up on the stack according to the system ABI, to be // passed to GenerateDirectCallFromJit. Since the direct JIT call creates its diff --git a/js/src/wasm/WasmTextToBinary.cpp b/js/src/wasm/WasmTextToBinary.cpp index 6f78c29758bd..8d4b41c15a52 100644 --- a/js/src/wasm/WasmTextToBinary.cpp +++ b/js/src/wasm/WasmTextToBinary.cpp @@ -97,9 +97,6 @@ class WasmToken Field, Float, Func, -#ifdef ENABLE_WASM_GC - GcFeatureOptIn, -#endif GetGlobal, GetLocal, Global, @@ -375,9 +372,6 @@ class WasmToken case Field: case Float: case Func: -#ifdef ENABLE_WASM_GC - case GcFeatureOptIn: -#endif case Global: case Mutable: case Import: @@ -1176,8 +1170,6 @@ WasmTokenStream::next() break; case 'g': - if (consume(u"gc_feature_opt_in")) - return WasmToken(WasmToken::GcFeatureOptIn, begin, cur_); if (consume(u"get_global")) return WasmToken(WasmToken::GetGlobal, begin, cur_); if (consume(u"get_local")) @@ -3631,28 +3623,6 @@ ParseMemory(WasmParseContext& c, AstModule* module) return module->addMemory(name, memory); } -#ifdef ENABLE_WASM_GC -// Custom section for experimental work. The size of this section should always -// be 1 byte, and that byte is a nonzero varint7 carrying the version number -// being opted into. -static bool -ParseGcFeatureOptIn(WasmParseContext& c, AstModule* module) -{ - WasmToken token; - if (!c.ts.getIf(WasmToken::Index, &token)) { - c.ts.generateError(token, "GC feature version number required", c.error); - return false; - } - - if (token.index() == 0 || token.index() > 127) { - c.ts.generateError(token, "invalid GC feature version number", c.error); - return false; - } - - return module->addGcFeatureOptIn(token.index()); -} -#endif - static bool ParseStartFunc(WasmParseContext& c, WasmToken token, AstModule* module) { @@ -4090,13 +4060,6 @@ ParseModule(const char16_t* text, uintptr_t stackLimit, LifoAlloc& lifo, UniqueC return nullptr; break; } -#ifdef ENABLE_WASM_GC - case WasmToken::GcFeatureOptIn: { - if (!ParseGcFeatureOptIn(c, module)) - return nullptr; - break; - } -#endif case WasmToken::Global: { if (!ParseGlobal(c, module)) return nullptr; @@ -5405,26 +5368,6 @@ EncodeExpr(Encoder& e, AstExpr& expr) /*****************************************************************************/ // wasm AST binary serialization -#ifdef ENABLE_WASM_GC -static bool -EncodeGcFeatureOptInSection(Encoder& e, AstModule& module) -{ - uint32_t optInVersion = module.gcFeatureOptIn(); - if (!optInVersion) - return true; - - size_t offset; - if (!e.startSection(SectionId::GcFeatureOptIn, &offset)) - return false; - - if (!e.writeVarU32(optInVersion)) - return false; - - e.finishSection(offset); - return true; -} -#endif - static bool EncodeTypeSection(Encoder& e, AstModule& module) { @@ -5915,11 +5858,6 @@ EncodeModule(AstModule& module, Uint32Vector* offsets, Bytes* bytes) if (!e.writeFixedU32(EncodingVersion)) return false; -#ifdef ENABLE_WASM_GC - if (!EncodeGcFeatureOptInSection(e, module)) - return false; -#endif - if (!EncodeTypeSection(e, module)) return false; diff --git a/js/src/wasm/WasmValidate.cpp b/js/src/wasm/WasmValidate.cpp index 0b38661f496d..c42a1a6a71c1 100644 --- a/js/src/wasm/WasmValidate.cpp +++ b/js/src/wasm/WasmValidate.cpp @@ -397,12 +397,12 @@ DecodeValType(Decoder& d, ModuleKind kind, uint32_t numTypes, HasGcTypes gcTypes return true; case uint8_t(ValType::AnyRef): if (gcTypesEnabled == HasGcTypes::False) - return d.fail("reference types not enabled"); + break; *type = ValType(ValType::Code(uncheckedCode)); return true; case uint8_t(ValType::Ref): { if (gcTypesEnabled == HasGcTypes::False) - return d.fail("reference types not enabled"); + break; if (uncheckedRefTypeIndex >= numTypes) return d.fail("ref index out of range"); // We further validate ref types in the caller. @@ -863,14 +863,14 @@ DecodeFunctionBodyExprs(const ModuleEnvironment& env, const FuncType& funcType, } #ifdef ENABLE_WASM_GC case uint16_t(Op::RefNull): { - if (env.gcTypesEnabled() == HasGcTypes::False) + if (env.gcTypesEnabled == HasGcTypes::False) return iter.unrecognizedOpcode(&op); ValType unusedType; CHECK(iter.readRefNull(&unusedType)); break; } case uint16_t(Op::RefIsNull): { - if (env.gcTypesEnabled() == HasGcTypes::False) + if (env.gcTypesEnabled == HasGcTypes::False) return iter.unrecognizedOpcode(&op); CHECK(iter.readConversion(ValType::AnyRef, ValType::I32, ¬hing)); break; @@ -1070,7 +1070,7 @@ wasm::ValidateFunctionBody(const ModuleEnvironment& env, uint32_t funcIndex, uin const uint8_t* bodyBegin = d.currentPosition(); - if (!DecodeLocalEntries(d, ModuleKind::Wasm, env.types, env.gcTypesEnabled(), &locals)) + if (!DecodeLocalEntries(d, ModuleKind::Wasm, env.types, env.gcTypesEnabled, &locals)) return false; if (!DecodeFunctionBodyExprs(env, funcType, locals, bodyBegin + bodySize, &d)) @@ -1154,7 +1154,7 @@ DecodeFuncType(Decoder& d, ModuleEnvironment* env, TypeStateVector* typeState, u return false; for (uint32_t i = 0; i < numArgs; i++) { - if (!DecodeValType(d, ModuleKind::Wasm, env->types.length(), env->gcTypesEnabled(), &args[i])) + if (!DecodeValType(d, ModuleKind::Wasm, env->types.length(), env->gcTypesEnabled, &args[i])) return false; if (!ValidateRefType(d, typeState, args[i])) return false; @@ -1171,7 +1171,7 @@ DecodeFuncType(Decoder& d, ModuleEnvironment* env, TypeStateVector* typeState, u if (numRets == 1) { ValType type; - if (!DecodeValType(d, ModuleKind::Wasm, env->types.length(), env->gcTypesEnabled(), &type)) + if (!DecodeValType(d, ModuleKind::Wasm, env->types.length(), env->gcTypesEnabled, &type)) return false; if (!ValidateRefType(d, typeState, type)) return false; @@ -1191,7 +1191,7 @@ DecodeFuncType(Decoder& d, ModuleEnvironment* env, TypeStateVector* typeState, u static bool DecodeStructType(Decoder& d, ModuleEnvironment* env, TypeStateVector* typeState, uint32_t typeIndex) { - if (env->gcTypesEnabled() == HasGcTypes::False) + if (env->gcTypesEnabled == HasGcTypes::False) return d.fail("Structure types not enabled"); uint32_t numFields; @@ -1214,7 +1214,7 @@ DecodeStructType(Decoder& d, ModuleEnvironment* env, TypeStateVector* typeState, if ((flags & ~uint8_t(FieldFlags::AllowedMask)) != 0) return d.fail("garbage flag bits"); fields[i].isMutable = flags & uint8_t(FieldFlags::Mutable); - if (!DecodeValType(d, ModuleKind::Wasm, env->types.length(), env->gcTypesEnabled(), &fields[i].type)) + if (!DecodeValType(d, ModuleKind::Wasm, env->types.length(), env->gcTypesEnabled, &fields[i].type)) return false; if (!ValidateRefType(d, typeState, fields[i].type)) return false; @@ -1229,34 +1229,6 @@ DecodeStructType(Decoder& d, ModuleEnvironment* env, TypeStateVector* typeState, return true; } -#ifdef ENABLE_WASM_GC -static bool -DecodeGCFeatureOptInSection(Decoder& d, ModuleEnvironment* env) -{ - MaybeSectionRange range; - if (!d.startSection(SectionId::GcFeatureOptIn, env, &range, "type")) - return false; - if (!range) - return true; - - uint32_t version; - if (!d.readVarU32(&version)) - return d.fail("expected gc feature version"); - - // For documentation of what's in the various versions, see - // https://github.com/lars-t-hansen/moz-gc-experiments - // - // When we evolve the engine to handle v2, we will continue to recognize v1 - // here if v2 is fully backwards compatible with v1. - - if (version != 1) - return d.fail("unsupported version of the gc feature"); - - env->gcFeatureOptIn = HasGcTypes::True; - return d.finishSection(*range, "gcfeatureoptin"); -} -#endif - static bool DecodeTypeSection(Decoder& d, ModuleEnvironment* env) { @@ -1564,7 +1536,7 @@ DecodeImport(Decoder& d, ModuleEnvironment* env) case DefinitionKind::Global: { ValType type; bool isMutable; - if (!DecodeGlobalType(d, env->types, env->gcTypesEnabled(), &type, &isMutable)) + if (!DecodeGlobalType(d, env->types, env->gcTypesEnabled, &type, &isMutable)) return false; if (!GlobalIsJSCompatible(d, type, isMutable)) return false; @@ -1796,11 +1768,11 @@ DecodeGlobalSection(Decoder& d, ModuleEnvironment* env) for (uint32_t i = 0; i < numDefs; i++) { ValType type; bool isMutable; - if (!DecodeGlobalType(d, env->types, env->gcTypesEnabled(), &type, &isMutable)) + if (!DecodeGlobalType(d, env->types, env->gcTypesEnabled, &type, &isMutable)) return false; InitExpr initializer; - if (!DecodeInitializerExpression(d, env->gcTypesEnabled(), env->globals, type, + if (!DecodeInitializerExpression(d, env->gcTypesEnabled, env->globals, type, env->types.length(), &initializer)) { return false; @@ -1989,7 +1961,7 @@ DecodeElemSection(Decoder& d, ModuleEnvironment* env) return d.fail("table index out of range"); InitExpr offset; - if (!DecodeInitializerExpression(d, env->gcTypesEnabled(), env->globals, ValType::I32, + if (!DecodeInitializerExpression(d, env->gcTypesEnabled, env->globals, ValType::I32, env->types.length(), &offset)) { return false; @@ -2069,11 +2041,6 @@ wasm::DecodeModuleEnvironment(Decoder& d, ModuleEnvironment* env) if (!DecodePreamble(d)) return false; -#ifdef ENABLE_WASM_GC - if (!DecodeGCFeatureOptInSection(d, env)) - return false; -#endif - if (!DecodeTypeSection(d, env)) return false; @@ -2181,7 +2148,7 @@ DecodeDataSection(Decoder& d, ModuleEnvironment* env) return d.fail("data segment requires a memory section"); DataSegment seg; - if (!DecodeInitializerExpression(d, env->gcTypesEnabled(), env->globals, ValType::I32, + if (!DecodeInitializerExpression(d, env->gcTypesEnabled, env->globals, ValType::I32, env->types.length(), &seg.offset)) { return false; diff --git a/js/src/wasm/WasmValidate.h b/js/src/wasm/WasmValidate.h index dbab1135d7d5..0906e7cba75e 100644 --- a/js/src/wasm/WasmValidate.h +++ b/js/src/wasm/WasmValidate.h @@ -60,30 +60,11 @@ struct ModuleEnvironment const ModuleKind kind; const CompileMode mode; const Shareable sharedMemoryEnabled; - // `gcTypesConfigured` reflects the value of the flags --wasm-gc and - // javascript.options.wasm_gc. These flags will disappear eventually, thus - // allowing the removal of this variable and its replacement everywhere by - // the value HasGcTypes::True. - // - // For now, the value is used (a) in the value of gcTypesEnabled(), which - // controls whether ref types and struct types and associated instructions - // are accepted during validation, and (b) to control whether we emit code - // to suppress GC while wasm activations are on the stack. - const HasGcTypes gcTypesConfigured; + const HasGcTypes gcTypesEnabled; const Tier tier; // Module fields decoded from the module environment (or initialized while // validating an asm.js module) and immutable during compilation: -#ifdef ENABLE_WASM_GC - // `gcFeatureOptIn` reflects the presence in a module of a GcFeatureOptIn - // section. This variable will be removed eventually, allowing it to be - // replaced everywhere by the value HasGcTypes::True. - // - // The flag is used in the value of gcTypesEnabled(), which controls whether - // ref types and struct types and associated instructions are accepted - // during validation. - HasGcTypes gcFeatureOptIn; -#endif MemoryUsage memoryUsage; uint32_t minMemoryLength; Maybe maxMemoryLength; @@ -115,11 +96,8 @@ struct ModuleEnvironment kind(kind), mode(mode), sharedMemoryEnabled(sharedMemoryEnabled), - gcTypesConfigured(hasGcTypes), + gcTypesEnabled(hasGcTypes), tier(tier), -#ifdef ENABLE_WASM_GC - gcFeatureOptIn(HasGcTypes::False), -#endif memoryUsage(MemoryUsage::None), minMemoryLength(0) {} @@ -139,13 +117,6 @@ struct ModuleEnvironment size_t numFuncDefs() const { return funcTypes.length() - funcImportGlobalDataOffsets.length(); } -#ifdef ENABLE_WASM_GC - HasGcTypes gcTypesEnabled() const { - if (gcTypesConfigured == HasGcTypes::True) - return gcFeatureOptIn; - return HasGcTypes::False; - } -#endif bool usesMemory() const { return memoryUsage != MemoryUsage::None; } @@ -358,7 +329,6 @@ class Encoder // after the section length is the string id of the section. MOZ_MUST_USE bool startSection(SectionId id, size_t* offset) { - MOZ_ASSERT(uint32_t(id) < 128); return writeVarU32(uint32_t(id)) && writePatchableVarU32(offset); } From ae7c0c9fa9c9a02819bf27f659cf4439bcc06802 Mon Sep 17 00:00:00 2001 From: ffxbld Date: Tue, 4 Sep 2018 11:10:28 -0700 Subject: [PATCH 60/61] No bug - Tagging mozilla-central 034c5ef24e98b0ce85fa849face079f568eb397c with FIREFOX_NIGHTLY_63_END a=release DONTBUILD CLOSED TREE --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index fb0245d14024..590c28e16505 100644 --- a/.hgtags +++ b/.hgtags @@ -146,3 +146,4 @@ ccfd7b716a91241ddbc084cb7116ec561e56d5d1 FIREFOX_BETA_61_BASE 9b74b9f2939a7ae3a0ea6e711dc32ed5203e03ff FIREFOX_BETA_62_BASE 4f6e597104dabedfecfafa2ab63dc79fd7f8bc7a FIREFOX_NIGHTLY_62_END 190b827aaa2b5e6fb9af7a0defb238ccc35f8b9e FIREFOX_BETA_63_BASE +034c5ef24e98b0ce85fa849face079f568eb397c FIREFOX_NIGHTLY_63_END From ebe4d2e4d60d4b74a25f6a6d29a25cc6c8136fc6 Mon Sep 17 00:00:00 2001 From: ffxbld Date: Tue, 4 Sep 2018 11:15:27 -0700 Subject: [PATCH 61/61] Update configs. IGNORE BROKEN CHANGESETS CLOSED TREE NO BUG a=release ba=release --- CLOBBER | 2 +- browser/config/version.txt | 2 +- browser/config/version_display.txt | 2 +- config/milestone.txt | 2 +- services/sync/modules/constants.js | 2 +- xpcom/components/Module.h | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CLOBBER b/CLOBBER index 54dd1f2aa44c..d4cdfaff33de 100644 --- a/CLOBBER +++ b/CLOBBER @@ -22,4 +22,4 @@ # changes to stick? As of bug 928195, this shouldn't be necessary! Please # don't change CLOBBER for WebIDL changes any more. -Bug 1346211 - Modifying ICU data file requires a clobber. +Merge day clobber \ No newline at end of file diff --git a/browser/config/version.txt b/browser/config/version.txt index f1d963ce19b6..351c72c7e70f 100644 --- a/browser/config/version.txt +++ b/browser/config/version.txt @@ -1 +1 @@ -63.0a1 +64.0a1 diff --git a/browser/config/version_display.txt b/browser/config/version_display.txt index f1d963ce19b6..351c72c7e70f 100644 --- a/browser/config/version_display.txt +++ b/browser/config/version_display.txt @@ -1 +1 @@ -63.0a1 +64.0a1 diff --git a/config/milestone.txt b/config/milestone.txt index bdc9bcf488b7..9f5ef7669eef 100644 --- a/config/milestone.txt +++ b/config/milestone.txt @@ -10,4 +10,4 @@ # hardcoded milestones in the tree from these two files. #-------------------------------------------------------- -63.0a1 +64.0a1 diff --git a/services/sync/modules/constants.js b/services/sync/modules/constants.js index 0d6cbc80529c..4a91fac9d315 100644 --- a/services/sync/modules/constants.js +++ b/services/sync/modules/constants.js @@ -8,7 +8,7 @@ for (let [key, val] of Object.entries({ // Don't manually modify this line, as it is automatically replaced on merge day // by the gecko_migration.py script. -WEAVE_VERSION: "1.65.0", +WEAVE_VERSION: "1.66.0", // Sync Server API version that the client supports. SYNC_API_VERSION: "1.5", diff --git a/xpcom/components/Module.h b/xpcom/components/Module.h index b073e83d27f8..fac3e6ca8d54 100644 --- a/xpcom/components/Module.h +++ b/xpcom/components/Module.h @@ -23,7 +23,7 @@ namespace mozilla { */ struct Module { - static const unsigned int kVersion = 63; + static const unsigned int kVersion = 64; struct CIDEntry;