author | Wes Kocher <wkocher@mozilla.com> |
Wed, 02 Nov 2016 17:31:08 -0700 | |
changeset 363664 | 227bccbfea15ddf0b0105cdecf54c77fbeb87ad3 |
parent 363663 | c3c0827d6c66d6cfdacaa6ae29b24f5b924ab851 (current diff) |
parent 363386 | ac55a6776435142feebf3c20bbabfee100686416 (diff) |
child 363665 | 5fd7c7cad7599f10bd1cc6d4b0d2db984eb45437 |
push id | 6795 |
push user | jlund@mozilla.com |
push date | Mon, 23 Jan 2017 14:19:46 +0000 |
treeherder | mozilla-beta@76101b503191 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | merge |
milestone | 52.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/Makefile.in +++ b/Makefile.in @@ -277,18 +277,18 @@ else DUMP_SYMS_BIN ?= $(topsrcdir)/toolkit/crashreporter/tools/win32/dump_syms_vc$(_MSC_VER).exe endif # PDB files don't get moved to dist, so we need to scan the whole objdir MAKE_SYM_STORE_PATH := . endif ifeq ($(OS_ARCH),Darwin) # need to pass arch flags for universal builds ifdef UNIVERSAL_BINARY -MAKE_SYM_STORE_ARGS := -c -a 'i386 x86_64' --vcs-info -MAKE_SYM_STORE_PATH := $(DIST)/universal +MAKE_SYM_STORE_ARGS := -c --vcs-info +MAKE_SYM_STORE_PATH := $(DIST)/bin $(UNIFY_DIST)/bin else MAKE_SYM_STORE_ARGS := -c -a $(OS_TEST) --vcs-info MAKE_SYM_STORE_PATH := $(DIST)/bin endif DUMP_SYMS_BIN ?= $(DIST)/host/bin/dump_syms endif ifeq (,$(filter-out Linux SunOS,$(OS_ARCH))) MAKE_SYM_STORE_ARGS := -c --vcs-info
--- a/accessible/ipc/win/moz.build +++ b/accessible/ipc/win/moz.build @@ -1,15 +1,16 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -DIRS += ['typelib'] +if CONFIG['COMPILE_ENVIRONMENT']: + DIRS += ['typelib'] # With --disable-accessibility, we need to compile PDocAccessible.ipdl (which # also depends on COMPtrTypes.h), but not the C++. IPDL_SOURCES += ['PDocAccessible.ipdl'] EXPORTS.mozilla.a11y += ['COMPtrTypes.h'] if CONFIG['ACCESSIBILITY']: EXPORTS.mozilla.a11y += [
--- a/b2g/app/b2g.js +++ b/b2g/app/b2g.js @@ -995,23 +995,16 @@ pref("dom.webnotifications.serviceworker #endif // Retain at most 10 processes' layers buffers pref("layers.compositor-lru-size", 10); // In B2G by deafult any AudioChannelAgent is muted when created. pref("dom.audiochannel.mutedByDefault", true); -// The app origin of bluetooth app, which is responsible for listening pairing -// requests. -pref("dom.bluetooth.app-origin", "app://bluetooth.gaiamobile.org"); - -// Enable W3C WebBluetooth API and disable B2G only GATT client API. -pref("dom.bluetooth.webbluetooth.enabled", false); - // Default device name for Presentation API pref("dom.presentation.device.name", "Firefox OS"); // Enable notification of performance timing pref("dom.performance.enable_notify_performance_timing", true); // Multi-screen pref("b2g.multiscreen.chrome_remote_url", "chrome://b2g/content/shell_remote.html");
--- a/b2g/common.configure +++ b/b2g/common.configure @@ -4,16 +4,17 @@ # 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/. # Truetype fonts for B2G # ============================================================== option(env='MOZTTDIR', nargs=1, help='Path to truetype fonts for B2G') @depends('MOZTTDIR') +@imports('os') def mozttdir(value): if value: path = value[0] if not os.path.isdir(path): die('MOZTTDIR "%s" is not a valid directory', path) return path set_config('MOZTTDIR', mozttdir)
--- a/b2g/installer/package-manifest.in +++ b/b2g/installer/package-manifest.in @@ -155,19 +155,16 @@ @RESPATH@/components/dom_workers.xpt #ifdef MOZ_WIDGET_GONK @RESPATH@/components/dom_wifi.xpt @RESPATH@/components/dom_system_gonk.xpt #endif #ifdef MOZ_B2G_RIL @RESPATH@/components/dom_mobileconnection.xpt #endif -#ifdef MOZ_B2G_BT -@RESPATH@/components/dom_bluetooth.xpt -#endif @RESPATH@/components/dom_canvas.xpt @RESPATH@/components/dom_contacts.xpt @RESPATH@/components/dom_core.xpt @RESPATH@/components/dom_css.xpt @RESPATH@/components/dom_events.xpt @RESPATH@/components/dom_geolocation.xpt @RESPATH@/components/dom_media.xpt @RESPATH@/components/dom_network.xpt
--- a/browser/app/blocklist.xml +++ b/browser/app/blocklist.xml @@ -1,10 +1,10 @@ <?xml version='1.0' encoding='UTF-8'?> -<blocklist lastupdate="1477919228776" xmlns="http://www.mozilla.org/2006/addons-blocklist"> +<blocklist lastupdate="1478088426949" xmlns="http://www.mozilla.org/2006/addons-blocklist"> <emItems> <emItem blockID="i988" id="{b12785f5-d8d0-4530-a3ea-5c4263b85bef}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> <emItem blockID="i398" id="{377e5d4d-77e5-476a-8716-7e70a9272da0}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> @@ -140,28 +140,28 @@ <emItem blockID="i537" id="rally_toolbar_ff@bulletmedia.com"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> <emItem blockID="i1266" id="@stopad"> <prefs/> <versionRange minVersion="0" maxVersion="0.0.4" severity="1"/> </emItem> + <emItem blockID="i473" id="{81b13b5d-fba1-49fd-9a6b-189483ac548a}"> + <prefs/> + <versionRange minVersion="0" maxVersion="*" severity="3"/> + </emItem> <emItem blockID="i914" id="{0153E448-190B-4987-BDE1-F256CADA672F}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"> <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"> <versionRange maxVersion="*" minVersion="39.0a1"/> </targetApplication> </versionRange> </emItem> - <emItem blockID="i473" id="{81b13b5d-fba1-49fd-9a6b-189483ac548a}"> - <prefs/> - <versionRange minVersion="0" maxVersion="*" severity="3"/> - </emItem> <emItem blockID="i496" id="{ACAA314B-EEBA-48e4-AD47-84E31C44796C}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> <emItem blockID="i690" id="{55dce8ba-9dec-4013-937e-adbf9317d990"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> @@ -326,38 +326,38 @@ <emItem blockID="i1261" id="support@lastpass.com"> <prefs/> <versionRange minVersion="4.0.0a" maxVersion="4.1.20a" severity="1"/> </emItem> <emItem blockID="i447" id="{B18B1E5C-4D81-11E1-9C00-AFEB4824019B}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> - <emItem blockID="i509" id="contato@facefollow.net"> + <emItem blockID="i394" id="{7D4F1959-3F72-49d5-8E59-F02F8AA6815D}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> - <emItem blockID="i394" id="{7D4F1959-3F72-49d5-8E59-F02F8AA6815D}"> + <emItem blockID="i509" id="contato@facefollow.net"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> <emItem blockID="i810" id="{41339ee8-61ed-489d-b049-01e41fd5d7e0}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> <emItem blockID="i618" id="toolbar@ask.com"> <prefs/> <versionRange minVersion="3.15.24" maxVersion="3.15.24.*" severity="1"/> <versionRange minVersion="3.15.13" maxVersion="3.15.13.*" severity="1"/> <versionRange minVersion="3.15.28" maxVersion="3.15.28.*" severity="1"/> <versionRange minVersion="3.15.22" maxVersion="3.15.22.*" severity="1"/> <versionRange minVersion="3.15.8" maxVersion="3.15.8.*" severity="1"/> <versionRange minVersion="3.15.10" maxVersion="3.15.11.*" severity="1"/> + <versionRange minVersion="3.15.18" maxVersion="3.15.20.*" severity="1"/> <versionRange minVersion="3.15.5" maxVersion="3.15.5.*" severity="1"/> - <versionRange minVersion="3.15.18" maxVersion="3.15.20.*" severity="1"/> <versionRange minVersion="3.15.31" maxVersion="3.15.31.*" severity="1"/> <versionRange minVersion="3.15.26" maxVersion="3.15.26.*" severity="1"/> </emItem> <emItem blockID="i15" id="personas@christopher.beard"> <prefs/> <versionRange minVersion="1.6" maxVersion="1.6"> <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"> <versionRange maxVersion="3.6.*" minVersion="3.6"/> @@ -451,39 +451,39 @@ <emItem blockID="i1232" id="nosquint@urandom.ca"> <prefs/> <versionRange minVersion="0" maxVersion="2.1.9.1-signed.1-signed" severity="1"> <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"> <versionRange maxVersion="*" minVersion="47"/> </targetApplication> </versionRange> </emItem> - <emItem blockID="i650" id="jid1-qj0w91o64N7Eeg@jetpack"> - <prefs/> - <versionRange minVersion="39.5.1" maxVersion="47.0.4" severity="3"/> + <emItem blockID="i748" id="{32da2f20-827d-40aa-a3b4-2fc4a294352e}"> + <prefs/> + <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> <emItem blockID="i544" id="/^(93abedcf-8e3a-4d02-b761-d1441e437c09@243f129d-aee2-42c2-bcd1-48858e1c22fd\.com|9acfc440-ac2d-417a-a64c-f6f14653b712@09f9a966-9258-4b12-af32-da29bdcc28c5\.com|58ad0086-1cfb-48bb-8ad2-33a8905572bc@5715d2be-69b9-4930-8f7e-64bdeb961cfd\.com)$/"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> - <emItem blockID="i748" id="{32da2f20-827d-40aa-a3b4-2fc4a294352e}"> - <prefs/> - <versionRange minVersion="0" maxVersion="*" severity="1"/> + <emItem blockID="i650" id="jid1-qj0w91o64N7Eeg@jetpack"> + <prefs/> + <versionRange minVersion="39.5.1" maxVersion="47.0.4" severity="3"/> + </emItem> + <emItem blockID="i640" id="jid0-l9BxpNUhx1UUgRfKigWzSfrZqAc@jetpack"> + <prefs/> + <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> <emItem blockID="i628" id="ffxtlbr@iminent.com"> <prefs> <pref>browser.startup.homepage</pref> <pref>browser.search.defaultenginename</pref> </prefs> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> - <emItem blockID="i640" id="jid0-l9BxpNUhx1UUgRfKigWzSfrZqAc@jetpack"> - <prefs/> - <versionRange minVersion="0" maxVersion="*" severity="3"/> - </emItem> <emItem blockID="i1228" id="unblocker30__web@unblocker.yt"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> <emItem blockID="i1042" id="gjhrjenrengoe@jfdnkwelfwkm.com"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> @@ -520,24 +520,24 @@ <emItem blockID="i772" id="{72b98dbc-939a-4e0e-b5a9-9fdbf75963ef}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> <emItem blockID="i996" id="9598582LLKmjasieijkaslesae@jetpack"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> + <emItem blockID="i586" id="jid1-0xtMKhXFEs4jIg@jetpack"> + <prefs/> + <versionRange minVersion="0" maxVersion="*" severity="3"/> + </emItem> <emItem blockID="i88" id="anttoolbar@ant.com"> <prefs/> <versionRange minVersion="2.4.6.4" maxVersion="2.4.6.4" severity="1"/> </emItem> - <emItem blockID="i586" id="jid1-0xtMKhXFEs4jIg@jetpack"> - <prefs/> - <versionRange minVersion="0" maxVersion="*" severity="3"/> - </emItem> <emItem blockID="i358" id="lfind@nijadsoft.net"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> <emItem blockID="i438" id="{02edb56b-9b33-435b-b7df-b2843273a694}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> @@ -657,43 +657,43 @@ <emItem blockID="i1038" id="344141-fasf9jas08hasoiesj9ia8ws@jetpack"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> <emItem blockID="i471" id="firefox@luckyleap.net"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> - <emItem blockID="i560" id="adsremoval@adsremoval.net"> + <emItem blockID="i396" id="/@(ft|putlocker|clickmovie|m2k|sharerepo|smarter-?)downloader\.com$/"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> - <emItem blockID="i396" id="/@(ft|putlocker|clickmovie|m2k|sharerepo|smarter-?)downloader\.com$/"> + <emItem blockID="i560" id="adsremoval@adsremoval.net"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> <emItem blockID="i538" id="{354dbb0a-71d5-4e9f-9c02-6c88b9d387ba}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> <emItem blockID="i968" id="{184AA5E6-741D-464a-820E-94B3ABC2F3B4}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> - <emItem blockID="i742" id="{f894a29a-f065-40c3-bb19-da6057778493}"> - <prefs/> - <versionRange minVersion="0" maxVersion="*" severity="1"/> + <emItem blockID="i658" id="low_quality_flash@pie2k.com"> + <prefs/> + <versionRange minVersion="46.2" maxVersion="47.1" severity="3"/> </emItem> <emItem blockID="i792" id="{8f894ed3-0bf2-498e-a103-27ef6e88899f}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> - <emItem blockID="i658" id="low_quality_flash@pie2k.com"> - <prefs/> - <versionRange minVersion="46.2" maxVersion="47.1" severity="3"/> + <emItem blockID="i742" id="{f894a29a-f065-40c3-bb19-da6057778493}"> + <prefs/> + <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> <emItem blockID="i17" id="{3252b9ae-c69a-4eaf-9502-dc9c1f6c009e}"> <prefs/> <versionRange minVersion="2.2" maxVersion="2.2"/> </emItem> <emItem blockID="i109" id="{392e123b-b691-4a5e-b52f-c4c1027e749c}"> <prefs/> <versionRange minVersion="0" maxVersion="*"/> @@ -713,17 +713,17 @@ <emItem blockID="i352" id="vpyekkifgv@vpyekkifgv.org"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> <emItem blockID="i256" id="/^[0-9a-f]+@[0-9a-f]+\.info/"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> - <emItem blockID="i1278" id="dodatek@firefox.pl"> + <emItem blockID="i1278" id="/^(ff\-)?dodate(kKKK|XkKKK|k|kk|kkx|kR)@(firefox|flash(1)?)\.pl|dode(ee)?k@firefoxnet\.pl$/"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> <emItem blockID="i980" id="wHO@W9.net"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> <emItem blockID="i127" id="plugin@youtubeplayer.com"> @@ -745,24 +745,24 @@ <emItem blockID="i380" id="{cc8f597b-0765-404e-a575-82aefbd81daf}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> <emItem blockID="i432" id="lugcla21@gmail.com"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> + <emItem blockID="i392" id="{EEE6C361-6118-11DC-9C72-001320C79847}"> + <prefs/> + <versionRange minVersion="0" maxVersion="*" severity="1"/> + </emItem> <emItem blockID="i724" id="{1cdbda58-45f8-4d91-b566-8edce18f8d0a}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> - <emItem blockID="i392" id="{EEE6C361-6118-11DC-9C72-001320C79847}"> - <prefs/> - <versionRange minVersion="0" maxVersion="*" severity="1"/> - </emItem> <emItem blockID="i429" id="{B40794A0-7477-4335-95C5-8CB9BBC5C4A5}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> <emItem blockID="i638" id="{7b1bf0b6-a1b9-42b0-b75d-252036438bdc}"> <prefs/> <versionRange minVersion="27.8" maxVersion="27.9" severity="3"/> </emItem> @@ -809,24 +809,24 @@ <emItem blockID="i434" id="afurladvisor@anchorfree.com"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> <emItem blockID="i872" id="search-snacks@search-snacks.com"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> + <emItem blockID="i90" id="videoplugin@player.com"> + <prefs/> + <versionRange minVersion="0" maxVersion="*"/> + </emItem> <emItem blockID="i306" id="{ADFA33FD-16F5-4355-8504-DF4D664CFE10}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> - <emItem blockID="i90" id="videoplugin@player.com"> - <prefs/> - <versionRange minVersion="0" maxVersion="*"/> - </emItem> <emItem blockID="i966" id="{5C655500-E712-41e7-9349-CE462F844B19}"> <prefs/> <versionRange minVersion="0" maxVersion="1.0.1-signed" severity="1"/> </emItem> <emItem blockID="i1012" id="wxtui502n2xce9j@no14"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> @@ -895,41 +895,41 @@ <emItem blockID="i1264" id="suchpony@suchpony.de"> <prefs/> <versionRange minVersion="0" maxVersion="1.6.7" severity="3"/> </emItem> <emItem blockID="i476" id="mbroctone@facebook.com"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> + <emItem blockID="i722" id="{9802047e-5a84-4da3-b103-c55995d147d1}"> + <prefs/> + <versionRange minVersion="0" maxVersion="*" severity="3"/> + </emItem> <emItem blockID="i656" id="hdv@vovcacik.addons.mozilla.org"> <prefs/> <versionRange minVersion="102.0" maxVersion="102.0" severity="3"/> </emItem> - <emItem blockID="i722" id="{9802047e-5a84-4da3-b103-c55995d147d1}"> - <prefs/> - <versionRange minVersion="0" maxVersion="*" severity="3"/> - </emItem> <emItem blockID="i228" id="crossriderapp5060@crossrider.com"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> <emItem blockID="i470" id="extension@FastFreeConverter.com"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> + <emItem blockID="i478" id="{7e8a1050-cf67-4575-92df-dcc60e7d952d}"> + <prefs/> + <versionRange minVersion="0" maxVersion="*" severity="1"/> + </emItem> <emItem blockID="i1223" id="tmbepff@trendmicro.com"> <prefs/> <versionRange minVersion="9.2" maxVersion="9.2.0.1023" severity="1"/> <versionRange minVersion="0" maxVersion="9.1.0.1035" severity="1"/> </emItem> - <emItem blockID="i478" id="{7e8a1050-cf67-4575-92df-dcc60e7d952d}"> - <prefs/> - <versionRange minVersion="0" maxVersion="*" severity="1"/> - </emItem> <emItem blockID="i370" id="happylyrics@hpyproductions.net"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> <emItem blockID="i440" id="{2d069a16-fca1-4e81-81ea-5d5086dcbd0c}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> @@ -993,24 +993,24 @@ <pref>browser.search.defaultenginename</pref> </prefs> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> <emItem blockID="i505" id="extacylife@a.com"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> - <emItem blockID="i1414" id="new@kuot.pro"> - <prefs/> - <versionRange minVersion="0" maxVersion="*" severity="3"/> - </emItem> <emItem blockID="i528" id="008abed2-b43a-46c9-9a5b-a771c87b82da@1ad61d53-2bdc-4484-a26b-b888ecae1906.com"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> + <emItem blockID="i1414" id="/^new@kuot\.pro|{13ec6687-0b15-4f01-a5a0-7a891c18e4ee}|rebeccahoppkins(ty(tr)?)?@gmail\.com|{501815af-725e-45be-b0f2-8f36f5617afc}|{9bdb5f1f-b1e1-4a75-be31-bdcaace20a99}|{e9d93e1d-792f-4f95-b738-7adb0e853b7b}|dojadewaskurwa@gmail\.com$/"> + <prefs/> + <versionRange minVersion="0" maxVersion="*" severity="3"/> + </emItem> <emItem blockID="i712" id="{a2bfe612-4cf5-48ea-907c-f3fb25bc9d6b}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> <emItem blockID="i652" id="garg_sms@yahoo.in"> <prefs/> <versionRange minVersion="67.9" maxVersion="67.9" severity="3"/> </emItem> @@ -1064,66 +1064,66 @@ <emItem blockID="i350" id="sqlmoz@facebook.com"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> <emItem blockID="i446" id="{E90FA778-C2B7-41D0-9FA9-3FEC1CA54D66}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> + <emItem blockID="i117" id="{ce7e73df-6a44-4028-8079-5927a588c948}"> + <prefs/> + <versionRange minVersion="0" maxVersion="1.0.8" severity="1"/> + </emItem> + <emItem blockID="i13" id="{E8E88AB0-7182-11DF-904E-6045E0D72085}"> + <prefs/> + </emItem> <emItem blockID="i226" id="{462be121-2b54-4218-bf00-b9bf8135b23f}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> - <emItem blockID="i13" id="{E8E88AB0-7182-11DF-904E-6045E0D72085}"> - <prefs/> - </emItem> - <emItem blockID="i117" id="{ce7e73df-6a44-4028-8079-5927a588c948}"> - <prefs/> - <versionRange minVersion="0" maxVersion="1.0.8" severity="1"/> - </emItem> <emItem blockID="i258" id="helperbar@helperbar.com"> <prefs/> <versionRange minVersion="0" maxVersion="1.0" severity="1"/> </emItem> <emItem blockID="i96" id="youtubeee@youtuber3.com"> <prefs/> <versionRange minVersion="0" maxVersion="*"/> </emItem> <emItem blockID="i44" id="sigma@labs.mozilla"> <prefs/> </emItem> <emItem blockID="i564" id="/^(firefox@vebergreat\.net|EFGLQA@78ETGYN-0W7FN789T87\.COM)$/"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> + <emItem blockID="i500" id="{2aab351c-ad56-444c-b935-38bffe18ad26}"> + <prefs/> + <versionRange minVersion="0" maxVersion="*" severity="3"/> + </emItem> <emItem blockID="i97" id="support3_en@adobe122.com"> <prefs/> <versionRange minVersion="0" maxVersion="*"/> </emItem> - <emItem blockID="i500" id="{2aab351c-ad56-444c-b935-38bffe18ad26}"> - <prefs/> - <versionRange minVersion="0" maxVersion="*" severity="3"/> - </emItem> <emItem blockID="i439" id="{d2cf9842-af95-48cd-b873-bfbb48cd7f5e}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> - <emItem blockID="i576" id="newmoz@facebook.com"> - <prefs/> - <versionRange minVersion="0" maxVersion="*" severity="3"/> - </emItem> <emItem blockID="i46" id="{841468a1-d7f4-4bd3-84e6-bb0f13a06c64}"> <prefs/> <versionRange minVersion="0.1" maxVersion="*"> <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"> <versionRange maxVersion="9.0" minVersion="9.0a1"/> </targetApplication> </versionRange> </emItem> + <emItem blockID="i576" id="newmoz@facebook.com"> + <prefs/> + <versionRange minVersion="0" maxVersion="*" severity="3"/> + </emItem> <emItem blockID="i776" id="g@uzcERQ6ko.net"> <prefs> <pref>browser.startup.homepage</pref> <pref>browser.search.defaultenginename</pref> </prefs> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> <emItem blockID="i494" id="/^({e9df9360-97f8-4690-afe6-996c80790da4}|{687578b9-7132-4a7a-80e4-30ee31099e03}|{46a3135d-3683-48cf-b94c-82655cbc0e8a}|{49c795c2-604a-4d18-aeb1-b3eba27e5ea2}|{7473b6bd-4691-4744-a82b-7854eb3d70b6}|{96f454ea-9d38-474f-b504-56193e00c1a5})$/"> @@ -1359,36 +1359,36 @@ <emItem blockID="i1034" id="a88a77ahjjfjakckmmabsy278djasi@jetpack"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> <emItem blockID="i562" id="iobitapps@mybrowserbar.com"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> - <emItem blockID="i430" id="1chtw@facebook.com"> - <prefs/> - <versionRange minVersion="0" maxVersion="*" severity="3"/> - </emItem> <emItem blockID="i338" id="{1FD91A9C-410C-4090-BBCC-55D3450EF433}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> <emItem blockID="i916" id="{97E22097-9A2F-45b1-8DAF-36AD648C7EF4}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"> <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"> <versionRange maxVersion="*" minVersion="39.0a1"/> </targetApplication> </versionRange> </emItem> <emItem blockID="i970" id="hha8771ui3-Fo9j9h7aH98jsdfa8sda@jetpack"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> + <emItem blockID="i430" id="1chtw@facebook.com"> + <prefs/> + <versionRange minVersion="0" maxVersion="*" severity="3"/> + </emItem> <emItem blockID="i344" id="lrcsTube@hansanddeta.com"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> <emItem blockID="i79" id="GifBlock@facebook.com"> <prefs/> <versionRange minVersion="0" maxVersion="*"/> </emItem> @@ -1445,24 +1445,24 @@ <emItem blockID="i58" id="webmaster@buzzzzvideos.info"> <prefs/> <versionRange minVersion="0" maxVersion="*"/> </emItem> <emItem blockID="i5" id="support@daemon-tools.cc"> <prefs/> <versionRange minVersion=" " maxVersion="1.0.0.5"/> </emItem> + <emItem blockID="i449" id="gystqfr@ylgga.com"> + <prefs/> + <versionRange minVersion="0" maxVersion="*" severity="1"/> + </emItem> <emItem blockID="i378" id="{a7aae4f0-bc2e-a0dd-fb8d-68ce32c9261f}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> - <emItem blockID="i449" id="gystqfr@ylgga.com"> - <prefs/> - <versionRange minVersion="0" maxVersion="*" severity="1"/> - </emItem> <emItem blockID="i545" id="superlrcs@svenyor.net"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> <emItem blockID="i163" id="info@allpremiumplay.info"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> @@ -1682,21 +1682,21 @@ <emItem blockID="i519" id="703db0db-5fe9-44b6-9f53-c6a91a0ad5bd@7314bc82-969e-4d2a-921b-e5edd0b02cf1.com"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> <emItem blockID="i477" id="mbrnovone@facebook.com"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> - <emItem blockID="i836" id="hansin@topvest.id"> + <emItem blockID="i495" id="kallow@facebook.com"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> - <emItem blockID="i495" id="kallow@facebook.com"> + <emItem blockID="i836" id="hansin@topvest.id"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> <emItem blockID="i542" id="/^({bf67a47c-ea97-4caf-a5e3-feeba5331231}|{24a0cfe1-f479-4b19-b627-a96bf1ea3a56})$/"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> <emItem blockID="i286" id="{58bd07eb-0ee0-4df0-8121-dc9b693373df}"> @@ -1796,28 +1796,28 @@ <emItem blockID="i926" id="{B1FC07E1-E05B-4567-8891-E63FBE545BA8}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"> <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"> <versionRange maxVersion="*" minVersion="39.0a1"/> </targetApplication> </versionRange> </emItem> - <emItem blockID="i782" id="safebrowse@safebrowse.co"> - <prefs/> - <versionRange minVersion="0" maxVersion="*" severity="3"/> - </emItem> <emItem blockID="i806" id="{d9284e50-81fc-11da-a72b-0800200c9a66}"> <prefs/> <versionRange minVersion="0" maxVersion="7.7.34" severity="1"> <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"> <versionRange maxVersion="*" minVersion="34.0a1"/> </targetApplication> </versionRange> </emItem> + <emItem blockID="i782" id="safebrowse@safebrowse.co"> + <prefs/> + <versionRange minVersion="0" maxVersion="*" severity="3"/> + </emItem> <emItem blockID="i382" id="{6926c7f7-6006-42d1-b046-eba1b3010315}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> <emItem blockID="i812" id="{1e4ea5fc-09e5-4f45-a43b-c048304899fc}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> @@ -1896,28 +1896,28 @@ <emItem blockID="i1214" id="firefoxdav@icloud.com"> <prefs/> <versionRange minVersion="0" maxVersion="1.4.22" severity="1"/> </emItem> <emItem blockID="i808" id="{c96d1ae6-c4cf-4984-b110-f5f561b33b5a}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="3"/> </emItem> + <emItem blockID="i66" id="youtubeer@youtuber.com"> + <prefs/> + <versionRange minVersion="0" maxVersion="*"/> + </emItem> <emItem blockID="i4" id="{4B3803EA-5230-4DC3-A7FC-33638F3D3542}"> <prefs/> <versionRange minVersion="1.2" maxVersion="1.2"> <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"> <versionRange maxVersion="*" minVersion="3.0a1"/> </targetApplication> </versionRange> </emItem> - <emItem blockID="i66" id="youtubeer@youtuber.com"> - <prefs/> - <versionRange minVersion="0" maxVersion="*"/> - </emItem> <emItem blockID="i517" id="/^({16e193c8-1706-40bf-b6f3-91403a9a22be}|{284fed43-2e13-4afe-8aeb-50827d510e20}|{5e3cc5d8-ed11-4bed-bc47-35b4c4bc1033}|{7429e64a-1fd4-4112-a186-2b5630816b91}|{8c9980d7-0f09-4459-9197-99b3e559660c}|{8f1d9545-0bb9-4583-bb3c-5e1ac1e2920c})$/"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem> <emItem blockID="i460" id="{845cab51-d8d2-472f-8bd9-2b44642d97c2}"> <prefs/> <versionRange minVersion="0" maxVersion="*" severity="1"/> </emItem>
new file mode 100644 --- /dev/null +++ b/browser/base/.eslintrc.js @@ -0,0 +1,11 @@ +"use strict"; + +module.exports = { + "rules": { + "no-unused-vars": ["error", { + "vars": "local", + "varsIgnorePattern": "^Cc|Ci|Cu|Cr|EXPORTED_SYMBOLS", + "args": "none", + }] + } +};
--- a/browser/base/content/aboutDialog-appUpdater.js +++ b/browser/base/content/aboutDialog-appUpdater.js @@ -361,17 +361,16 @@ appUpdater.prototype = break; case Components.results.NS_BINDING_ABORTED: // Do not remove UI listener since the user may resume downloading again. break; case Components.results.NS_OK: this.removeDownloadListener(); if (this.backgroundUpdateEnabled) { this.selectPanel("applying"); - let update = this.um.activeUpdate; let self = this; Services.obs.addObserver(function (aSubject, aTopic, aData) { // Update the UI when the background updater is finished let status = aData; if (status == "applied" || status == "applied-service" || status == "pending" || status == "pending-service" || status == "pending-elevate") { // If the update is successfully applied, or if the updater has
--- a/browser/base/content/browser-data-submission-info-bar.js +++ b/browser/base/content/browser-data-submission-info-bar.js @@ -64,17 +64,17 @@ var gDataNotificationInfoBar = { popup: null, callback: () => { this._actionTaken = true; window.openAdvancedPreferences("dataChoicesTab"); }, }]; this._log.info("Creating data reporting policy notification."); - let notification = this._notificationBox.appendNotification( + this._notificationBox.appendNotification( message, this._DATA_REPORTING_NOTIFICATION, null, this._notificationBox.PRIORITY_INFO_HIGH, buttons, event => { if (event == "removed") { Services.obs.notifyObservers(null, "datareporting:notify-data-policy:close", null); @@ -120,9 +120,8 @@ var gDataNotificationInfoBar = { } }, QueryInterface: XPCOMUtils.generateQI([ Ci.nsIObserver, Ci.nsISupportsWeakReference, ]), }; -
--- a/browser/base/content/browser-places.js +++ b/browser/base/content/browser-places.js @@ -747,19 +747,16 @@ HistoryMenu.prototype = { }, /** * Populate when the history menu is opened */ populateUndoWindowSubmenu: function PHM_populateUndoWindowSubmenu() { let undoMenu = this._rootElt.getElementsByClassName("recentlyClosedWindowsMenu")[0]; let undoPopup = undoMenu.firstChild; - let menuLabelString = gNavigatorBundle.getString("menuUndoCloseWindowLabel"); - let menuLabelStringSingleTab = - gNavigatorBundle.getString("menuUndoCloseWindowSingleTabLabel"); // remove existing menu items while (undoPopup.hasChildNodes()) undoPopup.removeChild(undoPopup.firstChild); // no restorable windows, so make sure menu is disabled, and return if (SessionStore.getClosedWindowCount() == 0) { undoMenu.setAttribute("disabled", true);
--- a/browser/base/content/browser-plugins.js +++ b/browser/base/content/browser-plugins.js @@ -190,17 +190,16 @@ var gPluginHandler = { aPluginInfo.fallbackType = Ci.nsIObjectLoadingContent.PLUGIN_ACTIVE; break; default: Cu.reportError(Error("Unexpected plugin state: " + aNewState)); return; } let browser = aNotification.browser; - let contentWindow = browser.contentWindow; if (aNewState != "continue") { let principal = aNotification.options.principal; Services.perms.addFromPrincipal(principal, aPluginInfo.permissionString, permission, expireType, expireTime); aPluginInfo.pluginPermissionType = expireType; } browser.messageManager.sendAsyncMessage("BrowserPlugins:ActivatePlugins", {
--- a/browser/base/content/browser-syncui.js +++ b/browser/base/content/browser-syncui.js @@ -436,20 +436,16 @@ var gSyncUI = { dateFormat = {month: 'long', day: 'numeric'}; } else { dateFormat = {weekday: 'long', hour: 'numeric', minute: 'numeric'}; } let lastSyncDateString = date.toLocaleDateString(undefined, dateFormat); return this._stringBundle.formatStringFromName("lastSync2.label", [lastSyncDateString], 1); }, - onSyncFinish: function SUI_onSyncFinish() { - let title = this._stringBundle.GetStringFromName("error.sync.title"); - }, - onClientsSynced: function() { let broadcaster = document.getElementById("sync-syncnow-state"); if (broadcaster) { if (Weave.Service.clientsEngine.stats.numClients > 1) { broadcaster.setAttribute("devices-status", "multi"); } else { broadcaster.setAttribute("devices-status", "single"); } @@ -479,17 +475,17 @@ var gSyncUI = { case "weave:service:sync:error": this.onActivityStop(); break; } // Now non-activity state (eg, enabled, errors, etc) // Note that sync uses the ":ui:" notifications for errors because sync. switch (topic) { case "weave:ui:sync:finish": - this.onSyncFinish(); + // Do nothing. break; case "weave:ui:sync:error": case "weave:service:setup-complete": case "weave:service:login:finish": case "weave:service:login:start": case "weave:service:start-over": this.updateUI(); break;
--- a/browser/base/content/browser-tabsintitlebar.js +++ b/browser/base/content/browser-tabsintitlebar.js @@ -111,18 +111,16 @@ var TabsInTitlebar = { // In some edgecases it is possible for this to fire before we've initialized. // Don't run now, but don't forget to run it when we do initialize. if (!this._initialized) { this._updateOnInit = true; return; } - let allowed = true; - if (!aForce) { // _update is called on resize events, because the window is not ready // after sizemode events. However, we only care about the event when the // sizemode is different from the last time we updated the appearance of // the tabs in the titlebar. let sizemode = document.documentElement.getAttribute("sizemode"); if (this._lastSizeMode == sizemode) { return; @@ -133,20 +131,17 @@ var TabsInTitlebar = { // still changing in the consequent "fullscreen" event. Code there will // call this function again when everything is ready. // See browser-fullScreen.js: FullScreen.toggle and bug 1173768. if (oldSizeMode == "fullscreen") { return; } } - for (let something in this._disallowed) { - allowed = false; - break; - } + let allowed = (Object.keys(this._disallowed)).length == 0; let titlebar = $("titlebar"); let titlebarContent = $("titlebar-content"); let menubar = $("toolbar-menubar"); if (allowed) { // We set the tabsintitlebar attribute first so that our CSS for // tabsintitlebar manifests before we do our measurements.
--- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -45,16 +45,17 @@ Cu.import("resource://gre/modules/Notifi ["SimpleServiceDiscovery", "resource://gre/modules/SimpleServiceDiscovery.jsm"], ["SitePermissions", "resource:///modules/SitePermissions.jsm"], ["Social", "resource:///modules/Social.jsm"], ["TabCrashHandler", "resource:///modules/ContentCrashHandlers.jsm"], ["Task", "resource://gre/modules/Task.jsm"], ["TelemetryStopwatch", "resource://gre/modules/TelemetryStopwatch.jsm"], ["Translation", "resource:///modules/translation/Translation.jsm"], ["UITour", "resource:///modules/UITour.jsm"], + ["URLBarZoom", "resource:///modules/URLBarZoom.jsm"], ["UpdateUtils", "resource://gre/modules/UpdateUtils.jsm"], ["Weave", "resource://services-sync/main.js"], ["fxAccounts", "resource://gre/modules/FxAccounts.jsm"], ["gDevTools", "resource://devtools/client/framework/gDevTools.jsm"], ["gDevToolsBrowser", "resource://devtools/client/framework/gDevTools.jsm"], ["webrtcUI", "resource:///modules/webrtcUI.jsm", ] ].forEach(([name, resource]) => XPCOMUtils.defineLazyModuleGetter(this, name, resource)); @@ -616,17 +617,17 @@ var gPopupBlockerObserver = { var target = aEvent.target; var popupReportIndex = target.getAttribute("popupReportIndex"); let browser = target.popupReportBrowser; browser.unblockPopup(popupReportIndex); }, showAllBlockedPopups: function (aBrowser) { - let popups = aBrowser.retrieveListOfBlockedPopups().then(popups => { + aBrowser.retrieveListOfBlockedPopups().then(popups => { for (let i = 0; i < popups.length; i++) { if (popups[i].popupWindowURIspec) aBrowser.unblockPopup(i); } }, null); }, editPopupSettings: function () @@ -791,17 +792,16 @@ function gKeywordURIFixup({ target: brow function _loadURIWithFlags(browser, uri, params) { if (!uri) { uri = "about:blank"; } let flags = params.flags || 0; let referrer = params.referrerURI; let referrerPolicy = ('referrerPolicy' in params ? params.referrerPolicy : Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT); - let charset = params.charset; let postData = params.postData; let wasRemote = browser.isRemoteBrowser; let process = browser.isRemoteBrowser ? Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT : Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT; let mustChangeProcess = gMultiProcessBrowser && !E10SUtils.canLoadURIInProcess(uri, process); @@ -3099,17 +3099,16 @@ function mirrorMenuItemClicked(event) { {service: event.originalTarget._service}); } function populateMirrorTabMenu(popup) { popup.innerHTML = null; if (!Services.prefs.getBoolPref("browser.casting.enabled")) { return; } - let videoEl = this.target; let doc = popup.ownerDocument; let services = CastingApps.getServicesForMirroring(); services.forEach(service => { let item = doc.createElement("menuitem"); item.setAttribute("label", service.friendlyName); item._service = service; item.addEventListener("command", mirrorMenuItemClicked); popup.appendChild(item); @@ -4444,26 +4443,23 @@ var XULBrowserWindow = { location == "") { // Second condition is for new tabs, otherwise // reload function is enabled until tab is refreshed. this.reloadCommand.setAttribute("disabled", "true"); } else { this.reloadCommand.removeAttribute("disabled"); } URLBarSetURI(aLocationURI); - BookmarkingUI.onLocationChange(); - gIdentityHandler.onLocationChange(); - SocialUI.updateState(); - UITour.onLocationChange(location); - gTabletModePageCounter.inc(); + ReaderParent.updateReaderButton(gBrowser.selectedBrowser); + URLBarZoom.updateZoomButton(gBrowser.selectedBrowser, "browser-fullZoom:location-change"); // Utility functions for disabling find var shouldDisableFind = function shouldDisableFind(aDocument) { let docElt = aDocument.documentElement; return docElt && docElt.getAttribute("disablefastfind") == "true"; } var disableFindCommands = function disableFindCommands(aDisable) { @@ -4507,17 +4503,16 @@ var XULBrowserWindow = { gBrowser.selectedTab.hasAttribute("customizemode")) { gCustomizeMode.enter(); } else if (CustomizationHandler.isEnteringCustomizeMode || CustomizationHandler.isCustomizing()) { gCustomizeMode.exit(); } } UpdateBackForwardCommands(gBrowser.webNavigation); - ReaderParent.updateReaderButton(gBrowser.selectedBrowser); gGestureSupport.restoreRotationState(); // See bug 358202, when tabs are switched during a drag operation, // timers don't fire on windows (bug 203573) if (aRequest) setTimeout(function () { XULBrowserWindow.asyncUpdateUI(); }, 0); else @@ -5630,17 +5625,17 @@ function handleDroppedLink(event, urlOrL let lastLocationChange = gBrowser.selectedBrowser.lastLocationChange; let userContextId = gBrowser.selectedBrowser.getAttribute("usercontextid"); // event is null if links are dropped in content process. // inBackground should be false, as it's loading into current browser. let inBackground = false; if (event) { - let inBackground = Services.prefs.getBoolPref("browser.tabs.loadInBackground"); + inBackground = Services.prefs.getBoolPref("browser.tabs.loadInBackground"); if (event.shiftKey) inBackground = !inBackground; } Task.spawn(function*() { let urls = []; let postDatas = []; for (let link of links) {
--- a/browser/base/content/contentSearchUI.js +++ b/browser/base/content/contentSearchUI.js @@ -4,17 +4,16 @@ "use strict"; this.ContentSearchUIController = (function () { const MAX_DISPLAYED_SUGGESTIONS = 6; const SUGGESTION_ID_PREFIX = "searchSuggestion"; const ONE_OFF_ID_PREFIX = "oneOff"; -const CSS_URI = "chrome://browser/content/contentSearchUI.css"; const HTML_NS = "http://www.w3.org/1999/xhtml"; /** * Creates a new object that manages search suggestions and their UI for a text * box. * * The UI consists of an html:table that's inserted into the DOM after the given
--- a/browser/base/content/pageinfo/pageInfo.js +++ b/browser/base/content/pageinfo/pageInfo.js @@ -819,17 +819,16 @@ function onImageSelect() tree.flex = 0; makePreview(getSelectedRows(tree)[0]); } } // Makes the media preview (image, video, etc) for the selected row on the media tab. function makePreview(row) { - var imageTree = document.getElementById("imagetree"); var item = gImageView.data[row][COL_IMAGE_NODE]; var url = gImageView.data[row][COL_IMAGE_ADDRESS]; var isBG = gImageView.data[row][COL_IMAGE_BG]; var isAudio = false; setItemValue("imageurltext", url); setItemValue("imagetext", item.imageText); setItemValue("imagelongdesctext", item.longDesc); @@ -1010,17 +1009,16 @@ var imagePermissionObserver = { if (document.getElementById("mediaPreviewBox").collapsed) return; if (aTopic == "perm-changed") { var permission = aSubject.QueryInterface(Components.interfaces.nsIPermission); if (permission.type == "image") { var imageTree = document.getElementById("imagetree"); var row = getSelectedRow(imageTree); - var item = gImageView.data[row][COL_IMAGE_NODE]; var url = gImageView.data[row][COL_IMAGE_ADDRESS]; if (permission.matchesURI(makeURI(url), true)) { makeBlockImage(url); } } } } }
--- a/browser/base/content/pageinfo/security.js +++ b/browser/base/content/pageinfo/security.js @@ -16,19 +16,16 @@ var security = { // Display the server certificate (static) viewCert : function () { var cert = security._cert; viewCertHelper(window, cert); }, _getSecurityInfo : function() { - const nsIX509Cert = Components.interfaces.nsIX509Cert; - const nsIX509CertDB = Components.interfaces.nsIX509CertDB; - const nsX509CertDB = "@mozilla.org/security/x509certdb;1"; const nsISSLStatusProvider = Components.interfaces.nsISSLStatusProvider; const nsISSLStatus = Components.interfaces.nsISSLStatus; // We don't have separate info for a frame, return null until further notice // (see bug 138479) if (!this.windowInfo.isTopWindow) return null;
--- a/browser/base/content/safeMode.js +++ b/browser/base/content/safeMode.js @@ -60,17 +60,16 @@ function onExtra1() { return true; } // The reset dialog will handle starting the reset process if the user confirms. showResetDialog(); return false; } function onLoad() { - let dialog = document.documentElement; if (appStartup.automaticSafeModeNecessary) { document.getElementById("autoSafeMode").hidden = false; document.getElementById("safeMode").hidden = true; if (ResetProfile.resetSupported()) { document.getElementById("resetProfile").hidden = false; } else { // Hide the reset button is it's not supported. document.documentElement.getButton("extra1").hidden = true;
--- a/browser/base/content/sync/aboutSyncTabs.js +++ b/browser/base/content/sync/aboutSyncTabs.js @@ -206,17 +206,17 @@ var RemoteTabViewer = { _generateWeaveTabList: function () { let engine = Weave.Service.engineManager.get("tabs"); let list = this._tabsList; let seenURLs = new Set(); let localURLs = engine.getOpenURLs(); - for (let [guid, client] of Object.entries(engine.getAllClients())) { + for (let [, client] of Object.entries(engine.getAllClients())) { // Create the client node, but don't add it in-case we don't show any tabs let appendClient = true; client.tabs.forEach(function({title, urlHistory, icon}) { let url = urlHistory[0]; if (!url || localURLs.has(url) || seenURLs.has(url)) { return; }
--- a/browser/base/content/sync/genericChange.js +++ b/browser/base/content/sync/genericChange.js @@ -27,17 +27,16 @@ var Change = { get _updatingPassphrase() { return this._dialogType == "UpdatePassphrase"; }, onLoad: function Change_onLoad() { /* Load labels */ let introText = document.getElementById("introText"); - let introText2 = document.getElementById("introText2"); let warningText = document.getElementById("warningText"); // load some other elements & info from the window this._dialog = document.getElementById("change-dialog"); this._dialogType = window.arguments[0]; this._duringSetup = window.arguments[1]; this._status = document.getElementById("status"); this._statusIcon = document.getElementById("statusIcon");
--- a/browser/base/content/sync/setup.js +++ b/browser/base/content/sync/setup.js @@ -792,17 +792,16 @@ var gSyncSetup = { }, 1000); }, checkServer: function () { delete this._checkServerTimer; let el = document.getElementById("server"); let valid = false; let feedback = document.getElementById("serverFeedbackRow"); - let str = ""; if (el.value) { valid = this._validateServer(el); let str = valid ? "" : "serverInvalid.label"; this._setFeedbackMessage(feedback, valid, str); } else this._setFeedbackMessage(feedback, true);
--- a/browser/base/content/tab-content.js +++ b/browser/base/content/tab-content.js @@ -267,17 +267,16 @@ var AboutReaderListener = { addEventListener("pagehide", this, false); addMessageListener("Reader:ToggleReaderMode", this); addMessageListener("Reader:PushState", this); }, receiveMessage: function(message) { switch (message.name) { case "Reader:ToggleReaderMode": - let url = content.document.location.href; if (!this.isAboutReader) { this._articlePromise = ReaderMode.parseDocument(content.document).catch(Cu.reportError); ReaderMode.enterReaderMode(docShell, content); } else { this._isLeavingReaderMode = true; ReaderMode.leaveReaderMode(docShell, content); } break;
--- a/browser/base/content/tabbrowser.xml +++ b/browser/base/content/tabbrowser.xml @@ -1761,17 +1761,17 @@ // Restore the securityUI state. let securityUI = aBrowser.securityUI; let state = securityUI ? securityUI.state : Ci.nsIWebProgressListener.STATE_IS_INSECURE; // Include the true final argument to indicate that this event is // simulated (instead of being observed by the webProgressListener). this._callProgressListeners(aBrowser, "onSecurityChange", - [aBrowser.webProgress, null, securityUI.state, true], + [aBrowser.webProgress, null, state, true], true, false); if (aShouldBeRemote) { // Switching the browser to be remote will connect to a new child // process so the browser can no longer be considered to be // crashed. tab.removeAttribute("crashed"); } else { @@ -3783,17 +3783,17 @@ }, // This function runs before every event. It fixes up the state // to account for closed tabs. preActions: function() { this.assert(this.tabbrowser._switcher); this.assert(this.tabbrowser._switcher === this); - for (let [tab, state] of this.tabState) { + for (let [tab, ] of this.tabState) { if (!tab.linkedBrowser) { this.tabState.delete(tab); } } if (this.lastVisibleTab && !this.lastVisibleTab.linkedBrowser) { this.lastVisibleTab = null; } @@ -4742,17 +4742,16 @@ this._findAsYouType = Services.prefs.getBoolPref("accessibility.typeaheadfind"); break; } ]]></body> </method> <constructor> <![CDATA[ - let browserStack = document.getAnonymousElementByAttribute(this, "anonid", "browserStack"); this.mCurrentBrowser = document.getAnonymousElementByAttribute(this, "anonid", "initialBrowser"); this.mCurrentBrowser.permanentKey = {}; Services.obs.addObserver(this, "live-resize-start", false); Services.obs.addObserver(this, "live-resize-end", false); this.mCurrentTab = this.tabContainer.firstChild; const nsIEventListenerService = @@ -5072,38 +5071,52 @@ var browser = event.originalTarget; var tab = this.getTabForBrowser(browser); if (!tab) return; clearTimeout(tab._soundPlayingAttrRemovalTimer); tab._soundPlayingAttrRemovalTimer = 0; + let modifiedAttrs = []; + if (tab.hasAttribute("soundplaying-scheduledremoval")) { + tab.removeAttribute("soundplaying-scheduledremoval"); + modifiedAttrs.push("soundplaying-scheduledremoval"); + } + if (!tab.hasAttribute("soundplaying")) { tab.setAttribute("soundplaying", true); - this._tabAttrModified(tab, ["soundplaying"]); + modifiedAttrs.push("soundplaying"); } + + this._tabAttrModified(tab, modifiedAttrs); ]]> </handler> <handler event="DOMAudioPlaybackStopped"> <![CDATA[ if (!Services.prefs.getBoolPref("browser.tabs.showAudioPlayingIcon") || !event.isTrusted) return; var browser = event.originalTarget; var tab = this.getTabForBrowser(browser); if (!tab) return; if (tab.hasAttribute("soundplaying")) { let removalDelay = Services.prefs.getIntPref("browser.tabs.delayHidingAudioPlayingIconMS"); + + tab.style.setProperty("--soundplaying-removal-delay", `${removalDelay - 300}ms`); + tab.setAttribute("soundplaying-scheduledremoval", "true"); + this._tabAttrModified(tab, ["soundplaying-scheduledremoval"]); + tab._soundPlayingAttrRemovalTimer = setTimeout(() => { + tab.removeAttribute("soundplaying-scheduledremoval"); tab.removeAttribute("soundplaying"); - this._tabAttrModified(tab, ["soundplaying"]); + this._tabAttrModified(tab, ["soundplaying", "soundplaying-scheduledremoval"]); }, removalDelay); } ]]> </handler> </handlers> </binding> <binding id="tabbrowser-tabbox" @@ -5589,17 +5602,16 @@ if (!("animLastScreenX" in draggedTab._dragData)) draggedTab._dragData.animLastScreenX = draggedTab._dragData.screenX; let screenX = event.screenX; if (screenX == draggedTab._dragData.animLastScreenX) return; - let draggingRight = screenX > draggedTab._dragData.animLastScreenX; draggedTab._dragData.animLastScreenX = screenX; let rtl = (window.getComputedStyle(this).direction == "rtl"); let pinned = draggedTab.pinned; let numPinned = this.tabbrowser._numPinnedTabs; let tabs = this.tabbrowser.visibleTabs .slice(pinned ? 0 : numPinned, pinned ? numPinned : undefined); @@ -6539,25 +6551,25 @@ anonid="tab-icon-image" class="tab-icon-image" validate="never" role="presentation"/> <xul:image xbl:inherits="sharing,selected=visuallyselected" anonid="sharing-icon" class="tab-sharing-icon-overlay" role="presentation"/> - <xul:image xbl:inherits="crashed,busy,soundplaying,pinned,muted,selected=visuallyselected" + <xul:image xbl:inherits="crashed,busy,soundplaying,soundplaying-scheduledremoval,pinned,muted,selected=visuallyselected" anonid="overlay-icon" class="tab-icon-overlay" role="presentation"/> <xul:label flex="1" xbl:inherits="value=label,crop,accesskey,fadein,pinned,selected=visuallyselected,attention" class="tab-text tab-label" role="presentation"/> - <xul:image xbl:inherits="soundplaying,pinned,muted,selected=visuallyselected" + <xul:image xbl:inherits="soundplaying,soundplaying-scheduledremoval,pinned,muted,selected=visuallyselected" anonid="soundplaying-icon" class="tab-icon-sound" role="presentation"/> <xul:toolbarbutton anonid="close-button" xbl:inherits="fadein,pinned,selected=visuallyselected" class="tab-close-button close-icon"/> </xul:hbox> </xul:stack> @@ -7154,18 +7166,16 @@ </getter> <setter> <![CDATA[ if (val < 0 || val >= this.childNodes.length) return val; let toTab = this.getRelatedElement(this.childNodes[val]); - let fromTab = this._selectedPanel ? this.getRelatedElement(this._selectedPanel) - : null; gBrowser._getSwitcher().requestTab(toTab); var panel = this._selectedPanel; var newPanel = this.childNodes[val]; this._selectedPanel = newPanel; if (this._selectedPanel != panel) { var event = document.createEvent("Events");
--- a/browser/base/content/test/alerts/browser_notification_close.js +++ b/browser/base/content/test/alerts/browser_notification_close.js @@ -1,14 +1,13 @@ "use strict"; const {PlacesTestUtils} = Cu.import("resource://testing-common/PlacesTestUtils.jsm", {}); -let tab; let notificationURL = "http://example.org/browser/browser/base/content/test/alerts/file_dom_notifications.html"; let oldShowFavicons; add_task(function* test_notificationClose() { let pm = Services.perms; let notificationURI = makeURI(notificationURL); pm.add(notificationURI, "desktop-notification", pm.ALLOW_ACTION); @@ -48,17 +47,17 @@ add_task(function* test_notificationClos let alertCloseButton = alertWindow.document.querySelector(".alertCloseButton"); is(alertCloseButton.localName, "toolbarbutton", "close button found"); let promiseBeforeUnloadEvent = BrowserTestUtils.waitForEvent(alertWindow, "beforeunload"); let closedTime = alertWindow.Date.now(); alertCloseButton.click(); info("Clicked on close button"); - let beforeUnloadEvent = yield promiseBeforeUnloadEvent; + yield promiseBeforeUnloadEvent; ok(true, "Alert should close when the close button is clicked"); let currentTime = alertWindow.Date.now(); // The notification will self-close at 12 seconds, so this checks // that the notification closed before the timeout. ok(currentTime - closedTime < 5000, "Close requested at " + closedTime + ", actually closed at " + currentTime); });
--- a/browser/base/content/test/general/browser_aboutAccounts.js +++ b/browser/base/content/test/general/browser_aboutAccounts.js @@ -124,17 +124,17 @@ var gTests = [ }, { desc: "Test action=signin - captive portal", teardown: () => gBrowser.removeCurrentTab(), run: function* () { const signinUrl = "https://redirproxy.example.com/test"; setPref("identity.fxaccounts.remote.signin.uri", signinUrl); - let [tab, url] = yield promiseNewTabWithIframeLoadEvent("about:accounts?action=signin"); + let [tab, ] = yield promiseNewTabWithIframeLoadEvent("about:accounts?action=signin"); yield checkVisibilities(tab, { stage: true, // parent of 'manage' and 'intro' manage: false, intro: false, // this is "get started" remote: false, networkError: true }); } @@ -147,17 +147,17 @@ var gTests = [ }, run: function* () { BrowserOffline.toggleOfflineStatus(); Services.cache2.clear(); const signinUrl = "https://unknowndomain.cow"; setPref("identity.fxaccounts.remote.signin.uri", signinUrl); - let [tab, url] = yield promiseNewTabWithIframeLoadEvent("about:accounts?action=signin"); + let [tab, ] = yield promiseNewTabWithIframeLoadEvent("about:accounts?action=signin"); yield checkVisibilities(tab, { stage: true, // parent of 'manage' and 'intro' manage: false, intro: false, // this is "get started" remote: false, networkError: true }); } @@ -206,28 +206,19 @@ var gTests = [ teardown: function* () { gBrowser.removeCurrentTab(); yield signOut(); }, run: function* () { const expected_url = "https://example.com/?is_force_auth"; setPref("identity.fxaccounts.remote.force_auth.uri", expected_url); - let userData = { - email: "foo@example.com", - uid: "1234@lcip.org", - assertion: "foobar", - sessionToken: "dead", - kA: "beef", - kB: "cafe", - verified: true - }; yield setSignedInUser(); - let [tab, url] = yield promiseNewTabWithIframeLoadEvent("about:accounts?action=reauth"); + let [, url] = yield promiseNewTabWithIframeLoadEvent("about:accounts?action=reauth"); // The current user will be appended to the url let expected = expected_url + "&email=foo%40example.com"; is(url, expected, "action=reauth got the expected URL"); }, }, { desc: "Test with migrateToDevEdition enabled (success)", teardown: function* () { @@ -346,69 +337,69 @@ var gTests = [ } }, { desc: "Test entrypoint query string, no action, no user logged in", teardown: () => gBrowser.removeCurrentTab(), run: function* () { // When this loads with no user logged-in, we expect the "normal" URL setPref("identity.fxaccounts.remote.signup.uri", "https://example.com/"); - let [tab, url] = yield promiseNewTabWithIframeLoadEvent("about:accounts?entrypoint=abouthome"); + let [, url] = yield promiseNewTabWithIframeLoadEvent("about:accounts?entrypoint=abouthome"); is(url, "https://example.com/?entrypoint=abouthome", "entrypoint=abouthome got the expected URL"); }, }, { desc: "Test entrypoint query string for signin", teardown: () => gBrowser.removeCurrentTab(), run: function* () { // When this loads with no user logged-in, we expect the "normal" URL const expected_url = "https://example.com/?is_sign_in"; setPref("identity.fxaccounts.remote.signin.uri", expected_url); - let [tab, url] = yield promiseNewTabWithIframeLoadEvent("about:accounts?action=signin&entrypoint=abouthome"); + let [, url] = yield promiseNewTabWithIframeLoadEvent("about:accounts?action=signin&entrypoint=abouthome"); is(url, expected_url + "&entrypoint=abouthome", "entrypoint=abouthome got the expected URL"); }, }, { desc: "Test entrypoint query string for signup", teardown: () => gBrowser.removeCurrentTab(), run: function* () { // When this loads with no user logged-in, we expect the "normal" URL const sign_up_url = "https://example.com/?is_sign_up"; setPref("identity.fxaccounts.remote.signup.uri", sign_up_url); - let [tab, url] = yield promiseNewTabWithIframeLoadEvent("about:accounts?entrypoint=abouthome&action=signup"); + let [, url] = yield promiseNewTabWithIframeLoadEvent("about:accounts?entrypoint=abouthome&action=signup"); is(url, sign_up_url + "&entrypoint=abouthome", "entrypoint=abouthome got the expected URL"); }, }, { desc: "about:accounts URL params should be copied to remote URL params " + "when remote URL has no URL params, except for 'action'", teardown() { gBrowser.removeCurrentTab(); }, run: function* () { let signupURL = "https://example.com/"; setPref("identity.fxaccounts.remote.signup.uri", signupURL); let queryStr = "email=foo%40example.com&foo=bar&baz=quux"; - let [tab, url] = + let [, url] = yield promiseNewTabWithIframeLoadEvent("about:accounts?" + queryStr + "&action=action"); is(url, signupURL + "?" + queryStr, "URL params are copied to signup URL"); }, }, { desc: "about:accounts URL params should be copied to remote URL params " + "when remote URL already has some URL params, except for 'action'", teardown() { gBrowser.removeCurrentTab(); }, run: function* () { let signupURL = "https://example.com/?param"; setPref("identity.fxaccounts.remote.signup.uri", signupURL); let queryStr = "email=foo%40example.com&foo=bar&baz=quux"; - let [tab, url] = + let [, url] = yield promiseNewTabWithIframeLoadEvent("about:accounts?" + queryStr + "&action=action"); is(url, signupURL + "&" + queryStr, "URL params are copied to signup URL"); }, }, ]; // gTests function test()
--- a/browser/base/content/test/general/browser_aboutCertError.js +++ b/browser/base/content/test/general/browser_aboutCertError.js @@ -82,17 +82,17 @@ add_task(function* checkReturnToPrevious is(browser.webNavigation.canGoForward, true, "webNavigation.canGoForward"); is(gBrowser.currentURI.spec, GOOD_PAGE, "Went back"); yield BrowserTestUtils.removeTab(gBrowser.selectedTab); }); add_task(function* checkBadStsCert() { info("Loading a badStsCert and making sure exception button doesn't show up"); - let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, GOOD_PAGE); + yield BrowserTestUtils.openNewForegroundTab(gBrowser, GOOD_PAGE); let browser = gBrowser.selectedBrowser; info("Loading and waiting for the cert error"); let certErrorLoaded = waitForCertErrorLoad(browser); BrowserTestUtils.loadURI(browser, BAD_STS_CERT); yield certErrorLoaded; let exceptionButtonHidden = yield ContentTask.spawn(browser, null, function* () { @@ -106,17 +106,17 @@ add_task(function* checkBadStsCert() { }); const PREF_BLOCKLIST_CLOCK_SKEW_SECONDS = "services.blocklist.clock_skew_seconds"; add_task(function* checkWrongSystemTimeWarning() { function* setUpPage() { let browser; let certErrorLoaded; - let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, () => { + yield BrowserTestUtils.openNewForegroundTab(gBrowser, () => { gBrowser.selectedTab = gBrowser.addTab(BAD_CERT); browser = gBrowser.selectedBrowser; certErrorLoaded = waitForCertErrorLoad(browser); }, false); info("Loading and waiting for the cert error"); yield certErrorLoaded; @@ -206,17 +206,17 @@ add_task(function* checkWrongSystemTimeW yield BrowserTestUtils.removeTab(gBrowser.selectedTab); }); add_task(function* checkAdvancedDetails() { info("Loading a bad cert page and verifying the advanced details section"); let browser; let certErrorLoaded; - let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, () => { + yield BrowserTestUtils.openNewForegroundTab(gBrowser, () => { gBrowser.selectedTab = gBrowser.addTab(BAD_CERT); browser = gBrowser.selectedBrowser; certErrorLoaded = waitForCertErrorLoad(browser); }, false); info("Loading and waiting for the cert error"); yield certErrorLoaded; @@ -233,19 +233,16 @@ add_task(function* checkAdvancedDetails( message = yield ContentTask.spawn(browser, null, function* () { let doc = content.document; let errorCode = doc.getElementById("errorCode"); errorCode.click(); let div = doc.getElementById("certificateErrorDebugInformation"); let text = doc.getElementById("certificateErrorText"); - let docshell = content.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebNavigation) - .QueryInterface(Ci.nsIDocShell); let serhelper = Cc["@mozilla.org/network/serialization-helper;1"] .getService(Ci.nsISerializationHelper); let serializable = docShell.failedChannel.securityInfo .QueryInterface(Ci.nsITransportSecurityInfo) .QueryInterface(Ci.nsISerializable); let serializedSecurityInfo = serhelper.serializeToString(serializable); return { divDisplay: content.getComputedStyle(div).display, @@ -266,17 +263,17 @@ add_task(function* checkAdvancedDetails( yield BrowserTestUtils.removeTab(gBrowser.selectedTab); }); add_task(function* checkAdvancedDetailsForHSTS() { info("Loading a bad STS cert page and verifying the advanced details section"); let browser; let certErrorLoaded; - let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, () => { + yield BrowserTestUtils.openNewForegroundTab(gBrowser, () => { gBrowser.selectedTab = gBrowser.addTab(BAD_STS_CERT); browser = gBrowser.selectedBrowser; certErrorLoaded = waitForCertErrorLoad(browser); }, false); info("Loading and waiting for the cert error"); yield certErrorLoaded; @@ -305,19 +302,16 @@ add_task(function* checkAdvancedDetailsF message = yield ContentTask.spawn(browser, null, function* () { let doc = content.document; let errorCode = doc.getElementById("errorCode"); errorCode.click(); let div = doc.getElementById("certificateErrorDebugInformation"); let text = doc.getElementById("certificateErrorText"); - let docshell = content.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebNavigation) - .QueryInterface(Ci.nsIDocShell); let serhelper = Cc["@mozilla.org/network/serialization-helper;1"] .getService(Ci.nsISerializationHelper); let serializable = docShell.failedChannel.securityInfo .QueryInterface(Ci.nsITransportSecurityInfo) .QueryInterface(Ci.nsISerializable); let serializedSecurityInfo = serhelper.serializeToString(serializable); return { divDisplay: content.getComputedStyle(div).display, @@ -338,17 +332,17 @@ add_task(function* checkAdvancedDetailsF yield BrowserTestUtils.removeTab(gBrowser.selectedTab); }); add_task(function* checkUnknownIssuerLearnMoreLink() { info("Loading a cert error for self-signed pages and checking the correct link is shown"); let browser; let certErrorLoaded; - let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, () => { + yield BrowserTestUtils.openNewForegroundTab(gBrowser, () => { gBrowser.selectedTab = gBrowser.addTab(UNKNOWN_ISSUER); browser = gBrowser.selectedBrowser; certErrorLoaded = waitForCertErrorLoad(browser); }, false); info("Loading and waiting for the cert error"); yield certErrorLoaded;
--- a/browser/base/content/test/general/browser_aboutNetError.js +++ b/browser/base/content/test/general/browser_aboutNetError.js @@ -10,17 +10,17 @@ Services.prefs.setIntPref("security.tls. const LOW_TLS_VERSION = "https://tls1.example.com/"; const {TabStateFlusher} = Cu.import("resource:///modules/sessionstore/TabStateFlusher.jsm", {}); const ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore); add_task(function* checkReturnToPreviousPage() { info("Loading a TLS page that isn't supported, ensure we have a fix button and clicking it then loads the page"); let browser; let pageLoaded; - let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, () => { + yield BrowserTestUtils.openNewForegroundTab(gBrowser, () => { gBrowser.selectedTab = gBrowser.addTab(LOW_TLS_VERSION); browser = gBrowser.selectedBrowser; pageLoaded = BrowserTestUtils.waitForErrorPage(browser); }, false); info("Loading and waiting for the net error"); yield pageLoaded; @@ -34,9 +34,8 @@ add_task(function* checkReturnToPrevious content.document.getElementById("prefResetButton").click(); }); yield pageshowPromise; Assert.equal(content.document.documentURI, LOW_TLS_VERSION, "Should not be showing page"); yield BrowserTestUtils.removeTab(gBrowser.selectedTab); }); -
--- a/browser/base/content/test/general/browser_aboutTabCrashed_showForm.js +++ b/browser/base/content/test/general/browser_aboutTabCrashed_showForm.js @@ -11,18 +11,16 @@ requestLongerTimeout(2); * Tests that we show the about:tabcrashed additional details form * if the "submit a crash report" checkbox was checked by default. */ add_task(function* test_show_form() { return BrowserTestUtils.withNewTab({ gBrowser, url: PAGE, }, function*(browser) { - let tab = gBrowser.getTabForBrowser(browser); - // Flip the pref so that the checkbox should be checked // by default. let pref = TabCrashHandler.prefs.root + "sendReport"; yield pushPrefs([pref, true]); // Now crash the browser. yield BrowserTestUtils.crashBrowser(browser);
--- a/browser/base/content/test/general/browser_bug409624.js +++ b/browser/base/content/test/general/browser_bug409624.js @@ -21,19 +21,16 @@ add_task(function* test() { } }, }); }); let prefService = Cc["@mozilla.org/preferences-service;1"] .getService(Components.interfaces.nsIPrefService); - let findBar = gFindBar; - let textbox = gFindBar.getElement("findbar-textbox"); - let tempScope = {}; Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader) .loadSubScript("chrome://browser/content/sanitize.js", tempScope); let Sanitizer = tempScope.Sanitizer; let s = new Sanitizer(); s.prefDomain = "privacy.cpd."; let prefBranch = prefService.getBranch(s.prefDomain);
--- a/browser/base/content/test/general/browser_bug431826.js +++ b/browser/base/content/test/general/browser_bug431826.js @@ -14,18 +14,16 @@ add_task(function* () { yield promise; yield remote(() => { // Confirm that we are displaying the contributed error page, not the default let uri = content.document.documentURI; Assert.ok(uri.startsWith("about:certerror"), "Broken page should go to about:certerror, not about:neterror"); }); - let advancedDiv, advancedDivVisibility, technicalDivCollapsed; - yield remote(() => { let div = content.document.getElementById("badCertAdvancedPanel"); // Confirm that the expert section is collapsed Assert.ok(div, "Advanced content div should exist"); Assert.equal(div.ownerGlobal.getComputedStyle(div).display, "none", "Advanced content should not be visible by default"); });
--- a/browser/base/content/test/general/browser_bug460146.js +++ b/browser/base/content/test/general/browser_bug460146.js @@ -3,17 +3,16 @@ function test() { waitForExplicitFinish(); gBrowser.selectedTab = gBrowser.addTab(); gBrowser.selectedBrowser.addEventListener("load", function () { gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true); - var doc = gBrowser.contentDocument; var pageInfo = BrowserPageInfo(gBrowser.selectedBrowser.currentURI.spec, "mediaTab"); pageInfo.addEventListener("load", function () { pageInfo.removeEventListener("load", arguments.callee, true); pageInfo.onFinished.push(function () { executeSoon(function () { var imageTree = pageInfo.document.getElementById("imagetree");
--- a/browser/base/content/test/general/browser_bug553455.js +++ b/browser/base/content/test/general/browser_bug553455.js @@ -1020,24 +1020,16 @@ function test_renotifyInstalled() { Services.perms.remove(makeURI("http://example.com/"), "install"); yield removeTab(); }); }, function test_cancel() { return Task.spawn(function* () { - function complete_install(callback) { - let url = TESTROOT + "slowinstall.sjs?continue=true" - NetUtil.asyncFetch({ - uri: url, - loadUsingSystemPrincipal: true - }, callback || (() => {})); - } - let pm = Services.perms; pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION); let notificationPromise = waitForNotification(PROGRESS_NOTIFICATION); let triggers = encodeURIComponent(JSON.stringify({ "XPI": "slowinstall.sjs?file=amosigned.xpi" })); BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?" + triggers);
--- a/browser/base/content/test/general/browser_bug585830.js +++ b/browser/base/content/test/general/browser_bug585830.js @@ -1,16 +1,16 @@ /* 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/. */ function test() { let tab1 = gBrowser.selectedTab; let tab2 = gBrowser.addTab("about:blank", {skipAnimation: true}); - let tab3 = gBrowser.addTab(); + gBrowser.addTab(); gBrowser.selectedTab = tab2; gBrowser.removeCurrentTab({animate: true}); gBrowser.tabContainer.advanceSelectedTab(-1, true); is(gBrowser.selectedTab, tab1, "First tab should be selected"); gBrowser.removeTab(tab2); // test for "null has no properties" fix. See Bug 585830 Comment 13
--- a/browser/base/content/test/general/browser_bug592338.js +++ b/browser/base/content/test/general/browser_bug592338.js @@ -52,20 +52,19 @@ function test_install_lwtheme() { gBrowser.selectedTab = gBrowser.addTab("https://example.com/browser/browser/base/content/test/general/bug592338.html"); gBrowser.selectedBrowser.addEventListener("pageshow", function() { if (gBrowser.contentDocument.location.href == "about:blank") return; gBrowser.selectedBrowser.removeEventListener("pageshow", arguments.callee, false); BrowserTestUtils.synthesizeMouse("#theme-install", 2, 2, {}, gBrowser.selectedBrowser); - let notification; let notificationBox = gBrowser.getNotificationBox(gBrowser.selectedBrowser); waitForCondition( - () => (notification = notificationBox.getNotificationWithValue("lwtheme-install-notification")), + () => notificationBox.getNotificationWithValue("lwtheme-install-notification"), () => { is(LightweightThemeManager.currentTheme.id, "test", "Should have installed the test theme"); LightweightThemeManager.currentTheme = null; gBrowser.removeTab(gBrowser.selectedTab); Services.perms.remove(makeURI("http://example.com/"), "install"); runNextTest();
--- a/browser/base/content/test/general/browser_bug676619.js +++ b/browser/base/content/test/general/browser_bug676619.js @@ -1,18 +1,18 @@ function test () { requestLongerTimeout(3); waitForExplicitFinish(); var isHTTPS = false; function loadListener() { function testLocation(link, url, next) { - var tabOpenListener = new TabOpenListener(url, function () { - gBrowser.removeTab(this.tab); + new TabOpenListener(url, function () { + gBrowser.removeTab(this.tab); }, function () { next(); }); ContentTask.spawn(gBrowser.selectedBrowser, link, link => { content.document.getElementById(link).click(); }); }
--- a/browser/base/content/test/general/browser_bug678392.js +++ b/browser/base/content/test/general/browser_bug678392.js @@ -152,17 +152,16 @@ function test1() { }); } function test2() { // Test growing of snapshot array across tabs. let tab = gBrowser.selectedTab; load(tab, HTTPROOT + "browser_bug678392-1.html", function() { - var historyIndex = gBrowser.webNavigation.sessionHistory.index - 1; load(tab, HTTPROOT + "browser_bug678392-2.html", function() { is(gHistorySwipeAnimation._trackedSnapshots.length, 2, "Length of " + "snapshot array is equal to 2 after loading two pages"); let prevTab = tab; tab = gBrowser.addTab("about:newtab"); gBrowser.selectedTab = tab; load(tab, HTTPROOT + "browser_bug678392-2.html" /* initial page */, function() {
--- a/browser/base/content/test/general/browser_bug822367.js +++ b/browser/base/content/test/general/browser_bug822367.js @@ -120,17 +120,16 @@ function MixedTest4A() { function MixedTest4B() { waitForCondition(() => content.document.location == gHttpTestRoot + "file_bug822367_4B.html", MixedTest4C, "Waited too long for mixed script to run in Test 4"); } function MixedTest4C() { ok(content.document.location == gHttpTestRoot + "file_bug822367_4B.html", "Location didn't change in test 4"); assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: true, passiveLoaded: false}); - let {gIdentityHandler} = gTestBrowser.ownerGlobal; waitForCondition(() => content.document.getElementById('p1').innerHTML == "", MixedTest4D, "Mixed script loaded in test 4 after location change!"); } function MixedTest4D() { ok(content.document.getElementById('p1').innerHTML == "", "p1.innerHTML changed; mixed script loaded after location change in Test 4"); MixedTest5(); } // Mixed script attempts to load in a document.open()
--- a/browser/base/content/test/general/browser_contentSearchUI.js +++ b/browser/base/content/test/general/browser_contentSearchUI.js @@ -577,17 +577,16 @@ add_task(function* search() { { str: "xfoo", type: "formHistory" }, "xbar"], 0); // Mouse over the second suggestion. state = yield msg("mousemove", 1); checkState(state, "x", [{ str: "x", type: "formHistory" }, { str: "xfoo", type: "formHistory" }, "xbar"], 1); modifiers.button = 0; - let currentTab = gBrowser.selectedTab; p = msg("waitForSearch"); yield msg("click", { eltIdx: 1, modifiers: modifiers }); mesg = yield p; eventData.searchString = "xfoo"; eventData.originalEvent = modifiers; eventData.selection = { index: 1, kind: "mouse", @@ -755,17 +754,17 @@ function promiseMsg(name, type, msgMan) function setUpEngines() { return Task.spawn(function* () { info("Removing default search engines"); let currentEngineName = Services.search.currentEngine.name; let currentEngines = Services.search.getVisibleEngines(); info("Adding test search engines"); let engine1 = yield promiseNewSearchEngine(TEST_ENGINE_BASENAME); - let engine2 = yield promiseNewSearchEngine(TEST_ENGINE_2_BASENAME); + yield promiseNewSearchEngine(TEST_ENGINE_2_BASENAME); Services.search.currentEngine = engine1; for (let engine of currentEngines) { Services.search.removeEngine(engine); } registerCleanupFunction(() => { Services.search.restoreDefaultEngines(); Services.search.currentEngine = Services.search.getEngineByName(currentEngineName); });
--- a/browser/base/content/test/general/browser_contextmenu_childprocess.js +++ b/browser/base/content/test/general/browser_contextmenu_childprocess.js @@ -7,17 +7,17 @@ add_task(function *() { let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, gBaseURL + "subtst_contextmenu.html"); let contextMenu = document.getElementById("contentAreaContextMenu"); // Get the point of the element with the page menu (test-pagemenu) and // synthesize a right mouse click there. let popupShownPromise = BrowserTestUtils.waitForEvent(contextMenu, "popupshown"); yield BrowserTestUtils.synthesizeMouse("#test-pagemenu", 5, 5, { type : "contextmenu", button : 2 }, tab.linkedBrowser); - let event = yield popupShownPromise; + yield popupShownPromise; checkMenu(contextMenu); let popupHiddenPromise = BrowserTestUtils.waitForEvent(contextMenu, "popuphidden"); contextMenu.hidePopup(); yield popupHiddenPromise; yield BrowserTestUtils.removeTab(tab);
--- a/browser/base/content/test/general/browser_datachoices_notification.js +++ b/browser/base/content/test/general/browser_datachoices_notification.js @@ -87,17 +87,17 @@ var checkInfobarButton = Task.async(func // Add an observer to ensure the "advanced" pane opened (but don't bother // closing it - we close the entire window when done.) let paneLoadedPromise = promiseTopicObserved("advanced-pane-loaded"); // Click on the button. button.click(); // Wait for the preferences panel to open. - let preferenceWindow = yield paneLoadedPromise; + yield paneLoadedPromise; yield promiseNextTick(); }); add_task(function* setup() { const bypassNotification = Preferences.get(PREF_BYPASS_NOTIFICATION, true); const currentPolicyVersion = Preferences.get(PREF_CURRENT_POLICY_VERSION, 1); // Register a cleanup function to reset our preferences.
--- a/browser/base/content/test/general/browser_double_close_tab.js +++ b/browser/base/content/test/general/browser_double_close_tab.js @@ -39,17 +39,17 @@ function waitForDialogDestroyed(node, ca add_task(function*() { testTab = gBrowser.selectedTab = gBrowser.addTab(); yield promiseTabLoadEvent(testTab, TEST_PAGE); // XXXgijs the reason this has nesting and callbacks rather than promises is // that DOM promises resolve on the next tick. So they're scheduled // in an event queue. So when we spin a new event queue for a modal dialog... // everything gets messed up and the promise's .then callbacks never get // called, despite resolve() being called just fine. - let dialogNode = yield new Promise(resolveOuter => { + yield new Promise(resolveOuter => { waitForDialog(dialogNode => { waitForDialogDestroyed(dialogNode, () => { let doCompletion = () => setTimeout(resolveOuter, 0); info("Now checking if dialog is destroyed"); ok(!dialogNode.parentNode, "onbeforeunload dialog should be gone."); if (dialogNode.parentNode) { // Failed to remove onbeforeunload dialog, so do it ourselves: let leaveBtn = dialogNode.ui.button0; @@ -73,10 +73,8 @@ registerCleanupFunction(function() { if (testTab.parentNode) { // Remove the handler, or closing this tab will prove tricky: try { testTab.linkedBrowser.contentWindow.onbeforeunload = null; } catch (ex) {} gBrowser.removeTab(testTab); } }); - -
--- a/browser/base/content/test/general/browser_fullscreen-window-open.js +++ b/browser/base/content/test/general/browser_fullscreen-window-open.js @@ -177,17 +177,16 @@ function test_open_from_chrome() { title: "test_open_from_chrome", param: "", }, finalizeFn: function () {} }); } function waitForTabOpen(aOptions) { - let start = Date.now(); let message = aOptions.message; if (!message.title) { ok(false, "Can't get message.title."); aOptions.finalizeFn(); runNextTest(); return; } @@ -226,17 +225,16 @@ function waitForTabOpen(aOptions) { uri: URI, title: message.title, option: message.param, }); } function waitForWindowOpen(aOptions) { - let start = Date.now(); let message = aOptions.message; let url = aOptions.url || "about:blank"; if (!message.title) { ok(false, "Can't get message.title"); aOptions.finalizeFn(); runNextTest(); return; @@ -268,17 +266,16 @@ function executeWindowOpenInContent(aPar ContentTask.spawn(gBrowser.selectedBrowser, JSON.stringify(aParam), function* (dataTestParam) { let testElm = content.document.getElementById("test"); testElm.setAttribute("data-test-param", dataTestParam); testElm.click(); }); } function waitForWindowOpenFromChrome(aOptions) { - let start = Date.now(); let message = aOptions.message; let url = aOptions.url || "about:blank"; if (!message.title) { ok(false, "Can't get message.title"); aOptions.finalizeFn(); runNextTest(); return; @@ -294,17 +291,17 @@ function waitForWindowOpenFromChrome(aOp }; let listener = new WindowListener(message.title, getBrowserURL(), { onSuccess: aOptions.successFn, onFinalize: onFinalize, }); Services.wm.addListener(listener); - let testWindow = window.open(url, message.title, message.option); + window.open(url, message.title, message.option); } function WindowListener(aTitle, aUrl, aCallBackObj) { this.test_title = aTitle; this.test_url = aUrl; this.callback_onSuccess = aCallBackObj.onSuccess; this.callBack_onFinalize = aCallBackObj.onFinalize; }
--- a/browser/base/content/test/general/browser_gestureSupport.js +++ b/browser/base/content/test/general/browser_gestureSupport.js @@ -541,17 +541,16 @@ function test_rotateHelperGetImageRotati function test_rotateHelperOneGesture(aImageElement, aCurrentRotation, aDirection, aAmount, aStop) { if (aAmount <= 0 || aAmount > 90) // Bound to 0 < aAmount <= 90 return; // easier to type names for the direction constants let clockwise = SimpleGestureEvent.ROTATION_CLOCKWISE; - let cclockwise = SimpleGestureEvent.ROTATION_COUNTERCLOCKWISE; let delta = aAmount * (aDirection == clockwise ? 1 : -1); // Kill transition time on image so test isn't wrong and doesn't take 10 seconds aImageElement.style.transitionDuration = "0s"; // Start the gesture, perform an update, and force flush test_utils.sendSimpleGestureEvent("MozRotateGestureStart", 0, 0, aDirection, .001, 0);
--- a/browser/base/content/test/general/browser_page_style_menu_update.js +++ b/browser/base/content/test/general/browser_page_style_menu_update.js @@ -40,17 +40,16 @@ add_task(function*() { gPageStyleMenu.fillPopup(menupopup); // page_style_sample.html should default us to selecting the stylesheet // with the title "6" first. let selected = menupopup.querySelector("menuitem[checked='true']"); is(selected.getAttribute("label"), "6", "Should have '6' stylesheet selected by default"); // Now select stylesheet "1" - let targets = menupopup.querySelectorAll("menuitem"); let target = menupopup.querySelector("menuitem[label='1']"); target.click(); // Now we need to wait for the content process to send its stylesheet // update for the selected tab to the parent. Because messages are // guaranteed to be sent in order, we'll make sure we do the check // after the parent has been updated by yielding until the child // has finished running a ContentTask for us.
--- a/browser/base/content/test/general/browser_parsable_script.js +++ b/browser/base/content/test/general/browser_parsable_script.js @@ -43,20 +43,19 @@ function uriIsWhiteListed(uri) { function parsePromise(uri) { let promise = new Promise((resolve, reject) => { let xhr = new XMLHttpRequest(); xhr.open("GET", uri, true); xhr.onreadystatechange = function() { if (this.readyState == this.DONE) { let scriptText = this.responseText; - let ast; try { info("Checking " + uri); - ast = Reflect.parse(scriptText); + Reflect.parse(scriptText); resolve(true); } catch (ex) { let errorMsg = "Script error reading " + uri + ": " + ex; ok(false, errorMsg); resolve(false); } } }; @@ -126,9 +125,8 @@ add_task(function* checkAllTheJS() { continue; } allPromises.push(parsePromise(uri.spec)); } let promiseResults = yield Promise.all(allPromises); is(promiseResults.filter((x) => !x).length, 0, "There should be 0 parsing errors"); }); -
--- a/browser/base/content/test/general/browser_permissions.js +++ b/browser/base/content/test/general/browser_permissions.js @@ -27,17 +27,16 @@ function* openIdentityPopup() { function* closeIdentityPopup() { let {gIdentityHandler} = gBrowser.ownerGlobal; let promise = BrowserTestUtils.waitForEvent(gIdentityHandler._identityPopup, "popuphidden"); gIdentityHandler._identityPopup.hidePopup(); return promise; } add_task(function* testMainViewVisible() { - let {gIdentityHandler} = gBrowser.ownerGlobal; let tab = gBrowser.selectedTab = gBrowser.addTab(); yield promiseTabLoadEvent(tab, PERMISSIONS_PAGE); let permissionsList = document.getElementById("identity-popup-permission-list"); let emptyLabel = permissionsList.nextSibling.nextSibling; yield openIdentityPopup(); @@ -97,17 +96,16 @@ add_task(function* testIdentityIcon() { "identity-box signals granted permissions"); SitePermissions.remove(gBrowser.currentURI, "geo"); SitePermissions.remove(gBrowser.currentURI, "camera"); SitePermissions.remove(gBrowser.currentURI, "cookie"); }); add_task(function* testCancelPermission() { - let {gIdentityHandler} = gBrowser.ownerGlobal; let tab = gBrowser.selectedTab = gBrowser.addTab(); yield promiseTabLoadEvent(tab, PERMISSIONS_PAGE); let permissionsList = document.getElementById("identity-popup-permission-list"); let emptyLabel = permissionsList.nextSibling.nextSibling; SitePermissions.set(gBrowser.currentURI, "geo", SitePermissions.ALLOW); SitePermissions.set(gBrowser.currentURI, "camera", SitePermissions.BLOCK); @@ -125,17 +123,16 @@ add_task(function* testCancelPermission( cancelButtons[1].click(); labels = permissionsList.querySelectorAll(".identity-popup-permission-label"); is(labels.length, 0, "One permission should be removed"); yield closeIdentityPopup(); }); add_task(function* testPermissionHints() { - let {gIdentityHandler} = gBrowser.ownerGlobal; let tab = gBrowser.selectedTab = gBrowser.addTab(); yield promiseTabLoadEvent(tab, PERMISSIONS_PAGE); let permissionsList = document.getElementById("identity-popup-permission-list"); let emptyHint = document.getElementById("identity-popup-permission-empty-hint"); let reloadHint = document.getElementById("identity-popup-permission-reload-hint"); yield openIdentityPopup();
--- a/browser/base/content/test/general/browser_purgehistory_clears_sh.js +++ b/browser/base/content/test/general/browser_purgehistory_clears_sh.js @@ -1,15 +1,15 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ const url = "http://example.org/browser/browser/base/content/test/general/dummy_page.html"; add_task(function* purgeHistoryTest() { - let tab = yield BrowserTestUtils.withNewTab({ + yield BrowserTestUtils.withNewTab({ gBrowser, url, }, function* purgeHistoryTestInner(browser) { let backButton = browser.ownerDocument.getElementById("Browser:Back"); let forwardButton = browser.ownerDocument.getElementById("Browser:Forward"); ok(!browser.webNavigation.canGoBack, "Initial value for webNavigation.canGoBack");
--- a/browser/base/content/test/general/browser_readerMode.js +++ b/browser/base/content/test/general/browser_readerMode.js @@ -108,21 +108,19 @@ add_task(function* test_getOriginalUrl() add_task(function* test_reader_view_element_attribute_transform() { registerCleanupFunction(function() { while (gBrowser.tabs.length > 1) { gBrowser.removeCurrentTab(); } }); function observeAttribute(element, attribute, triggerFn, checkFn) { - let initValue = element.getAttribute(attribute); return new Promise(resolve => { let observer = new MutationObserver((mutations) => { mutations.forEach( mu => { - let muValue = element.getAttribute(attribute); if (element.getAttribute(attribute) !== mu.oldValue) { checkFn(); resolve(); observer.disconnect(); } }); });
--- a/browser/base/content/test/general/browser_relatedTabs.js +++ b/browser/base/content/test/general/browser_relatedTabs.js @@ -5,17 +5,16 @@ add_task(function*() { is(gBrowser.tabs.length, 1, "one tab is open initially"); // Add several new tabs in sequence, interrupted by selecting a // different tab, moving a tab around and closing a tab, // returning a list of opened tabs for verifying the expected order. // The new tab behaviour is documented in bug 465673 let tabs = []; - let promises = []; function addTab(aURL, aReferrer) { let tab = gBrowser.addTab(aURL, {referrerURI: aReferrer}); tabs.push(tab); return BrowserTestUtils.browserLoaded(tab.linkedBrowser); } yield addTab("http://mochi.test:8888/#0"); gBrowser.selectedTab = tabs[0];
--- a/browser/base/content/test/general/browser_removeTabsToTheEnd.js +++ b/browser/base/content/test/general/browser_removeTabsToTheEnd.js @@ -1,17 +1,17 @@ /* 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/. */ function test() { // Add two new tabs after the original tab. Pin the first one. let originalTab = gBrowser.selectedTab; let newTab1 = gBrowser.addTab(); - let newTab2 = gBrowser.addTab(); + gBrowser.addTab(); gBrowser.pinTab(newTab1); // Check that there is only one closable tab from originalTab to the end is(gBrowser.getTabsToTheEndFrom(originalTab).length, 1, "One unpinned tab to the right"); // Remove tabs to the end gBrowser.removeTabsToTheEndFrom(originalTab);
--- a/browser/base/content/test/general/browser_sanitizeDialog.js +++ b/browser/base/content/test/general/browser_sanitizeDialog.js @@ -131,17 +131,16 @@ add_task(function* test_history_download for (let i = 0; i < 5; i++) { pURI = makeURI("http://" + (61 + i) + "-minutes-ago.com/"); places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(61 + i)}); olderURIs.push(pURI); } let promiseSanitized = promiseSanitizationComplete(); yield PlacesTestUtils.addVisits(places); - let totalHistoryVisits = uris.length + olderURIs.length; let wh = new WindowHelper(); wh.onload = function () { this.selectDuration(Sanitizer.TIMESPAN_HOUR); this.checkPrefCheckbox("history", true); this.acceptDialog(); }; wh.onunload = function* () {
--- a/browser/base/content/test/general/browser_save_video_frame.js +++ b/browser/base/content/test/general/browser_save_video_frame.js @@ -99,17 +99,16 @@ add_task(function*() { let tab = gBrowser.addTab(); gBrowser.selectedTab = tab; let browser = tab.linkedBrowser; info("Loading video tab"); yield promiseTabLoadEvent(tab, VIDEO_URL); info("Video tab loaded."); - let video = browser.contentDocument.getElementById("video1"); let context = document.getElementById("contentAreaContextMenu"); let popupPromise = promisePopupShown(context); info("Synthesizing right-click on video element"); rightClickVideo(browser); info("Waiting for popup to fire popupshown."); yield popupPromise; info("Popup fired popupshown");
--- a/browser/base/content/test/general/browser_tabDrop.js +++ b/browser/base/content/test/general/browser_tabDrop.js @@ -83,17 +83,16 @@ function* drop(dragData, expectedTabOpen var event = { clientX: 0, clientY: 0, screenX: 0, screenY: 0, }; EventUtils.synthesizeDrop(gBrowser.selectedTab, gBrowser.selectedTab, dragData, "link", window, undefined, event); let tabsOpened = false; - let tabOpened = false; if (awaitTabOpen) { yield awaitTabOpen; info("Got TabOpen event"); tabsOpened = true; for (let tab of openedTabs) { yield BrowserTestUtils.removeTab(tab); } }
--- a/browser/base/content/test/general/browser_tabfocus.js +++ b/browser/base/content/test/general/browser_tabfocus.js @@ -141,17 +141,16 @@ add_task(function*() { var childFocusScript = "data:,(" + focusInChild.toString() + ")();"; browser1.messageManager.loadFrameScript(childFocusScript, true); browser2.messageManager.loadFrameScript(childFocusScript, true); gURLBar.focus(); yield SimpleTest.promiseFocus(); - var messages = ""; if (gMultiProcessBrowser) { messageManager.addMessageListener("Browser:FocusChanged", message => { actualEvents.push(message.data.details); compareFocusResults(); }); } _lastfocus = "urlbar"; @@ -560,9 +559,8 @@ function* expectFocusShift(callback, exp // No events are expected, so resolve the promise immediately. if (expectedEvents["main-window"].length + expectedEvents["window1"].length + expectedEvents["window2"].length == 0) { currentPromiseResolver(); currentPromiseResolver = null; } }); } -
--- a/browser/base/content/test/general/browser_tabkeynavigation.js +++ b/browser/base/content/test/general/browser_tabkeynavigation.js @@ -135,17 +135,16 @@ add_task(function* test() { gBrowser.selectedTab = tab2; EventUtils.synthesizeKey("VK_F4", { type: "keydown", ctrlKey: true }); isnot(gBrowser.selectedTab, tab2, "Tab2 should be closed by pressing Ctrl+F4 on Tab2"); is(gBrowser.tabs.length, 3, "The count of tabs should be 3 since tab2 should be closed"); - let activeWindow = gBrowser.getBrowserForTab(gBrowser.selectedTab).contentWindow; // NOTE: keypress event shouldn't be fired since the keydown event should // be consumed by tab2. EventUtils.synthesizeKey("VK_F4", { type: "keyup", ctrlKey: true }); is(gBrowser.tabs.length, 3, "The count of tabs should be 3 since renaming key events shouldn't close other tabs"); } gBrowser.selectedTab = tab3;
--- a/browser/base/content/test/general/head.js +++ b/browser/base/content/test/general/head.js @@ -1052,17 +1052,17 @@ function getPropertyBagValue(bag, key) { * in expectedExtra. It's possible that the crash report * will contain other extra information that is not * compared against. * @returns Promise */ function promiseCrashReport(expectedExtra={}) { return Task.spawn(function*() { info("Starting wait on crash-report-status"); - let [subject, data] = + let [subject, ] = yield TestUtils.topicObserved("crash-report-status", (subject, data) => { return data == "success"; }); info("Topic observed!"); if (!(subject instanceof Ci.nsIPropertyBag2)) { throw new Error("Subject was not a Ci.nsIPropertyBag2"); }
--- a/browser/base/content/test/newtab/browser_newtab_bug991111.js +++ b/browser/base/content/test/newtab/browser_newtab_bug991111.js @@ -8,17 +8,16 @@ add_task(function* () { yield* addNewTabPageTab(); // we need a second newtab to honor max rows yield* addNewTabPageTab(); yield ContentTask.spawn(gBrowser.selectedBrowser, {index: 0}, function* (args) { let {site} = content.wrappedJSObject.gGrid.cells[args.index]; let origOnClick = site.onClick; - let clicked = false; site.onClick = e => { origOnClick.call(site, e); sendAsyncMessage("test:clicked-on-cell", {}); }; }); let mm = gBrowser.selectedBrowser.messageManager; let messagePromise = new Promise(resolve => {
--- a/browser/base/content/test/newtab/browser_newtab_bug991210.js +++ b/browser/base/content/test/newtab/browser_newtab_bug991210.js @@ -10,17 +10,17 @@ add_task(function* () { getLinks: function(callback) { this.callback = callback; }, addObserver: function() {}, }; NewTabUtils.links.addProvider(afterLoadProvider); // wait until about:newtab loads before calling provider callback - let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:newtab"); + yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:newtab"); afterLoadProvider.callback([]); yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () { let {_cellMargin, _cellHeight, _cellWidth, node} = content.gGrid; Assert.notEqual(_cellMargin, null, "grid has a computed cell margin"); Assert.notEqual(_cellHeight, null, "grid has a computed cell height"); Assert.notEqual(_cellWidth, null, "grid has a computed cell width");
--- a/browser/base/content/test/newtab/browser_newtab_bug998387.js +++ b/browser/base/content/test/newtab/browser_newtab_bug998387.js @@ -8,17 +8,16 @@ add_task(function* () { yield* addNewTabPageTab(); // we need a second newtab to honor max rows yield* addNewTabPageTab(); yield ContentTask.spawn(gBrowser.selectedBrowser, {index: 0}, function* (args) { let {site} = content.wrappedJSObject.gGrid.cells[args.index]; let origOnClick = site.onClick; - let clicked = false; site.onClick = e => { origOnClick.call(site, e); sendAsyncMessage("test:clicked-on-cell", {}); }; }); let mm = gBrowser.selectedBrowser.messageManager; let messagePromise = new Promise(resolve => { @@ -33,9 +32,8 @@ add_task(function* () { {button: 1}, gBrowser.selectedBrowser); yield messagePromise; ok(true, "middle click triggered click listener"); // Make sure the cell didn't actually get blocked yield* checkGrid("0"); }); -
--- a/browser/base/content/test/newtab/browser_newtab_enhanced.js +++ b/browser/base/content/test/newtab/browser_newtab_enhanced.js @@ -116,17 +116,16 @@ add_task(function* () { data = yield getData(1); is(data, null, "directory link still pushed out by pinned history link"); yield unpinCell(0); // Test that a suggested tile is not enhanced by a directory tile - let origIsTopPlacesSite = NewTabUtils.isTopPlacesSite; NewTabUtils.isTopPlacesSite = () => true; yield setLinks("-1,2,3,4,5,6,7,8"); // Test with enhanced = false yield* addNewTabPageTab(); ({type, enhanced, title, suggested} = yield getData(0)); isnot(type, "enhanced", "history link is not enhanced"); is(enhanced, "", "history link has no enhanced image");
--- a/browser/base/content/test/newtab/head.js +++ b/browser/base/content/test/newtab/head.js @@ -146,17 +146,17 @@ add_task(function* setup() { * @param aIndex index of cell * @param aFn function to call in child process or tab. * @returns result of calling the function. */ function performOnCell(aIndex, aFn) { return ContentTask.spawn(gWindow.gBrowser.selectedBrowser, { index: aIndex, fn: aFn.toString() }, function* (args) { let cell = content.gGrid.cells[args.index]; - return eval("(" + args.fn + ")(cell)"); + return eval(args.fn)(cell); }); } /** * Allows to provide a list of links that is used to construct the grid. * @param aLinksPattern the pattern (see below) * * Example: setLinks("-1,0,1,2,3") @@ -409,18 +409,16 @@ function* simulateExternalDrop(aDestInde return new Promise(resolve => { const url = "data:text/html;charset=utf-8," + "<a id='link' href='http://example99.com/'>link</a>"; let doc = content.document; let iframe = doc.createElement("iframe"); function iframeLoaded() { - let link = iframe.contentDocument.getElementById("link"); - let dataTransfer = new iframe.contentWindow.DataTransfer("dragstart", false); dataTransfer.mozSetDataAt("text/x-moz-url", "http://example99.com/", 0); let event = content.document.createEvent("DragEvent"); event.initDragEvent("drop", true, true, content, 0, 0, 0, 0, 0, false, false, false, false, 0, null, dataTransfer); let target = content.gGrid.cells[dropIndex].node;
--- a/browser/base/content/test/plugins/browser_CTP_crashreporting.js +++ b/browser/base/content/test/plugins/browser_CTP_crashreporting.js @@ -134,17 +134,17 @@ add_task(function*() { // And wait for the parent to say that the crash report was submitted // successfully. yield ContentTaskUtils.waitForCondition(() => { return statusDiv.getAttribute("status") == "success"; }, "Timed out waiting for plugin binding to be in success state"); }); - let [subject, data] = yield crashReportPromise; + let [subject, ] = yield crashReportPromise; ok(subject instanceof Ci.nsIPropertyBag, "The crash report subject should be an nsIPropertyBag."); let crashData = convertPropertyBag(subject); ok(crashData.serverCrashID, "Should have a serverCrashID set."); // Remove the submitted report file after ensuring it exists. @@ -206,17 +206,17 @@ add_task(function*() { // Then click the button to submit the crash report. let buttons = notification.querySelectorAll(".notification-button"); is(buttons.length, 2, "Should have two buttons."); // The "Submit Crash Report" button should be the second one. let submitButton = buttons[1]; submitButton.click(); - let [subject, data] = yield crashReportPromise; + let [subject, ] = yield crashReportPromise; ok(subject instanceof Ci.nsIPropertyBag, "The crash report subject should be an nsIPropertyBag."); let crashData = convertPropertyBag(subject); ok(crashData.serverCrashID, "Should have a serverCrashID set."); // Remove the submitted report file after ensuring it exists.
--- a/browser/base/content/test/plugins/browser_pageInfo_plugins.js +++ b/browser/base/content/test/plugins/browser_pageInfo_plugins.js @@ -75,17 +75,16 @@ function testPart1a() { doOnOpenPageInfo(testPart1b); } function testPart1b() { let testRadioGroup = gPageInfo.document.getElementById(gTestPermissionString + "RadioGroup"); let testRadioDefault = gPageInfo.document.getElementById(gTestPermissionString + "#0"); - var qString = "#" + gTestPermissionString.replace(':', '\\:') + "\\#0"; is(testRadioGroup.selectedItem, testRadioDefault, "part 1b: Test radio group should be set to 'Default'"); let testRadioAllow = gPageInfo.document.getElementById(gTestPermissionString + "#1"); testRadioGroup.selectedItem = testRadioAllow; testRadioAllow.doCommand(); let secondtestRadioGroup = gPageInfo.document.getElementById(gSecondTestPermissionString + "RadioGroup"); let secondtestRadioDefault = gPageInfo.document.getElementById(gSecondTestPermissionString + "#0"); is(secondtestRadioGroup.selectedItem, secondtestRadioDefault, "part 1b: Second Test radio group should be set to 'Default'");
--- a/browser/base/content/test/plugins/browser_pluginnotification.js +++ b/browser/base/content/test/plugins/browser_pluginnotification.js @@ -282,18 +282,16 @@ add_task(function* () { let pluginInfo = yield promiseForPluginInfo("test"); ok(!pluginInfo.activated, "Test 18g, Plugin should not be activated"); ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed, "Test 19e, Doorhanger should start out dismissed"); yield ContentTask.spawn(gTestBrowser, null, function* () { - let doc = content.document; - let plugin = doc.getElementById("test"); let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIDOMWindowUtils); utils.sendMouseEvent("mousedown", 50, 50, 0, 1, 0, false, 0, 0); utils.sendMouseEvent("mouseup", 50, 50, 0, 1, 0, false, 0, 0); }); let condition = () => !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed && PopupNotifications.panel.firstChild;
--- a/browser/base/content/test/plugins/head.js +++ b/browser/base/content/test/plugins/head.js @@ -10,18 +10,18 @@ XPCOMUtils.defineLazyModuleGetter(this, // The blocklist shim running in the content process does not initialize at // start up, so it's not active until we load content that needs to do a // check. This helper bypasses the delay to get the svc up and running // immediately. Note, call this after remote content has loaded. function promiseInitContentBlocklistSvc(aBrowser) { return ContentTask.spawn(aBrowser, {}, function* () { try { - let bls = Cc["@mozilla.org/extensions/blocklist;1"] - .getService(Ci.nsIBlocklistService); + Cc["@mozilla.org/extensions/blocklist;1"] + .getService(Ci.nsIBlocklistService); } catch (ex) { return ex.message; } return null; }); } /** @@ -203,17 +203,16 @@ function promisePlayObject(aId, aBrowser objLoadingContent.playPlugin(); }); } function promiseCrashObject(aId, aBrowser) { let browser = aBrowser || gTestBrowser; return ContentTask.spawn(browser, aId, function* (aId) { let plugin = content.document.getElementById(aId); - let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent); Components.utils.waiveXrays(plugin).crash(); }); } // Return a promise and call the plugin's getObjectValue() method. function promiseObjectValueResult(aId, aBrowser) { let browser = aBrowser || gTestBrowser; return ContentTask.spawn(browser, aId, function* (aId) {
--- a/browser/base/content/test/popupNotifications/browser_popupNotification_4.js +++ b/browser/base/content/test/popupNotifications/browser_popupNotification_4.js @@ -98,17 +98,16 @@ var tests = [ // Moving a tab to a new window should remove non-swappable notifications. { id: "Test#5", run: function() { gBrowser.selectedTab = gBrowser.addTab("about:blank"); let notifyObj = new BasicNotification(this.id); showNotification(notifyObj); let win = gBrowser.replaceTabWithWindow(gBrowser.selectedTab); whenDelayedStartupFinished(win, function() { - let [tab] = win.gBrowser.tabs; let anchor = win.document.getElementById("default-notification-icon"); win.PopupNotifications._reshowNotifications(anchor); ok(win.PopupNotifications.panel.childNodes.length == 0, "no notification displayed in new window"); ok(notifyObj.swappingCallbackTriggered, "the swapping callback was triggered"); ok(notifyObj.removedCallbackTriggered, "the removed callback was triggered"); win.close(); goNext(); @@ -127,18 +126,16 @@ var tests = [ notifyObj.options.eventCallback = function (eventName) { originalCallback(eventName); return eventName == "swapping"; }; let notification = showNotification(notifyObj); let win = gBrowser.replaceTabWithWindow(gBrowser.selectedTab); yield whenDelayedStartupFinished(win); - let [tab] = win.gBrowser.tabs; - let anchor = win.document.getElementById("default-notification-icon"); yield new Promise(resolve => { let originalCallback = notification.options.eventCallback; notification.options.eventCallback = function (eventName) { originalCallback(eventName); if (eventName == "shown") { resolve(); }
--- a/browser/base/content/test/social/browser_addons.js +++ b/browser/base/content/test/social/browser_addons.js @@ -194,17 +194,16 @@ var tests = { AddonManager.addAddonListener(installListener(next, manifest2)); BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown").then(() => { let panel = document.getElementById("servicesInstall-notification"); info("servicesInstall-notification panel opened"); panel.button.click(); }); - let activationURL = manifest2.origin + "/browser/browser/base/content/test/social/social_activate.html" Services.prefs.setCharPref("social.directories", manifest2.origin); is(SocialService.getOriginActivationType(manifest2.origin), "directory", "testing directory install"); let data = { origin: manifest2.origin, url: manifest2.origin + "/directory", manifest: manifest2, window: window }
--- a/browser/base/content/test/social/browser_share.js +++ b/browser/base/content/test/social/browser_share.js @@ -113,17 +113,16 @@ var corpus = [ previews: ["http://example.com/1234/56789.jpg"], url: "http://www.example.com/photos/56789/", shortUrl: "http://imshort/p/abcde" } } ]; function hasoptions(testOptions, options) { - let msg; for (let option in testOptions) { let data = testOptions[option]; info("data: "+JSON.stringify(data)); let message_data = options[option]; info("message_data: "+JSON.stringify(message_data)); if (Array.isArray(data)) { // the message may have more array elements than we are testing for, this // is ok since some of those are hard to test. So we just test that @@ -177,18 +176,16 @@ var tests = { ok(!shareButton.hasAttribute("disabled"), "share button is enabled"); // button should be visible is(shareButton.hidden, false, "share button is visible"); BrowserTestUtils.removeTab(tab).then(next); }); }); }, testSharePage: function(next) { - let provider = Social._getProviderFromOrigin(manifest.origin); - let testTab; let testIndex = 0; let testData = corpus[testIndex++]; // initialize the button into the navbar CustomizableUI.addWidgetToArea("social-share-button", CustomizableUI.AREA_NAVBAR); // ensure correct state SocialUI.onCustomizeEnd(window);
--- a/browser/base/content/test/social/head.js +++ b/browser/base/content/test/social/head.js @@ -105,17 +105,16 @@ function runSocialTestWithProvider(manif removeProvider(m.origin, callback); }); } function finishSocialTest(cleanup) { removeAddedProviders(cleanup); } let providersAdded = 0; - let firstProvider; manifests.forEach(function (m) { SocialService.addProvider(m, function(provider) { providersAdded++; info("runSocialTestWithProvider: provider added"); // we want to set the first specified provider as the UI's provider
--- a/browser/base/content/test/urlbar/browser_autocomplete_a11y_label.js +++ b/browser/base/content/test/urlbar/browser_autocomplete_a11y_label.js @@ -4,17 +4,16 @@ const SUGGEST_ALL_PREF = "browser.search.suggest.enabled"; const SUGGEST_URLBAR_PREF = "browser.urlbar.suggest.searches"; const TEST_ENGINE_BASENAME = "searchSuggestionEngine.xml"; add_task(function* switchToTab() { let tab = gBrowser.addTab("about:about"); yield promiseTabLoaded(tab); - let actionURL = makeActionURI("switchtab", {url: "about:about"}).spec; yield promiseAutocompleteResultPopup("% about"); ok(gURLBar.popup.richlistbox.children.length > 1, "Should get at least 2 results"); let result = gURLBar.popup.richlistbox.children[1]; is(result.getAttribute("type"), "switchtab", "Expect right type attribute"); is(result.label, "about:about about:about Tab", "Result a11y label should be: <title> <url> Tab"); gURLBar.popup.hidePopup();
--- a/browser/base/content/test/urlbar/browser_bug1104165-switchtab-decodeuri.js +++ b/browser/base/content/test/urlbar/browser_bug1104165-switchtab-decodeuri.js @@ -1,15 +1,15 @@ add_task(function* test_switchtab_decodeuri() { info("Opening first tab"); let tab = gBrowser.addTab("http://example.org/browser/browser/base/content/test/urlbar/dummy_page.html#test%7C1"); yield promiseTabLoadEvent(tab); info("Opening and selecting second tab"); - let newTab = gBrowser.selectedTab = gBrowser.addTab(); + gBrowser.selectedTab = gBrowser.addTab(); info("Wait for autocomplete") yield promiseAutocompleteResultPopup("dummy_page"); info("Select autocomplete popup entry"); EventUtils.synthesizeKey("VK_DOWN", {}); ok(gURLBar.value.startsWith("moz-action:switchtab"), "switch to tab entry found");
--- a/browser/base/content/test/urlbar/browser_search_favicon.js +++ b/browser/base/content/test/urlbar/browser_search_favicon.js @@ -20,17 +20,17 @@ add_task(function*() { gEngine = Services.search.getEngineByName("SearchEngine"); gEngine.addParam("q", "{searchTerms}", null); gOriginalEngine = Services.search.currentEngine; Services.search.currentEngine = gEngine; let uri = NetUtil.newURI("http://s.example.com/search?q=foo&client=1"); yield PlacesTestUtils.addVisits({ uri: uri, title: "Foo - SearchEngine Search" }); - let tab = gBrowser.selectedTab = gBrowser.addTab("about:mozilla", {animate: false}); + gBrowser.selectedTab = gBrowser.addTab("about:mozilla", {animate: false}); yield promiseTabLoaded(gBrowser.selectedTab); // The first autocomplete result has the action searchengine, while // the second result is the "search favicon" element. yield promiseAutocompleteResultPopup("foo"); let result = gURLBar.popup.richlistbox.children[1]; isnot(result, null, "Expect a search result");
--- a/browser/base/content/test/urlbar/browser_tabMatchesInAwesomebar_perwindowpb.js +++ b/browser/base/content/test/urlbar/browser_tabMatchesInAwesomebar_perwindowpb.js @@ -18,17 +18,17 @@ add_task(function*() { yield BrowserTestUtils.closeWindow(privateWindow); normalWindow = yield BrowserTestUtils.openNewBrowserWindow(); yield runTest(normalWindow, normalWindow, true); yield BrowserTestUtils.closeWindow(normalWindow); }); function* runTest(aSourceWindow, aDestWindow, aExpectSwitch, aCallback) { - let baseTab = yield BrowserTestUtils.openNewForegroundTab(aSourceWindow.gBrowser, testURL); + yield BrowserTestUtils.openNewForegroundTab(aSourceWindow.gBrowser, testURL); let testTab = yield BrowserTestUtils.openNewForegroundTab(aDestWindow.gBrowser); info("waiting for focus on the window"); yield SimpleTest.promiseFocus(aDestWindow); info("got focus on the window"); // Select the testTab aDestWindow.gBrowser.selectedTab = testTab;
--- a/browser/base/content/test/urlbar/browser_urlbarDecode.js +++ b/browser/base/content/test/urlbar/browser_urlbarDecode.js @@ -45,17 +45,17 @@ add_task(function* actionURILosslessDeco // simply `url`. Key down and back around until the heuristic result is // selected again, and at that point the urlbar's value should be a visiturl // moz-action. do { gURLBar.controller.handleKeyNavigation(KeyEvent.DOM_VK_DOWN); } while (gURLBar.popup.selectedIndex != 0); - let [, type, params] = gURLBar.value.match(/^moz-action:([^,]+),(.*)$/); + let [, type, ] = gURLBar.value.match(/^moz-action:([^,]+),(.*)$/); Assert.equal(type, "visiturl", "visiturl action URI should be in the urlbar"); Assert.equal(gURLBar.inputField.value, urlNoScheme, "The string displayed in the textbox should not be escaped"); gURLBar.value = ""; gURLBar.handleRevert();
--- a/browser/base/content/test/urlbar/browser_urlbarEnterAfterMouseOver.js +++ b/browser/base/content/test/urlbar/browser_urlbarEnterAfterMouseOver.js @@ -18,17 +18,16 @@ function is_selected(index) { let gMaxResults; add_task(function*() { registerCleanupFunction(function* () { yield PlacesTestUtils.clearHistory(); }); yield PlacesTestUtils.clearHistory(); - let tabCount = gBrowser.tabs.length; gMaxResults = Services.prefs.getIntPref("browser.urlbar.maxRichResults"); let visits = []; repeat(gMaxResults, i => { visits.push({ uri: makeURI("http://example.com/autocomplete/?" + i), });
--- a/browser/base/content/test/urlbar/browser_urlbarPrivateBrowsingWindowChange.js +++ b/browser/base/content/test/urlbar/browser_urlbarPrivateBrowsingWindowChange.js @@ -2,18 +2,16 @@ /** * Test that when opening a private browsing window and typing in it before about:privatebrowsing * loads, we don't clear the URL bar. */ add_task(function*() { let urlbarTestValue = "Mary had a little lamb"; let win = OpenBrowserWindow({private: true}); - let delayedStartupFinished = TestUtils.topicObserved("browser-delayed-startup-finished", - subject => subject == win); yield BrowserTestUtils.waitForEvent(win, "load"); let urlbar = win.document.getElementById("urlbar"); urlbar.value = urlbarTestValue; // Need this so the autocomplete controller attaches: let focusEv = new FocusEvent("focus", {}); urlbar.dispatchEvent(focusEv); // And so we know input happened: let inputEv = new InputEvent("input", {data: "", view: win, bubbles: true});
--- a/browser/base/content/test/urlbar/browser_urlbarSearchSuggestions.js +++ b/browser/base/content/test/urlbar/browser_urlbarSearchSuggestions.js @@ -37,17 +37,16 @@ add_task(function* clickSuggestion() { Assert.ok(uri.equals(gBrowser.currentURI), "The search results page should have loaded"); gBrowser.removeTab(gBrowser.selectedTab); }); function getFirstSuggestion() { let controller = gURLBar.popup.input.controller; let matchCount = controller.matchCount; - let present = false; for (let i = 0; i < matchCount; i++) { let url = controller.getValueAt(i); let mozActionMatch = url.match(/^moz-action:([^,]+),(.*)$/); if (mozActionMatch) { let [, type, paramStr] = mozActionMatch; let params = JSON.parse(paramStr); if (type == "searchengine" && "searchSuggestion" in params) { return [i, params.searchSuggestion, params.engineName];
--- a/browser/base/content/test/urlbar/browser_urlbarSearchSuggestionsNotification.js +++ b/browser/base/content/test/urlbar/browser_urlbarSearchSuggestionsNotification.js @@ -216,17 +216,16 @@ function setUserMadeChoicePref(userMadeC resolve(); } }); } function suggestionsPresent() { let controller = gURLBar.popup.input.controller; let matchCount = controller.matchCount; - let present = false; for (let i = 0; i < matchCount; i++) { let url = controller.getValueAt(i); let mozActionMatch = url.match(/^moz-action:([^,]+),(.*)$/); if (mozActionMatch) { let [, type, paramStr] = mozActionMatch; let params = JSON.parse(paramStr); if (type == "searchengine" && "searchSuggestion" in params) { return true;
--- a/browser/base/content/urlbarBindings.xml +++ b/browser/base/content/urlbarBindings.xml @@ -72,17 +72,16 @@ file, You can obtain one at http://mozil this.inputField.controllers.insertControllerAt(0, this._copyCutController); this.inputField.addEventListener("paste", this, false); this.inputField.addEventListener("mousedown", this, false); this.inputField.addEventListener("mousemove", this, false); this.inputField.addEventListener("mouseout", this, false); this.inputField.addEventListener("overflow", this, false); this.inputField.addEventListener("underflow", this, false); - const kXULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; var textBox = document.getAnonymousElementByAttribute(this, "anonid", "textbox-input-box"); var cxmenu = document.getAnonymousElementByAttribute(textBox, "anonid", "input-box-contextmenu"); var pasteAndGo; cxmenu.addEventListener("popupshowing", function() { if (!pasteAndGo) return; @@ -2336,17 +2335,17 @@ file, You can obtain one at http://mozil </method> <method name="_setupSingleState"> <body><![CDATA[ var action = this._items[0].action; var prePath = action.pluginPermissionPrePath; let chromeWin = window.QueryInterface(Ci.nsIDOMChromeWindow); let isWindowPrivate = PrivateBrowsingUtils.isWindowPrivate(chromeWin); - let label, linkLabel, linkUrl, button1, button2; + let label, linkLabel, button1, button2; if (action.fallbackType == Ci.nsIObjectLoadingContent.PLUGIN_ACTIVE) { button1 = { label: "pluginBlockNow.label", accesskey: "pluginBlockNow.accesskey", action: "_singleBlock" }; button2 = { @@ -2463,17 +2462,16 @@ file, You can obtain one at http://mozil } ]]></body> </method> <method name="_setupDescription"> <parameter name="baseString" /> <parameter name="pluginName" /> <!-- null for the multiple-plugin case --> <parameter name="prePath" /> <body><![CDATA[ - var bsn = this._brandShortName; var span = document.getAnonymousElementByAttribute(this, "anonid", "click-to-play-plugins-notification-description"); while (span.lastChild) { span.removeChild(span.lastChild); } var args = ["__prepath__", this._brandShortName]; if (pluginName) { args.unshift(pluginName);
--- a/browser/components/extensions/ext-tabs.js +++ b/browser/components/extensions/ext-tabs.js @@ -70,24 +70,18 @@ extensions.on("page-shutdown", (type, co let tab = gBrowser.getTabForBrowser(context.xulBrowser); if (tab) { gBrowser.removeTab(tab); } } } }); -extensions.on("fill-browser-data", (type, browser, data, result) => { - let tabId = TabManager.getBrowserId(browser); - if (tabId == -1) { - result.cancel = true; - return; - } - - data.tabId = tabId; +extensions.on("fill-browser-data", (type, browser, data) => { + data.tabId = browser ? TabManager.getBrowserId(browser) : -1; }); /* eslint-enable mozilla/balanced-listeners */ global.currentWindow = function(context) { let {xulWindow} = context; if (xulWindow && context.viewType != "background") { return xulWindow; }
--- a/browser/components/migration/360seProfileMigrator.js +++ b/browser/components/migration/360seProfileMigrator.js @@ -150,25 +150,25 @@ Bookmarks.prototype = { parentGuid = yield MigrationUtils.createImportedBookmarksFolder("360se", parentGuid); } idToGuid.set("fallback", parentGuid); } try { if (is_folder == 1) { - let newFolderGuid = (yield PlacesUtils.bookmarks.insert({ + let newFolderGuid = (yield MigrationUtils.insertBookmarkWrapper({ parentGuid, type: PlacesUtils.bookmarks.TYPE_FOLDER, title })).guid; idToGuid.set(id, newFolderGuid); } else { - yield PlacesUtils.bookmarks.insert({ + yield MigrationUtils.insertBookmarkWrapper({ parentGuid, url, title }); } } catch (ex) { Cu.reportError(ex); }
--- a/browser/components/migration/ChromeProfileMigrator.js +++ b/browser/components/migration/ChromeProfileMigrator.js @@ -83,21 +83,21 @@ function* insertBookmarkItems(parentGuid for (let item of items) { try { if (item.type == "url") { if (item.url.trim().startsWith("chrome:")) { // Skip invalid chrome URIs. Creating an actual URI always reports // messages to the console, so we avoid doing that. continue; } - yield PlacesUtils.bookmarks.insert({ + yield MigrationUtils.insertBookmarkWrapper({ parentGuid, url: item.url, title: item.name }); } else if (item.type == "folder") { - let newFolderGuid = (yield PlacesUtils.bookmarks.insert({ + let newFolderGuid = (yield MigrationUtils.insertBookmarkWrapper({ parentGuid, type: PlacesUtils.bookmarks.TYPE_FOLDER, title: item.name })).guid; yield insertBookmarkItems(newFolderGuid, item.children, errorAccumulator); } } catch (e) { Cu.reportError(e); errorAccumulator(e); @@ -334,17 +334,17 @@ function GetHistoryResource(aProfileFold }); } catch (e) { Cu.reportError(e); } } if (places.length > 0) { yield new Promise((resolve, reject) => { - PlacesUtils.asyncHistory.updatePlaces(places, { + MigrationUtils.insertVisitsWrapper(places, { _success: false, handleResult: function() { // Importing any entry is considered a successful import. this._success = true; }, handleError: function() {}, handleCompletion: function() { if (this._success) { @@ -442,17 +442,17 @@ function GetWindowsPasswordsResource(aPr let crypto = new OSCrypto(); for (let row of rows) { let loginInfo = { username: row.getResultByName("username_value"), password: crypto. decryptData(crypto.arrayToString(row.getResultByName("password_value")), null), - hostName: NetUtil.newURI(row.getResultByName("origin_url")).prePath, + hostname: NetUtil.newURI(row.getResultByName("origin_url")).prePath, submitURL: null, httpRealm: null, usernameElement: row.getResultByName("username_element"), passwordElement: row.getResultByName("password_element"), timeCreated: chromeTimeToDate(row.getResultByName("date_created") + 0).getTime(), timesUsed: row.getResultByName("times_used") + 0, }; @@ -460,42 +460,23 @@ function GetWindowsPasswordsResource(aPr switch (row.getResultByName("scheme")) { case AUTH_TYPE.SCHEME_HTML: loginInfo.submitURL = NetUtil.newURI(row.getResultByName("action_url")).prePath; break; case AUTH_TYPE.SCHEME_BASIC: case AUTH_TYPE.SCHEME_DIGEST: // signon_realm format is URIrealm, so we need remove URI loginInfo.httpRealm = row.getResultByName("signon_realm") - .substring(loginInfo.hostName.length + 1); + .substring(loginInfo.hostname.length + 1); break; default: throw new Error("Login data scheme type not supported: " + row.getResultByName("scheme")); } - let login = Cc["@mozilla.org/login-manager/loginInfo;1"].createInstance(Ci.nsILoginInfo); - - login.init(loginInfo.hostName, loginInfo.submitURL, loginInfo.httpRealm, - loginInfo.username, loginInfo.password, loginInfo.usernameElement, - loginInfo.passwordElement); - login.QueryInterface(Ci.nsILoginMetaInfo); - login.timeCreated = loginInfo.timeCreated; - login.timeLastUsed = loginInfo.timeCreated; - login.timePasswordChanged = loginInfo.timeCreated; - login.timesUsed = loginInfo.timesUsed; - - // Add the login only if there's not an existing entry - let logins = Services.logins.findLogins({}, login.hostname, - login.formSubmitURL, - login.httpRealm); - - // Bug 1187190: Password changes should be propagated depending on timestamps. - if (!logins.some(l => login.matches(l, true))) { - Services.logins.addLogin(login); - } + MigrationUtils.insertLoginWrapper(loginInfo); } catch (e) { Cu.reportError(e); } } crypto.finalize(); aCallback(true); }), };
--- a/browser/components/migration/EdgeProfileMigrator.js +++ b/browser/components/migration/EdgeProfileMigrator.js @@ -133,17 +133,17 @@ EdgeTypedURLMigrator.prototype = { }); } if (places.length == 0) { aCallback(typedURLs.size == 0); return; } - PlacesUtils.asyncHistory.updatePlaces(places, { + MigrationUtils.insertVisitsWrapper(places, { _success: false, handleResult: function() { // Importing any entry is considered a successful import. this._success = true; }, handleError: function() {}, handleCompletion: function() { aCallback(this._success); @@ -196,17 +196,17 @@ EdgeReadingListMigrator.prototype = { if (!readingListItems.length) { return; } let destFolderGuid = yield this._ensureReadingListFolder(parentGuid); let exceptionThrown; for (let item of readingListItems) { let dateAdded = item.AddedDate || new Date(); - yield PlacesUtils.bookmarks.insert({ + yield MigrationUtils.insertBookmarkWrapper({ parentGuid: destFolderGuid, url: item.URL, title: item.Title, dateAdded }).catch(ex => { if (!exceptionThrown) { exceptionThrown = ex; } Cu.reportError(ex); }); } @@ -214,17 +214,17 @@ EdgeReadingListMigrator.prototype = { throw exceptionThrown; } }), _ensureReadingListFolder: Task.async(function*(parentGuid) { if (!this.__readingListFolderGuid) { let folderTitle = MigrationUtils.getLocalizedString("importedEdgeReadingList"); let folderSpec = {type: PlacesUtils.bookmarks.TYPE_FOLDER, parentGuid, title: folderTitle}; - this.__readingListFolderGuid = (yield PlacesUtils.bookmarks.insert(folderSpec)).guid; + this.__readingListFolderGuid = (yield MigrationUtils.insertBookmarkWrapper(folderSpec)).guid; } return this.__readingListFolderGuid; }), }; function EdgeBookmarksMigrator(dbOverride) { this.dbOverride = dbOverride; } @@ -317,17 +317,17 @@ EdgeBookmarksMigrator.prototype = { } let placesInfo = { parentGuid, url: bookmark.URL, dateAdded: bookmark.DateUpdated || new Date(), title: bookmark.Title, }; - yield PlacesUtils.bookmarks.insert(placesInfo).catch(ex => { + yield MigrationUtils.insertBookmarkWrapper(placesInfo).catch(ex => { if (!exceptionThrown) { exceptionThrown = ex; } Cu.reportError(ex); }); } if (exceptionThrown) { @@ -385,17 +385,17 @@ EdgeBookmarksMigrator.prototype = { let parentGuid = yield this._getGuidForFolder(folder.ParentId, folderMap, rootGuid); let folderInfo = { title: folder.Title, type: PlacesUtils.bookmarks.TYPE_FOLDER, dateAdded: folder.DateUpdated || new Date(), parentGuid, }; // and add ourselves as a kid, and return the guid we got. - let parentBM = yield PlacesUtils.bookmarks.insert(folderInfo); + let parentBM = yield MigrationUtils.insertBookmarkWrapper(folderInfo); folder._guid = parentBM.guid; return folder._guid; }), }; function EdgeProfileMigrator() { this.wrappedJSObject = this; }
--- a/browser/components/migration/IEProfileMigrator.js +++ b/browser/components/migration/IEProfileMigrator.js @@ -14,17 +14,16 @@ const kMainKey = "Software\\Microsoft\\I Cu.import("resource://gre/modules/AppConstants.jsm"); Cu.import("resource://gre/modules/osfile.jsm"); /* globals OS */ Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Task.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource:///modules/MigrationUtils.jsm"); /* globals MigratorPrototype */ Cu.import("resource:///modules/MSMigrationUtils.jsm"); -Cu.import("resource://gre/modules/LoginHelper.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "ctypes", "resource://gre/modules/ctypes.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils", "resource://gre/modules/PlacesUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "OSCrypto", "resource://gre/modules/OSCrypto.jsm"); @@ -88,17 +87,17 @@ History.prototype = { } // Check whether there is any history to import. if (places.length == 0) { aCallback(true); return; } - PlacesUtils.asyncHistory.updatePlaces(places, { + MigrationUtils.insertVisitsWrapper(places, { _success: false, handleResult: function() { // Importing any entry is considered a successful import. this._success = true; }, handleError: function() {}, handleCompletion: function() { aCallback(this._success); @@ -244,17 +243,17 @@ IE7FormPasswords.prototype = { try { // create a new login let login = { username: ieLogin.username, password: ieLogin.password, hostname: ieLogin.url, timeCreated: ieLogin.creation, }; - LoginHelper.maybeImportLogin(login); + MigrationUtils.insertLoginWrapper(login); } catch (e) { Cu.reportError(e); } } }, /** * Extract the details of one or more logins from the raw decrypted data.
--- a/browser/components/migration/MSMigrationUtils.jsm +++ b/browser/components/migration/MSMigrationUtils.jsm @@ -8,17 +8,16 @@ this.EXPORTED_SYMBOLS = ["MSMigrationUti const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; Cu.import("resource://gre/modules/AppConstants.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Task.jsm"); Cu.import("resource:///modules/MigrationUtils.jsm"); -Cu.import("resource://gre/modules/LoginHelper.jsm"); Cu.importGlobalProperties(["FileReader"]); XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils", "resource://gre/modules/PlacesUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "WindowsRegistry", "resource://gre/modules/WindowsRegistry.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "ctypes", @@ -402,17 +401,17 @@ Bookmarks.prototype = { folderGuid = PlacesUtils.bookmarks.toolbarGuid; if (!MigrationUtils.isStartupMigration) { folderGuid = yield MigrationUtils.createImportedBookmarksFolder(this.importedAppLabel, folderGuid); } } else { // Import to a new folder. - folderGuid = (yield PlacesUtils.bookmarks.insert({ + folderGuid = (yield MigrationUtils.insertBookmarkWrapper({ type: PlacesUtils.bookmarks.TYPE_FOLDER, parentGuid: aDestFolderGuid, title: entry.leafName })).guid; } if (entry.isReadable()) { // Recursively import the folder. @@ -424,17 +423,17 @@ Bookmarks.prototype = { // and get the associated title. let matches = entry.leafName.match(/(.+)\.url$/i); if (matches) { let fileHandler = Cc["@mozilla.org/network/protocol;1?name=file"]. getService(Ci.nsIFileProtocolHandler); let uri = fileHandler.readURLFile(entry); let title = matches[1]; - yield PlacesUtils.bookmarks.insert({ + yield MigrationUtils.insertBookmarkWrapper({ parentGuid: aDestFolderGuid, url: uri, title }); } } } catch (ex) { Components.utils.reportError("Unable to import " + this.importedAppLabel + " favorite (" + entry.leafName + "): " + ex); succeeded = false; } @@ -833,17 +832,17 @@ WindowsVaultFormPasswords.prototype = { // Ignore exceptions in the dates and just create the login for right now. } // create a new login let login = { username, password, hostname: realURL.prePath, timeCreated: creation, }; - LoginHelper.maybeImportLogin(login); + MigrationUtils.insertLoginWrapper(login); // close current item error = ctypesVaultHelpers._functions.VaultFree(credential); if (error == FREE_CLOSE_FAILED) { throw new Error("Unable to free item: " + error); } } catch (e) { migrationSucceeded = false;
--- a/browser/components/migration/MigrationUtils.jsm +++ b/browser/components/migration/MigrationUtils.jsm @@ -15,16 +15,18 @@ Cu.import("resource://gre/modules/AppCon Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Task.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "AutoMigrate", "resource:///modules/AutoMigrate.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "BookmarkHTMLUtils", "resource://gre/modules/BookmarkHTMLUtils.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "LoginHelper", + "resource://gre/modules/LoginHelper.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils", "resource://gre/modules/PlacesUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "PromiseUtils", "resource://gre/modules/PromiseUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "Sqlite", "resource://gre/modules/Sqlite.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "TelemetryStopwatch", "resource://gre/modules/TelemetryStopwatch.jsm"); @@ -249,16 +251,27 @@ this.MigratorPrototype = { }; let maybeStopTelemetryStopwatch = (resourceType, resource) => { let histogram = getHistogramForResourceType(resourceType); if (histogram) { TelemetryStopwatch.finishKeyed(histogram, this.getKey(), resource); } }; + let collectQuantityTelemetry = () => { + try { + for (let resourceType of Object.keys(MigrationUtils._importQuantities)) { + let histogramId = + "FX_MIGRATION_" + resourceType.toUpperCase() + "_QUANTITY"; + let histogram = Services.telemetry.getKeyedHistogram(histogramId); + histogram.add(this.getKey(), MigrationUtils._importQuantities[resourceType]); + } + } catch (ex) { /* Telemetry is exception-happy */ } + }; + // Called either directly or through the bookmarks import callback. let doMigrate = Task.async(function*() { let resourcesGroupedByItems = new Map(); resources.forEach(function(resource) { if (!resourcesGroupedByItems.has(resource.type)) { resourcesGroupedByItems.set(resource.type, new Set()); } resourcesGroupedByItems.get(resource.type).add(resource); @@ -266,16 +279,19 @@ this.MigratorPrototype = { if (resourcesGroupedByItems.size == 0) throw new Error("No items to import"); let notify = function(aMsg, aItemType) { Services.obs.notifyObservers(null, aMsg, aItemType); }; + for (let resourceType of Object.keys(MigrationUtils._importQuantities)) { + MigrationUtils._importQuantities[resourceType] = 0; + } notify("Migration:Started"); for (let [key, value] of resourcesGroupedByItems) { // Workaround bug 449811. let migrationType = key, itemResources = value; notify("Migration:ItemBeforeMigrate", migrationType); let itemSuccess = false; @@ -289,16 +305,17 @@ this.MigratorPrototype = { itemResources.delete(resource); itemSuccess |= aSuccess; if (itemResources.size == 0) { notify(itemSuccess ? "Migration:ItemAfterMigrate" : "Migration:ItemError", migrationType); resourcesGroupedByItems.delete(migrationType); if (resourcesGroupedByItems.size == 0) { + collectQuantityTelemetry(); notify("Migration:Ended"); } } completeDeferred.resolve(); }; // If migrate throws, an error occurred, and the callback // (itemMayBeDone) might haven't been called. @@ -669,30 +686,35 @@ this.MigrationUtils = Object.freeze({ */ getMigratorKeyForDefaultBrowser() { // Canary uses the same description as Chrome so we can't distinguish them. const APP_DESC_TO_KEY = { "Internet Explorer": "ie", "Microsoft Edge": "edge", "Safari": "safari", "Firefox": "firefox", + "Nightly": "firefox", "Google Chrome": "chrome", // Windows, Linux "Chrome": "chrome", // OS X "Chromium": "chromium", // Windows, OS X "Chromium Web Browser": "chromium", // Linux "360\u5b89\u5168\u6d4f\u89c8\u5668": "360se", }; let key = ""; try { let browserDesc = Cc["@mozilla.org/uriloader/external-protocol-service;1"] .getService(Ci.nsIExternalProtocolService) .getApplicationDescription("http"); key = APP_DESC_TO_KEY[browserDesc] || ""; + // Handle devedition, as well as "FirefoxNightly" on OS X. + if (!key && browserDesc.startsWith("Firefox")) { + key = "firefox"; + } } catch (ex) { Cu.reportError("Could not detect default browser: " + ex); } // "firefox" is the least useful entry here, and might just be because we've set // ourselves as the default (on Windows 7 and below). In that case, check if we // have a registry key that tells us where to go: @@ -902,16 +924,37 @@ this.MigrationUtils = Object.freeze({ migrator, aProfileStartup, skipSourcePage, aProfileToMigrate, ]; this.showMigrationWizard(null, params); }, + _importQuantities: { + bookmarks: 0, + logins: 0, + history: 0, + }, + + insertBookmarkWrapper(bookmark) { + this._importQuantities.bookmarks++; + return PlacesUtils.bookmarks.insert(bookmark); + }, + + insertVisitsWrapper(places, options) { + this._importQuantities.history += places.length; + return PlacesUtils.asyncHistory.updatePlaces(places, options); + }, + + insertLoginWrapper(login) { + this._importQuantities.logins++; + return LoginHelper.maybeImportLogin(login); + }, + /** * Cleans up references to migrators and nsIProfileInstance instances. */ finishMigration: function MU_finishMigration() { gMigrators = null; gProfileStartup = null; gMigrationBundle = null; },
--- a/browser/components/migration/SafariProfileMigrator.js +++ b/browser/components/migration/SafariProfileMigrator.js @@ -126,17 +126,17 @@ Bookmarks.prototype = { yield MigrationUtils.createImportedBookmarksFolder("Safari", folderGuid); } break; } case this.READING_LIST_COLLECTION: { // Reading list items are imported as regular bookmarks. // They are imported under their own folder, created either under the // bookmarks menu (in the case of startup migration). - folderGuid = (yield PlacesUtils.bookmarks.insert({ + folderGuid = (yield MigrationUtils.insertBookmarkWrapper({ parentGuid: PlacesUtils.bookmarks.menuGuid, type: PlacesUtils.bookmarks.TYPE_FOLDER, title: MigrationUtils.getLocalizedString("importedSafariReadingList"), })).guid; break; } default: throw new Error("Unexpected value for aCollection!"); @@ -149,31 +149,31 @@ Bookmarks.prototype = { // migrate the given array of safari bookmarks to the given places // folder. _migrateEntries: Task.async(function* (entries, parentGuid) { for (let entry of entries) { let type = entry.get("WebBookmarkType"); if (type == "WebBookmarkTypeList" && entry.has("Children")) { let title = entry.get("Title"); - let newFolderGuid = (yield PlacesUtils.bookmarks.insert({ + let newFolderGuid = (yield MigrationUtils.insertBookmarkWrapper({ parentGuid, type: PlacesUtils.bookmarks.TYPE_FOLDER, title })).guid; // Empty folders may not have a children array. if (entry.has("Children")) yield this._migrateEntries(entry.get("Children"), newFolderGuid, false); } else if (type == "WebBookmarkTypeLeaf" && entry.has("URLString")) { let title; if (entry.has("URIDictionary")) title = entry.get("URIDictionary").get("title"); try { - yield PlacesUtils.bookmarks.insert({ + yield MigrationUtils.insertBookmarkWrapper({ parentGuid, url: entry.get("URLString"), title }); } catch (ex) { Cu.reportError("Invalid Safari bookmark: " + ex); } } } }) @@ -225,17 +225,17 @@ History.prototype = { catch (ex) { // Safari's History file may contain malformed URIs which // will be ignored. Cu.reportError(ex); } } } if (places.length > 0) { - PlacesUtils.asyncHistory.updatePlaces(places, { + MigrationUtils.insertVisitsWrapper(places, { _success: false, handleResult: function() { // Importing any entry is considered a successful import. this._success = true; }, handleError: function() {}, handleCompletion: function() { aCallback(this._success);
--- a/browser/components/migration/tests/unit/test_Chrome_passwords.js +++ b/browser/components/migration/tests/unit/test_Chrome_passwords.js @@ -168,16 +168,18 @@ add_task(function* test_importIntoEmptyD let logins = Services.logins.getAllLogins({}); Assert.equal(logins.length, 0, "There are no logins initially"); // Migrate the logins. yield promiseMigration(migrator, MigrationUtils.resourceTypes.PASSWORDS, PROFILE); logins = Services.logins.getAllLogins({}); Assert.equal(logins.length, TEST_LOGINS.length, "Check login count after importing the data"); + Assert.equal(logins.length, MigrationUtils._importQuantities.logins, + "Check telemetry matches the actual import."); for (let i = 0; i < TEST_LOGINS.length; i++) { checkLoginsAreEqual(logins[i], TEST_LOGINS[i], i + 1); } }); // Test that existing logins for the same primary key don't get overwritten add_task(function* test_importExistingLogins() { @@ -203,13 +205,15 @@ add_task(function* test_importExistingLo checkLoginsAreEqual(logins[i], newLogins[i], i + 1); } // Migrate the logins. yield promiseMigration(migrator, MigrationUtils.resourceTypes.PASSWORDS, PROFILE); logins = Services.logins.getAllLogins({}); Assert.equal(logins.length, TEST_LOGINS.length, "Check there are still the same number of logins after re-importing the data"); + Assert.equal(logins.length, MigrationUtils._importQuantities.logins, + "Check telemetry matches the actual import."); for (let i = 0; i < newLogins.length; i++) { checkLoginsAreEqual(logins[i], newLogins[i], i + 1); } });
--- a/browser/components/migration/tests/unit/test_Edge_db_migration.js +++ b/browser/components/migration/tests/unit/test_Edge_db_migration.js @@ -382,16 +382,19 @@ add_task(function*() { {type: COLUMN_TYPES.JET_coltypGUID, name: "ParentId"}, ], itemsInDB); let migrator = Cc["@mozilla.org/profile/migrator;1?app=browser&type=edge"] .createInstance(Ci.nsIBrowserProfileMigrator); let bookmarksMigrator = migrator.wrappedJSObject.getESEMigratorForTesting(db); Assert.ok(bookmarksMigrator.exists, "Should recognize table we just created"); + let source = MigrationUtils.getLocalizedString("sourceNameEdge"); + let sourceLabel = MigrationUtils.getLocalizedString("importedBookmarksFolder", [source]); + let seenBookmarks = []; let bookmarkObserver = { onItemAdded(itemId, parentId, index, itemType, url, title, dateAdded, itemGuid, parentGuid) { if (title.startsWith("Deleted")) { ok(false, "Should not see deleted items being bookmarked!"); } seenBookmarks.push({itemId, parentId, index, itemType, url, title, dateAdded, itemGuid, parentGuid}); }, @@ -407,16 +410,19 @@ add_task(function*() { let migrateResult = yield new Promise(resolve => bookmarksMigrator.migrate(resolve)).catch(ex => { Cu.reportError(ex); Assert.ok(false, "Got an exception trying to migrate data! " + ex); return false; }); PlacesUtils.bookmarks.removeObserver(bookmarkObserver); Assert.ok(migrateResult, "Migration should succeed"); Assert.equal(seenBookmarks.length, 7, "Should have seen 7 items being bookmarked."); + Assert.equal(seenBookmarks.filter(bm => bm.title != sourceLabel).length, + MigrationUtils._importQuantities.bookmarks, + "Telemetry should have items except for 'From Microsoft Edge' folders"); let menuParents = seenBookmarks.filter(item => item.parentGuid == PlacesUtils.bookmarks.menuGuid); Assert.equal(menuParents.length, 1, "Should have a single folder added to the menu"); let toolbarParents = seenBookmarks.filter(item => item.parentGuid == PlacesUtils.bookmarks.toolbarGuid); Assert.equal(toolbarParents.length, 1, "Should have a single item added to the toolbar"); let menuParentGuid = menuParents[0].itemGuid; let toolbarParentGuid = toolbarParents[0].itemGuid;
--- a/browser/components/migration/tests/unit/test_IE7_passwords.js +++ b/browser/components/migration/tests/unit/test_IE7_passwords.js @@ -373,16 +373,25 @@ add_task(function* test_passwordsAvailab migrator._migrateURIs(uris); logins = Services.logins.getAllLogins({}); // check that the number of logins in the password manager has increased as expected which means // that all the values for the current website were imported loginCount += website.logins.length; Assert.equal(logins.length, loginCount, "The number of logins has increased after the migration"); + // NB: because telemetry records any login data passed to the login manager, it + // also gets told about logins that are duplicates or invalid (for one reason + // or another) and so its counts might exceed those of the login manager itself. + Assert.greaterOrEqual(MigrationUtils._importQuantities.logins, loginCount, + "Telemetry quantities equal or exceed the actual import."); + // Reset - this normally happens at the start of a new migration, but we're calling + // the migrator directly so can't rely on that: + MigrationUtils._importQuantities.logins = 0; + let startIndex = loginCount - website.logins.length; // compares the imported password manager logins with their expected logins for (let i = 0; i < website.logins.length; i++) { checkLoginsAreEqual(logins[startIndex + i], website.logins[i], " " + current + " - " + i + " "); } } });
--- a/browser/components/migration/tests/unit/test_IE_bookmarks.js +++ b/browser/components/migration/tests/unit/test_IE_bookmarks.js @@ -8,31 +8,37 @@ add_task(function* () { // Wait for the imported bookmarks. Check that "From Internet Explorer" // folders are created in the menu and on the toolbar. let source = MigrationUtils.getLocalizedString("sourceNameIE"); let label = MigrationUtils.getLocalizedString("importedBookmarksFolder", [source]); let expectedParents = [ PlacesUtils.bookmarksMenuFolderId, PlacesUtils.toolbarFolderId ]; - PlacesUtils.bookmarks.addObserver({ + let itemCount = 0; + let bmObserver = { onItemAdded(aItemId, aParentId, aIndex, aItemType, aURI, aTitle) { - if (aTitle == label) { + if (aTitle != label) { + itemCount++; + } + if (expectedParents.length > 0 && aTitle == label) { let index = expectedParents.indexOf(aParentId); Assert.notEqual(index, -1); expectedParents.splice(index, 1); - if (expectedParents.length == 0) - PlacesUtils.bookmarks.removeObserver(this); } }, onBeginUpdateBatch() {}, onEndUpdateBatch() {}, onItemRemoved() {}, onItemChanged() {}, onItemVisited() {}, onItemMoved() {}, - }, false); + }; + PlacesUtils.bookmarks.addObserver(bmObserver, false); yield promiseMigration(migrator, MigrationUtils.resourceTypes.BOOKMARKS); + PlacesUtils.bookmarks.removeObserver(bmObserver); + Assert.equal(MigrationUtils._importQuantities.bookmarks, itemCount, + "Ensure telemetry matches actual number of imported items."); // Check the bookmarks have been imported to all the expected parents. - Assert.equal(expectedParents.length, 0); + Assert.equal(expectedParents.length, 0, "Got all the expected parents"); });
--- a/browser/components/migration/tests/unit/test_Safari_bookmarks.js +++ b/browser/components/migration/tests/unit/test_Safari_bookmarks.js @@ -8,32 +8,39 @@ add_task(function* () { Assert.ok(migrator.sourceExists); // Wait for the imported bookmarks. Check that "From Safari" // folders are created on the toolbar. let source = MigrationUtils.getLocalizedString("sourceNameSafari"); let label = MigrationUtils.getLocalizedString("importedBookmarksFolder", [source]); let expectedParents = [ PlacesUtils.toolbarFolderId ]; + let itemCount = 0; - PlacesUtils.bookmarks.addObserver({ + let bmObserver = { onItemAdded(aItemId, aParentId, aIndex, aItemType, aURI, aTitle) { - if (aTitle == label) { + if (aTitle != label) { + itemCount++; + } + if (expectedParents.length > 0 && aTitle == label) { let index = expectedParents.indexOf(aParentId); - Assert.notEqual(index, -1); + Assert.ok(index != -1, "Found expected parent"); expectedParents.splice(index, 1); - if (expectedParents.length == 0) - PlacesUtils.bookmarks.removeObserver(this); } }, onBeginUpdateBatch() {}, onEndUpdateBatch() {}, onItemRemoved() {}, onItemChanged() {}, onItemVisited() {}, onItemMoved() {}, - }, false); + }; + PlacesUtils.bookmarks.addObserver(bmObserver, false); yield promiseMigration(migrator, MigrationUtils.resourceTypes.BOOKMARKS); + PlacesUtils.bookmarks.removeObserver(bmObserver); // Check the bookmarks have been imported to all the expected parents. - Assert.equal(expectedParents.length, 0); + Assert.ok(!expectedParents.length, "No more expected parents"); + Assert.equal(itemCount, 13, "Should import all 13 items."); + // Check that the telemetry matches: + Assert.equal(MigrationUtils._importQuantities.bookmarks, itemCount, "Telemetry reporting correct."); });
--- a/browser/components/originattributes/test/browser/head.js +++ b/browser/components/originattributes/test/browser/head.js @@ -276,16 +276,21 @@ this.IsolationTestTools = { * An optional function which is called before any tabs are created so * that the test case can set up/reset local state. */ runTests(aURL, aGetResultFuncs, aCompareResultFunc, aBeforeFunc) { let pageURL; let firstFrameSetting; let secondFrameSetting; + // Request a longer timeout since the test will run a test for three times + // with different settings. Thus, one test here represents three tests. + // For this reason, we triple the timeout. + requestLongerTimeout(3); + if (typeof aURL === "string") { pageURL = aURL; } else if (typeof aURL === "object") { pageURL = aURL.url; firstFrameSetting = aURL.firstFrameSetting; secondFrameSetting = aURL.secondFrameSetting; }
--- a/browser/components/places/tests/unit/head_bookmarks.js +++ b/browser/components/places/tests/unit/head_bookmarks.js @@ -73,16 +73,20 @@ var createCorruptDB = Task.async(functio * exception generated. * * @return {Promise} * Resolved when done. */ function rebuildSmartBookmarks() { let consoleListener = { observe(aMsg) { + if (aMsg.message.startsWith("[JavaScript Warning:")) { + // TODO (Bug 1300416): Ignore spurious strict warnings. + return; + } do_throw("Got console message: " + aMsg.message); }, QueryInterface: XPCOMUtils.generateQI([ Ci.nsIConsoleListener ]), }; Services.console.reset(); Services.console.registerListener(consoleListener); do_register_cleanup(() => { try {
--- a/browser/components/sessionstore/SessionStore.jsm +++ b/browser/components/sessionstore/SessionStore.jsm @@ -206,16 +206,20 @@ this.SessionStore = { get canRestoreLastSession() { return SessionStoreInternal.canRestoreLastSession; }, set canRestoreLastSession(val) { SessionStoreInternal.canRestoreLastSession = val; }, + get lastClosedObjectType() { + return SessionStoreInternal.lastClosedObjectType; + }, + init: function ss_init() { SessionStoreInternal.init(); }, getBrowserState: function ss_getBrowserState() { return SessionStoreInternal.getBrowserState(); }, @@ -334,16 +338,20 @@ this.SessionStore = { navigateAndRestore(tab, loadArguments, historyIndex) { return SessionStoreInternal.navigateAndRestore(tab, loadArguments, historyIndex); }, getSessionHistory(tab, updatedCallback) { return SessionStoreInternal.getSessionHistory(tab, updatedCallback); }, + undoCloseById(aClosedId) { + return SessionStoreInternal.undoCloseById(aClosedId); + }, + /** * Determines whether the passed version number is compatible with * the current version number of the SessionStore. * * @param version The format and version of the file, as an array, e.g. * ["sessionrestore", 1] */ isFormatVersionCompatible(version) { @@ -373,16 +381,19 @@ var SessionStoreInternal = { QueryInterface: XPCOMUtils.generateQI([ Ci.nsIDOMEventListener, Ci.nsIObserver, Ci.nsISupportsWeakReference ]), _globalState: new GlobalState(), + // A counter to be used to generate a unique ID for each closed tab or window. + _nextClosedId: 0, + // During the initial restore and setBrowserState calls tracks the number of // windows yet to be restored _restoreCount: -1, // For each <browser> element, records the current epoch. _browserEpochs: new WeakMap(), // Any browsers that fires the oop-browser-crashed event gets stored in @@ -492,16 +503,43 @@ var SessionStoreInternal = { set canRestoreLastSession(val) { // Cheat a bit; only allow false. if (!val) { LastSession.clear(); } }, /** + * Returns a string describing the last closed object, either "tab" or "window". + * + * This was added to support the sessions.restore WebExtensions API. + */ + get lastClosedObjectType() { + if (this._closedWindows.length) { + // Since there are closed windows, we need to check if there's a closed tab + // in one of the currently open windows that was closed after the + // last-closed window. + let tabTimestamps = []; + let windowsEnum = Services.wm.getEnumerator("navigator:browser"); + while (windowsEnum.hasMoreElements()) { + let window = windowsEnum.getNext(); + let windowState = this._windows[window.__SSi]; + if (windowState && windowState._closedTabs[0]) { + tabTimestamps.push(windowState._closedTabs[0].closedAt); + } + } + if (!tabTimestamps.length || + (tabTimestamps.sort((a, b) => b - a)[0] < this._closedWindows[0].closedAt)) { + return "window"; + } + } + return "tab"; + }, + + /** * Initialize the sessionstore service. */ init: function () { if (this._initialized) { throw new Error("SessionStore.init() must only be called once!"); } TelemetryTimestamps.add("sessionRestoreInitialized"); @@ -1426,16 +1464,19 @@ var SessionStoreInternal = { }); // If we found no tab closed before our // tab then just append it to the list. if (index == -1) { index = this._closedWindows.length; } + // About to save the closed window, add a unique ID. + winData.closedId = this._nextClosedId++; + // Insert tabData at the right position. this._closedWindows.splice(index, 0, winData); this._capClosedWindows(); } else if (!shouldStore && alreadyStored) { this._closedWindows.splice(winIndex, 1); } } }, @@ -1847,16 +1888,19 @@ var SessionStoreInternal = { }); // If we found no tab closed before our // tab then just append it to the list. if (index == -1) { index = closedTabs.length; } + // About to save the closed tab, add a unique ID. + tabData.closedId = this._nextClosedId++; + // Insert tabData at the right position. closedTabs.splice(index, 0, tabData); // Truncate the list of closed tabs, if needed. if (closedTabs.length > this._max_tabs_undo) { closedTabs.splice(this._max_tabs_undo, closedTabs.length); } }, @@ -2393,16 +2437,52 @@ var SessionStoreInternal = { }, persistTabAttribute: function ssi_persistTabAttribute(aName) { if (TabAttributes.persist(aName)) { this.saveStateDelayed(); } }, + + /** + * Undoes the closing of a tab or window which corresponds + * to the closedId passed in. + * + * @param aClosedId + * The closedId of the tab or window + * + * @returns a tab or window object + */ + undoCloseById(aClosedId) { + // Check for a window first. + for (let i = 0, l = this._closedWindows.length; i < l; i++) { + if (this._closedWindows[i].closedId == aClosedId) { + return this.undoCloseWindow(i); + } + } + + // Check for a tab. + let windowsEnum = Services.wm.getEnumerator("navigator:browser"); + while (windowsEnum.hasMoreElements()) { + let window = windowsEnum.getNext(); + let windowState = this._windows[window.__SSi]; + if (windowState) { + for (let j = 0, l = windowState._closedTabs.length; j < l; j++) { + if (windowState._closedTabs[j].closedId == aClosedId) { + return this.undoCloseTab(window, j); + } + } + } + } + + // Neither a tab nor a window was found, return undefined and let the caller decide what to do about it. + return undefined; + }, + /** * Restores the session state stored in LastSession. This will attempt * to merge data into the current session. If a window was opened at startup * with pinned tab(s), then the remaining data from the previous session for * that window will be opened into that window. Otherwise new windows will * be opened. */ restoreLastSession: function ssi_restoreLastSession() {
--- a/browser/components/sessionstore/test/browser.ini +++ b/browser/components/sessionstore/test/browser.ini @@ -228,9 +228,13 @@ run-if = e10s [browser_parentProcessRestoreHash.js] run-if = e10s [browser_sessionStoreContainer.js] [browser_windowStateContainer.js] [browser_1234021.js] [browser_remoteness_flip_on_restore.js] run-if = e10s [browser_background_tab_crash.js] -run-if = e10s && crashreporter \ No newline at end of file +run-if = e10s && crashreporter + +# Disabled on Linux debug for frequent intermittent failures: +[browser_undoCloseById.js] +skip-if = os == "linux" && debug
--- a/browser/components/sessionstore/test/browser_switch_remoteness.js +++ b/browser/components/sessionstore/test/browser_switch_remoteness.js @@ -8,18 +8,21 @@ function countHistoryEntries(browser, ex let webNavigation = docShell.QueryInterface(Ci.nsIWebNavigation); let history = webNavigation.sessionHistory.QueryInterface(Ci.nsISHistoryInternal); Assert.equal(history && history.count, args.expected, "correct number of shistory entries"); }); } add_task(function* () { + // Open a new window. + let win = yield promiseNewWindowLoaded(); + // Add a new tab. - let tab = gBrowser.addTab("about:blank"); + let tab = win.gBrowser.addTab("about:blank"); let browser = tab.linkedBrowser; yield promiseBrowserLoaded(browser); ok(browser.isRemoteBrowser, "browser is remote"); // Get the maximum number of preceding entries to save. const MAX_BACK = Services.prefs.getIntPref("browser.sessionstore.max_serialize_back"); ok(MAX_BACK > -1, "check that the default has a value that caps data"); @@ -37,10 +40,10 @@ add_task(function* () { browser.loadURI("about:robots"); yield promiseTabRestored(tab); ok(!browser.isRemoteBrowser, "browser is not remote anymore"); // Check that we didn't lose any shistory entries. yield countHistoryEntries(browser, MAX_BACK + 3); // Cleanup. - gBrowser.removeTab(tab); + yield BrowserTestUtils.closeWindow(win); });
new file mode 100644 --- /dev/null +++ b/browser/components/sessionstore/test/browser_undoCloseById.js @@ -0,0 +1,118 @@ +"use strict"; + +/** + * This test is for the undoCloseById function. + */ + +Cu.import("resource:///modules/sessionstore/SessionStore.jsm"); + +function openAndCloseTab(window, url) { + let tab = window.gBrowser.addTab(url); + yield promiseBrowserLoaded(tab.linkedBrowser, true, url); + yield TabStateFlusher.flush(tab.linkedBrowser); + yield promiseRemoveTab(tab); +} + +function* openWindow(url) { + let win = yield promiseNewWindowLoaded(); + let flags = Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY; + win.gBrowser.selectedBrowser.loadURIWithFlags(url, flags); + yield promiseBrowserLoaded(win.gBrowser.selectedBrowser, true, url); + return win; +} + +function closeWindow(win) { + yield BrowserTestUtils.closeWindow(win); + // Wait 20 ms to allow SessionStorage a chance to register the closed window. + yield new Promise(resolve => setTimeout(resolve, 20)); +} + +add_task(function* test_undoCloseById() { + // Clear the lists of closed windows and tabs. + forgetClosedWindows(); + while (SessionStore.getClosedTabCount(window)) { + SessionStore.forgetClosedTab(window, 0); + } + + // Open a new window. + let win = yield openWindow("about:robots"); + + // Open and close a tab. + yield openAndCloseTab(win, "about:mozilla"); + is(SessionStore.lastClosedObjectType, "tab", "The last closed object is a tab"); + + // Record the first closedId created. + let initialClosedId = SessionStore.getClosedTabData(win, false)[0].closedId; + + // Open and close another window. + let win2 = yield openWindow("about:mozilla"); + yield closeWindow(win2); // closedId == initialClosedId + 1 + is(SessionStore.lastClosedObjectType, "window", "The last closed object is a window"); + + // Open and close another tab in the first window. + yield openAndCloseTab(win, "about:robots"); // closedId == initialClosedId + 2 + is(SessionStore.lastClosedObjectType, "tab", "The last closed object is a tab"); + + // Undo closing the second tab. + let tab = SessionStore.undoCloseById(initialClosedId + 2); + yield promiseBrowserLoaded(tab.linkedBrowser); + is(tab.linkedBrowser.currentURI.spec, "about:robots", "The expected tab was re-opened"); + + let notTab = SessionStore.undoCloseById(initialClosedId + 2); + is(notTab, undefined, "Re-opened tab cannot be unClosed again by closedId"); + + // Now the last closed object should be a window again. + is(SessionStore.lastClosedObjectType, "window", "The last closed object is a window"); + + // Undo closing the first tab. + let tab2 = SessionStore.undoCloseById(initialClosedId); + yield promiseBrowserLoaded(tab2.linkedBrowser); + is(tab2.linkedBrowser.currentURI.spec, "about:mozilla", "The expected tab was re-opened"); + + // Close the two tabs we re-opened. + yield promiseRemoveTab(tab); // closedId == initialClosedId + 3 + is(SessionStore.lastClosedObjectType, "tab", "The last closed object is a tab"); + yield promiseRemoveTab(tab2); // closedId == initialClosedId + 4 + is(SessionStore.lastClosedObjectType, "tab", "The last closed object is a tab"); + + // Open another new window. + let win3 = yield openWindow("about:mozilla"); + + // Close both windows. + yield closeWindow(win); // closedId == initialClosedId + 5 + is(SessionStore.lastClosedObjectType, "window", "The last closed object is a window"); + yield closeWindow(win3); // closedId == initialClosedId + 6 + is(SessionStore.lastClosedObjectType, "window", "The last closed object is a window"); + + // Undo closing the second window. + win = SessionStore.undoCloseById(initialClosedId + 6); + yield BrowserTestUtils.waitForEvent(win, "load"); + + // Make sure we wait until this window is restored. + yield BrowserTestUtils.waitForEvent(win.gBrowser.tabContainer, + "SSTabRestored"); + + is(win.gBrowser.selectedBrowser.currentURI.spec, "about:mozilla", "The expected window was re-opened"); + + let notWin = SessionStore.undoCloseById(initialClosedId + 6); + is(notWin, undefined, "Re-opened window cannot be unClosed again by closedId"); + + // Close the window again. + yield closeWindow(win); + is(SessionStore.lastClosedObjectType, "window", "The last closed object is a window"); + + // Undo closing the first window. + win = SessionStore.undoCloseById(initialClosedId + 5); + + yield BrowserTestUtils.waitForEvent(win, "load"); + + // Make sure we wait until this window is restored. + yield BrowserTestUtils.waitForEvent(win.gBrowser.tabContainer, + "SSTabRestored"); + + is(win.gBrowser.selectedBrowser.currentURI.spec, "about:robots", "The expected window was re-opened"); + + // Close the window again. + yield closeWindow(win); + is(SessionStore.lastClosedObjectType, "window", "The last closed object is a window"); +});
--- a/browser/components/sessionstore/test/head.js +++ b/browser/components/sessionstore/test/head.js @@ -278,18 +278,18 @@ var promiseForEachSessionRestoreFile = T if (!(ex instanceof OS.File.Error && ex.becauseNoSuchFile)) { throw ex; } } cb(data, key); } }); -function promiseBrowserLoaded(aBrowser, ignoreSubFrames = true) { - return BrowserTestUtils.browserLoaded(aBrowser, !ignoreSubFrames); +function promiseBrowserLoaded(aBrowser, ignoreSubFrames = true, wantLoad = null) { + return BrowserTestUtils.browserLoaded(aBrowser, !ignoreSubFrames, wantLoad); } function whenWindowLoaded(aWindow, aCallback = next) { aWindow.addEventListener("load", function windowLoadListener() { aWindow.removeEventListener("load", windowLoadListener, false); executeSoon(function executeWhenWindowLoaded() { aCallback(aWindow); });
--- a/browser/installer/Makefile.in +++ b/browser/installer/Makefile.in @@ -5,16 +5,17 @@ STANDALONE_MAKEFILE := 1 DIST_SUBDIR := browser include $(topsrcdir)/config/rules.mk MOZ_PKG_REMOVALS = $(srcdir)/removed-files.in MOZ_PKG_MANIFEST = $(srcdir)/package-manifest.in +MOZ_PKG_DUPEFLAGS = -f $(srcdir)/allowed-dupes.mn # Some files have been already bundled with xulrunner ifndef MOZ_MULET MOZ_PKG_FATAL_WARNINGS = 1 else DEFINES += -DMOZ_MULET endif
new file mode 100644 --- /dev/null +++ b/browser/installer/allowed-dupes.mn @@ -0,0 +1,222 @@ +# Known duplicate files +# This file is ideally removed, but some existing files will be grandfathered in +# See bug 1303184 +# +# PLEASE DO NOT ADD MORE EXCEPTIONS TO THIS LIST +# + +# updater on osx is bug 1311194 +LaunchServices/org.mozilla.updater +updater.app/Contents/MacOS/org.mozilla.updater +updater.app/Contents/PkgInfo +browser/chrome.manifest +# browser branding / themes is bug 1313106 +browser/chrome/browser/content/branding/icon128.png +browser/chrome/browser/content/branding/icon16.png +browser/chrome/browser/content/branding/icon32.png +browser/chrome/browser/content/branding/icon48.png +browser/chrome/browser/content/browser/defaultthemes/5.footer.png +browser/chrome/browser/content/browser/defaultthemes/5.header.png +browser/chrome/browser/content/browser/extension.svg +browser/chrome/browser/content/browser/places/bookmarkProperties.xul +browser/chrome/browser/content/browser/places/bookmarkProperties2.xul +browser/chrome/browser/skin/classic/browser/addons/addon-install-confirm.svg +browser/chrome/browser/skin/classic/browser/connection-secure.svg +browser/chrome/browser/skin/classic/browser/controlcenter/warning-gray.svg +browser/chrome/browser/skin/classic/browser/newtab/close.png +browser/chrome/browser/skin/classic/browser/theme-switcher-icon.png +# devtools reduction is bug 1311178 +browser/chrome/devtools/content/dom/content/dom-view.css +browser/chrome/devtools/content/dom/dom.html +browser/chrome/devtools/content/dom/main.js +browser/chrome/devtools/content/framework/toolbox-options.js +browser/chrome/devtools/content/inspector/fonts/fonts.js +browser/chrome/devtools/content/inspector/inspector.xhtml +browser/chrome/devtools/content/memory/initializer.js +browser/chrome/devtools/content/projecteditor/lib/helpers/readdir.js +browser/chrome/devtools/content/shared/frame-script-utils.js +browser/chrome/devtools/content/shared/theme-switching.js +browser/chrome/devtools/modules/devtools/client/dom/content/dom-view.css +browser/chrome/devtools/modules/devtools/client/dom/dom.html +browser/chrome/devtools/modules/devtools/client/dom/main.js +browser/chrome/devtools/modules/devtools/client/framework/toolbox-options.js +browser/chrome/devtools/modules/devtools/client/inspector/fonts/fonts.js +browser/chrome/devtools/modules/devtools/client/inspector/inspector.xhtml +browser/chrome/devtools/modules/devtools/client/jsonview/css/controls.png +browser/chrome/devtools/modules/devtools/client/jsonview/css/controls@2x.png +browser/chrome/devtools/modules/devtools/client/memory/initializer.js +browser/chrome/devtools/modules/devtools/client/projecteditor/lib/helpers/readdir.js +browser/chrome/devtools/modules/devtools/client/shared/frame-script-utils.js +browser/chrome/devtools/modules/devtools/client/shared/theme-switching.js +browser/chrome/devtools/modules/devtools/client/themes/common.css +browser/chrome/devtools/modules/devtools/client/themes/variables.css +browser/chrome/devtools/skin/common.css +browser/chrome/devtools/skin/images/command-scratchpad.svg +browser/chrome/devtools/skin/images/controls.png +browser/chrome/devtools/skin/images/controls@2x.png +browser/chrome/devtools/skin/images/debugger-blackbox.svg +browser/chrome/devtools/skin/images/debugger-prettyprint.svg +browser/chrome/devtools/skin/images/filetypes/store.svg +browser/chrome/devtools/skin/images/itemToggle.svg +browser/chrome/devtools/skin/images/security-state-broken.svg +browser/chrome/devtools/skin/images/security-state-local.svg +browser/chrome/devtools/skin/images/security-state-secure.svg +browser/chrome/devtools/skin/images/tabs-icon.svg +browser/chrome/devtools/skin/images/tool-scratchpad.svg +browser/chrome/devtools/skin/images/tool-storage.svg +browser/chrome/devtools/skin/images/tool-styleeditor.svg +browser/chrome/devtools/skin/promisedebugger.css +browser/chrome/devtools/skin/variables.css +modules/devtools/Console.jsm +modules/devtools/Loader.jsm +modules/devtools/Simulator.jsm +modules/devtools/shared/Console.jsm +modules/devtools/shared/Loader.jsm +modules/devtools/shared/apps/Simulator.jsm +browser/modules/devtools/client/framework/gDevTools.jsm +browser/modules/devtools/gDevTools.jsm +browser/chrome/icons/default/default16.png +browser/chrome/icons/default/default32.png +browser/chrome/icons/default/default48.png +browser/chrome/pdfjs/content/web/images/findbarButton-next-rtl.png +browser/chrome/pdfjs/content/web/images/findbarButton-next-rtl@2x.png +browser/chrome/pdfjs/content/web/images/findbarButton-next.png +browser/chrome/pdfjs/content/web/images/findbarButton-next@2x.png +browser/chrome/pdfjs/content/web/images/findbarButton-previous-rtl.png +browser/chrome/pdfjs/content/web/images/findbarButton-previous-rtl@2x.png +browser/chrome/pdfjs/content/web/images/findbarButton-previous.png +browser/chrome/pdfjs/content/web/images/findbarButton-previous@2x.png +browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/icon.png +browser/features/firefox@getpocket.com/chrome/skin/linux/menuPanel.png +browser/features/firefox@getpocket.com/chrome/skin/linux/menuPanel@2x.png +browser/features/firefox@getpocket.com/chrome/skin/windows/menuPanel.png +browser/features/firefox@getpocket.com/chrome/skin/windows/menuPanel@2x.png +# flyweb reduction is bug 1313107 +browser/features/flyweb@mozilla.org/chrome/skin/linux/flyweb.css +browser/features/flyweb@mozilla.org/chrome/skin/linux/icon-16.png +browser/features/flyweb@mozilla.org/chrome/skin/linux/icon-32-anchored.png +browser/features/flyweb@mozilla.org/chrome/skin/linux/icon-32.png +browser/features/flyweb@mozilla.org/chrome/skin/linux/icon-64-anchored.png +browser/features/flyweb@mozilla.org/chrome/skin/linux/icon-64.png +browser/features/flyweb@mozilla.org/chrome/skin/osx/flyweb.css +browser/features/flyweb@mozilla.org/chrome/skin/osx/icon-32-anchored.png +browser/features/flyweb@mozilla.org/chrome/skin/osx/icon-64-anchored.png +browser/features/flyweb@mozilla.org/chrome/skin/windows/flyweb.css +browser/features/flyweb@mozilla.org/chrome/skin/windows/icon-16.png +browser/features/flyweb@mozilla.org/chrome/skin/windows/icon-32-anchored.png +browser/features/flyweb@mozilla.org/chrome/skin/windows/icon-32.png +browser/features/flyweb@mozilla.org/chrome/skin/windows/icon-64-anchored.png +browser/features/flyweb@mozilla.org/chrome/skin/windows/icon-64.png +browser/icons/mozicon128.png +chrome.manifest +chrome/en-US/locale/en-US/browser/overrides/AccessFu.properties +chrome/en-US/locale/en-US/browser/overrides/about.dtd +chrome/en-US/locale/en-US/browser/overrides/aboutAbout.dtd +chrome/en-US/locale/en-US/browser/overrides/aboutReader.properties +chrome/en-US/locale/en-US/browser/overrides/aboutRights.dtd +chrome/en-US/locale/en-US/browser/overrides/charsetMenu.properties +chrome/en-US/locale/en-US/browser/overrides/commonDialogs.properties +chrome/en-US/locale/en-US/browser/overrides/crashreporter/crashes.dtd +chrome/en-US/locale/en-US/browser/overrides/crashreporter/crashes.properties +chrome/en-US/locale/en-US/browser/overrides/dom/dom.properties +chrome/en-US/locale/en-US/browser/overrides/global.dtd +chrome/en-US/locale/en-US/browser/overrides/global/aboutSupport.dtd +chrome/en-US/locale/en-US/browser/overrides/global/aboutSupport.properties +chrome/en-US/locale/en-US/browser/overrides/global/aboutTelemetry.dtd +chrome/en-US/locale/en-US/browser/overrides/global/aboutTelemetry.properties +chrome/en-US/locale/en-US/browser/overrides/global/aboutWebrtc.properties +chrome/en-US/locale/en-US/browser/overrides/global/mozilla.dtd +chrome/en-US/locale/en-US/browser/overrides/intl.css +chrome/en-US/locale/en-US/browser/overrides/intl.properties +chrome/en-US/locale/en-US/browser/overrides/passwordmgr.properties +chrome/en-US/locale/en-US/browser/overrides/plugins.properties +chrome/en-US/locale/en-US/browser/overrides/plugins/pluginproblem.dtd +chrome/en-US/locale/en-US/browser/overrides/search/search.properties +chrome/en-US/locale/en-US/global-platform/mac/intl.properties +chrome/en-US/locale/en-US/global-platform/unix/accessible.properties +chrome/en-US/locale/en-US/global-platform/unix/intl.properties +chrome/en-US/locale/en-US/global-platform/unix/platformKeys.properties +chrome/en-US/locale/en-US/global-platform/win/accessible.properties +chrome/en-US/locale/en-US/global-platform/win/intl.properties +chrome/en-US/locale/en-US/global-platform/win/platformKeys.properties +chrome/en-US/locale/en-US/global/AccessFu.properties +chrome/en-US/locale/en-US/global/about.dtd +chrome/en-US/locale/en-US/global/aboutAbout.dtd +chrome/en-US/locale/en-US/global/aboutReader.properties +chrome/en-US/locale/en-US/global/aboutRights.dtd +chrome/en-US/locale/en-US/global/aboutSupport.dtd +chrome/en-US/locale/en-US/global/aboutSupport.properties +chrome/en-US/locale/en-US/global/aboutTelemetry.dtd +chrome/en-US/locale/en-US/global/aboutTelemetry.properties +chrome/en-US/locale/en-US/global/aboutWebrtc.properties +chrome/en-US/locale/en-US/global/charsetMenu.properties +chrome/en-US/locale/en-US/global/commonDialogs.properties +chrome/en-US/locale/en-US/global/crashes.dtd +chrome/en-US/locale/en-US/global/crashes.properties +chrome/en-US/locale/en-US/global/dom/dom.properties +chrome/en-US/locale/en-US/global/global.dtd +chrome/en-US/locale/en-US/global/intl.css +chrome/en-US/locale/en-US/global/intl.properties +chrome/en-US/locale/en-US/global/mozilla.dtd +chrome/en-US/locale/en-US/global/plugins.properties +chrome/en-US/locale/en-US/global/search/search.properties +chrome/en-US/locale/en-US/passwordmgr/passwordmgr.properties +chrome/en-US/locale/en-US/pluginproblem/pluginproblem.dtd +chrome/toolkit/skin/classic/global/autocomplete.css +chrome/toolkit/skin/classic/global/button.css +chrome/toolkit/skin/classic/global/checkbox.css +chrome/toolkit/skin/classic/global/dialog.css +chrome/toolkit/skin/classic/global/dropmarker.css +chrome/toolkit/skin/classic/global/global.css +chrome/toolkit/skin/classic/global/groupbox.css +chrome/toolkit/skin/classic/global/icons/close-XPVista7.png +chrome/toolkit/skin/classic/global/icons/tabprompts-bgtexture.png +chrome/toolkit/skin/classic/global/listbox.css +chrome/toolkit/skin/classic/global/media/clicktoplay-bgtexture.png +chrome/toolkit/skin/classic/global/menu.css +chrome/toolkit/skin/classic/global/menulist.css +chrome/toolkit/skin/classic/global/numberbox.css +chrome/toolkit/skin/classic/global/popup.css +chrome/toolkit/skin/classic/global/preferences.css +chrome/toolkit/skin/classic/global/progressmeter.css +chrome/toolkit/skin/classic/global/radio.css +chrome/toolkit/skin/classic/global/resizer.css +chrome/toolkit/skin/classic/global/richlistbox.css +chrome/toolkit/skin/classic/global/scale.css +chrome/toolkit/skin/classic/global/scrollbars.css +chrome/toolkit/skin/classic/global/scrollbox.css +chrome/toolkit/skin/classic/global/spinbuttons.css +chrome/toolkit/skin/classic/global/splitter.css +chrome/toolkit/skin/classic/global/tabbox.css +chrome/toolkit/skin/classic/global/textbox.css +chrome/toolkit/skin/classic/global/toolbar.css +chrome/toolkit/skin/classic/global/toolbarbutton.css +chrome/toolkit/skin/classic/global/tree.css +chrome/toolkit/skin/classic/global/wizard.css +chrome/toolkit/skin/classic/mozapps/downloads/buttons.png +chrome/toolkit/skin/classic/mozapps/downloads/downloadButtons-XP.png +chrome/toolkit/skin/classic/mozapps/downloads/downloadButtons.png +chrome/toolkit/skin/classic/mozapps/extensions/category-dictionaries.png +chrome/toolkit/skin/classic/mozapps/extensions/category-experiments.png +chrome/toolkit/skin/classic/mozapps/extensions/dictionaryGeneric.png +chrome/toolkit/skin/classic/mozapps/extensions/experimentGeneric.png +chrome/toolkit/skin/classic/mozapps/update/buttons.png +chrome/toolkit/skin/classic/mozapps/update/downloadButtons-XP.png +chrome/toolkit/skin/classic/mozapps/update/downloadButtons.png +components/FxAccountsPush.js +crashreporter.app/Contents/Resources/English.lproj/MainMenu.nib/classes.nib +crashreporter.app/Contents/Resources/English.lproj/MainMenuRTL.nib/classes.nib +# firefox/firefox-bin is bug 658850 +firefox +firefox-bin +modules/FxAccountsPush.js +modules/commonjs/index.js +modules/commonjs/sdk/ui/button/view/events.js +modules/commonjs/sdk/ui/state/events.js +plugin-container.app/Contents/PkgInfo +res/table-remove-column-active.gif +res/table-remove-column-hover.gif +res/table-remove-column.gif +res/table-remove-row-active.gif +res/table-remove-row-hover.gif +res/table-remove-row.gif
--- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -179,19 +179,16 @@ @RESPATH@/components/content_xslt.xpt @RESPATH@/components/cookie.xpt @RESPATH@/components/directory.xpt @RESPATH@/components/docshell.xpt @RESPATH@/components/dom.xpt @RESPATH@/components/dom_apps.xpt @RESPATH@/components/dom_base.xpt @RESPATH@/components/dom_system.xpt -#ifdef MOZ_B2G_BT -@RESPATH@/components/dom_bluetooth.xpt -#endif @RESPATH@/components/dom_canvas.xpt @RESPATH@/components/dom_core.xpt @RESPATH@/components/dom_css.xpt @RESPATH@/components/dom_events.xpt @RESPATH@/components/dom_geolocation.xpt @RESPATH@/components/dom_media.xpt @RESPATH@/components/dom_network.xpt @RESPATH@/components/dom_notification.xpt
--- a/browser/modules/PermissionUI.jsm +++ b/browser/modules/PermissionUI.jsm @@ -316,16 +316,19 @@ this.PermissionPromptPrototype = { promptAction.action == Ci.nsIPermissionManager.ALLOW_ACTION) { this.allow(); } else { this.cancel(); } } }, }; + if (promptAction.dismiss) { + action.dismiss = promptAction.dismiss + } popupNotificationActions.push(action); } let mainAction = popupNotificationActions.length ? popupNotificationActions[0] : null; let secondaryActions = popupNotificationActions.splice(1);
--- a/browser/modules/URLBarZoom.jsm +++ b/browser/modules/URLBarZoom.jsm @@ -6,46 +6,57 @@ "use strict"; this.EXPORTED_SYMBOLS = [ "URLBarZoom" ]; Components.utils.import("resource://gre/modules/Services.jsm"); var URLBarZoom = { - init: function(aWindow) { + init(aWindow) { // Register ourselves with the service so we know when the zoom prefs change. - Services.obs.addObserver(updateZoomButton, "browser-fullZoom:zoomChange", false); - Services.obs.addObserver(updateZoomButton, "browser-fullZoom:zoomReset", false); - Services.obs.addObserver(updateZoomButton, "browser-fullZoom:location-change", false); + Services.obs.addObserver(this, "browser-fullZoom:zoomChange", false); + Services.obs.addObserver(this, "browser-fullZoom:zoomReset", false); + Services.obs.addObserver(this, "browser-fullZoom:location-change", false); + }, + + observe(aSubject, aTopic) { + this.updateZoomButton(aSubject, aTopic); }, -} -function updateZoomButton(aSubject, aTopic) { - let win = aSubject.ownerDocument.defaultView; - let customizableZoomControls = win.document.getElementById("zoom-controls"); - let zoomResetButton = win.document.getElementById("urlbar-zoom-button"); - let zoomFactor = Math.round(win.ZoomManager.zoom * 100); + updateZoomButton(aSubject, aTopic) { + // aSubject.ownerGlobal may no longer exist if a tab has been dragged to a + // new window. In this case, aSubject.ownerGlobal will be supplied by + // updateZoomButton() called in XULBrowserWindow.onLocationChange(). + if (!aSubject.ownerGlobal) { + return; + } + + let win = aSubject.ownerGlobal; + let customizableZoomControls = win.document.getElementById("zoom-controls"); + let zoomResetButton = win.document.getElementById("urlbar-zoom-button"); + let zoomFactor = Math.round(win.ZoomManager.zoom * 100); - // Ensure that zoom controls haven't already been added to browser in Customize Mode - if (customizableZoomControls && - customizableZoomControls.getAttribute("cui-areatype") == "toolbar") { - zoomResetButton.hidden = true; - return; - } - if (zoomFactor != 100) { - // Check if zoom button is visible and update label if it is - if (zoomResetButton.hidden) { - zoomResetButton.hidden = false; + // Ensure that zoom controls haven't already been added to browser in Customize Mode + if (customizableZoomControls && + customizableZoomControls.getAttribute("cui-areatype") == "toolbar") { + zoomResetButton.hidden = true; + return; } - // Only allow pulse animation for zoom changes, not tab switching - if (aTopic != "browser-fullZoom:location-change") { - zoomResetButton.setAttribute("animate", "true"); + if (zoomFactor != 100) { + // Check if zoom button is visible and update label if it is + if (zoomResetButton.hidden) { + zoomResetButton.hidden = false; + } + // Only allow pulse animation for zoom changes, not tab switching + if (aTopic != "browser-fullZoom:location-change") { + zoomResetButton.setAttribute("animate", "true"); + } else { + zoomResetButton.removeAttribute("animate"); + } + zoomResetButton.setAttribute("label", + win.gNavigatorBundle.getFormattedString("urlbar-zoom-button.label", [zoomFactor])); } else { - zoomResetButton.removeAttribute("animate"); + // Hide button if zoom is at 100% + zoomResetButton.hidden = true; } - zoomResetButton.setAttribute("label", - win.gNavigatorBundle.getFormattedString("urlbar-zoom-button.label", [zoomFactor])); - // Hide button if zoom is at 100% - } else { - zoomResetButton.hidden = true; - } -} + }, +};
--- a/browser/modules/test/browser_CaptivePortalWatcher.js +++ b/browser/modules/test/browser_CaptivePortalWatcher.js @@ -91,32 +91,56 @@ function ensureNoPortalTab(win) { function ensureNoPortalNotification(win) { let notificationBox = win.document.getElementById("high-priority-global-notificationbox"); is(notificationBox.getNotificationWithValue(PORTAL_NOTIFICATION_VALUE), null, "There should be no captive portal notification in the window."); } +/** + * Some tests open a new window and close it later. When the window is closed, + * the original window opened by mochitest gains focus, generating a + * xul-window-visible notification. If the next test also opens a new window + * before this notification has a chance to fire, CaptivePortalWatcher picks + * up the first one instead of the one from the new window. To avoid this + * unfortunate intermittent timing issue, we wait for the notification from + * the original window every time we close a window that we opened. + */ +function waitForXulWindowVisible() { + return new Promise(resolve => { + Services.obs.addObserver(function observe() { + Services.obs.removeObserver(observe, "xul-window-visible"); + resolve(); + }, "xul-window-visible", false); + }); +} + +function* closeWindowAndWaitForXulWindowVisible(win) { + let p = waitForXulWindowVisible(); + yield BrowserTestUtils.closeWindow(win); + yield p; +} + // Each of the test cases below is run twice: once for login-success and once // for login-abort (aSuccess set to true and false respectively). let testCasesForBothSuccessAndAbort = [ /** * A portal is detected when there's no browser window, * then a browser window is opened, then the portal is freed. * The portal tab should be added and focused when the window is * opened, and closed automatically when the success event is fired. */ function* test_detectedWithNoBrowserWindow_Open(aSuccess) { yield portalDetectedNoBrowserWindow(); let win = yield openWindowAndWaitForPortalTabAndNotification(); freePortal(aSuccess); ensureNoPortalTab(win); ensureNoPortalNotification(win); - yield BrowserTestUtils.closeWindow(win); + yield closeWindowAndWaitForXulWindowVisible(win); }, /** * A portal is detected when there's no browser window, and the * portal is freed before a browser window is opened. No portal * tab should be added when a browser window is opened. */ function* test_detectedWithNoBrowserWindow_GoneBeforeOpen(aSuccess) { @@ -124,17 +148,17 @@ let testCasesForBothSuccessAndAbort = [ freePortal(aSuccess); let win = yield BrowserTestUtils.openNewBrowserWindow(); // Wait for a while to make sure no tab is opened. yield new Promise(resolve => { setTimeout(resolve, 1000); }); ensureNoPortalTab(win); ensureNoPortalNotification(win); - yield BrowserTestUtils.closeWindow(win); + yield closeWindowAndWaitForXulWindowVisible(win); }, /** * A portal is detected when a browser window has focus. A portal tab should be * opened in the background in the focused browser window. If the portal is * freed when the tab isn't focused, the tab should be closed automatically. */ function* test_detectedWithFocus(aSuccess) { @@ -186,17 +210,17 @@ let singleRunTestCases = [ let browser = win.gBrowser.selectedTab.linkedBrowser; let loadPromise = BrowserTestUtils.browserLoaded(browser, false, CANONICAL_URL_REDIRECTED); BrowserTestUtils.loadURI(browser, CANONICAL_URL_REDIRECTED); yield loadPromise; freePortal(true); ensurePortalTab(win); ensureNoPortalNotification(win); - yield BrowserTestUtils.closeWindow(win); + yield closeWindowAndWaitForXulWindowVisible(win); }, /** * A portal is detected when a browser window has focus. A portal tab should be * opened in the background in the focused browser window. If the portal is * freed when the tab isn't focused, the tab should be closed automatically, * even if the portal has redirected to a URL other than CANONICAL_URL. */
--- a/browser/themes/linux/searchbar.css +++ b/browser/themes/linux/searchbar.css @@ -118,26 +118,49 @@ menuitem[cmd="cmd_clearhistory"][disable } .search-go-button:hover:active { -moz-image-region: rect(56px, 84px, 84px, 56px); } } .search-panel-current-engine { - border-top: none !important; -moz-box-align: center; } +/** + * The borders of the various elements are specified as follows. + * + * The current engine always has a bottom border. + * The search results never have a border. + * + * When the search results are not collapsed: + * - The elements underneath the search results all have a top border. + * + * When the search results are collapsed: + * - The elements underneath the search results all have a bottom border, except + * the lowest one: search-setting-button. + */ + .search-panel-current-engine { - border-bottom: none; + border-top: none !important; + border-bottom: 1px solid var(--panel-separator-color) !important; } -.search-panel-tree { - border-top: 1px solid var(--panel-separator-color) !important; +.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-header, +.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-one-offs, +.search-panel-tree[collapsed=true] + .search-one-offs > vbox > .addengine-item:first-of-type { + border-top: none !important; +} + +.search-panel-tree[collapsed=true] + .search-one-offs > .searchbar-engine-one-off-item, +.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-current-input, +.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-one-offs, +.search-panel-tree[collapsed=true] + .search-one-offs > vbox > .addengine-item:last-of-type { + border-bottom: 1px solid var(--panel-separator-color) !important; } .search-panel-header { font-weight: normal; background-color: var(--arrowpanel-dimmed); border: none; border-top: 1px solid var(--panel-separator-color); padding: 3px 5px;
--- a/browser/themes/osx/searchbar.css +++ b/browser/themes/osx/searchbar.css @@ -107,26 +107,49 @@ } .searchbar-search-button:hover:active { -moz-image-region: rect(0, 120px, 40px, 80px); } } .search-panel-current-engine { - border-top: none !important; border-radius: 4px 4px 0 0; } +/** + * The borders of the various elements are specified as follows. + * + * The current engine always has a bottom border. + * The search results never have a border. + * + * When the search results are not collapsed: + * - The elements underneath the search results all have a top border. + * + * When the search results are collapsed: + * - The elements underneath the search results all have a bottom border, except + * the lowest one: search-setting-button. + */ + .search-panel-current-engine { - border-bottom: none; + border-top: none !important; + border-bottom: 1px solid var(--panel-separator-color); } -.search-panel-tree { - border-top: 1px solid var(--panel-separator-color) !important; +.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-header, +.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-one-offs, +.search-panel-tree[collapsed=true] + .search-one-offs > vbox > .addengine-item:first-of-type { + border-top: none; +} + +.search-panel-tree[collapsed=true] + .search-one-offs > .searchbar-engine-one-off-item, +.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-current-input, +.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-one-offs, +.search-panel-tree[collapsed=true] + .search-one-offs > vbox > .addengine-item:last-of-type { + border-bottom: 1px solid var(--panel-separator-color); } .search-panel-header { font-size: 10px; font-weight: normal; background-color: var(--arrowpanel-dimmed); border-top: 1px solid var(--panel-separator-color); margin: 0;
--- a/browser/themes/shared/tabs.inc.css +++ b/browser/themes/shared/tabs.inc.css @@ -213,16 +213,22 @@ filter: url(chrome://browser/skin/filters.svg#fill) drop-shadow(1px 1px 1px black); } .tab-icon-sound[soundplaying]:not(:hover), .tab-icon-sound[muted]:not(:hover) { opacity: .8; } +.tab-icon-sound[soundplaying-scheduledremoval]:not(:hover), +.tab-icon-overlay[soundplaying-scheduledremoval]:not(:hover) { + transition: opacity .3s linear var(--soundplaying-removal-delay); + opacity: 0; +} + .tab-background, .tabs-newtab-button { /* overlap the tab curves */ margin-inline-end: -@tabCurveHalfWidth@; margin-inline-start: -@tabCurveHalfWidth@; } .tabbrowser-arrowscrollbox > .arrowscrollbox-scrollbox {
--- a/browser/themes/windows/searchbar.css +++ b/browser/themes/windows/searchbar.css @@ -113,26 +113,49 @@ } .search-go-button:hover:active { -moz-image-region: rect(56px, 84px, 84px, 56px); } } .search-panel-current-engine { - border-top: none !important; -moz-box-align: center; } +/** + * The borders of the various elements are specified as follows. + * + * The current engine always has a bottom border. + * The search results never have a border. + * + * When the search results are not collapsed: + * - The elements underneath the search results all have a top border. + * + * When the search results are collapsed: + * - The elements underneath the search results all have a bottom border, except + * the lowest one: search-setting-button. + */ + .search-panel-current-engine { - border-bottom: none; + border-top: none !important; + border-bottom: 1px solid var(--panel-separator-color) !important; } -.search-panel-tree { - border-top: 1px solid var(--panel-separator-color) !important; +.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-header, +.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-one-offs, +.search-panel-tree[collapsed=true] + .search-one-offs > vbox > .addengine-item:first-of-type { + border-top: none !important; +} + +.search-panel-tree[collapsed=true] + .search-one-offs > .searchbar-engine-one-off-item, +.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-current-input, +.search-panel-tree[collapsed=true] + .search-one-offs > .search-panel-one-offs, +.search-panel-tree[collapsed=true] + .search-one-offs > vbox > .addengine-item:last-of-type { + border-bottom: 1px solid var(--panel-separator-color) !important; } .search-panel-header { font-weight: normal; background-color: var(--arrowpanel-dimmed); border: none; border-top: 1px solid var(--panel-separator-color); margin: 0;
--- a/build/moz-automation.mk +++ b/build/moz-automation.mk @@ -83,22 +83,16 @@ automation/upload: automation/sdk # binaries/libs, and that's what we package/test. automation/pretty-package: automation/buildsymbols # The installer, sdk and packager all run stage-package, and may conflict # with each other. automation/installer: automation/package automation/sdk: automation/installer automation/package -# Universal builds need package staging happening before buildsymbols -# (bug 834228) -ifdef UNIVERSAL_BINARY -automation/buildsymbols: automation/package -endif - # The 'pretty' versions of targets run before the regular ones to avoid # conflicts in writing to the same files. automation/installer: automation/pretty-installer automation/package: automation/pretty-package automation/package-tests: automation/pretty-package-tests automation/l10n-check: automation/pretty-l10n-check automation/update-packaging: automation/pretty-update-packaging
--- a/build/moz.configure/android-ndk.configure +++ b/build/moz.configure/android-ndk.configure @@ -9,17 +9,17 @@ js_option('--with-android-ndk', nargs=1, help='location where the Android NDK can be found') js_option('--with-android-toolchain', nargs=1, help='location of the Android toolchain') js_option('--with-android-gnu-compiler-version', nargs=1, help='GNU compiler version to use') -min_android_version = dependable('9') +min_android_version = dependable(lambda: '9') js_option('--with-android-version', nargs=1, help='android platform version', default=min_android_version) @depends('--with-android-version', min_android_version) @imports(_from='__builtin__', _import='ValueError') @@ -49,16 +49,17 @@ def ndk(value, build_project): if value: return value[0] set_config('ANDROID_NDK', ndk) add_old_configure_assignment('android_ndk', ndk) @depends(target, android_version, ndk) @checking('for android platform directory') +@imports('os') def android_platform(target, android_version, ndk): if target.os != 'Android': return if 'mips' in target.cpu: target_dir_name = 'mips' elif 'aarch64' == target.cpu: target_dir_name = 'arm64' @@ -92,16 +93,17 @@ def extra_toolchain_flags(platform_dir): if not platform_dir: return [] return ['-idirafter', os.path.join(platform_dir, 'usr', 'include')] @depends(target, host, ndk, '--with-android-toolchain', '--with-android-gnu-compiler-version') @checking('for the Android toolchain directory', lambda x: x or 'not found') +@imports('os') @imports(_from='mozbuild.shellutil', _import='quote') def android_toolchain(target, host, ndk, toolchain, gnu_compiler_version): if not ndk: return if toolchain: return toolchain[0] else: if target.cpu == 'arm' and target.endianness == 'little':
--- a/build/moz.configure/init.configure +++ b/build/moz.configure/init.configure @@ -7,16 +7,17 @@ include('util.configure') include('checks.configure') option(env='DIST', nargs=1, help='DIST directory') # Do not allow objdir == srcdir builds. # ============================================================== @depends('--help', 'DIST') +@imports('os') def check_build_environment(help, dist): topobjdir = os.path.realpath(os.path.abspath('.')) topsrcdir = os.path.realpath(os.path.abspath( os.path.join(os.path.dirname(__file__), '..', '..'))) if dist: dist = normsep(dist[0]) else: @@ -628,16 +629,17 @@ def default_project(build_env, help): option('--enable-project', nargs=1, default=default_project, help='Project to build') option('--with-external-source-dir', env='EXTERNAL_SOURCE_DIR', nargs=1, help='External directory containing additional build files') @depends('--enable-project', '--with-external-source-dir', check_build_environment, '--help') +@imports('os') def include_project_configure(project, external_source_dir, build_env, help): if not project: die('--enable-project is required.') base_dir = build_env.topsrcdir if external_source_dir: base_dir = os.path.join(base_dir, external_source_dir[0]) @@ -806,11 +808,11 @@ def js_option(*args, **kwargs): add_old_configure_arg(js_option) # Bug 1278542: This function is a workaround to resolve # |android_ndk_include|'s dependency on 'gonkdir.' The # actual implementation is located in b2g/moz.configure. # Remove this function as soon as 'android_ndk_include' # depends on 'target.' -@dependable -def gonkdir(): +@depends('--help') +def gonkdir(_): return None
--- a/build/moz.configure/old.configure +++ b/build/moz.configure/old.configure @@ -10,16 +10,17 @@ def encoded_open(path, mode): encoding = 'mbcs' if sys.platform == 'win32' else 'utf-8' return codecs.open(path, mode, encoding) option(env='AUTOCONF', nargs=1, help='Path to autoconf 2.13') @depends(mozconfig, 'AUTOCONF') @checking('for autoconf') +@imports('os') @imports('re') def autoconf(mozconfig, autoconf): mozconfig_autoconf = None if mozconfig['path']: make_extra = mozconfig['make_extra'] if make_extra: for assignment in make_extra: m = re.match('(?:export\s+)?AUTOCONF\s*:?=\s*(.+)$', @@ -59,30 +60,31 @@ set_config('AUTOCONF', autoconf) @depends('OLD_CONFIGURE', mozconfig, autoconf, check_build_environment, shell, old_configure_assignments, build_project) @imports(_from='__builtin__', _import='open') @imports(_from='__builtin__', _import='print') @imports('glob') @imports('itertools') +@imports('os') @imports('subprocess') # Import getmtime without overwriting the sandbox os.path. @imports(_from='os.path', _import='getmtime') @imports(_from='mozbuild.shellutil', _import='quote') def prepare_configure(old_configure, mozconfig, autoconf, build_env, shell, old_configure_assignments, build_project): # os.path.abspath in the sandbox will ensure forward slashes on Windows, # which is actually necessary because this path actually ends up literally # as $0, and backslashes there breaks autoconf's detection of the source # directory. old_configure = os.path.abspath(old_configure[0]) if build_project == 'js': old_configure_dir = os.path.dirname(old_configure) - if not old_configure_dir.endswith('/js/src'): + if not old_configure_dir.replace(os.sep, '/').endswith('/js/src'): old_configure = os.path.join(old_configure_dir, 'js', 'src', os.path.basename(old_configure)) refresh = True if os.path.exists(old_configure): mtime = getmtime(old_configure) aclocal = os.path.join(build_env.topsrcdir, 'build', 'autoconf', '*.m4') @@ -402,20 +404,20 @@ def post_old_configure(raw_config): # Assuming no other option is declared after this function, handle the # env options that were injected by mozconfig_options by creating dummy # Option instances and having the sandbox's CommandLineHelper handle # them. We only do so for options that haven't been declared so far, # which should be a proxy for the options that old-configure handles # and that we don't know anything about. -@dependable +@depends('--help') @imports('__sandbox__') @imports(_from='mozbuild.configure.options', _import='Option') -def remaining_mozconfig_options(): +def remaining_mozconfig_options(_): helper = __sandbox__._helper for arg in helper: if helper._origins[arg] != 'mozconfig': continue name = arg.split('=', 1)[0] if name.isupper() and name not in __sandbox__._options: option = Option(env=name, nargs='*', help=name) helper.handle(option)
--- a/build/moz.configure/util.configure +++ b/build/moz.configure/util.configure @@ -113,16 +113,19 @@ def normalize_path(): path = normsep(path) if quote(path) == path: return path size = 0 while True: out = ctypes.create_unicode_buffer(size) needed = GetShortPathNameW(path, out, size) if size >= needed: + if ' ' in out.value: + die("GetShortPathName returned a long path name. " + "Are 8dot3 filenames disabled?") return normsep(out.value) size = needed else: def normalize_path(path): return normsep(path) return normalize_path @@ -333,51 +336,43 @@ def namespace(**kwargs): # or, for convenience, a @depends function. @template @imports(_from='inspect', _import='isfunction') @imports(_from='mozbuild.configure', _import='SandboxDependsFunction') def dependable(obj): if isinstance(obj, SandboxDependsFunction): return obj if isfunction(obj): - return depends('--help')(lambda _: obj()) - return depends('--help')(lambda _: obj) + return depends(when=True)(obj) + return depends(when=True)(lambda: obj) always = dependable(True) never = dependable(False) # Some @depends function return namespaces, and one could want to use one # specific attribute from such a namespace as a "value" given to functions # such as `set_config`. But those functions do not take immediate values. # The `delayed_getattr` function allows access to attributes from the result # of a @depends function in a non-immediate manner. # @depends('--option') # def option(value) # return namespace(foo=value) # set_config('FOO', delayed_getattr(option, 'foo') @template -@imports('__sandbox__') def delayed_getattr(func, key): - deps = __sandbox__._depends.get(func, ()) - if deps: - deps = deps.sandboxed_dependencies - - def result(value, _=None): + @depends(func) + def result(value): # The @depends function we're being passed may have returned # None, or an object that simply doesn't have the wanted key. # In that case, just return None. return getattr(value, key, None) - # Automatically add a dependency on --help when the given @depends - # function itself depends on --help. - if __sandbox__._help_option in deps: - return depends(func, '--help')(result) - return depends(func)(result) + return result # Like @depends, but the decorated function is only called if one of the # arguments it would be called with has a positive value (bool(value) is True) @template def depends_if(*args): def decorator(func): @depends(*args)
--- a/build/moz.configure/windows.configure +++ b/build/moz.configure/windows.configure @@ -260,16 +260,17 @@ def vc_path(c_compiler): result = next if p.lower() == 'bin': break return result @depends_win(vc_path) @checking('for the Debug Interface Access SDK', lambda x: x or 'not found') +@imports('os') def dia_sdk_dir(vc_path): if vc_path: path = os.path.join(os.path.dirname(vc_path), 'DIA SDK') if os.path.isdir(path): return path @depends_win(vc_path, valid_windows_sdk_dir, valid_ucrt_sdk_dir, dia_sdk_dir)
--- a/config/check_spidermonkey_style.py +++ b/config/check_spidermonkey_style.py @@ -75,27 +75,26 @@ included_inclnames_to_ignore = set([ 'private/pprio.h', # NSPR 'prlink.h', # NSPR 'prlock.h', # NSPR 'prprf.h', # NSPR 'prthread.h', # NSPR 'prtypes.h', # NSPR 'selfhosted.out.h', # generated in $OBJDIR 'shellmoduleloader.out.h', # generated in $OBJDIR - 'unicode/locid.h', # ICU - 'unicode/numsys.h', # ICU 'unicode/timezone.h', # ICU 'unicode/ucal.h', # ICU 'unicode/uclean.h', # ICU 'unicode/ucol.h', # ICU 'unicode/udat.h', # ICU 'unicode/udatpg.h', # ICU 'unicode/uenum.h', # ICU 'unicode/unorm.h', # ICU 'unicode/unum.h', # ICU + 'unicode/unumsys.h', # ICU 'unicode/ustring.h', # ICU 'unicode/utypes.h', # ICU 'vtune/VTuneWrapper.h' # VTune ]) # These files have additional constraints on where they are #included, so we # ignore #includes of them when checking #include ordering. oddly_ordered_inclnames = set([
--- a/devtools/client/framework/target.js +++ b/devtools/client/framework/target.js @@ -9,24 +9,26 @@ const promise = require("promise"); const defer = require("devtools/shared/defer"); const EventEmitter = require("devtools/shared/event-emitter"); const Services = require("Services"); const { XPCOMUtils } = require("resource://gre/modules/XPCOMUtils.jsm"); loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true); loader.lazyRequireGetter(this, "DebuggerClient", "devtools/shared/client/main", true); +loader.lazyRequireGetter(this, "gDevTools", + "devtools/client/framework/devtools", true); const targets = new WeakMap(); const promiseTargets = new WeakMap(); /** * Functions for creating Targets */ -exports.TargetFactory = { +const TargetFactory = exports.TargetFactory = { /** * Construct a Target * @param {XULTab} tab * The tab to use in creating a new target. * * @return A target object */ forTab: function (tab) { @@ -449,29 +451,31 @@ TabTarget.prototype = { * Listen to the different events. */ _setupListeners: function () { this._webProgressListener = new TabWebProgressListener(this); this.tab.linkedBrowser.addProgressListener(this._webProgressListener); this.tab.addEventListener("TabClose", this); this.tab.parentNode.addEventListener("TabSelect", this); this.tab.ownerDocument.defaultView.addEventListener("unload", this); + this.tab.addEventListener("TabRemotenessChange", this); }, /** * Teardown event listeners. */ _teardownListeners: function () { if (this._webProgressListener) { this._webProgressListener.destroy(); } this._tab.ownerDocument.defaultView.removeEventListener("unload", this); this._tab.removeEventListener("TabClose", this); this._tab.parentNode.removeEventListener("TabSelect", this); + this._tab.removeEventListener("TabRemotenessChange", this); }, /** * Setup listeners for remote debugging, updating existing ones as necessary. */ _setupRemoteListeners: function () { this.client.addListener("closed", this.destroy); @@ -543,19 +547,48 @@ TabTarget.prototype = { break; case "TabSelect": if (this.tab.selected) { this.emit("visible", event); } else { this.emit("hidden", event); } break; + case "TabRemotenessChange": + this.onRemotenessChange(); + break; } }, + // Automatically respawn the toolbox when the tab changes between being + // loaded within the parent process and loaded from a content process. + // Process change can go in both ways. + onRemotenessChange: function () { + // Responsive design do a crazy dance around tabs and triggers + // remotenesschange events. But we should ignore them as at the end + // the content doesn't change its remoteness. + if (this._tab.isReponsiveDesignMode) { + return; + } + + // Save a reference to the tab as it will be nullified on destroy + let tab = this._tab; + let onToolboxDestroyed = (event, target) => { + if (target != this) { + return; + } + gDevTools.off("toolbox-destroyed", target); + + // Recreate a fresh target instance as the current one is now destroyed + let newTarget = TargetFactory.forTab(tab); + gDevTools.showToolbox(newTarget); + }; + gDevTools.on("toolbox-destroyed", onToolboxDestroyed); + }, + /** * Target is not alive anymore. */ destroy: function () { // If several things call destroy then we give them all the same // destruction promise so we're sure to destroy only once if (this._destroyer) { return this._destroyer.promise;
--- a/devtools/client/framework/test/browser.ini +++ b/devtools/client/framework/test/browser.ini @@ -56,16 +56,18 @@ skip-if = true # Bug 1177463 - Temporari [browser_toolbox_options_disable_buttons.js] [browser_toolbox_options_disable_cache-01.js] [browser_toolbox_options_disable_cache-02.js] [browser_toolbox_options_disable_js.js] [browser_toolbox_options_enable_serviceworkers_testing.js] # [browser_toolbox_raise.js] # Bug 962258 # skip-if = os == "win" [browser_toolbox_ready.js] +[browser_toolbox_remoteness_change.js] +run-if = e10s [browser_toolbox_select_event.js] skip-if = e10s # Bug 1069044 - destroyInspector may hang during shutdown [browser_toolbox_selected_tool_unavailable.js] [browser_toolbox_sidebar.js] [browser_toolbox_sidebar_events.js] [browser_toolbox_sidebar_existing_tabs.js] [browser_toolbox_sidebar_overflow_menu.js] [browser_toolbox_split_console.js]
new file mode 100644 --- /dev/null +++ b/devtools/client/framework/test/browser_toolbox_remoteness_change.js @@ -0,0 +1,42 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +var {Toolbox} = require("devtools/client/framework/toolbox"); + +const URL_1 = "about:robots"; +const URL_2 = "data:text/html;charset=UTF-8," + + encodeURIComponent("<div id=\"remote-page\">foo</div>"); + +add_task(function* () { + info("Open a tab on a URL supporting only running in parent process"); + let tab = yield addTab(URL_1); + is(tab.linkedBrowser.currentURI.spec, URL_1, "We really are on the expected document"); + is(tab.linkedBrowser.getAttribute("remote"), "", "And running in parent process"); + + let toolbox = yield openToolboxForTab(tab); + + let onToolboxDestroyed = toolbox.once("destroyed"); + let onToolboxCreated = gDevTools.once("toolbox-created"); + + info("Navigate to a URL supporting remote process"); + let onLoaded = BrowserTestUtils.browserLoaded(tab.linkedBrowser); + gBrowser.loadURI(URL_2); + yield onLoaded; + + is(tab.linkedBrowser.getAttribute("remote"), "true", "Navigated to a data: URI and switching to remote"); + + info("Waiting for the toolbox to be destroyed"); + yield onToolboxDestroyed; + + info("Waiting for a new toolbox to be created"); + toolbox = yield onToolboxCreated; + + info("Waiting for the new toolbox to be ready"); + yield toolbox.once("ready"); + + info("Veryify we are inspecting the new document"); + let console = yield toolbox.selectTool("webconsole"); + let { jsterm } = console.hud; + let url = yield jsterm.execute("document.location.href"); + is(url.textContent, URL_2, "The console inspects the second document"); +});
--- a/devtools/client/inspector/markup/markup.js +++ b/devtools/client/inspector/markup/markup.js @@ -1,14 +1,12 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -/* globals template */ - "use strict"; const promise = require("promise"); const Services = require("Services"); const defer = require("devtools/shared/defer"); const {Task} = require("devtools/shared/task"); const nodeConstants = require("devtools/shared/dom-node-constants"); const nodeFilterConstants = require("devtools/shared/dom-node-filter-constants");
--- a/devtools/client/inspector/rules/rules.js +++ b/devtools/client/inspector/rules/rules.js @@ -1,14 +1,13 @@ /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ /* vim: set ts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -/* globals gDevTools */ "use strict"; const promise = require("promise"); const Services = require("Services"); const {Task} = require("devtools/shared/task"); const {Tools} = require("devtools/client/definitions"); const {l10n} = require("devtools/shared/inspector/css-logic");
--- a/devtools/client/locales/en-US/netmonitor.properties +++ b/devtools/client/locales/en-US/netmonitor.properties @@ -487,20 +487,16 @@ netmonitor.toolbar.filterFreetext.key=Cm # LOCALIZATION NOTE (netmonitor.toolbar.clear): This is the label displayed # in the network toolbar for the "Clear" button. netmonitor.toolbar.clear=Clear # LOCALIZATION NOTE (netmonitor.toolbar.perf): This is the label displayed # in the network toolbar for the performance analysis button. netmonitor.toolbar.perf=Toggle performance analysis… -# LOCALIZATION NOTE (netmonitor.panesButton.tooltip): This is the tooltip for -# the button that toggles the panes visible or hidden in the netmonitor UI. -netmonitor.panesButton.tooltip=Toggle network info - # LOCALIZATION NOTE (netmonitor.summary.url): This is the label displayed # in the network details headers tab identifying the URL. netmonitor.summary.url=Request URL: # LOCALIZATION NOTE (netmonitor.summary.method): This is the label displayed # in the network details headers tab identifying the method. netmonitor.summary.method=Request method:
--- a/devtools/client/netmonitor/actions/index.js +++ b/devtools/client/netmonitor/actions/index.js @@ -1,8 +1,9 @@ /* 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 filters = require("./filters"); +const sidebar = require("./sidebar"); -module.exports = Object.assign({}, filters); +module.exports = Object.assign({}, filters, sidebar);
--- a/devtools/client/netmonitor/actions/moz.build +++ b/devtools/client/netmonitor/actions/moz.build @@ -1,9 +1,10 @@ # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. DevToolsModules( 'filters.js', - 'index.js' + 'index.js', + 'sidebar.js', )
new file mode 100644 --- /dev/null +++ b/devtools/client/netmonitor/actions/sidebar.js @@ -0,0 +1,49 @@ +/* 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 { + DISABLE_TOGGLE_BUTTON, + SHOW_SIDEBAR, + TOGGLE_SIDEBAR, +} = require("../constants"); + +/** + * Change ToggleButton disabled state. + * + * @param {boolean} disabled - expected button disabled state + */ +function disableToggleButton(disabled) { + return { + type: DISABLE_TOGGLE_BUTTON, + disabled: disabled, + }; +} + +/** + * Change sidebar visible state. + * + * @param {boolean} visible - expected sidebar visible state + */ +function showSidebar(visible) { + return { + type: SHOW_SIDEBAR, + visible: visible, + }; +} + +/** + * Toggle to show/hide sidebar. + */ +function toggleSidebar() { + return { + type: TOGGLE_SIDEBAR, + }; +} + +module.exports = { + disableToggleButton, + showSidebar, + toggleSidebar, +};
--- a/devtools/client/netmonitor/components/moz.build +++ b/devtools/client/netmonitor/components/moz.build @@ -1,8 +1,9 @@ # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. DevToolsModules( 'filter-buttons.js', + 'toggle-button.js', )
new file mode 100644 --- /dev/null +++ b/devtools/client/netmonitor/components/toggle-button.js @@ -0,0 +1,69 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +/* globals NetMonitorView */ +"use strict"; + +const { DOM, PropTypes } = require("devtools/client/shared/vendor/react"); +const { connect } = require("devtools/client/shared/vendor/react-redux"); +const { L10N } = require("../l10n"); +const Actions = require("../actions/index"); + +// Shortcuts +const { button } = DOM; + +/** + * Button used to toggle sidebar + */ +function ToggleButton({ + disabled, + onToggle, + visible, +}) { + let className = ["devtools-button"]; + if (!visible) { + className.push("pane-collapsed"); + } + let titleMsg = visible ? L10N.getStr("collapseDetailsPane") : + L10N.getStr("expandDetailsPane"); + + return button({ + id: "details-pane-toggle", + className: className.join(" "), + title: titleMsg, + disabled: disabled, + tabIndex: "0", + onMouseDown: onToggle, + }); +} + +ToggleButton.propTypes = { + disabled: PropTypes.bool.isRequired, + onToggle: PropTypes.func.isRequired, + visible: PropTypes.bool.isRequired, +}; + +module.exports = connect( + (state) => ({ + disabled: state.sidebar.toggleButtonDisabled, + visible: state.sidebar.visible, + }), + (dispatch) => ({ + onToggle: () => { + dispatch(Actions.toggleSidebar()); + + let requestsMenu = NetMonitorView.RequestsMenu; + let selectedIndex = requestsMenu.selectedIndex; + + // Make sure there's a selection if the button is pressed, to avoid + // showing an empty network details pane. + if (selectedIndex == -1 && requestsMenu.itemCount) { + requestsMenu.selectedIndex = 0; + } else { + requestsMenu.selectedIndex = -1; + } + }, + }) +)(ToggleButton);
--- a/devtools/client/netmonitor/constants.js +++ b/devtools/client/netmonitor/constants.js @@ -1,11 +1,14 @@ /* 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 actionTypes = { TOGGLE_FILTER: "TOGGLE_FILTER", ENABLE_FILTER_ONLY: "ENABLE_FILTER_ONLY", + TOGGLE_SIDEBAR: "TOGGLE_SIDEBAR", + SHOW_SIDEBAR: "SHOW_SIDEBAR", + DISABLE_TOGGLE_BUTTON: "DISABLE_TOGGLE_BUTTON", }; module.exports = actionTypes;
--- a/devtools/client/netmonitor/netmonitor-view.js +++ b/devtools/client/netmonitor/netmonitor-view.js @@ -111,20 +111,16 @@ var NetMonitorView = { /** * Initializes the UI for all the displayed panes. */ _initializePanes: function () { dumpn("Initializing the NetMonitorView panes"); this._body = $("#body"); this._detailsPane = $("#details-pane"); - this._detailsPaneToggleButton = $("#details-pane-toggle"); - - this._collapsePaneString = L10N.getStr("collapseDetailsPane"); - this._expandPaneString = L10N.getStr("expandDetailsPane"); this._detailsPane.setAttribute("width", Prefs.networkDetailsWidth); this._detailsPane.setAttribute("height", Prefs.networkDetailsHeight); this.toggleDetailsPane({ visible: false }); // Disable the performance statistics mode. if (!Prefs.statistics) { $("#request-menu-context-perf").hidden = true; @@ -138,17 +134,16 @@ var NetMonitorView = { */ _destroyPanes: Task.async(function* () { dumpn("Destroying the NetMonitorView panes"); Prefs.networkDetailsWidth = this._detailsPane.getAttribute("width"); Prefs.networkDetailsHeight = this._detailsPane.getAttribute("height"); this._detailsPane = null; - this._detailsPaneToggleButton = null; for (let p of this._editorPromises.values()) { let editor = yield p; editor.destroy(); } }), /** @@ -167,29 +162,24 @@ var NetMonitorView = { * - visible: true if the pane should be shown, false to hide * - animated: true to display an animation on toggle * - delayed: true to wait a few cycles before toggle * - callback: a function to invoke when the toggle finishes * @param number tabIndex [optional] * The index of the intended selected tab in the details pane. */ toggleDetailsPane: function (flags, tabIndex) { - let pane = this._detailsPane; - let button = this._detailsPaneToggleButton; - - ViewHelpers.togglePane(flags, pane); + ViewHelpers.togglePane(flags, this._detailsPane); if (flags.visible) { this._body.classList.remove("pane-collapsed"); - button.classList.remove("pane-collapsed"); - button.setAttribute("tooltiptext", this._collapsePaneString); + gStore.dispatch(Actions.showSidebar(true)); } else { this._body.classList.add("pane-collapsed"); - button.classList.add("pane-collapsed"); - button.setAttribute("tooltiptext", this._expandPaneString); + gStore.dispatch(Actions.showSidebar(false)); } if (tabIndex !== undefined) { $("#event-details-pane").selectedIndex = tabIndex; } }, /** @@ -284,19 +274,16 @@ var NetMonitorView = { let editor = new Editor(DEFAULT_EDITOR_CONFIG); editor.appendTo($(id)).then(() => deferred.resolve(editor)); return deferred.promise; }, _body: null, _detailsPane: null, - _detailsPaneToggleButton: null, - _collapsePaneString: "", - _expandPaneString: "", _editorPromises: new Map() }; /** * Functions handling the sidebar details view. */ function SidebarView() { dumpn("SidebarView was instantiated");
--- a/devtools/client/netmonitor/netmonitor.xul +++ b/devtools/client/netmonitor/netmonitor.xul @@ -31,21 +31,18 @@ <toolbarbutton id="requests-menu-network-summary-button" class="devtools-toolbarbutton icon-and-text" data-localization="tooltiptext=netmonitor.toolbar.perf"/> <textbox id="requests-menu-filter-freetext-text" class="devtools-filterinput" type="search" required="true" data-localization="placeholder=netmonitor.toolbar.filterFreetext.label"/> - <toolbarbutton id="details-pane-toggle" - class="devtools-toolbarbutton" - data-localization="tooltiptext=netmonitor.panesButton.tooltip" - disabled="true" - tabindex="0"/> + <html:div xmlns="http://www.w3.org/1999/xhtml" + id="react-details-pane-toggle-hook"/> </hbox> <hbox id="network-table-and-sidebar" class="devtools-responsive-container" flex="1"> <vbox id="network-table" flex="1" class="devtools-main-content"> <toolbar id="requests-menu-toolbar" class="devtools-toolbar" align="center">
--- a/devtools/client/netmonitor/reducers/index.js +++ b/devtools/client/netmonitor/reducers/index.js @@ -1,11 +1,13 @@ /* 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 { combineReducers } = require("devtools/client/shared/vendor/redux"); const filters = require("./filters"); +const sidebar = require("./sidebar"); module.exports = combineReducers({ filters, + sidebar, });
--- a/devtools/client/netmonitor/reducers/moz.build +++ b/devtools/client/netmonitor/reducers/moz.build @@ -1,9 +1,10 @@ # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. DevToolsModules( 'filters.js', - 'index.js' + 'index.js', + 'sidebar.js', )
new file mode 100644 --- /dev/null +++ b/devtools/client/netmonitor/reducers/sidebar.js @@ -0,0 +1,43 @@ +/* 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 I = require("devtools/client/shared/vendor/immutable"); +const { + DISABLE_TOGGLE_BUTTON, + SHOW_SIDEBAR, + TOGGLE_SIDEBAR, +} = require("../constants"); + +const SidebarState = I.Record({ + toggleButtonDisabled: true, + visible: false, +}); + +function disableToggleButton(state, action) { + return state.set("toggleButtonDisabled", action.disabled); +} + +function showSidebar(state, action) { + return state.set("visible", action.visible); +} + +function toggleSidebar(state, action) { + return state.set("visible", !state.visible); +} + +function sidebar(state = new SidebarState(), action) { + switch (action.type) { + case DISABLE_TOGGLE_BUTTON: + return disableToggleButton(state, action); + case SHOW_SIDEBAR: + return showSidebar(state, action); + case TOGGLE_SIDEBAR: + return toggleSidebar(state, action); + default: + return state; + } +} + +module.exports = sidebar;
--- a/devtools/client/netmonitor/requests-menu-view.js +++ b/devtools/client/netmonitor/requests-menu-view.js @@ -122,16 +122,18 @@ function RequestsMenuView() { RequestsMenuView.prototype = Heritage.extend(WidgetMethods, { /** * Initialization function, called when the network monitor is started. */ initialize: function (store) { dumpn("Initializing the RequestsMenuView"); + this.store = store; + let widgetParentEl = $("#requests-menu-contents"); this.widget = new SideMenuWidget(widgetParentEl); this._splitter = $("#network-inspector-view-splitter"); this._summary = $("#requests-menu-network-summary-button"); this._summary.setAttribute("label", L10N.getStr("networkMenu.empty")); this.userInputTimer = Cc["@mozilla.org/timer;1"] .createInstance(Ci.nsITimer); @@ -760,17 +762,17 @@ RequestsMenuView.prototype = Heritage.ex /** * Removes all network requests and closes the sidebar if open. */ clear: function () { NetMonitorController.NetworkEventsHandler.clearMarkers(); NetMonitorView.Sidebar.toggle(false); - $("#details-pane-toggle").disabled = true; + this.store.dispatch(Actions.disableToggleButton(true)); $("#requests-menu-empty-notice").hidden = false; this.empty(); this.refreshSummary(); }, /** * Refreshes the status displayed in this container's footer, providing @@ -1073,17 +1075,17 @@ RequestsMenuView.prototype = Heritage.ex NetMonitorView.NetworkDetails.populate(selectedItem.attachment); } } // We're done flushing all the requests, clear the update queue. this._updateQueue = []; this._addQueue = []; - $("#details-pane-toggle").disabled = !this.itemCount; + this.store.dispatch(Actions.disableToggleButton(!this.itemCount)); $("#requests-menu-empty-notice").hidden = !!this.itemCount; // Make sure all the requests are sorted and filtered. // Freshly added requests may not yet contain all the information required // for sorting and filtering predicates, so this is done each time the // network requests table is flushed (don't worry, events are drained first // so this doesn't happen once per network event update). this.sortContents();
--- a/devtools/client/netmonitor/toolbar-view.js +++ b/devtools/client/netmonitor/toolbar-view.js @@ -1,38 +1,38 @@ /* globals dumpn, $, NetMonitorView */ "use strict"; const { createFactory, DOM } = require("devtools/client/shared/vendor/react"); const ReactDOM = require("devtools/client/shared/vendor/react-dom"); const Provider = createFactory(require("devtools/client/shared/vendor/react-redux").Provider); const FilterButtons = createFactory(require("./components/filter-buttons")); +const ToggleButton = createFactory(require("./components/toggle-button")); const { L10N } = require("./l10n"); // Shortcuts const { button } = DOM; /** * Functions handling the toolbar view: expand/collapse button etc. */ function ToolbarView() { dumpn("ToolbarView was instantiated"); - - this._onTogglePanesPressed = this._onTogglePanesPressed.bind(this); } ToolbarView.prototype = { /** * Initialization function, called when the debugger is started. */ initialize: function (store) { dumpn("Initializing the ToolbarView"); this._clearContainerNode = $("#react-clear-button-hook"); this._filterContainerNode = $("#react-filter-buttons-hook"); + this._toggleContainerNode = $("#react-details-pane-toggle-hook"); // clear button ReactDOM.render(button({ id: "requests-menu-clear-button", className: "devtools-button devtools-clear-icon", title: L10N.getStr("netmonitor.toolbar.clear"), onClick: () => { NetMonitorView.RequestsMenu.clear(); @@ -40,46 +40,27 @@ ToolbarView.prototype = { }), this._clearContainerNode); // filter button ReactDOM.render(Provider( { store }, FilterButtons() ), this._filterContainerNode); - this._detailsPaneToggleButton = $("#details-pane-toggle"); - this._detailsPaneToggleButton.addEventListener("mousedown", - this._onTogglePanesPressed, false); + ReactDOM.render(Provider( + { store }, + ToggleButton() + ), this._toggleContainerNode); }, /** * Destruction function, called when the debugger is closed. */ destroy: function () { dumpn("Destroying the ToolbarView"); ReactDOM.unmountComponentAtNode(this._clearContainerNode); ReactDOM.unmountComponentAtNode(this._filterContainerNode); - - this._detailsPaneToggleButton.removeEventListener("mousedown", - this._onTogglePanesPressed, false); - }, - - /** - * Listener handling the toggle button click event. - */ - _onTogglePanesPressed: function () { - let requestsMenu = NetMonitorView.RequestsMenu; - let selectedIndex = requestsMenu.selectedIndex; - - // Make sure there's a selection if the button is pressed, to avoid - // showing an empty network details pane. - if (selectedIndex == -1 && requestsMenu.itemCount) { - requestsMenu.selectedIndex = 0; - } else { - requestsMenu.selectedIndex = -1; - } - }, - - _detailsPaneToggleButton: null + ReactDOM.unmountComponentAtNode(this._toggleContainerNode); + } }; exports.ToolbarView = ToolbarView;
--- a/devtools/client/responsive.html/browser/swap.js +++ b/devtools/client/responsive.html/browser/swap.js @@ -47,16 +47,18 @@ function swapToInnerBrowser({ tab, conta bubbles: true, }); from.dispatchEvent(event); }; return { start: Task.async(function* () { + tab.isReponsiveDesignMode = true; + // Freeze navigation temporarily to avoid "blinking" in the location bar. freezeNavigationState(tab); // 1. Create a temporary, hidden tab to load the tool UI. let containerTab = gBrowser.addTab(containerURL, { skipAnimation: true, }); gBrowser.hideTab(containerTab); @@ -145,16 +147,18 @@ function swapToInnerBrowser({ tab, conta dispatchDevToolsBrowserSwap(contentBrowser, tab.linkedBrowser); gBrowser.swapBrowsersAndCloseOther(tab, contentTab); gBrowser = null; // The focus manager seems to get a little dizzy after all this swapping. If a // content element had been focused inside the viewport before stopping, it will // have lost focus. Activate the frame to restore expected focus. tab.linkedBrowser.frameLoader.activateRemoteFrame(); + + delete tab.isReponsiveDesignMode; }, }; } /** * Browser navigation properties we'll freeze temporarily to avoid "blinking" in the * location bar, etc. caused by the containerURL peeking through before the swap is
--- a/devtools/client/themes/netmonitor.css +++ b/devtools/client/themes/netmonitor.css @@ -2,17 +2,18 @@ /* 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/. */ #toolbar-labels { overflow: hidden; } -#react-clear-button-hook { +#react-clear-button-hook, +#react-details-pane-toggle-hook { display: flex; } /** * Collapsed details pane needs to be truly hidden to prevent both accessibility * tools and keyboard from accessing its contents. */ #details-pane.pane-collapsed { @@ -563,24 +564,24 @@ /* Size Column */ .theme-firebug .requests-menu-subitem.requests-menu-size { text-align: end; padding-inline-end: 4px; } /* Network request details */ -#details-pane-toggle:-moz-locale-dir(ltr), -#details-pane-toggle.pane-collapsed:-moz-locale-dir(rtl) { - list-style-image: var(--theme-pane-collapse-image); +#details-pane-toggle:-moz-locale-dir(ltr)::before, +#details-pane-toggle.pane-collapsed:-moz-locale-dir(rtl)::before { + background-image: var(--theme-pane-collapse-image); } -#details-pane-toggle.pane-collapsed:-moz-locale-dir(ltr), -#details-pane-toggle:-moz-locale-dir(rtl) { - list-style-image: var(--theme-pane-expand-image); +#details-pane-toggle.pane-collapsed:-moz-locale-dir(ltr)::before, +#details-pane-toggle:-moz-locale-dir(rtl)::before { + background-image: var(--theme-pane-expand-image); } /* Network request details tabpanels */ .tabpanel-content { background-color: var(--theme-sidebar-background); }
--- a/devtools/shared/touch/simulator-core.js +++ b/devtools/shared/touch/simulator-core.js @@ -138,18 +138,17 @@ SimulatorCore.prototype = { case "mouseleave": // Don't propagate events which are not related to touch events evt.stopPropagation(); break; case "mousedown": this.target = evt.target; - this.contextMenuTimeout = - this.sendContextMenu(evt.target, evt.pageX, evt.pageY); + this.contextMenuTimeout = this.sendContextMenu(evt); this.cancelClick = false; this.startX = evt.pageX; this.startY = evt.pageY; // Capture events so if a different window show up the events // won't be dispatched to something else. evt.target.setCapture(false); @@ -230,23 +229,28 @@ SimulatorCore.prototype = { fireMouseEvent(type, evt) { let content = this.getContent(evt.target); let utils = content.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIDOMWindowUtils); utils.sendMouseEvent(type, evt.clientX, evt.clientY, 0, 1, 0, true, 0, Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH); }, - sendContextMenu(target, x, y) { - let doc = target.ownerDocument; - let evt = doc.createEvent("MouseEvent"); - evt.initMouseEvent("contextmenu", true, true, doc.defaultView, - 0, x, y, x, y, false, false, false, false, - 0, null); - + sendContextMenu({ target, clientX, clientY, screenX, screenY }) { + let view = target.ownerDocument.defaultView; + let { MouseEvent } = view; + let evt = new MouseEvent("contextmenu", { + bubbles: true, + cancelable: true, + view, + screenX, + screenY, + clientX, + clientY, + }); let content = this.getContent(target); let timeout = content.setTimeout((function contextMenu() { target.dispatchEvent(evt); this.cancelClick = true; }).bind(this), delay); return timeout; },
--- a/dom/apps/PermissionsTable.jsm +++ b/dom/apps/PermissionsTable.jsm @@ -131,21 +131,16 @@ this.PermissionsTable = { geolocation: privileged: ALLOW_ACTION, certified: ALLOW_ACTION }, "browser:embedded-system-app": { app: DENY_ACTION, privileged: DENY_ACTION, certified: ALLOW_ACTION }, - bluetooth: { - app: DENY_ACTION, - privileged: DENY_ACTION, - certified: ALLOW_ACTION - }, mobileconnection: { app: DENY_ACTION, privileged: DENY_ACTION, certified: ALLOW_ACTION }, mobilenetwork: { app: DENY_ACTION, privileged: ALLOW_ACTION,
--- a/dom/base/DOMException.cpp +++ b/dom/base/DOMException.cpp @@ -70,29 +70,16 @@ enum DOM4ErrorTypeCodeMap { NotReadableError = 0, /* FileHandle API errors */ FileHandleInactiveError = 0, /* WebCrypto errors https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html#dfn-DataError */ OperationError = 0, - /* Bluetooth API errors */ - BtFailError = 0, - BtNotReadyError = 0, - BtNoMemError = 0, - BtBusyError = 0, - BtDoneError = 0, - BtUnsupportedError = 0, - BtParmInvalidError = 0, - BtUnhandledError = 0, - BtAuthFailureError = 0, - BtRmtDevDownError = 0, - BtAuthRejectedError = 0, - /* Push API errors */ NotAllowedError = 0, }; #define DOM4_MSG_DEF(name, message, nsresult) {(nsresult), name, #name, message}, #define DOM_MSG_DEF(val, message) {(val), NS_ERROR_GET_CODE(val), #val, message}, static const struct ResultStruct
--- a/dom/base/Navigator.cpp +++ b/dom/base/Navigator.cpp @@ -74,19 +74,16 @@ #include "nsStreamUtils.h" #include "nsIAppsService.h" #include "mozIApplication.h" #include "WidgetUtils.h" #include "nsIPresentationService.h" #include "mozilla/dom/MediaDevices.h" #include "MediaManager.h" -#ifdef MOZ_B2G_BT -#include "BluetoothManager.h" -#endif #ifdef MOZ_AUDIO_CHANNEL_MANAGER #include "AudioChannelManager.h" #endif #include "nsIDOMGlobalPropertyInitializer.h" #include "nsJSUtils.h" @@ -216,19 +213,16 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN( NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPowerManager) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIccManager) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mInputPortManager) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConnection) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStorageManager) #ifdef MOZ_B2G_RIL NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMobileConnections) #endif -#ifdef MOZ_B2G_BT - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBluetooth) -#endif #ifdef MOZ_AUDIO_CHANNEL_MANAGER NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAudioChannelManager) #endif NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaDevices) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTimeManager) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mServiceWorkerContainer) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow) @@ -299,22 +293,16 @@ Navigator::Invalidate() } #ifdef MOZ_B2G_RIL if (mMobileConnections) { mMobileConnections = nullptr; } #endif -#ifdef MOZ_B2G_BT - if (mBluetooth) { - mBluetooth = nullptr; - } -#endif - mMediaDevices = nullptr; #ifdef MOZ_AUDIO_CHANNEL_MANAGER if (mAudioChannelManager) { mAudioChannelManager = nullptr; } #endif @@ -1795,32 +1783,16 @@ Navigator::GetConnection(ErrorResult& aR return nullptr; } mConnection = new network::Connection(mWindow); } return mConnection; } -#ifdef MOZ_B2G_BT -bluetooth::BluetoothManager* -Navigator::GetMozBluetooth(ErrorResult& aRv) -{ - if (!mBluetooth) { - if (!mWindow) { - aRv.Throw(NS_ERROR_UNEXPECTED); - return nullptr; - } - mBluetooth = bluetooth::BluetoothManager::Create(mWindow); - } - - return mBluetooth; -} -#endif //MOZ_B2G_BT - #ifdef MOZ_TIME_MANAGER time::TimeManager* Navigator::GetMozTime(ErrorResult& aRv) { if (!mWindow) { aRv.Throw(NS_ERROR_UNEXPECTED); return nullptr; }
--- a/dom/base/Navigator.h +++ b/dom/base/Navigator.h @@ -67,22 +67,16 @@ class GamepadServiceTest; class NavigatorUserMediaSuccessCallback; class NavigatorUserMediaErrorCallback; class MozGetUserMediaDevicesSuccessCallback; namespace network { class Connection; } // namespace network -#ifdef MOZ_B2G_BT -namespace bluetooth { -class BluetoothManager; -} // namespace bluetooth -#endif // MOZ_B2G_BT - #ifdef MOZ_B2G_RIL class MobileConnectionArray; #endif class PowerManager; class IccManager; class InputPortManager; class DeviceStorageAreaListener; @@ -230,19 +224,16 @@ public: MobileConnectionArray* GetMozMobileConnections(ErrorResult& aRv); #endif // MOZ_B2G_RIL #ifdef MOZ_GAMEPAD void GetGamepads(nsTArray<RefPtr<Gamepad> >& aGamepads, ErrorResult& aRv); GamepadServiceTest* RequestGamepadServiceTest(); #endif // MOZ_GAMEPAD already_AddRefed<Promise> GetVRDisplays(ErrorResult& aRv); void GetActiveVRDisplays(nsTArray<RefPtr<VRDisplay>>& aDisplays) const; -#ifdef MOZ_B2G_BT - bluetooth::BluetoothManager* GetMozBluetooth(ErrorResult& aRv); -#endif // MOZ_B2G_BT #ifdef MOZ_TIME_MANAGER time::TimeManager* GetMozTime(ErrorResult& aRv); #endif // MOZ_TIME_MANAGER #ifdef MOZ_AUDIO_CHANNEL_MANAGER system::AudioChannelManager* GetMozAudioChannelManager(ErrorResult& aRv); #endif // MOZ_AUDIO_CHANNEL_MANAGER Presentation* GetPresentation(ErrorResult& aRv); @@ -321,19 +312,16 @@ private: RefPtr<Promise> mBatteryPromise; RefPtr<PowerManager> mPowerManager; RefPtr<IccManager> mIccManager; RefPtr<InputPortManager> mInputPortManager; RefPtr<network::Connection> mConnection; #ifdef MOZ_B2G_RIL RefPtr<MobileConnectionArray> mMobileConnections; #endif -#ifdef MOZ_B2G_BT - RefPtr<bluetooth::BluetoothManager> mBluetooth; -#endif #ifdef MOZ_AUDIO_CHANNEL_MANAGER RefPtr<system::AudioChannelManager> mAudioChannelManager; #endif RefPtr<MediaDevices> mMediaDevices; nsTArray<nsWeakPtr> mDeviceStorageStores; RefPtr<time::TimeManager> mTimeManager; RefPtr<ServiceWorkerContainer> mServiceWorkerContainer; nsCOMPtr<nsPIDOMWindowInner> mWindow;
--- a/dom/base/domerr.msg +++ b/dom/base/domerr.msg @@ -98,29 +98,16 @@ DOM_MSG_DEF(NS_ERROR_DOM_PROP_ACCESS_DEN DOM_MSG_DEF(NS_ERROR_DOM_XPCONNECT_ACCESS_DENIED, "Access to XPConnect service denied") DOM_MSG_DEF(NS_ERROR_DOM_BAD_URI, "Access to restricted URI denied") DOM_MSG_DEF(NS_ERROR_DOM_RETVAL_UNDEFINED, "Return value is undefined") DOM_MSG_DEF(NS_ERROR_DOM_QUOTA_REACHED, "Persistent storage maximum size reached") DOM4_MSG_DEF(NotFoundError, "File was not found", NS_ERROR_DOM_FILE_NOT_FOUND_ERR) DOM4_MSG_DEF(NotReadableError, "File could not be read", NS_ERROR_DOM_FILE_NOT_READABLE_ERR) -/* Non-standard Bluetooth DOM errors. */ -DOM4_MSG_DEF(BtFailError, "Fail", NS_ERROR_DOM_BLUETOOTH_FAIL) -DOM4_MSG_DEF(BtNotReadyError, "Not ready", NS_ERROR_DOM_BLUETOOTH_NOT_READY) -DOM4_MSG_DEF(BtNoMemError, "No memory", NS_ERROR_DOM_BLUETOOTH_NOMEM) -DOM4_MSG_DEF(BtBusyError, "Device busy with another command", NS_ERROR_DOM_BLUETOOTH_BUSY) -DOM4_MSG_DEF(BtDoneError, "Request already done", NS_ERROR_DOM_BLUETOOTH_DONE) -DOM4_MSG_DEF(BtUnsupportedError, "Unsupported", NS_ERROR_DOM_BLUETOOTH_UNSUPPORTED) -DOM4_MSG_DEF(BtParmInvalidError, "Invalid parameter", NS_ERROR_DOM_BLUETOOTH_PARM_INVALID) -DOM4_MSG_DEF(BtUnhandledError, "Unhandled", NS_ERROR_DOM_BLUETOOTH_UNHANDLED) -DOM4_MSG_DEF(BtAuthFailureError, "Authentication failure", NS_ERROR_DOM_BLUETOOTH_AUTH_FAILURE) -DOM4_MSG_DEF(BtRmtDevDownError, "Remote device down", NS_ERROR_DOM_BLUETOOTH_RMT_DEV_DOWN) -DOM4_MSG_DEF(BtAuthRejectedError, "Authentication rejected", NS_ERROR_DOM_BLUETOOTH_AUTH_REJECTED) - /* Web Animations errors */ DOM4_MSG_DEF(NotSupportedError, "Animation to or from an underlying value is not yet supported.", NS_ERROR_DOM_ANIM_MISSING_PROPS_ERR) /* common global codes (from nsError.h) */ DOM_MSG_DEF(NS_OK , "Success") DOM_MSG_DEF(NS_ERROR_NOT_INITIALIZED , "Component not initialized")
--- a/dom/base/moz.build +++ b/dom/base/moz.build @@ -416,18 +416,16 @@ if CONFIG['MOZ_BUILD_APP'] != 'mobile/an EXTRA_JS_MODULES += [ 'DOMRequestHelper.jsm', 'IndexedDBHelper.jsm', ] LOCAL_INCLUDES += [ '../battery', - '../bluetooth/common', - '../bluetooth/common/webapi', '../events', '../media', '../network', '../time', '/caps', '/docshell/base', '/dom/base', '/dom/geolocation',
--- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -102,85 +102,16 @@ DOMInterfaces = { 'headerFile': 'mozilla/dom/File.h', }, 'BatteryManager': { 'nativeType': 'mozilla::dom::battery::BatteryManager', 'headerFile': 'BatteryManager.h' }, -'BluetoothAdapter': { - 'nativeType': 'mozilla::dom::bluetooth::BluetoothAdapter', -}, - -'BluetoothClassOfDevice': { - 'nativeType': 'mozilla::dom::bluetooth::BluetoothClassOfDevice', -}, - -'BluetoothDevice': { - 'nativeType': 'mozilla::dom::bluetooth::BluetoothDevice', -}, - -'BluetoothDiscoveryHandle': { - 'nativeType': 'mozilla::dom::bluetooth::BluetoothDiscoveryHandle', -}, - -'BluetoothGatt': { - 'nativeType': 'mozilla::dom::bluetooth::BluetoothGatt', -}, - -'BluetoothGattAttributeEvent': { - 'nativeType': 'mozilla::dom::bluetooth::BluetoothGattAttributeEvent', -}, - -'BluetoothGattCharacteristic': { - 'nativeType': 'mozilla::dom::bluetooth::BluetoothGattCharacteristic', -}, - -'BluetoothGattDescriptor': { - 'nativeType': 'mozilla::dom::bluetooth::BluetoothGattDescriptor', -}, - -'BluetoothGattServer': { - 'nativeType': 'mozilla::dom::bluetooth::BluetoothGattServer', -}, - -'BluetoothGattService': { - 'nativeType': 'mozilla::dom::bluetooth::BluetoothGattService', -}, - -'BluetoothLeDeviceEvent': { - 'nativeType': 'mozilla::dom::bluetooth::BluetoothLeDeviceEvent', -}, - -'BluetoothManager': { - 'nativeType': 'mozilla::dom::bluetooth::BluetoothManager', -}, - -'BluetoothObexAuthHandle': { - 'nativeType': 'mozilla::dom::bluetooth::BluetoothObexAuthHandle', -}, - -'BluetoothPairingHandle': { - 'nativeType': 'mozilla::dom::bluetooth::BluetoothPairingHandle', -}, - -'BluetoothPairingListener': { - 'nativeType': - 'mozilla::dom::bluetooth::BluetoothPairingListener', -}, - -'BluetoothPbapRequestHandle': { - 'nativeType': 'mozilla::dom::bluetooth::BluetoothPbapRequestHandle', -}, - -'BluetoothMapRequestHandle': { - 'nativeType': 'mozilla::dom::bluetooth::BluetoothMapRequestHandle', -}, - 'BoxObject': { 'resultNotAddRefed': ['element'], }, 'Cache': { 'implicitJSContext': [ 'add', 'addAll' ], 'nativeType': 'mozilla::dom::cache::Cache', },
--- a/dom/bindings/Exceptions.cpp +++ b/dom/bindings/Exceptions.cpp @@ -188,17 +188,16 @@ CreateException(JSContext* aCx, nsresult { // Do we use DOM exceptions for this error code? switch (NS_ERROR_GET_MODULE(aRv)) { case NS_ERROR_MODULE_DOM: case NS_ERROR_MODULE_SVG: case NS_ERROR_MODULE_DOM_XPATH: case NS_ERROR_MODULE_DOM_INDEXEDDB: case NS_ERROR_MODULE_DOM_FILEHANDLE: - case NS_ERROR_MODULE_DOM_BLUETOOTH: case NS_ERROR_MODULE_DOM_ANIM: case NS_ERROR_MODULE_DOM_PUSH: case NS_ERROR_MODULE_DOM_MEDIA: if (aMessage.IsEmpty()) { return DOMException::Create(aRv); } return DOMException::Create(aRv, aMessage); default:
--- a/dom/bindings/moz.build +++ b/dom/bindings/moz.build @@ -54,17 +54,16 @@ EXPORTS.mozilla.dom += [ # Bug 932082 tracks. LOCAL_INCLUDES += [ '!/dist/include/mozilla/dom', ] LOCAL_INCLUDES += [ '/dom/base', '/dom/battery', - '/dom/bluetooth/common/webapi', '/dom/canvas', '/dom/geolocation', '/dom/html', '/dom/indexedDB', '/dom/media/webaudio', '/dom/media/webspeech/recognition', '/dom/svg', '/dom/workers',
deleted file mode 100644 --- a/dom/bluetooth/bluedroid/BluetoothA2dpManager.cpp +++ /dev/null @@ -1,779 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "base/basictypes.h" - -#include "BluetoothA2dpManager.h" -#include "BluetoothCommon.h" -#include "BluetoothService.h" -#include "BluetoothSocket.h" -#include "BluetoothUtils.h" - -#include "mozilla/dom/bluetooth/BluetoothTypes.h" -#include "mozilla/Services.h" -#include "mozilla/StaticPtr.h" -#include "MainThreadUtils.h" -#include "nsIObserverService.h" -#include "nsThreadUtils.h" - -using namespace mozilla; -USING_BLUETOOTH_NAMESPACE -// AVRC_ID op code follows bluedroid avrc_defs.h -#define AVRC_ID_REWIND 0x48 -#define AVRC_ID_FAST_FOR 0x49 -#define AVRC_KEY_PRESS_STATE 1 -#define AVRC_KEY_RELEASE_STATE 0 -// bluedroid bt_rc.h -#define AVRC_MAX_ATTR_STR_LEN 255 - -namespace { - StaticRefPtr<BluetoothA2dpManager> sBluetoothA2dpManager; - bool sInShutdown = false; - static BluetoothA2dpInterface* sBtA2dpInterface; -} // namespace - -const int BluetoothA2dpManager::MAX_NUM_CLIENTS = 1; - -NS_IMETHODIMP -BluetoothA2dpManager::Observe(nsISupports* aSubject, - const char* aTopic, - const char16_t* aData) -{ - MOZ_ASSERT(sBluetoothA2dpManager); - - if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) { - HandleShutdown(); - return NS_OK; - } - - MOZ_ASSERT(false, "BluetoothA2dpManager got unexpected topic!"); - return NS_ERROR_UNEXPECTED; -} - -BluetoothA2dpManager::BluetoothA2dpManager() -{ - Reset(); -} - -void -BluetoothA2dpManager::Reset() -{ - mA2dpConnected = false; - mSinkState = SinkState::SINK_DISCONNECTED; - mController = nullptr; -} - -static void -AvStatusToSinkString(BluetoothA2dpConnectionState aState, nsAString& aString) -{ - switch (aState) { - case A2DP_CONNECTION_STATE_DISCONNECTED: - aString.AssignLiteral("disconnected"); - break; - case A2DP_CONNECTION_STATE_CONNECTING: - aString.AssignLiteral("connecting"); - break; - case A2DP_CONNECTION_STATE_CONNECTED: - aString.AssignLiteral("connected"); - break; - case A2DP_CONNECTION_STATE_DISCONNECTING: - aString.AssignLiteral("disconnecting"); - break; - default: - BT_WARNING("Unknown sink state %d", static_cast<int>(aState)); - return; - } -} - -class BluetoothA2dpManager::RegisterModuleResultHandler final - : public BluetoothSetupResultHandler -{ -public: - RegisterModuleResultHandler(BluetoothA2dpInterface* aInterface, - BluetoothProfileResultHandler* aRes) - : mInterface(aInterface) - , mRes(aRes) - { } - - void OnError(BluetoothStatus aStatus) override - { - MOZ_ASSERT(NS_IsMainThread()); - - BT_WARNING("BluetoothSetupInterface::RegisterModule failed for A2DP: %d", - (int)aStatus); - - mInterface->SetNotificationHandler(nullptr); - - if (mRes) { - mRes->OnError(NS_ERROR_FAILURE); - } - } - - void RegisterModule() override - { - MOZ_ASSERT(NS_IsMainThread()); - - sBtA2dpInterface = mInterface; - - if (mRes) { - mRes->Init(); - } - } - -private: - BluetoothA2dpInterface* mInterface; - RefPtr<BluetoothProfileResultHandler> mRes; -}; - -class BluetoothA2dpManager::InitProfileResultHandlerRunnable final - : public Runnable -{ -public: - InitProfileResultHandlerRunnable(BluetoothProfileResultHandler* aRes, - nsresult aRv) - : mRes(aRes) - , mRv(aRv) - { - MOZ_ASSERT(mRes); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(NS_IsMainThread()); - - if (NS_SUCCEEDED(mRv)) { - mRes->Init(); - } else { - mRes->OnError(mRv); - } - return NS_OK; - } - -private: - RefPtr<BluetoothProfileResultHandler> mRes; - nsresult mRv; -}; - -/* - * This function will be only called when Bluetooth is turning on. - * It is important to register a2dp callbacks before enable() gets called. - * It is required to register a2dp callbacks before a2dp media task - * starts up. - */ -// static -void -BluetoothA2dpManager::InitA2dpInterface(BluetoothProfileResultHandler* aRes) -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (sBtA2dpInterface) { - BT_LOGR("Bluetooth A2DP interface is already initalized."); - RefPtr<Runnable> r = - new InitProfileResultHandlerRunnable(aRes, NS_OK); - if (NS_FAILED(NS_DispatchToMainThread(r))) { - BT_LOGR("Failed to dispatch A2DP Init runnable"); - } - return; - } - - auto btInf = BluetoothInterface::GetInstance(); - - if (NS_WARN_IF(!btInf)) { - // If there's no Bluetooth interface, we dispatch a runnable - // that calls the profile result handler. - RefPtr<Runnable> r = - new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE); - if (NS_FAILED(NS_DispatchToMainThread(r))) { - BT_LOGR("Failed to dispatch A2DP OnError runnable"); - } - return; - } - - auto setupInterface = btInf->GetBluetoothSetupInterface(); - - if (NS_WARN_IF(!setupInterface)) { - // If there's no Setup interface, we dispatch a runnable - // that calls the profile result handler. - RefPtr<Runnable> r = - new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE); - if (NS_FAILED(NS_DispatchToMainThread(r))) { - BT_LOGR("Failed to dispatch A2DP OnError runnable"); - } - return; - } - - auto a2dpInterface = btInf->GetBluetoothA2dpInterface(); - - if (NS_WARN_IF(!a2dpInterface)) { - // If there's no A2DP interface, we dispatch a runnable - // that calls the profile result handler. - RefPtr<Runnable> r = - new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE); - if (NS_FAILED(NS_DispatchToMainThread(r))) { - BT_LOGR("Failed to dispatch A2DP OnError runnable"); - } - return; - } - - // Set notification handler _before_ registering the module. It could - // happen that we receive notifications, before the result handler runs. - a2dpInterface->SetNotificationHandler(BluetoothA2dpManager::Get()); - - setupInterface->RegisterModule( - SETUP_SERVICE_ID_A2DP, 0, MAX_NUM_CLIENTS, - new RegisterModuleResultHandler(a2dpInterface, aRes)); -} - -BluetoothA2dpManager::~BluetoothA2dpManager() -{ } - -void -BluetoothA2dpManager::Uninit() -{ - nsCOMPtr<nsIObserverService> obs = services::GetObserverService(); - NS_ENSURE_TRUE_VOID(obs); - if (NS_FAILED(obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID))) { - BT_WARNING("Failed to remove shutdown observer!"); - } -} - -/* - * Static functions - */ - -static BluetoothA2dpManager::SinkState -StatusStringToSinkState(const nsAString& aStatus) -{ - BluetoothA2dpManager::SinkState state = - BluetoothA2dpManager::SinkState::SINK_UNKNOWN; - if (aStatus.EqualsLiteral("disconnected")) { - state = BluetoothA2dpManager::SinkState::SINK_DISCONNECTED; - } else if (aStatus.EqualsLiteral("connecting")) { - state = BluetoothA2dpManager::SinkState::SINK_CONNECTING; - } else if (aStatus.EqualsLiteral("connected")) { - state = BluetoothA2dpManager::SinkState::SINK_CONNECTED; - } else if (aStatus.EqualsLiteral("playing")) { - state = BluetoothA2dpManager::SinkState::SINK_PLAYING; - } else { - BT_WARNING("Unknown sink state"); - } - return state; -} - -//static -BluetoothA2dpManager* -BluetoothA2dpManager::Get() -{ - MOZ_ASSERT(NS_IsMainThread()); - - // If sBluetoothA2dpManager already exists, exit early - if (sBluetoothA2dpManager) { - return sBluetoothA2dpManager; - } - - // If we're in shutdown, don't create a new instance - NS_ENSURE_FALSE(sInShutdown, nullptr); - - // Create a new instance and return - sBluetoothA2dpManager = new BluetoothA2dpManager(); - - return sBluetoothA2dpManager; -} - -class BluetoothA2dpManager::UnregisterModuleResultHandler final - : public BluetoothSetupResultHandler -{ -public: - UnregisterModuleResultHandler(BluetoothProfileResultHandler* aRes) - : mRes(aRes) - { } - - void OnError(BluetoothStatus aStatus) override - { - MOZ_ASSERT(NS_IsMainThread()); - - BT_WARNING("BluetoothSetupInterface::UnregisterModule failed for A2DP: %d", - (int)aStatus); - - sBtA2dpInterface->SetNotificationHandler(nullptr); - sBtA2dpInterface = nullptr; - - sBluetoothA2dpManager->Uninit(); - sBluetoothA2dpManager = nullptr; - - if (mRes) { - mRes->OnError(NS_ERROR_FAILURE); - } - } - - void UnregisterModule() override - { - MOZ_ASSERT(NS_IsMainThread()); - - sBtA2dpInterface->SetNotificationHandler(nullptr); - sBtA2dpInterface = nullptr; - - sBluetoothA2dpManager->Uninit(); - sBluetoothA2dpManager = nullptr; - - if (mRes) { - mRes->Deinit(); - } - } - -private: - RefPtr<BluetoothProfileResultHandler> mRes; -}; - -class BluetoothA2dpManager::DeinitProfileResultHandlerRunnable final - : public Runnable -{ -public: - DeinitProfileResultHandlerRunnable(BluetoothProfileResultHandler* aRes, - nsresult aRv) - : mRes(aRes) - , mRv(aRv) - { - MOZ_ASSERT(mRes); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(NS_IsMainThread()); - - if (NS_SUCCEEDED(mRv)) { - mRes->Deinit(); - } else { - mRes->OnError(mRv); - } - return NS_OK; - } - -private: - RefPtr<BluetoothProfileResultHandler> mRes; - nsresult mRv; -}; - -// static -void -BluetoothA2dpManager::DeinitA2dpInterface(BluetoothProfileResultHandler* aRes) -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (!sBtA2dpInterface) { - BT_LOGR("Bluetooth A2DP interface has not been initalized."); - RefPtr<Runnable> r = - new DeinitProfileResultHandlerRunnable(aRes, NS_OK); - if (NS_FAILED(NS_DispatchToMainThread(r))) { - BT_LOGR("Failed to dispatch A2DP Deinit runnable"); - } - return; - } - - auto btInf = BluetoothInterface::GetInstance(); - - if (NS_WARN_IF(!btInf)) { - // If there's no backend interface, we dispatch a runnable - // that calls the profile result handler. - RefPtr<Runnable> r = - new DeinitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE); - if (NS_FAILED(NS_DispatchToMainThread(r))) { - BT_LOGR("Failed to dispatch A2DP OnError runnable"); - } - return; - } - - auto setupInterface = btInf->GetBluetoothSetupInterface(); - - if (NS_WARN_IF(!setupInterface)) { - // If there's no Setup interface, we dispatch a runnable - // that calls the profile result handler. - RefPtr<Runnable> r = - new DeinitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE); - if (NS_FAILED(NS_DispatchToMainThread(r))) { - BT_LOGR("Failed to dispatch A2DP OnError runnable"); - } - return; - } - - setupInterface->UnregisterModule( - SETUP_SERVICE_ID_A2DP, - new UnregisterModuleResultHandler(aRes)); -} - -void -BluetoothA2dpManager::HandleShutdown() -{ - MOZ_ASSERT(NS_IsMainThread()); - sInShutdown = true; - Disconnect(nullptr); - sBluetoothA2dpManager = nullptr; -} - -void -BluetoothA2dpManager::OnConnectError() -{ - MOZ_ASSERT(NS_IsMainThread()); - - mController->NotifyCompletion(NS_LITERAL_STRING(ERR_CONNECTION_FAILED)); - - mController = nullptr; - mDeviceAddress.Clear(); -} - -class BluetoothA2dpManager::ConnectResultHandler final - : public BluetoothA2dpResultHandler -{ -public: - void OnError(BluetoothStatus aStatus) override - { - BT_LOGR("BluetoothA2dpInterface::Connect failed: %d", (int)aStatus); - - NS_ENSURE_TRUE_VOID(sBluetoothA2dpManager); - sBluetoothA2dpManager->OnConnectError(); - } -}; - -void -BluetoothA2dpManager::Connect(const BluetoothAddress& aDeviceAddress, - BluetoothProfileController* aController) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(!aDeviceAddress.IsCleared()); - MOZ_ASSERT(aController); - - BluetoothService* bs = BluetoothService::Get(); - if (!bs || sInShutdown) { - aController->NotifyCompletion(NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE)); - return; - } - - if (mA2dpConnected) { - aController->NotifyCompletion(NS_LITERAL_STRING(ERR_ALREADY_CONNECTED)); - return; - } - - mDeviceAddress = aDeviceAddress; - mController = aController; - - if (!sBtA2dpInterface) { - BT_LOGR("sBluetoothA2dpInterface is null"); - aController->NotifyCompletion(NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE)); - return; - } - - sBtA2dpInterface->Connect(mDeviceAddress, new ConnectResultHandler()); -} - -void -BluetoothA2dpManager::OnDisconnectError() -{ - MOZ_ASSERT(NS_IsMainThread()); - NS_ENSURE_TRUE_VOID(mController); - - mController->NotifyCompletion(NS_LITERAL_STRING(ERR_DISCONNECTION_FAILED)); -} - -class BluetoothA2dpManager::DisconnectResultHandler final - : public BluetoothA2dpResultHandler -{ -public: - void OnError(BluetoothStatus aStatus) override - { - BT_LOGR("BluetoothA2dpInterface::Disconnect failed: %d", (int)aStatus); - - NS_ENSURE_TRUE_VOID(sBluetoothA2dpManager); - sBluetoothA2dpManager->OnDisconnectError(); - } -}; - -void -BluetoothA2dpManager::Disconnect(BluetoothProfileController* aController) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(!mController); - - BluetoothService* bs = BluetoothService::Get(); - if (!bs) { - if (aController) { - aController->NotifyCompletion( - NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE)); - } - return; - } - - if (!mA2dpConnected) { - if (aController) { - aController->NotifyCompletion( - NS_LITERAL_STRING(ERR_ALREADY_DISCONNECTED)); - } - return; - } - - MOZ_ASSERT(!mDeviceAddress.IsCleared()); - - mController = aController; - - if (!sBtA2dpInterface) { - BT_LOGR("sBluetoothA2dpInterface is null"); - if (aController) { - aController->NotifyCompletion( - NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE)); - } - return; - } - - sBtA2dpInterface->Disconnect(mDeviceAddress, new DisconnectResultHandler()); -} - -void -BluetoothA2dpManager::OnConnect(const nsAString& aErrorStr) -{ - MOZ_ASSERT(NS_IsMainThread()); - - /** - * On the one hand, notify the controller that we've done for outbound - * connections. On the other hand, we do nothing for inbound connections. - */ - NS_ENSURE_TRUE_VOID(mController); - - RefPtr<BluetoothProfileController> controller = mController.forget(); - controller->NotifyCompletion(aErrorStr); -} - -void -BluetoothA2dpManager::OnDisconnect(const nsAString& aErrorStr) -{ - MOZ_ASSERT(NS_IsMainThread()); - - /** - * On the one hand, notify the controller that we've done for outbound - * connections. On the other hand, we do nothing for inbound connections. - */ - NS_ENSURE_TRUE_VOID(mController); - - RefPtr<BluetoothProfileController> controller = mController.forget(); - controller->NotifyCompletion(aErrorStr); - - Reset(); -} - -/* HandleSinkPropertyChanged update sink state in A2dp - * - * Possible values: "disconnected", "connecting", "connected", "playing" - * - * 1. "disconnected" -> "connecting" - * Either an incoming or outgoing connection attempt ongoing - * 2. "connecting" -> "disconnected" - * Connection attempt failed - * 3. "connecting" -> "connected" - * Successfully connected - * 4. "connected" -> "playing" - * Audio stream active - * 5. "playing" -> "connected" - * Audio stream suspended - * 6. "connected" -> "disconnected" - * "playing" -> "disconnected" - * Disconnected from local or the remote device - */ -void -BluetoothA2dpManager::HandleSinkPropertyChanged(const BluetoothSignal& aSignal) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(aSignal.value().type() == - BluetoothValue::TArrayOfBluetoothNamedValue); - - BluetoothAddress address; - NS_ENSURE_TRUE_VOID(NS_SUCCEEDED(StringToAddress(aSignal.path(), address))); - - /** - * Update sink property only if - * - mDeviceAddress is empty (A2dp is disconnected), or - * - this property change is from the connected sink. - */ - NS_ENSURE_TRUE_VOID(mDeviceAddress.IsCleared() || mDeviceAddress == address); - - const InfallibleTArray<BluetoothNamedValue>& arr = - aSignal.value().get_ArrayOfBluetoothNamedValue(); - MOZ_ASSERT(arr.Length() == 1); - - /** - * There are three properties: - * - "State": a string - * - "Connected": a boolean value - * - "Playing": a boolean value - * - * Note that only "State" is handled in this function. - */ - - const nsString& name = arr[0].name(); - NS_ENSURE_TRUE_VOID(name.EqualsLiteral("State")); - - const BluetoothValue& value = arr[0].value(); - MOZ_ASSERT(value.type() == BluetoothValue::TnsString); - SinkState newState = StatusStringToSinkState(value.get_nsString()); - NS_ENSURE_TRUE_VOID((newState != SinkState::SINK_UNKNOWN) && - (newState != mSinkState)); - - SinkState prevState = mSinkState; - mSinkState = newState; - - switch(mSinkState) { - case SinkState::SINK_CONNECTING: - // case 1: Either an incoming or outgoing connection attempt ongoing - MOZ_ASSERT(prevState == SinkState::SINK_DISCONNECTED); - break; - case SinkState::SINK_PLAYING: - // case 4: Audio stream active - MOZ_ASSERT(prevState == SinkState::SINK_CONNECTED); - break; - case SinkState::SINK_CONNECTED: - // case 5: Audio stream suspended - if (prevState == SinkState::SINK_PLAYING || - prevState == SinkState::SINK_CONNECTED) { - break; - } - - // case 3: Successfully connected - mA2dpConnected = true; - mDeviceAddress = address; - NotifyConnectionStatusChanged(); - - OnConnect(EmptyString()); - break; - case SinkState::SINK_DISCONNECTED: - // case 2: Connection attempt failed - if (prevState == SinkState::SINK_CONNECTING) { - OnConnect(NS_LITERAL_STRING(ERR_CONNECTION_FAILED)); - break; - } - - // case 6: Disconnected from the remote device - MOZ_ASSERT(prevState == SinkState::SINK_CONNECTED || - prevState == SinkState::SINK_PLAYING) ; - - mA2dpConnected = false; - NotifyConnectionStatusChanged(); - mDeviceAddress.Clear(); - OnDisconnect(EmptyString()); - break; - default: - break; - } -} - -/* - * Reset connection state to DISCONNECTED to handle backend error. The state - * change triggers UI status bar update as ordinary bluetooth turn-off sequence. - */ -void -BluetoothA2dpManager::HandleBackendError() -{ - if (mSinkState != SinkState::SINK_DISCONNECTED) { - ConnectionStateNotification(A2DP_CONNECTION_STATE_DISCONNECTED, - mDeviceAddress); - } -} - -void -BluetoothA2dpManager::NotifyConnectionStatusChanged() -{ - MOZ_ASSERT(NS_IsMainThread()); - - // Notify Gecko observers - nsCOMPtr<nsIObserverService> obs = services::GetObserverService(); - NS_ENSURE_TRUE_VOID(obs); - - nsAutoString deviceAddressStr; - AddressToString(mDeviceAddress, deviceAddressStr); - - if (NS_FAILED(obs->NotifyObservers(this, - BLUETOOTH_A2DP_STATUS_CHANGED_ID, - deviceAddressStr.get()))) { - BT_WARNING("Failed to notify bluetooth-a2dp-status-changed observsers!"); - } - - // Dispatch an event of status change - DispatchStatusChangedEvent( - NS_LITERAL_STRING(A2DP_STATUS_CHANGED_ID), mDeviceAddress, mA2dpConnected); -} - -void -BluetoothA2dpManager::OnGetServiceChannel(const BluetoothAddress& aDeviceAddress, - const BluetoothUuid& aServiceUuid, - int aChannel) -{ -} - -void -BluetoothA2dpManager::OnUpdateSdpRecords(const BluetoothAddress& aDeviceAddress) -{ -} - -void -BluetoothA2dpManager::GetAddress(BluetoothAddress& aDeviceAddress) -{ - aDeviceAddress = mDeviceAddress; -} - -bool -BluetoothA2dpManager::IsConnected() -{ - return mA2dpConnected; -} - -/* - * Notifications - */ - -void -BluetoothA2dpManager::ConnectionStateNotification( - BluetoothA2dpConnectionState aState, const BluetoothAddress& aBdAddr) -{ - MOZ_ASSERT(NS_IsMainThread()); - - nsString a2dpState; - AvStatusToSinkString(aState, a2dpState); - - InfallibleTArray<BluetoothNamedValue> props; - AppendNamedValue(props, "State", a2dpState); - - nsAutoString addressStr; - AddressToString(aBdAddr, addressStr); - - HandleSinkPropertyChanged(BluetoothSignal(NS_LITERAL_STRING("AudioSink"), - addressStr, props)); -} - -void -BluetoothA2dpManager::AudioStateNotification(BluetoothA2dpAudioState aState, - const BluetoothAddress& aBdAddr) -{ - MOZ_ASSERT(NS_IsMainThread()); - - nsString a2dpState; - - if (aState == A2DP_AUDIO_STATE_STARTED) { - a2dpState = NS_LITERAL_STRING("playing"); - } else if (aState == A2DP_AUDIO_STATE_STOPPED) { - // for avdtp state stop stream - a2dpState = NS_LITERAL_STRING("connected"); - } else if (aState == A2DP_AUDIO_STATE_REMOTE_SUSPEND) { - // for avdtp state suspend stream from remote side - a2dpState = NS_LITERAL_STRING("connected"); - } - - InfallibleTArray<BluetoothNamedValue> props; - AppendNamedValue(props, "State", a2dpState); - - nsAutoString addressStr; - AddressToString(aBdAddr, addressStr); - - HandleSinkPropertyChanged(BluetoothSignal(NS_LITERAL_STRING("AudioSink"), - addressStr, props)); -} - -NS_IMPL_ISUPPORTS(BluetoothA2dpManager, nsIObserver)
deleted file mode 100644 --- a/dom/bluetooth/bluedroid/BluetoothA2dpManager.h +++ /dev/null @@ -1,80 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_bluetooth_bluedroid_BluetoothA2dpManager_h -#define mozilla_dom_bluetooth_bluedroid_BluetoothA2dpManager_h - -#include "BluetoothCommon.h" -#include "BluetoothInterface.h" -#include "BluetoothProfileController.h" -#include "BluetoothProfileManagerBase.h" - -BEGIN_BLUETOOTH_NAMESPACE -class BluetoothA2dpManager : public BluetoothProfileManagerBase - , public BluetoothA2dpNotificationHandler -{ -public: - static const int MAX_NUM_CLIENTS; - - BT_DECL_PROFILE_MGR_BASE - virtual void GetName(nsACString& aName) - { - aName.AssignLiteral("A2DP"); - } - - enum SinkState { - SINK_UNKNOWN, - SINK_DISCONNECTED, - SINK_CONNECTING, - SINK_CONNECTED, - SINK_PLAYING, - }; - - static BluetoothA2dpManager* Get(); - static void InitA2dpInterface(BluetoothProfileResultHandler* aRes); - static void DeinitA2dpInterface(BluetoothProfileResultHandler* aRes); - - void OnConnectError(); - void OnDisconnectError(); - - // A2DP-specific functions - void HandleSinkPropertyChanged(const BluetoothSignal& aSignal); - - void HandleBackendError(); - -protected: - virtual ~BluetoothA2dpManager(); - -private: - class ConnectResultHandler; - class DeinitProfileResultHandlerRunnable; - class DisconnectResultHandler; - class InitProfileResultHandlerRunnable; - class RegisterModuleResultHandler; - class UnregisterModuleResultHandler; - - BluetoothA2dpManager(); - - void Uninit(); - void HandleShutdown(); - void NotifyConnectionStatusChanged(); - - void ConnectionStateNotification(BluetoothA2dpConnectionState aState, - const BluetoothAddress& aBdAddr) override; - void AudioStateNotification(BluetoothA2dpAudioState aState, - const BluetoothAddress& aBdAddr) override; - - BluetoothAddress mDeviceAddress; - RefPtr<BluetoothProfileController> mController; - - // A2DP data member - bool mA2dpConnected; - SinkState mSinkState; -}; - -END_BLUETOOTH_NAMESPACE - -#endif
deleted file mode 100644 --- a/dom/bluetooth/bluedroid/BluetoothAvrcpManager.cpp +++ /dev/null @@ -1,951 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "base/basictypes.h" - -#include "BluetoothAvrcpManager.h" -#include "BluetoothCommon.h" -#include "BluetoothService.h" -#include "BluetoothSocket.h" -#include "BluetoothUtils.h" - -#include "mozilla/dom/bluetooth/BluetoothTypes.h" -#include "mozilla/Services.h" -#include "mozilla/StaticPtr.h" -#include "mozilla/UniquePtr.h" -#include "MainThreadUtils.h" -#include "nsIObserverService.h" -#include "nsThreadUtils.h" - -using namespace mozilla; -USING_BLUETOOTH_NAMESPACE -// AVRC_ID op code follows bluedroid avrc_defs.h -#define AVRC_ID_REWIND 0x48 -#define AVRC_ID_FAST_FOR 0x49 -#define AVRC_KEY_PRESS_STATE 1 -#define AVRC_KEY_RELEASE_STATE 0 -// bluedroid bt_rc.h -#define AVRC_MAX_ATTR_STR_LEN 255 - -namespace { - StaticRefPtr<BluetoothAvrcpManager> sBluetoothAvrcpManager; - bool sInShutdown = false; - static BluetoothAvrcpInterface* sBtAvrcpInterface; -} // namespace - -const int BluetoothAvrcpManager::MAX_NUM_CLIENTS = 1; - -/* - * This function maps attribute id and returns corresponding values - */ -static void -ConvertAttributeString(BluetoothAvrcpMediaAttribute aAttrId, - nsAString& aAttrStr) -{ - BluetoothAvrcpManager* avrcp = BluetoothAvrcpManager::Get(); - NS_ENSURE_TRUE_VOID(avrcp); - - switch (aAttrId) { - case AVRCP_MEDIA_ATTRIBUTE_TITLE: - avrcp->GetTitle(aAttrStr); - /* - * bluedroid can only send string length AVRC_MAX_ATTR_STR_LEN - 1 - */ - if (aAttrStr.Length() >= AVRC_MAX_ATTR_STR_LEN) { - aAttrStr.Truncate(AVRC_MAX_ATTR_STR_LEN - 1); - BT_WARNING("Truncate media item attribute title, length is over 255"); - } - break; - case AVRCP_MEDIA_ATTRIBUTE_ARTIST: - avrcp->GetArtist(aAttrStr); - if (aAttrStr.Length() >= AVRC_MAX_ATTR_STR_LEN) { - aAttrStr.Truncate(AVRC_MAX_ATTR_STR_LEN - 1); - BT_WARNING("Truncate media item attribute artist, length is over 255"); - } - break; - case AVRCP_MEDIA_ATTRIBUTE_ALBUM: - avrcp->GetAlbum(aAttrStr); - if (aAttrStr.Length() >= AVRC_MAX_ATTR_STR_LEN) { - aAttrStr.Truncate(AVRC_MAX_ATTR_STR_LEN - 1); - BT_WARNING("Truncate media item attribute album, length is over 255"); - } - break; - case AVRCP_MEDIA_ATTRIBUTE_TRACK_NUM: - aAttrStr.AppendInt(avrcp->GetMediaNumber()); - break; - case AVRCP_MEDIA_ATTRIBUTE_NUM_TRACKS: - aAttrStr.AppendInt(avrcp->GetTotalMediaNumber()); - break; - case AVRCP_MEDIA_ATTRIBUTE_GENRE: - // TODO: we currently don't support genre from music player - aAttrStr.Truncate(); - break; - case AVRCP_MEDIA_ATTRIBUTE_PLAYING_TIME: - aAttrStr.AppendInt(avrcp->GetDuration()); - break; - } -} - -NS_IMETHODIMP -BluetoothAvrcpManager::Observe(nsISupports* aSubject, - const char* aTopic, - const char16_t* aData) -{ - MOZ_ASSERT(sBluetoothAvrcpManager); - - if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) { - HandleShutdown(); - return NS_OK; - } - - MOZ_ASSERT(false, "BluetoothAvrcpManager got unexpected topic!"); - return NS_ERROR_UNEXPECTED; -} - -BluetoothAvrcpManager::BluetoothAvrcpManager() -{ - Reset(); -} - -void -BluetoothAvrcpManager::Reset() -{ - mAvrcpConnected = false; - mDuration = 0; - mMediaNumber = 0; - mTotalMediaCount = 0; - mPosition = 0; - mPlayStatus = ControlPlayStatus::PLAYSTATUS_STOPPED; -} - -class BluetoothAvrcpManager::RegisterModuleResultHandler final - : public BluetoothSetupResultHandler -{ -public: - RegisterModuleResultHandler(BluetoothAvrcpInterface* aInterface, - BluetoothProfileResultHandler* aRes) - : mInterface(aInterface) - , mRes(aRes) - { - MOZ_ASSERT(mInterface); - } - - void OnError(BluetoothStatus aStatus) override - { - MOZ_ASSERT(NS_IsMainThread()); - - BT_WARNING("BluetoothSetupInterface::RegisterModule failed for AVRCP: %d", - (int)aStatus); - - mInterface->SetNotificationHandler(nullptr); - - if (mRes) { - if (aStatus == STATUS_UNSUPPORTED) { - /* Not all versions of Bluedroid support AVRCP. So if the - * initialization fails with STATUS_UNSUPPORTED, we still - * signal success. - */ - mRes->Init(); - } else { - mRes->OnError(NS_ERROR_FAILURE); - } - } - } - - void RegisterModule() override - { - MOZ_ASSERT(NS_IsMainThread()); - - sBtAvrcpInterface = mInterface; - - if (mRes) { - mRes->Init(); - } - } - -private: - BluetoothAvrcpInterface* mInterface; - RefPtr<BluetoothProfileResultHandler> mRes; -}; - -class BluetoothAvrcpManager::InitProfileResultHandlerRunnable final - : public Runnable -{ -public: - InitProfileResultHandlerRunnable(BluetoothProfileResultHandler* aRes, - nsresult aRv) - : mRes(aRes) - , mRv(aRv) - { - MOZ_ASSERT(mRes); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(NS_IsMainThread()); - - if (NS_SUCCEEDED(mRv)) { - mRes->Init(); - } else { - mRes->OnError(mRv); - } - return NS_OK; - } - -private: - RefPtr<BluetoothProfileResultHandler> mRes; - nsresult mRv; -}; - -/* - * This function will be only called when Bluetooth is turning on. - */ -// static -void -BluetoothAvrcpManager::InitAvrcpInterface(BluetoothProfileResultHandler* aRes) -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (sBtAvrcpInterface) { - BT_LOGR("Bluetooth AVRCP interface is already initalized."); - RefPtr<Runnable> r = - new InitProfileResultHandlerRunnable(aRes, NS_OK); - if (NS_FAILED(NS_DispatchToMainThread(r))) { - BT_LOGR("Failed to dispatch AVRCP Init runnable"); - } - return; - } - - auto btInf = BluetoothInterface::GetInstance(); - - if (NS_WARN_IF(!btInf)) { - // If there's no Bluetooth interface, we dispatch a runnable - // that calls the profile result handler. - RefPtr<Runnable> r = - new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE); - if (NS_FAILED(NS_DispatchToMainThread(r))) { - BT_LOGR("Failed to dispatch AVRCP OnError runnable"); - } - return; - } - - auto setupInterface = btInf->GetBluetoothSetupInterface(); - - if (NS_WARN_IF(!setupInterface)) { - // If there's no Setup interface, we dispatch a runnable - // that calls the profile result handler. - RefPtr<Runnable> r = - new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE); - if (NS_FAILED(NS_DispatchToMainThread(r))) { - BT_LOGR("Failed to dispatch AVRCP OnError runnable"); - } - return; - } - - auto avrcpInterface = btInf->GetBluetoothAvrcpInterface(); - - if (NS_WARN_IF(!avrcpInterface)) { - // If there's no AVRCP interface, we dispatch a runnable - // that calls the profile result handler. - RefPtr<Runnable> r = - new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE); - if (NS_FAILED(NS_DispatchToMainThread(r))) { - BT_LOGR("Failed to dispatch AVRCP OnError runnable"); - } - return; - } - - // Set notification handler _before_ registering the module. It could - // happen that we receive notifications, before the result handler runs. - avrcpInterface->SetNotificationHandler(BluetoothAvrcpManager::Get()); - - setupInterface->RegisterModule( - SETUP_SERVICE_ID_AVRCP, 0, MAX_NUM_CLIENTS, - new RegisterModuleResultHandler(avrcpInterface, aRes)); -} - -BluetoothAvrcpManager::~BluetoothAvrcpManager() -{ } - -void -BluetoothAvrcpManager::Uninit() -{ - nsCOMPtr<nsIObserverService> obs = services::GetObserverService(); - NS_ENSURE_TRUE_VOID(obs); - if (NS_FAILED(obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID))) { - BT_WARNING("Failed to remove shutdown observer!"); - } -} - -/* - * Static functions - */ - -//static -BluetoothAvrcpManager* -BluetoothAvrcpManager::Get() -{ - MOZ_ASSERT(NS_IsMainThread()); - - // If sBluetoothAvrcpManager already exists, exit early - if (sBluetoothAvrcpManager) { - return sBluetoothAvrcpManager; - } - - // If we're in shutdown, don't create a new instance - NS_ENSURE_FALSE(sInShutdown, nullptr); - - // Create a new instance and return - sBluetoothAvrcpManager = new BluetoothAvrcpManager(); - - return sBluetoothAvrcpManager; -} - -class BluetoothAvrcpManager::UnregisterModuleResultHandler final - : public BluetoothSetupResultHandler -{ -public: - UnregisterModuleResultHandler(BluetoothProfileResultHandler* aRes) - : mRes(aRes) - { } - - void OnError(BluetoothStatus aStatus) override - { - MOZ_ASSERT(NS_IsMainThread()); - - BT_WARNING("BluetoothSetupInterface::UnregisterModule failed for AVRCP: %d", - (int)aStatus); - - sBtAvrcpInterface->SetNotificationHandler(nullptr); - sBtAvrcpInterface = nullptr; - - sBluetoothAvrcpManager->Uninit(); - sBluetoothAvrcpManager = nullptr; - - if (mRes) { - mRes->OnError(NS_ERROR_FAILURE); - } - } - - void UnregisterModule() override - { - MOZ_ASSERT(NS_IsMainThread()); - - sBtAvrcpInterface->SetNotificationHandler(nullptr); - sBtAvrcpInterface = nullptr; - - sBluetoothAvrcpManager->Uninit(); - sBluetoothAvrcpManager = nullptr; - - if (mRes) { - mRes->Deinit(); - } - } - -private: - RefPtr<BluetoothProfileResultHandler> mRes; -}; - -class BluetoothAvrcpManager::DeinitProfileResultHandlerRunnable final - : public Runnable -{ -public: - DeinitProfileResultHandlerRunnable(BluetoothProfileResultHandler* aRes, - nsresult aRv) - : mRes(aRes) - , mRv(aRv) - { - MOZ_ASSERT(mRes); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(NS_IsMainThread()); - - if (NS_SUCCEEDED(mRv)) { - mRes->Deinit(); - } else { - mRes->OnError(mRv); - } - return NS_OK; - } - -private: - RefPtr<BluetoothProfileResultHandler> mRes; - nsresult mRv; -}; - -// static -void -BluetoothAvrcpManager::DeinitAvrcpInterface(BluetoothProfileResultHandler* aRes) -{ - MOZ_ASSERT(NS_IsMainThread()); - - if (!sBtAvrcpInterface) { - BT_LOGR("Bluetooth AVRCP interface has not been initalized."); - RefPtr<Runnable> r = - new DeinitProfileResultHandlerRunnable(aRes, NS_OK); - if (NS_FAILED(NS_DispatchToMainThread(r))) { - BT_LOGR("Failed to dispatch AVRCP Deinit runnable"); - } - return; - } - - auto btInf = BluetoothInterface::GetInstance(); - - if (NS_WARN_IF(!btInf)) { - // If there's no backend interface, we dispatch a runnable - // that calls the profile result handler. - RefPtr<Runnable> r = - new DeinitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE); - if (NS_FAILED(NS_DispatchToMainThread(r))) { - BT_LOGR("Failed to dispatch AVRCP OnError runnable"); - } - return; - } - - auto setupInterface = btInf->GetBluetoothSetupInterface(); - - if (NS_WARN_IF(!setupInterface)) { - // If there's no Setup interface, we dispatch a runnable - // that calls the profile result handler. - RefPtr<Runnable> r = - new DeinitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE); - if (NS_FAILED(NS_DispatchToMainThread(r))) { - BT_LOGR("Failed to dispatch AVRCP OnError runnable"); - } - return; - } - - setupInterface->UnregisterModule( - SETUP_SERVICE_ID_AVRCP, - new UnregisterModuleResultHandler(aRes)); -} - -void -BluetoothAvrcpManager::HandleShutdown() -{ - MOZ_ASSERT(NS_IsMainThread()); - sInShutdown = true; - Disconnect(nullptr); - sBluetoothAvrcpManager = nullptr; -} - -class BluetoothAvrcpManager::ConnectRunnable final : public Runnable -{ -public: - ConnectRunnable(BluetoothAvrcpManager* aManager) - : mManager(aManager) - { - MOZ_ASSERT(mManager); - } - NS_IMETHOD Run() override - { - mManager->OnConnect(EmptyString()); - return NS_OK; - } -private: - BluetoothAvrcpManager* mManager; -}; - -void -BluetoothAvrcpManager::Connect(const BluetoothAddress& aDeviceAddress, - BluetoothProfileController* aController) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(!aDeviceAddress.IsCleared()); - MOZ_ASSERT(aController); - - // AVRCP doesn't require connecting. We just set the remote address here. - mDeviceAddress = aDeviceAddress; - mController = aController; - SetConnected(true); - - NS_DispatchToMainThread(new ConnectRunnable(this)); -} - -class BluetoothAvrcpManager::DisconnectRunnable final : public Runnable -{ -public: - DisconnectRunnable(BluetoothAvrcpManager* aManager) - : mManager(aManager) - { - MOZ_ASSERT(mManager); - } - NS_IMETHOD Run() override - { - mManager->OnDisconnect(EmptyString()); - return NS_OK; - } -private: - BluetoothAvrcpManager* mManager; -}; - -void -BluetoothAvrcpManager::Disconnect(BluetoothProfileController* aController) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(!mController); - - mDeviceAddress.Clear(); - mController = aController; - SetConnected(false); - - NS_DispatchToMainThread(new DisconnectRunnable(this)); -} - -void -BluetoothAvrcpManager::OnConnect(const nsAString& aErrorStr) -{ - MOZ_ASSERT(NS_IsMainThread()); - - /** - * On the one hand, notify the controller that we've done for outbound - * connections. On the other hand, we do nothing for inbound connections. - */ - NS_ENSURE_TRUE_VOID(mController); - - RefPtr<BluetoothProfileController> controller = mController.forget(); - controller->NotifyCompletion(aErrorStr); -} - -void -BluetoothAvrcpManager::OnDisconnect(const nsAString& aErrorStr) -{ - MOZ_ASSERT(NS_IsMainThread()); - - /** - * On the one hand, notify the controller that we've done for outbound - * connections. On the other hand, we do nothing for inbound connections. - */ - NS_ENSURE_TRUE_VOID(mController); - - RefPtr<BluetoothProfileController> controller = mController.forget(); - controller->NotifyCompletion(aErrorStr); - - Reset(); -} - -void -BluetoothAvrcpManager::OnGetServiceChannel( - const BluetoothAddress& aDeviceAddress, - const BluetoothUuid& aServiceUuid, - int aChannel) -{ } - -void -BluetoothAvrcpManager::OnUpdateSdpRecords( - const BluetoothAddress& aDeviceAddress) -{ } - -void -BluetoothAvrcpManager::GetAddress(BluetoothAddress& aDeviceAddress) -{ - aDeviceAddress = mDeviceAddress; -} - -bool -BluetoothAvrcpManager::IsConnected() -{ - return mAvrcpConnected; -} - -/* - * In bluedroid stack case, there is no interface to know exactly - * avrcp connection status. All connection are managed by bluedroid stack. - */ -void -BluetoothAvrcpManager::SetConnected(bool aConnected) -{ - mAvrcpConnected = aConnected; - if (!aConnected) { - Reset(); - } -} - -/* - * This function only updates meta data in BluetoothAvrcpManager. Send - * "Get Element Attributes response" in AvrcpGetElementAttrCallback - */ -void -BluetoothAvrcpManager::UpdateMetaData(const nsAString& aTitle, - const nsAString& aArtist, - const nsAString& aAlbum, - uint64_t aMediaNumber, - uint64_t aTotalMediaCount, - uint32_t aDuration) -{ - MOZ_ASSERT(NS_IsMainThread()); - - NS_ENSURE_TRUE_VOID(sBtAvrcpInterface); - - // Send track changed and position changed if track num is not the same. - // See also AVRCP 1.3 Spec 5.4.2 - if (mMediaNumber != aMediaNumber && - mTrackChangedNotifyType == AVRCP_NTF_INTERIM) { - BluetoothAvrcpNotificationParam param; - // convert to network big endian format - // since track stores as uint8[8] - // 56 = 8 * (AVRCP_UID_SIZE -1) - for (int i = 0; i < AVRCP_UID_SIZE; ++i) { - param.mTrack[i] = (aMediaNumber >> (56 - 8 * i)); - } - mTrackChangedNotifyType = AVRCP_NTF_CHANGED; - sBtAvrcpInterface->RegisterNotificationRsp(AVRCP_EVENT_TRACK_CHANGE, - AVRCP_NTF_CHANGED, - param, nullptr); - if (mPlayPosChangedNotifyType == AVRCP_NTF_INTERIM) { - param.mSongPos = mPosition; - // EVENT_PLAYBACK_POS_CHANGED shall be notified if changed current track - mPlayPosChangedNotifyType = AVRCP_NTF_CHANGED; - sBtAvrcpInterface->RegisterNotificationRsp(AVRCP_EVENT_PLAY_POS_CHANGED, - AVRCP_NTF_CHANGED, - param, nullptr); - } - } - - mTitle.Assign(aTitle); - mArtist.Assign(aArtist); - mAlbum.Assign(aAlbum); - mMediaNumber = aMediaNumber; - mTotalMediaCount = aTotalMediaCount; - mDuration = aDuration; -} - -/* - * This function is to reply AvrcpGetPlayStatusCallback (play-status-request) - * from media player application (Gaia side) - */ -void -BluetoothAvrcpManager::UpdatePlayStatus(uint32_t aDuration, - uint32_t aPosition, - ControlPlayStatus aPlayStatus) -{ - MOZ_ASSERT(NS_IsMainThread()); - - NS_ENSURE_TRUE_VOID(sBtAvrcpInterface); - // always update playstatus first - sBtAvrcpInterface->GetPlayStatusRsp(aPlayStatus, aDuration, - aPosition, nullptr); - // when play status changed, send both play status and position - if (mPlayStatus != aPlayStatus && - mPlayStatusChangedNotifyType == AVRCP_NTF_INTERIM) { - BluetoothAvrcpNotificationParam param; - param.mPlayStatus = aPlayStatus; - mPlayStatusChangedNotifyType = AVRCP_NTF_CHANGED; - sBtAvrcpInterface->RegisterNotificationRsp(AVRCP_EVENT_PLAY_STATUS_CHANGED, - AVRCP_NTF_CHANGED, - param, nullptr); - } - - if (mPosition != aPosition && - mPlayPosChangedNotifyType == AVRCP_NTF_INTERIM) { - BluetoothAvrcpNotificationParam param; - param.mSongPos = aPosition; - mPlayPosChangedNotifyType = AVRCP_NTF_CHANGED; - sBtAvrcpInterface->RegisterNotificationRsp(AVRCP_EVENT_PLAY_POS_CHANGED, - AVRCP_NTF_CHANGED, - param, nullptr); - } - - mDuration = aDuration; - mPosition = aPosition; - mPlayStatus = aPlayStatus; -} - -/* - * This function handles RegisterNotification request from - * AvrcpRegisterNotificationCallback, which updates current - * track/status/position status in the INTERRIM response. - * - * aParam is only valid when position changed - */ -void -BluetoothAvrcpManager::UpdateRegisterNotification(BluetoothAvrcpEvent aEvent, - uint32_t aParam) -{ - MOZ_ASSERT(NS_IsMainThread()); - - NS_ENSURE_TRUE_VOID(sBtAvrcpInterface); - - BluetoothAvrcpNotificationParam param; - - switch (aEvent) { - case AVRCP_EVENT_PLAY_STATUS_CHANGED: - mPlayStatusChangedNotifyType = AVRCP_NTF_INTERIM; - param.mPlayStatus = mPlayStatus; - break; - case AVRCP_EVENT_TRACK_CHANGE: - // In AVRCP 1.3 and 1.4, the identifier parameter of EVENT_TRACK_CHANGED - // is different. - // AVRCP 1.4: If no track is selected, we shall return 0xFFFFFFFFFFFFFFFF, - // otherwise return 0x0 in the INTERRIM response. The expanded text in - // version 1.4 is to allow for new UID feature. As for AVRCP 1.3, we shall - // return 0xFFFFFFFF. Since PTS enforces to check this part to comply with - // the most updated spec. - mTrackChangedNotifyType = AVRCP_NTF_INTERIM; - // needs to convert to network big endian format since track stores - // as uint8[8]. 56 = 8 * (BTRC_UID_SIZE -1). - for (int index = 0; index < AVRCP_UID_SIZE; ++index) { - // We cannot easily check if a track is selected, so whenever A2DP is - // streaming, we assume a track is selected. - if (mPlayStatus == ControlPlayStatus::PLAYSTATUS_PLAYING) { - param.mTrack[index] = 0x0; - } else { - param.mTrack[index] = 0xFF; - } - } - break; - case AVRCP_EVENT_PLAY_POS_CHANGED: - // If no track is selected, return 0xFFFFFFFF in the INTERIM response - mPlayPosChangedNotifyType = AVRCP_NTF_INTERIM; - if (mPlayStatus == ControlPlayStatus::PLAYSTATUS_PLAYING) { - param.mSongPos = mPosition; - } else { - param.mSongPos = 0xFFFFFFFF; - } - mPlaybackInterval = aParam; - break; - case AVRCP_EVENT_APP_SETTINGS_CHANGED: - mAppSettingsChangedNotifyType = AVRCP_NTF_INTERIM; - param.mNumAttr = 2; - param.mIds[0] = AVRCP_PLAYER_ATTRIBUTE_REPEAT; - param.mValues[0] = AVRCP_PLAYER_VAL_OFF_REPEAT; - param.mIds[1] = AVRCP_PLAYER_ATTRIBUTE_SHUFFLE; - param.mValues[1] = AVRCP_PLAYER_VAL_OFF_SHUFFLE; - break; - default: - break; - } - - sBtAvrcpInterface->RegisterNotificationRsp(aEvent, AVRCP_NTF_INTERIM, - param, nullptr); -} - -void -BluetoothAvrcpManager::GetAlbum(nsAString& aAlbum) -{ - aAlbum.Assign(mAlbum); -} - -uint32_t -BluetoothAvrcpManager::GetDuration() -{ - return mDuration; -} - -ControlPlayStatus -BluetoothAvrcpManager::GetPlayStatus() -{ - return mPlayStatus; -} - -uint32_t -BluetoothAvrcpManager::GetPosition() -{ - return mPosition; -} - -uint64_t -BluetoothAvrcpManager::GetMediaNumber() -{ - return mMediaNumber; -} - -uint64_t -BluetoothAvrcpManager::GetTotalMediaNumber() -{ - return mTotalMediaCount; -} - -void -BluetoothAvrcpManager::GetTitle(nsAString& aTitle) -{ - aTitle.Assign(mTitle); -} - -void -BluetoothAvrcpManager::GetArtist(nsAString& aArtist) -{ - aArtist.Assign(mArtist); -} - -/* - * Notifications - */ - -void -BluetoothAvrcpManager::GetPlayStatusNotification() -{ - MOZ_ASSERT(NS_IsMainThread()); - - BluetoothService* bs = BluetoothService::Get(); - if (!bs) { - return; - } - - bs->DistributeSignal(NS_LITERAL_STRING(REQUEST_MEDIA_PLAYSTATUS_ID), - NS_LITERAL_STRING(KEY_ADAPTER)); -} - -/* Player application settings is optional for AVRCP 1.3. B2G - * currently does not support player-application-setting related - * functionality. - */ -void -BluetoothAvrcpManager::ListPlayerAppAttrNotification() -{ - MOZ_ASSERT(NS_IsMainThread()); - - // TODO: Support AVRCP application-setting-related functions -} - -void -BluetoothAvrcpManager::ListPlayerAppValuesNotification( - BluetoothAvrcpPlayerAttribute aAttrId) -{ - MOZ_ASSERT(NS_IsMainThread()); - - // TODO: Support AVRCP application-setting-related functions -} - -void -BluetoothAvrcpManager::GetPlayerAppValueNotification( - uint8_t aNumAttrs, const BluetoothAvrcpPlayerAttribute* aAttrs) -{ - MOZ_ASSERT(NS_IsMainThread()); - - // TODO: Support AVRCP application-setting-related functions -} - -void -BluetoothAvrcpManager::GetPlayerAppAttrsTextNotification( - uint8_t aNumAttrs, const BluetoothAvrcpPlayerAttribute* aAttrs) -{ - MOZ_ASSERT(NS_IsMainThread()); - - // TODO: Support AVRCP application-setting-related functions -} - -void -BluetoothAvrcpManager::GetPlayerAppValuesTextNotification( - uint8_t aAttrId, uint8_t aNumVals, const uint8_t* aValues) -{ - MOZ_ASSERT(NS_IsMainThread()); - - // TODO: Support AVRCP application-setting-related functions -} - -void -BluetoothAvrcpManager::SetPlayerAppValueNotification( - const BluetoothAvrcpPlayerSettings& aSettings) -{ - MOZ_ASSERT(NS_IsMainThread()); - - // TODO: Support AVRCP application-setting-related functions -} - -/* This method returns element attributes, which are requested from - * CT. Unlike BlueZ it calls only UpdateMetaData. Bluedroid does not cache - * meta-data information, but instead uses |GetElementAttrNotifications| - * and |GetElementAttrRsp| request them. - */ -void -BluetoothAvrcpManager::GetElementAttrNotification( - uint8_t aNumAttrs, const BluetoothAvrcpMediaAttribute* aAttrs) -{ - MOZ_ASSERT(NS_IsMainThread()); - - auto attrs = MakeUnique<BluetoothAvrcpElementAttribute[]>(aNumAttrs); - - for (uint8_t i = 0; i < aNumAttrs; ++i) { - attrs[i].mId = aAttrs[i]; - ConvertAttributeString( - static_cast<BluetoothAvrcpMediaAttribute>(attrs[i].mId), - attrs[i].mValue); - } - - MOZ_ASSERT(sBtAvrcpInterface); - sBtAvrcpInterface->GetElementAttrRsp(aNumAttrs, attrs.get(), nullptr); -} - -void -BluetoothAvrcpManager::RegisterNotificationNotification( - BluetoothAvrcpEvent aEvent, uint32_t aParam) -{ - MOZ_ASSERT(NS_IsMainThread()); - - BluetoothAvrcpManager* avrcp = BluetoothAvrcpManager::Get(); - if (!avrcp) { - return; - } - - avrcp->UpdateRegisterNotification(aEvent, aParam); -} - -/* This method is used to get CT features from the Feature Bit Mask. If - * Advanced Control Player bit is set, the CT supports volume sync (absolute - * volume feature). If Browsing bit is set, AVRCP 1.4 Browse feature will be - * supported. - */ -void -BluetoothAvrcpManager::RemoteFeatureNotification( - const BluetoothAddress& aBdAddr, unsigned long aFeatures) -{ - MOZ_ASSERT(NS_IsMainThread()); - - // TODO: Support AVRCP 1.4 absolute volume/browse -} - -/* This method is used to get notifications about volume changes on the - * remote car kit (if it supports AVRCP 1.4), not notification from phone. - */ -void -BluetoothAvrcpManager::VolumeChangeNotification(uint8_t aVolume, - uint8_t aCType) -{ - MOZ_ASSERT(NS_IsMainThread()); - - // TODO: Support AVRCP 1.4 absolute volume/browse -} - -void -BluetoothAvrcpManager::PassthroughCmdNotification(uint8_t aId, - uint8_t aKeyState) -{ - MOZ_ASSERT(NS_IsMainThread()); - - // Fast-forward and rewind key events won't be generated from bluedroid - // stack after ANDROID_VERSION > 18, but via passthrough callback. - nsAutoString name; - NS_ENSURE_TRUE_VOID(aKeyState == AVRC_KEY_PRESS_STATE || - aKeyState == AVRC_KEY_RELEASE_STATE); - switch (aId) { - case AVRC_ID_FAST_FOR: - if (aKeyState == AVRC_KEY_PRESS_STATE) { - name.AssignLiteral("media-fast-forward-button-press"); - } else { - name.AssignLiteral("media-fast-forward-button-release"); - } - break; - case AVRC_ID_REWIND: - if (aKeyState == AVRC_KEY_PRESS_STATE) { - name.AssignLiteral("media-rewind-button-press"); - } else { - name.AssignLiteral("media-rewind-button-release"); - } - break; - default: - BT_WARNING("Unable to handle the unknown PassThrough command %d", aId); - return; - } - - NS_NAMED_LITERAL_STRING(type, "media-button"); - BroadcastSystemMessage(type, BluetoothValue(name)); -} - -NS_IMPL_ISUPPORTS(BluetoothAvrcpManager, nsIObserver) -
deleted file mode 100644 --- a/dom/bluetooth/bluedroid/BluetoothAvrcpManager.h +++ /dev/null @@ -1,150 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_bluetooth_bluedroid_BluetoothAvrcpManager_h -#define mozilla_dom_bluetooth_bluedroid_BluetoothAvrcpManager_h - -#include "BluetoothCommon.h" -#include "BluetoothInterface.h" -#include "BluetoothProfileController.h" -#include "BluetoothProfileManagerBase.h" - -BEGIN_BLUETOOTH_NAMESPACE -class BluetoothAvrcpManager : public BluetoothProfileManagerBase - , public BluetoothAvrcpNotificationHandler -{ -public: - static const int MAX_NUM_CLIENTS; - - BT_DECL_PROFILE_MGR_BASE - virtual void GetName(nsACString& aName) - { - aName.AssignLiteral("AVRCP"); - } - - enum SinkState { - SINK_UNKNOWN, - SINK_DISCONNECTED, - SINK_CONNECTING, - SINK_CONNECTED, - SINK_PLAYING, - }; - - static BluetoothAvrcpManager* Get(); - static void InitAvrcpInterface(BluetoothProfileResultHandler* aRes); - static void DeinitAvrcpInterface(BluetoothProfileResultHandler* aRes); - - void SetConnected(bool aConnected); - void UpdateMetaData(const nsAString& aTitle, - const nsAString& aArtist, - const nsAString& aAlbum, - uint64_t aMediaNumber, - uint64_t aTotalMediaCount, - uint32_t aDuration); - void UpdatePlayStatus(uint32_t aDuration, - uint32_t aPosition, - ControlPlayStatus aPlayStatus); - void UpdateRegisterNotification(BluetoothAvrcpEvent aEvent, uint32_t aParam); - void GetAlbum(nsAString& aAlbum); - uint32_t GetDuration(); - ControlPlayStatus GetPlayStatus(); - uint32_t GetPosition(); - uint64_t GetMediaNumber(); - uint64_t GetTotalMediaNumber(); - void GetTitle(nsAString& aTitle); - void GetArtist(nsAString& aArtist); - void HandleBackendError(); - -protected: - virtual ~BluetoothAvrcpManager(); - -private: - class ConnectRunnable; - class DeinitProfileResultHandlerRunnable; - class DisconnectRunnable; - class InitProfileResultHandlerRunnable; - class RegisterModuleResultHandler; - class UnregisterModuleResultHandler; - - BluetoothAvrcpManager(); - - void Uninit(); - void HandleShutdown(); - void NotifyConnectionStatusChanged(); - - void GetPlayStatusNotification() override; - - void ListPlayerAppAttrNotification() override; - - void ListPlayerAppValuesNotification( - BluetoothAvrcpPlayerAttribute aAttrId) override; - - void GetPlayerAppValueNotification( - uint8_t aNumAttrs, - const BluetoothAvrcpPlayerAttribute* aAttrs) override; - - void GetPlayerAppAttrsTextNotification( - uint8_t aNumAttrs, - const BluetoothAvrcpPlayerAttribute* aAttrs) override; - - void GetPlayerAppValuesTextNotification( - uint8_t aAttrId, uint8_t aNumVals, const uint8_t* aValues) override; - - void SetPlayerAppValueNotification( - const BluetoothAvrcpPlayerSettings& aSettings) override; - - void GetElementAttrNotification( - uint8_t aNumAttrs, - const BluetoothAvrcpMediaAttribute* aAttrs) override; - - void RegisterNotificationNotification( - BluetoothAvrcpEvent aEvent, uint32_t aParam) override; - - void RemoteFeatureNotification( - const BluetoothAddress& aBdAddr, unsigned long aFeatures) override; - - void VolumeChangeNotification(uint8_t aVolume, uint8_t aCType) override; - - void PassthroughCmdNotification(uint8_t aId, uint8_t aKeyState) override; - - BluetoothAddress mDeviceAddress; - RefPtr<BluetoothProfileController> mController; - - bool mAvrcpConnected; - nsString mAlbum; - nsString mArtist; - nsString mTitle; - uint32_t mDuration; - uint64_t mMediaNumber; - uint64_t mTotalMediaCount; - uint32_t mPosition; - /* - * mPlaybackInterval specifies the time interval (in seconds) at which - * the change in playback position will be notified. If the song is being - * forwarded / rewound, a notification will be received whenever the playback - * position will change by this value. - */ - uint32_t mPlaybackInterval; - ControlPlayStatus mPlayStatus; - /* - * Notification types: 1. INTERIM 2. CHANGED - * 1. The initial response to this Notify command shall be an INTERIM - * response with current status. - * 2. The following response shall be a CHANGED response with the updated - * status. - * mPlayStatusChangedNotifType, mTrackChangedNotifType, - * mPlayPosChangedNotifType represents current RegisterNotification - * notification type. - */ - BluetoothAvrcpNotification mPlayStatusChangedNotifyType; - BluetoothAvrcpNotification mTrackChangedNotifyType; - BluetoothAvrcpNotification mPlayPosChangedNotifyType; - BluetoothAvrcpNotification mAppSettingsChangedNotifyType; -}; - -END_BLUETOOTH_NAMESPACE - -#endif // mozilla_dom_bluetooth_bluedroid_BluetoothAvrcpManager_h
deleted file mode 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.cpp +++ /dev/null @@ -1,296 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "BluetoothDaemonA2dpInterface.h" -#include "mozilla/UniquePtr.h" -#include "mozilla/Unused.h" - -BEGIN_BLUETOOTH_NAMESPACE - -using namespace mozilla::ipc; - -// -// A2DP module -// - -BluetoothA2dpNotificationHandler* - BluetoothDaemonA2dpModule::sNotificationHandler; - -void -BluetoothDaemonA2dpModule::SetNotificationHandler( - BluetoothA2dpNotificationHandler* aNotificationHandler) -{ - sNotificationHandler = aNotificationHandler; -} - -void -BluetoothDaemonA2dpModule::HandleSvc(const DaemonSocketPDUHeader& aHeader, - DaemonSocketPDU& aPDU, - DaemonSocketResultHandler* aRes) -{ - static void (BluetoothDaemonA2dpModule::* const HandleOp[])( - const DaemonSocketPDUHeader&, DaemonSocketPDU&, - DaemonSocketResultHandler*) = { - [0] = &BluetoothDaemonA2dpModule::HandleRsp, - [1] = &BluetoothDaemonA2dpModule::HandleNtf - }; - - MOZ_ASSERT(!NS_IsMainThread()); - - // negate twice to map bit to 0/1 - unsigned int isNtf = !!(aHeader.mOpcode & 0x80); - - (this->*(HandleOp[isNtf]))(aHeader, aPDU, aRes); -} - -// Commands -// - -nsresult -BluetoothDaemonA2dpModule::ConnectCmd( - const BluetoothAddress& aRemoteAddr, BluetoothA2dpResultHandler* aRes) -{ - MOZ_ASSERT(NS_IsMainThread()); - - UniquePtr<DaemonSocketPDU> pdu = - MakeUnique<DaemonSocketPDU>(SERVICE_ID, OPCODE_CONNECT, - 6); // Address - - nsresult rv = PackPDU(aRemoteAddr, *pdu); - if (NS_FAILED(rv)) { - return rv; - } - rv = Send(pdu.get(), aRes); - if (NS_FAILED(rv)) { - return rv; - } - Unused << pdu.release(); - return NS_OK; -} - -nsresult -BluetoothDaemonA2dpModule::DisconnectCmd( - const BluetoothAddress& aRemoteAddr, BluetoothA2dpResultHandler* aRes) -{ - MOZ_ASSERT(NS_IsMainThread()); - - UniquePtr<DaemonSocketPDU> pdu = - MakeUnique<DaemonSocketPDU>(SERVICE_ID, OPCODE_DISCONNECT, - 6); // Address - - nsresult rv = PackPDU(aRemoteAddr, *pdu); - if (NS_FAILED(rv)) { - return rv; - } - rv = Send(pdu.get(), aRes); - if (NS_FAILED(rv)) { - return rv; - } - Unused << pdu.release(); - return NS_OK; -} - -// Responses -// - -void -BluetoothDaemonA2dpModule::ErrorRsp( - const DaemonSocketPDUHeader& aHeader, - DaemonSocketPDU& aPDU, BluetoothA2dpResultHandler* aRes) -{ - ErrorRunnable::Dispatch( - aRes, &BluetoothA2dpResultHandler::OnError, UnpackPDUInitOp(aPDU)); -} - -void -BluetoothDaemonA2dpModule::ConnectRsp( - const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU, - BluetoothA2dpResultHandler* aRes) -{ - ResultRunnable::Dispatch( - aRes, &BluetoothA2dpResultHandler::Connect, UnpackPDUInitOp(aPDU)); -} - -void -BluetoothDaemonA2dpModule::DisconnectRsp( - const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU, - BluetoothA2dpResultHandler* aRes) -{ - ResultRunnable::Dispatch( - aRes, &BluetoothA2dpResultHandler::Disconnect, UnpackPDUInitOp(aPDU)); -} - -void -BluetoothDaemonA2dpModule::HandleRsp( - const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU, - DaemonSocketResultHandler* aRes) -{ - static void (BluetoothDaemonA2dpModule::* const HandleRsp[])( - const DaemonSocketPDUHeader&, - DaemonSocketPDU&, - BluetoothA2dpResultHandler*) = { - [OPCODE_ERROR] = &BluetoothDaemonA2dpModule::ErrorRsp, - [OPCODE_CONNECT] = &BluetoothDaemonA2dpModule::ConnectRsp, - [OPCODE_DISCONNECT] = &BluetoothDaemonA2dpModule::DisconnectRsp - }; - - MOZ_ASSERT(!NS_IsMainThread()); // I/O thread - - if (NS_WARN_IF(!(aHeader.mOpcode < MOZ_ARRAY_LENGTH(HandleRsp))) || - NS_WARN_IF(!HandleRsp[aHeader.mOpcode])) { - return; - } - - RefPtr<BluetoothA2dpResultHandler> res = - static_cast<BluetoothA2dpResultHandler*>(aRes); - - if (!res) { - return; // Return early if no result handler has been set for response - } - - (this->*(HandleRsp[aHeader.mOpcode]))(aHeader, aPDU, res); -} - -// Notifications -// - -// Returns the current notification handler to a notification runnable -class BluetoothDaemonA2dpModule::NotificationHandlerWrapper final -{ -public: - typedef BluetoothA2dpNotificationHandler ObjectType; - - static ObjectType* GetInstance() - {