Merge mozilla-inbound to mozilla-central. a=merge
authorCosmin Sabou <csabou@mozilla.com>
Tue, 05 Feb 2019 23:58:20 +0200
changeset 515185 476293c6700f
parent 514700 1e374e23c02f (current diff)
parent 515184 66f5d5a88ad9 (diff)
child 515200 cf9adbd57c3d
child 515249 48b467365ea8
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone67.0a1
first release with
nightly linux32
476293c6700f / 67.0a1 / 20190205215922 / files
nightly linux64
476293c6700f / 67.0a1 / 20190205215922 / files
nightly mac
476293c6700f / 67.0a1 / 20190205215922 / files
nightly win32
476293c6700f / 67.0a1 / 20190205215922 / files
nightly win64
476293c6700f / 67.0a1 / 20190205215922 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-inbound to mozilla-central. a=merge
browser/base/content/browser.js
browser/components/enterprisepolicies/Policies.jsm
browser/installer/windows/nsis/uninstaller.nsi
testing/web-platform/meta/IndexedDB/transaction-lifecycle.htm.ini
testing/web-platform/meta/async-local-storage/storage-smoke-test.tentative.https.html.ini
testing/web-platform/meta/compat/webkit-appearance.html.ini
testing/web-platform/meta/css/CSS2/generated-content/content-173.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-001.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-002.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-003.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-004.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-067.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-070.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-071.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-072.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-073.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-074.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-076.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-081.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-082.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-083.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-084.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-085.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-087.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-089.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-090.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-091.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-093.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-094.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-095.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-096.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-097.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-098.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-099.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-100.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-101.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-102.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-103.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-104.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-105.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-106.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-151.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-152.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-153.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-154.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-155.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-156.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-157.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-158.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-159.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-160.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-161.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-162.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-163.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-164.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-165.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-166.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-167.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-168.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-215.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-216.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-217.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-221.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-223.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-268.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-269.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-270.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-271.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-272.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-273.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-274.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-275.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-276.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-277.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-278.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-279.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-280.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-281.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-282.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-334.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-335.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-346.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-347.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-348.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-349.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-352.xht.ini
testing/web-platform/meta/css/CSS2/selectors/first-letter-punctuation-353.xht.ini
testing/web-platform/meta/css/css-grid/abspos/grid-positioned-items-padding-001.html.ini
testing/web-platform/meta/css/css-grid/abspos/grid-positioned-items-unknown-named-grid-line-001.html.ini
testing/web-platform/meta/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-vert-003.xhtml.ini
testing/web-platform/meta/encoding/legacy-mb-japanese/euc-jp/__dir__.ini
testing/web-platform/meta/encoding/legacy-mb-japanese/iso-2022-jp/__dir__.ini
testing/web-platform/meta/encoding/legacy-mb-tchinese/big5/__dir__.ini
testing/web-platform/meta/html/semantics/selectors/pseudo-classes/link.html.ini
testing/web-platform/meta/html/syntax/parsing/__dir__.ini
testing/web-platform/meta/resource-timing/resource-timing.html.ini
testing/web-platform/meta/web-locks/query-order.tentative.https.any.js.ini
testing/web-platform/meta/workers/semantics/run-a-worker/003.html.ini
testing/web-platform/tests/async-local-storage/META.yml
testing/web-platform/tests/async-local-storage/helpers/class-assert.js
testing/web-platform/tests/async-local-storage/helpers/equality-asserters.js
testing/web-platform/tests/conformance-checkers/html-svg/struct-image-07-t-isvalid.html
testing/web-platform/tests/css/css-text/astral-bidi/adlam-anti-ref.html
testing/web-platform/tests/css/css-text/astral-bidi/adlam-ref.html
testing/web-platform/tests/css/css-text/astral-bidi/cypriot-anti-ref.html
testing/web-platform/tests/css/css-text/astral-bidi/cypriot-ref.html
testing/web-platform/tests/css/css-text/astral-bidi/support/adlam.css
testing/web-platform/tests/css/css-text/astral-bidi/support/cypriot.css
testing/web-platform/tests/infrastructure/metadata/infrastructure/testdriver/actions/elementTiming.html.ini
testing/web-platform/tests/pointerevents/pointerevent_lostpointercapture_for_disconnected_node-manual.html
testing/web-platform/tests/pointerevents/pointerevent_lostpointercapture_is_first-manual.html
testing/web-platform/tests/pointerevents/pointerevent_pointerenter_does_not_bubble-manual.html
testing/web-platform/tests/pointerevents/pointerevent_pointerleave_descendant_over-manual.html
testing/web-platform/tests/pointerevents/pointerevent_pointerleave_descendants-manual.html
testing/web-platform/tests/pointerevents/pointerevent_pointerleave_does_not_bubble-manual.html
testing/web-platform/tests/pointerevents/pointerevent_pointerout_pen-manual.html
testing/web-platform/tests/pointerevents/pointerevent_pointerout_received_once-manual.html
testing/web-platform/tests/pointerevents/pointerevent_releasepointercapture_invalid_pointerid-manual.html
testing/web-platform/tests/pointerevents/pointerevent_releasepointercapture_onpointerup_mouse-manual.html
testing/web-platform/tests/pointerevents/pointerevent_setpointercapture_disconnected-manual.html
testing/web-platform/tests/pointerevents/pointerevent_setpointercapture_invalid_pointerid-manual.html
testing/web-platform/tests/pointerevents/pointerevent_setpointercapture_relatedtarget-manual.html
testing/web-platform/tests/pointerevents/pointerevent_suppress_compat_events_on_click-manual.html
testing/web-platform/tests/pointerevents/pointerevent_suppress_compat_events_on_drag_mouse-manual.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/attr-referrer/same-origin/http-https/iframe-tag/keep-origin-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/attr-referrer/same-origin/http-https/iframe-tag/no-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/attr-referrer/same-origin/http-https/iframe-tag/swap-origin-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/attr-referrer/same-origin/http-https/iframe-tag/swap-origin-redirect/same-origin-upgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/attr-referrer/same-origin/http-https/img-tag/keep-origin-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/attr-referrer/same-origin/http-https/img-tag/no-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/attr-referrer/same-origin/http-https/img-tag/swap-origin-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/attr-referrer/same-origin/http-https/img-tag/swap-origin-redirect/same-origin-upgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/attr-referrer/same-origin/http-https/script-tag/keep-origin-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/attr-referrer/same-origin/http-https/script-tag/no-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/attr-referrer/same-origin/http-https/script-tag/swap-origin-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/attr-referrer/same-origin/http-https/script-tag/swap-origin-redirect/same-origin-upgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/a-tag/no-redirect/same-origin-downgrade.http.html.headers
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/fetch-request/keep-origin-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/fetch-request/keep-origin-redirect/same-origin-downgrade.http.html.headers
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/fetch-request/no-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/fetch-request/no-redirect/same-origin-downgrade.http.html.headers
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/fetch-request/swap-origin-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/fetch-request/swap-origin-redirect/same-origin-downgrade.http.html.headers
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/fetch-request/swap-origin-redirect/same-origin-upgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/fetch-request/swap-origin-redirect/same-origin-upgrade.http.html.headers
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/iframe-tag/keep-origin-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/iframe-tag/keep-origin-redirect/same-origin-downgrade.http.html.headers
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/iframe-tag/no-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/iframe-tag/no-redirect/same-origin-downgrade.http.html.headers
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/iframe-tag/swap-origin-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/iframe-tag/swap-origin-redirect/same-origin-downgrade.http.html.headers
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/iframe-tag/swap-origin-redirect/same-origin-upgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/iframe-tag/swap-origin-redirect/same-origin-upgrade.http.html.headers
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/img-tag/keep-origin-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/img-tag/keep-origin-redirect/same-origin-downgrade.http.html.headers
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/img-tag/no-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/img-tag/no-redirect/same-origin-downgrade.http.html.headers
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/img-tag/swap-origin-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/img-tag/swap-origin-redirect/same-origin-downgrade.http.html.headers
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/img-tag/swap-origin-redirect/same-origin-upgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/img-tag/swap-origin-redirect/same-origin-upgrade.http.html.headers
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/script-tag/keep-origin-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/script-tag/keep-origin-redirect/same-origin-downgrade.http.html.headers
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/script-tag/no-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/script-tag/no-redirect/same-origin-downgrade.http.html.headers
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/script-tag/swap-origin-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/script-tag/swap-origin-redirect/same-origin-downgrade.http.html.headers
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/script-tag/swap-origin-redirect/same-origin-upgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/script-tag/swap-origin-redirect/same-origin-upgrade.http.html.headers
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/xhr-request/keep-origin-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/xhr-request/keep-origin-redirect/same-origin-downgrade.http.html.headers
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/xhr-request/no-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/xhr-request/no-redirect/same-origin-downgrade.http.html.headers
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/xhr-request/swap-origin-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/xhr-request/swap-origin-redirect/same-origin-downgrade.http.html.headers
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/xhr-request/swap-origin-redirect/same-origin-upgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/xhr-request/swap-origin-redirect/same-origin-upgrade.http.html.headers
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/fetch-request/keep-origin-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/fetch-request/no-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/fetch-request/swap-origin-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/fetch-request/swap-origin-redirect/same-origin-upgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/iframe-tag/keep-origin-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/iframe-tag/no-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/iframe-tag/swap-origin-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/iframe-tag/swap-origin-redirect/same-origin-upgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/img-tag/keep-origin-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/img-tag/no-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/img-tag/swap-origin-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/img-tag/swap-origin-redirect/same-origin-upgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/script-tag/keep-origin-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/script-tag/no-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/script-tag/swap-origin-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/script-tag/swap-origin-redirect/same-origin-upgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/xhr-request/keep-origin-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/xhr-request/no-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/xhr-request/swap-origin-redirect/same-origin-downgrade.http.html
testing/web-platform/tests/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/xhr-request/swap-origin-redirect/same-origin-upgrade.http.html
testing/web-platform/tests/resource-timing/resource-timing.html
testing/web-platform/tests/resource-timing/resource-timing.js
testing/web-platform/tests/resources/chromium/device_manager.mojom.js
testing/web-platform/tests/signed-exchange/resources/nested-sxg.sxg
testing/web-platform/tests/signed-exchange/resources/sxg-invalid-validity-url.sxg
testing/web-platform/tests/signed-exchange/resources/sxg-location.sxg
testing/web-platform/tests/tools/ci/check_stability.py
testing/web-platform/tests/tools/ci/ci_stability.sh
testing/web-platform/tests/web-locks/query-order.tentative.https.any.js
toolkit/mozapps/extensions/content/extensions.xml
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -997,18 +997,19 @@ function serializeInputStream(aStream) {
  */
 function handleUriInChrome(aBrowser, aUri) {
   if (aUri.scheme == "file") {
     try {
       let mimeType = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService)
                                               .getTypeFromURI(aUri);
       if (mimeType == "application/x-xpinstall") {
         let systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
-        AddonManager.getInstallForURL(aUri.spec, mimeType, null, null, null, null, null,
-                                      {source: "file-url"}).then(install => {
+        AddonManager.getInstallForURL(aUri.spec, {
+          telemetryInfo: {source: "file-url"},
+        }).then(install => {
           AddonManager.installAddonFromWebpage(mimeType, aBrowser, systemPrincipal,
                                                install);
         });
         return true;
       }
     } catch (e) {
       return false;
     }
--- a/browser/base/content/test/webextensions/head.js
+++ b/browser/base/content/test/webextensions/head.js
@@ -92,20 +92,18 @@ function promiseInstallEvent(addon, even
  *        URL of the .xpi file to install
  * @param {Object?} installTelemetryInfo
  *        an optional object that contains additional details used by the telemetry events.
  *
  * @returns {Promise}
  *          Resolves when the extension has been installed with the Addon
  *          object as the resolution value.
  */
-async function promiseInstallAddon(url, installTelemetryInfo) {
-  let install = await AddonManager.getInstallForURL(url, "application/x-xpinstall",
-                                                    null, null, null, null, null,
-                                                    installTelemetryInfo);
+async function promiseInstallAddon(url, telemetryInfo) {
+  let install = await AddonManager.getInstallForURL(url, {telemetryInfo});
   install.install();
 
   let addon = await new Promise(resolve => {
     install.addListener({
       onInstallEnded(_install, _addon) {
         resolve(_addon);
       },
     });
--- a/browser/components/enterprisepolicies/Policies.jsm
+++ b/browser/components/enterprisepolicies/Policies.jsm
@@ -540,18 +540,19 @@ var Policies = {
               try {
                 xpiFile.initWithPath(location);
               } catch (e) {
                 log.error(`Invalid extension path location - ${location}`);
                 continue;
               }
               url = Services.io.newFileURI(xpiFile).spec;
             }
-            AddonManager.getInstallForURL(url, "application/x-xpinstall", null, null, null, null, null,
-                                          {source: "enterprise-policy"}).then(install => {
+            AddonManager.getInstallForURL(url, {
+              telemetryInfo: {source: "enterprise-policy"},
+            }).then(install => {
               if (install.addon && install.addon.appDisabled) {
                 log.error(`Incompatible add-on - ${location}`);
                 install.cancel();
                 return;
               }
               let listener = {
               /* eslint-disable-next-line no-shadow */
                 onDownloadEnded: (install) => {
--- a/browser/components/newtab/lib/ASRouter.jsm
+++ b/browser/components/newtab/lib/ASRouter.jsm
@@ -243,19 +243,18 @@ const MessageLoaderUtils = {
   async installAddonFromURL(browser, url) {
     try {
       MessageLoaderUtils._loadAddonIconInURLBar(browser);
       const aUri = Services.io.newURI(url);
       const systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
 
       // AddonManager installation source associated to the addons installed from activitystream
       // (See Bug 1496167 for a rationale).
-      const amTelemetryInfo = {source: "activitystream"};
-      const install = await AddonManager.getInstallForURL(aUri.spec, "application/x-xpinstall", null,
-                                                          null, null, null, null, amTelemetryInfo);
+      const telemetryInfo = {source: "activitystream"};
+      const install = await AddonManager.getInstallForURL(aUri.spec, {telemetryInfo});
       await AddonManager.installAddonFromWebpage("application/x-xpinstall", browser,
         systemPrincipal, install);
     } catch (e) {
       Cu.reportError(e);
     }
   },
 
   /**
--- a/browser/components/preferences/browserLanguages.js
+++ b/browser/components/preferences/browserLanguages.js
@@ -26,18 +26,17 @@ ChromeUtils.defineModuleGetter(this, "Se
  * it will only be listed as available if that locale is also available on AMO and
  * the user has opted to search for more languages.
  */
 
 async function installFromUrl(url, hash, callback) {
   let telemetryInfo = {
     source: "about:preferences",
   };
-  let install = await AddonManager.getInstallForURL(
-    url, "application/x-xpinstall", hash, null, null, null, null, telemetryInfo);
+  let install = await AddonManager.getInstallForURL(url, {hash, telemetryInfo});
   if (callback) {
     callback(install.installId.toString());
   }
   await install.install();
   return install.addon;
 }
 
 async function dictionaryIdsForLocale(locale) {
--- a/browser/components/search/test/browser/browser.ini
+++ b/browser/components/search/test/browser/browser.ini
@@ -42,13 +42,14 @@ skip-if = os == "mac" #1421238
 [browser_private_search_perwindowpb.js]
 [browser_searchbar_openpopup.js]
 skip-if = os == "linux" # Linux has different focus behaviours.
 [browser_searchbar_keyboard_navigation.js]
 [browser_searchbar_smallpanel_keyboard_navigation.js]
 [browser_searchEngine_behaviors.js]
 skip-if = artifact # bug 1315953
 [browser_searchTelemetry.js]
+skip-if = !debug && (os == 'linux') # Bug 1515466
 support-files =
   searchTelemetry.html
   searchTelemetryAd.html
 [browser_webapi.js]
 [browser_tooManyEnginesOffered.js]
--- a/browser/extensions/pdfjs/README.mozilla
+++ b/browser/extensions/pdfjs/README.mozilla
@@ -1,5 +1,5 @@
 This is the PDF.js project output, https://github.com/mozilla/pdf.js
 
-Current extension version is: 2.1.228
+Current extension version is: 2.1.243
 
-Taken from upstream commit: 1f3e7700
+Taken from upstream commit: c0d6e46e
--- a/browser/extensions/pdfjs/content/PdfJsDefaultPreferences.jsm
+++ b/browser/extensions/pdfjs/content/PdfJsDefaultPreferences.jsm
@@ -17,32 +17,30 @@
 
 //
 // THIS FILE IS GENERATED AUTOMATICALLY, DO NOT EDIT MANUALLY!
 //
 
 "use strict";
 var EXPORTED_SYMBOLS = ["PdfJsDefaultPreferences"];
 var PdfJsDefaultPreferences = Object.freeze({
- "showPreviousViewOnLoad": true,
+ "viewOnLoad": 0,
  "defaultZoomValue": "",
- "sidebarViewOnLoad": 0,
+ "sidebarViewOnLoad": -1,
  "cursorToolOnLoad": 0,
  "enableWebGL": false,
  "eventBusDispatchToDOM": false,
  "pdfBugEnabled": false,
  "disableRange": false,
  "disableStream": false,
  "disableAutoFetch": false,
  "disableFontFace": false,
  "textLayerMode": 1,
  "useOnlyCssZoom": false,
  "externalLinkTarget": 0,
  "renderer": "canvas",
  "renderInteractiveForms": false,
  "enablePrintAutoRotate": false,
- "disableOpenActionDestination": true,
- "disablePageMode": false,
  "disablePageLabels": false,
  "historyUpdateUrl": false,
- "scrollModeOnLoad": 0,
- "spreadModeOnLoad": 0
+ "scrollModeOnLoad": -1,
+ "spreadModeOnLoad": -1
 });
--- a/browser/extensions/pdfjs/content/build/pdf.js
+++ b/browser/extensions/pdfjs/content/build/pdf.js
@@ -118,18 +118,18 @@ return /******/ (function(modules) { // 
 /************************************************************************/
 /******/ ([
 /* 0 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
 
 
-var pdfjsVersion = '2.1.228';
-var pdfjsBuild = '1f3e7700';
+var pdfjsVersion = '2.1.243';
+var pdfjsBuild = 'c0d6e46e';
 
 var pdfjsSharedUtil = __w_pdfjs_require__(1);
 
 var pdfjsDisplayAPI = __w_pdfjs_require__(6);
 
 var pdfjsDisplayTextLayer = __w_pdfjs_require__(18);
 
 var pdfjsDisplayAnnotationLayer = __w_pdfjs_require__(19);
@@ -1095,20 +1095,34 @@ function isArrayBuffer(v) {
   return typeof v === 'object' && v !== null && v.byteLength !== undefined;
 }
 
 function isSpace(ch) {
   return ch === 0x20 || ch === 0x09 || ch === 0x0D || ch === 0x0A;
 }
 
 function createPromiseCapability() {
-  var capability = {};
+  const capability = Object.create(null);
+  let isSettled = false;
+  Object.defineProperty(capability, 'settled', {
+    get() {
+      return isSettled;
+    }
+
+  });
   capability.promise = new Promise(function (resolve, reject) {
-    capability.resolve = resolve;
-    capability.reject = reject;
+    capability.resolve = function (data) {
+      isSettled = true;
+      resolve(data);
+    };
+
+    capability.reject = function (reason) {
+      isSettled = true;
+      reject(reason);
+    };
   });
   return capability;
 }
 
 var createObjectURL = function createObjectURLClosure() {
   var digits = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
   return function createObjectURL(data, contentType, forceDataSchema = false) {
     if (!forceDataSchema && _url_polyfill.URL.createObjectURL) {
@@ -1392,17 +1406,17 @@ function _fetchDocument(worker, source, 
 
   if (pdfDataRangeTransport) {
     source.length = pdfDataRangeTransport.length;
     source.initialData = pdfDataRangeTransport.initialData;
   }
 
   return worker.messageHandler.sendWithPromise('GetDocRequest', {
     docId,
-    apiVersion: '2.1.228',
+    apiVersion: '2.1.243',
     source: {
       data: source.data,
       url: source.url,
       password: source.password,
       disableAutoFetch: source.disableAutoFetch,
       rangeChunkSize: source.rangeChunkSize,
       length: source.length
     },
@@ -3123,19 +3137,19 @@ const InternalRenderTask = function Inte
       }
     }
 
   }
 
   return InternalRenderTask;
 }();
 
-const version = '2.1.228';
+const version = '2.1.243';
 exports.version = version;
-const build = '1f3e7700';
+const build = 'c0d6e46e';
 exports.build = build;
 
 /***/ }),
 /* 7 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
 
--- a/browser/extensions/pdfjs/content/build/pdf.worker.js
+++ b/browser/extensions/pdfjs/content/build/pdf.worker.js
@@ -118,18 +118,18 @@ return /******/ (function(modules) { // 
 /************************************************************************/
 /******/ ([
 /* 0 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
 
 
-const pdfjsVersion = '2.1.228';
-const pdfjsBuild = '1f3e7700';
+const pdfjsVersion = '2.1.243';
+const pdfjsBuild = 'c0d6e46e';
 
 const pdfjsCoreWorker = __w_pdfjs_require__(1);
 
 exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler;
 
 /***/ }),
 /* 1 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
@@ -370,17 +370,17 @@ var WorkerMessageHandler = {
   },
 
   createDocumentHandler(docParams, port) {
     var pdfManager;
     var terminated = false;
     var cancelXHRs = null;
     var WorkerTasks = [];
     let apiVersion = docParams.apiVersion;
-    let workerVersion = '2.1.228';
+    let workerVersion = '2.1.243';
 
     if (apiVersion !== workerVersion) {
       throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`);
     }
 
     var docId = docParams.docId;
     var docBaseUrl = docParams.docBaseUrl;
     var workerHandlerName = docParams.docId + '_worker';
@@ -1732,20 +1732,34 @@ function isArrayBuffer(v) {
   return typeof v === 'object' && v !== null && v.byteLength !== undefined;
 }
 
 function isSpace(ch) {
   return ch === 0x20 || ch === 0x09 || ch === 0x0D || ch === 0x0A;
 }
 
 function createPromiseCapability() {
-  var capability = {};
+  const capability = Object.create(null);
+  let isSettled = false;
+  Object.defineProperty(capability, 'settled', {
+    get() {
+      return isSettled;
+    }
+
+  });
   capability.promise = new Promise(function (resolve, reject) {
-    capability.resolve = resolve;
-    capability.reject = reject;
+    capability.resolve = function (data) {
+      isSettled = true;
+      resolve(data);
+    };
+
+    capability.reject = function (reason) {
+      isSettled = true;
+      reject(reason);
+    };
   });
   return capability;
 }
 
 var createObjectURL = function createObjectURLClosure() {
   var digits = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
   return function createObjectURL(data, contentType, forceDataSchema = false) {
     if (!forceDataSchema && _url_polyfill.URL.createObjectURL) {
@@ -20759,17 +20773,17 @@ var PartialEvaluator = function PartialE
         var font = textState.font;
 
         if (!(font.loadedName in seenStyles)) {
           seenStyles[font.loadedName] = true;
           textContent.styles[font.loadedName] = {
             fontFamily: font.fallbackName,
             ascent: font.ascent,
             descent: font.descent,
-            vertical: font.vertical
+            vertical: !!font.vertical
           };
         }
 
         textContentItem.fontName = font.loadedName;
         var tsm = [textState.fontSize * textState.textHScale, 0, 0, textState.fontSize, 0, textState.textRise];
 
         if (font.isType3Font && textState.fontMatrix !== _util.FONT_IDENTITY_MATRIX && textState.fontSize === 1) {
           var glyphHeight = font.bbox[3] - font.bbox[1];
@@ -20936,18 +20950,22 @@ var PartialEvaluator = function PartialE
         }
       }
 
       function flushTextContentItem() {
         if (!textContentItem.initialized) {
           return;
         }
 
-        textContentItem.width *= textContentItem.textAdvanceScale;
-        textContentItem.height *= textContentItem.textAdvanceScale;
+        if (!textContentItem.vertical) {
+          textContentItem.width *= textContentItem.textAdvanceScale;
+        } else {
+          textContentItem.height *= textContentItem.textAdvanceScale;
+        }
+
         textContent.items.push(runBidiTransform(textContentItem));
         textContentItem.initialized = false;
         textContentItem.str.length = 0;
       }
 
       function enqueueChunk() {
         let length = textContent.items.length;
 
--- a/browser/extensions/pdfjs/content/web/viewer.js
+++ b/browser/extensions/pdfjs/content/web/viewer.js
@@ -319,16 +319,21 @@ var _secondary_toolbar = __webpack_requi
 var _toolbar = __webpack_require__(31);
 
 var _view_history = __webpack_require__(32);
 
 const DEFAULT_SCALE_DELTA = 1.1;
 const DISABLE_AUTO_FETCH_LOADING_BAR_TIMEOUT = 5000;
 const FORCE_PAGES_LOADED_TIMEOUT = 10000;
 const WHEEL_ZOOM_DISABLED_TIMEOUT = 1000;
+const ViewOnLoad = {
+  UNKNOWN: -1,
+  PREVIOUS: 0,
+  INITIAL: 1
+};
 const DefaultExternalServices = {
   updateFindControlState(data) {},
 
   updateFindMatchesCount(data) {},
 
   initPassiveLoading(callbacks) {},
 
   fallback(data, callback) {},
@@ -1014,72 +1019,67 @@ let PDFViewerApplication = {
     pdfViewer.setDocument(pdfDocument);
     let firstPagePromise = pdfViewer.firstPagePromise;
     let pagesPromise = pdfViewer.pagesPromise;
     let onePageRendered = pdfViewer.onePageRendered;
     let pdfThumbnailViewer = this.pdfThumbnailViewer;
     pdfThumbnailViewer.setDocument(pdfDocument);
     firstPagePromise.then(pdfPage => {
       this.loadingBar.setWidth(this.appConfig.viewerContainer);
-
-      if (!_app_options.AppOptions.get('disableHistory') && !this.isViewerEmbedded) {
-        this.pdfHistory.initialize({
-          fingerprint: pdfDocument.fingerprint,
-          resetHistory: !_app_options.AppOptions.get('showPreviousViewOnLoad'),
-          updateUrl: _app_options.AppOptions.get('historyUpdateUrl')
-        });
-
-        if (this.pdfHistory.initialBookmark) {
-          this.initialBookmark = this.pdfHistory.initialBookmark;
-          this.initialRotation = this.pdfHistory.initialRotation;
-        }
-      }
-
-      let storePromise = store.getMultiple({
+      const storePromise = store.getMultiple({
         page: null,
         zoom: _ui_utils.DEFAULT_SCALE_VALUE,
         scrollLeft: '0',
         scrollTop: '0',
         rotation: null,
-        sidebarView: _pdf_sidebar.SidebarView.NONE,
-        scrollMode: null,
-        spreadMode: null
+        sidebarView: _pdf_sidebar.SidebarView.UNKNOWN,
+        scrollMode: _ui_utils.ScrollMode.UNKNOWN,
+        spreadMode: _ui_utils.SpreadMode.UNKNOWN
       }).catch(() => {});
       Promise.all([storePromise, pageModePromise, openActionDestPromise]).then(async ([values = {}, pageMode, openActionDest]) => {
-        if (openActionDest && !this.initialBookmark && !_app_options.AppOptions.get('disableOpenActionDestination')) {
-          this.initialBookmark = JSON.stringify(openActionDest);
-          this.pdfHistory.push({
-            explicitDest: openActionDest,
-            pageNumber: null
-          });
-        }
+        const viewOnLoad = _app_options.AppOptions.get('viewOnLoad');
+
+        this._initializePdfHistory({
+          fingerprint: pdfDocument.fingerprint,
+          viewOnLoad,
+          initialDest: openActionDest
+        });
 
         const initialBookmark = this.initialBookmark;
 
         const zoom = _app_options.AppOptions.get('defaultZoomValue');
 
         let hash = zoom ? `zoom=${zoom}` : null;
         let rotation = null;
 
         let sidebarView = _app_options.AppOptions.get('sidebarViewOnLoad');
 
         let scrollMode = _app_options.AppOptions.get('scrollModeOnLoad');
 
         let spreadMode = _app_options.AppOptions.get('spreadModeOnLoad');
 
-        if (values.page && _app_options.AppOptions.get('showPreviousViewOnLoad')) {
-          hash = 'page=' + values.page + '&zoom=' + (zoom || values.zoom) + ',' + values.scrollLeft + ',' + values.scrollTop;
+        if (values.page && viewOnLoad !== ViewOnLoad.INITIAL) {
+          hash = `page=${values.page}&zoom=${zoom || values.zoom},` + `${values.scrollLeft},${values.scrollTop}`;
           rotation = parseInt(values.rotation, 10);
-          sidebarView = sidebarView || values.sidebarView | 0;
-          scrollMode = scrollMode || values.scrollMode | 0;
-          spreadMode = spreadMode || values.spreadMode | 0;
-        }
-
-        if (pageMode && !_app_options.AppOptions.get('disablePageMode')) {
-          sidebarView = sidebarView || apiPageModeToSidebarView(pageMode);
+
+          if (sidebarView === _pdf_sidebar.SidebarView.UNKNOWN) {
+            sidebarView = values.sidebarView | 0;
+          }
+
+          if (scrollMode === _ui_utils.ScrollMode.UNKNOWN) {
+            scrollMode = values.scrollMode | 0;
+          }
+
+          if (spreadMode === _ui_utils.SpreadMode.UNKNOWN) {
+            spreadMode = values.spreadMode | 0;
+          }
+        }
+
+        if (pageMode && sidebarView === _pdf_sidebar.SidebarView.UNKNOWN) {
+          sidebarView = apiPageModeToSidebarView(pageMode);
         }
 
         this.setInitialView(hash, {
           rotation,
           sidebarView,
           scrollMode,
           spreadMode
         });
@@ -1237,41 +1237,70 @@ let PDFViewerApplication = {
         type: 'documentInfo',
         version: versionId,
         generator: generatorId,
         formType
       });
     });
   },
 
+  _initializePdfHistory({
+    fingerprint,
+    viewOnLoad,
+    initialDest = null
+  }) {
+    if (_app_options.AppOptions.get('disableHistory') || this.isViewerEmbedded) {
+      return;
+    }
+
+    this.pdfHistory.initialize({
+      fingerprint,
+      resetHistory: viewOnLoad === ViewOnLoad.INITIAL,
+      updateUrl: _app_options.AppOptions.get('historyUpdateUrl')
+    });
+
+    if (this.pdfHistory.initialBookmark) {
+      this.initialBookmark = this.pdfHistory.initialBookmark;
+      this.initialRotation = this.pdfHistory.initialRotation;
+    }
+
+    if (initialDest && !this.initialBookmark && viewOnLoad === ViewOnLoad.UNKNOWN) {
+      this.initialBookmark = JSON.stringify(initialDest);
+      this.pdfHistory.push({
+        explicitDest: initialDest,
+        pageNumber: null
+      });
+    }
+  },
+
   setInitialView(storedHash, {
     rotation,
     sidebarView,
     scrollMode,
     spreadMode
   } = {}) {
-    let setRotation = angle => {
+    const setRotation = angle => {
       if ((0, _ui_utils.isValidRotation)(angle)) {
         this.pdfViewer.pagesRotation = angle;
       }
     };
 
-    let setViewerModes = (scroll, spread) => {
-      if (Number.isInteger(scroll)) {
+    const setViewerModes = (scroll, spread) => {
+      if ((0, _ui_utils.isValidScrollMode)(scroll)) {
         this.pdfViewer.scrollMode = scroll;
       }
 
-      if (Number.isInteger(spread)) {
+      if ((0, _ui_utils.isValidSpreadMode)(spread)) {
         this.pdfViewer.spreadMode = spread;
       }
     };
 
-    setViewerModes(scrollMode, spreadMode);
     this.isInitialViewSet = true;
     this.pdfSidebar.setInitialView(sidebarView);
+    setViewerModes(scrollMode, spreadMode);
 
     if (this.initialBookmark) {
       setRotation(this.initialRotation);
       delete this.initialRotation;
       this.pdfLinkService.setHash(this.initialBookmark);
       this.initialBookmark = null;
     } else if (storedHash) {
       setRotation(rotation);
@@ -2332,16 +2361,18 @@ exports.PDFPrintServiceFactory = PDFPrin
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.isValidRotation = isValidRotation;
+exports.isValidScrollMode = isValidScrollMode;
+exports.isValidSpreadMode = isValidSpreadMode;
 exports.isPortraitOrientation = isPortraitOrientation;
 exports.getGlobalEventBus = getGlobalEventBus;
 exports.getPDFFileNameFromURL = getPDFFileNameFromURL;
 exports.noContextMenuHandler = noContextMenuHandler;
 exports.parseQueryString = parseQueryString;
 exports.backtrackBeforeAllVisibleElements = backtrackBeforeAllVisibleElements;
 exports.getVisibleElements = getVisibleElements;
 exports.roundToDivide = roundToDivide;
@@ -2349,17 +2380,17 @@ exports.getPageSizeInches = getPageSizeI
 exports.approximateFraction = approximateFraction;
 exports.getOutputScale = getOutputScale;
 exports.scrollIntoView = scrollIntoView;
 exports.watchScroll = watchScroll;
 exports.binarySearchFirstItem = binarySearchFirstItem;
 exports.normalizeWheelEventDelta = normalizeWheelEventDelta;
 exports.waitOnEventOrTimeout = waitOnEventOrTimeout;
 exports.moveToEndOfArray = moveToEndOfArray;
-exports.WaitOnType = exports.animationStarted = exports.ProgressBar = exports.EventBus = exports.NullL10n = exports.TextLayerMode = exports.RendererType = exports.PresentationModeState = exports.VERTICAL_PADDING = exports.SCROLLBAR_PADDING = exports.MAX_AUTO_SCALE = exports.UNKNOWN_SCALE = exports.MAX_SCALE = exports.MIN_SCALE = exports.DEFAULT_SCALE = exports.DEFAULT_SCALE_VALUE = exports.CSS_UNITS = void 0;
+exports.WaitOnType = exports.animationStarted = exports.ProgressBar = exports.EventBus = exports.NullL10n = exports.SpreadMode = exports.ScrollMode = exports.TextLayerMode = exports.RendererType = exports.PresentationModeState = exports.VERTICAL_PADDING = exports.SCROLLBAR_PADDING = exports.MAX_AUTO_SCALE = exports.UNKNOWN_SCALE = exports.MAX_SCALE = exports.MIN_SCALE = exports.DEFAULT_SCALE = exports.DEFAULT_SCALE_VALUE = exports.CSS_UNITS = void 0;
 const CSS_UNITS = 96.0 / 72.0;
 exports.CSS_UNITS = CSS_UNITS;
 const DEFAULT_SCALE_VALUE = 'auto';
 exports.DEFAULT_SCALE_VALUE = DEFAULT_SCALE_VALUE;
 const DEFAULT_SCALE = 1.0;
 exports.DEFAULT_SCALE = DEFAULT_SCALE;
 const MIN_SCALE = 0.10;
 exports.MIN_SCALE = MIN_SCALE;
@@ -2386,16 +2417,30 @@ const RendererType = {
 };
 exports.RendererType = RendererType;
 const TextLayerMode = {
   DISABLE: 0,
   ENABLE: 1,
   ENABLE_ENHANCE: 2
 };
 exports.TextLayerMode = TextLayerMode;
+const ScrollMode = {
+  UNKNOWN: -1,
+  VERTICAL: 0,
+  HORIZONTAL: 1,
+  WRAPPED: 2
+};
+exports.ScrollMode = ScrollMode;
+const SpreadMode = {
+  UNKNOWN: -1,
+  NONE: 0,
+  ODD: 1,
+  EVEN: 2
+};
+exports.SpreadMode = SpreadMode;
 
 function formatL10nValue(text, args) {
   if (!args) {
     return text;
   }
 
   return text.replace(/\{\{\s*(\w+)\s*\}\}/g, (all, name) => {
     return name in args ? args[name] : '{{' + name + '}}';
@@ -2793,16 +2838,24 @@ function normalizeWheelEventDelta(evt) {
 
   return delta;
 }
 
 function isValidRotation(angle) {
   return Number.isInteger(angle) && angle % 90 === 0;
 }
 
+function isValidScrollMode(mode) {
+  return Number.isInteger(mode) && Object.values(ScrollMode).includes(mode) && mode !== ScrollMode.UNKNOWN;
+}
+
+function isValidSpreadMode(mode) {
+  return Number.isInteger(mode) && Object.values(SpreadMode).includes(mode) && mode !== SpreadMode.UNKNOWN;
+}
+
 function isPortraitOrientation(size) {
   return size.width <= size.height;
 }
 
 const WaitOnType = {
   EVENT: 'event',
   TIMEOUT: 'timeout'
 };
@@ -3496,20 +3549,22 @@ Object.defineProperty(exports, "__esModu
 exports.PDFSidebar = exports.SidebarView = void 0;
 
 var _ui_utils = __webpack_require__(2);
 
 var _pdf_rendering_queue = __webpack_require__(6);
 
 const UI_NOTIFICATION_CLASS = 'pdfSidebarNotification';
 const SidebarView = {
+  UNKNOWN: -1,
   NONE: 0,
   THUMBS: 1,
   OUTLINE: 2,
-  ATTACHMENTS: 3
+  ATTACHMENTS: 3,
+  LAYERS: 4
 };
 exports.SidebarView = SidebarView;
 
 class PDFSidebar {
   constructor(options, eventBus, l10n = _ui_utils.NullL10n) {
     this.isOpen = false;
     this.active = SidebarView.THUMBS;
     this.isInitialViewSet = false;
@@ -3560,40 +3615,44 @@ class PDFSidebar {
 
   setInitialView(view = SidebarView.NONE) {
     if (this.isInitialViewSet) {
       return;
     }
 
     this.isInitialViewSet = true;
 
-    if (this.isOpen && view === SidebarView.NONE) {
+    if (view === SidebarView.NONE || view === SidebarView.UNKNOWN) {
       this._dispatchEvent();
 
       return;
     }
 
-    let isViewPreserved = view === this.visibleView;
-    this.switchView(view, true);
-
-    if (isViewPreserved) {
+    if (!this._switchView(view, true)) {
       this._dispatchEvent();
     }
   }
 
   switchView(view, forceOpen = false) {
-    if (view === SidebarView.NONE) {
-      this.close();
-      return;
-    }
-
-    let isViewChanged = view !== this.active;
+    this._switchView(view, forceOpen);
+  }
+
+  _switchView(view, forceOpen = false) {
+    const isViewChanged = view !== this.active;
     let shouldForceRendering = false;
 
     switch (view) {
+      case SidebarView.NONE:
+        if (this.isOpen) {
+          this.close();
+          return true;
+        }
+
+        return false;
+
       case SidebarView.THUMBS:
         this.thumbnailButton.classList.add('toggled');
         this.outlineButton.classList.remove('toggled');
         this.attachmentsButton.classList.remove('toggled');
         this.thumbnailView.classList.remove('hidden');
         this.outlineView.classList.add('hidden');
         this.attachmentsView.classList.add('hidden');
 
@@ -3602,61 +3661,63 @@ class PDFSidebar {
 
           shouldForceRendering = true;
         }
 
         break;
 
       case SidebarView.OUTLINE:
         if (this.outlineButton.disabled) {
-          return;
+          return false;
         }
 
         this.thumbnailButton.classList.remove('toggled');
         this.outlineButton.classList.add('toggled');
         this.attachmentsButton.classList.remove('toggled');
         this.thumbnailView.classList.add('hidden');
         this.outlineView.classList.remove('hidden');
         this.attachmentsView.classList.add('hidden');
         break;
 
       case SidebarView.ATTACHMENTS:
         if (this.attachmentsButton.disabled) {
-          return;
+          return false;
         }
 
         this.thumbnailButton.classList.remove('toggled');
         this.outlineButton.classList.remove('toggled');
         this.attachmentsButton.classList.add('toggled');
         this.thumbnailView.classList.add('hidden');
         this.outlineView.classList.add('hidden');
         this.attachmentsView.classList.remove('hidden');
         break;
 
       default:
-        console.error('PDFSidebar_switchView: "' + view + '" is an unsupported value.');
-        return;
+        console.error(`PDFSidebar._switchView: "${view}" is not a valid view.`);
+        return false;
     }
 
     this.active = view | 0;
 
     if (forceOpen && !this.isOpen) {
       this.open();
-      return;
+      return true;
     }
 
     if (shouldForceRendering) {
       this._forceRendering();
     }
 
     if (isViewChanged) {
       this._dispatchEvent();
     }
 
     this._hideUINotification(this.active);
+
+    return isViewChanged;
   }
 
   open() {
     if (this.isOpen) {
       return;
     }
 
     this.isOpen = true;
@@ -3892,28 +3953,20 @@ const defaultOptions = {
   defaultZoomValue: {
     value: '',
     kind: OptionKind.VIEWER
   },
   disableHistory: {
     value: false,
     kind: OptionKind.VIEWER
   },
-  disableOpenActionDestination: {
-    value: true,
-    kind: OptionKind.VIEWER
-  },
   disablePageLabels: {
     value: false,
     kind: OptionKind.VIEWER
   },
-  disablePageMode: {
-    value: false,
-    kind: OptionKind.VIEWER
-  },
   enablePrintAutoRotate: {
     value: false,
     kind: OptionKind.VIEWER
   },
   enableWebGL: {
     value: false,
     kind: OptionKind.VIEWER
   },
@@ -3933,69 +3986,71 @@ const defaultOptions = {
     value: false,
     kind: OptionKind.VIEWER
   },
   imageResourcesPath: {
     value: './images/',
     kind: OptionKind.VIEWER
   },
   maxCanvasPixels: {
-    value: _viewer_compatibility.viewerCompatibilityParams.maxCanvasPixels || 16777216,
+    value: 16777216,
+    compatibility: _viewer_compatibility.viewerCompatibilityParams.maxCanvasPixels,
     kind: OptionKind.VIEWER
   },
   pdfBugEnabled: {
     value: false,
     kind: OptionKind.VIEWER
   },
   renderer: {
     value: 'canvas',
     kind: OptionKind.VIEWER
   },
   renderInteractiveForms: {
     value: false,
     kind: OptionKind.VIEWER
   },
-  showPreviousViewOnLoad: {
-    value: true,
-    kind: OptionKind.VIEWER
-  },
   sidebarViewOnLoad: {
-    value: 0,
+    value: -1,
     kind: OptionKind.VIEWER
   },
   scrollModeOnLoad: {
-    value: 0,
+    value: -1,
     kind: OptionKind.VIEWER
   },
   spreadModeOnLoad: {
-    value: 0,
+    value: -1,
     kind: OptionKind.VIEWER
   },
   textLayerMode: {
     value: 1,
     kind: OptionKind.VIEWER
   },
   useOnlyCssZoom: {
     value: false,
     kind: OptionKind.VIEWER
   },
+  viewOnLoad: {
+    value: 0,
+    kind: OptionKind.VIEWER
+  },
   cMapPacked: {
     value: true,
     kind: OptionKind.API
   },
   cMapUrl: {
     value: '../web/cmaps/',
     kind: OptionKind.API
   },
   disableAutoFetch: {
     value: false,
     kind: OptionKind.API
   },
   disableCreateObjectURL: {
-    value: _pdfjsLib.apiCompatibilityParams.disableCreateObjectURL || false,
+    value: false,
+    compatibility: _pdfjsLib.apiCompatibilityParams.disableCreateObjectURL,
     kind: OptionKind.API
   },
   disableFontFace: {
     value: false,
     kind: OptionKind.API
   },
   disableRange: {
     value: false,
@@ -4038,38 +4093,43 @@ const defaultOptions = {
 const userOptions = Object.create(null);
 
 class AppOptions {
   constructor() {
     throw new Error('Cannot initialize AppOptions.');
   }
 
   static get(name) {
-    let defaultOption = defaultOptions[name],
-        userOption = userOptions[name];
+    const userOption = userOptions[name];
 
     if (userOption !== undefined) {
       return userOption;
     }
 
-    return defaultOption !== undefined ? defaultOption.value : undefined;
+    const defaultOption = defaultOptions[name];
+
+    if (defaultOption !== undefined) {
+      return defaultOption.compatibility || defaultOption.value;
+    }
+
+    return undefined;
   }
 
   static getAll(kind = null) {
-    let options = Object.create(null);
-
-    for (let name in defaultOptions) {
-      let defaultOption = defaultOptions[name],
-          userOption = userOptions[name];
-
-      if (kind && defaultOption.kind !== kind) {
+    const options = Object.create(null);
+
+    for (const name in defaultOptions) {
+      const defaultOption = defaultOptions[name];
+
+      if (kind && kind !== defaultOption.kind) {
         continue;
       }
 
-      options[name] = userOption !== undefined ? userOption : defaultOption.value;
+      const userOption = userOptions[name];
+      options[name] = userOption !== undefined ? userOption : defaultOption.compatibility || defaultOption.value;
     }
 
     return options;
   }
 
   static set(name, value) {
     userOptions[name] = value;
   }
@@ -8206,45 +8266,33 @@ exports.PDFViewer = PDFViewer;
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.SpreadMode = exports.ScrollMode = exports.BaseViewer = void 0;
+exports.BaseViewer = void 0;
 
 var _ui_utils = __webpack_require__(2);
 
 var _pdf_rendering_queue = __webpack_require__(6);
 
 var _annotation_layer_builder = __webpack_require__(26);
 
 var _pdfjsLib = __webpack_require__(3);
 
 var _pdf_page_view = __webpack_require__(27);
 
 var _pdf_link_service = __webpack_require__(18);
 
 var _text_layer_builder = __webpack_require__(28);
 
 const DEFAULT_CACHE_SIZE = 10;
-const ScrollMode = {
-  VERTICAL: 0,
-  HORIZONTAL: 1,
-  WRAPPED: 2
-};
-exports.ScrollMode = ScrollMode;
-const SpreadMode = {
-  NONE: 0,
-  ODD: 1,
-  EVEN: 2
-};
-exports.SpreadMode = SpreadMode;
 
 function PDFPageViewBuffer(size) {
   let data = [];
 
   this.push = function (view) {
     let i = data.indexOf(view);
 
     if (i >= 0) {
@@ -8514,28 +8562,26 @@ class BaseViewer {
     this.pagesPromise = pagesCapability.promise;
     pagesCapability.promise.then(() => {
       this._pageViewsReady = true;
       this.eventBus.dispatch('pagesloaded', {
         source: this,
         pagesCount
       });
     });
-    let isOnePageRenderedResolved = false;
-    let onePageRenderedCapability = (0, _pdfjsLib.createPromiseCapability)();
+    const onePageRenderedCapability = (0, _pdfjsLib.createPromiseCapability)();
     this.onePageRendered = onePageRenderedCapability.promise;
 
     let bindOnAfterAndBeforeDraw = pageView => {
       pageView.onBeforeDraw = () => {
         this._buffer.push(pageView);
       };
 
       pageView.onAfterDraw = () => {
-        if (!isOnePageRenderedResolved) {
-          isOnePageRenderedResolved = true;
+        if (!onePageRenderedCapability.settled) {
           onePageRenderedCapability.resolve();
         }
       };
     };
 
     let firstPagePromise = pdfDocument.getPage(1);
     this.firstPagePromise = firstPagePromise;
     firstPagePromise.then(pdfPage => {
@@ -8569,17 +8615,17 @@ class BaseViewer {
           maxCanvasPixels: this.maxCanvasPixels,
           l10n: this.l10n
         });
         bindOnAfterAndBeforeDraw(pageView);
 
         this._pages.push(pageView);
       }
 
-      if (this._spreadMode !== SpreadMode.NONE) {
+      if (this._spreadMode !== _ui_utils.SpreadMode.NONE) {
         this._updateSpreadMode();
       }
 
       onePageRenderedCapability.promise.then(() => {
         if (pdfDocument.loadingParams['disableAutoFetch']) {
           pagesCapability.resolve();
           return;
         }
@@ -8651,18 +8697,18 @@ class BaseViewer {
     this._currentScale = _ui_utils.UNKNOWN_SCALE;
     this._currentScaleValue = null;
     this._pageLabels = null;
     this._buffer = new PDFPageViewBuffer(DEFAULT_CACHE_SIZE);
     this._location = null;
     this._pagesRotation = 0;
     this._pagesRequests = [];
     this._pageViewsReady = false;
-    this._scrollMode = ScrollMode.VERTICAL;
-    this._spreadMode = SpreadMode.NONE;
+    this._scrollMode = _ui_utils.ScrollMode.VERTICAL;
+    this._spreadMode = _ui_utils.SpreadMode.NONE;
     this.viewer.textContent = '';
 
     this._updateScrollMode();
   }
 
   _scrollUpdate() {
     if (this.pagesCount === 0) {
       return;
@@ -8970,17 +9016,17 @@ class BaseViewer {
     return this.container.contains(element);
   }
 
   focus() {
     this.container.focus();
   }
 
   get _isScrollModeHorizontal() {
-    return this.isInPresentationMode ? false : this._scrollMode === ScrollMode.HORIZONTAL;
+    return this.isInPresentationMode ? false : this._scrollMode === _ui_utils.ScrollMode.HORIZONTAL;
   }
 
   get isInPresentationMode() {
     return this.presentationModeState === _ui_utils.PresentationModeState.FULLSCREEN;
   }
 
   get isChangingPresentationMode() {
     return this.presentationModeState === _ui_utils.PresentationModeState.CHANGING;
@@ -9165,34 +9211,34 @@ class BaseViewer {
     return this._scrollMode;
   }
 
   set scrollMode(mode) {
     if (this._scrollMode === mode) {
       return;
     }
 
-    if (!Number.isInteger(mode) || !Object.values(ScrollMode).includes(mode)) {
+    if (!(0, _ui_utils.isValidScrollMode)(mode)) {
       throw new Error(`Invalid scroll mode: ${mode}`);
     }
 
     this._scrollMode = mode;
     this.eventBus.dispatch('scrollmodechanged', {
       source: this,
       mode
     });
 
     this._updateScrollMode(this._currentPageNumber);
   }
 
   _updateScrollMode(pageNumber = null) {
     const scrollMode = this._scrollMode,
           viewer = this.viewer;
-    viewer.classList.toggle('scrollHorizontal', scrollMode === ScrollMode.HORIZONTAL);
-    viewer.classList.toggle('scrollWrapped', scrollMode === ScrollMode.WRAPPED);
+    viewer.classList.toggle('scrollHorizontal', scrollMode === _ui_utils.ScrollMode.HORIZONTAL);
+    viewer.classList.toggle('scrollWrapped', scrollMode === _ui_utils.ScrollMode.WRAPPED);
 
     if (!this.pdfDocument || !pageNumber) {
       return;
     }
 
     if (this._currentScaleValue && isNaN(this._currentScaleValue)) {
       this._setScale(this._currentScaleValue, true);
     }
@@ -9206,17 +9252,17 @@ class BaseViewer {
     return this._spreadMode;
   }
 
   set spreadMode(mode) {
     if (this._spreadMode === mode) {
       return;
     }
 
-    if (!Number.isInteger(mode) || !Object.values(SpreadMode).includes(mode)) {
+    if (!(0, _ui_utils.isValidSpreadMode)(mode)) {
       throw new Error(`Invalid spread mode: ${mode}`);
     }
 
     this._spreadMode = mode;
     this.eventBus.dispatch('spreadmodechanged', {
       source: this,
       mode
     });
@@ -9228,17 +9274,17 @@ class BaseViewer {
     if (!this.pdfDocument) {
       return;
     }
 
     const viewer = this.viewer,
           pages = this._pages;
     viewer.textContent = '';
 
-    if (this._spreadMode === SpreadMode.NONE) {
+    if (this._spreadMode === _ui_utils.SpreadMode.NONE) {
       for (let i = 0, iMax = pages.length; i < iMax; ++i) {
         viewer.appendChild(pages[i].div);
       }
     } else {
       const parity = this._spreadMode - 1;
       let spread = null;
 
       for (let i = 0, iMax = pages.length; i < iMax; ++i) {
@@ -10340,24 +10386,22 @@ exports.DefaultTextLayerFactory = Defaul
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.SecondaryToolbar = void 0;
 
-var _base_viewer = __webpack_require__(25);
+var _ui_utils = __webpack_require__(2);
 
 var _pdf_cursor_tools = __webpack_require__(4);
 
 var _pdf_single_page_viewer = __webpack_require__(30);
 
-var _ui_utils = __webpack_require__(2);
-
 class SecondaryToolbar {
   constructor(options, mainContainer, eventBus) {
     this.toolbar = options.toolbar;
     this.toggleButton = options.toggleButton;
     this.toolbarButtonContainer = options.toolbarButtonContainer;
     this.buttons = [{
       element: options.presentationModeButton,
       eventName: 'presentationmode',
@@ -10407,52 +10451,52 @@ class SecondaryToolbar {
       eventDetails: {
         tool: _pdf_cursor_tools.CursorTool.HAND
       },
       close: true
     }, {
       element: options.scrollVerticalButton,
       eventName: 'switchscrollmode',
       eventDetails: {
-        mode: _base_viewer.ScrollMode.VERTICAL
+        mode: _ui_utils.ScrollMode.VERTICAL
       },
       close: true
     }, {
       element: options.scrollHorizontalButton,
       eventName: 'switchscrollmode',
       eventDetails: {
-        mode: _base_viewer.ScrollMode.HORIZONTAL
+        mode: _ui_utils.ScrollMode.HORIZONTAL
       },
       close: true
     }, {
       element: options.scrollWrappedButton,
       eventName: 'switchscrollmode',
       eventDetails: {
-        mode: _base_viewer.ScrollMode.WRAPPED
+        mode: _ui_utils.ScrollMode.WRAPPED
       },
       close: true
     }, {
       element: options.spreadNoneButton,
       eventName: 'switchspreadmode',
       eventDetails: {
-        mode: _base_viewer.SpreadMode.NONE
+        mode: _ui_utils.SpreadMode.NONE
       },
       close: true
     }, {
       element: options.spreadOddButton,
       eventName: 'switchspreadmode',
       eventDetails: {
-        mode: _base_viewer.SpreadMode.ODD
+        mode: _ui_utils.SpreadMode.ODD
       },
       close: true
     }, {
       element: options.spreadEvenButton,
       eventName: 'switchspreadmode',
       eventDetails: {
-        mode: _base_viewer.SpreadMode.EVEN
+        mode: _ui_utils.SpreadMode.EVEN
       },
       close: true
     }, {
       element: options.documentPropertiesButton,
       eventName: 'documentproperties',
       close: true
     }];
     this.items = {
@@ -10569,71 +10613,71 @@ class SecondaryToolbar {
 
   _bindScrollModeListener(buttons) {
     function scrollModeChanged(evt) {
       buttons.scrollVerticalButton.classList.remove('toggled');
       buttons.scrollHorizontalButton.classList.remove('toggled');
       buttons.scrollWrappedButton.classList.remove('toggled');
 
       switch (evt.mode) {
-        case _base_viewer.ScrollMode.VERTICAL:
+        case _ui_utils.ScrollMode.VERTICAL:
           buttons.scrollVerticalButton.classList.add('toggled');
           break;
 
-        case _base_viewer.ScrollMode.HORIZONTAL:
+        case _ui_utils.ScrollMode.HORIZONTAL:
           buttons.scrollHorizontalButton.classList.add('toggled');
           break;
 
-        case _base_viewer.ScrollMode.WRAPPED:
+        case _ui_utils.ScrollMode.WRAPPED:
           buttons.scrollWrappedButton.classList.add('toggled');
           break;
       }
 
-      const isScrollModeHorizontal = evt.mode === _base_viewer.ScrollMode.HORIZONTAL;
+      const isScrollModeHorizontal = evt.mode === _ui_utils.ScrollMode.HORIZONTAL;
       buttons.spreadNoneButton.disabled = isScrollModeHorizontal;
       buttons.spreadOddButton.disabled = isScrollModeHorizontal;
       buttons.spreadEvenButton.disabled = isScrollModeHorizontal;
     }
 
     this.eventBus.on('scrollmodechanged', scrollModeChanged);
     this.eventBus.on('secondarytoolbarreset', evt => {
       if (evt.source === this) {
         scrollModeChanged({
-          mode: _base_viewer.ScrollMode.VERTICAL
+          mode: _ui_utils.ScrollMode.VERTICAL
         });
       }
     });
   }
 
   _bindSpreadModeListener(buttons) {
     function spreadModeChanged(evt) {
       buttons.spreadNoneButton.classList.remove('toggled');
       buttons.spreadOddButton.classList.remove('toggled');
       buttons.spreadEvenButton.classList.remove('toggled');
 
       switch (evt.mode) {
-        case _base_viewer.SpreadMode.NONE:
+        case _ui_utils.SpreadMode.NONE:
           buttons.spreadNoneButton.classList.add('toggled');
           break;
 
-        case _base_viewer.SpreadMode.ODD:
+        case _ui_utils.SpreadMode.ODD:
           buttons.spreadOddButton.classList.add('toggled');
           break;
 
-        case _base_viewer.SpreadMode.EVEN:
+        case _ui_utils.SpreadMode.EVEN:
           buttons.spreadEvenButton.classList.add('toggled');
           break;
       }
     }
 
     this.eventBus.on('spreadmodechanged', spreadModeChanged);
     this.eventBus.on('secondarytoolbarreset', evt => {
       if (evt.source === this) {
         spreadModeChanged({
-          mode: _base_viewer.SpreadMode.NONE
+          mode: _ui_utils.SpreadMode.NONE
         });
       }
     });
   }
 
   open() {
     if (this.opened) {
       return;
@@ -11588,39 +11632,37 @@ Object.defineProperty(exports, "__esModu
   value: true
 });
 exports.BasePreferences = void 0;
 let defaultPreferences = null;
 
 function getDefaultPreferences() {
   if (!defaultPreferences) {
     defaultPreferences = Promise.resolve({
-      "showPreviousViewOnLoad": true,
+      "viewOnLoad": 0,
       "defaultZoomValue": "",
-      "sidebarViewOnLoad": 0,
+      "sidebarViewOnLoad": -1,
       "cursorToolOnLoad": 0,
       "enableWebGL": false,
       "eventBusDispatchToDOM": false,
       "pdfBugEnabled": false,
       "disableRange": false,
       "disableStream": false,
       "disableAutoFetch": false,
       "disableFontFace": false,
       "textLayerMode": 1,
       "useOnlyCssZoom": false,
       "externalLinkTarget": 0,
       "renderer": "canvas",
       "renderInteractiveForms": false,
       "enablePrintAutoRotate": false,
-      "disableOpenActionDestination": true,
-      "disablePageMode": false,
       "disablePageLabels": false,
       "historyUpdateUrl": false,
-      "scrollModeOnLoad": 0,
-      "spreadModeOnLoad": 0
+      "scrollModeOnLoad": -1,
+      "spreadModeOnLoad": -1
     });
   }
 
   return defaultPreferences;
 }
 
 class BasePreferences {
   constructor() {
--- a/browser/extensions/pdfjs/moz.yaml
+++ b/browser/extensions/pdfjs/moz.yaml
@@ -15,15 +15,15 @@ origin:
   description: Portable Document Format (PDF) viewer that is built with HTML5
 
   # Full URL for the package's homepage/etc
   # Usually different from repository url
   url: https://github.com/mozilla/pdf.js
 
   # Human-readable identifier for this version/release
   # Generally "version NNN", "tag SSS", "bookmark SSS"
-  release: version 2.1.228
+  release: version 2.1.243
 
   # The package's license, where possible using the mnemonic from
   # https://spdx.org/licenses/
   # Multiple licenses can be specified (as a YAML list)
   # A "LICENSE" file must exist containing the full license text
   license: Apache-2.0
--- a/browser/installer/windows/nsis/installer.nsi
+++ b/browser/installer/windows/nsis/installer.nsi
@@ -479,16 +479,29 @@ Section "-Application" APP_IDX
   ${WriteRegStr2} $TmpVal "$0" "" "$INSTDIR\${FileMainEXE}" 0
   ${WriteRegStr2} $TmpVal "$0" "Path" "$INSTDIR" 0
 
   StrCpy $0 "Software\Microsoft\MediaPlayer\ShimInclusionList\$R9"
   ${CreateRegKey} "$TmpVal" "$0" 0
   StrCpy $0 "Software\Microsoft\MediaPlayer\ShimInclusionList\plugin-container.exe"
   ${CreateRegKey} "$TmpVal" "$0" 0
 
+  ; MaxLoaderThreads option is only required on AArch64 (ARM64) and it can only
+  ; be set in HKEY_LOCAL_MACHINE.
+  ${If} "${ARCH}" == "AArch64"
+  ${AndIf} $TmpVal == "HKLM"
+    StrCpy $0 "Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\${FileMainEXE}"
+    ${CreateRegKey} "$TmpVal" "$0" 0
+    ${WriteRegDWORD2} $TmpVal "$0" "MaxLoaderThreads" 1 0
+
+    StrCpy $0 "Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\plugin-container.exe"
+    ${CreateRegKey} "$TmpVal" "$0" 0
+    ${WriteRegDWORD2} $TmpVal "$0" "MaxLoaderThreads" 1 0
+  ${EndIf}
+
   ${If} $TmpVal == "HKLM"
     ; Set the permitted LSP Categories
     ${SetAppLSPCategories} ${LSP_CATEGORIES}
   ${EndIf}
 
 !ifdef MOZ_LAUNCHER_PROCESS
 !ifdef RELEASE_OR_BETA
   ${DisableLauncherProcessByDefault}
--- a/browser/installer/windows/nsis/uninstaller.nsi
+++ b/browser/installer/windows/nsis/uninstaller.nsi
@@ -368,16 +368,23 @@ Section "Uninstall"
     DeleteRegKey HKLM "$0"
     DeleteRegKey HKCU "$0"
     StrCpy $0 "Software\Microsoft\MediaPlayer\ShimInclusionList\plugin-container.exe"
     DeleteRegKey HKLM "$0"
     DeleteRegKey HKCU "$0"
     StrCpy $0 "Software\Classes\MIME\Database\Content Type\application/x-xpinstall;app=firefox"
     DeleteRegKey HKLM "$0"
     DeleteRegKey HKCU "$0"
+    ; Image File Execution Options are only set on AArch64 (ARM64).
+    ${If} "${ARCH}" == "AArch64"
+      StrCpy $0 "Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\${FileMainEXE}"
+      DeleteRegKey HKLM "$0"
+      StrCpy $0 "Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\plugin-container.exe"
+      DeleteRegKey HKLM "$0"
+    ${EndIf}
   ${Else}
     ReadRegStr $R1 HKLM "$0" ""
     ${un.RemoveQuotesFromPath} "$R1" $R1
     ${un.GetParent} "$R1" $R1
     ${If} "$INSTDIR" == "$R1"
       WriteRegStr HKLM "$0" "" "$R9"
       ${un.GetParent} "$R9" $R1
       WriteRegStr HKLM "$0" "Path" "$R1"
--- a/build/moz.configure/toolchain.configure
+++ b/build/moz.configure/toolchain.configure
@@ -462,17 +462,17 @@ def get_compiler_info(compiler, language
     # clang used is below the minimum supported version (currently clang 3.9).
     # We then only include the version information when the C++ compiler
     # matches the feature check, so that an unsupported version of clang would
     # have no version number.
     check = dedent('''\
         #if defined(_MSC_VER)
         #if defined(__clang__)
         %COMPILER "clang-cl"
-        %VERSION _MSC_FULL_VER
+        %VERSION __clang_major__.__clang_minor__.__clang_patchlevel__
         #else
         %COMPILER "msvc"
         %VERSION _MSC_FULL_VER
         #endif
         #elif defined(__clang__)
         %COMPILER "clang"
         #  if !__cplusplus || __has_builtin(__builtin_bitreverse8)
         %VERSION __clang_major__.__clang_minor__.__clang_patchlevel__
@@ -543,17 +543,17 @@ def get_compiler_info(compiler, language
     except Exception:
         raise FatalCheckError(
             'Unknown compiler or compiler not supported.')
 
     cplusplus = int(data.get('cplusplus', '0L').rstrip('L'))
     stdc_version = int(data.get('STDC_VERSION', '0L').rstrip('L'))
 
     version = data.get('VERSION')
-    if version and type in ('msvc', 'clang-cl'):
+    if version and type == 'msvc':
         msc_ver = version
         version = msc_ver[0:2]
         if len(msc_ver) > 2:
             version += '.' + msc_ver[2:4]
         if len(msc_ver) > 4:
             version += '.' + msc_ver[4:]
 
     if version:
@@ -1700,26 +1700,36 @@ add_old_configure_assignment('MOZ_UBSAN_
 
 # Security Hardening
 # ==============================================================
 
 option('--enable-hardening', env='MOZ_SECURITY_HARDENING',
        help='Enables security hardening compiler options')
 
 
+# This function is a bit confusing. It adds or removes hardening flags in
+# three stuations: if --enable-hardening is passed; if --disable-hardening
+# is passed, and if no flag is passed.
+#
+# At time of this comment writing, all flags are actually added in the
+# default no-flag case; making --enable-hardening the same as omitting the
+# flag. --disable-hardening will omit the security flags. (However, not all
+# possible security flags will be omitted by --disable-hardening, as many are
+# compiler-default options we do not explicitly enable.)
 @depends('--enable-hardening', '--enable-address-sanitizer',
          '--enable-optimize', c_compiler, target)
 def security_hardening_cflags(hardening_flag, asan, optimize, c_compiler, target):
     compiler_is_gccish = c_compiler.type in ('gcc', 'clang')
 
     flags = []
     ldflags = []
     js_flags = []
     js_ldflags = []
 
+    # ----------------------------------------------------------
     # If hardening is explicitly enabled, or not explicitly disabled
     if hardening_flag.origin == "default" or hardening_flag:
         # FORTIFY_SOURCE ------------------------------------
         # Require optimization for FORTIFY_SOURCE. See Bug 1417452
         # Also, undefine it before defining it just in case a distro adds it, see Bug 1418398
         if compiler_is_gccish and optimize and not asan:
             # Don't enable FORTIFY_SOURCE on Android on the top-level, but do enable in js/
             if target.os != 'Android':
@@ -1738,17 +1748,27 @@ def security_hardening_cflags(hardening_
 
         # ASLR ------------------------------------------------
         # ASLR (dynamicbase) is enabled by default in clang-cl; but the
         # mingw-clang build requires it to be explicitly enabled
         if target.os == 'WINNT' and c_compiler.type == 'clang':
             ldflags.append("-Wl,--dynamicbase")
             js_ldflags.append("-Wl,--dynamicbase")
 
-    # If ASAN _is_ on, undefine FOTIFY_SOURCE just to be safe
+        # Control Flow Guard (CFG) ----------------------------
+        if c_compiler.type == 'clang-cl' and c_compiler.version >= '8':
+            flags.append("-guard:cf")
+            js_flags.append("-guard:cf")
+            # nolongjmp is needed because clang doesn't emit the CFG tables of
+            # setjmp return addresses https://bugs.llvm.org/show_bug.cgi?id=40057
+            ldflags.append("-guard:cf,nolongjmp")
+            js_ldflags.append("-guard:cf,nolongjmp")
+
+    # ----------------------------------------------------------
+    # If ASAN _is_ on, undefine FORTIFY_SOURCE just to be safe
     if asan:
         flags.append("-U_FORTIFY_SOURCE")
         js_flags.append("-U_FORTIFY_SOURCE")
 
     # fno-common -----------------------------------------
     # Do not merge variables for ASAN; can detect some subtle bugs
     if asan:
         # clang-cl does not recognize the flag, it must be passed down to clang
--- a/devtools/client/inspector/rules/components/Rule.js
+++ b/devtools/client/inspector/rules/components/Rule.js
@@ -1,37 +1,71 @@
 /* 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/. */
 
 "use strict";
 
-const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react");
+const { createFactory, createRef, PureComponent } = require("devtools/client/shared/vendor/react");
 const dom = require("devtools/client/shared/vendor/react-dom-factories");
 const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
+const { editableItem } = require("devtools/client/shared/inplace-editor");
 
 const Declarations = createFactory(require("./Declarations"));
 const Selector = createFactory(require("./Selector"));
 const SelectorHighlighter = createFactory(require("./SelectorHighlighter"));
 const SourceLink = createFactory(require("./SourceLink"));
 
 const Types = require("../types");
 
 class Rule extends PureComponent {
   static get propTypes() {
     return {
       onToggleDeclaration: PropTypes.func.isRequired,
       onToggleSelectorHighlighter: PropTypes.func.isRequired,
       rule: PropTypes.shape(Types.rule).isRequired,
       showDeclarationNameEditor: PropTypes.func.isRequired,
       showDeclarationValueEditor: PropTypes.func.isRequired,
+      showNewDeclarationEditor: PropTypes.func.isRequired,
       showSelectorEditor: PropTypes.func.isRequired,
     };
   }
 
+  constructor(props) {
+    super(props);
+
+    this.closeBraceSpan = createRef();
+    this.newDeclarationSpan = createRef();
+
+    this.state = {
+      // Whether or not the new declaration editor is visible.
+      isNewDeclarationEditorVisible: false,
+    };
+
+    this.onEditorBlur = this.onEditorBlur.bind(this);
+  }
+
+  componentDidMount() {
+    if (this.props.rule.isUserAgentStyle) {
+      return;
+    }
+
+    editableItem({
+      element: this.closeBraceSpan.current,
+    }, () => {
+      this.setState({ isNewDeclarationEditorVisible: true });
+      this.props.showNewDeclarationEditor(this.newDeclarationSpan.current,
+        this.props.rule.id, this.onEditorBlur);
+    });
+  }
+
+  onEditorBlur() {
+    this.setState({ isNewDeclarationEditorVisible: false });
+  }
+
   render() {
     const {
       onToggleDeclaration,
       onToggleSelectorHighlighter,
       rule,
       showDeclarationNameEditor,
       showDeclarationValueEditor,
       showSelectorEditor,
@@ -74,16 +108,36 @@ class Rule extends PureComponent {
           ),
           Declarations({
             declarations,
             isUserAgentStyle,
             onToggleDeclaration,
             showDeclarationNameEditor,
             showDeclarationValueEditor,
           }),
-          dom.div({ className: "ruleview-ruleclose" }, "}")
+          dom.li(
+            {
+              className: "ruleview-property ruleview-newproperty",
+              style: {
+                display: this.state.isNewDeclarationEditorVisible ? "block" : "none",
+              },
+            },
+            dom.span({
+              className: "ruleview-propertyname",
+              ref: this.newDeclarationSpan,
+            })
+          ),
+          dom.div(
+            {
+              className: "ruleview-ruleclose",
+              ref: this.closeBraceSpan,
+              tabIndex: !isUserAgentStyle && !this.state.isNewDeclarationEditorVisible ?
+                0 : -1,
+            },
+            "}"
+          )
         )
       )
     );
   }
 }
 
 module.exports = Rule;
--- a/devtools/client/inspector/rules/components/Rules.js
+++ b/devtools/client/inspector/rules/components/Rules.js
@@ -14,37 +14,40 @@ const Types = require("../types");
 class Rules extends PureComponent {
   static get propTypes() {
     return {
       onToggleDeclaration: PropTypes.func.isRequired,
       onToggleSelectorHighlighter: PropTypes.func.isRequired,
       rules: PropTypes.arrayOf(PropTypes.shape(Types.rule)).isRequired,
       showDeclarationNameEditor: PropTypes.func.isRequired,
       showDeclarationValueEditor: PropTypes.func.isRequired,
+      showNewDeclarationEditor: PropTypes.func.isRequired,
       showSelectorEditor: PropTypes.func.isRequired,
     };
   }
 
   render() {
     const {
       onToggleDeclaration,
       onToggleSelectorHighlighter,
       rules,
       showDeclarationNameEditor,
       showDeclarationValueEditor,
+      showNewDeclarationEditor,
       showSelectorEditor,
     } = this.props;
 
     return rules.map(rule => {
       return Rule({
         key: rule.id,
         onToggleDeclaration,
         onToggleSelectorHighlighter,
         rule,
         showDeclarationNameEditor,
         showDeclarationValueEditor,
+        showNewDeclarationEditor,
         showSelectorEditor,
       });
     });
   }
 }
 
 module.exports = Rules;
--- a/devtools/client/inspector/rules/components/RulesApp.js
+++ b/devtools/client/inspector/rules/components/RulesApp.js
@@ -33,26 +33,28 @@ class RulesApp extends PureComponent {
       onSetClassState: PropTypes.func.isRequired,
       onToggleClassPanelExpanded: PropTypes.func.isRequired,
       onToggleDeclaration: PropTypes.func.isRequired,
       onTogglePseudoClass: PropTypes.func.isRequired,
       onToggleSelectorHighlighter: PropTypes.func.isRequired,
       rules: PropTypes.arrayOf(PropTypes.shape(Types.rule)).isRequired,
       showDeclarationNameEditor: PropTypes.func.isRequired,
       showDeclarationValueEditor: PropTypes.func.isRequired,
+      showNewDeclarationEditor: PropTypes.func.isRequired,
       showSelectorEditor: PropTypes.func.isRequired,
     };
   }
 
   getRuleProps() {
     return {
       onToggleDeclaration: this.props.onToggleDeclaration,
       onToggleSelectorHighlighter: this.props.onToggleSelectorHighlighter,
       showDeclarationNameEditor: this.props.showDeclarationNameEditor,
       showDeclarationValueEditor: this.props.showDeclarationValueEditor,
+      showNewDeclarationEditor: this.props.showNewDeclarationEditor,
       showSelectorEditor: this.props.showSelectorEditor,
     };
   }
 
   renderInheritedRules(rules) {
     if (!rules.length) {
       return null;
     }
--- a/devtools/client/inspector/rules/models/element-style.js
+++ b/devtools/client/inspector/rules/models/element-style.js
@@ -6,16 +6,17 @@
 
 const promise = require("promise");
 const Rule = require("devtools/client/inspector/rules/models/rule");
 const UserProperties = require("devtools/client/inspector/rules/models/user-properties");
 const { ELEMENT_STYLE } = require("devtools/shared/specs/styles");
 
 loader.lazyRequireGetter(this, "promiseWarn", "devtools/client/inspector/shared/utils", true);
 loader.lazyRequireGetter(this, "parseDeclarations", "devtools/shared/css/parsing-utils", true);
+loader.lazyRequireGetter(this, "parseNamedDeclarations", "devtools/shared/css/parsing-utils", true);
 loader.lazyRequireGetter(this, "parseSingleValue", "devtools/shared/css/parsing-utils", true);
 loader.lazyRequireGetter(this, "isCssVariable", "devtools/shared/fronts/css-properties", true);
 
 /**
  * ElementStyle is responsible for the following:
  *   Keeps track of which properties are overridden.
  *   Maintains a list of Rule objects for a given element.
  *
@@ -340,16 +341,39 @@ ElementStyle.prototype = {
       // overridden state has changed for the text property.
       if (this._updatePropertyOverridden(textProp)) {
         textProp.updateEditor();
       }
     }
   },
 
   /**
+   * Adds a new declaration to the rule.
+   *
+   * @param {String} ruleId
+   *        The id of the Rule to be modified.
+   * @param {String} value
+   *        The new declaration value.
+   */
+  addNewDeclaration: function(ruleId, value) {
+    const rule = this.getRule(ruleId);
+    if (!rule) {
+      return;
+    }
+
+    const declarationsToAdd = parseNamedDeclarations(this.cssProperties.isKnown,
+      value, true);
+    if (!declarationsToAdd.length) {
+      return;
+    }
+
+    this._addMultipleDeclarations(rule, declarationsToAdd);
+  },
+
+  /**
    * Adds a new rule. The rules view is updated from a "stylesheet-updated" event
    * emitted the PageStyleActor as a result of the rule being inserted into the
    * the stylesheet.
    */
   async addNewRule() {
     await this.pageStyle.addNewRule(this.element, this.element.pseudoClassLocks);
   },
 
@@ -385,16 +409,36 @@ ElementStyle.prototype = {
     await declaration.setName(declarations[0].name);
 
     if (!declaration.enabled) {
       await declaration.setEnabled(true);
     }
   },
 
   /**
+   * Helper function to addNewDeclaration() and modifyDeclarationValue() for
+   * adding multiple declarations to a rule.
+   *
+   * @param  {Rule} rule
+   *         The Rule object to write new declarations to.
+   * @param  {Array<Object>} declarationsToAdd
+   *         An array of object containg the parsed declaration data to be added.
+   * @param  {TextProperty|null} siblingDeclaration
+   *         Optional declaration next to which the new declaration will be added.
+   */
+  _addMultipleDeclarations: function(rule, declarationsToAdd, siblingDeclaration = null) {
+    for (const { commentOffsets, name, value, priority } of declarationsToAdd) {
+      const isCommented = Boolean(commentOffsets);
+      const enabled = !isCommented;
+      siblingDeclaration = rule.createProperty(name, value, priority, enabled,
+        siblingDeclaration);
+    }
+  },
+
+  /**
    * Parse a value string and break it into pieces, starting with the
    * first value, and into an array of additional declarations (if any).
    *
    * Example: Calling with "red; width: 100px" would return
    * { firstValue: "red", propertiesToAdd: [{ name: "width", value: "100px" }] }
    *
    * @param  {String} value
    *         The string to parse.
@@ -469,23 +513,17 @@ ElementStyle.prototype = {
 
     // First, set this declaration value (common case, only modified a property)
     await declaration.setValue(parsedValue.value, parsedValue.priority);
 
     if (!declaration.enabled) {
       await declaration.setEnabled(true);
     }
 
-    let siblingDeclaration = declaration;
-    for (const { commentOffsets, name, value: val, priority } of declarationsToAdd) {
-      const isCommented = Boolean(commentOffsets);
-      const enabled = !isCommented;
-      siblingDeclaration = rule.createProperty(name, val, priority, enabled,
-        siblingDeclaration);
-    }
+    this._addMultipleDeclarations(rule, declarationsToAdd, declaration);
   },
 
   /**
    * Modifies the existing rule's selector to the new given value.
    *
    * @param {String} ruleId
    *        The id of the Rule to be modified.
    * @param {String} selector
--- a/devtools/client/inspector/rules/new-rules.js
+++ b/devtools/client/inspector/rules/new-rules.js
@@ -57,16 +57,17 @@ class RulesView {
     this.onSelection = this.onSelection.bind(this);
     this.onSetClassState = this.onSetClassState.bind(this);
     this.onToggleClassPanelExpanded = this.onToggleClassPanelExpanded.bind(this);
     this.onToggleDeclaration = this.onToggleDeclaration.bind(this);
     this.onTogglePseudoClass = this.onTogglePseudoClass.bind(this);
     this.onToggleSelectorHighlighter = this.onToggleSelectorHighlighter.bind(this);
     this.showDeclarationNameEditor = this.showDeclarationNameEditor.bind(this);
     this.showDeclarationValueEditor = this.showDeclarationValueEditor.bind(this);
+    this.showNewDeclarationEditor = this.showNewDeclarationEditor.bind(this);
     this.showSelectorEditor = this.showSelectorEditor.bind(this);
     this.updateClassList = this.updateClassList.bind(this);
     this.updateRules = this.updateRules.bind(this);
 
     this.inspector.sidebar.on("select", this.onSelection);
     this.selection.on("detached-front", this.onSelection);
     this.selection.on("new-node-front", this.onSelection);
 
@@ -85,16 +86,17 @@ class RulesView {
       onAddRule: this.onAddRule,
       onSetClassState: this.onSetClassState,
       onToggleClassPanelExpanded: this.onToggleClassPanelExpanded,
       onToggleDeclaration: this.onToggleDeclaration,
       onTogglePseudoClass: this.onTogglePseudoClass,
       onToggleSelectorHighlighter: this.onToggleSelectorHighlighter,
       showDeclarationNameEditor: this.showDeclarationNameEditor,
       showDeclarationValueEditor: this.showDeclarationValueEditor,
+      showNewDeclarationEditor: this.showNewDeclarationEditor,
       showSelectorEditor: this.showSelectorEditor,
     });
 
     const provider = createElement(Provider, {
       id: "ruleview",
       key: "ruleview",
       store: this.store,
       title: INSPECTOR_L10N.getStr("inspector.sidebar.ruleViewTitle"),
@@ -473,16 +475,49 @@ class RulesView {
       },
       multiline: true,
       popup: this.autocompletePopup,
       property: declaration,
     });
   }
 
   /**
+   * Shows the new inplace editor for a new declaration.
+   *
+   * @param  {DOMNode} element
+   *         A new declaration span element to be edited.
+   * @param  {String} ruleId
+   *         The id of the Rule object to be edited.
+   * @param  {Function} callback
+   *         A callback function that is called when the inplace editor is destroyed.
+   */
+  showNewDeclarationEditor(element, ruleId, callback) {
+    new InplaceEditor({
+      advanceChars: ":",
+      contentType: InplaceEditor.CONTENT_TYPES.CSS_PROPERTY,
+      cssProperties: this.cssProperties,
+      destroy: () => {
+        callback();
+      },
+      done: (value, commit) => {
+        if (!commit || !value || !value.trim()) {
+          return;
+        }
+
+        this.elementStyle.addNewDeclaration(ruleId, value);
+        this.telemetry.recordEvent("edit_rule", "ruleview", null, {
+          "session_id": this.toolbox.sessionId,
+        });
+      },
+      element,
+      popup: this.autocompletePopup,
+    });
+  }
+
+  /**
    * Shows the inplace editor for the a selector.
    *
    * @param  {DOMNode} element
    *         The selector's span element to show the inplace editor.
    * @param  {String} ruleId
    *         The id of the Rule to be modified.
    */
   showSelectorEditor(element, ruleId) {
--- a/devtools/shared/adb/adb-addon.js
+++ b/devtools/shared/adb/adb-addon.js
@@ -118,19 +118,17 @@ class ADBAddon extends EventEmitter {
       return;
     }
     this.status = ADB_ADDON_STATES.PREPARING;
     if (addon && addon.userDisabled) {
       await addon.enable();
     } else {
       const install = await AddonManager.getInstallForURL(
         this._getXpiLink(),
-        "application/x-xpinstall",
-        null, null, null, null, null,
-        { source }
+        {telemetryInfo: {source}}
       );
       install.addListener(this);
       install.install();
     }
   }
 
   async uninstall() {
     const addon = await this._getAddon();
--- a/dom/base/ContentBlockingLog.h
+++ b/dom/base/ContentBlockingLog.h
@@ -21,194 +21,206 @@ namespace dom {
 
 class ContentBlockingLog final {
   struct LogEntry {
     uint32_t mType;
     uint32_t mRepeatCount;
     bool mBlocked;
   };
 
-  // Each element is a tuple of (type, blocked, repeatCount). The type values
-  // come from the blocking types defined in nsIWebProgressListener.
-  typedef nsTArray<LogEntry> OriginLog;
-  typedef Tuple<bool, Maybe<bool>, OriginLog> OriginData;
-  typedef nsTArray<Tuple<nsCString, UniquePtr<OriginData>>> OriginDataTable;
+  struct OriginDataEntry {
+    OriginDataEntry() : mHasTrackingContentLoaded(false) {}
+
+    bool mHasTrackingContentLoaded;
+    Maybe<bool> mHasCookiesLoaded;
+    nsTArray<LogEntry> mLogs;
+  };
+
+  struct OriginEntry {
+    OriginEntry() { mData = MakeUnique<OriginDataEntry>(); }
+
+    nsCString mOrigin;
+    UniquePtr<OriginDataEntry> mData;
+  };
+
+  typedef nsTArray<OriginEntry> OriginDataTable;
 
   struct StringWriteFunc : public JSONWriteFunc {
     nsACString&
         mBuffer;  // The lifetime of the struct must be bound to the buffer
     explicit StringWriteFunc(nsACString& aBuffer) : mBuffer(aBuffer) {}
 
     void Write(const char* aStr) override { mBuffer.Append(aStr); }
   };
 
   struct Comparator {
    public:
     bool Equals(const OriginDataTable::elem_type& aLeft,
                 const OriginDataTable::elem_type& aRight) const {
-      return Get<0>(aLeft).Equals(Get<0>(aRight));
+      return aLeft.mOrigin.Equals(aRight.mOrigin);
     }
 
     bool Equals(const OriginDataTable::elem_type& aLeft,
                 const nsACString& aRight) const {
-      return Get<0>(aLeft).Equals(aRight);
+      return aLeft.mOrigin.Equals(aRight);
     }
   };
 
  public:
   ContentBlockingLog() = default;
   ~ContentBlockingLog() = default;
 
   void RecordLog(const nsACString& aOrigin, uint32_t aType, bool aBlocked) {
     if (aOrigin.IsVoid()) {
       return;
     }
     auto index = mLog.IndexOf(aOrigin, 0, Comparator());
     if (index != OriginDataTable::NoIndex) {
-      auto& data = Get<1>(mLog[index]);
+      OriginEntry& entry = mLog[index];
+      if (!entry.mData) {
+        return;
+      }
+
       if (aType == nsIWebProgressListener::STATE_LOADED_TRACKING_CONTENT) {
-        Get<0>(*data) = aBlocked;
+        entry.mData->mHasTrackingContentLoaded = aBlocked;
         return;
       }
       if (aType == nsIWebProgressListener::STATE_COOKIES_LOADED) {
-        if (Get<1>(*data).isSome()) {
-          Get<1>(*data).ref() = aBlocked;
+        if (entry.mData->mHasCookiesLoaded.isSome()) {
+          entry.mData->mHasCookiesLoaded.ref() = aBlocked;
         } else {
-          Get<1>(*data).emplace(aBlocked);
+          entry.mData->mHasCookiesLoaded.emplace(aBlocked);
         }
         return;
       }
-      auto& log = Get<2>(*data);
-      if (!log.IsEmpty()) {
-        auto& last = log.LastElement();
+      if (!entry.mData->mLogs.IsEmpty()) {
+        auto& last = entry.mData->mLogs.LastElement();
         if (last.mType == aType && last.mBlocked == aBlocked) {
           ++last.mRepeatCount;
           // Don't record recorded events.  This helps compress our log.
           return;
         }
       }
-      if (log.Length() ==
+      if (entry.mData->mLogs.Length() ==
           std::max(1u,
                    StaticPrefs::browser_contentblocking_originlog_length())) {
         // Cap the size at the maximum length adjustable by the pref
-        log.RemoveElementAt(0);
+        entry.mData->mLogs.RemoveElementAt(0);
       }
-      log.AppendElement(LogEntry{aType, 1u, aBlocked});
+      entry.mData->mLogs.AppendElement(LogEntry{aType, 1u, aBlocked});
+      return;
+    }
+
+    // The entry has not been found.
+
+    OriginEntry* entry = mLog.AppendElement();
+    if (NS_WARN_IF(!entry || !entry->mData)) {
+      return;
+    }
+
+    entry->mOrigin = aOrigin;
+
+    if (aType == nsIWebProgressListener::STATE_LOADED_TRACKING_CONTENT) {
+      entry->mData->mHasTrackingContentLoaded = aBlocked;
+    } else if (aType == nsIWebProgressListener::STATE_COOKIES_LOADED) {
+      MOZ_ASSERT(entry->mData->mHasCookiesLoaded.isNothing());
+      entry->mData->mHasCookiesLoaded.emplace(aBlocked);
     } else {
-      auto data = MakeUnique<OriginData>(false, Maybe<bool>(), OriginLog());
-      if (aType == nsIWebProgressListener::STATE_LOADED_TRACKING_CONTENT) {
-        Get<0>(*data) = aBlocked;
-      } else if (aType == nsIWebProgressListener::STATE_COOKIES_LOADED) {
-        if (Get<1>(*data).isSome()) {
-          Get<1>(*data).ref() = aBlocked;
-        } else {
-          Get<1>(*data).emplace(aBlocked);
-        }
-      } else {
-        Get<2>(*data).AppendElement(LogEntry{aType, 1u, aBlocked});
-      }
-      nsAutoCString origin(aOrigin);
-      mLog.AppendElement(Tuple<nsCString, UniquePtr<OriginData>>(
-          std::move(origin), std::move(data)));
+      entry->mData->mLogs.AppendElement(LogEntry{aType, 1u, aBlocked});
     }
   }
 
   nsAutoCString Stringify() {
     nsAutoCString buffer;
 
     JSONWriter w(MakeUnique<StringWriteFunc>(buffer));
     w.Start();
 
-    const auto end = mLog.end();
-    for (auto iter = mLog.begin(); iter != end; ++iter) {
-      if (!Get<1>(*iter)) {
-        w.StartArrayProperty(Get<0>(*iter).get(), w.SingleLineStyle);
-        w.EndArray();
+    for (const OriginEntry& entry : mLog) {
+      if (!entry.mData) {
         continue;
       }
 
-      w.StartArrayProperty(Get<0>(*iter).get(), w.SingleLineStyle);
-      auto& data = Get<1>(*iter);
-      if (Get<0>(*data)) {
+      w.StartArrayProperty(entry.mOrigin.get(), w.SingleLineStyle);
+
+      if (entry.mData->mHasTrackingContentLoaded) {
         w.StartArrayElement(w.SingleLineStyle);
         {
           w.IntElement(nsIWebProgressListener::STATE_LOADED_TRACKING_CONTENT);
           w.BoolElement(true);  // blocked
           w.IntElement(1);      // repeat count
         }
         w.EndArray();
       }
-      if (Get<1>(*data).isSome()) {
+      if (entry.mData->mHasCookiesLoaded.isSome()) {
         w.StartArrayElement(w.SingleLineStyle);
         {
           w.IntElement(nsIWebProgressListener::STATE_COOKIES_LOADED);
-          w.BoolElement(Get<1>(*data).value());  // blocked
-          w.IntElement(1);                       // repeat count
+          w.BoolElement(entry.mData->mHasCookiesLoaded.value());  // blocked
+          w.IntElement(1);  // repeat count
         }
         w.EndArray();
       }
-      for (auto& item : Get<2>(*data)) {
+      for (const LogEntry& item : entry.mData->mLogs) {
         w.StartArrayElement(w.SingleLineStyle);
         {
           w.IntElement(item.mType);
           w.BoolElement(item.mBlocked);
           w.IntElement(item.mRepeatCount);
         }
         w.EndArray();
       }
       w.EndArray();
     }
 
     w.End();
 
     return buffer;
   }
 
-  bool HasBlockedAnyOfType(uint32_t aType) {
+  bool HasBlockedAnyOfType(uint32_t aType) const {
     // Note: nothing inside this loop should return false, the goal for the
     // loop is to scan the log to see if we find a matching entry, and if so
     // we would return true, otherwise in the end of the function outside of
     // the loop we take the common `return false;` statement.
-    const auto end = mLog.end();
-    for (auto iter = mLog.begin(); iter != end; ++iter) {
-      if (!Get<1>(*iter)) {
+    for (const OriginEntry& entry : mLog) {
+      if (!entry.mData) {
         continue;
       }
 
       if (aType == nsIWebProgressListener::STATE_LOADED_TRACKING_CONTENT) {
-        if (Get<0>(*Get<1>(*iter))) {
+        if (entry.mData->mHasTrackingContentLoaded) {
           return true;
         }
       } else if (aType == nsIWebProgressListener::STATE_COOKIES_LOADED) {
-        if (Get<1>(*Get<1>(*iter)).isSome() && Get<1>(*Get<1>(*iter)).value()) {
+        if (entry.mData->mHasCookiesLoaded.isSome() &&
+            entry.mData->mHasCookiesLoaded.value()) {
           return true;
         }
       } else {
-        for (auto& item : Get<2>(*Get<1>(*iter))) {
+        for (const auto& item : entry.mData->mLogs) {
           if (((item.mType & aType) != 0) && item.mBlocked) {
             return true;
           }
         }
       }
     }
     return false;
   }
 
   void AddSizeOfExcludingThis(nsWindowSizes& aSizes) const {
     aSizes.mDOMOtherSize +=
         mLog.ShallowSizeOfExcludingThis(aSizes.mState.mMallocSizeOf);
 
     // Now add the sizes of each origin log queue.
-    const auto end = mLog.end();
-    for (auto iter = mLog.begin(); iter != end; ++iter) {
-      if (!Get<1>(*iter)) {
-        aSizes.mDOMOtherSize +=
-            aSizes.mState.mMallocSizeOf(Get<1>(*iter).get()) +
-            Get<2>(*Get<1>(*iter))
-                .ShallowSizeOfExcludingThis(aSizes.mState.mMallocSizeOf);
+    for (const OriginEntry& entry : mLog) {
+      if (entry.mData) {
+        aSizes.mDOMOtherSize += aSizes.mState.mMallocSizeOf(entry.mData.get()) +
+                                entry.mData->mLogs.ShallowSizeOfExcludingThis(
+                                    aSizes.mState.mMallocSizeOf);
       }
     }
   }
 
  private:
   OriginDataTable mLog;
 };
 
--- a/python/mozbuild/mozbuild/test/configure/test_toolchain_configure.py
+++ b/python/mozbuild/mozbuild/test/configure/test_toolchain_configure.py
@@ -922,24 +922,24 @@ class WindowsToolchainTest(BaseToolchain
     VSXX_2017u8_RESULT = CompilerResult(
         flags=[],
         version='19.15.26726',
         type='msvc',
         compiler='/usr/bin/cl',
         language='C++',
     )
     CLANG_CL_3_9_RESULT = CompilerResult(
-        version='18.00.00000',
+        version='3.9.0',
         flags=['-Xclang', '-std=gnu99'],
         type='clang-cl',
         compiler='/usr/bin/clang-cl',
         language='C',
     )
     CLANGXX_CL_3_9_RESULT = CompilerResult(
-        version='18.00.00000',
+        version='3.9.0',
         flags=['-Xclang', '-std=c++14'],
         type='clang-cl',
         compiler='/usr/bin/clang-cl',
         language='C++',
     )
     CLANG_3_3_RESULT = LinuxToolchainTest.CLANG_3_3_RESULT
     CLANGXX_3_3_RESULT = LinuxToolchainTest.CLANGXX_3_3_RESULT
     DEFAULT_CLANG_RESULT = LinuxToolchainTest.DEFAULT_CLANG_RESULT
--- a/services/sync/modules/addonutils.js
+++ b/services/sync/modules/addonutils.js
@@ -32,20 +32,22 @@ AddonUtilsInternal.prototype = {
   getInstallFromSearchResult(addon) {
     this._log.debug("Obtaining install for " + addon.id);
 
     // We should theoretically be able to obtain (and use) addon.install if
     // it is available. However, the addon.sourceURI rewriting won't be
     // reflected in the AddonInstall, so we can't use it. If we ever get rid
     // of sourceURI rewriting, we can avoid having to reconstruct the
     // AddonInstall.
-    return AddonManager.getInstallForURL(
-      addon.sourceURI.spec, "application/x-xpinstall", undefined, addon.name, addon.iconURL, addon.version,
-      null, {source: "sync"}
-    );
+    return AddonManager.getInstallForURL(addon.sourceURI.spec, {
+      name: addon.name,
+      icons: addon.iconURL,
+      version: addon.version,
+      telemetryInfo: {source: "sync"},
+    });
   },
 
   /**
    * Installs an add-on from an AddonSearchResult instance.
    *
    * The options argument defines extra options to control the install.
    * Recognized keys in this map are:
    *
--- a/taskcluster/ci/test/misc.yml
+++ b/taskcluster/ci/test/misc.yml
@@ -4,29 +4,29 @@ geckoview-junit:
     treeherder-symbol: gv-junit
     instance-size: xlarge
     loopback-video: true
     e10s: true
     target: geckoview-androidTest.apk
     max-run-time: 3600
     tier:
         by-test-platform:
-            android-em-7.0-x86/.*: 3
+            android-em-7.*: 3
             default: default
     chunks:
         by-test-platform:
             android-em-4.3-arm7-api-16-ccov/debug: 6
             android-em-4.3-arm7-api-16/debug: 6
             android-em-4.3-arm7-api-16/opt: 2
             default: 1
     mozharness:
         script: android_emulator_unittest.py
         config:
             by-test-platform:
-                android-em-7.0-x86/.*:
+                android-em-7.*:
                     - android/android_common.py
                     - android/androidx86_7_0.py
                 android-em-4.*:
                     - android/android_common.py
                     - android/androidarm_4_3_junit.py
         extra-options:
             - --test-suite=geckoview-junit
 
@@ -85,20 +85,20 @@ test-verify:
     tier: 2
     mozharness:
         script:
             by-test-platform:
                 android-em.*: android_emulator_unittest.py
                 default: desktop_unittest.py
         config:
             by-test-platform:
-                android-em-7.0-x86/opt:
+                android-em-7.*:
                     - android/android_common.py
                     - android/androidx86_7_0.py
-                android-em.*:
+                android-em-4.*:
                     - android/android_common.py
                     - android/androidarm_4_3.py
                 linux.*:
                     - unittests/linux_unittest.py
                     - remove_executables.py
                 macosx.*:
                     - unittests/mac_unittest.py
                 windows.*:
@@ -128,20 +128,20 @@ test-verify-gpu:
     tier: 2
     mozharness:
         script:
             by-test-platform:
                 android-em.*: android_emulator_unittest.py
                 default: desktop_unittest.py
         config:
             by-test-platform:
-                android-em-7.0-x86/opt:
+                android-em-7.*:
                     - android/android_common.py
                     - android/androidx86_7_0.py
-                android-em.*:
+                android-em-4.*:
                     - android/android_common.py
                     - android/androidarm_4_3.py
                 linux.*:
                     - unittests/linux_unittest.py
                     - remove_executables.py
                 macosx.*:
                     - unittests/mac_unittest.py
                 windows.*:
@@ -165,20 +165,20 @@ test-coverage:
     tier: 2
     mozharness:
         script:
             by-test-platform:
                 android-em.*: android_emulator_unittest.py
                 default: desktop_unittest.py
         config:
             by-test-platform:
-                android-em-7.0-x86/opt:
+                android-em-7.*:
                     - android/android_common.py
                     - android/androidx86_7_0.py
-                android-em.*:
+                android-em-4.*:
                     - android/android_common.py
                     - android/androidarm_4_3.py
                 linux.*:
                     - unittests/linux_unittest.py
                     - remove_executables.py
                 macosx.*:
                     - unittests/mac_unittest.py
                 windows.*:
@@ -206,20 +206,20 @@ test-coverage-gpu:
             default: 2
     mozharness:
         script:
             by-test-platform:
                 android-em.*: android_emulator_unittest.py
                 default: desktop_unittest.py
         config:
             by-test-platform:
-                android-em-7.0-x86/opt:
+                android-em-7.*:
                     - android/android_common.py
                     - android/androidx86_7_0.py
-                android-em.*:
+                android-em-4.*:
                     - android/android_common.py
                     - android/androidarm_4_3.py
                 linux.*:
                     - unittests/linux_unittest.py
                     - remove_executables.py
                 macosx.*:
                     - unittests/mac_unittest.py
                 windows.*:
--- a/taskcluster/ci/test/reftest.yml
+++ b/taskcluster/ci/test/reftest.yml
@@ -64,18 +64,18 @@ jsreftest:
     run-on-projects: built-projects
     instance-size:
         by-test-platform:
             android-em.*: xlarge
             default: default
     chunks:
         by-test-platform:
             android-em-4.3-arm7-api-16/debug: 100
-            android-em-7.0-x86/opt: 4
-            android-em-7.0-x86/debug: 8
+            android-em-7.0-x86_64/opt: 4
+            android-em-7.0-x86_64/debug: 8
             android-em.*: 40
             windows.*: 2
             windows10-64-ccov/debug: 5
             linux64-ccov/.*: 5
             linux64-qr/.*: 4
             linux32/debug: 5
             macosx64-ccov/debug: 5
             default: 3
--- a/taskcluster/ci/test/test-platforms.yml
+++ b/taskcluster/ci/test/test-platforms.yml
@@ -327,17 +327,28 @@ android-em-4.3-arm7-api-16/opt:
     build-platform: android-api-16/opt
     test-sets:
         - android-common-tests
         - android-opt-tests
 
 android-em-7.0-x86/opt:
     build-platform: android-x86/opt
     test-sets:
-        - android-x86-kvm-tests
+        - android-x86-tests
+
+android-em-7.0-x86_64/opt:
+    build-platform: android-x86_64/opt
+    test-sets:
+        - android-x86_64-tests
+        - android-x86_64-opt-tests
+
+android-em-7.0-x86_64/debug:
+    build-platform: android-x86_64/debug
+    test-sets:
+        - android-x86_64-tests
 
 # android-hw test platforms execute on real devices attached to Autophone hosts.
 
 # android-hw-g5-7-0 Motorola Moto G5 Android 7.0
 
 android-hw-g5-7-0-arm7-api-16/opt:
     build-platform: android-api-16/opt
     test-sets:
--- a/taskcluster/ci/test/test-sets.yml
+++ b/taskcluster/ci/test/test-sets.yml
@@ -369,31 +369,34 @@ android-common-tests:
     - reftest
     - test-verify
     - xpcshell
 
 android-opt-tests:
     # Robocop tests often fail on Debug builds
     - robocop
 
-android-x86-kvm-tests:
+android-x86_64-opt-tests:
     - crashtest
     - geckoview-junit
+
+android-x86_64-tests:
     - jsreftest
     # - mochitest
     # - mochitest-chrome
     - mochitest-clipboard
     - mochitest-gpu
     # - mochitest-media
     # - mochitest-webgl1-core
     # - reftest
     # - test-verify
+
+android-x86-tests:
     - web-platform-tests
     - web-platform-tests-reftests
-    # - web-platform-tests-wdspec
 
 android-ccov-tests:
     - geckoview-junit
     - robocop
 
 devtools-tests:
     - mochitest-devtools-chrome
 
--- a/taskcluster/taskgraph/transforms/tests.py
+++ b/taskcluster/taskgraph/transforms/tests.py
@@ -595,16 +595,19 @@ def set_treeherder_machine_platform(conf
         # conflict in `verify_task_graph_symbol` once you add a new test
         # platform based on regular macOS builds, such as for QR.
         # Since it's unclear if the regular macOS builds can be removed from
         # the table, workaround the issue for QR.
         if '-qr' in test['test-platform']:
             test['treeherder-machine-platform'] = test['test-platform']
         elif 'android-hw' in test['test-platform']:
             test['treeherder-machine-platform'] = test['test-platform']
+        elif 'android-em-7.0-x86_64' in test['test-platform']:
+            opt = test['test-platform'].split('/')[1]
+            test['treeherder-machine-platform'] = 'Android-7_0-x86_64/'+opt
         elif 'android-em-7.0-x86' in test['test-platform']:
             opt = test['test-platform'].split('/')[1]
             test['treeherder-machine-platform'] = 'android-em-7-0-x86/'+opt
         else:
             test['treeherder-machine-platform'] = translation.get(
                 test['build-platform'], test['test-platform'])
         yield test
 
@@ -648,16 +651,18 @@ def set_tier(config, tests):
                                          'macosx64/debug',
                                          'macosx64-nightly/opt',
                                          'macosx64-devedition/opt',
                                          'macosx64-qr/opt',
                                          'macosx64-qr/debug',
                                          'android-em-4.3-arm7-api-16/opt',
                                          'android-em-4.3-arm7-api-16/debug',
                                          'android-em-4.2-x86/opt',
+                                         'android-em-7.0-x86_64/opt',
+                                         'android-em-7.0-x86_64/debug',
                                          'android-em-7.0-x86/opt']:
                 test['tier'] = 1
             else:
                 test['tier'] = 2
 
         yield test
 
 
--- a/toolkit/components/extensions/parent/ext-management.js
+++ b/toolkit/components/extensions/parent/ext-management.js
@@ -196,18 +196,17 @@ this.management = class extends Extensio
               }
             },
           };
 
           let telemetryInfo = {
             source: "extension",
             method: "management-webext-api",
           };
-          let install = await AddonManager.getInstallForURL(url, "application/x-xpinstall", hash,
-                                                            null, null, null, null, telemetryInfo);
+          let install = await AddonManager.getInstallForURL(url, {hash, telemetryInfo});
           install.addListener(listener);
           try {
             await install.install();
           } catch (e) {
             Cu.reportError(e);
             throw new ExtensionError("Incompatible addon");
           }
           await install.addon.enable();
--- a/toolkit/components/normandy/actions/AddonStudyAction.jsm
+++ b/toolkit/components/normandy/actions/AddonStudyAction.jsm
@@ -144,19 +144,19 @@ class AddonStudyAction extends BaseActio
     // add-on installed but no record of it, which would leave it permanently
     // installed.
 
     const { addonUrl, name, description } = recipe.arguments;
 
     const downloadDeferred = PromiseUtils.defer();
     const installDeferred = PromiseUtils.defer();
 
-    const install = await AddonManager.getInstallForURL(addonUrl, "application/x-xpinstall",
-                                                        null, null, null, null, null,
-                                                        {source: "internal"});
+    const install = await AddonManager.getInstallForURL(addonUrl, {
+      telemetryInfo: {source: "internal"},
+    });
 
     const listener = {
       onDownloadFailed() {
         downloadDeferred.reject(new AddonStudyEnrollError(name, {
           reason: "download-failure",
           detail: AddonManager.errorToString(install.error),
         }));
       },
--- a/toolkit/components/normandy/test/browser/browser_ClientEnvironment.js
+++ b/toolkit/components/normandy/test/browser/browser_ClientEnvironment.js
@@ -100,17 +100,17 @@ add_task(async function testExperiments(
   );
 
   getAll.restore();
 });
 
 add_task(withDriver(Assert, async function testAddonsInContext(driver) {
   // Create before install so that the listener is added before startup completes.
   const startupPromise = AddonTestUtils.promiseWebExtensionStartup("normandydriver@example.com");
-  const addonInstall = await AddonManager.getInstallForURL(TEST_XPI_URL, "application/x-xpinstall");
+  const addonInstall = await AddonManager.getInstallForURL(TEST_XPI_URL);
   await addonInstall.install();
   const addonId = addonInstall.addon.id;
   await startupPromise;
 
   const addons = await ClientEnvironment.addons;
   Assert.deepEqual(addons[addonId], {
     id: [addonId],
     name: "normandy_fixture",
--- a/toolkit/components/telemetry/tests/unit/test_TelemetryEnvironment.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryEnvironment.js
@@ -20,17 +20,17 @@ ChromeUtils.defineModuleGetter(this, "At
 // Lazy load |LightweightThemeManager|.
 ChromeUtils.defineModuleGetter(this, "LightweightThemeManager",
                                "resource://gre/modules/LightweightThemeManager.jsm");
 
 ChromeUtils.defineModuleGetter(this, "ExtensionTestUtils",
                                "resource://testing-common/ExtensionXPCShellUtils.jsm");
 
 async function installXPIFromURL(url) {
-  let install = await AddonManager.getInstallForURL(url, "application/x-xpinstall");
+  let install = await AddonManager.getInstallForURL(url);
   return install.install();
 }
 
 function promiseNextTick() {
   return new Promise(resolve => executeSoon(resolve));
 }
 
 // The webserver hosting the addons.
--- a/toolkit/mozapps/extensions/AddonManager.jsm
+++ b/toolkit/mozapps/extensions/AddonManager.jsm
@@ -1566,83 +1566,79 @@ var AddonManagerInternal = {
       Services.obs.notifyObservers(null, "TEST:addon-repository-data-updated");
     })();
   },
 
   /**
    * Asynchronously gets an AddonInstall for a URL.
    *
    * @param  aUrl
-   *         The string represenation of the URL the add-on is located at
-   * @param  aMimetype
-   *         The mimetype of the add-on
-   * @param  aHash
+   *         The string represenation of the URL where the add-on is located
+   * @param  {Object} [aOptions = {}]
+   *         Additional options for this install
+   * @param  {string} [aOptions.hash]
    *         An optional hash of the add-on
-   * @param  aName
+   * @param  {string} [aOptions.name]
    *         An optional placeholder name while the add-on is being downloaded
-   * @param  aIcons
+   * @param  {string|Object} [aOptions.icons]
    *         Optional placeholder icons while the add-on is being downloaded
-   * @param  aVersion
+   * @param  {string} [aOptions.version]
    *         An optional placeholder version while the add-on is being downloaded
-   * @param  aBrowser
+   * @param  {XULElement} [aOptions.browser]
    *         An optional <browser> element for download permissions prompts.
-   * @param  aTelemetryInfo
+   * @param  {Object} [aOptions.telemetryInfo]
    *         An optional object which provides details about the installation source
    *         included in the addon manager telemetry events.
-   * @throws if the aUrl, aCallback or aMimetype arguments are not specified
+   * @throws if aUrl is not specified or if an optional argument of
+   *         an improper type is passed.
    */
-  getInstallForURL(aUrl, aMimetype, aHash, aName,
-                   aIcons, aVersion, aBrowser, aTelemetryInfo) {
+  async getInstallForURL(aUrl, aOptions = {}) {
     if (!gStarted)
       throw Components.Exception("AddonManager is not initialized",
                                  Cr.NS_ERROR_NOT_INITIALIZED);
 
     if (!aUrl || typeof aUrl != "string")
       throw Components.Exception("aURL must be a non-empty string",
                                  Cr.NS_ERROR_INVALID_ARG);
 
-    if (!aMimetype || typeof aMimetype != "string")
-      throw Components.Exception("aMimetype must be a non-empty string",
+    if (aOptions.hash && typeof aOptions.hash != "string")
+      throw Components.Exception("hash must be a string or null",
                                  Cr.NS_ERROR_INVALID_ARG);
 
-    if (aHash && typeof aHash != "string")
-      throw Components.Exception("aHash must be a string or null",
+    if (aOptions.name && typeof aOptions.name != "string")
+      throw Components.Exception("name must be a string or null",
                                  Cr.NS_ERROR_INVALID_ARG);
 
-    if (aName && typeof aName != "string")
-      throw Components.Exception("aName must be a string or null",
-                                 Cr.NS_ERROR_INVALID_ARG);
-
-    if (aIcons) {
-      if (typeof aIcons == "string")
-        aIcons = { "32": aIcons };
-      else if (typeof aIcons != "object")
-        throw Components.Exception("aIcons must be a string, an object or null",
+    if (aOptions.icons) {
+      if (typeof aOptions.icons == "string")
+        aOptions.icons = { "32": aOptions.icons };
+      else if (typeof aOptions.icons != "object")
+        throw Components.Exception("icons must be a string, an object or null",
                                    Cr.NS_ERROR_INVALID_ARG);
     } else {
-      aIcons = {};
+      aOptions.icons = {};
     }
 
-    if (aVersion && typeof aVersion != "string")
-      throw Components.Exception("aVersion must be a string or null",
+    if (aOptions.version && typeof aOptions.version != "string")
+      throw Components.Exception("version must be a string or null",
                                  Cr.NS_ERROR_INVALID_ARG);
 
-    if (aBrowser && !Element.isInstance(aBrowser))
-      throw Components.Exception("aBrowser must be an Element or null",
+    if (aOptions.browser && !Element.isInstance(aOptions.browser))
+      throw Components.Exception("aOptions.browser must be an Element or null",
                                  Cr.NS_ERROR_INVALID_ARG);
 
     for (let provider of this.providers) {
-      if (callProvider(provider, "supportsMimetype", false, aMimetype)) {
-        return promiseCallProvider(
-          provider, "getInstallForURL", aUrl, aHash, aName, aIcons,
-          aVersion, aBrowser, aTelemetryInfo);
+      let install = await promiseCallProvider(provider, "getInstallForURL",
+                                              aUrl, aOptions);
+      if (install) {
+        return install;
       }
     }
 
-    return Promise.resolve(null);
+    return null;
   },
 
   /**
    * Asynchronously gets an AddonInstall for an nsIFile.
    *
    * @param  aFile
    *         The nsIFile where the add-on is located
    * @param  aMimetype
@@ -2685,24 +2681,23 @@ var AddonManagerInternal = {
       }
 
       try {
         checkInstallUrl(options.url);
       } catch (err) {
         return Promise.reject({message: err.message});
       }
 
-      let installTelemetryInfo = {
-        source: AddonManager.getInstallSourceFromHost(options.sourceHost),
-        method: "amWebAPI",
-      };
-
-      return AddonManagerInternal.getInstallForURL(options.url, "application/x-xpinstall", options.hash,
-                                                   null, null, null, null, installTelemetryInfo)
-                                 .then(install => {
+      return AddonManagerInternal.getInstallForURL(options.url, {
+        hash: options.hash,
+        telemetryInfo: {
+          source: AddonManager.getInstallSourceFromHost(options.sourceHost),
+          method: "amWebAPI",
+        },
+      }).then(install => {
         AddonManagerInternal.setupPromptHandler(target, null, install, false, "AMO");
 
         let id = this.nextInstall++;
         let {listener, installPromise} = this.makeListener(id, target.messageManager);
         install.addListener(listener);
 
         this.installs.set(id, {install, target, listener, installPromise});
 
@@ -3272,20 +3267,18 @@ var AddonManager = {
 
     if (WEBAPI_TEST_INSTALL_HOSTS.includes(host)) {
       return "test-host";
     }
 
     return "unknown";
   },
 
-  getInstallForURL(aUrl, aMimetype, aHash, aName, aIcons,
-                   aVersion, aBrowser, aTelemetryInfo) {
-    return AddonManagerInternal.getInstallForURL(
-      aUrl, aMimetype, aHash, aName, aIcons, aVersion, aBrowser, aTelemetryInfo);
+  getInstallForURL(aUrl, aOptions) {
+    return AddonManagerInternal.getInstallForURL(aUrl, aOptions);
   },
 
   getInstallForFile(aFile, aMimetype, aTelemetryInfo) {
     return AddonManagerInternal.getInstallForFile(aFile, aMimetype, aTelemetryInfo);
   },
 
   /**
    * Gets an array of add-on IDs that changed during the most recent startup.
--- a/toolkit/mozapps/extensions/Blocklist.jsm
+++ b/toolkit/mozapps/extensions/Blocklist.jsm
@@ -662,17 +662,17 @@ var Blocklist = {
       var uri = Services.io.newURI(dsURI);
     } catch (e) {
       LOG("Blocklist::notify: There was an error creating the blocklist URI\r\n" +
           "for: " + dsURI + ", error: " + e);
       return;
     }
 
     LOG("Blocklist::notify: Requesting " + uri.spec);
-    let request = new ServiceRequest();
+    let request = new ServiceRequest({mozAnon: true});
     request.open("GET", uri.spec, true);
     request.channel.notificationCallbacks = new CertUtils.BadCertHandler();
     request.overrideMimeType("text/xml");
 
     // The server will return a `304 Not Modified` response if the blocklist was
     // not changed since last check.
     const lastModified = Services.prefs.getCharPref(PREF_BLOCKLIST_LAST_MODIFIED, "");
     if (lastModified) {
--- a/toolkit/mozapps/extensions/LightweightThemeManager.jsm
+++ b/toolkit/mozapps/extensions/LightweightThemeManager.jsm
@@ -278,17 +278,17 @@ var LightweightThemeManager = {
    * removed from the usedThemes list (ie, because it was updated to an
    * xpi packaged theme).
    */
   async _updateOneTheme(theme, isCurrent) {
     if (!theme.updateURL) {
       return theme;
     }
 
-    let req = new ServiceRequest();
+    let req = new ServiceRequest({mozAnon: true});
 
     req.mozBackgroundRequest = true;
     req.overrideMimeType("text/plain");
     req.open("GET", theme.updateURL, true);
     // Prevent the request from reading from the cache.
     req.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
     // Prevent the request from writing to the cache.
     req.channel.loadFlags |= Ci.nsIRequest.INHIBIT_CACHING;
@@ -305,18 +305,20 @@ var LightweightThemeManager = {
     try {
       parsed = JSON.parse(req.responseText);
     } catch (e) {
       return theme;
     }
 
     if ("converted_theme" in parsed) {
       const {url, hash} = parsed.converted_theme;
-      let install = await AddonManager.getInstallForURL(url, "application/x-xpinstall", hash,
-                                                        null, null, null, null, {source: "lwt-converted-theme"});
+      let install = await AddonManager.getInstallForURL(url, {
+        hash,
+        telemetryInfo: {source: "lwt-converted-theme"},
+      });
 
       install.addListener({
         onDownloadEnded() {
           if (install.addon && install.type !== "theme") {
             Cu.reportError(`Refusing to update lightweight theme to a ${install.type} (from ${url})`);
             install.cancel();
             return false;
           }
--- a/toolkit/mozapps/extensions/addonManager.js
+++ b/toolkit/mozapps/extensions/addonManager.js
@@ -85,26 +85,32 @@ amManager.prototype = {
       uri,
     } = aPayload;
 
     if (!AddonManager.isInstallAllowed(mimetype, triggeringPrincipal)) {
       aCallback = null;
       retval = false;
     }
 
-    let installTelemetryInfo = {
+    let telemetryInfo = {
       source: AddonManager.getInstallSourceFromHost(aPayload.sourceHost),
     };
 
     if ("method" in aPayload) {
-      installTelemetryInfo.method = aPayload.method;
+      telemetryInfo.method = aPayload.method;
     }
 
-    AddonManager.getInstallForURL(uri, mimetype, hash, name, icon, null, aBrowser,
-                                  installTelemetryInfo).then(aInstall => {
+    AddonManager.getInstallForURL(uri, {
+      hash,
+      name,
+      icon,
+      browser: aBrowser,
+      telemetryInfo,
+      sendCookies: true,
+    }).then(aInstall => {
       function callCallback(status) {
         try {
           aCallback.onInstallEnded(uri, status);
         } catch (e) {
           Cu.reportError(e);
         }
       }
 
--- a/toolkit/mozapps/extensions/content/extensions.js
+++ b/toolkit/mozapps/extensions/content/extensions.js
@@ -3654,21 +3654,22 @@ var gDragDrop = {
       } else {
         let file = dataTransfer.mozGetDataAt("application/x-moz-file", i);
         if (file) {
           url = Services.io.newFileURI(file).spec;
         }
       }
 
       if (url) {
-        let install = await AddonManager.getInstallForURL(url, "application/x-xpinstall",
-                                                          null, null, null, null, null, {
-                                                            source: "about:addons",
-                                                            method: "drag-and-drop",
-                                                          });
+        let install = await AddonManager.getInstallForURL(url, {
+          telemetryInfo: {
+            source: "about:addons",
+            method: "drag-and-drop",
+          },
+        });
         AddonManager.installAddonFromAOM(browser, document.documentURIObject, install);
       }
     }
   },
 };
 
 // Stub tabbrowser implementation for use by the tab-modal alert code
 // when an alert/prompt/confirm method is called in a WebExtensions options_ui page
--- a/toolkit/mozapps/extensions/content/extensions.xml
+++ b/toolkit/mozapps/extensions/content/extensions.xml
@@ -1217,24 +1217,24 @@
               else
                 transformData = req.responseXML;
               showRelNotes();
             } else {
               handleError();
             }
           }
 
-          var dataReq = new XMLHttpRequest();
+          var dataReq = new XMLHttpRequest({mozAnon: true});
           dataReq.open("GET", aURI.spec, true);
           dataReq.responseType = "document";
           dataReq.addEventListener("load", handleResponse);
           dataReq.addEventListener("error", handleError);
           dataReq.send(null);
 
-          var styleReq = new XMLHttpRequest();
+          var styleReq = new XMLHttpRequest({mozAnon: true});
           styleReq.open("GET", UPDATES_RELEASENOTES_TRANSFORMFILE, true);
           styleReq.responseType = "document";
           styleReq.addEventListener("load", handleResponse);
           styleReq.addEventListener("error", handleError);
           styleReq.send(null);
         ]]></body>
       </method>
 
--- a/toolkit/mozapps/extensions/internal/AddonRepository.jsm
+++ b/toolkit/mozapps/extensions/internal/AddonRepository.jsm
@@ -442,17 +442,17 @@ var AddonRepository = {
    *                         the API call(s).
    */
   _fetchPaged(ids, pref, handler) {
     let startURL = this._formatURLPref(pref, {IDS: ids.join(",")});
     let results = [];
 
     const fetchNextPage = (url) => {
       return new Promise((resolve, reject) => {
-        let request = new ServiceRequest();
+        let request = new ServiceRequest({mozAnon: true});
         request.mozBackgroundRequest = true;
         request.open("GET", url, true);
         request.responseType = "json";
 
         request.addEventListener("error", aEvent => {
           reject(new Error(`GET ${url} failed`));
         });
         request.addEventListener("timeout", aEvent => {
--- a/toolkit/mozapps/extensions/internal/AddonUpdateChecker.jsm
+++ b/toolkit/mozapps/extensions/internal/AddonUpdateChecker.jsm
@@ -225,24 +225,23 @@ function UpdateParser(aId, aUrl, aObserv
   this.id = aId;
   this.observer = aObserver;
   this.url = aUrl;
 
   let requireBuiltIn = Services.prefs.getBoolPref(PREF_UPDATE_REQUIREBUILTINCERTS, true);
 
   logger.debug("Requesting " + aUrl);
   try {
-    this.request = new ServiceRequest();
+    this.request = new ServiceRequest({mozAnon: true});
     this.request.open("GET", this.url, true);
     this.request.channel.notificationCallbacks = new CertUtils.BadCertHandler(!requireBuiltIn);
     this.request.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
     // Prevent the request from writing to cache.
     this.request.channel.loadFlags |= Ci.nsIRequest.INHIBIT_CACHING;
     this.request.overrideMimeType("text/plain");
-    this.request.setRequestHeader("Moz-XPI-Update", "1", true);
     this.request.timeout = TIMEOUT;
     this.request.addEventListener("load", () => this.onLoad());
     this.request.addEventListener("error", () => this.onError());
     this.request.addEventListener("timeout", () => this.onTimeout());
     this.request.send(null);
   } catch (e) {
     logger.error("Failed to request update manifest", e);
   }
--- a/toolkit/mozapps/extensions/internal/ProductAddonChecker.jsm
+++ b/toolkit/mozapps/extensions/internal/ProductAddonChecker.jsm
@@ -100,16 +100,18 @@ function downloadXML(url, allowNonBuiltI
       request = request.wrappedJSObject;
     }
     request.open("GET", url, true);
     request.channel.notificationCallbacks = new CertUtils.BadCertHandler(allowNonBuiltIn);
     // Prevent the request from reading from the cache.
     request.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
     // Prevent the request from writing to the cache.
     request.channel.loadFlags |= Ci.nsIRequest.INHIBIT_CACHING;
+    // Don't send any cookies
+    request.channel.loadFlags |= Ci.nsIRequest.LOAD_ANONYMOUS;
     // Use conservative TLS settings. See bug 1325501.
     // TODO move to ServiceRequest.
     if (request.channel instanceof Ci.nsIHttpChannelInternal) {
       request.channel.QueryInterface(Ci.nsIHttpChannelInternal).beConservative = true;
     }
     request.timeout = TIMEOUT_DELAY_MS;
 
     request.overrideMimeType("text/xml");
--- a/toolkit/mozapps/extensions/internal/XPIInstall.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIInstall.jsm
@@ -1052,17 +1052,17 @@ class AddonInstall {
    * @param {string} [options.name]
    *        An optional name for the add-on
    * @param {string} [options.type]
    *        An optional type for the add-on
    * @param {object} [options.icons]
    *        Optional icons for the add-on
    * @param {string} [options.version]
    *        An optional version for the add-on
-   * @param {Object?} [options.installTelemetryInfo]
+   * @param {Object?} [options.telemetryInfo]
    *        An optional object which provides details about the installation source
    *        included in the addon manager telemetry events.
    * @param {boolean} [options.isUserRequestedUpdate]
    *        An optional boolean, true if the install object is related to a user triggered update.
    * @param {function(string) : Promise<void>} [options.promptHandler]
    *        A callback to prompt the user before installing.
    */
   constructor(installLocation, url, options = {}) {
@@ -1102,18 +1102,18 @@ class AddonInstall {
     this.logger = logger;
 
     this.name = options.name || null;
     this.type = options.type || null;
     this.version = options.version || null;
     this.isUserRequestedUpdate = options.isUserRequestedUpdate;
     this.installTelemetryInfo = null;
 
-    if (options.installTelemetryInfo) {
-      this.installTelemetryInfo = options.installTelemetryInfo;
+    if (options.telemetryInfo) {
+      this.installTelemetryInfo = options.telemetryInfo;
     } else if (this.existingAddon) {
       // Inherits the installTelemetryInfo on updates (so that the source of the original
       // installation telemetry data is being preserved across the extension updates).
       this.installTelemetryInfo = this.existingAddon.installTelemetryInfo;
     }
 
     this.file = null;
     this.ownsTempFile = null;
@@ -1816,21 +1816,24 @@ var DownloadAddonInstall = class extends
    * @param {string} [options.type]
    *        An optional type for the add-on
    * @param {Object} [options.icons]
    *        Optional icons for the add-on
    * @param {string} [options.version]
    *        An optional version for the add-on
    * @param {function(string) : Promise<void>} [options.promptHandler]
    *        A callback to prompt the user before installing.
+   * @param {boolean} [options.sendCookies]
+   *        Whether cookies should be sent when downloading the add-on.
    */
   constructor(installLocation, url, options = {}) {
     super(installLocation, url, options);
 
     this.browser = options.browser;
+    this.sendCookies = Boolean(options.sendCookies);
 
     this.state = AddonManager.STATE_AVAILABLE;
 
     this.stream = null;
     this.crypto = null;
     this.badCertHandler = null;
     this.restartDownload = false;
     this.downloadStartedAt = null;
@@ -1931,20 +1934,22 @@ var DownloadAddonInstall = class extends
       let requireBuiltIn = Services.prefs.getBoolPref(PREF_INSTALL_REQUIREBUILTINCERTS, true);
       this.badCertHandler = new CertUtils.BadCertHandler(!requireBuiltIn);
 
       this.channel = NetUtil.newChannel({
         uri: this.sourceURI,
         loadUsingSystemPrincipal: true,
       });
       this.channel.notificationCallbacks = this;
-      if (this.channel instanceof Ci.nsIHttpChannel) {
-        this.channel.setRequestHeader("Moz-XPI-Update", "1", true);
-        if (this.channel instanceof Ci.nsIHttpChannelInternal)
+      if (this.sendCookies) {
+        if (this.channel instanceof Ci.nsIHttpChannelInternal) {
           this.channel.forceAllowThirdPartyCookie = true;
+        }
+      } else {
+        this.channel.loadFlags |= Ci.nsIRequest.LOAD_ANONYMOUS;
       }
       this.channel.asyncOpen2(listener);
 
       Services.obs.addObserver(this, "network:offline-about-to-go-offline");
     } catch (e) {
       logger.warn("Failed to start download for addon " + this.sourceURI.spec, e);
       this.state = AddonManager.STATE_DOWNLOAD_FAILED;
       this.error = AddonManager.ERROR_NETWORK_FAILURE;
@@ -2538,19 +2543,17 @@ UpdateChecker.prototype = {
  */
 function createLocalInstall(file, location, telemetryInfo) {
   if (!location) {
     location = XPIStates.getLocation(KEY_APP_PROFILE);
   }
   let url = Services.io.newFileURI(file);
 
   try {
-    let install = new LocalAddonInstall(location, url, {
-      installTelemetryInfo: telemetryInfo,
-    });
+    let install = new LocalAddonInstall(location, url, {telemetryInfo});
     return install.init().then(() => install);
   } catch (e) {
     logger.error("Error creating install", e);
     XPIInstall.installs.delete(this);
     return Promise.resolve(null);
   }
 }
 
@@ -3544,52 +3547,47 @@ var XPIInstall = {
 
     return true;
   },
 
   /**
    * Called to get an AddonInstall to download and install an add-on from a URL.
    *
    * @param {nsIURI} aUrl
-   *         The URL to be installed
-   * @param {string?} [aHash]
+   *        The URL to be installed
+   * @param {object} [aOptions]
+   *        Additional options for this install.
+   * @param {string?} [aOptions.hash]
    *        A hash for the install
-   * @param {string} [aName]
+   * @param {string} [aOptions.name]
    *        A name for the install
-   * @param {Object} [aIcons]
+   * @param {Object} [aOptions.icons]
    *        Icon URLs for the install
-   * @param {string} [aVersion]
+   * @param {string} [aOptions.version]
    *        A version for the install
-   * @param {XULElement?} [aBrowser]
+   * @param {XULElement} [aOptions.browser]
    *        The browser performing the install
-   * @param {Object?} [aInstallTelemetryInfo]
+   * @param {Object} [aOptions.telemetryInfo]
    *        An optional object which provides details about the installation source
    *        included in the addon manager telemetry events.
+   * @param {boolean} [options.sendCookies = false]
+   *        Whether cookies should be sent when downloading the add-on.
    * @returns {AddonInstall}
    */
-  async getInstallForURL(aUrl, aHash, aName, aIcons, aVersion, aBrowser, aInstallTelemetryInfo) {
+  async getInstallForURL(aUrl, aOptions) {
     let location = XPIStates.getLocation(KEY_APP_PROFILE);
     let url = Services.io.newURI(aUrl);
 
-    let options = {
-      hash: aHash,
-      browser: aBrowser,
-      name: aName,
-      icons: aIcons,
-      version: aVersion,
-      installTelemetryInfo: aInstallTelemetryInfo,
-    };
-
     if (url instanceof Ci.nsIFileURL) {
-      let install = new LocalAddonInstall(location, url, options);
+      let install = new LocalAddonInstall(location, url, aOptions);
       await install.init();
       return install.wrapper;
     }
 
-    let install = new DownloadAddonInstall(location, url, options);
+    let install = new DownloadAddonInstall(location, url, aOptions);
     return install.wrapper;
   },
 
   /**
    * Called to get an AddonInstall to install an add-on from a local file.
    *
    * @param {nsIFile} aFile
    *        The file to be installed
--- a/toolkit/mozapps/extensions/test/browser/browser_installssl.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_installssl.js
@@ -75,17 +75,17 @@ function run_install_tests(callback) {
       var message = "Should have seen the right result for an install redirected from " +
                     mainURL + " to " + redirectURL;
     } else {
       url = mainURL + xpi;
       message = "Should have seen the right result for an install from " +
                 mainURL;
     }
 
-    let install = await AddonManager.getInstallForURL(url, "application/x-xpinstall");
+    let install = await AddonManager.getInstallForURL(url);
     gPendingInstall = install;
     install.addListener({
       onDownloadEnded(install) {
         is(SUCCESS, expectedStatus, message);
         info("Install test ran in " + (Date.now() - gLast) + "ms");
         // Don't proceed with the install
         install.cancel();
         gPendingInstall = null;
--- a/toolkit/mozapps/extensions/test/browser/head.js
+++ b/toolkit/mozapps/extensions/test/browser/head.js
@@ -509,17 +509,17 @@ function promiseAddonsByIDs(aIDs) {
 }
 /**
  * Install an add-on and call a callback when complete.
  *
  * The callback will receive the Addon for the installed add-on.
  */
 function install_addon(path, cb, pathPrefix = TESTROOT) {
   let p = new Promise(async (resolve, reject) => {
-    let install = await AddonManager.getInstallForURL(pathPrefix + path, "application/x-xpinstall");
+    let install = await AddonManager.getInstallForURL(pathPrefix + path);
     install.addListener({
       onInstallEnded: () => resolve(install.addon),
     });
 
     install.install();
   });
 
   return log_callback(p, cb);
@@ -937,31 +937,22 @@ MockProvider.prototype = {
    */
   updateAddonAppDisabledStates: function MP_updateAddonAppDisabledStates() {
     // Not needed
   },
 
   /**
    * Called to get an AddonInstall to download and install an add-on from a URL.
    *
-   * @param  aUrl
+   * @param  {string} aUrl
    *         The URL to be installed
-   * @param  aHash
-   *         A hash for the install
-   * @param  aName
-   *         A name for the install
-   * @param  aIconURL
-   *         An icon URL for the install
-   * @param  aVersion
-   *         A version for the install
-   * @param  aLoadGroup
-   *         An nsILoadGroup to associate requests with
+   * @param  {object} aOptions
+   *         Options for the install
    */
-  getInstallForURL: function MP_getInstallForURL(aUrl, aHash, aName, aIconURL,
-                                                  aVersion, aLoadGroup) {
+  getInstallForURL: function MP_getInstallForURL(aUrl, aOptions) {
     // Not yet implemented
   },
 
   /**
    * Called to get an AddonInstall to install an add-on from a local file.
    *
    * @param  aFile
    *         The file to be installed
--- a/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository.js
@@ -154,22 +154,22 @@ add_task(async function setup() {
 
   await promiseStartupManager();
 
   // Install an add-on so can check that it isn't returned in the results
   await promiseInstallFile(xpis[0]);
   await promiseRestartManager();
 
   // Create an active AddonInstall so can check that it isn't returned in the results
-  let install = await AddonManager.getInstallForURL(BASE_URL + INSTALL_URL2, "application/x-xpinstall");
+  let install = await AddonManager.getInstallForURL(BASE_URL + INSTALL_URL2);
   let promise = promiseCompleteInstall(install);
   registerCleanupFunction(() => promise);
 
   // Create a non-active AddonInstall so can check that it is returned in the results
-  await AddonManager.getInstallForURL(BASE_URL + INSTALL_URL3, "application/x-xpinstall");
+  await AddonManager.getInstallForURL(BASE_URL + INSTALL_URL3);
 });
 
 // Tests homepageURL and getSearchURL()
 add_task(async function test_1() {
   function check_urls(aPreference, aGetURL, aTests) {
     aTests.forEach(function(aTest) {
       Services.prefs.setCharPref(aPreference, aTest.preferenceValue);
       Assert.equal(aGetURL(aTest), aTest.expectedURL);
--- a/toolkit/mozapps/extensions/test/xpcshell/test_blocklistchange.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_blocklistchange.js
@@ -153,17 +153,17 @@ function Pbackground_update() {
   });
 }
 
 // Manually updates the test add-ons to the given version
 function Pmanual_update(aVersion) {
   const names = ["soft1", "soft2", "soft3", "soft4", "hard", "regexp"];
   return Promise.all(names.map(async name => {
     let url = `http://example.com/addons/blocklist_${name}_${aVersion}.xpi`;
-    let install = await AddonManager.getInstallForURL(url, "application/x-xpinstall");
+    let install = await AddonManager.getInstallForURL(url);
 
     // installAddonFromAOM() does more checking than install.install().
     // In particular, it will refuse to install an incompatible addon.
 
     return new Promise(resolve => {
       install.addListener({
         onDownloadCancelled: resolve,
         onInstallEnded: resolve,
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_cookies.js
@@ -0,0 +1,93 @@
+"use strict";
+
+let server = createHttpServer({hosts: ["example.com"]});
+
+createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "45", "45");
+
+Services.prefs.setBoolPref("extensions.getAddons.cache.enabled", true);
+Services.prefs.setBoolPref(PREF_EM_CHECK_UPDATE_SECURITY, false);
+
+// Tests that cookies are not sent with background requests.
+add_task(async function test_cookies() {
+  const ID = "bg-cookies@tests.mozilla.org";
+
+  // Add a new handler to the test web server for the given file path.
+  // The handler appends the incoming requests to `results` and replies
+  // with the provided body.
+  function makeHandler(path, results, body) {
+    server.registerPathHandler(path, (request, response) => {
+      results.push(request);
+      response.write(body);
+    });
+  }
+
+  let gets = [];
+  makeHandler("/get", gets, JSON.stringify({results: []}));
+  Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, "http://example.com/get");
+
+  let overrides = [];
+  makeHandler("/overrides", overrides, JSON.stringify({results: []}));
+  Services.prefs.setCharPref(PREF_COMPAT_OVERRIDES, "http://example.com/overrides");
+
+  let updates = [];
+  makeHandler("/update", updates, JSON.stringify({
+    addons: {
+      [ID]: {
+        updates: [
+          {
+            version: "2.0",
+            update_link: "http://example.com/update.xpi",
+            applications: {
+              gecko: {},
+            },
+          },
+        ],
+      },
+    },
+  }));
+
+  let xpiFetches = [];
+  makeHandler("/update.xpi", xpiFetches, "");
+
+  const COOKIE = "test";
+  // cookies.add() takes a time in seconds
+  let expiration = Date.now() / 1000 + 60 * 60;
+  Services.cookies.add("example.com", "/", COOKIE, "testing",
+                       false, false, false, expiration, {},
+                       Ci.nsICookie2.SAMESITE_UNSET);
+
+  await promiseStartupManager();
+
+  let addon = await promiseInstallWebExtension({
+    manifest: {
+      version: "1.0",
+      applications: {
+        gecko: {
+          id: ID,
+          update_url: "http://example.com/update",
+        },
+      },
+    },
+  });
+
+  equal(gets.length, 1, "Saw one addon metadata request");
+  equal(gets[0].hasHeader("Cookie"), false, "Metadata request has no cookies");
+
+  equal(overrides.length, 1, "Saw one compat overrides request");
+  equal(overrides[0].hasHeader("Cookie"), false,
+        "Compat overrides request has no cookies");
+
+  await Promise.all([
+    AddonTestUtils.promiseInstallEvent("onDownloadFailed"),
+    AddonManagerPrivate.backgroundUpdateCheck(),
+  ]);
+
+  equal(updates.length, 1, "Saw one update check request");
+  equal(updates[0].hasHeader("Cookie"), false, "Update request has no cookies");
+
+  equal(xpiFetches.length, 1, "Saw one request for updated xpi");
+  equal(xpiFetches[0].hasHeader("Cookie"), false,
+        "Request for updated XPI has no cookies");
+
+  await addon.uninstall();
+});
--- a/toolkit/mozapps/extensions/test/xpcshell/test_error.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_error.js
@@ -41,17 +41,17 @@ add_task(async function run_test_3() {
   Assert.equal(install.state, AddonManager.STATE_DOWNLOAD_FAILED);
   Assert.equal(install.error, AddonManager.ERROR_CORRUPT_FILE);
 });
 
 // Checks that a file that doesn't match its hash shows an error
 add_task(async function run_test_4() {
   let xpi = await createTempWebExtensionFile({});
   let url = Services.io.newFileURI(xpi).spec;
-  let install = await AddonManager.getInstallForURL(url, "application/x-xpinstall", "sha1:foo");
+  let install = await AddonManager.getInstallForURL(url, {hash: "sha1:foo"});
   Assert.notEqual(install, null);
   Assert.equal(install.state, AddonManager.STATE_DOWNLOAD_FAILED);
   Assert.equal(install.error, AddonManager.ERROR_INCORRECT_HASH);
 });
 
 // Checks that a file that doesn't exist shows an error
 add_task(async function run_test_5() {
   let file = do_get_file("data");
--- a/toolkit/mozapps/extensions/test/xpcshell/test_install.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_install.js
@@ -244,17 +244,20 @@ add_task(async function test_install_fil
   let { id, version } = a1;
   await promiseRestartManager();
   do_check_not_in_crash_annotation(id, version);
 });
 
 // Tests that an install from a url downloads.
 add_task(async function test_install_url() {
   let url = "http://example.com/addons/test_install2_1.xpi";
-  let install = await AddonManager.getInstallForURL(url, "application/x-xpinstall", null, "Test 2", null, "1.0");
+  let install = await AddonManager.getInstallForURL(url, {
+    name: "Test 2",
+    version: "1.0",
+  });
   checkInstall(install, {
     version: "1.0",
     name: "Test 2",
     state: AddonManager.STATE_AVAILABLE,
     sourceURI: Services.io.newURI(url),
   });
 
   let activeInstalls = await AddonManager.getAllInstalls();
@@ -325,17 +328,20 @@ add_task(async function test_install_url
   gInstallDate = a2.installDate;
 });
 
 // Tests that installing a new version of an existing add-on works
 add_task(async function test_install_new_version() {
   let url = "http://example.com/addons/test_install2_2.xpi";
   let [, install] = await Promise.all([
     AddonTestUtils.promiseInstallEvent("onNewInstall"),
-    AddonManager.getInstallForURL(url, "application/x-xpinstall", null, "Test 2", null, "3.0"),
+    AddonManager.getInstallForURL(url, {
+      name: "Test 2",
+      version: "3.0",
+    }),
   ]);
 
   checkInstall(install, {
     version: "3.0",
     name: "Test 2",
     state: AddonManager.STATE_AVAILABLE,
     existingAddon: null,
   });
@@ -407,17 +413,20 @@ add_task(async function test_install_new
   await a2.uninstall();
 });
 
 // Tests that an install that requires a compatibility update works
 add_task(async function test_install_compat_update() {
   let url = "http://example.com/addons/test_install3.xpi";
   let [, install] = await Promise.all([
     AddonTestUtils.promiseInstallEvent("onNewInstall"),
-    await AddonManager.getInstallForURL(url, "application/x-xpinstall", null, "Test 3", null, "1.0"),
+    await AddonManager.getInstallForURL(url, {
+      name: "Test 3",
+      version: "1.0",
+    }),
   ]);
 
   checkInstall(install, {
     version: "1.0",
     name: "Test 3",
     state: AddonManager.STATE_AVAILABLE,
   });
 
@@ -520,17 +529,20 @@ add_task(async function test_compat_upda
   await a3.uninstall();
 });
 
 // Test that after cancelling a download it is removed from the active installs
 add_task(async function test_cancel() {
   let url = "http://example.com/addons/test_install3.xpi";
   let [, install] = await Promise.all([
     AddonTestUtils.promiseInstallEvent("onNewInstall"),
-    AddonManager.getInstallForURL(url, "application/x-xpinstall", null, "Test 3", null, "1.0"),
+    AddonManager.getInstallForURL(url, {
+      name: "Test 3",
+      version: "1.0",
+    }),
   ]);
 
   checkInstall(install, {
     version: "1.0",
     name: "Test 3",
     state: AddonManager.STATE_AVAILABLE,
   });
 
@@ -563,17 +575,17 @@ add_task(async function test_cancel() {
 });
 
 // Check that cancelling the install from onDownloadStarted actually cancels it
 add_task(async function test_cancel_onDownloadStarted() {
   clearListeners();
   let url = "http://example.com/addons/test_install2_1.xpi";
   let [, install] = await Promise.all([
     AddonTestUtils.promiseInstallEvent("onNewInstall"),
-    AddonManager.getInstallForURL(url, "application/x-xpinstall"),
+    AddonManager.getInstallForURL(url),
   ]);
 
   equal(install.file, null);
 
   install.addListener({
     onDownloadStarted() {
       install.removeListener(this);
       executeSoon(() => install.cancel());
@@ -602,17 +614,17 @@ add_task(async function test_cancel_onDo
   ok(!file.exists());
 });
 
 // Checks that cancelling the install from onDownloadEnded actually cancels it
 add_task(async function test_cancel_onDownloadEnded() {
   let url = "http://example.com/addons/test_install2_1.xpi";
   let [, install] = await Promise.all([
     AddonTestUtils.promiseInstallEvent("onNewInstall"),
-    AddonManager.getInstallForURL(url, "application/x-xpinstall"),
+    AddonManager.getInstallForURL(url),
   ]);
 
   equal(install.file, null);
 
   await new Promise(resolve => {
     prepare_test({ }, [
       "onDownloadStarted",
       "onDownloadEnded",
@@ -637,32 +649,32 @@ add_task(async function test_cancel_onDo
 });
 
 // Verify that the userDisabled value carries over to the upgrade by default
 add_task(async function test_userDisabled_update() {
   clearListeners();
   let url = "http://example.com/addons/test_install2_1.xpi";
   let [, install] = await Promise.all([
     AddonTestUtils.promiseInstallEvent("onNewInstall"),
-    AddonManager.getInstallForURL(url, "application/x-xpinstall"),
+    AddonManager.getInstallForURL(url),
   ]);
 
   await install.install();
 
   ok(!install.addon.userDisabled);
   await install.addon.disable();
 
   let addon = await AddonManager.getAddonByID("addon2@tests.mozilla.org");
   checkAddon("addon2@tests.mozilla.org", addon, {
     userDisabled: true,
     isActive: false,
   });
 
   url = "http://example.com/addons/test_install2_2.xpi";
-  install = await AddonManager.getInstallForURL(url, "application/x-xpinstall");
+  install = await AddonManager.getInstallForURL(url);
   await install.install();
 
   checkAddon("addon2@tests.mozilla.org", install.addon, {
     userDisabled: true,
     isActive: false,
   });
 
   await promiseRestartManager();
@@ -674,29 +686,29 @@ add_task(async function test_userDisable
   });
 
   await addon.uninstall();
 });
 
 // Verify that changing the userDisabled value before onInstallEnded works
 add_task(async function test_userDisabled() {
   let url = "http://example.com/addons/test_install2_1.xpi";
-  let install = await AddonManager.getInstallForURL(url, "application/x-xpinstall");
+  let install = await AddonManager.getInstallForURL(url);
   await install.install();
 
   ok(!install.addon.userDisabled);
 
   let addon = await AddonManager.getAddonByID("addon2@tests.mozilla.org");
   checkAddon("addon2@tests.mozilla.org", addon, {
     userDisabled: false,
     isActive: true,
   });
 
   url = "http://example.com/addons/test_install2_2.xpi";
-  install = await AddonManager.getInstallForURL(url, "application/x-xpinstall");
+  install = await AddonManager.getInstallForURL(url);
 
   install.addListener({
     onInstallStarted() {
       ok(!install.addon.userDisabled);
       install.addon.disable();
     },
   });
 
@@ -720,17 +732,17 @@ add_task(async function test_18_1() {
   AddonTestUtils.registerJSON(testserver, "/compat.json", COMPAT_JSON);
   Services.prefs.setCharPref(PREF_COMPAT_OVERRIDES,
                              "http://example.com/compat.json");
 
   Services.prefs.setBoolPref("extensions.getAddons.cache.enabled", true);
   Services.prefs.setBoolPref("extensions.addon2@tests.mozilla.org.getAddons.cache.enabled", false);
 
   let url = "http://example.com/addons/test_install2_1.xpi";
-  let install = await AddonManager.getInstallForURL(url, "application/x-xpinstall");
+  let install = await AddonManager.getInstallForURL(url);
   await install.install();
 
   notEqual(install.addon.fullDescription, "Repository description");
 
   await promiseRestartManager();
 
   let addon = await AddonManager.getAddonByID("addon2@tests.mozilla.org");
   notEqual(addon.fullDescription, "Repository description");
@@ -739,49 +751,49 @@ add_task(async function test_18_1() {
 });
 
 // Checks that metadata is downloaded for new installs and is visible before and
 // after restart
 add_task(async function test_metadata() {
   Services.prefs.setBoolPref("extensions.addon2@tests.mozilla.org.getAddons.cache.enabled", true);
 
   let url = "http://example.com/addons/test_install2_1.xpi";
-  let install = await AddonManager.getInstallForURL(url, "application/x-xpinstall");
+  let install = await AddonManager.getInstallForURL(url);
   await install.install();
 
   equal(install.addon.fullDescription, "Repository description");
 
   await promiseRestartManager();
 
   let addon = await AddonManager.getAddonByID("addon2@tests.mozilla.org");
   equal(addon.fullDescription, "Repository description");
 
   await addon.uninstall();
 });
 
 // Do the same again to make sure it works when the data is already in the cache
 add_task(async function test_metadata_again() {
   let url = "http://example.com/addons/test_install2_1.xpi";
-  let install = await AddonManager.getInstallForURL(url, "application/x-xpinstall");
+  let install = await AddonManager.getInstallForURL(url);
   await install.install();
 
   equal(install.addon.fullDescription, "Repository description");
 
   await promiseRestartManager();
 
   let addon = await AddonManager.getAddonByID("addon2@tests.mozilla.org");
   equal(addon.fullDescription, "Repository description");
 
   await addon.uninstall();
 });
 
 // Tests that an install can be restarted after being cancelled
 add_task(async function test_restart() {
   let url = "http://example.com/addons/test_install1.xpi";
-  let install = await AddonManager.getInstallForURL(url, "application/x-xpinstall");
+  let install = await AddonManager.getInstallForURL(url);
   equal(install.state, AddonManager.STATE_AVAILABLE);
 
   install.addListener({
     onDownloadEnded() {
       install.removeListener(this);
       install.cancel();
     },
   });
@@ -816,17 +828,19 @@ add_task(async function test_restart() {
 
   await install.addon.uninstall();
 });
 
 // Tests that an install can be restarted after being cancelled when a hash
 // was provided
 add_task(async function test_restart_hash() {
   let url = "http://example.com/addons/test_install1.xpi";
-  let install = await AddonManager.getInstallForURL(url, "application/x-xpinstall", do_get_file_hash(XPIS.test_install1));
+  let install = await AddonManager.getInstallForURL(url, {
+    hash: do_get_file_hash(XPIS.test_install1),
+  });
   equal(install.state, AddonManager.STATE_AVAILABLE);
 
   install.addListener({
     onDownloadEnded() {
       install.removeListener(this);
       install.cancel();
     },
   });
@@ -861,17 +875,17 @@ add_task(async function test_restart_has
 
   await install.addon.uninstall();
 });
 
 // Tests that an install with a bad hash can be restarted after it fails, though
 // it will only fail again
 add_task(async function test_restart_badhash() {
   let url = "http://example.com/addons/test_install1.xpi";
-  let install = await AddonManager.getInstallForURL(url, "application/x-xpinstall", "sha1:foo");
+  let install = await AddonManager.getInstallForURL(url, {hash: "sha1:foo"});
   equal(install.state, AddonManager.STATE_AVAILABLE);
 
   install.addListener({
     onDownloadEnded() {
       install.removeListener(this);
       install.cancel();
     },
   });
@@ -887,30 +901,32 @@ add_task(async function test_restart_bad
   } catch (err) {
     ok(true, "Resumed install should have failed");
   }
 });
 
 // Tests that installs with a hash for a local file work
 add_task(async function test_local_hash() {
   let url = Services.io.newFileURI(XPIS.test_install1).spec;
-  let install = await AddonManager.getInstallForURL(url, "application/x-xpinstall", do_get_file_hash(XPIS.test_install1));
+  let install = await AddonManager.getInstallForURL(url, {
+    hash: do_get_file_hash(XPIS.test_install1),
+  });
 
   checkInstall(install, {
     state: AddonManager.STATE_DOWNLOADED,
     error: 0,
   });
 
   install.cancel();
 });
 
 // Test that an install may be canceled after a redirect.
 add_task(async function test_cancel_redirect() {
   let url = "http://example.com/redirect?/addons/test_install1.xpi";
-  let install = await AddonManager.getInstallForURL(url, "application/x-xpinstall");
+  let install = await AddonManager.getInstallForURL(url);
 
   install.addListener({
     onDownloadProgress() {
       install.cancel();
     },
   });
 
   let promise = AddonTestUtils.promiseInstallEvent("onDownloadCancelled");
@@ -920,17 +936,17 @@ add_task(async function test_cancel_redi
 
   equal(install.state, AddonManager.STATE_CANCELLED);
 });
 
 // Tests that an install can be restarted during onDownloadCancelled after being
 // cancelled in mid-download
 add_task(async function test_restart2() {
   let url = "http://example.com/addons/test_install1.xpi";
-  let install = await AddonManager.getInstallForURL(url, "application/x-xpinstall");
+  let install = await AddonManager.getInstallForURL(url);
 
   equal(install.state, AddonManager.STATE_AVAILABLE);
 
   install.addListener({
     onDownloadProgress() {
       install.removeListener(this);
       install.cancel();
     },
--- a/toolkit/mozapps/extensions/test/xpcshell/test_install_icons.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_install_icons.js
@@ -15,42 +15,46 @@ async function run_test() {
   do_test_pending();
   createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
   await promiseStartupManager();
 
   test_1();
 }
 
 async function test_1() {
-  let aInstall = await AddonManager.getInstallForURL(addon_url, "application/x-xpinstall", null, null, null, null, null);
+  let aInstall = await AddonManager.getInstallForURL(addon_url);
   Assert.equal(aInstall.iconURL, null);
   Assert.notEqual(aInstall.icons, null);
   Assert.equal(aInstall.icons[32], undefined);
   Assert.equal(aInstall.icons[64], undefined);
   test_2();
 }
 
 async function test_2() {
-  let aInstall = await AddonManager.getInstallForURL(addon_url, "application/x-xpinstall", null, null, icon32_url, null, null);
+  let aInstall = await AddonManager.getInstallForURL(addon_url, {icons: icon32_url});
   Assert.equal(aInstall.iconURL, icon32_url);
   Assert.notEqual(aInstall.icons, null);
   Assert.equal(aInstall.icons[32], icon32_url);
   Assert.equal(aInstall.icons[64], undefined);
   test_3();
 }
 
 async function test_3() {
-  let aInstall = await AddonManager.getInstallForURL(addon_url, "application/x-xpinstall", null, null, { "32": icon32_url }, null, null);
+  let aInstall = await AddonManager.getInstallForURL(addon_url, {
+    icons: { "32": icon32_url },
+  });
   Assert.equal(aInstall.iconURL, icon32_url);
   Assert.notEqual(aInstall.icons, null);
   Assert.equal(aInstall.icons[32], icon32_url);
   Assert.equal(aInstall.icons[64], undefined);
   test_4();
 }
 
 async function test_4() {
-  let aInstall = await AddonManager.getInstallForURL(addon_url, "application/x-xpinstall", null, null, { "32": icon32_url, "64": icon64_url }, null, null);
+  let aInstall = await AddonManager.getInstallForURL(addon_url, {
+    icons: { "32": icon32_url, "64": icon64_url },
+  });
   Assert.equal(aInstall.iconURL, icon32_url);
   Assert.notEqual(aInstall.icons, null);
   Assert.equal(aInstall.icons[32], icon32_url);
   Assert.equal(aInstall.icons[64], icon64_url);
   executeSoon(do_test_finished);
 }
--- a/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
+++ b/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
@@ -64,16 +64,17 @@ tags = blocklist
 requesttimeoutfactor = 2
 tags = blocklist
 [test_builtin_location.js]
 [test_cache_certdb.js]
 [test_cacheflush.js]
 [test_childprocess.js]
 [test_compatoverrides.js]
 head = head_addons.js head_compat.js
+[test_cookies.js]
 [test_corrupt.js]
 [test_crash_annotation_quoting.js]
 [test_db_path.js]
 head =
 [test_delay_update_webextension.js]
 tags = webextensions
 [test_dependencies.js]
 [test_dictionary_webextension.js]