diff options
376 files changed, 1367 insertions, 17292 deletions
diff --git a/Makefile.in b/Makefile.in index f196af545..26cd688d4 100644 --- a/Makefile.in +++ b/Makefile.in @@ -299,13 +299,6 @@ MAKE_SYM_STORE_ARGS += --install-manifest=$(DEPTH)/_build_manifests/install/dist SYM_STORE_SOURCE_DIRS := $(topsrcdir) -ifdef MOZ_CRASHREPORTER -include $(topsrcdir)/toolkit/mozapps/installer/package-name.mk - -SYMBOL_INDEX_NAME = \ - $(MOZ_APP_NAME)-$(MOZ_APP_VERSION)-$(OS_TARGET)-$(BUILDID)-$(CPU_ARCH)-symbols.txt -endif - .PHONY: generatesymbols generatesymbols: echo building symbol store @@ -337,18 +330,9 @@ symbolsarchive: generatesymbols cd $(DIST)/crashreporter-symbols && \ zip -r5D '../$(PKG_PATH)$(SYMBOL_ARCHIVE_BASENAME).zip' . -i '*.sym' -i '*.txt' -ifdef MOZ_CRASHREPORTER -buildsymbols: symbolsfullarchive symbolsarchive -else buildsymbols: -endif uploadsymbols: -ifdef MOZ_CRASHREPORTER -ifdef SOCORRO_SYMBOL_UPLOAD_TOKEN_FILE - $(PYTHON) -u $(topsrcdir)/toolkit/crashreporter/tools/upload_symbols.py '$(DIST)/$(PKG_PATH)$(SYMBOL_FULL_ARCHIVE_BASENAME).zip' -endif -endif .PHONY: update-packaging update-packaging: diff --git a/accessible/base/nsAccessibilityService.cpp b/accessible/base/nsAccessibilityService.cpp index 2590969a0..46d4dde01 100644 --- a/accessible/base/nsAccessibilityService.cpp +++ b/accessible/base/nsAccessibilityService.cpp @@ -53,10 +53,6 @@ #include "Logging.h" #endif -#ifdef MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" -#endif - #include "nsImageFrame.h" #include "nsIObserverService.h" #include "nsLayoutUtils.h" @@ -1283,12 +1279,6 @@ nsAccessibilityService::Init() NS_ADDREF(gApplicationAccessible); // will release in Shutdown() gApplicationAccessible->Init(); -#ifdef MOZ_CRASHREPORTER - CrashReporter:: - AnnotateCrashReport(NS_LITERAL_CSTRING("Accessibility"), - NS_LITERAL_CSTRING("Active")); -#endif - #ifdef XP_WIN sPendingPlugins = new nsTArray<nsCOMPtr<nsIContent> >; sPluginTimers = new nsTArray<nsCOMPtr<nsITimer> >; diff --git a/accessible/windows/msaa/IUnknownImpl.cpp b/accessible/windows/msaa/IUnknownImpl.cpp index c74f86e33..c5e614b60 100644 --- a/accessible/windows/msaa/IUnknownImpl.cpp +++ b/accessible/windows/msaa/IUnknownImpl.cpp @@ -9,10 +9,6 @@ #include "nsDebug.h" -#ifdef MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" -#endif - namespace mozilla { namespace a11y { diff --git a/application/palemoon/app/profile/palemoon.js b/application/palemoon/app/profile/palemoon.js index 7338a83a2..ee4a95d38 100644 --- a/application/palemoon/app/profile/palemoon.js +++ b/application/palemoon/app/profile/palemoon.js @@ -1036,6 +1036,9 @@ pref("browser.newtab.preload", false); // Toggles the content of 'about:newtab'. Shows the grid when enabled. pref("browser.newtabpage.enabled", true); +// XXX: Remove this when "enhanced" tiles are dead +pref("browser.newtabpage.enhanced", false); + // number of columns of newtab grid pref("browser.newtabpage.columns", 4); diff --git a/application/palemoon/base/content/autorecovery.js b/application/palemoon/base/content/autorecovery.js index c24d1bfe4..01a092f5c 100644 --- a/application/palemoon/base/content/autorecovery.js +++ b/application/palemoon/base/content/autorecovery.js @@ -10,6 +10,10 @@ * have been properly initialized already. */ +var Cc = Components.classes; +var Ci = Components.interfaces; +var Cu = Components.utils; + // Services = object with smart getters for common XPCOM services Cu.import("resource://gre/modules/Services.jsm"); diff --git a/application/palemoon/base/content/baseMenuOverlay.xul b/application/palemoon/base/content/baseMenuOverlay.xul index c6c1b16dc..f61348c9f 100644 --- a/application/palemoon/base/content/baseMenuOverlay.xul +++ b/application/palemoon/base/content/baseMenuOverlay.xul @@ -29,7 +29,7 @@ <menuitem id="menu_mac_show_all" label="&showAllAppsCmdMac.label;"/> </menupopup> <!-- Mac window menu --> -#include ../../../toolkit/content/macWindowMenu.inc +#include ../../../../toolkit/content/macWindowMenu.inc #endif #ifdef XP_WIN diff --git a/application/palemoon/base/content/browser-appmenu.inc b/application/palemoon/base/content/browser-appmenu.inc index 835bf22bc..cfc855484 100644 --- a/application/palemoon/base/content/browser-appmenu.inc +++ b/application/palemoon/base/content/browser-appmenu.inc @@ -132,38 +132,8 @@ </splitmenu> <menuseparator class="appmenu-menuseparator"/> <splitmenu id="appmenu_webDeveloper" - command="Tools:DevToolbox" label="&appMenuWebDeveloper.label;"> <menupopup id="appmenu_webDeveloper_popup"> -#ifdef MOZ_DEVTOOLS - <menuitem id="appmenu_devToolbox" - observes="devtoolsMenuBroadcaster_DevToolbox"/> - <menuseparator id="appmenu_devtools_separator"/> - <menuitem id="appmenu_devToolbar" - observes="devtoolsMenuBroadcaster_DevToolbar"/> - <menuitem id="appmenu_chromeDebugger" - observes="devtoolsMenuBroadcaster_ChromeDebugger"/> - <menuitem id="appmenu_browserConsole" - observes="devtoolsMenuBroadcaster_BrowserConsole"/> - <menuitem id="appmenu_responsiveUI" - observes="devtoolsMenuBroadcaster_ResponsiveUI"/> - <menuitem id="appmenu_eyedropper" - observes="devtoolsMenuBroadcaster_Eyedropper"/> - <menuitem id="appmenu_scratchpad" - observes="devtoolsMenuBroadcaster_Scratchpad"/> -#endif - <menuitem id="appmenu_pageSource" - observes="devtoolsMenuBroadcaster_PageSource"/> - <menuitem id="appmenu_errorConsole" - observes="devtoolsMenuBroadcaster_ErrorConsole"/> -#ifdef MOZ_DEVTOOLS - <menuitem id="appmenu_devtools_connect" - observes="devtoolsMenuBroadcaster_connect"/> -#endif - <menuseparator id="appmenu_devToolsEndSeparator"/> - <menuitem id="appmenu_getMoreDevtools" - observes="devtoolsMenuBroadcaster_GetMoreTools"/> - <menuseparator/> #define ID_PREFIX appmenu_developer_ #define OMIT_ACCESSKEYS #include browser-charsetmenu.inc @@ -173,6 +143,11 @@ type="checkbox" observes="workOfflineMenuitemState" oncommand="BrowserOffline.toggleOfflineStatus();"/> + <menuseparator/> + <menuitem id="appmenu_pageSource" + observes="devtoolsMenuBroadcaster_PageSource"/> + <menuitem id="appmenu_javascriptConsole" + observes="devtoolsMenuBroadcaster_ErrorConsole"/> </menupopup> </splitmenu> <menuseparator class="appmenu-menuseparator"/> diff --git a/application/palemoon/base/content/browser-fullScreen.js b/application/palemoon/base/content/browser-fullScreen.js index b8a29199e..400340e77 100644 --- a/application/palemoon/base/content/browser-fullScreen.js +++ b/application/palemoon/base/content/browser-fullScreen.js @@ -304,7 +304,7 @@ var FullScreen = { }, _cancelAnimation: function() { - window.mozCancelAnimationFrame(this._animationHandle); + window.cancelAnimationFrame(this._animationHandle); this._animationHandle = 0; clearTimeout(this._animationTimeout); this._isAnimating = false; diff --git a/application/palemoon/base/content/browser-menubar.inc b/application/palemoon/base/content/browser-menubar.inc index fa9d7f0f4..fc6bc7694 100644 --- a/application/palemoon/base/content/browser-menubar.inc +++ b/application/palemoon/base/content/browser-menubar.inc @@ -534,43 +534,12 @@ label="&webDeveloperMenu.label;" accesskey="&webDeveloperMenu.accesskey;"> <menupopup id="menuWebDeveloperPopup"> -#ifdef MOZ_DEVTOOLS - <menuitem id="menu_devToolbox" - observes="devtoolsMenuBroadcaster_DevToolbox" - accesskey="&devToolboxMenuItem.accesskey;"/> - <menuseparator id="menu_devtools_separator"/> - <menuitem id="menu_devToolbar" - observes="devtoolsMenuBroadcaster_DevToolbar" - accesskey="&devToolbarMenu.accesskey;"/> - <menuitem id="menu_chromeDebugger" - observes="devtoolsMenuBroadcaster_ChromeDebugger"/> - <menuitem id="menu_browserConsole" - observes="devtoolsMenuBroadcaster_BrowserConsole" - accesskey="&browserConsoleCmd.accesskey;"/> - <menuitem id="menu_responsiveUI" - observes="devtoolsMenuBroadcaster_ResponsiveUI" - accesskey="&responsiveDesignTool.accesskey;"/> - <menuitem id="menu_eyedropper" - observes="devtoolsMenuBroadcaster_Eyedropper" - accesskey="&eyedropper.accesskey;"/> - <menuitem id="menu_scratchpad" - observes="devtoolsMenuBroadcaster_Scratchpad" - accesskey="&scratchpad.accesskey;"/> -#endif <menuitem id="menu_pageSource" observes="devtoolsMenuBroadcaster_PageSource" accesskey="&pageSourceCmd.accesskey;"/> <menuitem id="javascriptConsole" observes="devtoolsMenuBroadcaster_ErrorConsole" accesskey="&errorConsoleCmd.accesskey;"/> -#ifdef MOZ_DEVTOOLS - <menuitem id="menu_devtools_connect" - observes="devtoolsMenuBroadcaster_connect"/> -#endif - <menuseparator id="devToolsEndSeparator"/> - <menuitem id="getMoreDevtools" - observes="devtoolsMenuBroadcaster_GetMoreTools" - accesskey="&getMoreDevtoolsCmd.accesskey;"/> </menupopup> </menu> <menuitem id="menu_pageInfo" diff --git a/application/palemoon/base/content/browser-sets.inc b/application/palemoon/base/content/browser-sets.inc index 78cfb7faa..64228678e 100644 --- a/application/palemoon/base/content/browser-sets.inc +++ b/application/palemoon/base/content/browser-sets.inc @@ -92,24 +92,9 @@ <command id="Tools:Search" oncommand="BrowserSearch.webSearch();"/> <command id="Tools:Downloads" oncommand="BrowserDownloadsUI();"/> -#ifdef MOZ_DEVTOOLS - <command id="Tools:DevToolbox" oncommand="gDevToolsBrowser.toggleToolboxCommand(gBrowser);"/> - <command id="Tools:DevToolbar" oncommand="DeveloperToolbar.toggle();" disabled="true" hidden="true"/> - <command id="Tools:DevToolbarFocus" oncommand="DeveloperToolbar.focusToggle();" disabled="true"/> - <command id="Tools:DevAppMgr" oncommand="gDevToolsBrowser.openAppManager(gBrowser);" disabled="true" hidden="true"/> - <command id="Tools:WebIDE" oncommand="gDevToolsBrowser.openWebIDE();" disabled="true" hidden="true"/> - <command id="Tools:ChromeDebugger" oncommand="BrowserToolboxProcess.init();" disabled="true" hidden="true"/> - <command id="Tools:BrowserConsole" oncommand="HUDService.openBrowserConsoleOrFocus();"/> - <command id="Tools:Scratchpad" oncommand="Scratchpad.openScratchpad();" disabled="true" hidden="true"/> - <command id="Tools:ResponsiveUI" oncommand="ResponsiveUI.toggle();" disabled="true" hidden="true"/> - <command id="Tools:Eyedropper" oncommand="openEyedropper();"/> -#endif <command id="Tools:Addons" oncommand="BrowserOpenAddonsMgr();"/> <command id="Tools:Permissions" oncommand="BrowserOpenPermissionsMgr();"/> <command id="Tools:ErrorConsole" oncommand="toJavaScriptConsole()" disabled="true" hidden="true"/> -#ifdef MOZ_DEVTOOLS - <command id="Tools:DevToolsConnect" oncommand="gDevToolsBrowser.openConnectScreen(gBrowser)" disabled="true" hidden="true"/> -#endif <command id="Tools:Sanitize" oncommand="Cc['@mozilla.org/browser/browserglue;1'].getService(Ci.nsIBrowserGlue).sanitize(window);"/> <command id="Tools:PrivateBrowsing" @@ -170,46 +155,6 @@ #endif <broadcaster id="workOfflineMenuitemState"/> -#ifdef MOZ_DEVTOOLS - <!-- DevTools broadcasters --> - <broadcaster id="devtoolsMenuBroadcaster_DevToolbox" - label="&devToolboxMenuItem.label;" - type="checkbox" autocheck="false" - command="Tools:DevToolbox" - key="key_devToolbox"/> - <broadcaster id="devtoolsMenuBroadcaster_DevToolbar" - label="&devToolbarMenu.label;" - type="checkbox" autocheck="false" - command="Tools:DevToolbar" - key="key_devToolbar"/> - <broadcaster id="devtoolsMenuBroadcaster_DevAppMgr" - label="&devAppMgrMenu.label;" - command="Tools:DevAppMgr"/> - <broadcaster id="devtoolsMenuBroadcaster_webide" - label="&webide.label;" - command="Tools:WebIDE" - key="key_webide"/> - <broadcaster id="devtoolsMenuBroadcaster_ChromeDebugger" - label="&chromeDebuggerMenu.label;" - command="Tools:ChromeDebugger"/> - <broadcaster id="devtoolsMenuBroadcaster_BrowserConsole" - label="&browserConsoleCmd.label;" - key="key_browserConsole" - command="Tools:BrowserConsole"/> - <broadcaster id="devtoolsMenuBroadcaster_Scratchpad" - label="&scratchpad.label;" - command="Tools:Scratchpad" - key="key_scratchpad"/> - <broadcaster id="devtoolsMenuBroadcaster_ResponsiveUI" - label="&responsiveDesignTool.label;" - type="checkbox" autocheck="false" - command="Tools:ResponsiveUI" - key="key_responsiveUI"/> - <broadcaster id="devtoolsMenuBroadcaster_Eyedropper" - label="&eyedropper.label;" - type="checkbox" autocheck="false" - command="Tools:Eyedropper"/> -#endif <broadcaster id="devtoolsMenuBroadcaster_PageSource" label="&pageSourceCmd.label;" key="key_viewSource" @@ -217,14 +162,6 @@ <broadcaster id="devtoolsMenuBroadcaster_ErrorConsole" label="&errorConsoleCmd.label;" command="Tools:ErrorConsole"/> - <broadcaster id="devtoolsMenuBroadcaster_GetMoreTools" - label="&getMoreDevtoolsCmd.label;" - oncommand="openUILinkIn(gPrefService.getCharPref('browser.getdevtools.url'), 'tab');"/> -#ifdef MOZ_DEVTOOLS - <broadcaster id="devtoolsMenuBroadcaster_connect" - label="&devtoolsConnect.label;" - command="Tools:DevToolsConnect"/> -#endif </broadcasterset> <keyset id="mainKeyset"> @@ -271,21 +208,6 @@ <key id="key_openDownloads" key="&downloads.commandkey;" command="Tools:Downloads" modifiers="accel"/> #endif <key id="key_openAddons" key="&addons.commandkey;" command="Tools:Addons" modifiers="accel,shift"/> -#ifdef MOZ_DEVTOOLS - <key id="key_browserConsole" key="&browserConsoleCmd.commandkey;" command="Tools:BrowserConsole" modifiers="accel,shift"/> - <key id="key_devToolbox" keycode="VK_F12" keytext="F12" command="Tools:DevToolbox"/> - <key id="key_devToolbar" keycode="&devToolbar.keycode;" modifiers="shift" - keytext="&devToolbar.keytext;" command="Tools:DevToolbarFocus"/> - <key id="key_responsiveUI" key="&responsiveDesignTool.commandkey;" command="Tools:ResponsiveUI" -#ifdef XP_MACOSX - modifiers="accel,alt" -#else - modifiers="accel,shift" -#endif - /> - <key id="key_scratchpad" keycode="&scratchpad.keycode;" modifiers="shift" - keytext="&scratchpad.keytext;" command="Tools:Scratchpad"/> -#endif <key id="openFileKb" key="&openFileCmd.commandkey;" command="Browser:OpenFile" modifiers="accel"/> <key id="key_savePage" key="&savePageCmd.commandkey;" command="Browser:SavePage" modifiers="accel"/> <key id="printKb" key="&printCmd.commandkey;" command="cmd_print" modifiers="accel"/> diff --git a/application/palemoon/base/content/browser-thumbnails.js b/application/palemoon/base/content/browser-thumbnails.js index d6fe25231..b06dfd503 100644 --- a/application/palemoon/base/content/browser-thumbnails.js +++ b/application/palemoon/base/content/browser-thumbnails.js @@ -95,7 +95,7 @@ let gBrowserThumbnails = { // Tycho: aCallback([browser.currentURI.spec for (browser of gBrowser.browsers)]); let result = []; for (let browser of gBrowser.browsers) { - result.push(browser.currentURL.spec); + result.push(browser.currentURI.spec); } aCallback(result); }, @@ -142,7 +142,7 @@ let gBrowserThumbnails = { // FIXME Bug 720575 - Don't capture thumbnails for SVG or XML documents as // that currently regresses Talos SVG tests. - if (doc instanceof SVGDocument || doc instanceof XMLDocument) + if (doc instanceof XMLDocument) return false; // There's no point in taking screenshot of loading pages. diff --git a/application/palemoon/base/content/browser.css b/application/palemoon/base/content/browser.css index 2c8ba3e69..e6a84421b 100644 --- a/application/palemoon/base/content/browser.css +++ b/application/palemoon/base/content/browser.css @@ -115,8 +115,17 @@ toolbar[printpreview="true"] { #titlebar { -moz-binding: url("chrome://global/content/bindings/general.xml#windowdragbox"); + -moz-window-dragging: drag; } +%ifdef XP_WIN +#main-window[tabsontop="true"] #TabsToolbar, +#main-window[tabsontop="true"] #toolbar-menubar, +#main-window[tabsontop="true"] #navigator-toolbox > toolbar:-moz-lwtheme { + -moz-window-dragging: drag; +} +%endif + #titlebar-spacer { pointer-events: none; } diff --git a/application/palemoon/base/content/browser.js b/application/palemoon/base/content/browser.js index ffb133963..8b3fa0b4f 100644 --- a/application/palemoon/base/content/browser.js +++ b/application/palemoon/base/content/browser.js @@ -3,9 +3,8 @@ # 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/. -let Cc = Components.classes; -let Ci = Components.interfaces; -let Cu = Components.utils; +var Ci = Components.interfaces; +var Cu = Components.utils; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource:///modules/RecentWindow.jsm"); @@ -110,20 +109,6 @@ XPCOMUtils.defineLazyGetter(this, "PopupNotifications", function () { } }); -#ifdef MOZ_DEVTOOLS -XPCOMUtils.defineLazyGetter(this, "DeveloperToolbar", function() { - let tmp = {}; - Cu.import("resource://gre/modules/devtools/DeveloperToolbar.jsm", tmp); - return new tmp.DeveloperToolbar(window, document.getElementById("developer-toolbar")); -}); - -XPCOMUtils.defineLazyGetter(this, "BrowserToolboxProcess", function() { - let tmp = {}; - Cu.import("resource://gre/modules/devtools/ToolboxProcess.jsm", tmp); - return tmp.BrowserToolboxProcess; -}); -#endif - XPCOMUtils.defineLazyModuleGetter(this, "PageThumbs", "resource://gre/modules/PageThumbs.jsm"); @@ -153,7 +138,11 @@ let gInitialPages = [ #include browser-plugins.js #include browser-tabPreviews.js #include browser-thumbnails.js + +#ifdef MOZ_WEBRTC #include browser-webrtcUI.js +#endif + #include browser-gestureSupport.js #ifdef MOZ_SERVICES_SYNC @@ -706,6 +695,8 @@ const gXSSObserver = { }; var gBrowserInit = { + delayedStartupFinished: false, + onLoad: function() { gMultiProcessBrowser = gPrefService.getBoolPref("browser.tabs.remote"); @@ -1020,7 +1011,9 @@ var gBrowserInit = { OfflineApps.init(); IndexedDBPromptHelper.init(); AddonManager.addAddonListener(AddonsMgrListener); +#ifdef MOZ_WEBRTC WebrtcIndicator.init(); +#endif // Ensure login manager is up and running. Services.logins; @@ -1162,27 +1155,6 @@ var gBrowserInit = { setUrlAndSearchBarWidthForConditionalForwardButton(); }); -#ifdef MOZ_DEVTOOLS - // Enable Chrome Debugger? - let chromeEnabled = gPrefService.getBoolPref("devtools.chrome.enabled"); - let remoteEnabled = chromeEnabled && - gPrefService.getBoolPref("devtools.debugger.chrome-enabled") && - gPrefService.getBoolPref("devtools.debugger.remote-enabled"); - if (remoteEnabled) { - let cmd = document.getElementById("Tools:ChromeDebugger"); - cmd.removeAttribute("disabled"); - cmd.removeAttribute("hidden"); - } - - // Enable Scratchpad in the UI, if the preference allows this. - let scratchpadEnabled = gPrefService.getBoolPref(Scratchpad.prefEnabledName); - if (scratchpadEnabled) { - let cmd = document.getElementById("Tools:Scratchpad"); - cmd.removeAttribute("disabled"); - cmd.removeAttribute("hidden"); - } -#endif - // Enable Error Console? let consoleEnabled = gPrefService.getBoolPref("devtools.errorconsole.enabled"); if (consoleEnabled) { @@ -1200,19 +1172,6 @@ var gBrowserInit = { document.getElementById("appmenu_charsetMenu").hidden = true; #endif -#ifdef MOZ_DEVTOOLS - // Enable Responsive UI? - let responsiveUIEnabled = gPrefService.getBoolPref("devtools.responsiveUI.enabled"); - if (responsiveUIEnabled) { - let cmd = document.getElementById("Tools:ResponsiveUI"); - cmd.removeAttribute("disabled"); - cmd.removeAttribute("hidden"); - } - - // Add Devtools menuitems and listeners - gDevToolsBrowser.registerBrowserWindow(window); -#endif - let appMenuButton = document.getElementById("appmenu-button"); let appMenuPopup = document.getElementById("appmenu-popup"); if (appMenuButton && appMenuPopup) { @@ -1253,6 +1212,8 @@ var gBrowserInit = { setTimeout(function () { BrowserChromeTest.markAsReady(); }, 0); }); + this.delayedStartupFinished = true; + Services.obs.notifyObservers(window, "browser-delayed-startup-finished", ""); }, @@ -1288,15 +1249,6 @@ var gBrowserInit = { if (!this._loadHandled) return; -#ifdef MOZ_DEVTOOLS - gDevToolsBrowser.forgetBrowserWindow(window); - - let desc = Object.getOwnPropertyDescriptor(window, "DeveloperToolbar"); - if (desc && !desc.get) { - DeveloperToolbar.destroy(); - } -#endif - // First clean up services initialized in gBrowserInit.onLoad (or those whose // uninit methods don't depend on the services having been initialized). @@ -2065,49 +2017,43 @@ function readFromClipboard() return url; } -function BrowserViewSourceOfDocument(aDocument) +function BrowserViewSourceOfDocument(aArgsOrDocument) { - var pageCookie; - var webNav; - - // Get the document charset - var docCharset = "charset=" + aDocument.characterSet; - - // Get the nsIWebNavigation associated with the document - try { - var win; - var ifRequestor; - - // Get the DOMWindow for the requested document. If the DOMWindow - // cannot be found, then just use the content window... - // - // XXX: This is a bit of a hack... - win = aDocument.defaultView; - if (win == window) { - win = content; - } - ifRequestor = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor); - - webNav = ifRequestor.getInterface(nsIWebNavigation); - } catch(err) { - // If nsIWebNavigation cannot be found, just get the one for the whole - // window... - webNav = gBrowser.webNavigation; + let args; + + if (aArgsOrDocument instanceof Document) { + let doc = aArgsOrDocument; + + let requestor = doc.defaultView + .QueryInterface(Ci.nsIInterfaceRequestor); + let browser = requestor.getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShell) + .chromeEventHandler; + let outerWindowID = requestor.getInterface(Ci.nsIDOMWindowUtils) + .outerWindowID; + let URL = browser.currentURI.spec; + args = { browser, outerWindowID, URL }; + } else { + args = aArgsOrDocument; } - // - // Get the 'PageDescriptor' for the current document. This allows the - // view-source to access the cached copy of the content rather than - // refetching it from the network... - // - try{ - var PageLoader = webNav.QueryInterface(Components.interfaces.nsIWebPageDescriptor); - pageCookie = PageLoader.currentDescriptor; - } catch(err) { - // If no page descriptor is available, just use the view-source URL... + let viewInternal = () => { + top.gViewSourceUtils.viewSource(args); } - top.gViewSourceUtils.viewSource(webNav.currentURI.spec, pageCookie, aDocument); + // Check if external view source is enabled. If so, try it. If it fails, + // fallback to internal view source. + if (Services.prefs.getBoolPref("view_source.editor.external")) { + top.gViewSourceUtils + .openInExternalEditor(args, null, null, null, result => { + if (!result) { + viewInternal(); + } + }); + } else { + // Display using internal view source + viewInternal(); + } } // doc - document to use for source, or null for this window's document @@ -6880,20 +6826,9 @@ var TabContextMenu = { }; #ifdef MOZ_DEVTOOLS +// Note: Do not delete! It is used for: base/content/nsContextMenu.js XPCOMUtils.defineLazyModuleGetter(this, "gDevTools", - "resource://gre/modules/devtools/gDevTools.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "gDevToolsBrowser", - "resource://gre/modules/devtools/gDevTools.jsm"); - -Object.defineProperty(this, "HUDService", { - get: function HUDService_getter() { - let devtools = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools; - return devtools.require("devtools/webconsole/hudservice").HUDService; - }, - configurable: true, - enumerable: true -}); + "resource://devtools/client/framework/gDevTools.jsm"); #endif // Prompt user to restart the browser in safe mode or normally @@ -6984,49 +6919,6 @@ function toggleAddonBar() { setToolbarVisibility(addonBar, addonBar.collapsed); } -#ifdef MOZ_DEVTOOLS -var Scratchpad = { - prefEnabledName: "devtools.scratchpad.enabled", - - openScratchpad: function SP_openScratchpad() { - return this.ScratchpadManager.openScratchpad(); - } -}; - -XPCOMUtils.defineLazyGetter(Scratchpad, "ScratchpadManager", function() { - let tmp = {}; - Cu.import("resource://gre/modules/devtools/scratchpad-manager.jsm", tmp); - return tmp.ScratchpadManager; -}); - -var ResponsiveUI = { - toggle: function RUI_toggle() { - this.ResponsiveUIManager.toggle(window, gBrowser.selectedTab); - } -}; - -XPCOMUtils.defineLazyGetter(ResponsiveUI, "ResponsiveUIManager", function() { - let tmp = {}; - Cu.import("resource://gre/modules/devtools/responsivedesign.jsm", tmp); - return tmp.ResponsiveUIManager; -}); - -function openEyedropper() { - var eyedropper = new this.Eyedropper(this, { context: "menu", - copyOnSelect: true }); - eyedropper.open(); -} - -Object.defineProperty(this, "Eyedropper", { - get: function() { - let devtools = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools; - return devtools.require("devtools/eyedropper/eyedropper").Eyedropper; - }, - configurable: true, - enumerable: true -}); -#endif - XPCOMUtils.defineLazyGetter(window, "gShowPageResizers", function () { #ifdef XP_WIN // Only show resizers on Windows 2000 and XP diff --git a/application/palemoon/base/content/browser.xul b/application/palemoon/base/content/browser.xul index 3044ce675..0a0ce01dc 100644 --- a/application/palemoon/base/content/browser.xul +++ b/application/palemoon/base/content/browser.xul @@ -440,8 +440,10 @@ <image id="alert-plugins-notification-icon" class="notification-anchor-icon" role="button"/> <image id="blocked-plugins-notification-icon" class="notification-anchor-icon" role="button"/> <image id="mixed-content-blocked-notification-icon" class="notification-anchor-icon" role="button"/> +#ifdef MOZ_WEBRTC <image id="webRTC-shareDevices-notification-icon" class="notification-anchor-icon" role="button"/> <image id="webRTC-sharingDevices-notification-icon" class="notification-anchor-icon" role="button"/> +#endif <image id="pointerLock-notification-icon" class="notification-anchor-icon" role="button"/> <image id="servicesInstall-notification-icon" class="notification-anchor-icon" role="button"/> </box> @@ -513,7 +515,7 @@ flex="100" persist="width" removable="true"> <searchbar id="searchbar" flex="1"/> </toolbaritem> - +#ifdef MOZ_WEBRTC <toolbarbutton id="webrtc-status-button" class="toolbarbutton-1 chromeclass-toolbar-additional" type="menu" @@ -525,7 +527,7 @@ onpopuphiding="WebrtcIndicator.clearPopup(this);" oncommand="WebrtcIndicator.menuCommand(event.target);"/> </toolbarbutton> - +#endif <toolbarbutton id="bookmarks-menu-button" class="toolbarbutton-1 chromeclass-toolbar-additional" persist="class" @@ -971,33 +973,6 @@ <vbox id="browser-bottombox" layer="true"> <notificationbox id="global-notificationbox"/> -#ifdef MOZ_DEVTOOLS - <toolbar id="developer-toolbar" - class="devtools-toolbar" - hidden="true"> -#ifdef XP_MACOSX - <toolbarbutton id="developer-toolbar-closebutton" - class="devtools-closebutton" - oncommand="DeveloperToolbar.hide();" - tooltiptext="&devToolbarCloseButton.tooltiptext;"/> -#endif - <stack class="gclitoolbar-stack-node" flex="1"> - <textbox class="gclitoolbar-input-node" rows="1"/> - <hbox class="gclitoolbar-complete-node"/> - </stack> - <toolbarbutton id="developer-toolbar-toolbox-button" - class="developer-toolbar-button" - observes="devtoolsMenuBroadcaster_DevToolbox" - tooltiptext="&devToolbarToolsButton.tooltip;"/> -#ifndef XP_MACOSX - <toolbarbutton id="developer-toolbar-closebutton" - class="devtools-closebutton" - oncommand="DeveloperToolbar.hide();" - tooltiptext="&devToolbarCloseButton.tooltiptext;"/> -#endif - </toolbar> -#endif - <toolbar id="addon-bar" toolbarname="&statusBar.label;" accesskey="&statusBar.accesskey;" collapsed="true" diff --git a/application/palemoon/base/content/content.js b/application/palemoon/base/content/content.js index 3587bbeef..19c8b0682 100644 --- a/application/palemoon/base/content/content.js +++ b/application/palemoon/base/content/content.js @@ -3,9 +3,9 @@ * 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/. */ -let Cc = Components.classes; -let Ci = Components.interfaces; -let Cu = Components.utils; +var Cc = Components.classes; +var Ci = Components.interfaces; +var Cu = Components.utils; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); @@ -13,6 +13,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "BrowserUtils", "resource://gre/modules/BrowserUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "LoginManagerContent", "resource://gre/modules/LoginManagerContent.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "LoginFormFactory", + "resource://gre/modules/LoginManagerContent.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "InsecurePasswordUtils", "resource://gre/modules/InsecurePasswordUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "FormSubmitObserver", @@ -47,8 +49,9 @@ addMessageListener("Browser:HideSessionRestoreButton", function (message) { }); addEventListener("DOMFormHasPassword", function(event) { - InsecurePasswordUtils.checkForInsecurePasswords(event.target); - LoginManagerContent.onFormPassword(event); + LoginManagerContent.onDOMFormHasPassword(event, content); + let formLike = LoginFormFactory.createFromForm(event.target); + InsecurePasswordUtils.reportInsecurePasswords(formLike); }); addEventListener("DOMAutoComplete", function(event) { LoginManagerContent.onUsernameInput(event); diff --git a/application/palemoon/base/content/newtab/grid.js b/application/palemoon/base/content/newtab/grid.js index 37559a063..3b7dfc35f 100644 --- a/application/palemoon/base/content/newtab/grid.js +++ b/application/palemoon/base/content/newtab/grid.js @@ -109,7 +109,12 @@ let gGrid = { // (Re-)initialize all cells. let cellElements = this.node.querySelectorAll(".newtab-cell"); - this._cells = [new Cell(this, cell) for (cell of cellElements)]; + // Tycho: this._cells = [new Cell(this, cell) for (cell of cellElements)]; + this.cells = []; + + for (let cellItem of cellElements) { + this.cells.push(new Cell(this, cellItem)); + } }, /** diff --git a/application/palemoon/base/content/newtab/newTab.js b/application/palemoon/base/content/newtab/newTab.js index 77c929125..6d8647ab6 100644 --- a/application/palemoon/base/content/newtab/newTab.js +++ b/application/palemoon/base/content/newtab/newTab.js @@ -4,8 +4,8 @@ "use strict"; -let Cu = Components.utils; -let Ci = Components.interfaces; +var Cu = Components.utils; +var Ci = Components.interfaces; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); diff --git a/application/palemoon/base/content/nsContextMenu.js b/application/palemoon/base/content/nsContextMenu.js index 8e6bc96c2..f914f5841 100644 --- a/application/palemoon/base/content/nsContextMenu.js +++ b/application/palemoon/base/content/nsContextMenu.js @@ -422,12 +422,17 @@ nsContextMenu.prototype = { }, inspectNode: function CM_inspectNode() { - let {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}); + let {devtools} = Cu.import("resource://devtools/shared/Loader.jsm", {}); let gBrowser = this.browser.ownerDocument.defaultView.gBrowser; - let tt = devtools.TargetFactory.forTab(gBrowser.selectedTab); - return gDevTools.showToolbox(tt, "inspector").then(function(toolbox) { + let target = devtools.TargetFactory.forTab(gBrowser.selectedTab); + + return gDevTools.showToolbox(target, "inspector").then(function(toolbox) { let inspector = toolbox.getCurrentPanel(); - inspector.selection.setNode(this.target, "browser-context-menu"); + + this.browser.messageManager.sendAsyncMessage("debug:inspect", {}, {node: this.target}); + inspector.walker.findInspectingNode().then(nodeFront => { + inspector.selection.setNodeFront(nodeFront, "browser-context-menu"); + }); }.bind(this)); }, diff --git a/application/palemoon/base/content/padlock.js b/application/palemoon/base/content/padlock.js index 9e6715769..9c29524ce 100644 --- a/application/palemoon/base/content/padlock.js +++ b/application/palemoon/base/content/padlock.js @@ -1,3 +1,6 @@ +var Cc = Components.classes; +var Ci = Components.interfaces; +var Cu = Components.utils; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); var padlock_PadLock = diff --git a/application/palemoon/base/content/pageinfo/pageInfo.js b/application/palemoon/base/content/pageinfo/pageInfo.js index ba93ee817..83f0ddb91 100644 --- a/application/palemoon/base/content/pageinfo/pageInfo.js +++ b/application/palemoon/base/content/pageinfo/pageInfo.js @@ -359,7 +359,7 @@ function loadPageInfo() makeTabs(gDocument, gWindow); initFeedTab(); - onLoadPermission(); + onLoadPermission(gDocument.nodePrincipal); /* Call registered overlay init functions */ onLoadRegistry.forEach(function(func) { func(); }); @@ -857,7 +857,7 @@ function onBlockImage() if (checkbox.checked) permissionManager.add(uri, "image", nsIPermissionManager.DENY_ACTION); else - permissionManager.remove(uri.host, "image"); + permissionManager.remove(uri, "image"); } function onImageSelect() diff --git a/application/palemoon/base/content/pageinfo/permissions.js b/application/palemoon/base/content/pageinfo/permissions.js index 7a0006b61..2fa0cc303 100644 --- a/application/palemoon/base/content/pageinfo/permissions.js +++ b/application/palemoon/base/content/pageinfo/permissions.js @@ -12,9 +12,10 @@ const IMAGE_DENY = 2; const COOKIE_DENY = 2; const COOKIE_SESSION = 2; -const nsIQuotaManager = Components.interfaces.nsIQuotaManager; +const nsIQuotaManagerService = Components.interfaces.nsIQuotaManagerService; var gPermURI; +var gPermPrincipal; var gPrefs; var gUsageRequest; @@ -107,7 +108,7 @@ var permissionObserver = { } }; -function onLoadPermission() +function onLoadPermission(principal) { gPrefs = Components.classes[PREFERENCES_CONTRACTID] .getService(Components.interfaces.nsIPrefBranch); @@ -116,6 +117,7 @@ function onLoadPermission() var permTab = document.getElementById("permTab"); if (/^https?$/.test(uri.scheme)) { gPermURI = uri; + gPermPrincipal = principal; var hostText = document.getElementById("hostText"); hostText.value = gPermURI.host; @@ -187,7 +189,7 @@ function onCheckboxClick(aPartId) var command = document.getElementById("cmd_" + aPartId + "Toggle"); var checkbox = document.getElementById(aPartId + "Def"); if (checkbox.checked) { - permissionManager.remove(gPermURI.host, aPartId); + permissionManager.remove(gPermURI, aPartId); command.setAttribute("disabled", "true"); var perm = gPermObj[aPartId](); setRadioState(aPartId, perm); @@ -211,7 +213,7 @@ function onRadioClick(aPartId) var id = radioGroup.selectedItem.id; var permission = id.split('#')[1]; if (permission == UNKNOWN) { - permissionManager.remove(gPermURI.host, aPartId); + permissionManager.remove(gPermURI, aPartId); } else { permissionManager.add(gPermURI, aPartId, permission); } @@ -230,10 +232,13 @@ function initIndexedDBRow() row.appendChild(extras); - var quotaManager = Components.classes["@mozilla.org/dom/quota/manager;1"] - .getService(nsIQuotaManager); + var quotaManagerService = + Components.classes["@mozilla.org/dom/quota-manager-service;1"] + .getService(nsIQuotaManagerService); + gUsageRequest = - quotaManager.getUsageForURI(gPermURI, onIndexedDBUsageCallback); + quotaManagerService.getUsageForPrincipal(gPermPrincipal, + onIndexedDBUsageCallback); var status = document.getElementById("indexedDBStatus"); var button = document.getElementById("indexedDBClear"); @@ -245,22 +250,24 @@ function initIndexedDBRow() function onIndexedDBClear() { - Components.classes["@mozilla.org/dom/quota/manager;1"] - .getService(nsIQuotaManager) - .clearStoragesForURI(gPermURI); + Components.classes["@mozilla.org/dom/quota-manager-service;1"] + .getService(nsIQuotaManagerService) + .clearStoragesForPrincipal(gPermPrincipal); var permissionManager = Components.classes[PERMISSION_CONTRACTID] .getService(nsIPermissionManager); - permissionManager.remove(gPermURI.host, "indexedDB"); + permissionManager.remove(gPermURI, "indexedDB"); initIndexedDBRow(); } -function onIndexedDBUsageCallback(uri, usage, fileUsage) +function onIndexedDBUsageCallback(request) { + let uri = request.principal.URI; if (!uri.equals(gPermURI)) { - throw new Error("Callback received for bad URI: " + uri); + throw new Error("Callback received for bad URI: " + uri.spec); } + let usage = request.result.usage; if (usage) { if (!("DownloadUtils" in window)) { Components.utils.import("resource://gre/modules/DownloadUtils.jsm"); @@ -355,20 +362,33 @@ function initPluginsRow() { } } - let entries = [ - { + // Tycho: + // let entries = [ + // { + // "permission": item[0], + // "obj": item[1], + // } + // for (item of permissionMap) + // ]; + let entries = []; + for (let item of permissionMap) { + entries.push({ "permission": item[0], - "obj": item[1], - } - for (item of permissionMap) - ]; + "obj": item[1] + }); + } entries.sort(function(a, b) { return ((a.obj.name < b.obj.name) ? -1 : (a.obj.name == b.obj.name ? 0 : 1)); }); - let permissionEntries = [ - fillInPluginPermissionTemplate(p.permission, p.obj) for (p of entries) - ]; + // Tycho: + // let permissionEntries = [ + // fillInPluginPermissionTemplate(p.permission, p.obj) for (p of entries) + // ]; + let permissionEntries = []; + entries.forEach(function (p) { + permissionEntries.push(fillInPluginPermissionTemplate(p.permission, p.obj)); + }); let permPluginsRow = document.getElementById("permPluginsRow"); clearPluginPermissionTemplate(); diff --git a/application/palemoon/base/content/popup-notifications.inc b/application/palemoon/base/content/popup-notifications.inc index 04f4cb5b7..7be975b7f 100644 --- a/application/palemoon/base/content/popup-notifications.inc +++ b/application/palemoon/base/content/popup-notifications.inc @@ -54,7 +54,7 @@ </hbox> </panel> - +#ifdef MOZ_WEBRTC <popupnotification id="webRTC-shareDevices-notification" hidden="true"> <popupnotificationcontent id="webRTC-selectCamera" orient="vertical"> <separator class="thin"/> @@ -75,7 +75,7 @@ </menulist> </popupnotificationcontent> </popupnotification> - +#endif <popupnotification id="servicesInstall-notification" hidden="true"> <popupnotificationcontent orient="vertical" align="start"> <!-- XXX bug 974146, tests are looking for this, can't remove yet. --> @@ -89,6 +89,14 @@ </popupnotificationcontent> </popupnotification> + <popupnotification id="password-notification" hidden="true"> + <popupnotificationcontent orient="vertical"> + <textbox id="password-notification-username"/> + <textbox id="password-notification-password" type="password" show-content=""/> + <checkbox id="password-notification-visibilityToggle" hidden="true"/> + </popupnotificationcontent> + </popupnotification> + <popupnotification id="mixed-content-blocked-notification" hidden="true"> <popupnotificationcontent orient="vertical" align="start"> <separator/> diff --git a/application/palemoon/base/content/sanitize.js b/application/palemoon/base/content/sanitize.js index 89843c86d..fccec6c98 100644 --- a/application/palemoon/base/content/sanitize.js +++ b/application/palemoon/base/content/sanitize.js @@ -15,7 +15,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "Promise", XPCOMUtils.defineLazyModuleGetter(this, "Task", "resource://gre/modules/Task.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "console", - "resource://gre/modules/devtools/Console.jsm"); + "resource://gre/modules/Console.jsm"); function Sanitizer() {} Sanitizer.prototype = { diff --git a/application/palemoon/base/content/tabbrowser.xml b/application/palemoon/base/content/tabbrowser.xml index 3e30c2ba1..b5395bbd9 100644 --- a/application/palemoon/base/content/tabbrowser.xml +++ b/application/palemoon/base/content/tabbrowser.xml @@ -302,6 +302,16 @@ </body> </method> + <method name="getBrowserForContentWindow"> + <parameter name="aWindow"/> + <body> + <![CDATA[ + var tab = this._getTabForContentWindow(aWindow); + return tab ? tab.linkedBrowser : null; + ]]> + </body> + </method> + <method name="getBrowserForOuterWindowID"> <parameter name="aID"/> <body> @@ -707,7 +717,8 @@ let autocomplete = this.mTabBrowser._placesAutocomplete; if (this.mBrowser.registeredOpenURI) { - autocomplete.unregisterOpenPage(this.mBrowser.registeredOpenURI); + autocomplete.unregisterOpenPage(this.mBrowser.registeredOpenURI, + this.mBrowser.getAttribute("usercontextid") || 0); delete this.mBrowser.registeredOpenURI; } // Tabs in private windows aren't registered as "Open" so @@ -715,7 +726,8 @@ if (!isBlankPageURL(aLocation.spec) && (!PrivateBrowsingUtils.isWindowPrivate(window) || PrivateBrowsingUtils.permanentPrivateBrowsing)) { - autocomplete.registerOpenPage(aLocation); + autocomplete.registerOpenPage(aLocation, + this.mBrowser.getAttribute("usercontextid") || 0); this.mBrowser.registeredOpenURI = aLocation; } } @@ -1865,7 +1877,8 @@ this.mTabListeners[aTab._tPos].destroy(); if (browser.registeredOpenURI && !aTabWillBeMoved) { - this._placesAutocomplete.unregisterOpenPage(browser.registeredOpenURI); + this._placesAutocomplete.unregisterOpenPage(browser.registeredOpenURI, + browser.getAttribute("usercontextid") || 0); delete browser.registeredOpenURI; } @@ -2209,7 +2222,8 @@ <![CDATA[ // If the current URI is registered as open remove it from the list. if (aOurBrowser.registeredOpenURI) { - this._placesAutocomplete.unregisterOpenPage(aOurBrowser.registeredOpenURI); + this._placesAutocomplete.unregisterOpenPage(aOurBrowser.registeredOpenURI, + aOurBrowser.getAttribute("usercontextid") || 0); delete aOurBrowser.registeredOpenURI; } @@ -3066,7 +3080,8 @@ for (var i = 0; i < this.mTabListeners.length; ++i) { let browser = this.getBrowserAtIndex(i); if (browser.registeredOpenURI) { - this._placesAutocomplete.unregisterOpenPage(browser.registeredOpenURI); + this._placesAutocomplete.unregisterOpenPage(browser.registeredOpenURI, + browser.getAttribute("usercontextid") || 0); delete browser.registeredOpenURI; } browser.webProgress.removeProgressListener(this.mTabFilters[i]); diff --git a/application/palemoon/branding/shared/pref/preferences.inc b/application/palemoon/branding/shared/pref/preferences.inc index a45870b01..a3cfcd138 100644 --- a/application/palemoon/branding/shared/pref/preferences.inc +++ b/application/palemoon/branding/shared/pref/preferences.inc @@ -119,3 +119,11 @@ pref("browser.sessionstore.interval",60000); //every minute instead of every 10 pref("accessibility.force_disabled", 1); // ============================================================================ + +// ===| DevTools |============================================================= + +// Number of usages of the web console or scratchpad. +// If this is less than 5, then pasting code into the web console or scratchpad is disabled +pref("devtools.selfxss.count", 100); + +// ============================================================================ diff --git a/application/palemoon/components/about/AboutRedirector.cpp b/application/palemoon/components/about/AboutRedirector.cpp index b5dd4abfb..d52b873b9 100644 --- a/application/palemoon/components/about/AboutRedirector.cpp +++ b/application/palemoon/components/about/AboutRedirector.cpp @@ -30,17 +30,47 @@ struct RedirEntry { URI_SAFE_FOR_UNTRUSTED_CONTENT. */ static RedirEntry kRedirMap[] = { - { "certerror", "chrome://browser/content/certerror/aboutCertError.xhtml", + { + "certerror", "chrome://browser/content/certerror/aboutCertError.xhtml", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | nsIAboutModule::ALLOW_SCRIPT | - nsIAboutModule::HIDE_FROM_ABOUTABOUT }, - { "feeds", "chrome://browser/content/feeds/subscribe.xhtml", + nsIAboutModule::HIDE_FROM_ABOUTABOUT + }, + { + "downloads", "chrome://browser/content/downloads/contentAreaDownloadsView.xul", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "feeds", "chrome://browser/content/feeds/subscribe.xhtml", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | nsIAboutModule::ALLOW_SCRIPT | - nsIAboutModule::HIDE_FROM_ABOUTABOUT }, - { "privatebrowsing", "chrome://browser/content/aboutPrivateBrowsing.xhtml", - nsIAboutModule::ALLOW_SCRIPT }, - { "rights", + nsIAboutModule::HIDE_FROM_ABOUTABOUT + }, + { + "home", "chrome://browser/content/abouthome/aboutHome.xhtml", + nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | + nsIAboutModule::MAKE_LINKABLE | + nsIAboutModule::ALLOW_SCRIPT + }, + { + "newtab", "chrome://browser/content/newtab/newTab.xul", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "palemoon", "chrome://global/content/memoriam.xhtml", + nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | + nsIAboutModule::HIDE_FROM_ABOUTABOUT + }, + { + "permissions", "chrome://browser/content/preferences/aboutPermissions.xul", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "privatebrowsing", "chrome://browser/content/aboutPrivateBrowsing.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "rights", #ifdef MOZ_OFFICIAL_BRANDING "chrome://global/content/aboutRights.xhtml", #else @@ -48,34 +78,27 @@ static RedirEntry kRedirMap[] = { #endif nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | nsIAboutModule::MAKE_LINKABLE | - nsIAboutModule::ALLOW_SCRIPT }, - { "palemoon", "chrome://global/content/palemoon.xhtml", - nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | - nsIAboutModule::HIDE_FROM_ABOUTABOUT }, - { "logopage", "chrome://global/content/logopage.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "robots", "chrome://browser/content/aboutRobots.xhtml", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | - nsIAboutModule::HIDE_FROM_ABOUTABOUT }, - { "robots", "chrome://browser/content/aboutRobots.xhtml", - nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | - nsIAboutModule::ALLOW_SCRIPT }, - { "sessionrestore", "chrome://browser/content/aboutSessionRestore.xhtml", - nsIAboutModule::ALLOW_SCRIPT }, + nsIAboutModule::ALLOW_SCRIPT + }, + { + "sessionrestore", "chrome://browser/content/aboutSessionRestore.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, #ifdef MOZ_SERVICES_SYNC - { "sync-progress", "chrome://browser/content/sync/progress.xhtml", - nsIAboutModule::ALLOW_SCRIPT }, - { "sync-tabs", "chrome://browser/content/sync/aboutSyncTabs.xul", - nsIAboutModule::ALLOW_SCRIPT }, + { + "sync-progress", "chrome://browser/content/sync/progress.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "sync-tabs", "chrome://browser/content/sync/aboutSyncTabs.xul", + nsIAboutModule::ALLOW_SCRIPT + }, #endif - { "home", "chrome://browser/content/abouthome/aboutHome.xhtml", - nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | - nsIAboutModule::MAKE_LINKABLE | - nsIAboutModule::ALLOW_SCRIPT }, - { "newtab", "chrome://browser/content/newtab/newTab.xul", - nsIAboutModule::ALLOW_SCRIPT }, - { "permissions", "chrome://browser/content/preferences/aboutPermissions.xul", - nsIAboutModule::ALLOW_SCRIPT }, - { "downloads", "chrome://browser/content/downloads/contentAreaDownloadsView.xul", - nsIAboutModule::ALLOW_SCRIPT }, }; static const int kRedirTotal = ArrayLength(kRedirMap); diff --git a/application/palemoon/components/build/moz.build b/application/palemoon/components/build/moz.build index 5bc4858d7..c85723e16 100644 --- a/application/palemoon/components/build/moz.build +++ b/application/palemoon/components/build/moz.build @@ -18,7 +18,6 @@ LOCAL_INCLUDES += [ '../about', '../dirprovider', '../feeds', - '../migration', '../shell', ] diff --git a/application/palemoon/components/build/nsBrowserCompsCID.h b/application/palemoon/components/build/nsBrowserCompsCID.h index e325e43d4..23670ae80 100644 --- a/application/palemoon/components/build/nsBrowserCompsCID.h +++ b/application/palemoon/components/build/nsBrowserCompsCID.h @@ -4,14 +4,6 @@ ///////////////////////////////////////////////////////////////////////////// -#ifdef XP_WIN -#define NS_WINIEHISTORYENUMERATOR_CID \ -{ 0x93480624, 0x806e, 0x4756, { 0xb7, 0xcb, 0x0f, 0xb7, 0xdd, 0x74, 0x6a, 0x8f } } - -#define NS_IEHISTORYENUMERATOR_CONTRACTID \ - "@mozilla.org/profile/migrator/iehistoryenumerator;1" -#endif - #define NS_SHELLSERVICE_CID \ { 0x63c7b9f4, 0xcc8, 0x43f8, { 0xb6, 0x66, 0xa, 0x66, 0x16, 0x55, 0xcb, 0x73 } } diff --git a/application/palemoon/components/build/nsModule.cpp b/application/palemoon/components/build/nsModule.cpp index d5b79b455..304280ca9 100644 --- a/application/palemoon/components/build/nsModule.cpp +++ b/application/palemoon/components/build/nsModule.cpp @@ -16,10 +16,6 @@ #include "nsGNOMEShellService.h" #endif -#if defined(XP_WIN) -#include "nsIEHistoryEnumerator.h" -#endif - #include "rdf.h" #include "nsFeedSniffer.h" #include "AboutRedirector.h" @@ -40,10 +36,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacShellService) NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGNOMEShellService, Init) #endif -#if defined(XP_WIN) -NS_GENERIC_FACTORY_CONSTRUCTOR(nsIEHistoryEnumerator) -#endif - NS_GENERIC_FACTORY_CONSTRUCTOR(nsFeedSniffer) NS_DEFINE_NAMED_CID(NS_BROWSERDIRECTORYPROVIDER_CID); @@ -54,9 +46,7 @@ NS_DEFINE_NAMED_CID(NS_SHELLSERVICE_CID); #endif NS_DEFINE_NAMED_CID(NS_FEEDSNIFFER_CID); NS_DEFINE_NAMED_CID(NS_BROWSER_ABOUT_REDIRECTOR_CID); -#if defined(XP_WIN) -NS_DEFINE_NAMED_CID(NS_WINIEHISTORYENUMERATOR_CID); -#elif defined(XP_MACOSX) +#ifdef XP_MACOSX NS_DEFINE_NAMED_CID(NS_SHELLSERVICE_CID); #endif @@ -69,9 +59,7 @@ static const mozilla::Module::CIDEntry kBrowserCIDs[] = { #endif { &kNS_FEEDSNIFFER_CID, false, nullptr, nsFeedSnifferConstructor }, { &kNS_BROWSER_ABOUT_REDIRECTOR_CID, false, nullptr, AboutRedirector::Create }, -#if defined(XP_WIN) - { &kNS_WINIEHISTORYENUMERATOR_CID, false, nullptr, nsIEHistoryEnumeratorConstructor }, -#elif defined(XP_MACOSX) +#ifdef XP_MACOSX { &kNS_SHELLSERVICE_CID, false, nullptr, nsMacShellServiceConstructor }, #endif { nullptr } @@ -91,7 +79,6 @@ static const mozilla::Module::ContractIDEntry kBrowserContracts[] = { { NS_ABOUT_MODULE_CONTRACTID_PREFIX "privatebrowsing", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, { NS_ABOUT_MODULE_CONTRACTID_PREFIX "rights", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, { NS_ABOUT_MODULE_CONTRACTID_PREFIX "palemoon", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, - { NS_ABOUT_MODULE_CONTRACTID_PREFIX "logopage", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, { NS_ABOUT_MODULE_CONTRACTID_PREFIX "robots", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, { NS_ABOUT_MODULE_CONTRACTID_PREFIX "sessionrestore", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, #ifdef MOZ_SERVICES_SYNC @@ -102,9 +89,7 @@ static const mozilla::Module::ContractIDEntry kBrowserContracts[] = { { NS_ABOUT_MODULE_CONTRACTID_PREFIX "newtab", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, { NS_ABOUT_MODULE_CONTRACTID_PREFIX "permissions", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, { NS_ABOUT_MODULE_CONTRACTID_PREFIX "downloads", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, -#if defined(XP_WIN) - { NS_IEHISTORYENUMERATOR_CONTRACTID, &kNS_WINIEHISTORYENUMERATOR_CID }, -#elif defined(XP_MACOSX) +#ifdef XP_MACOSX { NS_SHELLSERVICE_CONTRACTID, &kNS_SHELLSERVICE_CID }, #endif { nullptr } diff --git a/application/palemoon/components/downloads/DownloadsCommon.jsm b/application/palemoon/components/downloads/DownloadsCommon.jsm index b90baaf9c..0921f8400 100644 --- a/application/palemoon/components/downloads/DownloadsCommon.jsm +++ b/application/palemoon/components/downloads/DownloadsCommon.jsm @@ -867,9 +867,19 @@ DownloadsDataCtor.prototype = { // Sort backwards by start time, ensuring that the most recent // downloads are added first regardless of their state. - let loadedItemsArray = [dataItem - for each (dataItem in this.dataItems) - if (dataItem)]; + // Tycho: + //let loadedItemsArray = [dataItem + // for each (dataItem in this.dataItems) + // if (dataItem)]; + + let loadedItemsArray = []; + + for each (let dataItem in this.dataItems) { + if (dataItem) { + loadedItemsArray.push(dataItem); + } + } + loadedItemsArray.sort(function(a, b) b.startTime - a.startTime); loadedItemsArray.forEach( function (dataItem) aView.onDataItemAdded(dataItem, false) diff --git a/application/palemoon/components/downloads/content/allDownloadsViewOverlay.js b/application/palemoon/components/downloads/content/allDownloadsViewOverlay.js index e1d0e75d4..9d90b20e1 100644 --- a/application/palemoon/components/downloads/content/allDownloadsViewOverlay.js +++ b/application/palemoon/components/downloads/content/allDownloadsViewOverlay.js @@ -8,9 +8,9 @@ * ON IT AS AN API. */ -let Cu = Components.utils; -let Ci = Components.interfaces; -let Cc = Components.classes; +var Cu = Components.utils; +var Ci = Components.interfaces; +var Cc = Components.classes; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); @@ -1408,7 +1408,12 @@ DownloadsPlacesView.prototype = { _copySelectedDownloadsToClipboard: function DPV__copySelectedDownloadsToClipboard() { let selectedElements = this._richlistbox.selectedItems; - let urls = [e._shell.downloadURI for each (e in selectedElements)]; + // Tycho: let urls = [e._shell.downloadURI for each (e in selectedElements)]; + let urls = []; + + for each (e in selectedElements) { + urls.push(e._shell.downloadURI); + } Cc["@mozilla.org/widget/clipboardhelper;1"]. getService(Ci.nsIClipboardHelper).copyString(urls.join("\n"), document); diff --git a/application/palemoon/components/migration/BrowserProfileMigrators.manifest b/application/palemoon/components/migration/BrowserProfileMigrators.manifest deleted file mode 100644 index d7fec75e3..000000000 --- a/application/palemoon/components/migration/BrowserProfileMigrators.manifest +++ /dev/null @@ -1,14 +0,0 @@ -component {6F8BB968-C14F-4D6F-9733-6C6737B35DCE} ProfileMigrator.js -contract @mozilla.org/toolkit/profile-migrator;1 {6F8BB968-C14F-4D6F-9733-6C6737B35DCE} -component {4cec1de4-1671-4fc3-a53e-6c539dc77a26} ChromeProfileMigrator.js -contract @mozilla.org/profile/migrator;1?app=browser&type=chrome {4cec1de4-1671-4fc3-a53e-6c539dc77a26} -component {91185366-ba97-4438-acba-48deaca63386} FirefoxProfileMigrator.js -contract @mozilla.org/profile/migrator;1?app=browser&type=firefox {91185366-ba97-4438-acba-48deaca63386} -#ifdef HAS_IE_MIGRATOR -component {3d2532e3-4932-4774-b7ba-968f5899d3a4} IEProfileMigrator.js -contract @mozilla.org/profile/migrator;1?app=browser&type=ie {3d2532e3-4932-4774-b7ba-968f5899d3a4} -#endif -#ifdef HAS_SAFARI_MIGRATOR -component {4b609ecf-60b2-4655-9df4-dc149e474da1} SafariProfileMigrator.js -contract @mozilla.org/profile/migrator;1?app=browser&type=safari {4b609ecf-60b2-4655-9df4-dc149e474da1} -#endif diff --git a/application/palemoon/components/migration/ChromeProfileMigrator.js b/application/palemoon/components/migration/ChromeProfileMigrator.js deleted file mode 100644 index 61955fbb4..000000000 --- a/application/palemoon/components/migration/ChromeProfileMigrator.js +++ /dev/null @@ -1,463 +0,0 @@ -/* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: sw=2 ts=2 sts=2 et */ -/* 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 Cc = Components.classes; -const Ci = Components.interfaces; -const Cu = Components.utils; -const Cr = Components.results; - -const FILE_INPUT_STREAM_CID = "@mozilla.org/network/file-input-stream;1"; - -const S100NS_FROM1601TO1970 = 0x19DB1DED53E8000; -const S100NS_PER_MS = 10; - -const AUTH_TYPE = { - SCHEME_HTML: 0, - SCHEME_BASIC: 1, - SCHEME_DIGEST: 2 -}; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/NetUtil.jsm"); -Cu.import("resource://gre/modules/FileUtils.jsm"); -Cu.import("resource:///modules/MigrationUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils", - "resource://gre/modules/PlacesUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "OSCrypto", - "resource://gre/modules/OSCrypto.jsm"); - -/** - * Convert Chrome time format to Date object - * - * @param aTime - * Chrome time - * @return converted Date object - * @note Google Chrome uses FILETIME / 10 as time. - * FILETIME is based on same structure of Windows. - */ -function chromeTimeToDate(aTime) -{ - return new Date((aTime * S100NS_PER_MS - S100NS_FROM1601TO1970 ) / 10000); -} - -/** - * Insert bookmark items into specific folder. - * - * @param aFolderId - * id of folder where items will be inserted - * @param aItems - * bookmark items to be inserted - */ -function insertBookmarkItems(aFolderId, aItems) -{ - for (let i = 0; i < aItems.length; i++) { - let item = aItems[i]; - - try { - if (item.type == "url") { - PlacesUtils.bookmarks.insertBookmark(aFolderId, - NetUtil.newURI(item.url), - PlacesUtils.bookmarks.DEFAULT_INDEX, - item.name); - } else if (item.type == "folder") { - let newFolderId = - PlacesUtils.bookmarks.createFolder(aFolderId, - item.name, - PlacesUtils.bookmarks.DEFAULT_INDEX); - - insertBookmarkItems(newFolderId, item.children); - } - } catch (e) { - Cu.reportError(e); - } - } -} - - -function ChromeProfileMigrator() { - let chromeUserDataFolder = FileUtils.getDir( -#ifdef XP_WIN - "LocalAppData", ["Google", "Chrome", "User Data"] -#elifdef XP_MACOSX - "ULibDir", ["Application Support", "Google", "Chrome"] -#else - "Home", [".config", "google-chrome"] -#endif - , false); - this._chromeUserDataFolder = chromeUserDataFolder.exists() ? - chromeUserDataFolder : null; -} - -ChromeProfileMigrator.prototype = Object.create(MigratorPrototype); - -ChromeProfileMigrator.prototype.getResources = - function Chrome_getResources(aProfile) { - if (this._chromeUserDataFolder) { - let profileFolder = this._chromeUserDataFolder.clone(); - profileFolder.append(aProfile.id); - if (profileFolder.exists()) { - let possibleResources = [GetBookmarksResource(profileFolder), - GetHistoryResource(profileFolder), - GetCookiesResource(profileFolder), -#ifdef XP_WIN - GetWindowsPasswordsResource(profileFolder) -#endif - ]; - return [r for each (r in possibleResources) if (r != null)]; - } - } - return []; - }; - -Object.defineProperty(ChromeProfileMigrator.prototype, "sourceProfiles", { - get: function Chrome_sourceProfiles() { - if ("__sourceProfiles" in this) - return this.__sourceProfiles; - - if (!this._chromeUserDataFolder) - return []; - - let profiles = []; - try { - // Local State is a JSON file that contains profile info. - let localState = this._chromeUserDataFolder.clone(); - localState.append("Local State"); - if (!localState.exists()) - throw new Error("Chrome's 'Local State' file does not exist."); - if (!localState.isReadable()) - throw new Error("Chrome's 'Local State' file could not be read."); - - let fstream = Cc[FILE_INPUT_STREAM_CID].createInstance(Ci.nsIFileInputStream); - fstream.init(localState, -1, 0, 0); - let inputStream = NetUtil.readInputStreamToString(fstream, fstream.available(), - { charset: "UTF-8" }); - let info_cache = JSON.parse(inputStream).profile.info_cache; - for (let profileFolderName in info_cache) { - let profileFolder = this._chromeUserDataFolder.clone(); - profileFolder.append(profileFolderName); - profiles.push({ - id: profileFolderName, - name: info_cache[profileFolderName].name || profileFolderName, - }); - } - } catch (e) { - Cu.reportError("Error detecting Chrome profiles: " + e); - // If we weren't able to detect any profiles above, fallback to the Default profile. - let defaultProfileFolder = this._chromeUserDataFolder.clone(); - defaultProfileFolder.append("Default"); - if (defaultProfileFolder.exists()) { - profiles = [{ - id: "Default", - name: "Default", - }]; - } - } - - // Only list profiles from which any data can be imported - return this.__sourceProfiles = profiles.filter(function(profile) { - let resources = this.getResources(profile); - return resources && resources.length > 0; - }, this); - } -}); - -Object.defineProperty(ChromeProfileMigrator.prototype, "sourceHomePageURL", { - get: function Chrome_sourceHomePageURL() { - let prefsFile = this._chromeUserDataFolder.clone(); - prefsFile.append("Preferences"); - if (prefsFile.exists()) { - // XXX reading and parsing JSON is synchronous. - let fstream = Cc[FILE_INPUT_STREAM_CID]. - createInstance(Ci.nsIFileInputStream); - fstream.init(file, -1, 0, 0); - try { - return JSON.parse( - NetUtil.readInputStreamToString(fstream, fstream.available(), - { charset: "UTF-8" }) - ).homepage; - } - catch(e) { - Cu.reportError("Error parsing Chrome's preferences file: " + e); - } - } - return ""; - } -}); - -function GetBookmarksResource(aProfileFolder) { - let bookmarksFile = aProfileFolder.clone(); - bookmarksFile.append("Bookmarks"); - if (!bookmarksFile.exists()) - return null; - - return { - type: MigrationUtils.resourceTypes.BOOKMARKS, - - migrate: function(aCallback) { - NetUtil.asyncFetch(bookmarksFile, MigrationUtils.wrapMigrateFunction( - function(aInputStream, aResultCode) { - if (!Components.isSuccessCode(aResultCode)) - throw new Error("Could not read Bookmarks file"); - - // Parse Chrome bookmark file that is JSON format - let bookmarkJSON = NetUtil.readInputStreamToString( - aInputStream, aInputStream.available(), { charset : "UTF-8" }); - let roots = JSON.parse(bookmarkJSON).roots; - PlacesUtils.bookmarks.runInBatchMode({ - runBatched: function() { - // Importing bookmark bar items - if (roots.bookmark_bar.children && - roots.bookmark_bar.children.length > 0) { - // Toolbar - let parentId = PlacesUtils.toolbarFolderId; - if (!MigrationUtils.isStartupMigration) { - parentId = MigrationUtils.createImportedBookmarksFolder( - "Chrome", parentId); - } - insertBookmarkItems(parentId, roots.bookmark_bar.children); - } - - // Importing bookmark menu items - if (roots.other.children && - roots.other.children.length > 0) { - // Bookmark menu - let parentId = PlacesUtils.bookmarksMenuFolderId; - if (!MigrationUtils.isStartupMigration) { - parentId = MigrationUtils.createImportedBookmarksFolder( - "Chrome", parentId); - } - insertBookmarkItems(parentId, roots.other.children); - } - } - }, null); - }, aCallback)); - } - }; -} - -function GetHistoryResource(aProfileFolder) { - let historyFile = aProfileFolder.clone(); - historyFile.append("History"); - if (!historyFile.exists()) - return null; - - return { - type: MigrationUtils.resourceTypes.HISTORY, - - migrate: function(aCallback) { - let dbConn = Services.storage.openUnsharedDatabase(historyFile); - let stmt = dbConn.createAsyncStatement( - "SELECT url, title, last_visit_time, typed_count FROM urls WHERE hidden = 0"); - - stmt.executeAsync({ - handleResult : function(aResults) { - let places = []; - for (let row = aResults.getNextRow(); row; row = aResults.getNextRow()) { - try { - // if having typed_count, we changes transition type to typed. - let transType = PlacesUtils.history.TRANSITION_LINK; - if (row.getResultByName("typed_count") > 0) - transType = PlacesUtils.history.TRANSITION_TYPED; - - places.push({ - uri: NetUtil.newURI(row.getResultByName("url")), - title: row.getResultByName("title"), - visits: [{ - transitionType: transType, - visitDate: chromeTimeToDate( - row.getResultByName( - "last_visit_time")) * 1000, - }], - }); - } catch (e) { - Cu.reportError(e); - } - } - - try { - PlacesUtils.asyncHistory.updatePlaces(places); - } catch (e) { - Cu.reportError(e); - } - }, - - handleError : function(aError) { - Cu.reportError("Async statement execution returned with '" + - aError.result + "', '" + aError.message + "'"); - }, - - handleCompletion : function(aReason) { - dbConn.asyncClose(); - aCallback(aReason == Ci.mozIStorageStatementCallback.REASON_FINISHED); - } - }); - stmt.finalize(); - } - }; -} - -function GetCookiesResource(aProfileFolder) { - let cookiesFile = aProfileFolder.clone(); - cookiesFile.append("Cookies"); - if (!cookiesFile.exists()) - return null; - - return { - type: MigrationUtils.resourceTypes.COOKIES, - - migrate: function(aCallback) { - let dbConn = Services.storage.openUnsharedDatabase(cookiesFile); - let stmt = dbConn.createAsyncStatement( - "SELECT host_key, path, name, value, secure, httponly, expires_utc FROM cookies"); - - stmt.executeAsync({ - handleResult : function(aResults) { - for (let row = aResults.getNextRow(); row; row = aResults.getNextRow()) { - let host_key = row.getResultByName("host_key"); - if (host_key.match(/^\./)) { - // 1st character of host_key may be ".", so we have to remove it - host_key = host_key.substr(1); - } - - try { - let expiresUtc = - chromeTimeToDate(row.getResultByName("expires_utc")) / 1000; - Services.cookies.add(host_key, - row.getResultByName("path"), - row.getResultByName("name"), - row.getResultByName("value"), - row.getResultByName("secure"), - row.getResultByName("httponly"), - false, - parseInt(expiresUtc)); - } catch (e) { - Cu.reportError(e); - } - } - }, - - handleError : function(aError) { - Cu.reportError("Async statement execution returned with '" + - aError.result + "', '" + aError.message + "'"); - }, - - handleCompletion : function(aReason) { - dbConn.asyncClose(); - aCallback(aReason == Ci.mozIStorageStatementCallback.REASON_FINISHED); - }, - }); - stmt.finalize(); - } - } -} - -function GetWindowsPasswordsResource(aProfileFolder) { - let loginFile = aProfileFolder.clone(); - loginFile.append("Login Data"); - if (!loginFile.exists()) - return null; - - return { - type: MigrationUtils.resourceTypes.PASSWORDS, - - migrate(aCallback) { - let dbConn = Services.storage.openUnsharedDatabase(loginFile); - let stmt = dbConn.createAsyncStatement(` - SELECT origin_url, action_url, username_element, username_value, - password_element, password_value, signon_realm, scheme, date_created, - times_used FROM logins WHERE blacklisted_by_user = 0`); - let crypto = new OSCrypto(); - let utf8Converter = Cc["@mozilla.org/intl/utf8converterservice;1"].getService(Ci.nsIUTF8ConverterService); - - stmt.executeAsync({ - _rowToLoginInfo(row) { - let loginInfo = { - username: utf8Converter.convertURISpecToUTF8(row.getResultByName("username_value"), "UTF-8"), - password: utf8Converter.convertURISpecToUTF8( - crypto.decryptData(crypto.arrayToString(row.getResultByName("password_value")), null), - "UTF-8"), - 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, - }; - - 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); - break; - default: - throw new Error("Login data scheme type not supported: " + - row.getResultByName("scheme")); - } - - return loginInfo; - }, - - handleResult(aResults) { - for (let row = aResults.getNextRow(); row; row = aResults.getNextRow()) { - try { - let loginInfo = this._rowToLoginInfo(row); - 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); - } - } catch (e) { - Cu.reportError(e); - } - } - }, - - handleError(aError) { - Cu.reportError("Async statement execution returned with '" + - aError.result + "', '" + aError.message + "'"); - }, - - handleCompletion(aReason) { - dbConn.asyncClose(); - aCallback(aReason == Ci.mozIStorageStatementCallback.REASON_FINISHED); - crypto.finalize(); - }, - }); - stmt.finalize(); - } - }; -} - -ChromeProfileMigrator.prototype.classDescription = "Chrome Profile Migrator"; -ChromeProfileMigrator.prototype.contractID = "@mozilla.org/profile/migrator;1?app=browser&type=chrome"; -ChromeProfileMigrator.prototype.classID = Components.ID("{4cec1de4-1671-4fc3-a53e-6c539dc77a26}"); - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ChromeProfileMigrator]); diff --git a/application/palemoon/components/migration/FirefoxProfileMigrator.js b/application/palemoon/components/migration/FirefoxProfileMigrator.js deleted file mode 100644 index ab4ae55fb..000000000 --- a/application/palemoon/components/migration/FirefoxProfileMigrator.js +++ /dev/null @@ -1,117 +0,0 @@ -/* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: sw=2 ts=2 sts=2 et */ - /* 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"; - -/* - * Migrates from a Pale Moon profile in a lossy manner in order to clean up a - * user's profile. Data is only migrated where the benefits outweigh the - * potential problems caused by importing undesired/invalid configurations - * from the source profile. - */ - -Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); -Components.utils.import("resource:///modules/MigrationUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "PlacesBackups", - "resource://gre/modules/PlacesBackups.jsm"); - -function FirefoxProfileMigrator() { } - -FirefoxProfileMigrator.prototype = Object.create(MigratorPrototype); - -FirefoxProfileMigrator.prototype._getAllProfiles = function () { - let allProfiles = new Map(); - let profiles = - Components.classes["@mozilla.org/toolkit/profile-service;1"] - .getService(Components.interfaces.nsIToolkitProfileService) - .profiles; - while (profiles.hasMoreElements()) { - let profile = profiles.getNext().QueryInterface(Components.interfaces.nsIToolkitProfile); - let rootDir = profile.rootDir; - - if (rootDir.exists() && rootDir.isReadable() && - !rootDir.equals(MigrationUtils.profileStartup.directory)) { - allProfiles.set(profile.name, rootDir); - } - } - return allProfiles; -}; - -function sorter(a, b) { - return a.id.toLocaleLowerCase().localeCompare(b.id.toLocaleLowerCase()); -} - -Object.defineProperty(FirefoxProfileMigrator.prototype, "sourceProfiles", { - get: function() { - return [{id: x, name: x} for (x of this._getAllProfiles().keys())].sort(sorter); - } -}); - -FirefoxProfileMigrator.prototype.getResources = function(aProfile) { - let sourceProfileDir = aProfile ? this._getAllProfiles().get(aProfile.id) : - Components.classes["@mozilla.org/toolkit/profile-service;1"] - .getService(Components.interfaces.nsIToolkitProfileService) - .selectedProfile.rootDir; - if (!sourceProfileDir || !sourceProfileDir.exists() || - !sourceProfileDir.isReadable()) - return null; - - // Being a startup-only migrator, we can rely on - // MigrationUtils.profileStartup being set. - let currentProfileDir = MigrationUtils.profileStartup.directory; - - // Surely data cannot be imported from the current profile. - if (sourceProfileDir.equals(currentProfileDir)) - return null; - - let getFileResource = function(aMigrationType, aFileNames) { - let files = []; - for (let fileName of aFileNames) { - let file = sourceProfileDir.clone(); - file.append(fileName); - - if (file.exists()) { - files.push(file); - } - } - if (!files.length) { - return null; - } - return { - type: aMigrationType, - migrate: function(aCallback) { - for (let file of files) { - file.copyTo(currentProfileDir, ""); - } - aCallback(true); - } - }; - }; - - let types = MigrationUtils.resourceTypes; - let places = getFileResource(types.HISTORY, ["places.sqlite", "places.sqlite-wal"]); - let cookies = getFileResource(types.COOKIES, ["cookies.sqlite", "cookies.sqlite-wal"]); - let passwords = getFileResource(types.PASSWORDS, - ["signons.sqlite", "logins.json", "key3.db"]); - let formData = getFileResource(types.FORMDATA, ["formhistory.sqlite"]); - let bookmarksBackups = getFileResource(types.OTHERDATA, - [PlacesBackups.profileRelativeFolderPath]); - let dictionary = getFileResource(types.OTHERDATA, ["persdict.dat"]); - - return [r for each (r in [places, cookies, passwords, formData, - dictionary, bookmarksBackups]) if (r)]; -} - -Object.defineProperty(FirefoxProfileMigrator.prototype, "startupOnlyMigrator", { - get: function() true -}); - - -FirefoxProfileMigrator.prototype.classDescription = "Firefox Profile Migrator"; -FirefoxProfileMigrator.prototype.contractID = "@mozilla.org/profile/migrator;1?app=browser&type=firefox"; -FirefoxProfileMigrator.prototype.classID = Components.ID("{91185366-ba97-4438-acba-48deaca63386}"); - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([FirefoxProfileMigrator]); diff --git a/application/palemoon/components/migration/IEProfileMigrator.js b/application/palemoon/components/migration/IEProfileMigrator.js deleted file mode 100644 index a46deae68..000000000 --- a/application/palemoon/components/migration/IEProfileMigrator.js +++ /dev/null @@ -1,521 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cu = Components.utils; -const Cr = Components.results; - -const kMainKey = "Software\\Microsoft\\Internet Explorer\\Main"; -const kRegMultiSz = 7; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/NetUtil.jsm"); -Cu.import("resource:///modules/MigrationUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils", - "resource://gre/modules/PlacesUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "ctypes", - "resource://gre/modules/ctypes.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "WindowsRegistry", - "resource://gre/modules/WindowsRegistry.jsm"); - -Cu.importGlobalProperties(["File"]); - -//////////////////////////////////////////////////////////////////////////////// -//// Helpers. - -let CtypesHelpers = { - _structs: {}, - _functions: {}, - _libs: {}, - - /** - * Must be invoked once before first use of any of the provided helpers. - */ - initialize: function CH_initialize() { - const WORD = ctypes.uint16_t; - const DWORD = ctypes.uint32_t; - const BOOL = ctypes.int; - - this._structs.SYSTEMTIME = new ctypes.StructType('SYSTEMTIME', [ - {wYear: WORD}, - {wMonth: WORD}, - {wDayOfWeek: WORD}, - {wDay: WORD}, - {wHour: WORD}, - {wMinute: WORD}, - {wSecond: WORD}, - {wMilliseconds: WORD} - ]); - - this._structs.FILETIME = new ctypes.StructType('FILETIME', [ - {dwLowDateTime: DWORD}, - {dwHighDateTime: DWORD} - ]); - - try { - this._libs.kernel32 = ctypes.open("Kernel32"); - this._functions.FileTimeToSystemTime = - this._libs.kernel32.declare("FileTimeToSystemTime", - ctypes.default_abi, - BOOL, - this._structs.FILETIME.ptr, - this._structs.SYSTEMTIME.ptr); - } catch (ex) { - this.finalize(); - } - }, - - /** - * Must be invoked once after last use of any of the provided helpers. - */ - finalize: function CH_finalize() { - this._structs = {}; - this._functions = {}; - for each (let lib in this._libs) { - try { - lib.close(); - } catch (ex) {} - } - this._libs = {}; - }, - - /** - * Converts a FILETIME struct (2 DWORDS), to a SYSTEMTIME struct. - * - * @param aTimeHi - * Least significant DWORD. - * @param aTimeLo - * Most significant DWORD. - * @return a Date object representing the converted datetime. - */ - fileTimeToDate: function CH_fileTimeToDate(aTimeHi, aTimeLo) { - let fileTime = this._structs.FILETIME(); - fileTime.dwLowDateTime = aTimeLo; - fileTime.dwHighDateTime = aTimeHi; - let systemTime = this._structs.SYSTEMTIME(); - let result = this._functions.FileTimeToSystemTime(fileTime.address(), - systemTime.address()); - if (result == 0) - throw new Error(ctypes.winLastError); - - return new Date(systemTime.wYear, - systemTime.wMonth - 1, - systemTime.wDay, - systemTime.wHour, - systemTime.wMinute, - systemTime.wSecond, - systemTime.wMilliseconds); - } -}; - -/** - * Checks whether an host is an IP (v4 or v6) address. - * - * @param aHost - * The host to check. - * @return whether aHost is an IP address. - */ -function hostIsIPAddress(aHost) { - try { - Services.eTLD.getBaseDomainFromHost(aHost); - } catch (e if e.result == Cr.NS_ERROR_HOST_IS_IP_ADDRESS) { - return true; - } catch (e) {} - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -//// Resources - -function Bookmarks() { -} - -Bookmarks.prototype = { - type: MigrationUtils.resourceTypes.BOOKMARKS, - - get exists() !!this._favoritesFolder, - - __favoritesFolder: null, - get _favoritesFolder() { - if (!this.__favoritesFolder) { - let favoritesFolder = Services.dirsvc.get("Favs", Ci.nsIFile); - if (favoritesFolder.exists() && favoritesFolder.isReadable()) - this.__favoritesFolder = favoritesFolder; - } - return this.__favoritesFolder; - }, - - __toolbarFolderName: null, - get _toolbarFolderName() { - if (!this.__toolbarFolderName) { - // Retrieve the name of IE's favorites subfolder that holds the bookmarks - // in the toolbar. This was previously stored in the registry and changed - // in IE7 to always be called "Links". - let folderName = WindowsRegistry.readRegKey(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER, - "Software\\Microsoft\\Internet Explorer\\Toolbar", - "LinksFolderName"); - this.__toolbarFolderName = folderName || "Links"; - } - return this.__toolbarFolderName; - }, - - migrate: function B_migrate(aCallback) { - PlacesUtils.bookmarks.runInBatchMode({ - runBatched: (function migrateBatched() { - // Import to the bookmarks menu. - let destFolderId = PlacesUtils.bookmarksMenuFolderId; - if (!MigrationUtils.isStartupMigration) { - destFolderId = - MigrationUtils.createImportedBookmarksFolder("IE", destFolderId); - } - - this._migrateFolder(this._favoritesFolder, destFolderId); - - aCallback(true); - }).bind(this) - }, null); - }, - - _migrateFolder: function B__migrateFolder(aSourceFolder, aDestFolderId) { - // TODO (bug 741993): the favorites order is stored in the Registry, at - // HCU\Software\Microsoft\Windows\CurrentVersion\Explorer\MenuOrder\Favorites - // Until we support it, bookmarks are imported in alphabetical order. - let entries = aSourceFolder.directoryEntries; - while (entries.hasMoreElements()) { - let entry = entries.getNext().QueryInterface(Ci.nsIFile); - - // Make sure that entry.path == entry.target to not follow .lnk folder - // shortcuts which could lead to infinite cycles. - if (entry.isDirectory() && entry.path == entry.target) { - let destFolderId; - if (entry.leafName == this._toolbarFolderName && - entry.parent.equals(this._favoritesFolder)) { - // Import to the bookmarks toolbar. - destFolderId = PlacesUtils.toolbarFolderId; - if (!MigrationUtils.isStartupMigration) { - destFolderId = - MigrationUtils.createImportedBookmarksFolder("IE", destFolderId); - } - } - else { - // Import to a new folder. - destFolderId = - PlacesUtils.bookmarks.createFolder(aDestFolderId, entry.leafName, - PlacesUtils.bookmarks.DEFAULT_INDEX); - } - - if (entry.isReadable()) { - // Recursively import the folder. - this._migrateFolder(entry, destFolderId); - } - } - else { - // Strip the .url extension, to both check this is a valid link file, - // 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]; - - PlacesUtils.bookmarks.insertBookmark(aDestFolderId, - uri, - PlacesUtils.bookmarks.DEFAULT_INDEX, - title); - } - } - } - } -}; - -function History() { -} - -History.prototype = { - type: MigrationUtils.resourceTypes.HISTORY, - - get exists() true, - - __typedURLs: null, - get _typedURLs() { - if (!this.__typedURLs) { - // The list of typed URLs is a sort of annotation stored in the registry. - // Currently, IE stores 25 entries and this value is not configurable, - // but we just keep reading up to the first non-existing entry to support - // possible future bumps of this limit. - this.__typedURLs = {}; - let registry = Cc["@mozilla.org/windows-registry-key;1"]. - createInstance(Ci.nsIWindowsRegKey); - try { - registry.open(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER, - "Software\\Microsoft\\Internet Explorer\\TypedURLs", - Ci.nsIWindowsRegKey.ACCESS_READ); - for (let entry = 1; registry.hasValue("url" + entry); entry++) { - let url = registry.readStringValue("url" + entry); - this.__typedURLs[url] = true; - } - } catch (ex) { - } finally { - registry.close(); - } - } - return this.__typedURLs; - }, - - migrate: function H_migrate(aCallback) { - let places = []; - let historyEnumerator = Cc["@mozilla.org/profile/migrator/iehistoryenumerator;1"]. - createInstance(Ci.nsISimpleEnumerator); - while (historyEnumerator.hasMoreElements()) { - let entry = historyEnumerator.getNext().QueryInterface(Ci.nsIPropertyBag2); - let uri = entry.get("uri").QueryInterface(Ci.nsIURI); - // MSIE stores some types of URLs in its history that we don't handle, - // like HTMLHelp and others. Since we don't properly map handling for - // all of them we just avoid importing them. - if (["http", "https", "ftp", "file"].indexOf(uri.scheme) == -1) { - continue; - } - - let title = entry.get("title"); - // Embed visits have no title and don't need to be imported. - if (title.length == 0) { - continue; - } - - // The typed urls are already fixed-up, so we can use them for comparison. - let transitionType = this._typedURLs[uri.spec] ? - Ci.nsINavHistoryService.TRANSITION_TYPED : - Ci.nsINavHistoryService.TRANSITION_LINK; - let lastVisitTime = entry.get("time"); - - places.push( - { uri: uri, - title: title, - visits: [{ transitionType: transitionType, - visitDate: lastVisitTime }] - } - ); - } - - // Check whether there is any history to import. - if (places.length == 0) { - aCallback(true); - return; - } - - PlacesUtils.asyncHistory.updatePlaces(places, { - _success: false, - handleResult: function() { - // Importing any entry is considered a successful import. - this._success = true; - }, - handleError: function() {}, - handleCompletion: function() { - aCallback(this._success); - } - }); - } -}; - -function Cookies() { -} - -Cookies.prototype = { - type: MigrationUtils.resourceTypes.COOKIES, - - get exists() !!this._cookiesFolder, - - __cookiesFolder: null, - get _cookiesFolder() { - // Cookies are stored in txt files, in a Cookies folder whose path varies - // across the different OS versions. CookD takes care of most of these - // cases, though, in Windows Vista/7, UAC makes a difference. - // If UAC is enabled, the most common destination is CookD/Low. Though, - // if the user runs the application in administrator mode or disables UAC, - // cookies are stored in the original CookD destination. Cause running the - // browser in administrator mode is unsafe and discouraged, we just care - // about the UAC state. - if (!this.__cookiesFolder) { - let cookiesFolder = Services.dirsvc.get("CookD", Ci.nsIFile); - if (cookiesFolder.exists() && cookiesFolder.isReadable()) { - // Check if UAC is enabled. - if (Services.appinfo.QueryInterface(Ci.nsIWinAppHelper).userCanElevate) { - cookiesFolder.append("Low"); - } - this.__cookiesFolder = cookiesFolder; - } - } - return this.__cookiesFolder; - }, - - migrate: function C_migrate(aCallback) { - CtypesHelpers.initialize(); - - let cookiesGenerator = (function genCookie() { - let success = false; - let entries = this._cookiesFolder.directoryEntries; - while (entries.hasMoreElements()) { - let entry = entries.getNext().QueryInterface(Ci.nsIFile); - // Skip eventual bogus entries. - if (!entry.isFile() || !/\.txt$/.test(entry.leafName)) - continue; - - this._readCookieFile(entry, function(aSuccess) { - // Importing even a single cookie file is considered a success. - if (aSuccess) - success = true; - try { - cookiesGenerator.next(); - } catch (ex) {} - }); - - yield; - } - - CtypesHelpers.finalize(); - - aCallback(success); - }).apply(this); - cookiesGenerator.next(); - }, - - _readCookieFile: function C__readCookieFile(aFile, aCallback) { - let fileReader = Cc["@mozilla.org/files/filereader;1"]. - createInstance(Ci.nsIDOMFileReader); - fileReader.addEventListener("loadend", (function onLoadEnd() { - fileReader.removeEventListener("loadend", onLoadEnd, false); - - if (fileReader.readyState != fileReader.DONE) { - Cu.reportError("Could not read cookie contents: " + fileReader.error); - aCallback(false); - return; - } - - let success = true; - try { - this._parseCookieBuffer(fileReader.result); - } catch (ex) { - Components.utils.reportError("Unable to migrate cookie: " + ex); - success = false; - } finally { - aCallback(success); - } - }).bind(this), false); - fileReader.readAsText(new File(aFile)); - }, - - /** - * Parses a cookie file buffer and returns an array of the contained cookies. - * - * The cookie file format is a newline-separated-values with a "*" used as - * delimeter between multiple records. - * Each cookie has the following fields: - * - name - * - value - * - host/path - * - flags - * - Expiration time most significant integer - * - Expiration time least significant integer - * - Creation time most significant integer - * - Creation time least significant integer - * - Record delimiter "*" - * - * @note All the times are in FILETIME format. - */ - _parseCookieBuffer: function C__parseCookieBuffer(aTextBuffer) { - // Note the last record is an empty string. - let records = [r for each (r in aTextBuffer.split("*\n")) if (r)]; - for (let record of records) { - let [name, value, hostpath, flags, - expireTimeLo, expireTimeHi] = record.split("\n"); - - // IE stores deleted cookies with a zero-length value, skip them. - if (value.length == 0) - continue; - - let hostLen = hostpath.indexOf("/"); - let host = hostpath.substr(0, hostLen); - let path = hostpath.substr(hostLen); - - // For a non-null domain, assume it's what Mozilla considers - // a domain cookie. See bug 222343. - if (host.length > 0) { - // Fist delete any possible extant matching host cookie. - Services.cookies.remove(host, name, path, false); - // Now make it a domain cookie. - if (host[0] != "." && !hostIsIPAddress(host)) - host = "." + host; - } - - let expireTime = CtypesHelpers.fileTimeToDate(Number(expireTimeHi), - Number(expireTimeLo)); - Services.cookies.add(host, - path, - name, - value, - Number(flags) & 0x1, // secure - false, // httpOnly - false, // session - expireTime); - } - } -}; - - -//////////////////////////////////////////////////////////////////////////////// -//// Migrator - -function IEProfileMigrator() -{ -} - -IEProfileMigrator.prototype = Object.create(MigratorPrototype); - -IEProfileMigrator.prototype.getResources = function IE_getResources() { - let resources = [ - new Bookmarks() - , new History() - , new Cookies() - ]; - return [r for each (r in resources) if (r.exists)]; -}; - -Object.defineProperty(IEProfileMigrator.prototype, "sourceHomePageURL", { - get: function IE_get_sourceHomePageURL() { - let defaultStartPage = WindowsRegistry.readRegKey(Ci.nsIWindowsRegKey.ROOT_KEY_LOCAL_MACHINE, - kMainKey, "Default_Page_URL"); - let startPage = WindowsRegistry.readRegKey(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER, - kMainKey, "Start Page"); - // If the user didn't customize the Start Page, he is still on the default - // page, that may be considered the equivalent of our about:home. There's - // no reason to retain it, since it is heavily targeted to IE. - let homepage = startPage != defaultStartPage ? startPage : ""; - - // IE7+ supports secondary home pages located in a REG_MULTI_SZ key. These - // are in addition to the Start Page, and no empty entries are possible, - // thus a Start Page is always defined if any of these exists, though it - // may be the default one. - let secondaryPages = WindowsRegistry.readRegKey(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER, - kMainKey, "Secondary Start Pages"); - if (secondaryPages) { - if (homepage) - secondaryPages.unshift(homepage); - homepage = secondaryPages.join("|"); - } - - return homepage; - } -}); - -IEProfileMigrator.prototype.classDescription = "IE Profile Migrator"; -IEProfileMigrator.prototype.contractID = "@mozilla.org/profile/migrator;1?app=browser&type=ie"; -IEProfileMigrator.prototype.classID = Components.ID("{3d2532e3-4932-4774-b7ba-968f5899d3a4}"); - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([IEProfileMigrator]); diff --git a/application/palemoon/components/migration/MigrationUtils.jsm b/application/palemoon/components/migration/MigrationUtils.jsm deleted file mode 100644 index fcd73a798..000000000 --- a/application/palemoon/components/migration/MigrationUtils.jsm +++ /dev/null @@ -1,644 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -this.EXPORTED_SYMBOLS = ["MigrationUtils", "MigratorPrototype"]; - -const Cu = Components.utils; -const Ci = Components.interfaces; -const Cc = Components.classes; - -const TOPIC_WILL_IMPORT_BOOKMARKS = "initial-migration-will-import-default-bookmarks"; -const TOPIC_DID_IMPORT_BOOKMARKS = "initial-migration-did-import-default-bookmarks"; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "Dict", - "resource://gre/modules/Dict.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils", - "resource://gre/modules/PlacesUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "NetUtil", - "resource://gre/modules/NetUtil.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "BookmarkHTMLUtils", - "resource://gre/modules/BookmarkHTMLUtils.jsm"); - -let gMigrators = null; -let gProfileStartup = null; -let gMigrationBundle = null; - -function getMigrationBundle() { - if (!gMigrationBundle) { - gMigrationBundle = Services.strings.createBundle( - "chrome://browser/locale/migration/migration.properties"); - } - return gMigrationBundle; -} - -/** - * Figure out what is the default browser, and if there is a migrator - * for it, return that migrator's internal name. - * For the time being, the "internal name" of a migraotr is its contract-id - * trailer (e.g. ie for @mozilla.org/profile/migrator;1?app=browser&type=ie), - * but it will soon be exposed properly. - */ -function getMigratorKeyForDefaultBrowser() { - const APP_DESC_TO_KEY = { - "Internet Explorer": "ie", - "Safari": "safari", - "Pale Moon web browser": "firefox", - "Google Chrome": "chrome", // Windows, Linux - "Chrome": "chrome", // OS X - }; - - let browserDesc = ""; - try { - let browserDesc = - Cc["@mozilla.org/uriloader/external-protocol-service;1"]. - getService(Ci.nsIExternalProtocolService). - getApplicationDescription("http"); - return APP_DESC_TO_KEY[browserDesc] || ""; - } - catch(ex) { - Cu.reportError("Could not detect default browser: " + ex); - } - return ""; -} - -/** - * Shared prototype for migrators, implementing nsIBrowserProfileMigrator. - * - * To implement a migrator: - * 1. Import this module. - * 2. Create the prototype for the migrator, extending MigratorPrototype. - * Namely: MosaicMigrator.prototype = Object.create(MigratorPrototype); - * 3. Set classDescription, contractID and classID for your migrator, and set - * NSGetFactory appropriately. - * 4. If the migrator supports multiple profiles, override the sourceProfiles - * Here we default for single-profile migrator. - * 5. Implement getResources(aProfile) (see below). - * 6. If the migrator supports reading the home page of the source browser, - * override |sourceHomePageURL| getter. - * 7. For startup-only migrators, override |startupOnlyMigrator|. - */ -this.MigratorPrototype = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIBrowserProfileMigrator]), - - /** - * OVERRIDE IF AND ONLY IF the source supports multiple profiles. - * - * Returns array of profile objects from which data may be imported. The object - * should have the following keys: - * id - a unique string identifier for the profile - * name - a pretty name to display to the user in the UI - * - * Only profiles from which data can be imported should be listed. Otherwise - * the behavior of the migration wizard isn't well-defined. - * - * For a single-profile source (e.g. safari, ie), this returns null, - * and not an empty array. That is the default implementation. - */ - get sourceProfiles() null, - - /** - * MUST BE OVERRIDDEN. - * - * Returns an array of "migration resources" objects for the given profile, - * or for the "default" profile, if the migrator does not support multiple - * profiles. - * - * Each migration resource should provide: - * - a |type| getter, retunring any of the migration types (see - * nsIBrowserProfileMigrator). - * - * - a |migrate| method, taking a single argument, aCallback(bool success), - * for migrating the data for this resource. It may do its job - * synchronously or asynchronously. Either way, it must call - * aCallback(bool aSuccess) when it's done. In the case of an exception - * thrown from |migrate|, it's taken as if aCallback(false) is called. - * - * Note: In the case of a simple asynchronous implementation, you may find - * MigrationUtils.wrapMigrateFunction handy for handling aCallback easily. - * - * For each migration type listed in nsIBrowserProfileMigrator, multiple - * migration resources may be provided. This practice is useful when the - * data for a certain migration type is independently stored in few - * locations. For example, the mac version of Safari stores its "reading list" - * bookmarks in a separate property list. - * - * Note that the importation of a particular migration type is reported as - * successful if _any_ of its resources succeeded to import (that is, called, - * |aCallback(true)|). However, completion-status for a particular migration - * type is reported to the UI only once all of its migrators have called - * aCallback. - * - * @note The returned array should only include resources from which data - * can be imported. So, for example, before adding a resource for the - * BOOKMARKS migration type, you should check if you should check that the - * bookmarks file exists. - * - * @param aProfile - * The profile from which data may be imported, or an empty string - * in the case of a single-profile migrator. - * In the case of multiple-profiles migrator, it is guaranteed that - * aProfile is a value returned by the sourceProfiles getter (see - * above). - */ - getResources: function MP_getResources(aProfile) { - throw new Error("getResources must be overridden"); - }, - - /** - * OVERRIDE IF AND ONLY IF the migrator is a startup-only migrator (For now, - * that is just the Firefox migrator, see bug 737381). Default: false. - * - * Startup-only migrators are different in two ways: - * - they may only be used during startup. - * - the user-profile is half baked during migration. The folder exists, - * but it's only accessible through MigrationUtils.profileStartup. - * The migrator can call MigrationUtils.profileStartup.doStartup - * at any point in order to initialize the profile. - */ - get startupOnlyMigrator() false, - - /** - * OVERRIDE IF AND ONLY IF your migrator supports importing the homepage. - * @see nsIBrowserProfileMigrator - */ - get sourceHomePageURL() "", - - /** - * DO NOT OVERRIDE - After deCOMing migration, the UI will just call - * getResources. - * - * @see nsIBrowserProfileMigrator - */ - getMigrateData: function MP_getMigrateData(aProfile) { - let types = [r.type for each (r in this._getMaybeCachedResources(aProfile))]; - return types.reduce(function(a, b) a |= b, 0); - }, - - /** - * DO NOT OVERRIDE - After deCOMing migration, the UI will just call - * migrate for each resource. - * - * @see nsIBrowserProfileMigrator - */ - migrate: function MP_migrate(aItems, aStartup, aProfile) { - let resources = this._getMaybeCachedResources(aProfile); - if (resources.length == 0) - throw new Error("migrate called for a non-existent source"); - - if (aItems != Ci.nsIBrowserProfileMigrator.ALL) - resources = [r for each (r in resources) if (aItems & r.type)]; - - // Called either directly or through the bookmarks import callback. - function doMigrate() { - // TODO: use Map (for the items) and Set (for the resources) - // once they are iterable. - let resourcesGroupedByItems = new Dict(); - resources.forEach(function(resource) { - if (resourcesGroupedByItems.has(resource.type)) - resourcesGroupedByItems.get(resource.type).push(resource); - else - resourcesGroupedByItems.set(resource.type, [resource]); - }); - - if (resourcesGroupedByItems.count == 0) - throw new Error("No items to import"); - - let notify = function(aMsg, aItemType) { - Services.obs.notifyObservers(null, aMsg, aItemType); - } - - notify("Migration:Started"); - resourcesGroupedByItems.listkeys().forEach(function(migrationType) { - let migrationTypeA = migrationType; - let itemResources = resourcesGroupedByItems.get(migrationType); - notify("Migration:ItemBeforeMigrate", migrationType); - - let itemSuccess = false; - itemResources.forEach(function(resource) { - let resourceDone = function(aSuccess) { - let resourceIndex = itemResources.indexOf(resource); - if (resourceIndex != -1) { - itemResources.splice(resourceIndex, 1); - itemSuccess |= aSuccess; - if (itemResources.length == 0) { - resourcesGroupedByItems.del(migrationType); - notify(itemSuccess ? - "Migration:ItemAfterMigrate" : "Migration:ItemError", - migrationType); - if (resourcesGroupedByItems.count == 0) - notify("Migration:Ended"); - } - } - }; - - Services.tm.mainThread.dispatch(function() { - // If migrate throws, an error occurred, and the callback - // (itemMayBeDone) might haven't been called. - try { - resource.migrate(resourceDone); - } - catch(ex) { - Cu.reportError(ex); - resourceDone(false); - } - }, Ci.nsIThread.DISPATCH_NORMAL); - }); - }); - } - - if (MigrationUtils.isStartupMigration && !this.startupOnlyMigrator) { - MigrationUtils.profileStartup.doStartup(); - - // If we're about to migrate bookmarks, first import the default bookmarks. - // Note We do not need to do so for the Firefox migrator - // (=startupOnlyMigrator), as it just copies over the places database - // from another profile. - const BOOKMARKS = MigrationUtils.resourceTypes.BOOKMARKS; - let migratingBookmarks = resources.some(function(r) r.type == BOOKMARKS); - if (migratingBookmarks) { - let browserGlue = Cc["@mozilla.org/browser/browserglue;1"]. - getService(Ci.nsIObserver); - browserGlue.observe(null, TOPIC_WILL_IMPORT_BOOKMARKS, ""); - - // Note doMigrate doesn't care about the success of the import. - let onImportComplete = function() { - browserGlue.observe(null, TOPIC_DID_IMPORT_BOOKMARKS, ""); - doMigrate(); - }; - BookmarkHTMLUtils.importFromURL( - "resource:///defaults/profile/bookmarks.html", true).then( - onImportComplete, onImportComplete); - return; - } - } - doMigrate(); - }, - - /** - * DO NOT OVERRIDE - After deCOMing migration, this code - * won't be part of the migrator itself. - * - * @see nsIBrowserProfileMigrator - */ - get sourceExists() { - if (this.startupOnlyMigrator && !MigrationUtils.isStartupMigration) - return false; - - // For a single-profile source, check if any data is available. - // For multiple-profiles source, make sure that at least one - // profile is available. - let exists = false; - try { - let profiles = this.sourceProfiles; - if (!profiles) { - let resources = this._getMaybeCachedResources(""); - if (resources && resources.length > 0) - exists = true; - } - else { - exists = profiles.length > 0; - } - } - catch(ex) { - Cu.reportError(ex); - } - return exists; - }, - - /*** PRIVATE STUFF - DO NOT OVERRIDE ***/ - _getMaybeCachedResources: function PMB__getMaybeCachedResources(aProfile) { - let profileKey = aProfile ? aProfile.id : ""; - if (this._resourcesByProfile) { - if (profileKey in this._resourcesByProfile) - return this._resourcesByProfile[profileKey]; - } - else { - this._resourcesByProfile = { }; - } - return this._resourcesByProfile[profileKey] = this.getResources(aProfile); - } -}; - -this.MigrationUtils = Object.freeze({ - resourceTypes: { - SETTINGS: Ci.nsIBrowserProfileMigrator.SETTINGS, - COOKIES: Ci.nsIBrowserProfileMigrator.COOKIES, - HISTORY: Ci.nsIBrowserProfileMigrator.HISTORY, - FORMDATA: Ci.nsIBrowserProfileMigrator.FORMDATA, - PASSWORDS: Ci.nsIBrowserProfileMigrator.PASSWORDS, - BOOKMARKS: Ci.nsIBrowserProfileMigrator.BOOKMARKS, - OTHERDATA: Ci.nsIBrowserProfileMigrator.OTHERDATA - }, - - /** - * Helper for implementing simple asynchronous cases of migration resources' - * |migrate(aCallback)| (see MigratorPrototype). If your |migrate| method - * just waits for some file to be read, for example, and then migrates - * everything right away, you can wrap the async-function with this helper - * and not worry about notifying the callback. - * - * For example, instead of writing: - * setTimeout(function() { - * try { - * .... - * aCallback(true); - * } - * catch() { - * aCallback(false); - * } - * }, 0); - * - * You may write: - * setTimeout(MigrationUtils.wrapMigrateFunction(function() { - * if (importingFromMosaic) - * throw Cr.NS_ERROR_UNEXPECTED; - * }, aCallback), 0); - * - * ... and aCallback will be called with aSuccess=false when importing - * from Mosaic, or with aSuccess=true otherwise. - * - * @param aFunction - * the function that will be called sometime later. If aFunction - * throws when it's called, aCallback(false) is called, otherwise - * aCallback(true) is called. - * @param aCallback - * the callback function passed to |migrate|. - * @return the wrapped function. - */ - wrapMigrateFunction: function MU_wrapMigrateFunction(aFunction, aCallback) { - return function() { - let success = false; - try { - aFunction.apply(null, arguments); - success = true; - } - catch(ex) { - Cu.reportError(ex); - } - // Do not change this to call aCallback directly in try try & catch - // blocks, because if aCallback throws, we may end up calling aCallback - // twice. - aCallback(success); - } - }, - - /** - * Gets a string from the migration bundle. Shorthand for - * nsIStringBundle.GetStringFromName, if aReplacements isn't passed, or for - * nsIStringBundle.formatStringFromName if it is. - * - * This method also takes care of "bumped" keys (See bug 737381 comment 8 for - * details). - * - * @param aKey - * The key of the string to retrieve. - * @param aReplacemts - * [optioanl] Array of replacements to run on the retrieved string. - * @return the retrieved string. - * - * @see nsIStringBundle - */ - getLocalizedString: function MU_getLocalizedString(aKey, aReplacements) { - const OVERRIDES = { - "4_firefox": "4_firefox_history_and_bookmarks", - "64_firefox": "64_firefox_other" - }; - aKey = OVERRIDES[aKey] || aKey; - - if (aReplacements === undefined) - return getMigrationBundle().GetStringFromName(aKey); - return getMigrationBundle().formatStringFromName( - aKey, aReplacements, aReplacements.length); - }, - - /** - * Helper for creating a folder for imported bookmarks from a particular - * migration source. The folder is created at the end of the given folder. - * - * @param aSourceNameStr - * the source name (first letter capitalized). This is used - * for reading the localized source name from the migration - * bundle (e.g. if aSourceNameStr is Mosaic, this will try to read - * sourceNameMosaic from the migration bundle). - * @param aParentId - * the item-id of the folder in which the new folder should be - * created. - * @return the item-id of the new folder. - */ - createImportedBookmarksFolder: - function MU_createImportedBookmarksFolder(aSourceNameStr, aParentId) { - let source = this.getLocalizedString("sourceName" + aSourceNameStr); - let label = this.getLocalizedString("importedBookmarksFolder", [source]); - return PlacesUtils.bookmarks.createFolder( - aParentId, label, PlacesUtils.bookmarks.DEFAULT_INDEX); - }, - - get _migrators() gMigrators ? gMigrators : gMigrators = new Dict(), - - /* - * Returns the migrator for the given source, if any data is available - * for this source, or null otherwise. - * - * @param aKey internal name of the migration source. - * Supported values: ie (windows), - * safari (mac/windows), - * chrome (mac/windows/linux), - * firefox. - * - * If null is returned, either no data can be imported - * for the given migrator, or aMigratorKey is invalid (e.g. ie on mac, - * or mosaic everywhere). This method should be used rather than direct - * getService for future compatibility (see bug 718280). - * - * @return profile migrator implementing nsIBrowserProfileMigrator, if it can - * import any data, null otherwise. - */ - getMigrator: function MU_getMigrator(aKey) { - let migrator = null; - if (this._migrators.has(aKey)) { - migrator = this._migrators.get(aKey); - } - else { - try { - migrator = Cc["@mozilla.org/profile/migrator;1?app=browser&type=" + - aKey].createInstance(Ci.nsIBrowserProfileMigrator); - } - catch(ex) { } - this._migrators.set(aKey, migrator); - } - - return migrator && migrator.sourceExists ? migrator : null; - }, - - // Iterates the available migrators, in the most suitable - // order for the running platform. - get migrators() { - let migratorKeysOrdered = [ -#ifdef XP_WIN - "firefox", "ie", "chrome", "safari" -#elifdef XP_MACOSX - "firefox", "safari", "chrome" -#elifdef XP_UNIX - "firefox", "chrome" -#endif - ]; - - // If a supported default browser is found check it first - // so that the wizard defaults to import from that browser. - let defaultBrowserKey = getMigratorKeyForDefaultBrowser(); - if (defaultBrowserKey) - migratorKeysOrdered.sort(function (a, b) b == defaultBrowserKey ? 1 : 0); - - for (let migratorKey of migratorKeysOrdered) { - let migrator = this.getMigrator(migratorKey); - if (migrator) - yield migrator; - } - }, - - // Whether or not we're in the process of startup migration - get isStartupMigration() gProfileStartup != null, - - /** - * In the case of startup migration, this is set to the nsIProfileStartup - * instance passed to ProfileMigrator's migrate. - * - * @see showMigrationWizard - */ - get profileStartup() gProfileStartup, - - /** - * Show the migration wizard. On mac, this may just focus the wizard if it's - * already running, in which case aOpener and aParams are ignored. - * - * @param [optional] aOpener - * the window that asks to open the wizard. - * @param [optional] aParams - * arguments for the migration wizard, in the form of an nsIArray. - * This is passed as-is for the params argument of - * nsIWindowWatcher.openWindow. - */ - showMigrationWizard: - function MU_showMigrationWizard(aOpener, aParams) { - let features = "chrome,dialog,modal,centerscreen,titlebar,resizable=no"; -#ifdef XP_MACOSX - if (!this.isStartupMigration) { - let win = Services.wm.getMostRecentWindow("Browser:MigrationWizard"); - if (win) { - win.focus(); - return; - } - // On mac, the migration wiazrd should only be modal in the case of - // startup-migration. - features = "centerscreen,chrome,resizable=no"; - } -#endif - - Services.ww.openWindow(aOpener, - "chrome://browser/content/migration/migration.xul", - "_blank", - features, - aParams); - }, - - /** - * Show the migration wizard for startup-migration. This should only be - * called by ProfileMigrator (see ProfileMigrator.js), which implements - * nsIProfileMigrator. - * - * @param aProfileStartup - * the nsIProfileStartup instance provided to ProfileMigrator.migrate. - * @param [optional] aMigratorKey - * If set, the migration wizard will import from the corresponding - * migrator, bypassing the source-selection page. Otherwise, the - * source-selection page will be displayed, either with the default - * browser selected, if it could be detected and if there is a - * migrator for it, or with the first option selected as a fallback - * (The first option is hardcoded to be the most common browser for - * the OS we run on. See migration.xul). - * @param [optional] aProfileToMigrate - * If set, the migration wizard will import from the profile indicated. - * - * @throws if aMigratorKey is invalid or if it points to a non-existent - * source. - */ - startupMigration: - function MU_startupMigrator(aProfileStartup, aMigratorKey, aProfileToMigrate) { - if (!aProfileStartup) { - throw new Error("a profile-startup instance is required for startup-migration"); - } - gProfileStartup = aProfileStartup; - - let skipSourcePage = false, migrator = null, migratorKey = ""; - if (aMigratorKey) { - migrator = this.getMigrator(aMigratorKey); - if (!migrator) { - // aMigratorKey must point to a valid source, so, if it doesn't - // cleanup and throw. - this.finishMigration(); - throw new Error("startMigration was asked to open auto-migrate from " + - "a non-existent source: " + aMigratorKey); - } - migratorKey = aMigratorKey; - skipSourcePage = true; - } - else { - let defaultBrowserKey = getMigratorKeyForDefaultBrowser(); - if (defaultBrowserKey) { - migrator = this.getMigrator(defaultBrowserKey); - if (migrator) - migratorKey = defaultBrowserKey; - } - } - - if (!migrator) { - // If there's no migrator set so far, ensure that there is at least one - // migrator available before opening the wizard. - try { - this.migrators.next(); - } - catch(ex) { - this.finishMigration(); - if (!(ex instanceof StopIteration)) - throw ex; - return; - } - } - - let params = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray); - let keyCSTR = Cc["@mozilla.org/supports-cstring;1"]. - createInstance(Ci.nsISupportsCString); - keyCSTR.data = migratorKey; - let skipImportSourcePageBool = Cc["@mozilla.org/supports-PRBool;1"]. - createInstance(Ci.nsISupportsPRBool); - skipImportSourcePageBool.data = skipSourcePage; - let profileToMigrate = null; - if (aProfileToMigrate) { - profileToMigrate = Cc["@mozilla.org/supports-string;1"]. - createInstance(Ci.nsISupportsString); - profileToMigrate.data = aProfileToMigrate; - } - params.appendElement(keyCSTR, false); - params.appendElement(migrator, false); - params.appendElement(aProfileStartup, false); - params.appendElement(skipImportSourcePageBool, false); - params.appendElement(profileToMigrate, false); - - this.showMigrationWizard(null, params); - }, - - /** - * Cleans up references to migrators and nsIProfileInstance instances. - */ - finishMigration: function MU_finishMigration() { - gMigrators = null; - gProfileStartup = null; - gMigrationBundle = null; - } -}); diff --git a/application/palemoon/components/migration/ProfileMigrator.js b/application/palemoon/components/migration/ProfileMigrator.js deleted file mode 100644 index f67823bae..000000000 --- a/application/palemoon/components/migration/ProfileMigrator.js +++ /dev/null @@ -1,21 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); -Components.utils.import("resource:///modules/MigrationUtils.jsm"); - -function ProfileMigrator() { -} - -ProfileMigrator.prototype = { - migrate: MigrationUtils.startupMigration.bind(MigrationUtils), - QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsIProfileMigrator]), - classDescription: "Profile Migrator", - contractID: "@mozilla.org/toolkit/profile-migrator;1", - classID: Components.ID("6F8BB968-C14F-4D6F-9733-6C6737B35DCE") -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ProfileMigrator]); diff --git a/application/palemoon/components/migration/SafariProfileMigrator.js b/application/palemoon/components/migration/SafariProfileMigrator.js deleted file mode 100644 index 70804793d..000000000 --- a/application/palemoon/components/migration/SafariProfileMigrator.js +++ /dev/null @@ -1,416 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -let Cc = Components.classes; -let Ci = Components.interfaces; -let Cu = Components.utils; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/FileUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource:///modules/MigrationUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "PropertyListUtils", - "resource://gre/modules/PropertyListUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils", - "resource://gre/modules/PlacesUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "NetUtil", - "resource://gre/modules/NetUtil.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "FormHistory", - "resource://gre/modules/FormHistory.jsm"); - -function Bookmarks(aBookmarksFile) { - this._file = aBookmarksFile; -} -Bookmarks.prototype = { - type: MigrationUtils.resourceTypes.BOOKMARKS, - - migrate: function B_migrate(aCallback) { - PropertyListUtils.read(this._file, - MigrationUtils.wrapMigrateFunction(function migrateBookmarks(aDict) { - if (!aDict) - throw new Error("Could not read Bookmarks.plist"); - - let children = aDict.get("Children");; - if (!children) - throw new Error("Invalid Bookmarks.plist format"); - - PlacesUtils.bookmarks.runInBatchMode({ - runBatched: function() { - let collection = aDict.get("Title") == "com.apple.ReadingList" ? - this.READING_LIST_COLLECTION : this.ROOT_COLLECTION; - this._migrateCollection(children, collection); - }.bind(this) - }, null); - }.bind(this), aCallback)); - }, - - // Bookmarks collections in Safari. Constants for migrateCollection. - ROOT_COLLECTION: 0, - MENU_COLLECTION: 1, - TOOLBAR_COLLECTION: 2, - READING_LIST_COLLECTION: 3, - - /** - * Recursively migrate a Safari collection of bookmarks. - * - * @param aEntries - * the collection's children - * @param aCollection - * one of the values above. - */ - _migrateCollection: function B__migrateCollection(aEntries, aCollection) { - // A collection of bookmarks in Safari resembles places roots. In the - // property list files (Bookmarks.plist, ReadingList.plist) they are - // stored as regular bookmarks folders, and thus can only be distinguished - // from by their names and places in the hierarchy. - - let entriesFiltered = []; - if (aCollection == this.ROOT_COLLECTION) { - for (let entry of aEntries) { - let type = entry.get("WebBookmarkType"); - if (type == "WebBookmarkTypeList" && entry.has("Children")) { - let title = entry.get("Title"); - let children = entry.get("Children"); - if (title == "BookmarksBar") - this._migrateCollection(children, this.TOOLBAR_COLLECTION); - else if (title == "BookmarksMenu") - this._migrateCollection(children, this.MENU_COLLECTION); - else if (title == "com.apple.ReadingList") - this._migrateCollection(children, this.READING_LIST_COLLECTION); - else if (entry.get("ShouldOmitFromUI") !== true) - entriesFiltered.push(entry); - } - else if (type == "WebBookmarkTypeLeaf") { - entriesFiltered.push(entry); - } - } - } - else { - entriesFiltered = aEntries; - } - - if (entriesFiltered.length == 0) - return; - - let folder = -1; - switch (aCollection) { - case this.ROOT_COLLECTION: { - // In Safari, it is possible (though quite cumbersome) to move - // bookmarks to the bookmarks root, which is the parent folder of - // all bookmarks "collections". That is somewhat in parallel with - // both the places root and the unfiled-bookmarks root. - // Because the former is only an implementation detail in our UI, - // the unfiled root seems to be the best choice. - folder = PlacesUtils.unfiledBookmarksFolderId; - break; - } - case this.MENU_COLLECTION: { - folder = PlacesUtils.bookmarksMenuFolderId; - if (!MigrationUtils.isStartupMigration) { - folder = MigrationUtils.createImportedBookmarksFolder("Safari", - folder); - } - break; - } - case this.TOOLBAR_COLLECTION: { - folder = PlacesUtils.toolbarFolderId; - if (!MigrationUtils.isStartupMigration) { - folder = MigrationUtils.createImportedBookmarksFolder("Safari", - folder); - } - 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). - folder = PlacesUtils.bookmarks.createFolder( - PlacesUtils.bookmarksMenuFolderId, - MigrationUtils.getLocalizedString("importedSafariReadingList"), - PlacesUtils.bookmarks.DEFAULT_INDEX); - break; - } - default: - throw new Error("Unexpected value for aCollection!"); - } - - this._migrateEntries(entriesFiltered, folder); - }, - - // migrate the given array of safari bookmarks to the given places - // folder. - _migrateEntries: function B__migrateEntries(aEntries, aFolderId) { - for (let entry of aEntries) { - let type = entry.get("WebBookmarkType"); - if (type == "WebBookmarkTypeList" && entry.has("Children")) { - let title = entry.get("Title"); - let folderId = PlacesUtils.bookmarks.createFolder( - aFolderId, title, PlacesUtils.bookmarks.DEFAULT_INDEX); - - // Empty folders may not have a children array. - if (entry.has("Children")) - this._migrateEntries(entry.get("Children"), folderId, false); - } - else if (type == "WebBookmarkTypeLeaf" && entry.has("URLString")) { - let title, uri; - if (entry.has("URIDictionary")) - title = entry.get("URIDictionary").get("title"); - - try { - uri = NetUtil.newURI(entry.get("URLString")); - } - catch(ex) { - Cu.reportError("Invalid uri set for Safari bookmark: " + entry.get("URLString")); - } - if (uri) { - PlacesUtils.bookmarks.insertBookmark(aFolderId, uri, - PlacesUtils.bookmarks.DEFAULT_INDEX, title); - } - } - } - } -}; - -function History(aHistoryFile) { - this._file = aHistoryFile; -} -History.prototype = { - type: MigrationUtils.resourceTypes.HISTORY, - - // Helper method for converting the visit date property to a PRTime value. - // The visit date is stored as a string, so it's not read as a Date - // object by PropertyListUtils. - _parseCocoaDate: function H___parseCocoaDate(aCocoaDateStr) { - let asDouble = parseFloat(aCocoaDateStr); - if (!isNaN(asDouble)) { - // reference date of NSDate. - let date = new Date("1 January 2001, GMT"); - date.setMilliseconds(asDouble * 1000); - return date * 1000; - } - return 0; - }, - - migrate: function H_migrate(aCallback) { - PropertyListUtils.read(this._file, function migrateHistory(aDict) { - try { - if (!aDict) - throw new Error("Could not read history property list"); - if (!aDict.has("WebHistoryDates")) - throw new Error("Unexpected history-property list format"); - - // Safari's History file contains only top-level urls. It does not - // distinguish between typed urls and linked urls. - let transType = PlacesUtils.history.TRANSITION_LINK; - - let places = []; - let entries = aDict.get("WebHistoryDates"); - for (let entry of entries) { - if (entry.has("lastVisitedDate")) { - let visitDate = this._parseCocoaDate(entry.get("lastVisitedDate")); - places.push({ uri: NetUtil.newURI(entry.get("")), - title: entry.get("title"), - visits: [{ transitionType: transType, - visitDate: visitDate }] }); - } - } - if (places.length > 0) { - PlacesUtils.asyncHistory.updatePlaces(places, { - _success: false, - handleResult: function() { - // Importing any entry is considered a successful import. - this._success = true; - }, - handleError: function() {}, - handleCompletion: function() { - aCallback(this._success); - } - }); - } - else { - aCallback(false); - } - } - catch(ex) { - Cu.reportError(ex); - aCallback(false); - } - }.bind(this)); - } -}; - -/** - * Safari's preferences property list is independently used for three purposes: - * (a) importation of preferences - * (b) importation of search strings - * (c) retrieving the home page. - * - * So, rather than reading it three times, it's cached and managed here. - */ -function MainPreferencesPropertyList(aPreferencesFile) { - this._file = aPreferencesFile; - this._callbacks = []; -} -MainPreferencesPropertyList.prototype = { - /** - * @see PropertyListUtils.read - */ - read: function MPPL_read(aCallback) { - if ("_dict" in this) { - aCallback(this._dict); - return; - } - - let alreadyReading = this._callbacks.length > 0; - this._callbacks.push(aCallback); - if (!alreadyReading) { - PropertyListUtils.read(this._file, function readPrefs(aDict) { - this._dict = aDict; - for (let callback of this._callbacks) { - try { - callback(aDict); - } - catch(ex) { - Cu.reportError(ex); - } - } - this._callbacks.splice(0); - }.bind(this)); - } - }, - - // Workaround for nsIBrowserProfileMigrator.sourceHomePageURL until - // it's replaced with an async method. - _readSync: function MPPL__readSync() { - if ("_dict" in this) - return this._dict; - - let inputStream = Cc["@mozilla.org/network/file-input-stream;1"]. - createInstance(Ci.nsIFileInputStream); - inputStream.init(this._file, -1, -1, 0); - let binaryStream = Cc["@mozilla.org/binaryinputstream;1"]. - createInstance(Ci.nsIBinaryInputStream); - binaryStream.setInputStream(inputStream); - let bytes = binaryStream.readByteArray(inputStream.available()); - this._dict = PropertyListUtils._readFromArrayBufferSync( - Uint8Array(bytes).buffer); - return this._dict; - } -}; - -function SearchStrings(aMainPreferencesPropertyListInstance) { - this._mainPreferencesPropertyList = aMainPreferencesPropertyListInstance; -} -SearchStrings.prototype = { - type: MigrationUtils.resourceTypes.OTHERDATA, - - migrate: function SS_migrate(aCallback) { - this._mainPreferencesPropertyList.read(MigrationUtils.wrapMigrateFunction( - function migrateSearchStrings(aDict) { - if (!aDict) - throw new Error("Could not get preferences dictionary"); - - if (aDict.has("RecentSearchStrings")) { - let recentSearchStrings = aDict.get("RecentSearchStrings"); - if (recentSearchStrings && recentSearchStrings.length > 0) { - let changes = [{op: "add", - fieldname: "searchbar-history", - value: searchString} - for (searchString of recentSearchStrings)]; - FormHistory.update(changes); - } - } - }.bind(this), aCallback)); - } -}; - -function SafariProfileMigrator() { -} - -SafariProfileMigrator.prototype = Object.create(MigratorPrototype); - -SafariProfileMigrator.prototype.getResources = function SM_getResources() { - let profileDir = -#ifdef XP_MACOSX - FileUtils.getDir("ULibDir", ["Safari"], false); -#else - FileUtils.getDir("AppData", ["Apple Computer", "Safari"], false); -#endif - if (!profileDir.exists()) - return null; - - let resources = []; - let pushProfileFileResource = function(aFileName, aConstructor) { - let file = profileDir.clone(); - file.append(aFileName); - if (file.exists()) - resources.push(new aConstructor(file)); - }; - - pushProfileFileResource("History.plist", History); - pushProfileFileResource("Bookmarks.plist", Bookmarks); - - // The Reading List feature was introduced at the same time in Windows and - // Mac versions of Safari. Not surprisingly, they are stored in the same - // format in both versions. Surpsingly, only on Windows there is a - // separate property list for it. This isn't #ifdefed out on mac, because - // Apple may fix this at some point. - pushProfileFileResource("ReadingList.plist", Bookmarks); - - let prefsDir = -#ifdef XP_MACOSX - FileUtils.getDir("UsrPrfs", [], false); -#else - FileUtils.getDir("AppData", ["Apple Computer", "Preferences"], false); -#endif - - let prefs = this.mainPreferencesPropertyList; - if (prefs) { - resources.push(new SearchStrings(prefs)); - } - - return resources; -}; - -Object.defineProperty(SafariProfileMigrator.prototype, "mainPreferencesPropertyList", { - get: function get_mainPreferencesPropertyList() { - if (this._mainPreferencesPropertyList === undefined) { - let file = -#ifdef XP_MACOSX - FileUtils.getDir("UsrPrfs", [], false); -#else - FileUtils.getDir("AppData", ["Apple Computer", "Preferences"], false); -#endif - if (file.exists()) { - file.append("com.apple.Safari.plist"); - if (file.exists()) { - return this._mainPreferencesPropertyList = - new MainPreferencesPropertyList(file); - } - } - return this._mainPreferencesPropertyList = null; - } - return this._mainPreferencesPropertyList; - } -}); - -Object.defineProperty(SafariProfileMigrator.prototype, "sourceHomePageURL", { - get: function get_sourceHomePageURL() { - if (this.mainPreferencesPropertyList) { - let dict = this.mainPreferencesPropertyList._readSync(); - if (dict.has("HomePage")) - return dict.get("HomePage"); - } - return ""; - } -}); - -SafariProfileMigrator.prototype.classDescription = "Safari Profile Migrator"; -SafariProfileMigrator.prototype.contractID = "@mozilla.org/profile/migrator;1?app=browser&type=safari"; -SafariProfileMigrator.prototype.classID = Components.ID("{4b609ecf-60b2-4655-9df4-dc149e474da1}"); - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SafariProfileMigrator]); diff --git a/application/palemoon/components/migration/content/migration.js b/application/palemoon/components/migration/content/migration.js deleted file mode 100644 index 512197b8b..000000000 --- a/application/palemoon/components/migration/content/migration.js +++ /dev/null @@ -1,474 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cu = Components.utils; - -const kIMig = Ci.nsIBrowserProfileMigrator; -const kIPStartup = Ci.nsIProfileStartup; - -Cu.import("resource:///modules/MigrationUtils.jsm"); - -var MigrationWizard = { - _source: "", // Source Profile Migrator ContractID suffix - _itemsFlags: kIMig.ALL, // Selected Import Data Sources (16-bit bitfield) - _selectedProfile: null, // Selected Profile name to import from - _wiz: null, - _migrator: null, - _autoMigrate: null, - - init: function () - { - var os = Components.classes["@mozilla.org/observer-service;1"] - .getService(Components.interfaces.nsIObserverService); - os.addObserver(this, "Migration:Started", false); - os.addObserver(this, "Migration:ItemBeforeMigrate", false); - os.addObserver(this, "Migration:ItemAfterMigrate", false); - os.addObserver(this, "Migration:ItemError", false); - os.addObserver(this, "Migration:Ended", false); - - this._wiz = document.documentElement; - - if ("arguments" in window && window.arguments.length > 1) { - this._source = window.arguments[0]; - this._migrator = window.arguments[1] instanceof kIMig ? - window.arguments[1] : null; - this._autoMigrate = window.arguments[2].QueryInterface(kIPStartup); - this._skipImportSourcePage = window.arguments[3]; - if (this._migrator && window.arguments[4]) { - let sourceProfiles = this._migrator.sourceProfiles; - this._selectedProfile = sourceProfiles.find(profile => profile.id == window.arguments[4]); - } - - if (this._autoMigrate) { - // Show the "nothing" option in the automigrate case to provide an - // easily identifiable way to avoid migration and create a new profile. - var nothing = document.getElementById("nothing"); - nothing.hidden = false; - } - } - - this.onImportSourcePageShow(); - }, - - uninit: function () - { - var os = Components.classes["@mozilla.org/observer-service;1"] - .getService(Components.interfaces.nsIObserverService); - os.removeObserver(this, "Migration:Started"); - os.removeObserver(this, "Migration:ItemBeforeMigrate"); - os.removeObserver(this, "Migration:ItemAfterMigrate"); - os.removeObserver(this, "Migration:ItemError"); - os.removeObserver(this, "Migration:Ended"); - MigrationUtils.finishMigration(); - }, - - // 1 - Import Source - onImportSourcePageShow: function () - { - this._wiz.canRewind = false; - - var selectedMigrator = null; - - // Figure out what source apps are are available to import from: - var group = document.getElementById("importSourceGroup"); - for (var i = 0; i < group.childNodes.length; ++i) { - var migratorKey = group.childNodes[i].id; - if (migratorKey != "nothing") { - var migrator = MigrationUtils.getMigrator(migratorKey); - if (migrator) { - // Save this as the first selectable item, if we don't already have - // one, or if it is the migrator that was passed to us. - if (!selectedMigrator || this._source == migratorKey) - selectedMigrator = group.childNodes[i]; - } else { - // Hide this option - group.childNodes[i].hidden = true; - } - } - } - - if (selectedMigrator) - group.selectedItem = selectedMigrator; - else { - // We didn't find a migrator, notify the user - document.getElementById("noSources").hidden = false; - - this._wiz.canAdvance = false; - - document.getElementById("importBookmarks").hidden = true; - document.getElementById("importAll").hidden = true; - } - - // Advance to the next page if the caller told us to. - if (this._migrator && this._skipImportSourcePage) { - this._wiz.advance(); - this._wiz.canRewind = false; - } - }, - - onImportSourcePageAdvanced: function () - { - var newSource = document.getElementById("importSourceGroup").selectedItem.id; - - if (newSource == "nothing") { - document.documentElement.cancel(); - return false; - } - - if (!this._migrator || (newSource != this._source)) { - // Create the migrator for the selected source. - this._migrator = MigrationUtils.getMigrator(newSource); - - this._itemsFlags = kIMig.ALL; - this._selectedProfile = null; - } - this._source = newSource; - - // check for more than one source profile - var sourceProfiles = this._migrator.sourceProfiles; - if (this._skipImportSourcePage) { - this._wiz.currentPage.next = "homePageImport"; - } - else if (sourceProfiles && sourceProfiles.length > 1) { - this._wiz.currentPage.next = "selectProfile"; - } - else { - if (this._autoMigrate) - this._wiz.currentPage.next = "homePageImport"; - else - this._wiz.currentPage.next = "importItems"; - - if (sourceProfiles && sourceProfiles.length == 1) - this._selectedProfile = sourceProfiles[0]; - else - this._selectedProfile = null; - } - }, - - // 2 - [Profile Selection] - onSelectProfilePageShow: function () - { - // Disabling this for now, since we ask about import sources in automigration - // too and don't want to disable the back button - // if (this._autoMigrate) - // document.documentElement.getButton("back").disabled = true; - - var profiles = document.getElementById("profiles"); - while (profiles.hasChildNodes()) - profiles.removeChild(profiles.firstChild); - - // Note that this block is still reached even if the user chose 'From File' - // and we canceled the dialog. When that happens, _migrator will be null. - if (this._migrator) { - var sourceProfiles = this._migrator.sourceProfiles; - - for (let profile of sourceProfiles) { - var item = document.createElement("radio"); - item.id = profile.id; - item.setAttribute("label", profile.name); - profiles.appendChild(item); - } - } - - profiles.selectedItem = this._selectedProfile ? document.getElementById(this._selectedProfile.id) : profiles.firstChild; - }, - - onSelectProfilePageRewound: function () - { - var profiles = document.getElementById("profiles"); - this._selectedProfile = this._migrator.sourceProfiles.find( - profile => profile.id == profiles.selectedItem.id - ) || null; - }, - - onSelectProfilePageAdvanced: function () - { - var profiles = document.getElementById("profiles"); - this._selectedProfile = this._migrator.sourceProfiles.find( - profile => profile.id == profiles.selectedItem.id - ) || null; - - // If we're automigrating or just doing bookmarks don't show the item selection page - if (this._autoMigrate) - this._wiz.currentPage.next = "homePageImport"; - }, - - // 3 - ImportItems - onImportItemsPageShow: function () - { - var dataSources = document.getElementById("dataSources"); - while (dataSources.hasChildNodes()) - dataSources.removeChild(dataSources.firstChild); - - var items = this._migrator.getMigrateData(this._selectedProfile, this._autoMigrate); - for (var i = 0; i < 16; ++i) { - var itemID = (items >> i) & 0x1 ? Math.pow(2, i) : 0; - if (itemID > 0) { - var checkbox = document.createElement("checkbox"); - checkbox.id = itemID; - checkbox.setAttribute("label", - MigrationUtils.getLocalizedString(itemID + "_" + this._source)); - dataSources.appendChild(checkbox); - if (!this._itemsFlags || this._itemsFlags & itemID) - checkbox.checked = true; - } - } - }, - - onImportItemsPageRewound: function () - { - this._wiz.canAdvance = true; - this.onImportItemsPageAdvanced(); - }, - - onImportItemsPageAdvanced: function () - { - var dataSources = document.getElementById("dataSources"); - this._itemsFlags = 0; - for (var i = 0; i < dataSources.childNodes.length; ++i) { - var checkbox = dataSources.childNodes[i]; - if (checkbox.localName == "checkbox" && checkbox.checked) - this._itemsFlags |= parseInt(checkbox.id); - } - }, - - onImportItemCommand: function (aEvent) - { - var items = document.getElementById("dataSources"); - var checkboxes = items.getElementsByTagName("checkbox"); - - var oneChecked = false; - for (var i = 0; i < checkboxes.length; ++i) { - if (checkboxes[i].checked) { - oneChecked = true; - break; - } - } - - this._wiz.canAdvance = oneChecked; - }, - - // 4 - Home Page Selection - onHomePageMigrationPageShow: function () - { - // only want this on the first run - if (!this._autoMigrate) { - this._wiz.advance(); - return; - } - - var brandBundle = document.getElementById("brandBundle"); - // These strings don't exist when not using official branding. If that's - // the case, just skip this page. - try { - var pageTitle = brandBundle.getString("homePageMigrationPageTitle"); - var pageDesc = brandBundle.getString("homePageMigrationDescription"); - var mainStr = brandBundle.getString("homePageSingleStartMain"); - } - catch (e) { - this._wiz.advance(); - return; - } - - document.getElementById("homePageImport").setAttribute("label", pageTitle); - document.getElementById("homePageImportDesc").setAttribute("value", pageDesc); - - this._wiz._adjustWizardHeader(); - - var singleStart = document.getElementById("homePageSingleStart"); - singleStart.setAttribute("label", mainStr); - singleStart.setAttribute("value", "DEFAULT"); - - var source = null; - switch (this._source) { - case "ie": - source = "sourceNameIE"; - break; - case "safari": - source = "sourceNameSafari"; - break; - case "chrome": - source = "sourceNameChrome"; - break; - case "firefox": - source = "sourceNameFirefox"; - break; - } - - // semi-wallpaper for crash when multiple profiles exist, since we haven't initialized mSourceProfile in places - this._migrator.getMigrateData(this._selectedProfile, this._autoMigrate); - - var oldHomePageURL = this._migrator.sourceHomePageURL; - - if (oldHomePageURL && source) { - var appName = MigrationUtils.getLocalizedString(source); - var oldHomePageLabel = - brandBundle.getFormattedString("homePageImport", [appName]); - var oldHomePage = document.getElementById("oldHomePage"); - oldHomePage.setAttribute("label", oldHomePageLabel); - oldHomePage.setAttribute("value", oldHomePageURL); - oldHomePage.removeAttribute("hidden"); - } - else { - // if we don't have at least two options, just advance - this._wiz.advance(); - } - }, - - onHomePageMigrationPageAdvanced: function () - { - // we might not have a selectedItem if we're in fallback mode - try { - var radioGroup = document.getElementById("homePageRadiogroup"); - - this._newHomePage = radioGroup.selectedItem.value; - } catch(ex) {} - }, - - // 5 - Migrating - onMigratingPageShow: function () - { - this._wiz.getButton("cancel").disabled = true; - this._wiz.canRewind = false; - this._wiz.canAdvance = false; - - // When automigrating, show all of the data that can be received from this source. - if (this._autoMigrate) - this._itemsFlags = this._migrator.getMigrateData(this._selectedProfile, this._autoMigrate); - - this._listItems("migratingItems"); - setTimeout(this.onMigratingMigrate, 0, this); - }, - - onMigratingMigrate: function (aOuter) - { - aOuter._migrator.migrate(aOuter._itemsFlags, aOuter._autoMigrate, aOuter._selectedProfile); - }, - - _listItems: function (aID) - { - var items = document.getElementById(aID); - while (items.hasChildNodes()) - items.removeChild(items.firstChild); - - var brandBundle = document.getElementById("brandBundle"); - var itemID; - for (var i = 0; i < 16; ++i) { - var itemID = (this._itemsFlags >> i) & 0x1 ? Math.pow(2, i) : 0; - if (itemID > 0) { - var label = document.createElement("label"); - label.id = itemID + "_migrated"; - try { - label.setAttribute("value", - MigrationUtils.getLocalizedString(itemID + "_" + this._source)); - items.appendChild(label); - } - catch (e) { - // if the block above throws, we've enumerated all the import data types we - // currently support and are now just wasting time, break. - break; - } - } - } - }, - - observe: function (aSubject, aTopic, aData) - { - switch (aTopic) { - case "Migration:Started": - break; - case "Migration:ItemBeforeMigrate": - var label = document.getElementById(aData + "_migrated"); - if (label) - label.setAttribute("style", "font-weight: bold"); - break; - case "Migration:ItemAfterMigrate": - var label = document.getElementById(aData + "_migrated"); - if (label) - label.removeAttribute("style"); - break; - case "Migration:Ended": - if (this._autoMigrate) { - if (this._newHomePage) { - try { - // set homepage properly - var prefSvc = Components.classes["@mozilla.org/preferences-service;1"] - .getService(Components.interfaces.nsIPrefService); - var prefBranch = prefSvc.getBranch(null); - - if (this._newHomePage == "DEFAULT") { - prefBranch.clearUserPref("browser.startup.homepage"); - } - else { - var str = Components.classes["@mozilla.org/supports-string;1"] - .createInstance(Components.interfaces.nsISupportsString); - str.data = this._newHomePage; - prefBranch.setComplexValue("browser.startup.homepage", - Components.interfaces.nsISupportsString, - str); - } - - var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"] - .getService(Components.interfaces.nsIProperties); - var prefFile = dirSvc.get("ProfDS", Components.interfaces.nsIFile); - prefFile.append("prefs.js"); - prefSvc.savePrefFile(prefFile); - } catch(ex) { - dump(ex); - } - } - - // We're done now. - this._wiz.canAdvance = true; - this._wiz.advance(); - - setTimeout(close, 5000); - } - else { - this._wiz.canAdvance = true; - var nextButton = this._wiz.getButton("next"); - nextButton.click(); - } - break; - case "Migration:ItemError": - var type = "undefined"; - switch (parseInt(aData)) { - case Ci.nsIBrowserProfileMigrator.SETTINGS: - type = "settings"; - break; - case Ci.nsIBrowserProfileMigrator.COOKIES: - type = "cookies"; - break; - case Ci.nsIBrowserProfileMigrator.HISTORY: - type = "history"; - break; - case Ci.nsIBrowserProfileMigrator.FORMDATA: - type = "form data"; - break; - case Ci.nsIBrowserProfileMigrator.PASSWORDS: - type = "passwords"; - break; - case Ci.nsIBrowserProfileMigrator.BOOKMARKS: - type = "bookmarks"; - break; - case Ci.nsIBrowserProfileMigrator.OTHERDATA: - type = "misc. data"; - break; - } - Cc["@mozilla.org/consoleservice;1"] - .getService(Ci.nsIConsoleService) - .logStringMessage("some " + type + " did not successfully migrate."); - break; - } - }, - - onDonePageShow: function () - { - this._wiz.getButton("cancel").disabled = true; - this._wiz.canRewind = false; - this._listItems("doneItems"); - } -}; diff --git a/application/palemoon/components/migration/content/migration.xul b/application/palemoon/components/migration/content/migration.xul deleted file mode 100644 index 2c8df7b3e..000000000 --- a/application/palemoon/components/migration/content/migration.xul +++ /dev/null @@ -1,96 +0,0 @@ -<?xml version="1.0"?> -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> - -<!DOCTYPE dialog SYSTEM "chrome://browser/locale/migration/migration.dtd" > - -<wizard id="migrationWizard" - xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - windowtype="Browser:MigrationWizard" - title="&migrationWizard.title;" - onload="MigrationWizard.init()" - onunload="MigrationWizard.uninit()" - style="width: 40em;" - buttons="accept,cancel" - branded="true"> - - <script type="application/javascript" src="chrome://browser/content/migration/migration.js"/> - - <stringbundle id="brandBundle" src="chrome://branding/locale/brand.properties"/> - - <wizardpage id="importSource" pageid="importSource" next="selectProfile" - label="&importSource.title;" - onpageadvanced="return MigrationWizard.onImportSourcePageAdvanced();"> - <description id="importAll" control="importSourceGroup">&importFrom.label;</description> - <description id="importBookmarks" control="importSourceGroup" hidden="true">&importFromBookmarks.label;</description> - - <radiogroup id="importSourceGroup" align="start"> - <radio id="firefox" label="&importFromFirefox.label;" accesskey="&importFromFirefox.accesskey;"/> -#ifdef XP_WIN - <radio id="ie" label="&importFromIE.label;" accesskey="&importFromIE.accesskey;"/> - <radio id="chrome" label="&importFromChrome.label;" accesskey="&importFromChrome.accesskey;"/> - <radio id="safari" label="&importFromSafari.label;" accesskey="&importFromSafari.accesskey;"/> -#elifdef XP_MACOSX - <radio id="safari" label="&importFromSafari.label;" accesskey="&importFromSafari.accesskey;"/> - <radio id="chrome" label="&importFromChrome.label;" accesskey="&importFromChrome.accesskey;"/> -#elifdef XP_UNIX - <radio id="chrome" label="&importFromChrome.label;" accesskey="&importFromChrome.accesskey;"/> -#endif - <radio id="nothing" label="&importFromNothing.label;" accesskey="&importFromNothing.accesskey;" hidden="true"/> - </radiogroup> - <label id="noSources" hidden="true">&noMigrationSources.label;</label> - </wizardpage> - - <wizardpage id="selectProfile" pageid="selectProfile" label="&selectProfile.title;" - next="importItems" - onpageshow="return MigrationWizard.onSelectProfilePageShow();" - onpagerewound="return MigrationWizard.onSelectProfilePageRewound();" - onpageadvanced="return MigrationWizard.onSelectProfilePageAdvanced();"> - <description control="profiles">&selectProfile.label;</description> - - <radiogroup id="profiles" align="left"/> - </wizardpage> - - <wizardpage id="importItems" pageid="importItems" label="&importItems.title;" - next="homePageImport" - onpageshow="return MigrationWizard.onImportItemsPageShow();" - onpagerewound="return MigrationWizard.onImportItemsPageRewound();" - onpageadvanced="return MigrationWizard.onImportItemsPageAdvanced();" - oncommand="MigrationWizard.onImportItemCommand();"> - <description control="dataSources">&importItems.label;</description> - - <vbox id="dataSources" style="overflow: auto; -moz-appearance: listbox" align="left" flex="1" role="group"/> - </wizardpage> - - <wizardpage id="homePageImport" pageid="homePageImport" - next="migrating" - onpageshow="return MigrationWizard.onHomePageMigrationPageShow();" - onpageadvanced="return MigrationWizard.onHomePageMigrationPageAdvanced();"> - - <description id="homePageImportDesc" control="homePageRadioGroup"/> - <radiogroup id="homePageRadiogroup"> - <radio id="homePageSingleStart" selected="true" /> - <radio id="oldHomePage" hidden="true" /> - </radiogroup> - </wizardpage> - - <wizardpage id="migrating" pageid="migrating" label="&migrating.title;" - next="done" - onpageshow="MigrationWizard.onMigratingPageShow();"> - <description control="migratingItems">&migrating.label;</description> - - <vbox id="migratingItems" style="overflow: auto;" align="left" role="group"/> - </wizardpage> - - <wizardpage id="done" pageid="done" label="&done.title;" - onpageshow="MigrationWizard.onDonePageShow();"> - <description control="doneItems">&done.label;</description> - - <vbox id="doneItems" style="overflow: auto;" align="left" role="group"/> - </wizardpage> - -</wizard> - diff --git a/application/palemoon/components/migration/jar.mn b/application/palemoon/components/migration/jar.mn deleted file mode 100644 index b369ee1dc..000000000 --- a/application/palemoon/components/migration/jar.mn +++ /dev/null @@ -1,7 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -browser.jar: -* content/browser/migration/migration.xul (content/migration.xul) - content/browser/migration/migration.js (content/migration.js) diff --git a/application/palemoon/components/migration/moz.build b/application/palemoon/components/migration/moz.build deleted file mode 100644 index 4cbf7b8ea..000000000 --- a/application/palemoon/components/migration/moz.build +++ /dev/null @@ -1,53 +0,0 @@ -# -*- 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/. - -JAR_MANIFESTS += ['jar.mn'] - -XPIDL_SOURCES += [ - 'nsIBrowserProfileMigrator.idl', -] - -XPIDL_MODULE = 'migration' - -if CONFIG['OS_ARCH'] == 'WINNT': - SOURCES += [ - 'nsIEHistoryEnumerator.cpp', - ] - -EXTRA_COMPONENTS += [ - 'FirefoxProfileMigrator.js', - 'ProfileMigrator.js', -] - -if CONFIG['OS_ARCH'] == 'WINNT': - EXTRA_COMPONENTS += [ - 'IEProfileMigrator.js', - ] - DEFINES['HAS_IE_MIGRATOR'] = True - -EXTRA_PP_COMPONENTS += [ - 'BrowserProfileMigrators.manifest', - 'ChromeProfileMigrator.js', -] - -if CONFIG['OS_ARCH'] == 'WINNT': - EXTRA_PP_COMPONENTS += [ - 'SafariProfileMigrator.js', - ] - DEFINES['HAS_SAFARI_MIGRATOR'] = True - -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': - EXTRA_PP_COMPONENTS += [ - 'SafariProfileMigrator.js', - ] - DEFINES['HAS_SAFARI_MIGRATOR'] = True - -EXTRA_PP_JS_MODULES += [ - 'MigrationUtils.jsm', -] - -FINAL_LIBRARY = 'browsercomps' - diff --git a/application/palemoon/components/migration/nsIBrowserProfileMigrator.idl b/application/palemoon/components/migration/nsIBrowserProfileMigrator.idl deleted file mode 100644 index ebff4628c..000000000 --- a/application/palemoon/components/migration/nsIBrowserProfileMigrator.idl +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsISupports.idl" - -interface nsIArray; -interface nsIProfileStartup; - -[scriptable, uuid(30e5a7ec-f71e-4f41-9dbd-7429c02132ec)] -interface nsIBrowserProfileMigrator : nsISupports -{ - /** - * profile items to migrate. use with migrate(). - */ - const unsigned short ALL = 0x0000; - const unsigned short SETTINGS = 0x0001; - const unsigned short COOKIES = 0x0002; - const unsigned short HISTORY = 0x0004; - const unsigned short FORMDATA = 0x0008; - const unsigned short PASSWORDS = 0x0010; - const unsigned short BOOKMARKS = 0x0020; - const unsigned short OTHERDATA = 0x0040; - - /** - * Copy user profile information to the current active profile. - * @param aItems list of data items to migrate. see above for values. - * @param aStartup helper interface which is non-null if called during startup. - * @param aProfile profile to migrate from, if there is more than one. - */ - void migrate(in unsigned short aItems, in nsIProfileStartup aStartup, in jsval aProfile); - - /** - * A bit field containing profile items that this migrator - * offers for import. - * @param aProfile the profile that we are looking for available data - * to import - * @param aDoingStartup "true" if the profile is not currently being used. - * @return bit field containing profile items (see above) - * @note a return value of 0 represents no items rather than ALL. - */ - unsigned short getMigrateData(in jsval aProfile, in boolean aDoingStartup); - - /** - * Whether or not there is any data that can be imported from this - * browser (i.e. whether or not it is installed, and there exists - * a user profile) - */ - readonly attribute boolean sourceExists; - - - /** - * An enumeration of available profiles. If the import source does - * not support profiles, this attribute is null. - */ - readonly attribute jsval sourceProfiles; - - /** - * The import source homepage. Returns null if not present/available - */ - readonly attribute AUTF8String sourceHomePageURL; -}; diff --git a/application/palemoon/components/migration/nsIEHistoryEnumerator.cpp b/application/palemoon/components/migration/nsIEHistoryEnumerator.cpp deleted file mode 100644 index 0b377d27e..000000000 --- a/application/palemoon/components/migration/nsIEHistoryEnumerator.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsIEHistoryEnumerator.h" - -#include <urlhist.h> -#include <shlguid.h> - -#include "nsArrayEnumerator.h" -#include "nsCOMArray.h" -#include "nsIVariant.h" -#include "nsNetUtil.h" -#include "nsStringAPI.h" -#include "nsWindowsMigrationUtils.h" -#include "prtime.h" - -//////////////////////////////////////////////////////////////////////////////// -//// nsIEHistoryEnumerator - -NS_IMPL_ISUPPORTS(nsIEHistoryEnumerator, nsISimpleEnumerator) - -nsIEHistoryEnumerator::nsIEHistoryEnumerator() -{ - ::CoInitialize(nullptr); -} - -nsIEHistoryEnumerator::~nsIEHistoryEnumerator() -{ - ::CoUninitialize(); -} - -void -nsIEHistoryEnumerator::EnsureInitialized() -{ - if (mURLEnumerator) - return; - - HRESULT hr = ::CoCreateInstance(CLSID_CUrlHistory, - nullptr, - CLSCTX_INPROC_SERVER, - IID_IUrlHistoryStg2, - getter_AddRefs(mIEHistory)); - if (FAILED(hr)) - return; - - hr = mIEHistory->EnumUrls(getter_AddRefs(mURLEnumerator)); - if (FAILED(hr)) - return; -} - -NS_IMETHODIMP -nsIEHistoryEnumerator::HasMoreElements(bool* _retval) -{ - *_retval = false; - - EnsureInitialized(); - MOZ_ASSERT(mURLEnumerator, "Should have instanced an IE History URLEnumerator"); - if (!mURLEnumerator) - return NS_OK; - - STATURL statURL; - ULONG fetched; - - // First argument is not implemented, so doesn't matter what we pass. - HRESULT hr = mURLEnumerator->Next(1, &statURL, &fetched); - if (FAILED(hr) || fetched != 1UL) { - // Reached the last entry. - return NS_OK; - } - - nsCOMPtr<nsIURI> uri; - if (statURL.pwcsUrl) { - nsDependentString url(statURL.pwcsUrl); - nsresult rv = NS_NewURI(getter_AddRefs(uri), url); - ::CoTaskMemFree(statURL.pwcsUrl); - if (NS_FAILED(rv)) { - // Got a corrupt or invalid URI, continue to the next entry. - return HasMoreElements(_retval); - } - } - - nsDependentString title(statURL.pwcsTitle ? statURL.pwcsTitle : L""); - - bool lastVisitTimeIsValid; - PRTime lastVisited = WinMigrationFileTimeToPRTime(&(statURL.ftLastVisited), &lastVisitTimeIsValid); - - mCachedNextEntry = do_CreateInstance("@mozilla.org/hash-property-bag;1"); - MOZ_ASSERT(mCachedNextEntry, "Should have instanced a new property bag"); - if (mCachedNextEntry) { - mCachedNextEntry->SetPropertyAsInterface(NS_LITERAL_STRING("uri"), uri); - mCachedNextEntry->SetPropertyAsAString(NS_LITERAL_STRING("title"), title); - if (lastVisitTimeIsValid) { - mCachedNextEntry->SetPropertyAsInt64(NS_LITERAL_STRING("time"), lastVisited); - } - - *_retval = true; - } - - if (statURL.pwcsTitle) - ::CoTaskMemFree(statURL.pwcsTitle); - - return NS_OK; -} - -NS_IMETHODIMP -nsIEHistoryEnumerator::GetNext(nsISupports** _retval) -{ - *_retval = nullptr; - - if (!mCachedNextEntry) - return NS_ERROR_FAILURE; - - NS_ADDREF(*_retval = mCachedNextEntry); - // Release the cached entry, so it can't be returned twice. - mCachedNextEntry = nullptr; - - return NS_OK; -} diff --git a/application/palemoon/components/migration/nsIEHistoryEnumerator.h b/application/palemoon/components/migration/nsIEHistoryEnumerator.h deleted file mode 100644 index 1572a8dd5..000000000 --- a/application/palemoon/components/migration/nsIEHistoryEnumerator.h +++ /dev/null @@ -1,37 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef iehistoryenumerator___h___ -#define iehistoryenumerator___h___ - -#include <urlhist.h> - -#include "mozilla/Attributes.h" -#include "nsCOMPtr.h" -#include "nsISimpleEnumerator.h" -#include "nsIWritablePropertyBag2.h" - -class nsIEHistoryEnumerator final : public nsISimpleEnumerator -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSISIMPLEENUMERATOR - - nsIEHistoryEnumerator(); - -private: - ~nsIEHistoryEnumerator(); - - /** - * Initializes the history reader, if needed. - */ - void EnsureInitialized(); - - RefPtr<IUrlHistoryStg2> mIEHistory; - RefPtr<IEnumSTATURL> mURLEnumerator; - - nsCOMPtr<nsIWritablePropertyBag2> mCachedNextEntry; -}; - -#endif diff --git a/application/palemoon/components/migration/nsWindowsMigrationUtils.h b/application/palemoon/components/migration/nsWindowsMigrationUtils.h deleted file mode 100644 index 0288d93d3..000000000 --- a/application/palemoon/components/migration/nsWindowsMigrationUtils.h +++ /dev/null @@ -1,36 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef windowsmigrationutils__h__ -#define windowsmigrationutils__h__ - -#include "prtime.h" - -static -PRTime WinMigrationFileTimeToPRTime(FILETIME* filetime, bool* isValid) -{ - SYSTEMTIME st; - *isValid = ::FileTimeToSystemTime(filetime, &st); - if (!*isValid) { - return 0; - } - PRExplodedTime prt; - prt.tm_year = st.wYear; - // SYSTEMTIME's day-of-month parameter is 1-based, - // PRExplodedTime's is 0-based. - prt.tm_month = st.wMonth - 1; - prt.tm_mday = st.wDay; - prt.tm_hour = st.wHour; - prt.tm_min = st.wMinute; - prt.tm_sec = st.wSecond; - prt.tm_usec = st.wMilliseconds * 1000; - prt.tm_wday = 0; - prt.tm_yday = 0; - prt.tm_params.tp_gmt_offset = 0; - prt.tm_params.tp_dst_offset = 0; - return PR_ImplodeTime(&prt); -} - -#endif - diff --git a/application/palemoon/components/moz.build b/application/palemoon/components/moz.build index 1c1098f0a..6e83936a9 100644 --- a/application/palemoon/components/moz.build +++ b/application/palemoon/components/moz.build @@ -17,7 +17,6 @@ DIRS += [ 'search', 'sessionstore', 'shell', - 'migration', ] if CONFIG['MOZ_BROWSER_STATUSBAR']: diff --git a/application/palemoon/components/nsBrowserGlue.js b/application/palemoon/components/nsBrowserGlue.js index 5b7fdde33..cdb0b7522 100644 --- a/application/palemoon/components/nsBrowserGlue.js +++ b/application/palemoon/components/nsBrowserGlue.js @@ -13,59 +13,29 @@ const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "AddonManager", - "resource://gre/modules/AddonManager.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "NetUtil", - "resource://gre/modules/NetUtil.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "UserAgentOverrides", - "resource://gre/modules/UserAgentOverrides.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "FileUtils", - "resource://gre/modules/FileUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils", - "resource://gre/modules/PlacesUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "BookmarkHTMLUtils", - "resource://gre/modules/BookmarkHTMLUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "BookmarkJSONUtils", - "resource://gre/modules/BookmarkJSONUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "PageThumbs", - "resource://gre/modules/PageThumbs.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "NewTabUtils", - "resource://gre/modules/NewTabUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "BrowserNewTabPreloader", - "resource:///modules/BrowserNewTabPreloader.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "webrtcUI", - "resource:///modules/webrtcUI.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils", - "resource://gre/modules/PrivateBrowsingUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "RecentWindow", - "resource:///modules/RecentWindow.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "Task", - "resource://gre/modules/Task.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "PlacesBackups", - "resource://gre/modules/PlacesBackups.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "OS", - "resource://gre/modules/osfile.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "LoginManagerParent", - "resource://gre/modules/LoginManagerParent.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "FormValidationHandler", - "resource:///modules/FormValidationHandler.jsm"); +// Define Lazy Module Gitters +[ + ["AddonManager", "resource://gre/modules/AddonManager.jsm"], + ["NetUtil", "resource://gre/modules/NetUtil.jsm"], + ["UserAgentOverrides", "resource://gre/modules/UserAgentOverrides.jsm"], + ["FileUtils", "resource://gre/modules/FileUtils.jsm"], + ["PlacesUtils", "resource://gre/modules/PlacesUtils.jsm"], + ["BookmarkHTMLUtils", "resource://gre/modules/BookmarkHTMLUtils.jsm"], + ["BookmarkJSONUtils", "resource://gre/modules/BookmarkJSONUtils.jsm"], + ["PageThumbs", "resource://gre/modules/PageThumbs.jsm"], + ["NewTabUtils", "resource://gre/modules/NewTabUtils.jsm"], + ["BrowserNewTabPreloader", "resource:///modules/BrowserNewTabPreloader.jsm"], +#ifdef MOZ_WEBRTC + ["webrtcUI", "resource:///modules/webrtcUI.jsm"], +#endif + ["PrivateBrowsingUtils", "resource://gre/modules/PrivateBrowsingUtils.jsm"], + ["RecentWindow", "resource:///modules/RecentWindow.jsm"], + ["Task", "resource://gre/modules/Task.jsm"], + ["PlacesBackups", "resource://gre/modules/PlacesBackups.jsm"], + ["OS", "resource://gre/modules/osfile.jsm"], + ["LoginManagerParent", "resource://gre/modules/LoginManagerParent.jsm"], + ["FormValidationHandler", "resource:///modules/FormValidationHandler.jsm"], +].forEach(([name, resource]) => XPCOMUtils.defineLazyModuleGetter(this, name, resource)); const PREF_PLUGINS_NOTIFYUSER = "plugins.update.notifyUser"; const PREF_PLUGINS_UPDATEURL = "plugins.update.url"; @@ -284,7 +254,8 @@ BrowserGlue.prototype = { if (!linkHandled.data) { let win = this.getMostRecentBrowserWindow(); if (win) { - win.openUILinkIn(data, "tab"); + data = JSON.parse(data); + win.openUILinkIn(data.href, "tab"); linkHandled.data = true; } } @@ -427,7 +398,9 @@ BrowserGlue.prototype = { PageThumbs.init(); NewTabUtils.init(); BrowserNewTabPreloader.init(); +#ifdef MOZ_WEBRTC webrtcUI.init(); +#endif FormValidationHandler.init(); LoginManagerParent.init(); @@ -534,7 +507,9 @@ BrowserGlue.prototype = { _onProfileShutdown: function BG__onProfileShutdown() { BrowserNewTabPreloader.uninit(); UserAgentOverrides.uninit(); +#ifdef MOZ_WEBRTC webrtcUI.uninit(); +#endif FormValidationHandler.uninit(); this._dispose(); }, diff --git a/application/palemoon/components/places/content/places.js b/application/palemoon/components/places/content/places.js index af254a7fb..9ecdfebe0 100644 --- a/application/palemoon/components/places/content/places.js +++ b/application/palemoon/components/places/content/places.js @@ -4,7 +4,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); -Components.utils.import("resource:///modules/MigrationUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "Task", "resource://gre/modules/Task.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "BookmarkJSONUtils", @@ -335,14 +334,6 @@ var PlacesOrganizer = { }, /** - * Show the migration wizard for importing passwords, - * cookies, history, preferences, and bookmarks. - */ - importFromBrowser: function PO_importFromBrowser() { - MigrationUtils.showMigrationWizard(window); - }, - - /** * Open a file-picker and import the selected file into the bookmarks store */ importFromFile: function PO_importFromFile() { diff --git a/application/palemoon/components/places/content/places.xul b/application/palemoon/components/places/content/places.xul index ee1f2ff48..92e8a70e9 100644 --- a/application/palemoon/components/places/content/places.xul +++ b/application/palemoon/components/places/content/places.xul @@ -68,8 +68,6 @@ oncommand="PlacesOrganizer.exportBookmarks();"/> <command id="OrganizerCommand_import" oncommand="PlacesOrganizer.importFromFile();"/> - <command id="OrganizerCommand_browserImport" - oncommand="PlacesOrganizer.importFromBrowser();"/> <command id="OrganizerCommand_backup" oncommand="PlacesOrganizer.backupBookmarks();"/> <command id="OrganizerCommand_restoreFromFile" @@ -312,11 +310,6 @@ command="OrganizerCommand_export" label="&exportBookmarksToHTML.label;" accesskey="&exportBookmarksToHTML.accesskey;"/> - <menuseparator/> - <menuitem id="browserImport" - command="OrganizerCommand_browserImport" - label="&importOtherBrowser.label;" - accesskey="&importOtherBrowser.accesskey;"/> </menupopup> #ifdef XP_MACOSX </toolbarbutton> diff --git a/application/palemoon/components/places/content/placesOverlay.xul b/application/palemoon/components/places/content/placesOverlay.xul index 30319a6ac..dd4d50f01 100644 --- a/application/palemoon/components/places/content/placesOverlay.xul +++ b/application/palemoon/components/places/content/placesOverlay.xul @@ -20,8 +20,8 @@ <script type="application/javascript"><![CDATA[ // TODO: Bug 406371. // A bunch of browser code depends on us defining these, sad but true :( - // var Cc = Components.classes; - // var Ci = Components.interfaces; + var Cc = Components.classes; + var Ci = Components.interfaces; var Cr = Components.results; Components.utils.import("resource://gre/modules/PlacesUtils.jsm"); diff --git a/application/palemoon/components/preferences/aboutPermissions.js b/application/palemoon/components/preferences/aboutPermissions.js index 4d803145d..106d45f89 100644 --- a/application/palemoon/components/preferences/aboutPermissions.js +++ b/application/palemoon/components/preferences/aboutPermissions.js @@ -2,9 +2,9 @@ * 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/. */ -let Ci = Components.interfaces; -let Cc = Components.classes; -let Cu = Components.utils; +var Ci = Components.interfaces; +var Cc = Components.classes; +var Cu = Components.utils; Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/PluralForm.jsm"); diff --git a/application/palemoon/components/preferences/security.js b/application/palemoon/components/preferences/security.js index a337f398c..56664bf66 100644 --- a/application/palemoon/components/preferences/security.js +++ b/application/palemoon/components/preferences/security.js @@ -3,6 +3,9 @@ * 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/. */ +XPCOMUtils.defineLazyModuleGetter(this, "LoginHelper", + "resource://gre/modules/LoginHelper.jsm"); + Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm"); var gSecurityPane = { @@ -141,7 +144,7 @@ var gSecurityPane = { */ _initMasterPasswordUI: function () { - var noMP = !this._masterPasswordSet(); + var noMP = !LoginHelper.isMasterPasswordSet(); var button = document.getElementById("changeMasterPassword"); button.disabled = noMP; @@ -151,26 +154,6 @@ var gSecurityPane = { }, /** - * Returns true if the user has a master password set and false otherwise. - */ - _masterPasswordSet: function () - { - const Cc = Components.classes, Ci = Components.interfaces; - var secmodDB = Cc["@mozilla.org/security/pkcs11moduledb;1"]. - getService(Ci.nsIPKCS11ModuleDB); - var slot = secmodDB.findSlotByName(""); - if (slot) { - var status = slot.status; - var hasMP = status != Ci.nsIPKCS11Slot.SLOT_UNINITIALIZED && - status != Ci.nsIPKCS11Slot.SLOT_READY; - return hasMP; - } else { - // XXX I have no bloody idea what this means - return false; - } - }, - - /** * Enables/disables the master password button depending on the state of the * "use master password" checkbox, and prompts for master password removal if * one is set. diff --git a/application/palemoon/components/sessionstore/SessionStore.jsm b/application/palemoon/components/sessionstore/SessionStore.jsm index b74e68a2f..136a3d8de 100644 --- a/application/palemoon/components/sessionstore/SessionStore.jsm +++ b/application/palemoon/components/sessionstore/SessionStore.jsm @@ -106,12 +106,12 @@ XPCOMUtils.defineLazyModuleGetter(this, "NetUtil", #ifdef MOZ_DEVTOOLS XPCOMUtils.defineLazyModuleGetter(this, "ScratchpadManager", - "resource://gre/modules/devtools/scratchpad-manager.jsm"); + "resource://devtools/client/scratchpad/scratchpad-manager.jsm"); Object.defineProperty(this, "HUDService", { get: function HUDService_getter() { - let devtools = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools; - return devtools.require("devtools/webconsole/hudservice").HUDService; + let devtools = Cu.import("resource://devtools/shared/Loader.jsm", {}).devtools; + return devtools.require("devtools/client/webconsole/hudservice").HUDService; }, configurable: true, enumerable: true diff --git a/application/palemoon/components/sessionstore/_SessionFile.jsm b/application/palemoon/components/sessionstore/_SessionFile.jsm index 7e1b05f74..e949112f2 100644 --- a/application/palemoon/components/sessionstore/_SessionFile.jsm +++ b/application/palemoon/components/sessionstore/_SessionFile.jsm @@ -41,7 +41,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "FileUtils", XPCOMUtils.defineLazyModuleGetter(this, "Task", "resource://gre/modules/Task.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "console", - "resource://gre/modules/devtools/Console.jsm"); + "resource://gre/modules/Console.jsm"); // An encoder to UTF-8. XPCOMUtils.defineLazyGetter(this, "gEncoder", function () { diff --git a/application/palemoon/confvars.sh b/application/palemoon/confvars.sh index 560eb1cec..8a1d00c68 100644 --- a/application/palemoon/confvars.sh +++ b/application/palemoon/confvars.sh @@ -59,7 +59,7 @@ ACCEPTED_MAR_CHANNEL_IDS=palemoon-release # Platform Feature: Developer Tools # XXX: Devtools are disabled until they can be made to work with Pale Moon -MOZ_DEVTOOLS= +MOZ_DEVTOOLS=1 # Platform Feature: "Phoenix" Extensions Support aka Dual-guid system. # Allows installation of Firefox GUID targeted extensions despite having diff --git a/application/palemoon/installer/package-manifest.in b/application/palemoon/installer/package-manifest.in index a581ff469..ffe033596 100644 --- a/application/palemoon/installer/package-manifest.in +++ b/application/palemoon/installer/package-manifest.in @@ -282,7 +282,7 @@ @RESPATH@/components/jar.xpt @RESPATH@/components/jsdebugger.xpt @RESPATH@/components/jsdownloads.xpt -@RESPATH@/components/jsinspector.xpt +@RESPATH@/browser/components/jsinspector.xpt @RESPATH@/components/layout_base.xpt #ifdef NS_PRINTING @@ -322,7 +322,7 @@ @RESPATH@/components/plugin.xpt @RESPATH@/components/pref.xpt @RESPATH@/components/prefetch.xpt -@RESPATH@/components/profile.xpt +@RESPATH@/components/profiler.xpt @RESPATH@/components/rdf.xpt @RESPATH@/components/satchel.xpt @RESPATH@/components/saxparser.xpt @@ -421,8 +421,8 @@ @RESPATH@/components/jsconsole-clhandler.manifest @RESPATH@/components/jsconsole-clhandler.js #ifdef MOZ_DEVTOOLS -@RESPATH@/components/devtools-clhandler.manifest -@RESPATH@/components/devtools-clhandler.js +@RESPATH@/browser/components/devtools-startup.manifest +@RESPATH@/browser/components/devtools-startup.js #endif @RESPATH@/components/webvtt.xpt @RESPATH@/components/WebVTT.manifest @@ -677,6 +677,16 @@ @RESPATH@/browser/chrome/icons/default/default48.png #endif +; [Webide Files] +@RESPATH@/browser/chrome/webide@JAREXT@ +@RESPATH@/browser/chrome/webide.manifest +@RESPATH@/browser/@PREF_DIR@/webide-prefs.js + +; DevTools +@RESPATH@/browser/chrome/devtools@JAREXT@ +@RESPATH@/browser/chrome/devtools.manifest +@RESPATH@/browser/@PREF_DIR@/devtools.js + ; shell icons #ifdef XP_UNIX #ifndef XP_MACOSX diff --git a/application/palemoon/locales/en-US/chrome/browser/browser.dtd b/application/palemoon/locales/en-US/chrome/browser/browser.dtd index 0225f422b..65cc34fa0 100644 --- a/application/palemoon/locales/en-US/chrome/browser/browser.dtd +++ b/application/palemoon/locales/en-US/chrome/browser/browser.dtd @@ -642,8 +642,10 @@ just addresses the organization to follow, e.g. "This site is run by " --> <!ENTITY getUserMedia.selectMicrophone.label "Microphone to share:"> <!ENTITY getUserMedia.selectMicrophone.accesskey "M"> +#ifdef MOZ_WEBRTC <!ENTITY webrtcIndicatorButton.label "Camera / Microphone Access"> <!ENTITY webrtcIndicatorButton.tooltip "Display sites you are currently sharing your camera or microphone with"> +#endif <!ENTITY mixedContentBlocked.moreinfo "Most websites will still work properly even when this content is blocked."> diff --git a/application/palemoon/locales/en-US/chrome/browser/migration/migration.dtd b/application/palemoon/locales/en-US/chrome/browser/migration/migration.dtd deleted file mode 100644 index 2848c4e67..000000000 --- a/application/palemoon/locales/en-US/chrome/browser/migration/migration.dtd +++ /dev/null @@ -1,36 +0,0 @@ -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - - -<!ENTITY migrationWizard.title "Import Wizard"> - -<!ENTITY importFrom.label "Import Preferences, Bookmarks, History, Passwords and other data from:"> -<!ENTITY importFromBookmarks.label "Import Bookmarks from:"> - -<!ENTITY importFromIE.label "Microsoft Internet Explorer"> -<!ENTITY importFromIE.accesskey "M"> -<!ENTITY importFromNothing.label "Don't import anything"> -<!ENTITY importFromNothing.accesskey "D"> -<!ENTITY importFromSafari.label "Safari"> -<!ENTITY importFromSafari.accesskey "S"> -<!ENTITY importFromChrome.label "Chrome"> -<!ENTITY importFromChrome.accesskey "C"> -<!ENTITY importFromFirefox.label "Firefox"> -<!ENTITY importFromFirefox.accesskey "X"> - -<!ENTITY noMigrationSources.label "No programs that contain bookmarks, history or password data could be found."> - -<!ENTITY importSource.title "Import Settings and Data"> -<!ENTITY importItems.title "Items to Import"> -<!ENTITY importItems.label "Select which items to import:"> - -<!ENTITY migrating.title "Importing…"> -<!ENTITY migrating.label "The following items are currently being imported…"> - -<!ENTITY selectProfile.title "Select Profile"> -<!ENTITY selectProfile.label "The following profiles are available to import from:"> - -<!ENTITY done.title "Import Complete"> -<!ENTITY done.label "The following items were successfully imported:"> - diff --git a/application/palemoon/locales/en-US/chrome/browser/migration/migration.properties b/application/palemoon/locales/en-US/chrome/browser/migration/migration.properties deleted file mode 100644 index b1cb03d0a..000000000 --- a/application/palemoon/locales/en-US/chrome/browser/migration/migration.properties +++ /dev/null @@ -1,51 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -profileName_format=%S %S - -# Browser Specific -sourceNameIE=Internet Explorer -sourceNameSafari=Safari -sourceNameChrome=Google Chrome -sourceNameFirefox=Mozilla Firefox - -importedBookmarksFolder=From %S - -importedSafariReadingList=Reading List (From Safari) - -# Import Sources -# Note: When adding an import source for profile reset, add the string name to -# resetProfile.js if it should be listed in the reset dialog. -1_ie=Internet Options -1_safari=Preferences -1_chrome=Preferences - -2_ie=Cookies -2_safari=Cookies -2_chrome=Cookies -2_firefox=Cookies - -4_ie=Browsing History -4_safari=Browsing History -4_chrome=Browsing History -4_firefox_history_and_bookmarks=Browsing History and Bookmarks - -8_ie=Saved Form History -8_safari=Saved Form History -8_chrome=Saved Form History -8_firefox=Saved Form History - -16_ie=Saved Passwords -16_safari=Saved Passwords -16_chrome=Saved Passwords -16_firefox=Saved Passwords - -32_ie=Favorites -32_safari=Bookmarks -32_chrome=Bookmarks - -64_ie=Other Data -64_safari=Other Data -64_chrome=Other Data -64_firefox_other=Other Data diff --git a/application/palemoon/locales/en-US/chrome/browser/places/places.dtd b/application/palemoon/locales/en-US/chrome/browser/places/places.dtd index 949593e7d..9578754d2 100644 --- a/application/palemoon/locales/en-US/chrome/browser/places/places.dtd +++ b/application/palemoon/locales/en-US/chrome/browser/places/places.dtd @@ -31,8 +31,6 @@ <!ENTITY importBookmarksFromHTML.accesskey "I"> <!ENTITY exportBookmarksToHTML.label "Export Bookmarks to HTML…"> <!ENTITY exportBookmarksToHTML.accesskey "E"> -<!ENTITY importOtherBrowser.label "Import Data from Another Browser…"> -<!ENTITY importOtherBrowser.accesskey "A"> <!ENTITY cmd.backup.label "Backup…"> <!ENTITY cmd.backup.accesskey "B"> diff --git a/application/palemoon/locales/jar.mn b/application/palemoon/locales/jar.mn index 451a86ab7..f2b9ddeb2 100644 --- a/application/palemoon/locales/jar.mn +++ b/application/palemoon/locales/jar.mn @@ -16,7 +16,7 @@ locale/browser/syncProgress.dtd (%chrome/browser/syncProgress.dtd) locale/browser/aboutSyncTabs.dtd (%chrome/browser/aboutSyncTabs.dtd) #endif - locale/browser/browser.dtd (%chrome/browser/browser.dtd) +* locale/browser/browser.dtd (%chrome/browser/browser.dtd) locale/browser/baseMenuOverlay.dtd (%chrome/browser/baseMenuOverlay.dtd) locale/browser/charsetOverlay.dtd (%chrome/browser/charsetOverlay.dtd) locale/browser/browser.properties (%chrome/browser/browser.properties) @@ -55,8 +55,6 @@ locale/browser/places/moveBookmarks.dtd (%chrome/browser/places/moveBookmarks.dtd) locale/browser/feeds/subscribe.dtd (%chrome/browser/feeds/subscribe.dtd) locale/browser/feeds/subscribe.properties (%chrome/browser/feeds/subscribe.properties) - locale/browser/migration/migration.dtd (%chrome/browser/migration/migration.dtd) - locale/browser/migration/migration.properties (%chrome/browser/migration/migration.properties) locale/browser/preferences/aboutPermissions.dtd (%chrome/browser/preferences/aboutPermissions.dtd) locale/browser/preferences/aboutPermissions.properties (%chrome/browser/preferences/aboutPermissions.properties) locale/browser/preferences/advanced.dtd (%chrome/browser/preferences/advanced.dtd) diff --git a/application/palemoon/modules/QuotaManager.jsm b/application/palemoon/modules/QuotaManager.jsm index e03161a69..48cfe88b3 100644 --- a/application/palemoon/modules/QuotaManager.jsm +++ b/application/palemoon/modules/QuotaManager.jsm @@ -6,8 +6,9 @@ this.EXPORTED_SYMBOLS = ["QuotaManagerHelper"]; Components.utils.import('resource://gre/modules/Services.jsm'); -const Cc = Components.classes; const Ci = Components.interfaces; +const Cc = Components.classes; +const Cu = Components.utils; this.QuotaManagerHelper = { clear: function(isShutDown) { @@ -34,12 +35,17 @@ this.QuotaManagerHelper = { } } } - var qm = Cc["@mozilla.org/dom/quota/manager;1"].getService(Ci.nsIQuotaManager); + var qm = Cc["@mozilla.org/dom/quota-manager-service;1"] + .getService(Ci.nsIQuotaManagerService); for (var dom in doms) { var uri = Services.io.newURI(dom, null, null); - qm.clearStoragesForURI(uri); + let principal = Services.scriptSecurityManager + .createCodebasePrincipal(uri, {}); + qm.clearStoragesForPrincipal(principal); } } - } catch(er) {} + } catch(er) { + Cu.reportError(er); + } } }; diff --git a/application/palemoon/modules/WindowsPreviewPerTab.jsm b/application/palemoon/modules/WindowsPreviewPerTab.jsm index 41b38f0cf..e186bcad2 100644 --- a/application/palemoon/modules/WindowsPreviewPerTab.jsm +++ b/application/palemoon/modules/WindowsPreviewPerTab.jsm @@ -510,7 +510,14 @@ TabWindow.prototype = { // Previews are internally stored using a map, so we need to iterate over // the tabbrowser's array of tabs to retrieve previews in the same order. - let inorder = [previews.get(t) for (t of tabs) if (previews.has(t))]; + // Tycho: let inorder = [previews.get(t) for (t of tabs) if (previews.has(t))]; + let inorder = []; + + for (let t of tabs) { + if (previews.has(t)) { + inorder.push(previews.get(t)); + } + } // Since the internal taskbar array has not yet been updated, we must force // the sorting order of our local array on it. To do so, we must walk diff --git a/application/palemoon/modules/moz.build b/application/palemoon/modules/moz.build index b3459bcd5..7620b9862 100644 --- a/application/palemoon/modules/moz.build +++ b/application/palemoon/modules/moz.build @@ -19,10 +19,12 @@ EXTRA_JS_MODULES += [ 'PageMenu.jsm', 'PopupNotifications.jsm', 'QuotaManager.jsm', - 'SharedFrame.jsm', - 'webrtcUI.jsm' + 'SharedFrame.jsm' ] +if CONFIG['MOZ_WEBRTC']: + EXTRA_JS_MODULES += ['webrtcUI.jsm'] + if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows': EXTRA_JS_MODULES += [ 'Windows8WindowFrameColor.jsm', diff --git a/application/palemoon/themes/linux/browser.css b/application/palemoon/themes/linux/browser.css index 07e9dae9c..a396ea5fd 100644 --- a/application/palemoon/themes/linux/browser.css +++ b/application/palemoon/themes/linux/browser.css @@ -728,9 +728,11 @@ toolbar[mode="full"] .toolbarbutton-1 > .toolbarbutton-menubutton-button { opacity: .4; } +%ifdef MOZ_WEBRTC #webrtc-status-button { -moz-image-region: rect(0px 192px 24px 168px); } +%endif /* 16px primary toolbar buttons */ toolbar[iconsize="small"] .toolbarbutton-1:not([type="menu-button"]) { @@ -812,7 +814,9 @@ toolbar[iconsize="small"] #downloads-button { -moz-image-region: rect(0px 16px 16px 0px); } +%ifdef MOZ_WEBRTC toolbar[iconsize="small"] #webrtc-status-button /* temporary placeholder (bug 824825) */, +%endif toolbar[iconsize="small"] #history-button, toolbar[iconsize="small"] #history-menu-button { -moz-image-region: rect(0px 32px 16px 16px); @@ -884,9 +888,11 @@ toolbar[iconsize="small"] #feed-button { -moz-image-region: rect(0px 112px 16px 96px); } +%ifdef MOZ_WEBRTC toolbar[iconsize="small"] #webrtc-status-button { -moz-image-region: rect(0px 128px 16px 112px); } +%endif /* Fullscreen window controls */ #window-controls { @@ -1226,10 +1232,12 @@ toolbar[iconsize="small"] #webrtc-status-button { list-style-image: url(chrome://browser/skin/mixed-content-blocked-64.png); } +%ifdef MOZ_WEBRTC .popup-notification-icon[popupid="webRTC-sharingDevices"], .popup-notification-icon[popupid="webRTC-shareDevices"] { list-style-image: url(chrome://browser/skin/webRTC-shareDevice-64.png); } +%endif .popup-notification-icon[popupid="pointerLock"] { list-style-image: url(chrome://browser/skin/pointerLock-64.png); @@ -1352,6 +1360,7 @@ toolbar[iconsize="small"] #webrtc-status-button { list-style-image: url(chrome://browser/skin/mixed-content-blocked-16.png); } +%ifdef MOZ_WEBRTC .webRTC-shareDevices-notification-icon, #webRTC-shareDevices-notification-icon { list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png); @@ -1361,6 +1370,7 @@ toolbar[iconsize="small"] #webrtc-status-button { #webRTC-sharingDevices-notification-icon { list-style-image: url(chrome://browser/skin/webRTC-sharingDevice-16.png); } +%endif .web-notifications-notification-icon, #web-notifications-notification-icon { @@ -2083,8 +2093,8 @@ toolbar[mode="text"] toolbarbutton.chevron > .toolbarbutton-icon { } %ifdef MOZ_DEVTOOLS -%include ../../../toolkit/themes/shared/devtools/responsivedesign.inc.css -%include ../../../toolkit/themes/shared/devtools/commandline.inc.css +%include ../../../../devtools/client/themes/responsivedesign.inc.css +%include ../../../../devtools/client/themes/commandline.inc.css %endif %include ../shared/plugin-doorhanger.inc.css diff --git a/application/palemoon/themes/linux/jar.mn b/application/palemoon/themes/linux/jar.mn index a756edbc3..44d837778 100644 --- a/application/palemoon/themes/linux/jar.mn +++ b/application/palemoon/themes/linux/jar.mn @@ -53,9 +53,11 @@ browser.jar: skin/classic/browser/Toolbar.png skin/classic/browser/Toolbar-small.png skin/classic/browser/urlbar-arrow.png +#ifdef MOZ_WEBRTC skin/classic/browser/webRTC-shareDevice-16.png skin/classic/browser/webRTC-shareDevice-64.png skin/classic/browser/webRTC-sharingDevice-16.png +#endif skin/classic/browser/downloads/buttons.png (downloads/buttons.png) skin/classic/browser/downloads/download-glow.png (downloads/download-glow.png) skin/classic/browser/downloads/download-glow-small.png (downloads/download-glow-small.png) diff --git a/application/palemoon/themes/osx/browser.css b/application/palemoon/themes/osx/browser.css index 58348a408..aa5918bab 100644 --- a/application/palemoon/themes/osx/browser.css +++ b/application/palemoon/themes/osx/browser.css @@ -801,10 +801,11 @@ toolbar[brighttext] #bookmarks-menu-button.bookmark-item { -moz-image-region: rect(0, 342px, 18px, 324px); } +%ifdef MOZ_WEBRTC #webrtc-status-button { -moz-image-region: rect(0, 360px, 18px, 342px); } - +%endif /* ::::: fullscreen window controls ::::: */ @@ -1955,11 +1956,13 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] { list-style-image: url(chrome://browser/skin/mixed-content-blocked-64.png); } +%ifdef MOZ_WEBRTC .popup-notification-icon[popupid="webRTC-sharingDevices"], .popup-notification-icon[popupid="webRTC-shareDevices"] { list-style-image: url(chrome://browser/skin/webRTC-shareDevice-64.png); } +%endif .popup-notification-icon[popupid="pointerLock"] { list-style-image: url(chrome://browser/skin/pointerLock-64.png); } @@ -2079,6 +2082,7 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] { list-style-image: url(chrome://browser/skin/mixed-content-blocked-16.png); } +%ifdef MOZ_WEBRTC .webRTC-shareDevices-notification-icon, #webRTC-shareDevices-notification-icon { list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png); @@ -2088,6 +2092,7 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] { #webRTC-sharingDevices-notification-icon { list-style-image: url(chrome://browser/skin/webRTC-sharingDevice-16.png); } +%endif .web-notifications-notification-icon, #web-notifications-notification-icon { @@ -2383,8 +2388,8 @@ toolbar[brighttext] #addonbar-closebutton { } %ifdef MOZ_DEVTOOLS -%include ../../../toolkit/themes/shared/devtools/responsivedesign.inc.css -%include ../../../toolkit/themes/shared/devtools/commandline.inc.css +%include ../../../../devtools/client/themes/responsivedesign.inc.css +%include ../../../../devtools/client/themes/commandline.inc.css %endif %include ../shared/plugin-doorhanger.inc.css diff --git a/application/palemoon/themes/osx/jar.mn b/application/palemoon/themes/osx/jar.mn index 00575bac8..8742f1b87 100644 --- a/application/palemoon/themes/osx/jar.mn +++ b/application/palemoon/themes/osx/jar.mn @@ -72,9 +72,11 @@ browser.jar: skin/classic/browser/notification-pluginNormal.png (../shared/plugins/notification-pluginNormal.png) skin/classic/browser/notification-pluginAlert.png (../shared/plugins/notification-pluginAlert.png) skin/classic/browser/notification-pluginBlocked.png (../shared/plugins/notification-pluginBlocked.png) +#ifdef MOZ_WEBRTC skin/classic/browser/webRTC-shareDevice-16.png skin/classic/browser/webRTC-shareDevice-64.png skin/classic/browser/webRTC-sharingDevice-16.png +#endif skin/classic/browser/downloads/buttons.png (downloads/buttons.png) skin/classic/browser/downloads/download-glow.png (downloads/download-glow.png) skin/classic/browser/downloads/download-notification-finish.png (downloads/download-notification-finish.png) diff --git a/application/palemoon/themes/osx/shared.inc b/application/palemoon/themes/osx/shared.inc index 2e8a8f269..ef27746a3 100644 --- a/application/palemoon/themes/osx/shared.inc +++ b/application/palemoon/themes/osx/shared.inc @@ -1,4 +1,4 @@ -%include ../../../toolkit/themes/osx/global/shared.inc
+%include ../../../../toolkit/themes/osx/global/shared.inc
%include ../shared/browser.inc
%define hudButton -moz-appearance: none; color: #434343; border-radius: 4px; border: 1px solid #b5b5b5; background: linear-gradient(#fff, #f2f2f2); box-shadow: inset 0 1px rgba(255,255,255,.8), inset 0 0 1px rgba(255,255, 255,.25), 0 1px rgba(255,255,255,.3); background-clip: padding-box; background-origin: padding-box; padding: 2px 6px;
diff --git a/application/palemoon/themes/shared/browser.inc b/application/palemoon/themes/shared/browser.inc index cd17903ce..18e69ad43 100644 --- a/application/palemoon/themes/shared/browser.inc +++ b/application/palemoon/themes/shared/browser.inc @@ -1,3 +1,8 @@ %filter substitution +%ifndef MOZ_WEBRTC +%define primaryToolbarButtons #back-button, #forward-button, #reload-button, #stop-button, #home-button, #print-button, #downloads-button, #downloads-indicator, #history-button, #history-menu-button, #bookmarks-button, #bookmarks-menu-button, #new-tab-button, #new-window-button, #cut-button, #copy-button, #paste-button, #fullscreen-button, #zoom-out-button, #zoom-in-button, #sync-button, #feed-button, #alltabs-button +%else %define primaryToolbarButtons #back-button, #forward-button, #reload-button, #stop-button, #home-button, #print-button, #downloads-button, #downloads-indicator, #history-button, #history-menu-button, #bookmarks-button, #bookmarks-menu-button, #new-tab-button, #new-window-button, #cut-button, #copy-button, #paste-button, #fullscreen-button, #zoom-out-button, #zoom-in-button, #sync-button, #feed-button, #alltabs-button, #webrtc-status-button +%endif + diff --git a/application/palemoon/themes/windows/browser.css b/application/palemoon/themes/windows/browser.css index 7c837764d..3e8c63af4 100644 --- a/application/palemoon/themes/windows/browser.css +++ b/application/palemoon/themes/windows/browser.css @@ -1192,10 +1192,11 @@ toolbar[brighttext] #bookmarks-menu-button.bookmark-item { -moz-image-region: rect(0, 342px, 18px, 324px); } +%ifdef MOZ_WEBRTC #webrtc-status-button { -moz-image-region: rect(0, 360px, 18px, 342px); } - +%endif /* ::::: fullscreen window controls ::::: */ @@ -2443,10 +2444,12 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] { list-style-image: url(chrome://browser/skin/mixed-content-blocked-64.png); } +%ifdef MOZ_WEBRTC .popup-notification-icon[popupid="webRTC-sharingDevices"], .popup-notification-icon[popupid="webRTC-shareDevices"] { list-style-image: url(chrome://browser/skin/webRTC-shareDevice-64.png); } +%endif .popup-notification-icon[popupid="pointerLock"] { list-style-image: url(chrome://browser/skin/pointerLock-64.png); @@ -2567,6 +2570,7 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] { list-style-image: url(chrome://browser/skin/mixed-content-blocked-16.png); } +%ifdef MOZ_WEBRTC .webRTC-shareDevices-notification-icon, #webRTC-shareDevices-notification-icon { list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png); @@ -2576,6 +2580,7 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] { #webRTC-sharingDevices-notification-icon { list-style-image: url(chrome://browser/skin/webRTC-sharingDevice-16.png); } +%endif .web-notifications-notification-icon, #web-notifications-notification-icon { @@ -2858,8 +2863,8 @@ toolbar[brighttext] #addonbar-closebutton { } %ifdef MOZ_DEVTOOLS -%include ../../../toolkit/themes/shared/devtools/responsivedesign.inc.css -%include ../../../toolkit/themes/shared/devtools/commandline.inc.css +%include ../../../../devtools/client/themes/responsivedesign.inc.css +%include ../../../../devtools/client/themes/commandline.inc.css %endif %include ../shared/plugin-doorhanger.inc.css diff --git a/application/palemoon/themes/windows/jar.mn b/application/palemoon/themes/windows/jar.mn index 1c1f139de..994e87be3 100644 --- a/application/palemoon/themes/windows/jar.mn +++ b/application/palemoon/themes/windows/jar.mn @@ -74,9 +74,11 @@ browser.jar: skin/classic/browser/notification-pluginNormal.png (../shared/plugins/notification-pluginNormal.png) skin/classic/browser/notification-pluginAlert.png (../shared/plugins/notification-pluginAlert.png) skin/classic/browser/notification-pluginBlocked.png (../shared/plugins/notification-pluginBlocked.png) +#ifdef MOZ_WEBRTC skin/classic/browser/webRTC-shareDevice-16.png skin/classic/browser/webRTC-shareDevice-64.png skin/classic/browser/webRTC-sharingDevice-16.png +#endif skin/classic/browser/downloads/buttons.png (downloads/buttons.png) skin/classic/browser/downloads/download-glow.png (downloads/download-glow.png) skin/classic/browser/downloads/download-notification-finish.png (downloads/download-notification-finish.png) @@ -98,7 +100,7 @@ browser.jar: skin/classic/browser/newtab/controls.png (newtab/controls.png) skin/classic/browser/newtab/noise.png (newtab/noise.png) skin/classic/browser/places/places.css (places/places.css) - skin/classic/browser/places/organizer.css (places/organizer.css) +* skin/classic/browser/places/organizer.css (places/organizer.css) skin/classic/browser/places/editBookmark.png (places/editBookmark.png) skin/classic/browser/places/bookmark.png (places/bookmark.png) skin/classic/browser/places/query.png (places/query.png) diff --git a/browser/LICENSE b/browser/LICENSE index 99d9d6bcd..f1b2067a7 100644 --- a/browser/LICENSE +++ b/browser/LICENSE @@ -2,6 +2,10 @@ Please see the file ../toolkit/content/license.html for the copyright licensing conditions attached to this codebase, including copies of the licenses concerned. -You are not granted rights or licenses to the trademarks of the -Mozilla Foundation or any party, including without limitation the -Firefox name or logo. +You are not granted rights or licenses to the trademarks of Moonchild +Productions or any other party, including without limitation the +Basilisk name or logo. + +The Serpent logo in branding/unofficial is derived from "Sea Serpent" +by Lorc, licensed under the Creative Commons license CC-BY 3.0 + diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index d6de538d7..0ef9d4ab5 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -229,11 +229,6 @@ pref("browser.slowStartup.notificationDisabled", false); pref("browser.slowStartup.timeThreshold", 40000); pref("browser.slowStartup.maxSamples", 5); -// This url, if changed, MUST continue to point to an https url. Pulling arbitrary content to inject into -// this page over http opens us up to a man-in-the-middle attack that we'd rather not face. If you are a downstream -// repackager of this code using an alternate snippet url, please keep your users safe -pref("browser.aboutHomeSnippets.updateUrl", "https://snippets.cdn.mozilla.net/%STARTPAGE_VERSION%/%NAME%/%VERSION%/%APPBUILDID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/"); - pref("browser.enable_automatic_image_resizing", true); pref("browser.casting.enabled", false); pref("browser.chrome.site_icons", true); @@ -1397,13 +1392,6 @@ pref("browser.translation.engine", "bing"); // Determines if Telemetry pings can be archived locally. pref("toolkit.telemetry.archive.enabled", true); -// Telemetry experiments settings. -pref("experiments.enabled", true); -pref("experiments.manifest.fetchIntervalSeconds", 86400); -pref("experiments.manifest.uri", "https://telemetry-experiment.cdn.mozilla.net/manifest/v1/firefox/%VERSION%/%CHANNEL%"); -// Whether experiments are supported by the current application profile. -pref("experiments.supported", true); - // Enable GMP support in the addon manager. pref("media.gmp-provider.enabled", true); diff --git a/browser/base/content/abouthome/aboutHome.css b/browser/base/content/abouthome/aboutHome.css index c0b02e257..bc3f9882c 100644 --- a/browser/base/content/abouthome/aboutHome.css +++ b/browser/base/content/abouthome/aboutHome.css @@ -49,8 +49,7 @@ a { background-repeat: no-repeat; } -#searchIconAndTextContainer, -#snippets { +#searchIconAndTextContainer { width: 470px; } @@ -168,48 +167,6 @@ a { transition-duration: 0ms; } -#defaultSnippet1, -#defaultSnippet2, -#rightsSnippet { - display: block; - min-height: 38px; - background: 0 center no-repeat; - padding: 6px 0; - padding-inline-start: 49px; -} - -#rightsSnippet[hidden] { - display: none; -} - -#defaultSnippet1:dir(rtl), -#defaultSnippet2:dir(rtl), -#rightsSnippet:dir(rtl) { - background-position: right 0 center; -} - -#defaultSnippet1 { - background-image: url("chrome://browser/content/abouthome/snippet1.png"); -} - -#defaultSnippet2 { - background-image: url("chrome://browser/content/abouthome/snippet2.png"); -} - -#snippets { - display: inline-block; - text-align: start; - margin: 12px 0; - color: #3c3c3c; - font-size: 75%; - /* 12px is the computed font size, 15px the computed line height of the snippets - with Segoe UI on a default Windows 7 setup. The 15/12 multiplier approximately - converts em from units of font-size to units of line-height. The goal is to - preset the height of a three-line snippet to avoid visual moving/flickering as - the snippets load. */ - min-height: calc(15/12 * 3em); -} - #launcher { display: -moz-box; -moz-box-align: center; @@ -385,20 +342,6 @@ body[narrow] #restorePreviousSession::before { background-image: url("chrome://branding/content/about-logo@2x.png"); } - #defaultSnippet1, - #defaultSnippet2, - #rightsSnippet { - background-size: 40px; - } - - #defaultSnippet1 { - background-image: url("chrome://browser/content/abouthome/snippet1@2x.png"); - } - - #defaultSnippet2 { - background-image: url("chrome://browser/content/abouthome/snippet2@2x.png"); - } - .launchButton::before, #aboutMozilla::before { transform: scale(.5); diff --git a/browser/base/content/abouthome/aboutHome.js b/browser/base/content/abouthome/aboutHome.js index 50f3e01cd..0cbcc835a 100644 --- a/browser/base/content/abouthome/aboutHome.js +++ b/browser/base/content/abouthome/aboutHome.js @@ -6,23 +6,10 @@ /* import-globals-from ../contentSearchUI.js */ -// The process of adding a new default snippet involves: -// * add a new entity to aboutHome.dtd -// * add a <span/> for it in aboutHome.xhtml -// * add an entry here in the proper ordering (based on spans) -// The <a/> part of the snippet will be linked to the corresponding url. -const DEFAULT_SNIPPETS_URLS = [ - "https://www.mozilla.org/firefox/features/?utm_source=snippet&utm_medium=snippet&utm_campaign=default+feature+snippet" -, "https://addons.mozilla.org/firefox/?utm_source=snippet&utm_medium=snippet&utm_campaign=addons" -]; - -const SNIPPETS_UPDATE_INTERVAL_MS = 14400000; // 4 hours. - // IndexedDB storage constants. const DATABASE_NAME = "abouthome"; const DATABASE_VERSION = 1; const DATABASE_STORAGE = "persistent"; -const SNIPPETS_OBJECTSTORE_NAME = "snippets"; var searchText; // This global tracks if the page has been set up before, to prevent double inits @@ -33,13 +20,6 @@ var gObserver = new MutationObserver(function (mutations) { if (mutation.attributeName == "session") { fitToWidth(); } - if (mutation.attributeName == "snippetsVersion") { - if (!gInitialized) { - ensureSnippetsMapThen(loadSnippets); - gInitialized = true; - } - return; - } } }); @@ -90,126 +70,6 @@ window.addEventListener("keypress", ev => { searchText.value += ev.key; }); -// This object has the same interface as Map and is used to store and retrieve -// the snippets data. It is lazily initialized by ensureSnippetsMapThen(), so -// be sure its callback returned before trying to use it. -var gSnippetsMap; -var gSnippetsMapCallbacks = []; - -/** - * Ensure the snippets map is properly initialized. - * - * @param aCallback - * Invoked once the map has been initialized, gets the map as argument. - * @note Snippets should never directly manage the underlying storage, since - * it may change inadvertently. - */ -function ensureSnippetsMapThen(aCallback) -{ - if (gSnippetsMap) { - aCallback(gSnippetsMap); - return; - } - - // Handle multiple requests during the async initialization. - gSnippetsMapCallbacks.push(aCallback); - if (gSnippetsMapCallbacks.length > 1) { - // We are already updating, the callbacks will be invoked when done. - return; - } - - let invokeCallbacks = function () { - if (!gSnippetsMap) { - gSnippetsMap = Object.freeze(new Map()); - } - - for (let callback of gSnippetsMapCallbacks) { - callback(gSnippetsMap); - } - gSnippetsMapCallbacks.length = 0; - } - - let openRequest = indexedDB.open(DATABASE_NAME, {version: DATABASE_VERSION, - storage: DATABASE_STORAGE}); - - openRequest.onerror = function (event) { - // Try to delete the old database so that we can start this process over - // next time. - indexedDB.deleteDatabase(DATABASE_NAME); - invokeCallbacks(); - }; - - openRequest.onupgradeneeded = function (event) { - let db = event.target.result; - if (!db.objectStoreNames.contains(SNIPPETS_OBJECTSTORE_NAME)) { - db.createObjectStore(SNIPPETS_OBJECTSTORE_NAME); - } - } - - openRequest.onsuccess = function (event) { - let db = event.target.result; - - db.onerror = function (event) { - invokeCallbacks(); - } - - db.onversionchange = function (event) { - event.target.close(); - invokeCallbacks(); - } - - let cache = new Map(); - let cursorRequest; - try { - cursorRequest = db.transaction(SNIPPETS_OBJECTSTORE_NAME) - .objectStore(SNIPPETS_OBJECTSTORE_NAME).openCursor(); - } catch (ex) { - console.error(ex); - invokeCallbacks(); - return; - } - - cursorRequest.onerror = function (event) { - invokeCallbacks(); - } - - cursorRequest.onsuccess = function(event) { - let cursor = event.target.result; - - // Populate the cache from the persistent storage. - if (cursor) { - cache.set(cursor.key, cursor.value); - cursor.continue(); - return; - } - - // The cache has been filled up, create the snippets map. - gSnippetsMap = Object.freeze({ - get: (aKey) => cache.get(aKey), - set: function (aKey, aValue) { - db.transaction(SNIPPETS_OBJECTSTORE_NAME, "readwrite") - .objectStore(SNIPPETS_OBJECTSTORE_NAME).put(aValue, aKey); - return cache.set(aKey, aValue); - }, - has: (aKey) => cache.has(aKey), - delete: function (aKey) { - db.transaction(SNIPPETS_OBJECTSTORE_NAME, "readwrite") - .objectStore(SNIPPETS_OBJECTSTORE_NAME).delete(aKey); - return cache.delete(aKey); - }, - clear: function () { - db.transaction(SNIPPETS_OBJECTSTORE_NAME, "readwrite") - .objectStore(SNIPPETS_OBJECTSTORE_NAME).clear(); - return cache.clear(); - }, - get size() { return cache.size; }, - }); - - setTimeout(invokeCallbacks, 0); - } - } -} - function onSearchSubmit(aEvent) { gContentSearchController.search(aEvent); @@ -246,146 +106,6 @@ function setupSearch() */ function loadCompleted() { - var event = new CustomEvent("AboutHomeLoadSnippetsCompleted", {bubbles:true}); - document.dispatchEvent(event); -} - -/** - * Update the local snippets from the remote storage, then show them through - * showSnippets. - */ -function loadSnippets() -{ - if (!gSnippetsMap) - throw new Error("Snippets map has not properly been initialized"); - - // Allow tests to modify the snippets map before using it. - var event = new CustomEvent("AboutHomeLoadSnippets", {bubbles:true}); - document.dispatchEvent(event); - - // Check cached snippets version. - let cachedVersion = gSnippetsMap.get("snippets-cached-version") || 0; - let currentVersion = document.documentElement.getAttribute("snippetsVersion"); - if (cachedVersion < currentVersion) { - // The cached snippets are old and unsupported, restart from scratch. - gSnippetsMap.clear(); - } - - // Check last snippets update. - let lastUpdate = gSnippetsMap.get("snippets-last-update"); - let updateURL = document.documentElement.getAttribute("snippetsURL"); - let shouldUpdate = !lastUpdate || - Date.now() - lastUpdate > SNIPPETS_UPDATE_INTERVAL_MS; - if (updateURL && shouldUpdate) { - // Try to update from network. - let xhr = new XMLHttpRequest(); - xhr.timeout = 5000; - // Even if fetching should fail we don't want to spam the server, thus - // set the last update time regardless its results. Will retry tomorrow. - gSnippetsMap.set("snippets-last-update", Date.now()); - xhr.onloadend = function (event) { - if (xhr.status == 200) { - gSnippetsMap.set("snippets", xhr.responseText); - gSnippetsMap.set("snippets-cached-version", currentVersion); - } - showSnippets(); - loadCompleted(); - }; - try { - xhr.open("GET", updateURL, true); - xhr.send(null); - } catch (ex) { - showSnippets(); - loadCompleted(); - return; - } - } else { - showSnippets(); - loadCompleted(); - } -} - -/** - * Shows locally cached remote snippets, or default ones when not available. - * - * @note: snippets should never invoke showSnippets(), or they may cause - * a "too much recursion" exception. - */ -var _snippetsShown = false; -function showSnippets() -{ - let snippetsElt = document.getElementById("snippets"); - - // Show about:rights notification, if needed. - let showRights = document.documentElement.getAttribute("showKnowYourRights"); - if (showRights) { - let rightsElt = document.getElementById("rightsSnippet"); - let anchor = rightsElt.getElementsByTagName("a")[0]; - anchor.href = "about:rights"; - snippetsElt.appendChild(rightsElt); - rightsElt.removeAttribute("hidden"); - return; - } - - if (!gSnippetsMap) - throw new Error("Snippets map has not properly been initialized"); - if (_snippetsShown) { - // There's something wrong with the remote snippets, just in case fall back - // to the default snippets. - showDefaultSnippets(); - throw new Error("showSnippets should never be invoked multiple times"); - } - _snippetsShown = true; - - let snippets = gSnippetsMap.get("snippets"); - // If there are remotely fetched snippets, try to to show them. - if (snippets) { - // Injecting snippets can throw if they're invalid XML. - try { - snippetsElt.innerHTML = snippets; - // Scripts injected by innerHTML are inactive, so we have to relocate them - // through DOM manipulation to activate their contents. - Array.forEach(snippetsElt.getElementsByTagName("script"), function(elt) { - let relocatedScript = document.createElement("script"); - relocatedScript.type = "text/javascript;version=1.8"; - relocatedScript.text = elt.text; - elt.parentNode.replaceChild(relocatedScript, elt); - }); - return; - } catch (ex) { - // Bad content, continue to show default snippets. - } - } - - showDefaultSnippets(); -} - -/** - * Clear snippets element contents and show default snippets. - */ -function showDefaultSnippets() -{ - // Clear eventual contents... - let snippetsElt = document.getElementById("snippets"); - snippetsElt.innerHTML = ""; - - // ...then show default snippets. - let defaultSnippetsElt = document.getElementById("defaultSnippets"); - let entries = defaultSnippetsElt.querySelectorAll("span"); - // Choose a random snippet. Assume there is always at least one. - let randIndex = Math.floor(Math.random() * entries.length); - let entry = entries[randIndex]; - // Inject url in the eventual link. - if (DEFAULT_SNIPPETS_URLS[randIndex]) { - let links = entry.getElementsByTagName("a"); - // Default snippets can have only one link, otherwise something is messed - // up in the translation. - if (links.length == 1) { - links[0].href = DEFAULT_SNIPPETS_URLS[randIndex]; - } - } - // Move the default snippet to the snippets element. - snippetsElt.appendChild(entry); } function fitToWidth() { diff --git a/browser/base/content/abouthome/aboutHome.xhtml b/browser/base/content/abouthome/aboutHome.xhtml index c288e732e..22bf2e7e8 100644 --- a/browser/base/content/abouthome/aboutHome.xhtml +++ b/browser/base/content/abouthome/aboutHome.xhtml @@ -46,15 +46,6 @@ <input id="searchSubmit" type="button" onclick="onSearchSubmit(event)" title="&contentSearchSubmit.tooltip;"/> </div> - - <div id="snippetContainer"> - <div id="defaultSnippets" hidden="true"> - <span id="defaultSnippet1">&abouthome.defaultSnippet1.v1;</span> - <span id="defaultSnippet2">&abouthome.defaultSnippet2.v1;</span> - </div> - <span id="rightsSnippet" hidden="true">&abouthome.rightsSnippet;</span> - <div id="snippets"/> - </div> </div> <div class="spacer"/> @@ -73,7 +64,5 @@ <button class="launchButton" id="restorePreviousSession">&historyRestoreLastSession.label;</button> </div> - <a id="aboutMozilla" href="https://www.mozilla.org/about/?utm_source=about-home&utm_medium=Referral" - aria-label="&abouthome.aboutMozilla.label;"/> </body> </html> diff --git a/browser/base/content/browser-context.inc b/browser/base/content/browser-context.inc index 51b14d152..3061cccdd 100644 --- a/browser/base/content/browser-context.inc +++ b/browser/base/content/browser-context.inc @@ -456,12 +456,14 @@ oncommand="gContextMenu.openPasswordManager();"/> </menupopup> </menu> +#ifdef MOZ_DEVTOOLS <menuseparator id="inspect-separator" hidden="true"/> <menuitem id="context-inspect" hidden="true" label="&inspectContextMenu.label;" accesskey="&inspectContextMenu.accesskey;" oncommand="gContextMenu.inspectNode();"/> +#endif <menuseparator id="context-media-eme-separator" hidden="true"/> <menuitem id="context-media-eme-learnmore" class="menuitem-iconic" diff --git a/browser/base/content/browser-places.js b/browser/base/content/browser-places.js index a447880be..83c737977 100644 --- a/browser/base/content/browser-places.js +++ b/browser/base/content/browser-places.js @@ -299,24 +299,23 @@ var StarUI = { parent.setAttribute("open", "true"); } } - let panel = this.panel; - let target = panel; - if (target.parentNode) { - // By targeting the panel's parent and using a capturing listener, we - // can have our listener called before others waiting for the panel to - // be shown (which probably expect the panel to be fully initialized) - target = target.parentNode; - } - target.addEventListener("popupshown", function shownListener(event) { - if (event.target == panel) { - target.removeEventListener("popupshown", shownListener, true); - - gEditItemOverlay.initPanel({ node: aNode - , hiddenRows: ["description", "location", - "loadInSidebar", "keyword"] - , focusedElement: "preferred"}); + let onPanelReady = fn => { + let target = this.panel; + if (target.parentNode) { + // By targeting the panel's parent and using a capturing listener, we + // can have our listener called before others waiting for the panel to + // be shown (which probably expect the panel to be fully initialized) + target = target.parentNode; } - }, true); + target.addEventListener("popupshown", function(event) { + fn(); + }, {"capture": true, "once": true}); + }; + gEditItemOverlay.initPanel({ node: aNode + , onPanelReady + , hiddenRows: ["description", "location", + "loadInSidebar", "keyword"] + , focusedElement: "preferred"}); this.panel.openPopup(aAnchorElement, aPosition); }), diff --git a/browser/base/content/browser-plugins.js b/browser/base/content/browser-plugins.js index ad070df12..c1bc65860 100644 --- a/browser/base/content/browser-plugins.js +++ b/browser/base/content/browser-plugins.js @@ -63,9 +63,7 @@ var gPluginHandler = { msg.data.pluginID); break; case "PluginContent:SubmitReport": - if (AppConstants.MOZ_CRASHREPORTER) { - this.submitReport(msg.data.runID, msg.data.keyVals, msg.data.submitURLOptIn); - } + // Nothing to do here break; case "PluginContent:LinkClickCallback": switch (msg.data.name) { @@ -98,11 +96,8 @@ var gPluginHandler = { }, submitReport: function submitReport(runID, keyVals, submitURLOptIn) { - if (!AppConstants.MOZ_CRASHREPORTER) { - return; - } - Services.prefs.setBoolPref("dom.ipc.plugins.reportCrashURL", submitURLOptIn); - PluginCrashReporter.submitCrashReport(runID, keyVals); + /*** STUB ***/ + return; }, // Callback for user clicking a "reload page" link @@ -461,18 +456,7 @@ var gPluginHandler = { // If we don't have a minidumpID, we can't (or didn't) submit anything. // This can happen if the plugin is killed from the task manager. - let state; - if (!AppConstants.MOZ_CRASHREPORTER || !gCrashReporter.enabled) { - // This state tells the user that crash reporting is disabled, so we - // cannot send a report. - state = "noSubmit"; - } else if (!pluginDumpID) { - // This state tells the user that there is no crash report available. - state = "noReport"; - } else { - // This state asks the user to submit a crash report. - state = "please"; - } + let state = "noSubmit"; let mm = window.getGroupMessageManager("browsers"); mm.broadcastAsyncMessage("BrowserPlugins:NPAPIPluginProcessCrashed", @@ -513,22 +497,6 @@ var gPluginHandler = { callback: function() { browser.reload(); }, }]; - if (AppConstants.MOZ_CRASHREPORTER && - PluginCrashReporter.hasCrashReport(pluginID)) { - let submitLabel = gNavigatorBundle.getString("crashedpluginsMessage.submitButton.label"); - let submitKey = gNavigatorBundle.getString("crashedpluginsMessage.submitButton.accesskey"); - let submitButton = { - label: submitLabel, - accessKey: submitKey, - popup: null, - callback: () => { - PluginCrashReporter.submitCrashReport(pluginID); - }, - }; - - buttons.push(submitButton); - } - notification = notificationBox.appendNotification(messageString, "plugin-crashed", iconURL, priority, buttons); diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index d41e94ae6..696a2871a 100755 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -53,19 +53,16 @@ Cu.import("resource://gre/modules/NotificationDB.jsm"); ["UpdateUtils", "resource://gre/modules/UpdateUtils.jsm"], ["Weave", "resource://services-sync/main.js"], ["fxAccounts", "resource://gre/modules/FxAccounts.jsm"], +#ifdef MOZ_DEVTOOLS + // Note: Do not delete! It is used for: base/content/nsContextMenu.js ["gDevTools", "resource://devtools/client/framework/gDevTools.jsm"], - ["gDevToolsBrowser", "resource://devtools/client/framework/gDevTools.jsm"], +#endif ["webrtcUI", "resource:///modules/webrtcUI.jsm", ] ].forEach(([name, resource]) => XPCOMUtils.defineLazyModuleGetter(this, name, resource)); XPCOMUtils.defineLazyModuleGetter(this, "SafeBrowsing", "resource://gre/modules/SafeBrowsing.jsm"); -if (AppConstants.MOZ_CRASHREPORTER) { - XPCOMUtils.defineLazyModuleGetter(this, "PluginCrashReporter", - "resource:///modules/ContentCrashHandlers.jsm"); -} - // lazy service getters [ ["Favicons", "@mozilla.org/browser/favicon-service;1", "mozIAsyncFavicons"], @@ -74,13 +71,6 @@ if (AppConstants.MOZ_CRASHREPORTER) { ["gDNSService", "@mozilla.org/network/dns-service;1", "nsIDNSService"], ].forEach(([name, cc, ci]) => XPCOMUtils.defineLazyServiceGetter(this, name, cc, ci)); -if (AppConstants.MOZ_CRASHREPORTER) { - XPCOMUtils.defineLazyServiceGetter(this, "gCrashReporter", - "@mozilla.org/xre/app-info;1", - "nsICrashReporter"); -} - - XPCOMUtils.defineLazyGetter(this, "BrowserToolboxProcess", function() { let tmp = {}; Cu.import("resource://devtools/client/framework/ToolboxProcess.jsm", tmp); @@ -214,7 +204,8 @@ var gInitialPages = [ "about:home", "about:privatebrowsing", "about:welcomeback", - "about:sessionrestore" + "about:sessionrestore", + "about:logopage" ]; function* browserWindows() { @@ -4582,23 +4573,6 @@ var XULBrowserWindow = { setTimeout(function () { XULBrowserWindow.asyncUpdateUI(); }, 0); else this.asyncUpdateUI(); - - if (AppConstants.MOZ_CRASHREPORTER && aLocationURI) { - let uri = aLocationURI.clone(); - try { - // If the current URI contains a username/password, remove it. - uri.userPass = ""; - } catch (ex) { /* Ignore failures on about: URIs. */ } - - try { - gCrashReporter.annotateCrashReport("URL", uri.spec); - } catch (ex) { - // Don't make noise when the crash reporter is built but not enabled. - if (ex.result != Components.results.NS_ERROR_NOT_INITIALIZED) { - throw ex; - } - } - } }, asyncUpdateUI: function () { @@ -7893,15 +7867,6 @@ var TabContextMenu = { } }; -Object.defineProperty(this, "HUDService", { - get: function HUDService_getter() { - let devtools = Cu.import("resource://devtools/shared/Loader.jsm", {}).devtools; - return devtools.require("devtools/client/webconsole/hudservice").HUDService; - }, - configurable: true, - enumerable: true -}); - // Prompt user to restart the browser in safe mode function safeModeRestart() { if (Services.appinfo.inSafeMode) { @@ -7959,30 +7924,6 @@ function duplicateTabIn(aTab, where, delta) { } } -var Scratchpad = { - openScratchpad: function SP_openScratchpad() { - return this.ScratchpadManager.openScratchpad(); - } -}; - -XPCOMUtils.defineLazyGetter(Scratchpad, "ScratchpadManager", function() { - let tmp = {}; - Cu.import("resource://devtools/client/scratchpad/scratchpad-manager.jsm", tmp); - return tmp.ScratchpadManager; -}); - -var ResponsiveUI = { - toggle: function RUI_toggle() { - this.ResponsiveUIManager.toggle(window, gBrowser.selectedTab); - } -}; - -XPCOMUtils.defineLazyGetter(ResponsiveUI, "ResponsiveUIManager", function() { - let tmp = {}; - Cu.import("resource://devtools/client/responsivedesign/responsivedesign.jsm", tmp); - return tmp.ResponsiveUIManager; -}); - var MousePosTracker = { _listeners: new Set(), _x: 0, diff --git a/browser/base/content/tab-content.js b/browser/base/content/tab-content.js index 05f8e00ab..7e803796a 100644 --- a/browser/base/content/tab-content.js +++ b/browser/base/content/tab-content.js @@ -147,13 +147,10 @@ var AboutHomeListener = { if (aData.showRestoreLastSession && !PrivateBrowsingUtils.isContentWindowPrivate(content)) doc.getElementById("launcher").setAttribute("session", "true"); - // Inject search engine and snippets URL. + // Inject search engine URL. let docElt = doc.documentElement; - // Set snippetsVersion last, which triggers to show the snippets when it's set. - docElt.setAttribute("snippetsURL", aData.snippetsURL); if (aData.showKnowYourRights) docElt.setAttribute("showKnowYourRights", "true"); - docElt.setAttribute("snippetsVersion", aData.snippetsVersion); }, onPageLoad: function() { diff --git a/browser/base/content/utilityOverlay.js b/browser/base/content/utilityOverlay.js index 833369f4d..0b703b6f8 100644 --- a/browser/base/content/utilityOverlay.js +++ b/browser/base/content/utilityOverlay.js @@ -35,7 +35,7 @@ var gBidiUI = false; * Determines whether the given url is considered a special URL for new tabs. */ function isBlankPageURL(aURL) { - return aURL == "about:blank" || aURL == BROWSER_NEW_TAB_URL; + return aURL == "about:blank" || aURL == "about:newtab" || aURL == "about:logopage"; } function getBrowserURL() diff --git a/browser/base/jar.mn b/browser/base/jar.mn index a65c77338..9cbfe7c15 100644 --- a/browser/base/jar.mn +++ b/browser/base/jar.mn @@ -67,7 +67,7 @@ browser.jar: content/browser/aboutTabCrashed.js (content/aboutTabCrashed.js) content/browser/aboutTabCrashed.xhtml (content/aboutTabCrashed.xhtml) * content/browser/browser.css (content/browser.css) - content/browser/browser.js (content/browser.js) +* content/browser/browser.js (content/browser.js) * content/browser/browser.xul (content/browser.xul) content/browser/browser-addons.js (content/browser-addons.js) content/browser/browser-captivePortal.js (content/browser-captivePortal.js) diff --git a/browser/branding/shared/preferences.inc b/browser/branding/shared/preferences.inc index 08f6c950b..90fd3da06 100644 --- a/browser/branding/shared/preferences.inc +++ b/browser/branding/shared/preferences.inc @@ -31,3 +31,5 @@ pref("browser.safebrowsing.downloads.remote.enabled", false); // Disable the UI controls for it as well for Basilisk-official. pref("browser.safebrowsing.UI.enabled", false); +// +pref("general.useragent.appVersionIsBuildID", true); diff --git a/browser/branding/unofficial/VisualElements_150.png b/browser/branding/unofficial/VisualElements_150.png Binary files differindex 461961e8d..eb74e4adc 100644 --- a/browser/branding/unofficial/VisualElements_150.png +++ b/browser/branding/unofficial/VisualElements_150.png diff --git a/browser/branding/unofficial/VisualElements_70.png b/browser/branding/unofficial/VisualElements_70.png Binary files differindex aad81f40d..571532a9b 100644 --- a/browser/branding/unofficial/VisualElements_70.png +++ b/browser/branding/unofficial/VisualElements_70.png diff --git a/browser/branding/unofficial/branding.nsi b/browser/branding/unofficial/branding.nsi index 34214453f..77f08a4cb 100644 --- a/browser/branding/unofficial/branding.nsi +++ b/browser/branding/unofficial/branding.nsi @@ -8,19 +8,19 @@ # BrandFullNameInternal is used for some registry and file system values # instead of BrandFullName and typically should not be modified. -!define BrandFullNameInternal "Mozilla Developer Preview" -!define CompanyName "mozilla.org" -!define URLInfoAbout "https://www.mozilla.org" -!define HelpLink "https://support.mozilla.org" +!define BrandFullNameInternal "Serpent" +!define CompanyName "Moonchild Productions" +!define URLInfoAbout "http://www.basilisk-browser.org" +!define HelpLink "https://forum.palemoon.org" -!define URLStubDownload "http://download.mozilla.org/?os=win&lang=${AB_CD}&product=firefox-latest" -!define URLManualDownload "https://www.mozilla.org/${AB_CD}/firefox/installer-help/?channel=release&installer_lang=${AB_CD}" -!define URLSystemRequirements "https://www.mozilla.org/firefox/system-requirements/" +!define URLStubDownload "" +!define URLManualDownload "" +!define URLSystemRequirements "" !define Channel "unofficial" # The installer's certificate name and issuer expected by the stub installer -!define CertNameDownload "Mozilla Corporation" -!define CertIssuerDownload "DigiCert SHA2 Assured ID Code Signing CA" +!define CertNameDownload "" +!define CertIssuerDownload "" # Dialog units are used so the UI displays correctly with the system's DPI # settings. diff --git a/browser/branding/unofficial/configure.sh b/browser/branding/unofficial/configure.sh index edd3bd3e8..ea4e37e45 100644 --- a/browser/branding/unofficial/configure.sh +++ b/browser/branding/unofficial/configure.sh @@ -2,4 +2,4 @@ # 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/. -MOZ_APP_DISPLAYNAME=Nightly +MOZ_APP_DISPLAYNAME=Serpent diff --git a/browser/branding/unofficial/content/about-background.png b/browser/branding/unofficial/content/about-background.png Binary files differindex 70eb8dafd..e36211b08 100644 --- a/browser/branding/unofficial/content/about-background.png +++ b/browser/branding/unofficial/content/about-background.png diff --git a/browser/branding/unofficial/content/about-logo.png b/browser/branding/unofficial/content/about-logo.png Binary files differindex 4c7214ba3..c5a838178 100644 --- a/browser/branding/unofficial/content/about-logo.png +++ b/browser/branding/unofficial/content/about-logo.png diff --git a/browser/branding/unofficial/content/about-logo@2x.png b/browser/branding/unofficial/content/about-logo@2x.png Binary files differindex 3526eda54..48c31564c 100644 --- a/browser/branding/unofficial/content/about-logo@2x.png +++ b/browser/branding/unofficial/content/about-logo@2x.png diff --git a/browser/branding/unofficial/content/about-wordmark.svg b/browser/branding/unofficial/content/about-wordmark.svg index 60b278d03..ce7a5c07b 100644 --- a/browser/branding/unofficial/content/about-wordmark.svg +++ b/browser/branding/unofficial/content/about-wordmark.svg @@ -1,22 +1,87 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- 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/. --> -<svg xmlns="http://www.w3.org/2000/svg" width="132px" height="48px" viewBox="0 0 132 48"> - <path fill="#fff" d="M60.6,14.3l-2.4-2.4C57,12.7,56,13,54.7,13c-3,0-3.8-1.4-7.6-1.4c-5.4,0-9.2,3.4-9.2,8.4 - c0,3.3,2.2,6.1,5.6,7.2c-3.4,1-4.5,2.2-4.5,4.3c0,2.2,1.8,3.6,4.7,3.6h3.8c2.5,0,3.9,0.2,4.9,0.9c0.9,0.6,1.4,1.6,1.4,3 - c0,3.1-2.2,4.4-6,4.4c-2,0-3.8-0.5-5.1-1.2c-0.9-0.6-1.5-1.6-1.5-2.9c0-0.8,0.3-1.7,0.7-2.2l-4.1,0.4c-0.3,1-0.5,1.7-0.5,2.6 - c0,3.5,3,6.4,10.8,6.4c6.1,0,9.9-2.5,9.9-7.9c0-2.1-0.8-3.9-2.7-5.3c-1.5-1.1-3.1-1.4-6-1.4h-4c-1.3,0-2-0.5-2-1.2 - c0-0.8,1.1-1.7,4.5-2.9c1.8,0,3.4-0.3,4.7-1.1c2.3-1.4,3.7-4.1,3.7-6.8c0-1.6-0.5-3-1.5-4.3c0.4,0.2,1.1,0.3,1.7,0.3 - C57.9,15.8,59,15.4,60.6,14.3z M47.1,24.8c-3.1,0-4.8-1.7-4.8-4.8c0-3.5,1.6-5.1,4.7-5.1c3.3,0,4.6,1.5,4.6,4.9 - C51.6,23.1,50.1,24.8,47.1,24.8z M30.7,1.3c-1.7,0-3,1.4-3,3.1s1.4,3,3,3c1.7,0,3.1-1.3,3.1-3C33.7,2.7,32.4,1.3,30.7,1.3z - M107.7,34.5c-1.1,0-1.4-0.6-1.4-2.5V6.5c0-3.8-0.6-5.9-0.6-5.9l-3.9,0.8c0,0,0.6,1.9,0.6,5.1v26.4c0,1.8,0.4,2.8,1.2,3.5 - c0.7,0.7,1.7,1,2.9,1c1,0,1.5-0.1,2.5-0.5l-0.8-2.5C108.2,34.4,107.8,34.5,107.7,34.5z M74.7,11.6c-3.2,0-6.1,1.8-8.3,3.9 - c0,0,0.2-1.8,0.2-3.4V6.3c0-3.8-0.7-5.9-0.7-5.9l-3.9,0.7c0,0,0.7,1.9,0.7,5.1V37h3.9V19.3c2.1-2.7,4.9-4.2,7.2-4.2 - c1.3,0,2.3,0.4,2.9,1c0.7,0.7,0.9,1.8,0.9,3.7V37h3.8V19.1c0-1.8-0.1-2.6-0.4-3.6C80.4,13.2,77.7,11.6,74.7,11.6z M127.4,12.1 - l-4.9,16.4c-0.6,2-1.6,5.2-1.6,5.2s-0.7-3.9-1.5-6.2l-5.1-16.2l-3.9,1.3l5.4,15.6c0.8,2.5,2.2,7.4,2.5,9l1.6-0.3 - c-1.3,5.1-2.5,6.7-5.7,7.6l1.2,2.7c4.4-1,6.4-4.3,8-9.3l8.6-25.8H127.4z M96.9,15l1.2-2.9h-6.2c0-3.3,0.5-7.2,0.5-7.2l-4.1,0.9 - c0,0-0.4,3.9-0.4,6.3h-3.2V15h3.2v17.1c0,2.5,0.7,4.1,2.4,5c0.9,0.4,1.9,0.7,3.3,0.7c1.8,0,3.1-0.4,4.4-1l-0.6-2.5 - c-0.7,0.3-1.3,0.5-2.4,0.5c-2.4,0-3.2-0.9-3.2-3.7V15H96.9z M28.6,37h4.1V11.5l-4.1,0.6V37z M18.9,21.3c0,5,0.4,10.5,0.4,10.5 - s-1.4-3.8-3.2-7.2L4.8,2.7H0V37h4.2L4,17.1c0-4.5-0.4-9.3-0.4-9.3s1.7,4.1,3.9,8.2l11,21h4.3V2.7h-4L18.9,21.3z"/> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="132px" + height="48px" + viewBox="0 0 132 48" + id="svg2" + version="1.1" + inkscape:version="0.91 r13725" + sodipodi:docname="about-wordmark.svg"> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1215" + inkscape:window-height="778" + id="namedview6" + showgrid="false" + inkscape:zoom="2.4090909" + inkscape:cx="91.154186" + inkscape:cy="24" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="0" + inkscape:current-layer="svg2" /> + <g + transform="scale(0.83939803,1.1913299)" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:42.56122971px;line-height:125%;font-family:'Levenim MT';-inkscape-font-specification:'Levenim MT';letter-spacing:0px;word-spacing:0px;fill:#a8e6db;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + id="text4138"> + <path + d="m 18.521413,24.115665 q 0,3.470569 -2.618513,5.881264 -2.535386,2.348349 -6.0475185,2.348349 -5.6942271,0 -9.22714164,-6.463156 L 3.2259712,24.323483 q 2.7432042,5.04999 6.3384644,5.04999 3.4082234,0 4.9460804,-2.639295 0.706583,-1.205347 0.706583,-2.556167 0,-1.537857 -1.039093,-3.013369 Q 12.827186,19.23193 9.1487985,16.488726 5.3872836,13.703958 4.1819363,12.082974 2.560952,9.9008792 2.560952,7.4070572 q 0,-4.2394975 3.6576056,-6.2345551 1.7248936,-0.93518331 3.761515,-0.93518331 4.3641884,0 8.0217944,5.00842591 L 15.508045,7.1368931 Q 14.115661,5.3080903 13.138914,4.5391618 11.684184,3.3961601 9.917727,3.3961601 q -1.7664573,0 -2.9510228,1.0598743 -1.246911,1.0806563 -1.246911,2.8263317 0,2.0574032 1.9327121,3.9693339 0.56111,0.540328 3.9485517,3.054932 3.117277,2.306785 4.655134,4.15637 2.265222,2.763986 2.265222,5.652663 z" + style="" + id="path4143" /> + <path + d="m 46.743165,20.499623 -20.324649,0 q 0.08313,3.803079 2.369131,6.338464 2.410694,2.660077 6.151427,2.660077 3.616042,0 6.130646,-2.202876 1.143002,-0.997529 2.47304,-3.221187 l 2.452259,1.288475 q -2.286004,4.468098 -6.338465,6.026737 -1.974275,0.768928 -4.468097,0.768928 -5.091554,0 -8.437432,-3.36666 -3.325096,-3.366659 -3.325096,-8.458213 0,-4.301843 2.639295,-7.668503 3.345878,-4.2810608 8.956978,-4.2810608 5.777354,0 9.227141,4.3849708 2.452259,3.117277 2.493822,7.730848 z M 43.54276,17.985019 q -1.080656,-4.301843 -4.634352,-5.964391 -1.828803,-0.852056 -3.844643,-0.852056 -3.325096,0 -5.715008,2.140531 -1.745676,1.558639 -2.639295,4.675916 l 16.833298,0 z" + style="" + id="path4145" /> + <path + d="m 62.516592,9.1527326 -1.517075,2.4522584 q -0.914401,-0.394855 -1.537857,-0.394855 -3.491351,0 -4.862953,4.904517 -0.540328,1.932712 -0.540328,7.813975 l 0,7.647721 -2.971805,0 0,-22.610653 2.971805,0 0,3.304314 q 2.639295,-3.8862058 5.881264,-3.8862058 1.205347,0 2.576949,0.7689284 z" + style="" + id="path4147" /> + <path + d="m 88.577029,20.208677 q 0,4.94608 -3.325096,8.416649 -3.366659,3.532915 -8.271176,3.532915 -5.382499,0 -9.060887,-4.468098 l 0,12.157383 -2.888677,0 0,-30.88183 2.888677,0 0,4.15637 q 3.449787,-4.7382618 8.977759,-4.7382618 4.883735,0 8.271177,3.4705688 3.408223,3.470569 3.408223,8.354304 z m -2.930241,0.103909 q 0,-2.410694 -1.205347,-4.572007 -1.205347,-2.161312 -3.283532,-3.345878 -2.057403,-1.205347 -4.48888,-1.205347 -3.865424,0 -6.421592,2.660077 -2.535385,2.660077 -2.535385,6.546283 0,5.403281 4.468097,7.897103 2.140531,1.205347 4.530444,1.205347 2.410694,0 4.488879,-1.246911 2.01584,-1.226129 3.221187,-3.387441 1.226129,-2.161313 1.226129,-4.551226 z" + style="" + id="path4149" /> + <path + d="m 116.23767,20.499623 -20.324647,0 q 0.08313,3.803079 2.36913,6.338464 2.410697,2.660077 6.151427,2.660077 3.61604,0 6.13065,-2.202876 1.143,-0.997529 2.47304,-3.221187 l 2.45226,1.288475 q -2.28601,4.468098 -6.33847,6.026737 -1.97427,0.768928 -4.4681,0.768928 -5.09155,0 -8.437428,-3.36666 -3.325096,-3.366659 -3.325096,-8.458213 0,-4.301843 2.639295,-7.668503 3.345878,-4.2810608 8.956979,-4.2810608 5.77735,0 9.22714,4.3849708 2.45226,3.117277 2.49382,7.730848 z m -3.2004,-2.514604 q -1.08066,-4.301843 -4.63436,-5.964391 -1.8288,-0.852056 -3.84464,-0.852056 -3.32509,0 -5.715007,2.140531 -1.745675,1.558639 -2.639295,4.675916 l 16.833302,0 z" + style="" + id="path4151" /> + <path + d="m 141.4045,31.576349 -2.88868,0 0,-10.78578 q 0,-3.823861 -0.33251,-5.216245 -1.08066,-4.509661 -5.69423,-4.509661 -2.63929,0 -4.73826,1.745675 -2.07819,1.724894 -2.7432,4.322625 -0.41564,1.641766 -0.41564,6.151428 l 0,8.291958 -2.90946,0 0,-22.610653 2.90946,0 0,4.052461 q 3.47057,-4.6343528 8.47899,-4.6343528 2.47304,0 4.44732,1.2676928 1.99506,1.246911 2.93024,3.470569 0.95597,2.202876 0.95597,6.816447 l 0,11.637836 z" + style="" + id="path4153" /> + <path + d="m 157.69747,11.459518 -4.61357,0 0,20.116831 -2.93024,0 0,-20.116831 -3.96934,0 0,-2.493822 3.96934,0 0,-8.3958676 2.93024,0 0,8.3958676 4.61357,0 0,2.493822 z" + style="" + id="path4155" /> + </g> </svg> diff --git a/browser/branding/unofficial/content/about.png b/browser/branding/unofficial/content/about.png Binary files differindex 231449344..e323c8df5 100644 --- a/browser/branding/unofficial/content/about.png +++ b/browser/branding/unofficial/content/about.png diff --git a/browser/branding/unofficial/content/icon48.png b/browser/branding/unofficial/content/icon48.png Binary files differindex 5fc7861e5..16e022a64 100644 --- a/browser/branding/unofficial/content/icon48.png +++ b/browser/branding/unofficial/content/icon48.png diff --git a/browser/branding/unofficial/content/icon64.png b/browser/branding/unofficial/content/icon64.png Binary files differindex 83f7016bc..9860917e3 100644 --- a/browser/branding/unofficial/content/icon64.png +++ b/browser/branding/unofficial/content/icon64.png diff --git a/browser/branding/unofficial/default16.png b/browser/branding/unofficial/default16.png Binary files differindex d285a90b4..67ef39df8 100644 --- a/browser/branding/unofficial/default16.png +++ b/browser/branding/unofficial/default16.png diff --git a/browser/branding/unofficial/default32.png b/browser/branding/unofficial/default32.png Binary files differindex 95adf2497..2f709e6b2 100644 --- a/browser/branding/unofficial/default32.png +++ b/browser/branding/unofficial/default32.png diff --git a/browser/branding/unofficial/default48.png b/browser/branding/unofficial/default48.png Binary files differindex d38185f54..02a1e14c1 100644 --- a/browser/branding/unofficial/default48.png +++ b/browser/branding/unofficial/default48.png diff --git a/browser/branding/unofficial/firefox.icns b/browser/branding/unofficial/firefox.icns Binary files differindex 0c6941acf..2c613634b 100644 --- a/browser/branding/unofficial/firefox.icns +++ b/browser/branding/unofficial/firefox.icns diff --git a/browser/branding/unofficial/firefox.ico b/browser/branding/unofficial/firefox.ico Binary files differindex 5217a6c0b..0c7acb61b 100644 --- a/browser/branding/unofficial/firefox.ico +++ b/browser/branding/unofficial/firefox.ico diff --git a/browser/branding/unofficial/locales/en-US/brand.dtd b/browser/branding/unofficial/locales/en-US/brand.dtd index cf4596ae0..17c243606 100644 --- a/browser/branding/unofficial/locales/en-US/brand.dtd +++ b/browser/branding/unofficial/locales/en-US/brand.dtd @@ -2,8 +2,9 @@ - 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/. --> -<!ENTITY brandShorterName "Nightly"> -<!ENTITY brandShortName "Nightly"> -<!ENTITY brandFullName "Nightly"> -<!ENTITY vendorShortName "Mozilla"> +<!ENTITY brandShorterName "Serpent"> +<!ENTITY brandShortName "Serpent"> +<!ENTITY brandFullName "Serpent"> +<!ENTITY vendorShortName "Moonchild"> +<!ENTITY vendorFullName "Moonchild Productions"> <!ENTITY trademarkInfo.part1 " "> diff --git a/browser/branding/unofficial/locales/en-US/brand.properties b/browser/branding/unofficial/locales/en-US/brand.properties index 8cd2c2ec9..80349f0e3 100644 --- a/browser/branding/unofficial/locales/en-US/brand.properties +++ b/browser/branding/unofficial/locales/en-US/brand.properties @@ -2,9 +2,10 @@ # 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/. -brandShorterName=Nightly -brandShortName=Nightly -brandFullName=Nightly -vendorShortName=Mozilla +brandShorterName=Serpent +brandShortName=Serpent +brandFullName=Serpent +vendorShortName=Moonchild +vendorFullName=Moonchild Productions syncBrandShortName=Sync diff --git a/browser/branding/unofficial/mozicon128.png b/browser/branding/unofficial/mozicon128.png Binary files differindex 471cf4645..739b61084 100644 --- a/browser/branding/unofficial/mozicon128.png +++ b/browser/branding/unofficial/mozicon128.png diff --git a/browser/branding/unofficial/basilisk.VisualElementsManifest.xml b/browser/branding/unofficial/serpent.VisualElementsManifest.xml index 7654e0ab7..5046ee7da 100644 --- a/browser/branding/unofficial/basilisk.VisualElementsManifest.xml +++ b/browser/branding/unofficial/serpent.VisualElementsManifest.xml @@ -4,5 +4,5 @@ Square150x150Logo='browser\VisualElements\VisualElements_150.png' Square70x70Logo='browser\VisualElements\VisualElements_70.png' ForegroundText='light' - BackgroundColor='#14171a'/> + BackgroundColor='#304D7E'/> </Application> diff --git a/browser/components/about/AboutRedirector.cpp b/browser/components/about/AboutRedirector.cpp index a09932d95..717ae9c48 100644 --- a/browser/components/about/AboutRedirector.cpp +++ b/browser/components/about/AboutRedirector.cpp @@ -35,75 +35,117 @@ struct RedirEntry { URI_SAFE_FOR_UNTRUSTED_CONTENT. */ static RedirEntry kRedirMap[] = { - { "blocked", "chrome://browser/content/blockedSite.xhtml", + { + "basilisk", "chrome://global/content/memoriam.xhtml", + nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | + nsIAboutModule::HIDE_FROM_ABOUTABOUT + }, + { + "blocked", "chrome://browser/content/blockedSite.xhtml", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | nsIAboutModule::URI_CAN_LOAD_IN_CHILD | nsIAboutModule::ALLOW_SCRIPT | - nsIAboutModule::HIDE_FROM_ABOUTABOUT }, - { "certerror", "chrome://browser/content/aboutNetError.xhtml", + nsIAboutModule::HIDE_FROM_ABOUTABOUT + }, + { + "certerror", "chrome://browser/content/aboutNetError.xhtml", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | nsIAboutModule::URI_CAN_LOAD_IN_CHILD | nsIAboutModule::ALLOW_SCRIPT | - nsIAboutModule::HIDE_FROM_ABOUTABOUT }, - { "socialerror", "chrome://browser/content/aboutSocialError.xhtml", + nsIAboutModule::HIDE_FROM_ABOUTABOUT + }, + { + "socialerror", "chrome://browser/content/aboutSocialError.xhtml", nsIAboutModule::ALLOW_SCRIPT | - nsIAboutModule::HIDE_FROM_ABOUTABOUT }, - { "providerdirectory", "chrome://browser/content/aboutProviderDirectory.xhtml", + nsIAboutModule::HIDE_FROM_ABOUTABOUT + }, + { + "providerdirectory", "chrome://browser/content/aboutProviderDirectory.xhtml", nsIAboutModule::ALLOW_SCRIPT | - nsIAboutModule::HIDE_FROM_ABOUTABOUT }, - { "tabcrashed", "chrome://browser/content/aboutTabCrashed.xhtml", + nsIAboutModule::HIDE_FROM_ABOUTABOUT + }, + { + "tabcrashed", "chrome://browser/content/aboutTabCrashed.xhtml", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | nsIAboutModule::ALLOW_SCRIPT | - nsIAboutModule::HIDE_FROM_ABOUTABOUT }, - { "feeds", "chrome://browser/content/feeds/subscribe.xhtml", + nsIAboutModule::HIDE_FROM_ABOUTABOUT + }, + { + "feeds", "chrome://browser/content/feeds/subscribe.xhtml", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | nsIAboutModule::ALLOW_SCRIPT | - nsIAboutModule::HIDE_FROM_ABOUTABOUT }, - { "privatebrowsing", "chrome://browser/content/aboutPrivateBrowsing.xhtml", + nsIAboutModule::HIDE_FROM_ABOUTABOUT + }, + { + "privatebrowsing", "chrome://browser/content/aboutPrivateBrowsing.xhtml", nsIAboutModule::URI_MUST_LOAD_IN_CHILD | - nsIAboutModule::ALLOW_SCRIPT }, - { "rights", - "chrome://global/content/aboutRights.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "rights", "chrome://global/content/aboutRights.xhtml", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | nsIAboutModule::MAKE_LINKABLE | - nsIAboutModule::ALLOW_SCRIPT }, - { "robots", "chrome://browser/content/aboutRobots.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "robots", "chrome://browser/content/aboutRobots.xhtml", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | - nsIAboutModule::ALLOW_SCRIPT }, - { "searchreset", "chrome://browser/content/search/searchReset.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "searchreset", "chrome://browser/content/search/searchReset.xhtml", nsIAboutModule::ALLOW_SCRIPT | - nsIAboutModule::HIDE_FROM_ABOUTABOUT }, - { "sessionrestore", "chrome://browser/content/aboutSessionRestore.xhtml", - nsIAboutModule::ALLOW_SCRIPT }, - { "welcomeback", "chrome://browser/content/aboutWelcomeBack.xhtml", - nsIAboutModule::ALLOW_SCRIPT }, - { "sync-tabs", "chrome://browser/content/sync/aboutSyncTabs.xul", - nsIAboutModule::ALLOW_SCRIPT }, - // Linkable because of indexeddb use (bug 1228118) + nsIAboutModule::HIDE_FROM_ABOUTABOUT + }, + { + "sessionrestore", "chrome://browser/content/aboutSessionRestore.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "welcomeback", "chrome://browser/content/aboutWelcomeBack.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "sync-tabs", "chrome://browser/content/sync/aboutSyncTabs.xul", + nsIAboutModule::ALLOW_SCRIPT + }, { "home", "chrome://browser/content/abouthome/aboutHome.xhtml", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | nsIAboutModule::URI_MUST_LOAD_IN_CHILD | nsIAboutModule::ALLOW_SCRIPT | + // Linkable because of indexeddb use (bug 1228118) nsIAboutModule::MAKE_LINKABLE | nsIAboutModule::ENABLE_INDEXED_DB }, - // the newtab's actual URL will be determined when the channel is created - { "newtab", "about:blank", - nsIAboutModule::ALLOW_SCRIPT }, - { "preferences", "chrome://browser/content/preferences/in-content/preferences.xul", - nsIAboutModule::ALLOW_SCRIPT }, - { "downloads", "chrome://browser/content/downloads/contentAreaDownloadsView.xul", - nsIAboutModule::ALLOW_SCRIPT }, + { + // the newtab's actual URL will be determined when the channel is created + "newtab", "about:blank", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "preferences", "chrome://browser/content/preferences/in-content/preferences.xul", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "downloads", "chrome://browser/content/downloads/contentAreaDownloadsView.xul", + nsIAboutModule::ALLOW_SCRIPT + }, #ifdef MOZ_SERVICES_HEALTHREPORT - { "healthreport", "chrome://browser/content/abouthealthreport/abouthealth.xhtml", - nsIAboutModule::ALLOW_SCRIPT }, + { + "healthreport", "chrome://browser/content/abouthealthreport/abouthealth.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, #endif - { "accounts", "chrome://browser/content/aboutaccounts/aboutaccounts.xhtml", - nsIAboutModule::ALLOW_SCRIPT }, - { "reader", "chrome://global/content/reader/aboutReader.html", + { + "accounts", "chrome://browser/content/aboutaccounts/aboutaccounts.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "reader", "chrome://global/content/reader/aboutReader.html", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | nsIAboutModule::ALLOW_SCRIPT | nsIAboutModule::URI_MUST_LOAD_IN_CHILD | - nsIAboutModule::HIDE_FROM_ABOUTABOUT }, + nsIAboutModule::HIDE_FROM_ABOUTABOUT + }, }; static const int kRedirTotal = ArrayLength(kRedirMap); diff --git a/browser/components/build/nsModule.cpp b/browser/components/build/nsModule.cpp index f85d8812c..1fad0ce68 100644 --- a/browser/components/build/nsModule.cpp +++ b/browser/components/build/nsModule.cpp @@ -85,6 +85,7 @@ static const mozilla::Module::ContractIDEntry kBrowserContracts[] = { { NS_SHELLSERVICE_CONTRACTID, &kNS_SHELLSERVICE_CID }, #endif { NS_FEEDSNIFFER_CONTRACTID, &kNS_FEEDSNIFFER_CID }, + { NS_ABOUT_MODULE_CONTRACTID_PREFIX "basilisk", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, { NS_ABOUT_MODULE_CONTRACTID_PREFIX "blocked", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, { NS_ABOUT_MODULE_CONTRACTID_PREFIX "certerror", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, { NS_ABOUT_MODULE_CONTRACTID_PREFIX "socialerror", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, diff --git a/browser/components/nsBrowserContentHandler.js b/browser/components/nsBrowserContentHandler.js index b366c3f81..74144fc1b 100644 --- a/browser/components/nsBrowserContentHandler.js +++ b/browser/components/nsBrowserContentHandler.js @@ -558,7 +558,7 @@ nsBrowserContentHandler.prototype = { if (overridePage && startPage && !willRestoreSession && !skipStartPage) return overridePage + "|" + startPage; - return overridePage || startPage || "about:blank"; + return overridePage || startPage || "about:blank" || "about:logopage"; }, get startPage() { diff --git a/browser/components/nsBrowserGlue.js b/browser/components/nsBrowserGlue.js index f97c173a0..448bb910d 100644 --- a/browser/components/nsBrowserGlue.js +++ b/browser/components/nsBrowserGlue.js @@ -70,15 +70,6 @@ XPCOMUtils.defineLazyServiceGetter(this, "AlertsService", "@mozilla.org/alerts-s ["webrtcUI", "resource:///modules/webrtcUI.jsm"], ].forEach(([name, resource]) => XPCOMUtils.defineLazyModuleGetter(this, name, resource)); -if (AppConstants.MOZ_CRASHREPORTER) { - XPCOMUtils.defineLazyModuleGetter(this, "PluginCrashReporter", - "resource:///modules/ContentCrashHandlers.jsm"); - XPCOMUtils.defineLazyModuleGetter(this, "UnsubmittedCrashHandler", - "resource:///modules/ContentCrashHandlers.jsm"); - XPCOMUtils.defineLazyModuleGetter(this, "CrashSubmit", - "resource://gre/modules/CrashSubmit.jsm"); -} - XPCOMUtils.defineLazyGetter(this, "gBrandBundle", function() { return Services.strings.createBundle('chrome://branding/locale/brand.properties'); }); @@ -710,10 +701,6 @@ BrowserGlue.prototype = { } TabCrashHandler.init(); - if (AppConstants.MOZ_CRASHREPORTER) { - PluginCrashReporter.init(); - UnsubmittedCrashHandler.init(); - } Services.obs.notifyObservers(null, "browser-ui-startup-complete", ""); }, diff --git a/browser/components/places/content/editBookmarkOverlay.js b/browser/components/places/content/editBookmarkOverlay.js index e26cfb138..d59f5c764 100644 --- a/browser/components/places/content/editBookmarkOverlay.js +++ b/browser/components/places/content/editBookmarkOverlay.js @@ -57,12 +57,14 @@ var gEditItemOverlay = { } } let focusedElement = aInitInfo.focusedElement; + let onPanelReady = aInitInfo.onPanelReady; return this._paneInfo = { itemId, itemGuid, isItem, isURI, uri, title, isBookmark, isFolderShortcut, isParentReadOnly, bulkTagging, uris, - visibleRows, postData, isTag, focusedElement }; + visibleRows, postData, isTag, focusedElement, + onPanelReady }; }, get initialized() { @@ -214,7 +216,8 @@ var gEditItemOverlay = { let { itemId, isItem, isURI, isBookmark, bulkTagging, uris, - visibleRows, focusedElement } = this._setPaneInfo(aInfo); + visibleRows, focusedElement, + onPanelReady } = this._setPaneInfo(aInfo); let showOrCollapse = (rowId, isAppropriateForInput, nameInHiddenRows = null) => { @@ -286,22 +289,34 @@ var gEditItemOverlay = { this._observersAdded = true; } - // The focusedElement possible values are: - // * preferred: focus the field that the user touched first the last - // time the pane was shown (either namePicker or tagsField) - // * first: focus the first non collapsed textbox - // Note: since all controls are collapsed by default, we don't get the - // default XUL dialog behavior, that selects the first control, so we set - // the focus explicitly. - let elt; - if (focusedElement === "preferred") { - elt = this._element(gPrefService.getCharPref("browser.bookmarks.editDialog.firstEditField")); - } else if (focusedElement === "first") { - elt = document.querySelector("textbox:not([collapsed=true])"); - } - if (elt) { - elt.focus(); - elt.select(); + let focusElement = () => { + // The focusedElement possible values are: + // * preferred: focus the field that the user touched first the last + // time the pane was shown (either namePicker or tagsField) + // * first: focus the first non collapsed textbox + // Note: since all controls are collapsed by default, we don't get the + // default XUL dialog behavior, that selects the first control, so we set + // the focus explicitly. + // Note: If focusedElement === "preferred", this file expects gPrefService + // to be defined in the global scope. + let elt; + if (focusedElement === "preferred") { + /* eslint-disable no-undef */ + elt = this._element(gPrefService.getCharPref("browser.bookmarks.editDialog.firstEditField")); + /* eslint-enable no-undef */ + } else if (focusedElement === "first") { + elt = document.querySelector("textbox:not([collapsed=true])"); + } + if (elt) { + elt.focus(); + elt.select(); + } + }; + + if (onPanelReady) { + onPanelReady(focusElement); + } else { + focusElement(); } }, @@ -335,10 +350,23 @@ var gEditItemOverlay = { if (aElement.value != aValue) { aElement.value = aValue; - // Clear the undo stack - let editor = aElement.editor; - if (editor) - editor.transactionManager.clear(); + // Clear the editor's undo stack + let transactionManager; + try { + transactionManager = aElement.editor.transactionManager; + } catch (e) { + // When retrieving the transaction manager, editor may be null resulting + // in a TypeError. Additionally, the transaction manager may not + // exist yet, which causes access to it to throw NS_ERROR_FAILURE. + // In either event, the transaction manager doesn't exist it, so we + // don't need to worry about clearing it. + if (!(e instanceof TypeError) && e.result != Cr.NS_ERROR_FAILURE) { + throw e; + } + } + if (transactionManager) { + transactionManager.clear(); + } } }, diff --git a/browser/components/preferences/in-content/advanced.js b/browser/components/preferences/in-content/advanced.js index 448a21dae..5f9458eee 100644 --- a/browser/components/preferences/in-content/advanced.js +++ b/browser/components/preferences/in-content/advanced.js @@ -40,9 +40,6 @@ var gAdvancedPane = { this.updateReadPrefs(); } this.updateOfflineApps(); - if (AppConstants.MOZ_CRASHREPORTER) { - this.initSubmitCrashes(); - } this.initTelemetry(); if (AppConstants.MOZ_TELEMETRY_REPORTING) { this.initSubmitHealthReport(); diff --git a/browser/components/preferences/in-content/advanced.xul b/browser/components/preferences/in-content/advanced.xul index facaaeaa9..4973f8e09 100644 --- a/browser/components/preferences/in-content/advanced.xul +++ b/browser/components/preferences/in-content/advanced.xul @@ -54,13 +54,6 @@ type="bool"/> #endif - <!-- Data Choices tab --> -#ifdef MOZ_CRASHREPORTER - <preference id="browser.crashReports.unsubmittedCheck.autoSubmit2" - name="browser.crashReports.unsubmittedCheck.autoSubmit2" - type="bool"/> -#endif - <!-- Network tab --> <preference id="browser.cache.disk.capacity" name="browser.cache.disk.capacity" @@ -233,22 +226,6 @@ </vbox> </groupbox> #endif -#ifdef MOZ_CRASHREPORTER - <groupbox> - <caption> - <checkbox id="automaticallySubmitCrashesBox" - preference="browser.crashReports.unsubmittedCheck.autoSubmit2" - label="&alwaysSubmitCrashReports.label;" - accesskey="&alwaysSubmitCrashReports.accesskey;"/> - </caption> - <hbox class="indent"> - <label flex="1">&crashReporterDesc2.label;</label> - <spacer flex="10"/> - <label id="crashReporterLearnMore" - class="text-link">&crashReporterLearnMore.label;</label> - </hbox> - </groupbox> -#endif </tabpanel> #endif diff --git a/browser/experiments/.eslintrc.js b/browser/experiments/.eslintrc.js deleted file mode 100644 index 1f6b11d67..000000000 --- a/browser/experiments/.eslintrc.js +++ /dev/null @@ -1,11 +0,0 @@ -"use strict"; - -module.exports = { - "rules": { - "no-unused-vars": ["error", { - "vars": "all", - "varsIgnorePattern": "^(Cc|Ci|Cr|Cu|EXPORTED_SYMBOLS)$", - "args": "none" - }] - } -}; diff --git a/browser/experiments/Experiments.jsm b/browser/experiments/Experiments.jsm deleted file mode 100644 index e9a63f19f..000000000 --- a/browser/experiments/Experiments.jsm +++ /dev/null @@ -1,2354 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -this.EXPORTED_SYMBOLS = [ - "Experiments", -]; - -const {classes: Cc, interfaces: Ci, utils: Cu} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/Task.jsm"); -Cu.import("resource://gre/modules/Promise.jsm"); -Cu.import("resource://gre/modules/osfile.jsm"); -Cu.import("resource://gre/modules/Log.jsm"); -Cu.import("resource://gre/modules/Preferences.jsm"); -Cu.import("resource://gre/modules/AsyncShutdown.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils", - "resource://gre/modules/UpdateUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "AddonManager", - "resource://gre/modules/AddonManager.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "AddonManagerPrivate", - "resource://gre/modules/AddonManager.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "TelemetryEnvironment", - "resource://gre/modules/TelemetryEnvironment.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "TelemetryLog", - "resource://gre/modules/TelemetryLog.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "TelemetryUtils", - "resource://gre/modules/TelemetryUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "CommonUtils", - "resource://services-common/utils.js"); - -XPCOMUtils.defineLazyServiceGetter(this, "gCrashReporter", - "@mozilla.org/xre/app-info;1", - "nsICrashReporter"); - -const FILE_CACHE = "experiments.json"; -const EXPERIMENTS_CHANGED_TOPIC = "experiments-changed"; -const MANIFEST_VERSION = 1; -const CACHE_VERSION = 1; - -const KEEP_HISTORY_N_DAYS = 180; - -const PREF_BRANCH = "experiments."; -const PREF_ENABLED = "enabled"; // experiments.enabled -const PREF_ACTIVE_EXPERIMENT = "activeExperiment"; // whether we have an active experiment -const PREF_LOGGING = "logging"; -const PREF_LOGGING_LEVEL = PREF_LOGGING + ".level"; // experiments.logging.level -const PREF_LOGGING_DUMP = PREF_LOGGING + ".dump"; // experiments.logging.dump -const PREF_MANIFEST_URI = "manifest.uri"; // experiments.logging.manifest.uri -const PREF_FORCE_SAMPLE = "force-sample-value"; // experiments.force-sample-value - -const PREF_BRANCH_TELEMETRY = "toolkit.telemetry."; -const PREF_TELEMETRY_ENABLED = "enabled"; - -const URI_EXTENSION_STRINGS = "chrome://mozapps/locale/extensions/extensions.properties"; -const STRING_TYPE_NAME = "type.%ID%.name"; - -const CACHE_WRITE_RETRY_DELAY_SEC = 60 * 3; -const MANIFEST_FETCH_TIMEOUT_MSEC = 60 * 3 * 1000; // 3 minutes - -const TELEMETRY_LOG = { - // log(key, [kind, experimentId, details]) - ACTIVATION_KEY: "EXPERIMENT_ACTIVATION", - ACTIVATION: { - // Successfully activated. - ACTIVATED: "ACTIVATED", - // Failed to install the add-on. - INSTALL_FAILURE: "INSTALL_FAILURE", - // Experiment does not meet activation requirements. Details will - // be provided. - REJECTED: "REJECTED", - }, - - // log(key, [kind, experimentId, optionalDetails...]) - TERMINATION_KEY: "EXPERIMENT_TERMINATION", - TERMINATION: { - // The Experiments service was disabled. - SERVICE_DISABLED: "SERVICE_DISABLED", - // Add-on uninstalled. - ADDON_UNINSTALLED: "ADDON_UNINSTALLED", - // The experiment disabled itself. - FROM_API: "FROM_API", - // The experiment expired (e.g. by exceeding the end date). - EXPIRED: "EXPIRED", - // Disabled after re-evaluating conditions. If this is specified, - // details will be provided. - RECHECK: "RECHECK", - }, -}; -XPCOMUtils.defineConstant(this, "TELEMETRY_LOG", TELEMETRY_LOG); - -const gPrefs = new Preferences(PREF_BRANCH); -const gPrefsTelemetry = new Preferences(PREF_BRANCH_TELEMETRY); -var gExperimentsEnabled = false; -var gAddonProvider = null; -var gExperiments = null; -var gLogAppenderDump = null; -var gPolicyCounter = 0; -var gExperimentsCounter = 0; -var gExperimentEntryCounter = 0; -var gPreviousProviderCounter = 0; - -// Tracks active AddonInstall we know about so we can deny external -// installs. -var gActiveInstallURLs = new Set(); - -// Tracks add-on IDs that are being uninstalled by us. This allows us -// to differentiate between expected uninstalled and user-driven uninstalls. -var gActiveUninstallAddonIDs = new Set(); - -var gLogger; -var gLogDumping = false; - -function configureLogging() { - if (!gLogger) { - gLogger = Log.repository.getLogger("Browser.Experiments"); - gLogger.addAppender(new Log.ConsoleAppender(new Log.BasicFormatter())); - } - gLogger.level = gPrefs.get(PREF_LOGGING_LEVEL, Log.Level.Warn); - - let logDumping = gPrefs.get(PREF_LOGGING_DUMP, false); - if (logDumping != gLogDumping) { - if (logDumping) { - gLogAppenderDump = new Log.DumpAppender(new Log.BasicFormatter()); - gLogger.addAppender(gLogAppenderDump); - } else { - gLogger.removeAppender(gLogAppenderDump); - gLogAppenderDump = null; - } - gLogDumping = logDumping; - } -} - -// Loads a JSON file using OS.file. file is a string representing the path -// of the file to be read, options contains additional options to pass to -// OS.File.read. -// Returns a Promise resolved with the json payload or rejected with -// OS.File.Error or JSON.parse() errors. -function loadJSONAsync(file, options) { - return Task.spawn(function*() { - let rawData = yield OS.File.read(file, options); - // Read json file into a string - let data; - try { - // Obtain a converter to read from a UTF-8 encoded input stream. - let converter = new TextDecoder(); - data = JSON.parse(converter.decode(rawData)); - } catch (ex) { - gLogger.error("Experiments: Could not parse JSON: " + file + " " + ex); - throw ex; - } - return data; - }); -} - -// Returns a promise that is resolved with the AddonInstall for that URL. -function addonInstallForURL(url, hash) { - let deferred = Promise.defer(); - AddonManager.getInstallForURL(url, install => deferred.resolve(install), - "application/x-xpinstall", hash); - return deferred.promise; -} - -// Returns a promise that is resolved with an Array<Addon> of the installed -// experiment addons. -function installedExperimentAddons() { - let deferred = Promise.defer(); - AddonManager.getAddonsByTypes(["experiment"], (addons) => { - deferred.resolve(addons.filter(a => !a.appDisabled)); - }); - return deferred.promise; -} - -// Takes an Array<Addon> and returns a promise that is resolved when the -// addons are uninstalled. -function uninstallAddons(addons) { - let ids = new Set(addons.map(addon => addon.id)); - let deferred = Promise.defer(); - - let listener = {}; - listener.onUninstalled = addon => { - if (!ids.has(addon.id)) { - return; - } - - ids.delete(addon.id); - if (ids.size == 0) { - AddonManager.removeAddonListener(listener); - deferred.resolve(); - } - }; - - AddonManager.addAddonListener(listener); - - for (let addon of addons) { - // Disabling the add-on before uninstalling is necessary to cause tests to - // pass. This might be indicative of a bug in XPIProvider. - // TODO follow up in bug 992396. - addon.userDisabled = true; - addon.uninstall(); - } - - return deferred.promise; -} - -/** - * The experiments module. - */ - -var Experiments = { - /** - * Provides access to the global `Experiments.Experiments` instance. - */ - instance: function () { - if (!gExperiments) { - gExperiments = new Experiments.Experiments(); - } - - return gExperiments; - }, -}; - -/* - * The policy object allows us to inject fake enviroment data from the - * outside by monkey-patching. - */ - -Experiments.Policy = function () { - this._log = Log.repository.getLoggerWithMessagePrefix( - "Browser.Experiments.Policy", - "Policy #" + gPolicyCounter++ + "::"); - - // Set to true to ignore hash verification on downloaded XPIs. This should - // not be used outside of testing. - this.ignoreHashes = false; -}; - -Experiments.Policy.prototype = { - now: function () { - return new Date(); - }, - - random: function () { - let pref = gPrefs.get(PREF_FORCE_SAMPLE); - if (pref !== undefined) { - let val = Number.parseFloat(pref); - this._log.debug("random sample forced: " + val); - if (isNaN(val) || val < 0) { - return 0; - } - if (val > 1) { - return 1; - } - return val; - } - return Math.random(); - }, - - futureDate: function (offset) { - return new Date(this.now().getTime() + offset); - }, - - oneshotTimer: function (callback, timeout, thisObj, name) { - return CommonUtils.namedTimer(callback, timeout, thisObj, name); - }, - - updatechannel: function () { - return UpdateUtils.UpdateChannel; - }, - - locale: function () { - let chrome = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry); - return chrome.getSelectedLocale("global"); - }, - - /** - * For testing a race condition, one of the tests delays the callback of - * writing the cache by replacing this policy function. - */ - delayCacheWrite: function(promise) { - return promise; - }, -}; - -function AlreadyShutdownError(message="already shut down") { - Error.call(this, message); - let error = new Error(); - this.name = "AlreadyShutdownError"; - this.message = message; - this.stack = error.stack; -} -AlreadyShutdownError.prototype = Object.create(Error.prototype); -AlreadyShutdownError.prototype.constructor = AlreadyShutdownError; - -function CacheWriteError(message="Error writing cache file") { - Error.call(this, message); - let error = new Error(); - this.name = "CacheWriteError"; - this.message = message; - this.stack = error.stack; -} -CacheWriteError.prototype = Object.create(Error.prototype); -CacheWriteError.prototype.constructor = CacheWriteError; - -/** - * Manages the experiments and provides an interface to control them. - */ - -Experiments.Experiments = function (policy=new Experiments.Policy()) { - let log = Log.repository.getLoggerWithMessagePrefix( - "Browser.Experiments.Experiments", - "Experiments #" + gExperimentsCounter++ + "::"); - - // At the time of this writing, Experiments.jsm has severe - // crashes. For forensics purposes, keep the last few log - // messages in memory and upload them in case of crash. - this._forensicsLogs = []; - this._forensicsLogs.length = 30; - this._log = Object.create(log); - this._log.log = (level, string, params) => { - this._addToForensicsLog("Experiments", string); - log.log(level, string, params); - }; - - this._log.trace("constructor"); - - // Capture the latest error, for forensics purposes. - this._latestError = null; - - - this._policy = policy; - - // This is a Map of (string -> ExperimentEntry), keyed with the experiment id. - // It holds both the current experiments and history. - // Map() preserves insertion order, which means we preserve the manifest order. - // This is null until we've successfully completed loading the cache from - // disk the first time. - this._experiments = null; - this._refresh = false; - this._terminateReason = null; // or TELEMETRY_LOG.TERMINATION.... - this._dirty = false; - - // Loading the cache happens once asynchronously on startup - this._loadTask = null; - - // The _main task handles all other actions: - // * refreshing the manifest off the network (if _refresh) - // * disabling/enabling experiments - // * saving the cache (if _dirty) - this._mainTask = null; - - // Timer for re-evaluating experiment status. - this._timer = null; - - this._shutdown = false; - this._networkRequest = null; - - // We need to tell when we first evaluated the experiments to fire an - // experiments-changed notification when we only loaded completed experiments. - this._firstEvaluate = true; - - this.init(); -}; - -Experiments.Experiments.prototype = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsITimerCallback, Ci.nsIObserver]), - - /** - * `true` if the experiments manager is currently setup (has been fully initialized - * and not uninitialized yet). - */ - get isReady() { - return !this._shutdown; - }, - - init: function () { - this._shutdown = false; - configureLogging(); - - gExperimentsEnabled = gPrefs.get(PREF_ENABLED, false) && TelemetryUtils.isTelemetryEnabled; - this._log.trace("enabled=" + gExperimentsEnabled + ", " + this.enabled); - - gPrefs.observe(PREF_LOGGING, configureLogging); - gPrefs.observe(PREF_MANIFEST_URI, this.updateManifest, this); - gPrefs.observe(PREF_ENABLED, this._toggleExperimentsEnabled, this); - - gPrefsTelemetry.observe(PREF_TELEMETRY_ENABLED, this._telemetryStatusChanged, this); - - AddonManager.shutdown.addBlocker("Experiments.jsm shutdown", - this.uninit.bind(this), - this._getState.bind(this) - ); - - this._registerWithAddonManager(); - - this._loadTask = this._loadFromCache(); - - return this._loadTask.then( - () => { - this._log.trace("_loadTask finished ok"); - this._loadTask = null; - return this._run(); - }, - (e) => { - this._log.error("_loadFromCache caught error: " + e); - this._latestError = e; - throw e; - } - ); - }, - - /** - * Uninitialize this instance. - * - * This function is susceptible to race conditions. If it is called multiple - * times before the previous uninit() has completed or if it is called while - * an init() operation is being performed, the object may get in bad state - * and/or deadlock could occur. - * - * @return Promise<> - * The promise is fulfilled when all pending tasks are finished. - */ - uninit: Task.async(function* () { - this._log.trace("uninit: started"); - yield this._loadTask; - this._log.trace("uninit: finished with _loadTask"); - - if (!this._shutdown) { - this._log.trace("uninit: no previous shutdown"); - this._unregisterWithAddonManager(); - - gPrefs.ignore(PREF_LOGGING, configureLogging); - gPrefs.ignore(PREF_MANIFEST_URI, this.updateManifest, this); - gPrefs.ignore(PREF_ENABLED, this._toggleExperimentsEnabled, this); - - gPrefsTelemetry.ignore(PREF_TELEMETRY_ENABLED, this._telemetryStatusChanged, this); - - if (this._timer) { - this._timer.clear(); - } - } - - this._shutdown = true; - if (this._mainTask) { - if (this._networkRequest) { - try { - this._log.trace("Aborting pending network request: " + this._networkRequest); - this._networkRequest.abort(); - } catch (e) { - // pass - } - } - try { - this._log.trace("uninit: waiting on _mainTask"); - yield this._mainTask; - } catch (e) { - // We error out of tasks after shutdown via this exception. - this._log.trace(`uninit: caught error - ${e}`); - if (!(e instanceof AlreadyShutdownError)) { - this._latestError = e; - throw e; - } - } - } - - this._log.info("Completed uninitialization."); - }), - - // Return state information, for debugging purposes. - _getState: function() { - let activeExperiment = this._getActiveExperiment(); - let state = { - isShutdown: this._shutdown, - isEnabled: gExperimentsEnabled, - isRefresh: this._refresh, - isDirty: this._dirty, - isFirstEvaluate: this._firstEvaluate, - hasLoadTask: !!this._loadTask, - hasMainTask: !!this._mainTask, - hasTimer: !!this._hasTimer, - hasAddonProvider: !!gAddonProvider, - latestLogs: this._forensicsLogs, - experiments: this._experiments ? [...this._experiments.keys()] : null, - terminateReason: this._terminateReason, - activeExperiment: activeExperiment ? activeExperiment.id : null, - }; - if (this._latestError) { - if (typeof this._latestError == "object") { - state.latestError = { - message: this._latestError.message, - stack: this._latestError.stack - }; - } else { - state.latestError = "" + this._latestError; - } - } - return state; - }, - - _addToForensicsLog: function (what, string) { - this._forensicsLogs.shift(); - let timeInSec = Math.floor(Services.telemetry.msSinceProcessStart() / 1000); - this._forensicsLogs.push(`${timeInSec}: ${what} - ${string}`); - }, - - _registerWithAddonManager: function (previousExperimentsProvider) { - this._log.trace("Registering instance with Addon Manager."); - - AddonManager.addAddonListener(this); - AddonManager.addInstallListener(this); - - if (!gAddonProvider) { - // The properties of this AddonType should be kept in sync with the - // experiment AddonType registered in XPIProvider. - this._log.trace("Registering previous experiment add-on provider."); - gAddonProvider = previousExperimentsProvider || new Experiments.PreviousExperimentProvider(this); - AddonManagerPrivate.registerProvider(gAddonProvider, [ - new AddonManagerPrivate.AddonType("experiment", - URI_EXTENSION_STRINGS, - STRING_TYPE_NAME, - AddonManager.VIEW_TYPE_LIST, - 11000, - AddonManager.TYPE_UI_HIDE_EMPTY), - ]); - } - - }, - - _unregisterWithAddonManager: function () { - this._log.trace("Unregistering instance with Addon Manager."); - - this._log.trace("Removing install listener from add-on manager."); - AddonManager.removeInstallListener(this); - this._log.trace("Removing addon listener from add-on manager."); - AddonManager.removeAddonListener(this); - this._log.trace("Finished unregistering with addon manager."); - - if (gAddonProvider) { - this._log.trace("Unregistering previous experiment add-on provider."); - AddonManagerPrivate.unregisterProvider(gAddonProvider); - gAddonProvider = null; - } - }, - - /* - * Change the PreviousExperimentsProvider that this instance uses. - * For testing only. - */ - _setPreviousExperimentsProvider: function (provider) { - this._unregisterWithAddonManager(); - this._registerWithAddonManager(provider); - }, - - /** - * Throws an exception if we've already shut down. - */ - _checkForShutdown: function() { - if (this._shutdown) { - throw new AlreadyShutdownError("uninit() already called"); - } - }, - - /** - * Whether the experiments feature is enabled. - */ - get enabled() { - return gExperimentsEnabled; - }, - - /** - * Toggle whether the experiments feature is enabled or not. - */ - set enabled(enabled) { - this._log.trace("set enabled(" + enabled + ")"); - gPrefs.set(PREF_ENABLED, enabled); - }, - - _toggleExperimentsEnabled: Task.async(function* (enabled) { - this._log.trace("_toggleExperimentsEnabled(" + enabled + ")"); - let wasEnabled = gExperimentsEnabled; - gExperimentsEnabled = enabled && TelemetryUtils.isTelemetryEnabled; - - if (wasEnabled == gExperimentsEnabled) { - return; - } - - if (gExperimentsEnabled) { - yield this.updateManifest(); - } else { - yield this.disableExperiment(TELEMETRY_LOG.TERMINATION.SERVICE_DISABLED); - if (this._timer) { - this._timer.clear(); - } - } - }), - - _telemetryStatusChanged: function () { - this._toggleExperimentsEnabled(gExperimentsEnabled); - }, - - /** - * Returns a promise that is resolved with an array of `ExperimentInfo` objects, - * which provide info on the currently and recently active experiments. - * The array is in chronological order. - * - * The experiment info is of the form: - * { - * id: <string>, - * name: <string>, - * description: <string>, - * active: <boolean>, - * endDate: <integer>, // epoch ms - * detailURL: <string>, - * ... // possibly extended later - * } - * - * @return Promise<Array<ExperimentInfo>> Array of experiment info objects. - */ - getExperiments: function () { - return Task.spawn(function*() { - yield this._loadTask; - let list = []; - - for (let [id, experiment] of this._experiments) { - if (!experiment.startDate) { - // We only collect experiments that are or were active. - continue; - } - - list.push({ - id: id, - name: experiment._name, - description: experiment._description, - active: experiment.enabled, - endDate: experiment.endDate.getTime(), - detailURL: experiment._homepageURL, - branch: experiment.branch, - }); - } - - // Sort chronologically, descending. - list.sort((a, b) => b.endDate - a.endDate); - return list; - }.bind(this)); - }, - - /** - * Returns the ExperimentInfo for the active experiment, or null - * if there is none. - */ - getActiveExperiment: function () { - let experiment = this._getActiveExperiment(); - if (!experiment) { - return null; - } - - let info = { - id: experiment.id, - name: experiment._name, - description: experiment._description, - active: experiment.enabled, - endDate: experiment.endDate.getTime(), - detailURL: experiment._homepageURL, - }; - - return info; - }, - - /** - * Experiment "branch" support. If an experiment has multiple branches, it - * can record the branch with the experiment system and it will - * automatically be included in data reporting (FHR/telemetry payloads). - */ - - /** - * Set the experiment branch for the specified experiment ID. - * @returns Promise<> - */ - setExperimentBranch: Task.async(function*(id, branchstr) { - yield this._loadTask; - let e = this._experiments.get(id); - if (!e) { - throw new Error("Experiment not found"); - } - e.branch = String(branchstr); - this._log.trace("setExperimentBranch(" + id + ", " + e.branch + ") _dirty=" + this._dirty); - this._dirty = true; - Services.obs.notifyObservers(null, EXPERIMENTS_CHANGED_TOPIC, null); - yield this._run(); - }), - /** - * Get the branch of the specified experiment. If the experiment is unknown, - * throws an error. - * - * @param id The ID of the experiment. Pass null for the currently running - * experiment. - * @returns Promise<string|null> - * @throws Error if the specified experiment ID is unknown, or if there is no - * current experiment. - */ - getExperimentBranch: Task.async(function*(id=null) { - yield this._loadTask; - let e; - if (id) { - e = this._experiments.get(id); - if (!e) { - throw new Error("Experiment not found"); - } - } else { - e = this._getActiveExperiment(); - if (e === null) { - throw new Error("No active experiment"); - } - } - return e.branch; - }), - - /** - * Determine whether another date has the same UTC day as now(). - */ - _dateIsTodayUTC: function (d) { - let now = this._policy.now(); - - return stripDateToMidnight(now).getTime() == stripDateToMidnight(d).getTime(); - }, - - /** - * Obtain the entry of the most recent active experiment that was active - * today. - * - * If no experiment was active today, this resolves to nothing. - * - * Assumption: Only a single experiment can be active at a time. - * - * @return Promise<object> - */ - lastActiveToday: function () { - return Task.spawn(function* getMostRecentActiveExperimentTask() { - let experiments = yield this.getExperiments(); - - // Assumption: Ordered chronologically, descending, with active always - // first. - for (let experiment of experiments) { - if (experiment.active) { - return experiment; - } - - if (experiment.endDate && this._dateIsTodayUTC(experiment.endDate)) { - return experiment; - } - } - return null; - }.bind(this)); - }, - - _run: function() { - this._log.trace("_run"); - this._checkForShutdown(); - if (!this._mainTask) { - this._mainTask = Task.spawn(function*() { - try { - yield this._main(); - } catch (e) { - // In the CacheWriteError case we want to reschedule - if (!(e instanceof CacheWriteError)) { - this._log.error("_main caught error: " + e); - return; - } - } finally { - this._mainTask = null; - } - this._log.trace("_main finished, scheduling next run"); - try { - yield this._scheduleNextRun(); - } catch (ex) { - // We error out of tasks after shutdown via this exception. - if (!(ex instanceof AlreadyShutdownError)) { - throw ex; - } - } - }.bind(this)); - } - return this._mainTask; - }, - - _main: function*() { - do { - this._log.trace("_main iteration"); - yield this._loadTask; - if (!gExperimentsEnabled) { - this._refresh = false; - } - - if (this._refresh) { - yield this._loadManifest(); - } - yield this._evaluateExperiments(); - if (this._dirty) { - yield this._saveToCache(); - } - // If somebody called .updateManifest() or disableExperiment() - // while we were running, go again right now. - } - while (this._refresh || this._terminateReason || this._dirty); - }, - - _loadManifest: function*() { - this._log.trace("_loadManifest"); - let uri = Services.urlFormatter.formatURLPref(PREF_BRANCH + PREF_MANIFEST_URI); - - this._checkForShutdown(); - - this._refresh = false; - try { - let responseText = yield this._httpGetRequest(uri); - this._log.trace("_loadManifest() - responseText=\"" + responseText + "\""); - - if (this._shutdown) { - return; - } - - let data = JSON.parse(responseText); - this._updateExperiments(data); - } catch (e) { - this._log.error("_loadManifest - failure to fetch/parse manifest (continuing anyway): " + e); - } - }, - - /** - * Fetch an updated list of experiments and trigger experiment updates. - * Do only use when experiments are enabled. - * - * @return Promise<> - * The promise is resolved when the manifest and experiment list is updated. - */ - updateManifest: function () { - this._log.trace("updateManifest()"); - - if (!gExperimentsEnabled) { - return Promise.reject(new Error("experiments are disabled")); - } - - if (this._shutdown) { - return Promise.reject(Error("uninit() alrady called")); - } - - this._refresh = true; - return this._run(); - }, - - notify: function (timer) { - this._log.trace("notify()"); - this._checkForShutdown(); - return this._run(); - }, - - // START OF ADD-ON LISTENERS - - onUninstalled: function (addon) { - this._log.trace("onUninstalled() - addon id: " + addon.id); - if (gActiveUninstallAddonIDs.has(addon.id)) { - this._log.trace("matches pending uninstall"); - return; - } - let activeExperiment = this._getActiveExperiment(); - if (!activeExperiment || activeExperiment._addonId != addon.id) { - return; - } - - this.disableExperiment(TELEMETRY_LOG.TERMINATION.ADDON_UNINSTALLED); - }, - - /** - * @returns {Boolean} returns false when we cancel the install. - */ - onInstallStarted: function (install) { - if (install.addon.type != "experiment") { - return true; - } - - this._log.trace("onInstallStarted() - " + install.addon.id); - if (install.addon.appDisabled) { - // This is a PreviousExperiment - return true; - } - - // We want to be in control of all experiment add-ons: reject installs - // for add-ons that we don't know about. - - // We have a race condition of sorts to worry about here. We have 2 - // onInstallStarted listeners. This one (the global one) and the one - // created as part of ExperimentEntry._installAddon. Because of the order - // they are registered in, this one likely executes first. Unfortunately, - // this means that the add-on ID is not yet set on the ExperimentEntry. - // So, we can't just look at this._trackedAddonIds because the new experiment - // will have its add-on ID set to null. We work around this by storing a - // identifying field - the source URL of the install - in a module-level - // variable (so multiple Experiments instances doesn't cancel each other - // out). - - if (this._trackedAddonIds.has(install.addon.id)) { - this._log.info("onInstallStarted allowing install because add-on ID " + - "tracked by us."); - return true; - } - - if (gActiveInstallURLs.has(install.sourceURI.spec)) { - this._log.info("onInstallStarted allowing install because install " + - "tracked by us."); - return true; - } - - this._log.warn("onInstallStarted cancelling install of unknown " + - "experiment add-on: " + install.addon.id); - return false; - }, - - // END OF ADD-ON LISTENERS. - - _getExperimentByAddonId: function (addonId) { - for (let [, entry] of this._experiments) { - if (entry._addonId === addonId) { - return entry; - } - } - - return null; - }, - - /* - * Helper function to make HTTP GET requests. Returns a promise that is resolved with - * the responseText when the request is complete. - */ - _httpGetRequest: function (url) { - this._log.trace("httpGetRequest(" + url + ")"); - let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest); - - this._networkRequest = xhr; - let deferred = Promise.defer(); - - let log = this._log; - let errorhandler = (evt) => { - log.error("httpGetRequest::onError() - Error making request to " + url + ": " + evt.type); - deferred.reject(new Error("Experiments - XHR error for " + url + " - " + evt.type)); - this._networkRequest = null; - }; - xhr.onerror = errorhandler; - xhr.ontimeout = errorhandler; - xhr.onabort = errorhandler; - - xhr.onload = (event) => { - if (xhr.status !== 200 && xhr.state !== 0) { - log.error("httpGetRequest::onLoad() - Request to " + url + " returned status " + xhr.status); - deferred.reject(new Error("Experiments - XHR status for " + url + " is " + xhr.status)); - this._networkRequest = null; - return; - } - - deferred.resolve(xhr.responseText); - this._networkRequest = null; - }; - - try { - xhr.open("GET", url); - - if (xhr.channel instanceof Ci.nsISupportsPriority) { - xhr.channel.priority = Ci.nsISupportsPriority.PRIORITY_LOWEST; - } - - xhr.timeout = MANIFEST_FETCH_TIMEOUT_MSEC; - xhr.send(null); - } catch (e) { - this._log.error("httpGetRequest() - Error opening request to " + url + ": " + e); - return Promise.reject(new Error("Experiments - Error opening XHR for " + url)); - } - return deferred.promise; - }, - - /* - * Path of the cache file we use in the profile. - */ - get _cacheFilePath() { - return OS.Path.join(OS.Constants.Path.profileDir, FILE_CACHE); - }, - - /* - * Part of the main task to save the cache to disk, called from _main. - */ - _saveToCache: function* () { - this._log.trace("_saveToCache"); - let path = this._cacheFilePath; - this._dirty = false; - try { - let textData = JSON.stringify({ - version: CACHE_VERSION, - data: [...this._experiments.values()].map(e => e.toJSON()), - }); - - let encoder = new TextEncoder(); - let data = encoder.encode(textData); - let options = { tmpPath: path + ".tmp", compression: "lz4" }; - yield this._policy.delayCacheWrite(OS.File.writeAtomic(path, data, options)); - } catch (e) { - // We failed to write the cache, it's still dirty. - this._dirty = true; - this._log.error("_saveToCache failed and caught error: " + e); - throw new CacheWriteError(); - } - - this._log.debug("_saveToCache saved to " + path); - }, - - /* - * Task function, load the cached experiments manifest file from disk. - */ - _loadFromCache: Task.async(function* () { - this._log.trace("_loadFromCache"); - let path = this._cacheFilePath; - try { - let result = yield loadJSONAsync(path, { compression: "lz4" }); - this._populateFromCache(result); - } catch (e) { - if (e instanceof OS.File.Error && e.becauseNoSuchFile) { - // No cached manifest yet. - this._experiments = new Map(); - } else { - throw e; - } - } - }), - - _populateFromCache: function (data) { - this._log.trace("populateFromCache() - data: " + JSON.stringify(data)); - - // If the user has a newer cache version than we can understand, we fail - // hard; no experiments should be active in this older client. - if (CACHE_VERSION !== data.version) { - throw new Error("Experiments::_populateFromCache() - invalid cache version"); - } - - let experiments = new Map(); - for (let item of data.data) { - let entry = new Experiments.ExperimentEntry(this._policy); - if (!entry.initFromCacheData(item)) { - continue; - } - - // Discard old experiments if they ended more than 180 days ago. - if (entry.shouldDiscard()) { - // We discarded an experiment, the cache needs to be updated. - this._dirty = true; - continue; - } - - experiments.set(entry.id, entry); - } - - this._experiments = experiments; - }, - - /* - * Update the experiment entries from the experiments - * array in the manifest - */ - _updateExperiments: function (manifestObject) { - this._log.trace("_updateExperiments() - experiments: " + JSON.stringify(manifestObject)); - - if (manifestObject.version !== MANIFEST_VERSION) { - this._log.warning("updateExperiments() - unsupported version " + manifestObject.version); - } - - let experiments = new Map(); // The new experiments map - - // Collect new and updated experiments. - for (let data of manifestObject.experiments) { - let entry = this._experiments.get(data.id); - - if (entry) { - if (!entry.updateFromManifestData(data)) { - this._log.error("updateExperiments() - Invalid manifest data for " + data.id); - continue; - } - } else { - entry = new Experiments.ExperimentEntry(this._policy); - if (!entry.initFromManifestData(data)) { - continue; - } - } - - if (entry.shouldDiscard()) { - continue; - } - - experiments.set(entry.id, entry); - } - - // Make sure we keep experiments that are or were running. - // We remove them after KEEP_HISTORY_N_DAYS. - for (let [id, entry] of this._experiments) { - if (experiments.has(id)) { - continue; - } - - if (!entry.startDate || entry.shouldDiscard()) { - this._log.trace("updateExperiments() - discarding entry for " + id); - continue; - } - - experiments.set(id, entry); - } - - this._experiments = experiments; - this._dirty = true; - }, - - getActiveExperimentID: function() { - if (!this._experiments) { - return null; - } - let e = this._getActiveExperiment(); - if (!e) { - return null; - } - return e.id; - }, - - getActiveExperimentBranch: function() { - if (!this._experiments) { - return null; - } - let e = this._getActiveExperiment(); - if (!e) { - return null; - } - return e.branch; - }, - - _getActiveExperiment: function () { - let enabled = [...this._experiments.values()].filter(experiment => experiment._enabled); - - if (enabled.length == 1) { - return enabled[0]; - } - - if (enabled.length > 1) { - this._log.error("getActiveExperimentId() - should not have more than 1 active experiment"); - throw new Error("have more than 1 active experiment"); - } - - return null; - }, - - /** - * Disables all active experiments. - * - * @return Promise<> Promise that will get resolved once the task is done or failed. - */ - disableExperiment: function (reason) { - if (!reason) { - throw new Error("Must specify a termination reason."); - } - - this._log.trace("disableExperiment()"); - this._terminateReason = reason; - return this._run(); - }, - - /** - * The Set of add-on IDs that we know about from manifests. - */ - get _trackedAddonIds() { - if (!this._experiments) { - return new Set(); - } - - return new Set([...this._experiments.values()].map(e => e._addonId)); - }, - - /* - * Task function to check applicability of experiments, disable the active - * experiment if needed and activate the first applicable candidate. - */ - _evaluateExperiments: function*() { - this._log.trace("_evaluateExperiments"); - - this._checkForShutdown(); - - // The first thing we do is reconcile our state against what's in the - // Addon Manager. It's possible that the Addon Manager knows of experiment - // add-ons that we don't. This could happen if an experiment gets installed - // when we're not listening or if there is a bug in our synchronization - // code. - // - // We have a few options of what to do with unknown experiment add-ons - // coming from the Addon Manager. Ideally, we'd convert these to - // ExperimentEntry instances and stuff them inside this._experiments. - // However, since ExperimentEntry contain lots of metadata from the - // manifest and trying to make up data could be error prone, it's safer - // to not try. Furthermore, if an experiment really did come from us, we - // should have some record of it. In the end, we decide to discard all - // knowledge for these unknown experiment add-ons. - let installedExperiments = yield installedExperimentAddons(); - let expectedAddonIds = this._trackedAddonIds; - let unknownAddons = installedExperiments.filter(a => !expectedAddonIds.has(a.id)); - if (unknownAddons.length) { - this._log.warn("_evaluateExperiments() - unknown add-ons in AddonManager: " + - unknownAddons.map(a => a.id).join(", ")); - - yield uninstallAddons(unknownAddons); - } - - let activeExperiment = this._getActiveExperiment(); - let activeChanged = false; - - if (!activeExperiment) { - // Avoid this pref staying out of sync if there were e.g. crashes. - gPrefs.set(PREF_ACTIVE_EXPERIMENT, false); - } - - // Ensure the active experiment is in the proper state. This may install, - // uninstall, upgrade, or enable the experiment add-on. What exactly is - // abstracted away from us by design. - if (activeExperiment) { - let changes; - let shouldStopResult = yield activeExperiment.shouldStop(); - if (shouldStopResult.shouldStop) { - let expireReasons = ["endTime", "maxActiveSeconds"]; - let kind, reason; - - if (expireReasons.indexOf(shouldStopResult.reason[0]) != -1) { - kind = TELEMETRY_LOG.TERMINATION.EXPIRED; - reason = null; - } else { - kind = TELEMETRY_LOG.TERMINATION.RECHECK; - reason = shouldStopResult.reason; - } - changes = yield activeExperiment.stop(kind, reason); - } - else if (this._terminateReason) { - changes = yield activeExperiment.stop(this._terminateReason); - } - else { - changes = yield activeExperiment.reconcileAddonState(); - } - - if (changes) { - this._dirty = true; - activeChanged = true; - } - - if (!activeExperiment._enabled) { - activeExperiment = null; - activeChanged = true; - } - } - - this._terminateReason = null; - - if (!activeExperiment && gExperimentsEnabled) { - for (let [id, experiment] of this._experiments) { - let applicable; - let reason = null; - try { - applicable = yield experiment.isApplicable(); - } - catch (e) { - applicable = false; - reason = e; - } - - if (!applicable && reason && reason[0] != "was-active") { - // Report this from here to avoid over-reporting. - let data = [TELEMETRY_LOG.ACTIVATION.REJECTED, id]; - data = data.concat(reason); - const key = TELEMETRY_LOG.ACTIVATION_KEY; - TelemetryLog.log(key, data); - this._log.trace("evaluateExperiments() - added " + key + " to TelemetryLog: " + JSON.stringify(data)); - } - - if (!applicable) { - continue; - } - - this._log.debug("evaluateExperiments() - activating experiment " + id); - try { - yield experiment.start(); - activeChanged = true; - activeExperiment = experiment; - this._dirty = true; - break; - } catch (e) { - // On failure, clean up the best we can and try the next experiment. - this._log.error("evaluateExperiments() - Unable to start experiment: " + e.message); - experiment._enabled = false; - yield experiment.reconcileAddonState(); - } - } - } - - gPrefs.set(PREF_ACTIVE_EXPERIMENT, activeExperiment != null); - - if (activeChanged || this._firstEvaluate) { - Services.obs.notifyObservers(null, EXPERIMENTS_CHANGED_TOPIC, null); - this._firstEvaluate = false; - } - - if ("@mozilla.org/toolkit/crash-reporter;1" in Cc && activeExperiment) { - try { - gCrashReporter.annotateCrashReport("ActiveExperiment", activeExperiment.id); - gCrashReporter.annotateCrashReport("ActiveExperimentBranch", activeExperiment.branch); - } catch (e) { - // It's ok if crash reporting is disabled. - } - } - }, - - /* - * Schedule the soonest re-check of experiment applicability that is needed. - */ - _scheduleNextRun: function () { - this._checkForShutdown(); - - if (this._timer) { - this._timer.clear(); - } - - if (!gExperimentsEnabled || this._experiments.length == 0) { - return; - } - - let time = null; - let now = this._policy.now().getTime(); - if (this._dirty) { - // If we failed to write the cache, we should try again periodically - time = now + 1000 * CACHE_WRITE_RETRY_DELAY_SEC; - } - - for (let [, experiment] of this._experiments) { - let scheduleTime = experiment.getScheduleTime(); - if (scheduleTime > now) { - if (time !== null) { - time = Math.min(time, scheduleTime); - } else { - time = scheduleTime; - } - } - } - - if (time === null) { - // No schedule time found. - return; - } - - this._log.trace("scheduleExperimentEvaluation() - scheduling for "+time+", now: "+now); - this._policy.oneshotTimer(this.notify, time - now, this, "_timer"); - }, -}; - - -/* - * Represents a single experiment. - */ - -Experiments.ExperimentEntry = function (policy) { - this._policy = policy || new Experiments.Policy(); - let log = Log.repository.getLoggerWithMessagePrefix( - "Browser.Experiments.Experiments", - "ExperimentEntry #" + gExperimentEntryCounter++ + "::"); - this._log = Object.create(log); - this._log.log = (level, string, params) => { - if (gExperiments) { - gExperiments._addToForensicsLog("ExperimentEntry", string); - } - log.log(level, string, params); - }; - - // Is the experiment supposed to be running. - this._enabled = false; - // When this experiment was started, if ever. - this._startDate = null; - // When this experiment was ended, if ever. - this._endDate = null; - // The condition data from the manifest. - this._manifestData = null; - // For an active experiment, signifies whether we need to update the xpi. - this._needsUpdate = false; - // A random sample value for comparison against the manifest conditions. - this._randomValue = null; - // When this entry was last changed for respecting history retention duration. - this._lastChangedDate = null; - // Has this experiment failed to activate before? - this._failedStart = false; - // The experiment branch - this._branch = null; - - // We grab these from the addon after download. - this._name = null; - this._description = null; - this._homepageURL = null; - this._addonId = null; -}; - -Experiments.ExperimentEntry.prototype = { - MANIFEST_REQUIRED_FIELDS: new Set([ - "id", - "xpiURL", - "xpiHash", - "startTime", - "endTime", - "maxActiveSeconds", - "appName", - "channel", - ]), - - MANIFEST_OPTIONAL_FIELDS: new Set([ - "maxStartTime", - "minVersion", - "maxVersion", - "version", - "minBuildID", - "maxBuildID", - "buildIDs", - "os", - "locale", - "sample", - "disabled", - "frozen", - "jsfilter", - ]), - - SERIALIZE_KEYS: new Set([ - "_enabled", - "_manifestData", - "_needsUpdate", - "_randomValue", - "_failedStart", - "_name", - "_description", - "_homepageURL", - "_addonId", - "_startDate", - "_endDate", - "_branch", - ]), - - DATE_KEYS: new Set([ - "_startDate", - "_endDate", - ]), - - UPGRADE_KEYS: new Map([ - ["_branch", null], - ]), - - ADDON_CHANGE_NONE: 0, - ADDON_CHANGE_INSTALL: 1, - ADDON_CHANGE_UNINSTALL: 2, - ADDON_CHANGE_ENABLE: 4, - - /* - * Initialize entry from the manifest. - * @param data The experiment data from the manifest. - * @return boolean Whether initialization succeeded. - */ - initFromManifestData: function (data) { - if (!this._isManifestDataValid(data)) { - return false; - } - - this._manifestData = data; - - this._randomValue = this._policy.random(); - this._lastChangedDate = this._policy.now(); - - return true; - }, - - get enabled() { - return this._enabled; - }, - - get id() { - return this._manifestData.id; - }, - - get branch() { - return this._branch; - }, - - set branch(v) { - this._branch = v; - }, - - get startDate() { - return this._startDate; - }, - - get endDate() { - if (!this._startDate) { - return null; - } - - let endTime = 0; - - if (!this._enabled) { - return this._endDate; - } - - let maxActiveMs = 1000 * this._manifestData.maxActiveSeconds; - endTime = Math.min(1000 * this._manifestData.endTime, - this._startDate.getTime() + maxActiveMs); - - return new Date(endTime); - }, - - get needsUpdate() { - return this._needsUpdate; - }, - - /* - * Initialize entry from the cache. - * @param data The entry data from the cache. - * @return boolean Whether initialization succeeded. - */ - initFromCacheData: function (data) { - for (let [key, dval] of this.UPGRADE_KEYS) { - if (!(key in data)) { - data[key] = dval; - } - } - - for (let key of this.SERIALIZE_KEYS) { - if (!(key in data) && !this.DATE_KEYS.has(key)) { - this._log.error("initFromCacheData() - missing required key " + key); - return false; - } - } - - if (!this._isManifestDataValid(data._manifestData)) { - return false; - } - - // Dates are restored separately from epoch ms, everything else is just - // copied in. - - this.SERIALIZE_KEYS.forEach(key => { - if (!this.DATE_KEYS.has(key)) { - this[key] = data[key]; - } - }); - - this.DATE_KEYS.forEach(key => { - if (key in data) { - let date = new Date(); - date.setTime(data[key]); - this[key] = date; - } - }); - - // In order for the experiment's data expiration mechanism to work, use the experiment's - // |_endData| as the |_lastChangedDate| (if available). - this._lastChangedDate = this._endDate ? this._endDate : this._policy.now(); - - return true; - }, - - /* - * Returns a JSON representation of this object. - */ - toJSON: function () { - let obj = {}; - - // Dates are serialized separately as epoch ms. - - this.SERIALIZE_KEYS.forEach(key => { - if (!this.DATE_KEYS.has(key)) { - obj[key] = this[key]; - } - }); - - this.DATE_KEYS.forEach(key => { - if (this[key]) { - obj[key] = this[key].getTime(); - } - }); - - return obj; - }, - - /* - * Update from the experiment data from the manifest. - * @param data The experiment data from the manifest. - * @return boolean Whether updating succeeded. - */ - updateFromManifestData: function (data) { - let old = this._manifestData; - - if (!this._isManifestDataValid(data)) { - return false; - } - - if (this._enabled) { - if (old.xpiHash !== data.xpiHash) { - // A changed hash means we need to update active experiments. - this._needsUpdate = true; - } - } else if (this._failedStart && - (old.xpiHash !== data.xpiHash) || - (old.xpiURL !== data.xpiURL)) { - // Retry installation of previously invalid experiments - // if hash or url changed. - this._failedStart = false; - } - - this._manifestData = data; - this._lastChangedDate = this._policy.now(); - - return true; - }, - - /* - * Is this experiment applicable? - * @return Promise<> Resolved if the experiment is applicable. - * If it is not applicable it is rejected with - * a Promise<string> which contains the reason. - */ - isApplicable: function () { - let versionCmp = Cc["@mozilla.org/xpcom/version-comparator;1"] - .getService(Ci.nsIVersionComparator); - let app = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo); - let runtime = Cc["@mozilla.org/xre/app-info;1"] - .getService(Ci.nsIXULRuntime); - - let locale = this._policy.locale(); - let channel = this._policy.updatechannel(); - let data = this._manifestData; - - let now = this._policy.now() / 1000; // The manifest times are in seconds. - let maxActive = data.maxActiveSeconds || 0; - let startSec = (this.startDate || 0) / 1000; - - this._log.trace("isApplicable() - now=" + now - + ", randomValue=" + this._randomValue); - - // Not applicable if it already ran. - - if (!this.enabled && this._endDate) { - return Promise.reject(["was-active"]); - } - - // Define and run the condition checks. - - let simpleChecks = [ - { name: "failedStart", - condition: () => !this._failedStart }, - { name: "disabled", - condition: () => !data.disabled }, - { name: "frozen", - condition: () => !data.frozen || this._enabled }, - { name: "startTime", - condition: () => now >= data.startTime }, - { name: "endTime", - condition: () => now < data.endTime }, - { name: "maxStartTime", - condition: () => this._startDate || !data.maxStartTime || now <= data.maxStartTime }, - { name: "maxActiveSeconds", - condition: () => !this._startDate || now <= (startSec + maxActive) }, - { name: "appName", - condition: () => !data.appName || data.appName.indexOf(app.name) != -1 }, - { name: "minBuildID", - condition: () => !data.minBuildID || app.platformBuildID >= data.minBuildID }, - { name: "maxBuildID", - condition: () => !data.maxBuildID || app.platformBuildID <= data.maxBuildID }, - { name: "buildIDs", - condition: () => !data.buildIDs || data.buildIDs.indexOf(app.platformBuildID) != -1 }, - { name: "os", - condition: () => !data.os || data.os.indexOf(runtime.OS) != -1 }, - { name: "channel", - condition: () => !data.channel || data.channel.indexOf(channel) != -1 }, - { name: "locale", - condition: () => !data.locale || data.locale.indexOf(locale) != -1 }, - { name: "sample", - condition: () => data.sample === undefined || this._randomValue <= data.sample }, - { name: "version", - condition: () => !data.version || data.version.indexOf(app.version) != -1 }, - { name: "minVersion", - condition: () => !data.minVersion || versionCmp.compare(app.version, data.minVersion) >= 0 }, - { name: "maxVersion", - condition: () => !data.maxVersion || versionCmp.compare(app.version, data.maxVersion) <= 0 }, - ]; - - for (let check of simpleChecks) { - let result = check.condition(); - if (!result) { - this._log.debug("isApplicable() - id=" - + data.id + " - test '" + check.name + "' failed"); - return Promise.reject([check.name]); - } - } - - if (data.jsfilter) { - return this._runFilterFunction(data.jsfilter); - } - - return Promise.resolve(true); - }, - - /* - * Run the jsfilter function from the manifest in a sandbox and return the - * result (forced to boolean). - */ - _runFilterFunction: Task.async(function* (jsfilter) { - this._log.trace("runFilterFunction() - filter: " + jsfilter); - - let ssm = Services.scriptSecurityManager; - const nullPrincipal = ssm.createNullPrincipal({}); - let options = { - sandboxName: "telemetry experiments jsfilter sandbox", - wantComponents: false, - }; - - let sandbox = Cu.Sandbox(nullPrincipal, options); - try { - Cu.evalInSandbox(jsfilter, sandbox); - } catch (e) { - this._log.error("runFilterFunction() - failed to eval jsfilter: " + e.message); - throw ["jsfilter-evalfailed"]; - } - - let currentEnvironment = yield TelemetryEnvironment.onInitialized(); - - Object.defineProperty(sandbox, "_e", - { get: () => Cu.cloneInto(currentEnvironment, sandbox) }); - - let result = false; - try { - result = !!Cu.evalInSandbox("filter({get telemetryEnvironment() { return _e; } })", sandbox); - } - catch (e) { - this._log.debug("runFilterFunction() - filter function failed: " - + e.message + ", " + e.stack); - throw ["jsfilter-threw", e.message]; - } - finally { - Cu.nukeSandbox(sandbox); - } - - if (!result) { - throw ["jsfilter-false"]; - } - - return true; - }), - - /* - * Start running the experiment. - * - * @return Promise<> Resolved when the operation is complete. - */ - start: Task.async(function* () { - this._log.trace("start() for " + this.id); - - this._enabled = true; - return yield this.reconcileAddonState(); - }), - - // Async install of the addon for this experiment, part of the start task above. - _installAddon: Task.async(function* () { - let deferred = Promise.defer(); - - let hash = this._policy.ignoreHashes ? null : this._manifestData.xpiHash; - - let install = yield addonInstallForURL(this._manifestData.xpiURL, hash); - gActiveInstallURLs.add(install.sourceURI.spec); - - let failureHandler = (install, handler) => { - let message = "AddonInstall " + handler + " for " + this.id + ", state=" + - (install.state || "?") + ", error=" + install.error; - this._log.error("_installAddon() - " + message); - this._failedStart = true; - gActiveInstallURLs.delete(install.sourceURI.spec); - - TelemetryLog.log(TELEMETRY_LOG.ACTIVATION_KEY, - [TELEMETRY_LOG.ACTIVATION.INSTALL_FAILURE, this.id]); - - deferred.reject(new Error(message)); - }; - - let listener = { - _expectedID: null, - - onDownloadEnded: install => { - this._log.trace("_installAddon() - onDownloadEnded for " + this.id); - - if (install.existingAddon) { - this._log.warn("_installAddon() - onDownloadEnded, addon already installed"); - } - - if (install.addon.type !== "experiment") { - this._log.error("_installAddon() - onDownloadEnded, wrong addon type"); - install.cancel(); - } - }, - - onInstallStarted: install => { - this._log.trace("_installAddon() - onInstallStarted for " + this.id); - - if (install.existingAddon) { - this._log.warn("_installAddon() - onInstallStarted, addon already installed"); - } - - if (install.addon.type !== "experiment") { - this._log.error("_installAddon() - onInstallStarted, wrong addon type"); - return false; - } - return undefined; - }, - - onInstallEnded: install => { - this._log.trace("_installAddon() - install ended for " + this.id); - gActiveInstallURLs.delete(install.sourceURI.spec); - - this._lastChangedDate = this._policy.now(); - this._startDate = this._policy.now(); - this._enabled = true; - - TelemetryLog.log(TELEMETRY_LOG.ACTIVATION_KEY, - [TELEMETRY_LOG.ACTIVATION.ACTIVATED, this.id]); - - let addon = install.addon; - this._name = addon.name; - this._addonId = addon.id; - this._description = addon.description || ""; - this._homepageURL = addon.homepageURL || ""; - - // Experiment add-ons default to userDisabled=true. Enable if needed. - if (addon.userDisabled) { - this._log.trace("Add-on is disabled. Enabling."); - listener._expectedID = addon.id; - AddonManager.addAddonListener(listener); - addon.userDisabled = false; - } else { - this._log.trace("Add-on is enabled. start() completed."); - deferred.resolve(); - } - }, - - onEnabled: addon => { - this._log.info("onEnabled() for " + addon.id); - - if (addon.id != listener._expectedID) { - return; - } - - AddonManager.removeAddonListener(listener); - deferred.resolve(); - }, - }; - - ["onDownloadCancelled", "onDownloadFailed", "onInstallCancelled", "onInstallFailed"] - .forEach(what => { - listener[what] = install => failureHandler(install, what) - }); - - install.addListener(listener); - install.install(); - - return yield deferred.promise; - }), - - /** - * Stop running the experiment if it is active. - * - * @param terminationKind (optional) - * The termination kind, e.g. ADDON_UNINSTALLED or EXPIRED. - * @param terminationReason (optional) - * The termination reason details for termination kind RECHECK. - * @return Promise<> Resolved when the operation is complete. - */ - stop: Task.async(function* (terminationKind, terminationReason) { - this._log.trace("stop() - id=" + this.id + ", terminationKind=" + terminationKind); - if (!this._enabled) { - throw new Error("Must not call stop() on an inactive experiment."); - } - - this._enabled = false; - let now = this._policy.now(); - this._lastChangedDate = now; - this._endDate = now; - - let changes = yield this.reconcileAddonState(); - this._logTermination(terminationKind, terminationReason); - - if (terminationKind == TELEMETRY_LOG.TERMINATION.ADDON_UNINSTALLED) { - changes |= this.ADDON_CHANGE_UNINSTALL; - } - - return changes; - }), - - /** - * Reconcile the state of the add-on against what it's supposed to be. - * - * If we are active, ensure the add-on is enabled and up to date. - * - * If we are inactive, ensure the add-on is not installed. - */ - reconcileAddonState: Task.async(function* () { - this._log.trace("reconcileAddonState()"); - - if (!this._enabled) { - if (!this._addonId) { - this._log.trace("reconcileAddonState() - Experiment is not enabled and " + - "has no add-on. Doing nothing."); - return this.ADDON_CHANGE_NONE; - } - - let addon = yield this._getAddon(); - if (!addon) { - this._log.trace("reconcileAddonState() - Inactive experiment has no " + - "add-on. Doing nothing."); - return this.ADDON_CHANGE_NONE; - } - - this._log.info("reconcileAddonState() - Uninstalling add-on for inactive " + - "experiment: " + addon.id); - gActiveUninstallAddonIDs.add(addon.id); - yield uninstallAddons([addon]); - gActiveUninstallAddonIDs.delete(addon.id); - return this.ADDON_CHANGE_UNINSTALL; - } - - // If we get here, we're supposed to be active. - - let changes = 0; - - // That requires an add-on. - let currentAddon = yield this._getAddon(); - - // If we have an add-on but it isn't up to date, uninstall it - // (to prepare for reinstall). - if (currentAddon && this._needsUpdate) { - this._log.info("reconcileAddonState() - Uninstalling add-on because update " + - "needed: " + currentAddon.id); - gActiveUninstallAddonIDs.add(currentAddon.id); - yield uninstallAddons([currentAddon]); - gActiveUninstallAddonIDs.delete(currentAddon.id); - changes |= this.ADDON_CHANGE_UNINSTALL; - } - - if (!currentAddon || this._needsUpdate) { - this._log.info("reconcileAddonState() - Installing add-on."); - yield this._installAddon(); - changes |= this.ADDON_CHANGE_INSTALL; - } - - let addon = yield this._getAddon(); - if (!addon) { - throw new Error("Could not obtain add-on for experiment that should be " + - "enabled."); - } - - // If we have the add-on and it is enabled, we are done. - if (!addon.userDisabled) { - return changes; - } - - // Check permissions to see if we can enable the addon. - if (!(addon.permissions & AddonManager.PERM_CAN_ENABLE)) { - throw new Error("Don't have permission to enable addon " + addon.id + ", perm=" + addon.permission); - } - - // Experiment addons should not require a restart. - if (addon.operationsRequiringRestart & AddonManager.OP_NEEDS_RESTART_ENABLE) { - throw new Error("Experiment addon requires a restart: " + addon.id); - } - - let deferred = Promise.defer(); - - // Else we need to enable it. - let listener = { - onEnabled: enabledAddon => { - if (enabledAddon.id != addon.id) { - return; - } - - AddonManager.removeAddonListener(listener); - deferred.resolve(); - }, - }; - - for (let handler of ["onDisabled", "onOperationCancelled", "onUninstalled"]) { - listener[handler] = (evtAddon) => { - if (evtAddon.id != addon.id) { - return; - } - - AddonManager.removeAddonListener(listener); - deferred.reject("Failed to enable addon " + addon.id + " due to: " + handler); - }; - } - - this._log.info("reconcileAddonState() - Activating add-on: " + addon.id); - AddonManager.addAddonListener(listener); - addon.userDisabled = false; - yield deferred.promise; - changes |= this.ADDON_CHANGE_ENABLE; - - this._log.info("reconcileAddonState() - Add-on has been enabled: " + addon.id); - return changes; - }), - - /** - * Obtain the underlying Addon from the Addon Manager. - * - * @return Promise<Addon|null> - */ - _getAddon: function () { - if (!this._addonId) { - return Promise.resolve(null); - } - - let deferred = Promise.defer(); - - AddonManager.getAddonByID(this._addonId, (addon) => { - if (addon && addon.appDisabled) { - // Don't return PreviousExperiments. - addon = null; - } - - deferred.resolve(addon); - }); - - return deferred.promise; - }, - - _logTermination: function (terminationKind, terminationReason) { - if (terminationKind === undefined) { - return; - } - - if (!(terminationKind in TELEMETRY_LOG.TERMINATION)) { - this._log.warn("stop() - unknown terminationKind " + terminationKind); - return; - } - - let data = [terminationKind, this.id]; - if (terminationReason) { - data = data.concat(terminationReason); - } - - TelemetryLog.log(TELEMETRY_LOG.TERMINATION_KEY, data); - }, - - /** - * Determine whether an active experiment should be stopped. - */ - shouldStop: function () { - if (!this._enabled) { - throw new Error("shouldStop must not be called on disabled experiments."); - } - - let deferred = Promise.defer(); - this.isApplicable().then( - () => deferred.resolve({shouldStop: false}), - reason => deferred.resolve({shouldStop: true, reason: reason}) - ); - - return deferred.promise; - }, - - /* - * Should this be discarded from the cache due to age? - */ - shouldDiscard: function () { - let limit = this._policy.now(); - limit.setDate(limit.getDate() - KEEP_HISTORY_N_DAYS); - return (this._lastChangedDate < limit); - }, - - /* - * Get next date (in epoch-ms) to schedule a re-evaluation for this. - * Returns 0 if it doesn't need one. - */ - getScheduleTime: function () { - if (this._enabled) { - let startTime = this._startDate.getTime(); - let maxActiveTime = startTime + 1000 * this._manifestData.maxActiveSeconds; - return Math.min(1000 * this._manifestData.endTime, maxActiveTime); - } - - if (this._endDate) { - return this._endDate.getTime(); - } - - return 1000 * this._manifestData.startTime; - }, - - /* - * Perform sanity checks on the experiment data. - */ - _isManifestDataValid: function (data) { - this._log.trace("isManifestDataValid() - data: " + JSON.stringify(data)); - - for (let key of this.MANIFEST_REQUIRED_FIELDS) { - if (!(key in data)) { - this._log.error("isManifestDataValid() - missing required key: " + key); - return false; - } - } - - for (let key in data) { - if (!this.MANIFEST_OPTIONAL_FIELDS.has(key) && - !this.MANIFEST_REQUIRED_FIELDS.has(key)) { - this._log.error("isManifestDataValid() - unknown key: " + key); - return false; - } - } - - return true; - }, -}; - -/** - * Strip a Date down to its UTC midnight. - * - * This will return a cloned Date object. The original is unchanged. - */ -var stripDateToMidnight = function (d) { - let m = new Date(d); - m.setUTCHours(0, 0, 0, 0); - - return m; -}; - -/** - * An Add-ons Manager provider that knows about old experiments. - * - * This provider exposes read-only add-ons corresponding to previously-active - * experiments. The existence of this provider (and the add-ons it knows about) - * facilitates the display of old experiments in the Add-ons Manager UI with - * very little custom code in that component. - */ -this.Experiments.PreviousExperimentProvider = function (experiments) { - this._experiments = experiments; - this._experimentList = []; - this._log = Log.repository.getLoggerWithMessagePrefix( - "Browser.Experiments.Experiments", - "PreviousExperimentProvider #" + gPreviousProviderCounter++ + "::"); -} - -this.Experiments.PreviousExperimentProvider.prototype = Object.freeze({ - name: "PreviousExperimentProvider", - - startup: function () { - this._log.trace("startup()"); - Services.obs.addObserver(this, EXPERIMENTS_CHANGED_TOPIC, false); - }, - - shutdown: function () { - this._log.trace("shutdown()"); - try { - Services.obs.removeObserver(this, EXPERIMENTS_CHANGED_TOPIC); - } catch (e) { - // Prevent crash in mochitest-browser3 on Mulet - } - }, - - observe: function (subject, topic, data) { - switch (topic) { - case EXPERIMENTS_CHANGED_TOPIC: - this._updateExperimentList(); - break; - } - }, - - getAddonByID: function (id, cb) { - for (let experiment of this._experimentList) { - if (experiment.id == id) { - cb(new PreviousExperimentAddon(experiment)); - return; - } - } - - cb(null); - }, - - getAddonsByTypes: function (types, cb) { - if (types && types.length > 0 && types.indexOf("experiment") == -1) { - cb([]); - return; - } - - cb(this._experimentList.map(e => new PreviousExperimentAddon(e))); - }, - - _updateExperimentList: function () { - return this._experiments.getExperiments().then((experiments) => { - let list = experiments.filter(e => !e.active); - - let newMap = new Map(list.map(e => [e.id, e])); - let oldMap = new Map(this._experimentList.map(e => [e.id, e])); - - let added = [...newMap.keys()].filter(id => !oldMap.has(id)); - let removed = [...oldMap.keys()].filter(id => !newMap.has(id)); - - for (let id of added) { - this._log.trace("updateExperimentList() - adding " + id); - let wrapper = new PreviousExperimentAddon(newMap.get(id)); - AddonManagerPrivate.callInstallListeners("onExternalInstall", null, wrapper, null, false); - AddonManagerPrivate.callAddonListeners("onInstalling", wrapper, false); - } - - for (let id of removed) { - this._log.trace("updateExperimentList() - removing " + id); - let wrapper = new PreviousExperimentAddon(oldMap.get(id)); - AddonManagerPrivate.callAddonListeners("onUninstalling", wrapper, false); - } - - this._experimentList = list; - - for (let id of added) { - let wrapper = new PreviousExperimentAddon(newMap.get(id)); - AddonManagerPrivate.callAddonListeners("onInstalled", wrapper); - } - - for (let id of removed) { - let wrapper = new PreviousExperimentAddon(oldMap.get(id)); - AddonManagerPrivate.callAddonListeners("onUninstalled", wrapper); - } - - return this._experimentList; - }); - }, -}); - -/** - * An add-on that represents a previously-installed experiment. - */ -function PreviousExperimentAddon(experiment) { - this._id = experiment.id; - this._name = experiment.name; - this._endDate = experiment.endDate; - this._description = experiment.description; -} - -PreviousExperimentAddon.prototype = Object.freeze({ - // BEGIN REQUIRED ADDON PROPERTIES - - get appDisabled() { - return true; - }, - - get blocklistState() { - Ci.nsIBlocklistService.STATE_NOT_BLOCKED - }, - - get creator() { - return new AddonManagerPrivate.AddonAuthor(""); - }, - - get foreignInstall() { - return false; - }, - - get id() { - return this._id; - }, - - get isActive() { - return false; - }, - - get isCompatible() { - return true; - }, - - get isPlatformCompatible() { - return true; - }, - - get name() { - return this._name; - }, - - get pendingOperations() { - return AddonManager.PENDING_NONE; - }, - - get permissions() { - return 0; - }, - - get providesUpdatesSecurely() { - return true; - }, - - get scope() { - return AddonManager.SCOPE_PROFILE; - }, - - get type() { - return "experiment"; - }, - - get userDisabled() { - return true; - }, - - get version() { - return null; - }, - - // END REQUIRED PROPERTIES - - // BEGIN OPTIONAL PROPERTIES - - get description() { - return this._description; - }, - - get updateDate() { - return new Date(this._endDate); - }, - - // END OPTIONAL PROPERTIES - - // BEGIN REQUIRED METHODS - - isCompatibleWith: function (appVersion, platformVersion) { - return true; - }, - - findUpdates: function (listener, reason, appVersion, platformVersion) { - AddonManagerPrivate.callNoUpdateListeners(this, listener, reason, - appVersion, platformVersion); - }, - - // END REQUIRED METHODS - - /** - * The end-date of the experiment, required for the Addon Manager UI. - */ - - get endDate() { - return this._endDate; - }, - -}); diff --git a/browser/experiments/Experiments.manifest b/browser/experiments/Experiments.manifest deleted file mode 100644 index 4a6a05a60..000000000 --- a/browser/experiments/Experiments.manifest +++ /dev/null @@ -1,6 +0,0 @@ -component {f7800463-3b97-47f9-9341-b7617e6d8d49} ExperimentsService.js -contract @mozilla.org/browser/experiments-service;1 {f7800463-3b97-47f9-9341-b7617e6d8d49} -category update-timer ExperimentsService @mozilla.org/browser/experiments-service;1,getService,experiments-update-timer,experiments.manifest.fetchIntervalSeconds,86400 -category profile-after-change ExperimentsService @mozilla.org/browser/experiments-service;1 - - diff --git a/browser/experiments/ExperimentsService.js b/browser/experiments/ExperimentsService.js deleted file mode 100644 index 53e811251..000000000 --- a/browser/experiments/ExperimentsService.js +++ /dev/null @@ -1,118 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const {interfaces: Ci, utils: Cu} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/Preferences.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "Experiments", - "resource:///modules/experiments/Experiments.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "OS", - "resource://gre/modules/osfile.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "CommonUtils", - "resource://services-common/utils.js"); - -const PREF_EXPERIMENTS_ENABLED = "experiments.enabled"; -const PREF_ACTIVE_EXPERIMENT = "experiments.activeExperiment"; // whether we have an active experiment -const PREF_TELEMETRY_ENABLED = "toolkit.telemetry.enabled"; -const PREF_TELEMETRY_UNIFIED = "toolkit.telemetry.unified"; -const DELAY_INIT_MS = 30 * 1000; - -// Whether the FHR/Telemetry unification features are enabled. -// Changing this pref requires a restart. -const IS_UNIFIED_TELEMETRY = Preferences.get(PREF_TELEMETRY_UNIFIED, false); - -XPCOMUtils.defineLazyGetter( - this, "gPrefs", () => { - return new Preferences(); - }); - -XPCOMUtils.defineLazyGetter( - this, "gExperimentsEnabled", () => { - // We can enable experiments if either unified Telemetry or FHR is on, and the user - // has opted into Telemetry. - return gPrefs.get(PREF_EXPERIMENTS_ENABLED, false) && - IS_UNIFIED_TELEMETRY && gPrefs.get(PREF_TELEMETRY_ENABLED, false); - }); - -XPCOMUtils.defineLazyGetter( - this, "gActiveExperiment", () => { - return gPrefs.get(PREF_ACTIVE_EXPERIMENT); - }); - -function ExperimentsService() { - this._initialized = false; - this._delayedInitTimer = null; -} - -ExperimentsService.prototype = { - classID: Components.ID("{f7800463-3b97-47f9-9341-b7617e6d8d49}"), - QueryInterface: XPCOMUtils.generateQI([Ci.nsITimerCallback, Ci.nsIObserver]), - - notify: function (timer) { - if (!gExperimentsEnabled) { - return; - } - if (OS.Constants.Path.profileDir === undefined) { - throw Error("Update timer fired before profile was initialized?"); - } - let instance = Experiments.instance(); - if (instance.isReady) { - instance.updateManifest(); - } - }, - - _delayedInit: function () { - if (!this._initialized) { - this._initialized = true; - Experiments.instance(); // for side effects - } - }, - - observe: function (subject, topic, data) { - switch (topic) { - case "profile-after-change": - if (gExperimentsEnabled) { - Services.obs.addObserver(this, "quit-application", false); - Services.obs.addObserver(this, "sessionstore-state-finalized", false); - Services.obs.addObserver(this, "EM-loaded", false); - - if (gActiveExperiment) { - this._initialized = true; - Experiments.instance(); // for side effects - } - } - break; - case "sessionstore-state-finalized": - if (!this._initialized) { - CommonUtils.namedTimer(this._delayedInit, DELAY_INIT_MS, this, "_delayedInitTimer"); - } - break; - case "EM-loaded": - if (!this._initialized) { - Experiments.instance(); // for side effects - this._initialized = true; - - if (this._delayedInitTimer) { - this._delayedInitTimer.clear(); - } - } - break; - case "quit-application": - Services.obs.removeObserver(this, "quit-application"); - Services.obs.removeObserver(this, "sessionstore-state-finalized"); - Services.obs.removeObserver(this, "EM-loaded"); - if (this._delayedInitTimer) { - this._delayedInitTimer.clear(); - } - break; - } - }, -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ExperimentsService]); diff --git a/browser/experiments/Makefile.in b/browser/experiments/Makefile.in deleted file mode 100644 index 5558582a6..000000000 --- a/browser/experiments/Makefile.in +++ /dev/null @@ -1,16 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -include $(topsrcdir)/config/rules.mk - -# This is so hacky. Waiting on bug 988938. -addondir = $(srcdir)/test/addons -testdir = $(topobjdir)/_tests/xpcshell/browser/experiments/test/xpcshell - -misc:: $(call mkdir_deps,$(testdir)) - $(EXIT_ON_ERROR) \ - for dir in $(addondir)/*; do \ - base=`basename $$dir`; \ - (cd $$dir && zip -qr $(testdir)/$$base.xpi *); \ - done diff --git a/browser/experiments/docs/index.rst b/browser/experiments/docs/index.rst deleted file mode 100644 index 11e5d4faa..000000000 --- a/browser/experiments/docs/index.rst +++ /dev/null @@ -1,13 +0,0 @@ -===================== -Telemetry Experiments -===================== - -Telemetry Experiments is a feature of Firefox that allows the installation -of add-ons called experiments to a subset of the Firefox population for -the purposes of experimenting with changes and collecting data on specific -aspects of application usage. - -.. toctree:: - :maxdepth: 1 - - manifest diff --git a/browser/experiments/docs/manifest.rst b/browser/experiments/docs/manifest.rst deleted file mode 100644 index d4fad5243..000000000 --- a/browser/experiments/docs/manifest.rst +++ /dev/null @@ -1,429 +0,0 @@ -.. _experiments_manifests: - -===================== -Experiments Manifests -===================== - -*Experiments Manifests* are documents that describe the set of active -experiments a client may run. - -*Experiments Manifests* are fetched periodically by clients. When -fetched, clients look at the experiments within the manifest and -determine which experiments are applicable. If an experiment is -applicable, the client may download and start the experiment. - -Manifest Format -=============== - -Manifests are JSON documents where the main element is an object. - -The *schema* of the object is versioned and defined by the presence -of a top-level ``version`` property, whose integer value is the -schema version used by that manifest. Each version is documented -in the sections below. - -Version 1 ---------- - -Version 1 is the original manifest format. - -The following properties may exist in the root object: - -experiments - An array of objects describing candidate experiments. The format of - these objects is documented below. - - An array is used to create an explicit priority of experiments. - Experiments listed at the beginning of the array take priority over - experiments that follow. - -Experiments Objects -^^^^^^^^^^^^^^^^^^^ - -Each object in the ``experiments`` array may contain the following -properties: - -id - (required) String identifier of this experiment. The identifier should - be treated as opaque by clients. It is used to uniquely identify an - experiment for all of time. - -xpiURL - (required) String URL of the XPI that implements this experiment. - - If the experiment is activated, the client will download and install this - XPI. - -xpiHash - (required) String hash of the XPI that implements this experiment. - - The value is composed of a hash identifier followed by a colon - followed by the hash value. e.g. - `sha1:f677428b9172e22e9911039aef03f3736e7f78a7`. `sha1` and `sha256` - are the two supported hashing mechanisms. The hash value is the hex - encoding of the binary hash. - - When the client downloads the XPI for the experiment, it should compare - the hash of that XPI against this value. If the hashes don't match, - the client should not install the XPI. - - Clients may also use this hash as a means of determining when an - experiment's XPI has changed and should be refreshed. - -startTime - Integer seconds since UNIX epoch that this experiment should - start. Clients should not start an experiment if *now()* is less than - this value. - -maxStartTime - (optional) Integer seconds since UNIX epoch after which this experiment - should no longer start. - - Some experiments may wish to impose hard deadlines after which no new - clients should activate the experiment. This property may be used to - facilitate that. - -endTime - Integer seconds since UNIX epoch after which this experiment - should no longer run. Clients should cease an experiment when the current - time is beyond this value. - -maxActiveSeconds - Integer seconds defining the max wall time this experiment should be - active for. - - The client should deactivate the experiment this many seconds after - initial activation. - - This value only involves wall time, not browser activity or session time. - -appName - Array of application names this experiment should run on. - - An application name comes from ``nsIXULAppInfo.name``. It is a value - like ``Firefox``, ``Fennec``, or `B2G`. - - The client should compare its application name against the members of - this array. If a match is found, the experiment is applicable. - -minVersion - (optional) String version number of the minimum application version this - experiment should run on. - - A version number is something like ``27.0.0`` or ``28``. - - The client should compare its version number to this value. If the client's - version is greater or equal to this version (using a version-aware comparison - function), the experiment is applicable. - - If this is not specified, there is no lower bound to versions this - experiment should run on. - -maxVersion - (optional) String version number of the maximum application version this - experiment should run on. - - This is similar to ``minVersion`` except it sets the upper bound for - application versions. - - If the client's version is less than or equal to this version, the - experiment is applicable. - - If this is not specified, there is no upper bound to versions this - experiment should run on. - -version - (optional) Array of application versions this experiment should run on. - - This is similar to ``minVersion`` and ``maxVersion`` except only a - whitelisted set of specific versions are allowed. - - The client should compare its version to members of this array. If a match - is found, the experiment is applicable. - -minBuildID - (optional) String minimum Build ID this experiment should run on. - - Build IDs are values like ``201402261424``. - - The client should perform a string comparison of its Build ID against this - value. If its value is greater than or equal to this value, the experiment - is applicable. - -maxBuildID - (optional) String maximum Build ID this experiment should run on. - - This is similar to ``minBuildID`` except it sets the upper bound - for Build IDs. - - The client should perform a string comparison of its Build ID against - this value. If its value is less than or equal to this value, the - experiment is applicable. - -buildIDs - (optional) Array of Build IDs this experiment should run on. - - This is similar to ``minBuildID`` and ``maxBuildID`` except only a - whitelisted set of Build IDs are considered. - - The client should compare its Build ID to members of this array. If a - match is found, the experiment is applicable. - -os - (optional) Array of operating system identifiers this experiment should - run on. - - Values for this array come from ``nsIXULRuntime.OS``. - - The client will compare its operating system identifier to members - of this array. If a match is found, the experiment is applicable to the - client. - -channel - (optional) Array of release channel identifiers this experiment should run - on. - - The client will compare its channel to members of this array. If a match - is found, the experiment is applicable. - - If this property is not defined, the client should assume the experiment - is to run on all channels. - -locale - (optional) Array of locale identifiers this experiment should run on. - - A locale identifier is a string like ``en-US`` or ``zh-CN`` and is - obtained by looking at - ``nsIXULChromeRegistry.getSelectedLocale("global")``. - - The client should compare its locale identifier to members of this array. - If a match is found, the experiment is applicable. - - If this property is not defined, the client should assume the experiment - is to run on all locales. - -sample - (optional) Decimal number indicating the sampling rate for this experiment. - - This will contain a value between ``0.0`` and ``1.0``. The client should - generate a random decimal between ``0.0`` and ``1.0``. If the randomly - generated number is less than or equal to the value of this field, the - experiment is applicable. - -disabled - (optional) Boolean value indicating whether an experiment is disabled. - - Normally, experiments are deactivated after a certain time has passed or - after the experiment itself determines it no longer needs to run (perhaps - it collected sufficient data already). - - This property serves as a backup mechanism to remotely disable an - experiment before it was scheduled to be disabled. It can be used to - kill experiments that are found to be doing wrong or bad things or that - aren't useful. - - If this property is not defined or is false, the client should assume - the experiment is active and a candidate for activation. - -frozen - (optional) Boolean value indicating this experiment is frozen and no - longer accepting new enrollments. - - If a client sees a true value in this field, it should not attempt to - activate an experiment. - -jsfilter - (optional) JavaScript code that will be evaluated to determine experiment - applicability. - - This property contains the string representation of JavaScript code that - will be evaluated in a sandboxed environment using JavaScript's - ``eval()``. - - The string is expected to contain the definition of a JavaScript function - ``filter(context)``. This function receives as its argument an object - holding application state. See the section below for the definition of - this object. - - The purpose of this property is to allow experiments to define complex - rules and logic for evaluating experiment applicability in a manner - that is privacy conscious and doesn't require the transmission of - excessive data. - - The return value of this filter indicates whether the experiment is - applicable. Functions should return true if the experiment is - applicable. - - If an experiment is not applicable, they should throw an Error whose - message contains the reason the experiment is not applicable. This - message may be logged and sent to remote servers, so it should not - contain private or otherwise sensitive data that wouldn't normally - be submitted. - - If a falsey (or undefined) value is returned, the client should - assume the experiment is not applicable. - - If this property is not defined, the client does not consider a custom - JavaScript filter function when determining whether an experiment is - applicable. - -JavaScript Filter Context Objects -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The object passed to a ``jsfilter`` ``filter()`` function contains the -following properties: - -healthReportSubmissionEnabled - This property contains a boolean indicating whether Firefox Health - Report has its data submission flag enabled (whether Firefox Health - Report is sending data to remote servers). - -healthReportPayload - This property contains the current Firefox Health Report payload. - - The payload format is documented at :ref:`healthreport_dataformat`. - -telemetryPayload - This property contains the current Telemetry payload. - -The evaluation sandbox for the JavaScript filters may be destroyed -immediately after ``filter()`` returns. This function should not assume -async code will finish. - -Experiment Applicability and Client Behavior -============================================ - -The point of an experiment manifest is to define which experiments are -available and where and how to run them. This section explains those -rules in more detail. - -Many of the properties in *Experiment Objects* are related to determining -whether an experiment should run on a given client. This evaluation is -performed client side. - -1. Multiple conditions in an experiment ---------------------------------------- - -If multiple conditions are defined for an experiment, the client should -combine each condition with a logical *AND*: all conditions must be -satisfied for an experiment to run. If one condition fails, the experiment -is not applicable. - -2. Active experiment disappears from manifest ---------------------------------------------- - -If a specific experiment disappears from the manifest, the client should -continue conducting an already-active experiment. Furthermore, the -client should remember what the expiration events were for an experiment -and honor them. - -The rationale here is that we want to prevent an accidental deletion -or temporary failure on the server to inadvertantly deactivate -supposed-to-be-active experiments. We also don't want premature deletion -of an experiment from the manifest to result in indefinite activation -periods. - -3. Inactive experiment disappears from manifest ------------------------------------------------ - -If an inactive but scheduled-to-be-active experiment disappears from the -manifest, the client should not activate the experiment. - -If that experiment reappears in the manifest, the client should not -treat that experiment any differently than any other new experiment. Put -another way, the fact an inactive experiment disappears and then -reappears should not be significant. - -The rationale here is that server operators should have complete -control of an inactive experiment up to it's go-live date. - -4. Re-evaluating applicability on manifest refresh --------------------------------------------------- - -When an experiment manifest is refreshed or updated, the client should -re-evaluate the applicability of each experiment therein. - -The rationale here is that the server may change the parameters of an -experiment and want clients to pick those up. - -5. Activating a previously non-applicable experiment ----------------------------------------------------- - -If the conditions of an experiment change or the state of the client -changes to allow an experiment to transition from previously -non-applicable to applicable, the experiment should be activated. - -For example, if a client is running version 28 and the experiment -initially requires version 29 or above, the client will not mark the -experiment as applicable. But if the client upgrades to version 29 or if -the manifest is updated to require 28 or above, the experiment will -become applicable. - -6. Deactivating a previously active experiment ----------------------------------------------- - -If the conditions of an experiment change or the state of the client -changes and an active experiment is no longer applicable, that -experiment should be deactivated. - -7. Calculation of sampling-based applicability ----------------------------------------------- - -For calculating sampling-based applicability, the client will associate -a random value between ``0.0`` and ``1.0`` for each observed experiment -ID. This random value will be generated the first time sampling -applicability is evaluated. This random value will be persisted and used -in future applicability evaluations for this experiment. - -By saving and re-using the value, the client is able to reliably and -consistently evaluate applicability, even if the sampling threshold -in the manifest changes. - -Clients should retain the randomly-generated sampling value for -experiments that no longer appear in a manifest for a period of at least -30 days. The rationale is that if an experiment disappears and reappears -from a manifest, the client will not have multiple opportunities to -generate a random value that satisfies the sampling criteria. - -8. Incompatible version numbers -------------------------------- - -If a client receives a manifest with a version number that it doesn't -recognize, it should ignore the manifest. - -9. Usage of old manifests -------------------------- - -If a client experiences an error fetching a manifest (server not -available) or if the manifest is corrupt, not readable, or compatible, -the client may use a previously-fetched (cached) manifest. - -10. Updating XPIs ------------------ - -If the URL or hash of an active experiment's XPI changes, the client -should fetch the new XPI, uninstall the old XPI, and install the new -XPI. - -Examples -======== - -Here is an example manifest:: - - { - "version": 1, - "experiments": [ - { - "id": "da9d7f4f-f3f9-4f81-bacd-6f0626ffa360", - "xpiURL": "https://experiments.mozilla.org/foo.xpi", - "xpiHash": "sha1:cb1eb32b89d86d78b7326f416cf404548c5e0099", - "startTime": 1393000000, - "endTime": 1394000000, - "appName": ["Firefox", "Fennec"], - "minVersion": "28", - "maxVersion": "30", - "os": ["windows", "linux", "osx"], - "jsfilter": "function filter(context) { return context.healthReportEnabled; }" - } - ] - } diff --git a/browser/experiments/moz.build b/browser/experiments/moz.build deleted file mode 100644 index a11e4b725..000000000 --- a/browser/experiments/moz.build +++ /dev/null @@ -1,18 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -HAS_MISC_RULE = True - -EXTRA_COMPONENTS += [ - 'Experiments.manifest', - 'ExperimentsService.js', -] - -EXTRA_JS_MODULES.experiments += [ - 'Experiments.jsm', -] - -XPCSHELL_TESTS_MANIFESTS += ['test/xpcshell/xpcshell.ini'] - -SPHINX_TREES['experiments'] = 'docs' diff --git a/browser/experiments/test/addons/experiment-1/install.rdf b/browser/experiments/test/addons/experiment-1/install.rdf deleted file mode 100644 index f9d70054a..000000000 --- a/browser/experiments/test/addons/experiment-1/install.rdf +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0"?> - -<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:em="http://www.mozilla.org/2004/em-rdf#"> - - <Description about="urn:mozilla:install-manifest"> - <em:id>test-experiment-1@tests.mozilla.org</em:id> - <em:version>1</em:version> - <em:type>128</em:type> - - <!-- Front End MetaData --> - <em:name>Test experiment 1</em:name> - <em:description>Yet another experiment that experiments experimentally.</em:description> - - </Description> -</RDF> diff --git a/browser/experiments/test/addons/experiment-1a/install.rdf b/browser/experiments/test/addons/experiment-1a/install.rdf deleted file mode 100644 index 7806b11b1..000000000 --- a/browser/experiments/test/addons/experiment-1a/install.rdf +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0"?> - -<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:em="http://www.mozilla.org/2004/em-rdf#"> - - <Description about="urn:mozilla:install-manifest"> - <em:id>test-experiment-1@tests.mozilla.org</em:id> - <em:version>1.1</em:version> - <em:type>128</em:type> - - <!-- Front End MetaData --> - <em:name>Test experiment 1.1</em:name> - <em:description>And yet another experiment that experiments experimentally.</em:description> - - </Description> -</RDF> diff --git a/browser/experiments/test/addons/experiment-2/install.rdf b/browser/experiments/test/addons/experiment-2/install.rdf deleted file mode 100644 index 69122c0ef..000000000 --- a/browser/experiments/test/addons/experiment-2/install.rdf +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0"?> - -<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:em="http://www.mozilla.org/2004/em-rdf#"> - - <Description about="urn:mozilla:install-manifest"> - <em:id>test-experiment-2@tests.mozilla.org</em:id> - <em:version>1</em:version> - <em:type>128</em:type> - - <!-- Front End MetaData --> - <em:name>Test experiment 2</em:name> - <em:description>And yet another experiment that experiments experimentally.</em:description> - - </Description> -</RDF> diff --git a/browser/experiments/test/addons/experiment-racybranch/bootstrap.js b/browser/experiments/test/addons/experiment-racybranch/bootstrap.js deleted file mode 100644 index e8278f50f..000000000 --- a/browser/experiments/test/addons/experiment-racybranch/bootstrap.js +++ /dev/null @@ -1,35 +0,0 @@ -/* exported startup, shutdown, install, uninstall */ - -var {classes: Cc, interfaces: Ci, utils: Cu} = Components; - -Cu.import("resource:///modules/experiments/Experiments.jsm"); - -var gStarted = false; - -function startup(data, reasonCode) { - if (gStarted) { - return; - } - gStarted = true; - - // delay realstartup to trigger the race condition - Cc['@mozilla.org/thread-manager;1'].getService(Ci.nsIThreadManager) - .mainThread.dispatch(realstartup, 0); -} - -function realstartup() { - let experiments = Experiments.instance(); - let experiment = experiments._getActiveExperiment(); - if (experiment.branch) { - Cu.reportError("Found pre-existing branch: " + experiment.branch); - return; - } - - let branch = "racy-set"; - experiments.setExperimentBranch(experiment.id, branch) - .then(null, Cu.reportError); -} - -function shutdown() { } -function install() { } -function uninstall() { } diff --git a/browser/experiments/test/addons/experiment-racybranch/install.rdf b/browser/experiments/test/addons/experiment-racybranch/install.rdf deleted file mode 100644 index cebaede56..000000000 --- a/browser/experiments/test/addons/experiment-racybranch/install.rdf +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0"?>
-
-<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:em="http://www.mozilla.org/2004/em-rdf#">
-
- <Description about="urn:mozilla:install-manifest">
- <em:id>test-experiment-racybranch@tests.mozilla.org</em:id>
- <em:version>1</em:version>
- <em:type>128</em:type>
-
- <!-- Front End MetaData -->
- <em:name>Test experiment racybranch</em:name>
- <em:description>An experiment that sets the experiment branch in a potentially racy way.</em:description>
-
- </Description>
-</RDF>
diff --git a/browser/experiments/test/xpcshell/.eslintrc.js b/browser/experiments/test/xpcshell/.eslintrc.js deleted file mode 100644 index 1f540a05b..000000000 --- a/browser/experiments/test/xpcshell/.eslintrc.js +++ /dev/null @@ -1,15 +0,0 @@ -"use strict"; - -module.exports = { - "extends": [ - "../../../../testing/xpcshell/xpcshell.eslintrc.js" - ], - - "rules": { - "no-unused-vars": ["error", { - "vars": "all", - "varsIgnorePattern": "^(Cc|Ci|Cr|Cu|EXPORTED_SYMBOLS)$", - "args": "none" - }] - } -}; diff --git a/browser/experiments/test/xpcshell/experiments_1.manifest b/browser/experiments/test/xpcshell/experiments_1.manifest deleted file mode 100644 index 0401ea328..000000000 --- a/browser/experiments/test/xpcshell/experiments_1.manifest +++ /dev/null @@ -1,19 +0,0 @@ -{ - "version": 1, - "experiments": [ - { - "id": "test-experiment-1@tests.mozilla.org", - "xpiURL": "https://experiments.mozilla.org/foo.xpi", - "xpiHash": "sha1:cb1eb32b89d86d78b7326f416cf404548c5e0099", - "startTime": 1393000000, - "endTime": 1394000000, - "appName": ["Firefox", "Fennec"], - "minVersion": "28", - "maxVersion": "30", - "maxActiveSeconds": 60, - "os": ["windows", "linux", "osx"], - "channel": ["daily", "weekly", "nightly"], - "jsfilter": "function filter(context) { return true; }" - } - ] -} diff --git a/browser/experiments/test/xpcshell/head.js b/browser/experiments/test/xpcshell/head.js deleted file mode 100644 index ae356ea2d..000000000 --- a/browser/experiments/test/xpcshell/head.js +++ /dev/null @@ -1,199 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -/* exported PREF_EXPERIMENTS_ENABLED, PREF_LOGGING_LEVEL, PREF_LOGGING_DUMP - PREF_MANIFEST_URI, PREF_FETCHINTERVAL, EXPERIMENT1_ID, - EXPERIMENT1_NAME, EXPERIMENT1_XPI_SHA1, EXPERIMENT1A_NAME, - EXPERIMENT1A_XPI_SHA1, EXPERIMENT2_ID, EXPERIMENT2_XPI_SHA1, - EXPERIMENT3_ID, EXPERIMENT4_ID, FAKE_EXPERIMENTS_1, - FAKE_EXPERIMENTS_2, gAppInfo, removeCacheFile, defineNow, - futureDate, dateToSeconds, loadAddonManager, promiseRestartManager, - startAddonManagerOnly, getExperimentAddons, replaceExperiments */ - -var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Promise.jsm"); -Cu.import("resource://gre/modules/Task.jsm"); -Cu.import("resource://gre/modules/osfile.jsm"); -Cu.import("resource://testing-common/AddonManagerTesting.jsm"); -Cu.import("resource://testing-common/AddonTestUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "AddonManager", - "resource://gre/modules/AddonManager.jsm"); - -const PREF_EXPERIMENTS_ENABLED = "experiments.enabled"; -const PREF_LOGGING_LEVEL = "experiments.logging.level"; -const PREF_LOGGING_DUMP = "experiments.logging.dump"; -const PREF_MANIFEST_URI = "experiments.manifest.uri"; -const PREF_FETCHINTERVAL = "experiments.manifest.fetchIntervalSeconds"; -const PREF_TELEMETRY_ENABLED = "toolkit.telemetry.enabled"; - -function getExperimentPath(base) { - let p = do_get_cwd(); - p.append(base); - return p.path; -} - -function sha1File(path) { - let f = Cc["@mozilla.org/file/local;1"] - .createInstance(Ci.nsILocalFile); - f.initWithPath(path); - let hasher = Cc["@mozilla.org/security/hash;1"] - .createInstance(Ci.nsICryptoHash); - hasher.init(hasher.SHA1); - - let is = Cc["@mozilla.org/network/file-input-stream;1"] - .createInstance(Ci.nsIFileInputStream); - is.init(f, -1, 0, 0); - hasher.updateFromStream(is, Math.pow(2, 32) - 1); - is.close(); - let bytes = hasher.finish(false); - - let rv = ""; - for (let i = 0; i < bytes.length; i++) { - rv += ("0" + bytes.charCodeAt(i).toString(16)).substr(-2); - } - return rv; -} - -const EXPERIMENT1_ID = "test-experiment-1@tests.mozilla.org"; -const EXPERIMENT1_XPI_NAME = "experiment-1.xpi"; -const EXPERIMENT1_NAME = "Test experiment 1"; -const EXPERIMENT1_PATH = getExperimentPath(EXPERIMENT1_XPI_NAME); -const EXPERIMENT1_XPI_SHA1 = "sha1:" + sha1File(EXPERIMENT1_PATH); - - -const EXPERIMENT1A_XPI_NAME = "experiment-1a.xpi"; -const EXPERIMENT1A_NAME = "Test experiment 1.1"; -const EXPERIMENT1A_PATH = getExperimentPath(EXPERIMENT1A_XPI_NAME); -const EXPERIMENT1A_XPI_SHA1 = "sha1:" + sha1File(EXPERIMENT1A_PATH); - -const EXPERIMENT2_ID = "test-experiment-2@tests.mozilla.org" -const EXPERIMENT2_XPI_NAME = "experiment-2.xpi"; -const EXPERIMENT2_PATH = getExperimentPath(EXPERIMENT2_XPI_NAME); -const EXPERIMENT2_XPI_SHA1 = "sha1:" + sha1File(EXPERIMENT2_PATH); - -const EXPERIMENT3_ID = "test-experiment-3@tests.mozilla.org"; -const EXPERIMENT4_ID = "test-experiment-4@tests.mozilla.org"; - -const FAKE_EXPERIMENTS_1 = [ - { - id: "id1", - name: "experiment1", - description: "experiment 1", - active: true, - detailUrl: "https://dummy/experiment1", - branch: "foo", - }, -]; - -const FAKE_EXPERIMENTS_2 = [ - { - id: "id2", - name: "experiment2", - description: "experiment 2", - active: false, - endDate: new Date(2014, 2, 11, 2, 4, 35, 42).getTime(), - detailUrl: "https://dummy/experiment2", - branch: null, - }, - { - id: "id1", - name: "experiment1", - description: "experiment 1", - active: false, - endDate: new Date(2014, 2, 10, 0, 0, 0, 0).getTime(), - detailURL: "https://dummy/experiment1", - branch: null, - }, -]; - -var gAppInfo = null; - -function removeCacheFile() { - let path = OS.Path.join(OS.Constants.Path.profileDir, "experiments.json"); - return OS.File.remove(path); -} - -function patchPolicy(policy, data) { - for (let key of Object.keys(data)) { - Object.defineProperty(policy, key, { - value: data[key], - writable: true, - }); - } -} - -function defineNow(policy, time) { - patchPolicy(policy, { now: () => new Date(time) }); -} - -function futureDate(date, offset) { - return new Date(date.getTime() + offset); -} - -function dateToSeconds(date) { - return date.getTime() / 1000; -} - -var gGlobalScope = this; -function loadAddonManager() { - AddonTestUtils.init(gGlobalScope); - AddonTestUtils.overrideCertDB(); - createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2"); - return AddonTestUtils.promiseStartupManager(); -} - -const { - promiseRestartManager, -} = AddonTestUtils; - -// Starts the addon manager without creating app info. We can't directly use -// |loadAddonManager| defined above in test_conditions.js as it would make the test fail. -function startAddonManagerOnly() { - let addonManager = Cc["@mozilla.org/addons/integration;1"] - .getService(Ci.nsIObserver) - .QueryInterface(Ci.nsITimerCallback); - addonManager.observe(null, "addons-startup", null); -} - -function getExperimentAddons(previous=false) { - let deferred = Promise.defer(); - - AddonManager.getAddonsByTypes(["experiment"], (addons) => { - if (previous) { - deferred.resolve(addons); - } else { - deferred.resolve(addons.filter(a => !a.appDisabled)); - } - }); - - return deferred.promise; -} - -function createAppInfo(ID="xpcshell@tests.mozilla.org", name="XPCShell", - version="1.0", platformVersion="1.0") { - AddonTestUtils.createAppInfo(ID, name, version, platformVersion); - gAppInfo = AddonTestUtils.appInfo; -} - -/** - * Replace the experiments on an Experiments with a new list. - * - * This monkeypatches getExperiments(). It doesn't monkeypatch the internal - * experiments list. So its utility is not as great as it could be. - */ -function replaceExperiments(experiment, list) { - Object.defineProperty(experiment, "getExperiments", { - writable: true, - value: () => { - return Promise.resolve(list); - }, - }); -} - -// Experiments require Telemetry to be enabled, and that's not true for debug -// builds. Let's just enable it here instead of going through each test. -Services.prefs.setBoolPref(PREF_TELEMETRY_ENABLED, true); diff --git a/browser/experiments/test/xpcshell/test_activate.js b/browser/experiments/test/xpcshell/test_activate.js deleted file mode 100644 index 60deafbfb..000000000 --- a/browser/experiments/test/xpcshell/test_activate.js +++ /dev/null @@ -1,151 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -Cu.import("resource://testing-common/httpd.js"); -Cu.import("resource:///modules/experiments/Experiments.jsm"); - -const SEC_IN_ONE_DAY = 24 * 60 * 60; -const MS_IN_ONE_DAY = SEC_IN_ONE_DAY * 1000; - -var gHttpServer = null; -var gHttpRoot = null; -var gPolicy = null; - -function ManifestEntry(data) { - this.id = data.id || EXPERIMENT1_ID; - this.xpiURL = data.xpiURL || gHttpRoot + EXPERIMENT1_XPI_NAME; - this.xpiHash = data.xpiHash || EXPERIMENT1_XPI_SHA1; - this.appName = data.appName || ["XPCShell"]; - this.channel = data.appName || ["nightly"]; - this.startTime = data.startTime || new Date(2010, 0, 1, 12).getTime() / 1000; - this.endTime = data.endTime || new Date(9001, 0, 1, 12).getTime() / 1000; - this.maxActiveSeconds = data.maxActiveSeconds || 5 * SEC_IN_ONE_DAY; -} - -function run_test() { - run_next_test(); -} - -add_task(function* test_setup() { - loadAddonManager(); - gPolicy = new Experiments.Policy(); - - gHttpServer = new HttpServer(); - gHttpServer.start(-1); - let port = gHttpServer.identity.primaryPort; - gHttpRoot = "http://localhost:" + port + "/"; - gHttpServer.registerDirectory("/", do_get_cwd()); - do_register_cleanup(() => gHttpServer.stop(() => {})); - - patchPolicy(gPolicy, { - updatechannel: () => "nightly", - }); - - Services.prefs.setBoolPref(PREF_EXPERIMENTS_ENABLED, true); - Services.prefs.setIntPref(PREF_LOGGING_LEVEL, 0); - Services.prefs.setBoolPref(PREF_LOGGING_DUMP, true); -}); - -function isApplicable(experiment) { - let deferred = Promise.defer(); - experiment.isApplicable().then( - result => deferred.resolve({ applicable: true, reason: null }), - reason => deferred.resolve({ applicable: false, reason: reason }) - ); - - return deferred.promise; -} - -add_task(function* test_startStop() { - let baseDate = new Date(2014, 5, 1, 12); - let startDate = futureDate(baseDate, 30 * MS_IN_ONE_DAY); - let endDate = futureDate(baseDate, 60 * MS_IN_ONE_DAY); - let manifestData = new ManifestEntry({ - startTime: dateToSeconds(startDate), - endTime: dateToSeconds(endDate), - maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - }); - let experiment = new Experiments.ExperimentEntry(gPolicy); - experiment.initFromManifestData(manifestData); - - // We need to associate it with the singleton so the onInstallStarted - // Addon Manager listener will know about it. - Experiments.instance()._experiments = new Map(); - Experiments.instance()._experiments.set(experiment.id, experiment); - - let result; - - defineNow(gPolicy, baseDate); - result = yield isApplicable(experiment); - Assert.equal(result.applicable, false, "Experiment should not be applicable."); - Assert.equal(experiment.enabled, false, "Experiment should not be enabled."); - - let addons = yield getExperimentAddons(); - Assert.equal(addons.length, 0, "No experiment add-ons are installed."); - - defineNow(gPolicy, futureDate(startDate, 5 * MS_IN_ONE_DAY)); - result = yield isApplicable(experiment); - Assert.equal(result.applicable, true, "Experiment should now be applicable."); - Assert.equal(experiment.enabled, false, "Experiment should not be enabled."); - - let changes = yield experiment.start(); - Assert.equal(changes, experiment.ADDON_CHANGE_INSTALL, "Add-on was installed."); - addons = yield getExperimentAddons(); - Assert.equal(experiment.enabled, true, "Experiment should now be enabled."); - Assert.equal(addons.length, 1, "1 experiment add-on is installed."); - Assert.equal(addons[0].id, experiment._addonId, "The add-on is the one we expect."); - Assert.equal(addons[0].userDisabled, false, "The add-on is not userDisabled."); - Assert.ok(addons[0].isActive, "The add-on is active."); - - changes = yield experiment.stop(); - Assert.equal(changes, experiment.ADDON_CHANGE_UNINSTALL, "Add-on was uninstalled."); - addons = yield getExperimentAddons(); - Assert.equal(experiment.enabled, false, "Experiment should not be enabled."); - Assert.equal(addons.length, 0, "Experiment should be uninstalled from the Addon Manager."); - - changes = yield experiment.start(); - Assert.equal(changes, experiment.ADDON_CHANGE_INSTALL, "Add-on was installed."); - addons = yield getExperimentAddons(); - Assert.equal(experiment.enabled, true, "Experiment should now be enabled."); - Assert.equal(addons.length, 1, "1 experiment add-on is installed."); - Assert.equal(addons[0].id, experiment._addonId, "The add-on is the one we expect."); - Assert.equal(addons[0].userDisabled, false, "The add-on is not userDisabled."); - Assert.ok(addons[0].isActive, "The add-on is active."); - - result = yield experiment.shouldStop(); - Assert.equal(result.shouldStop, false, "shouldStop should be false."); - Assert.equal(experiment.enabled, true, "Experiment should be enabled."); - addons = yield getExperimentAddons(); - Assert.equal(addons.length, 1, "Experiment still in add-ons manager."); - Assert.ok(addons[0].isActive, "The add-on is still active."); - - defineNow(gPolicy, futureDate(endDate, MS_IN_ONE_DAY)); - result = yield experiment.shouldStop(); - Assert.equal(result.shouldStop, true, "shouldStop should now be true."); - changes = yield experiment.stop(); - Assert.equal(changes, experiment.ADDON_CHANGE_UNINSTALL, "Add-on should be uninstalled."); - Assert.equal(experiment.enabled, false, "Experiment should be disabled."); - addons = yield getExperimentAddons(); - Assert.equal(addons.length, 0, "Experiment add-on is uninstalled."); - - // Ensure hash validation works. - // We set an incorrect hash and expect the install to fail. - experiment._manifestData.xpiHash = "sha1:41014dcc66b4dcedcd973491a1530a32f0517d8a"; - let errored = false; - try { - yield experiment.start(); - } catch (ex) { - errored = true; - } - Assert.ok(experiment._failedStart, "Experiment failed to start."); - Assert.ok(errored, "start() threw an exception."); - - // Make sure "ignore hashes" mode works. - gPolicy.ignoreHashes = true; - changes = yield experiment.start(); - Assert.equal(changes, experiment.ADDON_CHANGE_INSTALL); - yield experiment.stop(); - gPolicy.ignoreHashes = false; -}); diff --git a/browser/experiments/test/xpcshell/test_api.js b/browser/experiments/test/xpcshell/test_api.js deleted file mode 100644 index 9f0112570..000000000 --- a/browser/experiments/test/xpcshell/test_api.js +++ /dev/null @@ -1,1647 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -Cu.import("resource://testing-common/httpd.js"); -Cu.import("resource://testing-common/AddonManagerTesting.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "Experiments", - "resource:///modules/experiments/Experiments.jsm"); - -const MANIFEST_HANDLER = "manifests/handler"; - -const SEC_IN_ONE_DAY = 24 * 60 * 60; -const MS_IN_ONE_DAY = SEC_IN_ONE_DAY * 1000; - -var gHttpServer = null; -var gHttpRoot = null; -var gDataRoot = null; -var gPolicy = null; -var gManifestObject = null; -var gManifestHandlerURI = null; -var gTimerScheduleOffset = -1; - -function uninstallExperimentAddons() { - return Task.spawn(function* () { - let addons = yield getExperimentAddons(); - for (let a of addons) { - yield AddonManagerTesting.uninstallAddonByID(a.id); - } - }); -} - -function testCleanup(experimentsInstance) { - return Task.spawn(function* () { - yield promiseRestartManager(); - yield uninstallExperimentAddons(); - yield removeCacheFile(); - }); -} - -function run_test() { - run_next_test(); -} - -add_task(function* test_setup() { - loadAddonManager(); - - gHttpServer = new HttpServer(); - gHttpServer.start(-1); - let port = gHttpServer.identity.primaryPort; - gHttpRoot = "http://localhost:" + port + "/"; - gDataRoot = gHttpRoot + "data/"; - gManifestHandlerURI = gHttpRoot + MANIFEST_HANDLER; - gHttpServer.registerDirectory("/data/", do_get_cwd()); - gHttpServer.registerPathHandler("/" + MANIFEST_HANDLER, (request, response) => { - response.setStatusLine(null, 200, "OK"); - response.write(JSON.stringify(gManifestObject)); - response.processAsync(); - response.finish(); - }); - do_register_cleanup(() => gHttpServer.stop(() => {})); - - Services.prefs.setBoolPref(PREF_EXPERIMENTS_ENABLED, true); - Services.prefs.setIntPref(PREF_LOGGING_LEVEL, 0); - Services.prefs.setBoolPref(PREF_LOGGING_DUMP, true); - Services.prefs.setCharPref(PREF_MANIFEST_URI, gManifestHandlerURI); - Services.prefs.setIntPref(PREF_FETCHINTERVAL, 0); - - gPolicy = new Experiments.Policy(); - patchPolicy(gPolicy, { - updatechannel: () => "nightly", - oneshotTimer: (callback, timeout, thisObj, name) => gTimerScheduleOffset = timeout, - }); -}); - -add_task(function* test_contract() { - Cc["@mozilla.org/browser/experiments-service;1"].getService(); -}); - -// Test basic starting and stopping of experiments. - -add_task(function* test_getExperiments() { - const OBSERVER_TOPIC = "experiments-changed"; - let observerFireCount = 0; - let expectedObserverFireCount = 0; - let observer = () => ++observerFireCount; - Services.obs.addObserver(observer, OBSERVER_TOPIC, false); - - // Dates the following tests are based on. - - let baseDate = new Date(2014, 5, 1, 12); - let startDate1 = futureDate(baseDate, 50 * MS_IN_ONE_DAY); - let endDate1 = futureDate(baseDate, 100 * MS_IN_ONE_DAY); - let startDate2 = futureDate(baseDate, 150 * MS_IN_ONE_DAY); - let endDate2 = futureDate(baseDate, 200 * MS_IN_ONE_DAY); - - // The manifest data we test with. - - gManifestObject = { - "version": 1, - experiments: [ - { - id: EXPERIMENT2_ID, - xpiURL: gDataRoot + EXPERIMENT2_XPI_NAME, - xpiHash: EXPERIMENT2_XPI_SHA1, - startTime: dateToSeconds(startDate2), - endTime: dateToSeconds(endDate2), - maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - appName: ["XPCShell"], - channel: ["nightly"], - }, - { - id: EXPERIMENT1_ID, - xpiURL: gDataRoot + EXPERIMENT1_XPI_NAME, - xpiHash: EXPERIMENT1_XPI_SHA1, - startTime: dateToSeconds(startDate1), - endTime: dateToSeconds(endDate1), - maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - appName: ["XPCShell"], - channel: ["nightly"], - }, - ], - }; - - // Data to compare the result of Experiments.getExperiments() against. - - let experimentListData = [ - { - id: EXPERIMENT2_ID, - name: "Test experiment 2", - description: "And yet another experiment that experiments experimentally.", - }, - { - id: EXPERIMENT1_ID, - name: EXPERIMENT1_NAME, - description: "Yet another experiment that experiments experimentally.", - }, - ]; - - let experiments = new Experiments.Experiments(gPolicy); - - // Trigger update, clock set to before any activation. - // Use updateManifest() to provide for coverage of that path. - - let now = baseDate; - gTimerScheduleOffset = -1; - defineNow(gPolicy, now); - - yield experiments.updateManifest(); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - Assert.equal(experiments.getActiveExperimentID(), null, - "getActiveExperimentID should return null"); - - let list = yield experiments.getExperiments(); - Assert.equal(list.length, 0, "Experiment list should be empty."); - let addons = yield getExperimentAddons(); - Assert.equal(addons.length, 0, "Precondition: No experiment add-ons are installed."); - - try { - yield experiments.getExperimentBranch(); - Assert.ok(false, "getExperimentBranch should fail with no experiment"); - } - catch (e) { - Assert.ok(true, "getExperimentBranch correctly threw"); - } - - // Trigger update, clock set for experiment 1 to start. - - now = futureDate(startDate1, 5 * MS_IN_ONE_DAY); - gTimerScheduleOffset = -1; - defineNow(gPolicy, now); - - yield experiments.updateManifest(); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - - Assert.equal(experiments.getActiveExperimentID(), EXPERIMENT1_ID, - "getActiveExperimentID should return the active experiment1"); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry now."); - addons = yield getExperimentAddons(); - Assert.equal(addons.length, 1, "An experiment add-on was installed."); - - experimentListData[1].active = true; - experimentListData[1].endDate = now.getTime() + 10 * MS_IN_ONE_DAY; - for (let k of Object.keys(experimentListData[1])) { - Assert.equal(experimentListData[1][k], list[0][k], - "Property " + k + " should match reference data."); - } - - let b = yield experiments.getExperimentBranch(); - Assert.strictEqual(b, null, "getExperimentBranch should return null by default"); - - b = yield experiments.getExperimentBranch(EXPERIMENT1_ID); - Assert.strictEqual(b, null, "getExperimentsBranch should return null (with id)"); - - yield experiments.setExperimentBranch(EXPERIMENT1_ID, "foo"); - b = yield experiments.getExperimentBranch(); - Assert.strictEqual(b, "foo", "getExperimentsBranch should return the set value"); - - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - - Assert.equal(gTimerScheduleOffset, 10 * MS_IN_ONE_DAY, - "Experiment re-evaluation should have been scheduled correctly."); - - // Trigger update, clock set for experiment 1 to stop. - - now = futureDate(endDate1, 1000); - gTimerScheduleOffset = -1; - defineNow(gPolicy, now); - - yield experiments.updateManifest(); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - - Assert.equal(experiments.getActiveExperimentID(), null, - "getActiveExperimentID should return null again"); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry."); - addons = yield getExperimentAddons(); - Assert.equal(addons.length, 0, "The experiment add-on should be uninstalled."); - - experimentListData[1].active = false; - experimentListData[1].endDate = now.getTime(); - for (let k of Object.keys(experimentListData[1])) { - Assert.equal(experimentListData[1][k], list[0][k], - "Property " + k + " should match reference data."); - } - - Assert.equal(gTimerScheduleOffset, startDate2 - now, - "Experiment re-evaluation should have been scheduled correctly."); - - // Trigger update, clock set for experiment 2 to start. - // Use notify() to provide for coverage of that path. - - now = startDate2; - gTimerScheduleOffset = -1; - defineNow(gPolicy, now); - - yield experiments.notify(); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - - Assert.equal(experiments.getActiveExperimentID(), EXPERIMENT2_ID, - "getActiveExperimentID should return the active experiment2"); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 2, "Experiment list should have 2 entries now."); - addons = yield getExperimentAddons(); - Assert.equal(addons.length, 1, "An experiment add-on is installed."); - - experimentListData[0].active = true; - experimentListData[0].endDate = now.getTime() + 10 * MS_IN_ONE_DAY; - for (let i=0; i<experimentListData.length; ++i) { - let entry = experimentListData[i]; - for (let k of Object.keys(entry)) { - Assert.equal(entry[k], list[i][k], - "Entry " + i + " - Property '" + k + "' should match reference data."); - } - } - - Assert.equal(gTimerScheduleOffset, 10 * MS_IN_ONE_DAY, - "Experiment re-evaluation should have been scheduled correctly."); - - // Trigger update, clock set for experiment 2 to stop. - - now = futureDate(startDate2, 10 * MS_IN_ONE_DAY + 1000); - gTimerScheduleOffset = -1; - defineNow(gPolicy, now); - yield experiments.notify(); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - - Assert.equal(experiments.getActiveExperimentID(), null, - "getActiveExperimentID should return null again2"); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 2, "Experiment list should have 2 entries now."); - addons = yield getExperimentAddons(); - Assert.equal(addons.length, 0, "No experiments add-ons are installed."); - - experimentListData[0].active = false; - experimentListData[0].endDate = now.getTime(); - for (let i=0; i<experimentListData.length; ++i) { - let entry = experimentListData[i]; - for (let k of Object.keys(entry)) { - Assert.equal(entry[k], list[i][k], - "Entry " + i + " - Property '" + k + "' should match reference data."); - } - } - - // Cleanup. - - Services.obs.removeObserver(observer, OBSERVER_TOPIC); - yield testCleanup(experiments); -}); - -add_task(function* test_getActiveExperimentID() { - // Check that getActiveExperimentID returns the correct result even - // after .uninit() - - // Dates the following tests are based on. - - let baseDate = new Date(2014, 5, 1, 12); - let startDate1 = futureDate(baseDate, 50 * MS_IN_ONE_DAY); - let endDate1 = futureDate(baseDate, 100 * MS_IN_ONE_DAY); - - gManifestObject = { - "version": 1, - experiments: [ - { - id: EXPERIMENT1_ID, - xpiURL: gDataRoot + EXPERIMENT1_XPI_NAME, - xpiHash: EXPERIMENT1_XPI_SHA1, - startTime: dateToSeconds(startDate1), - endTime: dateToSeconds(endDate1), - maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - appName: ["XPCShell"], - channel: ["nightly"], - }, - ], - }; - - let now = futureDate(startDate1, 5 * MS_IN_ONE_DAY); - gTimerScheduleOffset = -1; - defineNow(gPolicy, now); - - let experiments = new Experiments.Experiments(gPolicy); - yield experiments.updateManifest(); - - Assert.equal(experiments.getActiveExperimentID(), EXPERIMENT1_ID, - "getActiveExperimentID should return the active experiment1"); - - yield promiseRestartManager(); - Assert.equal(experiments.getActiveExperimentID(), EXPERIMENT1_ID, - "getActiveExperimentID should return the active experiment1 after uninit()"); - - yield testCleanup(experiments); -}); - -// Test that we handle the experiments addon already being -// installed properly. -// We should just pave over them. - -add_task(function* test_addonAlreadyInstalled() { - const OBSERVER_TOPIC = "experiments-changed"; - let observerFireCount = 0; - let expectedObserverFireCount = 0; - let observer = () => ++observerFireCount; - Services.obs.addObserver(observer, OBSERVER_TOPIC, false); - - // Dates the following tests are based on. - - let baseDate = new Date(2014, 5, 1, 12); - let startDate = futureDate(baseDate, 100 * MS_IN_ONE_DAY); - let endDate = futureDate(baseDate, 10000 * MS_IN_ONE_DAY); - - // The manifest data we test with. - - gManifestObject = { - "version": 1, - experiments: [ - { - id: EXPERIMENT1_ID, - xpiURL: gDataRoot + EXPERIMENT1_XPI_NAME, - xpiHash: EXPERIMENT1_XPI_SHA1, - startTime: dateToSeconds(startDate), - endTime: dateToSeconds(endDate), - maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - appName: ["XPCShell"], - channel: ["nightly"], - }, - ], - }; - - let experiments = new Experiments.Experiments(gPolicy); - - // Trigger update, clock set to before any activation. - - let now = baseDate; - defineNow(gPolicy, now); - yield experiments.updateManifest(); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - let list = yield experiments.getExperiments(); - Assert.equal(list.length, 0, "Experiment list should be empty."); - - // Trigger update, clock set for the experiment to start. - - now = futureDate(startDate, 10 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - yield experiments.updateManifest(); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - - list = yield experiments.getExperiments(); - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry now."); - Assert.equal(list[0].id, EXPERIMENT1_ID, "Experiment 1 should be the sole entry."); - Assert.equal(list[0].active, true, "Experiment 1 should be active."); - - let addons = yield getExperimentAddons(); - Assert.equal(addons.length, 1, "1 add-on is installed."); - - // Install conflicting addon. - - yield AddonManagerTesting.installXPIFromURL(gDataRoot + EXPERIMENT1_XPI_NAME, EXPERIMENT1_XPI_SHA1); - addons = yield getExperimentAddons(); - Assert.equal(addons.length, 1, "1 add-on is installed."); - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should still have 1 entry."); - Assert.equal(list[0].id, EXPERIMENT1_ID, "Experiment 1 should be the sole entry."); - Assert.equal(list[0].active, true, "Experiment 1 should be active."); - - // Cleanup. - - Services.obs.removeObserver(observer, OBSERVER_TOPIC); - yield testCleanup(experiments); -}); - -add_task(function* test_lastActiveToday() { - let experiments = new Experiments.Experiments(gPolicy); - - replaceExperiments(experiments, FAKE_EXPERIMENTS_1); - - let e = yield experiments.getExperiments(); - Assert.equal(e.length, 1, "Monkeypatch successful."); - Assert.equal(e[0].id, "id1", "ID looks sane"); - Assert.ok(e[0].active, "Experiment is active."); - - let lastActive = yield experiments.lastActiveToday(); - Assert.equal(e[0], lastActive, "Last active object is expected."); - - replaceExperiments(experiments, FAKE_EXPERIMENTS_2); - e = yield experiments.getExperiments(); - Assert.equal(e.length, 2, "Monkeypatch successful."); - - defineNow(gPolicy, e[0].endDate); - - lastActive = yield experiments.lastActiveToday(); - Assert.ok(lastActive, "Have a last active experiment"); - Assert.equal(lastActive, e[0], "Last active object is expected."); - - yield testCleanup(experiments); -}); - -// Test explicitly disabling experiments. - -add_task(function* test_disableExperiment() { - // Dates this test is based on. - - let startDate = new Date(2004, 10, 9, 12); - let endDate = futureDate(startDate, 100 * MS_IN_ONE_DAY); - - // The manifest data we test with. - - gManifestObject = { - "version": 1, - experiments: [ - { - id: EXPERIMENT1_ID, - xpiURL: gDataRoot + EXPERIMENT1_XPI_NAME, - xpiHash: EXPERIMENT1_XPI_SHA1, - startTime: dateToSeconds(startDate), - endTime: dateToSeconds(endDate), - maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - appName: ["XPCShell"], - channel: ["nightly"], - }, - ], - }; - - // Data to compare the result of Experiments.getExperiments() against. - - let experimentInfo = { - id: EXPERIMENT1_ID, - name: EXPERIMENT1_NAME, - description: "Yet another experiment that experiments experimentally.", - }; - - let experiments = new Experiments.Experiments(gPolicy); - - // Trigger update, clock set for the experiment to start. - - let now = futureDate(startDate, 5 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - yield experiments.updateManifest(); - - let list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry now."); - - experimentInfo.active = true; - experimentInfo.endDate = now.getTime() + 10 * MS_IN_ONE_DAY; - for (let k of Object.keys(experimentInfo)) { - Assert.equal(experimentInfo[k], list[0][k], - "Property " + k + " should match reference data."); - } - - // Test disabling the experiment. - - now = futureDate(now, 1 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - yield experiments.disableExperiment("foo"); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry."); - - experimentInfo.active = false; - experimentInfo.endDate = now.getTime(); - for (let k of Object.keys(experimentInfo)) { - Assert.equal(experimentInfo[k], list[0][k], - "Property " + k + " should match reference data."); - } - - // Test that updating the list doesn't re-enable it. - - now = futureDate(now, 1 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - yield experiments.updateManifest(); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry."); - - for (let k of Object.keys(experimentInfo)) { - Assert.equal(experimentInfo[k], list[0][k], - "Property " + k + " should match reference data."); - } - - yield testCleanup(experiments); -}); - -add_task(function* test_disableExperimentsFeature() { - // Dates this test is based on. - - let startDate = new Date(2004, 10, 9, 12); - let endDate = futureDate(startDate, 100 * MS_IN_ONE_DAY); - - // The manifest data we test with. - - gManifestObject = { - "version": 1, - experiments: [ - { - id: EXPERIMENT1_ID, - xpiURL: gDataRoot + EXPERIMENT1_XPI_NAME, - xpiHash: EXPERIMENT1_XPI_SHA1, - startTime: dateToSeconds(startDate), - endTime: dateToSeconds(endDate), - maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - appName: ["XPCShell"], - channel: ["nightly"], - }, - ], - }; - - // Data to compare the result of Experiments.getExperiments() against. - - let experimentInfo = { - id: EXPERIMENT1_ID, - name: EXPERIMENT1_NAME, - description: "Yet another experiment that experiments experimentally.", - }; - - let experiments = new Experiments.Experiments(gPolicy); - Assert.equal(experiments.enabled, true, "Experiments feature should be enabled."); - - // Trigger update, clock set for the experiment to start. - - let now = futureDate(startDate, 5 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - yield experiments.updateManifest(); - - let list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry now."); - - experimentInfo.active = true; - experimentInfo.endDate = now.getTime() + 10 * MS_IN_ONE_DAY; - for (let k of Object.keys(experimentInfo)) { - Assert.equal(experimentInfo[k], list[0][k], - "Property " + k + " should match reference data."); - } - - // Test disabling experiments. - - experiments._toggleExperimentsEnabled(false); - yield experiments.notify(); - Assert.equal(experiments.enabled, false, "Experiments feature should be disabled now."); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry."); - - experimentInfo.active = false; - experimentInfo.endDate = now.getTime(); - for (let k of Object.keys(experimentInfo)) { - Assert.equal(experimentInfo[k], list[0][k], - "Property " + k + " should match reference data."); - } - - // Test that updating the list doesn't re-enable it. - - now = futureDate(now, 1 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - try { - yield experiments.updateManifest(); - } catch (e) { - // Exception expected, the feature is disabled. - } - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry."); - - for (let k of Object.keys(experimentInfo)) { - Assert.equal(experimentInfo[k], list[0][k], - "Property " + k + " should match reference data."); - } - - yield testCleanup(experiments); -}); - -// Test that after a failed experiment install: -// * the next applicable experiment gets installed -// * changing the experiments data later triggers re-evaluation - -add_task(function* test_installFailure() { - const OBSERVER_TOPIC = "experiments-changed"; - let observerFireCount = 0; - let expectedObserverFireCount = 0; - let observer = () => ++observerFireCount; - Services.obs.addObserver(observer, OBSERVER_TOPIC, false); - - // Dates the following tests are based on. - - let baseDate = new Date(2014, 5, 1, 12); - let startDate = futureDate(baseDate, 100 * MS_IN_ONE_DAY); - let endDate = futureDate(baseDate, 10000 * MS_IN_ONE_DAY); - - // The manifest data we test with. - - gManifestObject = { - "version": 1, - experiments: [ - { - id: EXPERIMENT1_ID, - xpiURL: gDataRoot + EXPERIMENT1_XPI_NAME, - xpiHash: EXPERIMENT1_XPI_SHA1, - startTime: dateToSeconds(startDate), - endTime: dateToSeconds(endDate), - maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - appName: ["XPCShell"], - channel: ["nightly"], - }, - { - id: EXPERIMENT2_ID, - xpiURL: gDataRoot + EXPERIMENT2_XPI_NAME, - xpiHash: EXPERIMENT2_XPI_SHA1, - startTime: dateToSeconds(startDate), - endTime: dateToSeconds(endDate), - maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - appName: ["XPCShell"], - channel: ["nightly"], - }, - ], - }; - - // Data to compare the result of Experiments.getExperiments() against. - - let experimentListData = [ - { - id: EXPERIMENT1_ID, - name: EXPERIMENT1_NAME, - description: "Yet another experiment that experiments experimentally.", - }, - { - id: EXPERIMENT2_ID, - name: "Test experiment 2", - description: "And yet another experiment that experiments experimentally.", - }, - ]; - - let experiments = new Experiments.Experiments(gPolicy); - - // Trigger update, clock set to before any activation. - - let now = baseDate; - defineNow(gPolicy, now); - yield experiments.updateManifest(); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - let list = yield experiments.getExperiments(); - Assert.equal(list.length, 0, "Experiment list should be empty."); - - // Trigger update, clock set for experiment 1 & 2 to start, - // invalid hash for experiment 1. - // Order in the manifest matters, so we should start experiment 1, - // fail to install it & start experiment 2 instead. - - now = futureDate(startDate, 10 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - gManifestObject.experiments[0].xpiHash = "sha1:0000000000000000000000000000000000000000"; - yield experiments.updateManifest(); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry now."); - Assert.equal(list[0].id, EXPERIMENT2_ID, "Experiment 2 should be the sole entry."); - Assert.equal(list[0].active, true, "Experiment 2 should be active."); - - // Trigger update, clock set for experiment 2 to stop. - - now = futureDate(now, 20 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - yield experiments.updateManifest(); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - - experimentListData[0].active = false; - experimentListData[0].endDate = now; - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry now."); - Assert.equal(list[0].id, EXPERIMENT2_ID, "Experiment 2 should be the sole entry."); - Assert.equal(list[0].active, false, "Experiment should not be active."); - - // Trigger update with a fixed entry for experiment 1, - // which should get re-evaluated & started now. - - now = futureDate(now, 20 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - gManifestObject.experiments[0].xpiHash = EXPERIMENT1_XPI_SHA1; - yield experiments.updateManifest(); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - - experimentListData[0].active = true; - experimentListData[0].endDate = now.getTime() + 10 * MS_IN_ONE_DAY; - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 2, "Experiment list should have 2 entries now."); - - for (let i=0; i<experimentListData.length; ++i) { - let entry = experimentListData[i]; - for (let k of Object.keys(entry)) { - Assert.equal(entry[k], list[i][k], - "Entry " + i + " - Property '" + k + "' should match reference data."); - } - } - - yield testCleanup(experiments); -}); - -// Test that after an experiment was disabled by user action, -// the experiment is not activated again if manifest data changes. - -add_task(function* test_userDisabledAndUpdated() { - const OBSERVER_TOPIC = "experiments-changed"; - let observerFireCount = 0; - let expectedObserverFireCount = 0; - let observer = () => ++observerFireCount; - Services.obs.addObserver(observer, OBSERVER_TOPIC, false); - - // Dates the following tests are based on. - - let baseDate = new Date(2014, 5, 1, 12); - let startDate = futureDate(baseDate, 100 * MS_IN_ONE_DAY); - let endDate = futureDate(baseDate, 10000 * MS_IN_ONE_DAY); - - // The manifest data we test with. - - gManifestObject = { - "version": 1, - experiments: [ - { - id: EXPERIMENT1_ID, - xpiURL: gDataRoot + EXPERIMENT1_XPI_NAME, - xpiHash: EXPERIMENT1_XPI_SHA1, - startTime: dateToSeconds(startDate), - endTime: dateToSeconds(endDate), - maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - appName: ["XPCShell"], - channel: ["nightly"], - }, - ], - }; - - let experiments = new Experiments.Experiments(gPolicy); - - // Trigger update, clock set to before any activation. - - let now = baseDate; - defineNow(gPolicy, now); - yield experiments.updateManifest(); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - let list = yield experiments.getExperiments(); - Assert.equal(list.length, 0, "Experiment list should be empty."); - - // Trigger update, clock set for experiment 1 to start. - - now = futureDate(startDate, 10 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - yield experiments.updateManifest(); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry now."); - Assert.equal(list[0].id, EXPERIMENT1_ID, "Experiment 1 should be the sole entry."); - Assert.equal(list[0].active, true, "Experiment 1 should be active."); - let todayActive = yield experiments.lastActiveToday(); - Assert.ok(todayActive, "Last active for today reports a value."); - Assert.equal(todayActive.id, list[0].id, "The entry is what we expect."); - - // Explicitly disable an experiment. - - now = futureDate(now, 20 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - yield experiments.disableExperiment("foo"); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry now."); - Assert.equal(list[0].id, EXPERIMENT1_ID, "Experiment 1 should be the sole entry."); - Assert.equal(list[0].active, false, "Experiment should not be active anymore."); - todayActive = yield experiments.lastActiveToday(); - Assert.ok(todayActive, "Last active for today still returns a value."); - Assert.equal(todayActive.id, list[0].id, "The ID is still the same."); - - // Trigger an update with a faked change for experiment 1. - - now = futureDate(now, 20 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - experiments._experiments.get(EXPERIMENT1_ID)._manifestData.xpiHash = - "sha1:0000000000000000000000000000000000000000"; - yield experiments.updateManifest(); - Assert.equal(observerFireCount, expectedObserverFireCount, - "Experiments observer should not have been called."); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry now."); - Assert.equal(list[0].id, EXPERIMENT1_ID, "Experiment 1 should be the sole entry."); - Assert.equal(list[0].active, false, "Experiment should still be inactive."); - - // Cleanup. - - Services.obs.removeObserver(observer, OBSERVER_TOPIC); - yield testCleanup(experiments); -}); - -// Test that changing the hash for an active experiments triggers an -// update for it. - -add_task(function* test_updateActiveExperiment() { - const OBSERVER_TOPIC = "experiments-changed"; - let observerFireCount = 0; - let expectedObserverFireCount = 0; - let observer = () => ++observerFireCount; - Services.obs.addObserver(observer, OBSERVER_TOPIC, false); - - // Dates the following tests are based on. - - let baseDate = new Date(2014, 5, 1, 12); - let startDate = futureDate(baseDate, 100 * MS_IN_ONE_DAY); - let endDate = futureDate(baseDate, 10000 * MS_IN_ONE_DAY); - - // The manifest data we test with. - - gManifestObject = { - "version": 1, - experiments: [ - { - id: EXPERIMENT1_ID, - xpiURL: gDataRoot + EXPERIMENT1_XPI_NAME, - xpiHash: EXPERIMENT1_XPI_SHA1, - startTime: dateToSeconds(startDate), - endTime: dateToSeconds(endDate), - maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - appName: ["XPCShell"], - channel: ["nightly"], - }, - ], - }; - - let experiments = new Experiments.Experiments(gPolicy); - - // Trigger update, clock set to before any activation. - - let now = baseDate; - defineNow(gPolicy, now); - yield experiments.updateManifest(); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - let list = yield experiments.getExperiments(); - Assert.equal(list.length, 0, "Experiment list should be empty."); - - let todayActive = yield experiments.lastActiveToday(); - Assert.equal(todayActive, null, "No experiment active today."); - - // Trigger update, clock set for the experiment to start. - - now = futureDate(startDate, 10 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - yield experiments.updateManifest(); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry now."); - Assert.equal(list[0].id, EXPERIMENT1_ID, "Experiment 1 should be the sole entry."); - Assert.equal(list[0].active, true, "Experiment 1 should be active."); - Assert.equal(list[0].name, EXPERIMENT1_NAME, "Experiments name should match."); - todayActive = yield experiments.lastActiveToday(); - Assert.ok(todayActive, "todayActive() returns a value."); - Assert.equal(todayActive.id, list[0].id, "It returns the active experiment."); - - // Trigger an update for the active experiment by changing it's hash (and xpi) - // in the manifest. - - now = futureDate(now, 1 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - gManifestObject.experiments[0].xpiHash = EXPERIMENT1A_XPI_SHA1; - gManifestObject.experiments[0].xpiURL = gDataRoot + EXPERIMENT1A_XPI_NAME; - yield experiments.updateManifest(); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry now."); - Assert.equal(list[0].id, EXPERIMENT1_ID, "Experiment 1 should be the sole entry."); - Assert.equal(list[0].active, true, "Experiment 1 should still be active."); - Assert.equal(list[0].name, EXPERIMENT1A_NAME, "Experiments name should have been updated."); - todayActive = yield experiments.lastActiveToday(); - Assert.equal(todayActive.id, list[0].id, "last active today is still sane."); - - // Cleanup. - - Services.obs.removeObserver(observer, OBSERVER_TOPIC); - yield testCleanup(experiments); -}); - -// Tests that setting the disable flag for an active experiment -// stops it. - -add_task(function* test_disableActiveExperiment() { - const OBSERVER_TOPIC = "experiments-changed"; - let observerFireCount = 0; - let expectedObserverFireCount = 0; - let observer = () => ++observerFireCount; - Services.obs.addObserver(observer, OBSERVER_TOPIC, false); - - // Dates the following tests are based on. - - let baseDate = new Date(2014, 5, 1, 12); - let startDate = futureDate(baseDate, 100 * MS_IN_ONE_DAY); - let endDate = futureDate(baseDate, 10000 * MS_IN_ONE_DAY); - - // The manifest data we test with. - - gManifestObject = { - "version": 1, - experiments: [ - { - id: EXPERIMENT1_ID, - xpiURL: gDataRoot + EXPERIMENT1_XPI_NAME, - xpiHash: EXPERIMENT1_XPI_SHA1, - startTime: dateToSeconds(startDate), - endTime: dateToSeconds(endDate), - maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - appName: ["XPCShell"], - channel: ["nightly"], - }, - ], - }; - - let experiments = new Experiments.Experiments(gPolicy); - - // Trigger update, clock set to before any activation. - - let now = baseDate; - defineNow(gPolicy, now); - yield experiments.updateManifest(); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - let list = yield experiments.getExperiments(); - Assert.equal(list.length, 0, "Experiment list should be empty."); - - // Trigger update, clock set for the experiment to start. - - now = futureDate(startDate, 10 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - yield experiments.updateManifest(); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry now."); - Assert.equal(list[0].id, EXPERIMENT1_ID, "Experiment 1 should be the sole entry."); - Assert.equal(list[0].active, true, "Experiment 1 should be active."); - - // Trigger an update with the experiment being disabled. - - now = futureDate(now, 1 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - gManifestObject.experiments[0].disabled = true; - yield experiments.updateManifest(); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry now."); - Assert.equal(list[0].id, EXPERIMENT1_ID, "Experiment 1 should be the sole entry."); - Assert.equal(list[0].active, false, "Experiment 1 should be disabled."); - - // Check that the experiment stays disabled. - - now = futureDate(now, 1 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - delete gManifestObject.experiments[0].disabled; - yield experiments.updateManifest(); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry now."); - Assert.equal(list[0].id, EXPERIMENT1_ID, "Experiment 1 should be the sole entry."); - Assert.equal(list[0].active, false, "Experiment 1 should still be disabled."); - - // Cleanup. - - Services.obs.removeObserver(observer, OBSERVER_TOPIC); - yield testCleanup(experiments); -}); - -// Test that: -// * setting the frozen flag for a not-yet-started experiment keeps -// it from starting -// * after a removing the frozen flag, the experiment can still start - -add_task(function* test_freezePendingExperiment() { - const OBSERVER_TOPIC = "experiments-changed"; - let observerFireCount = 0; - let expectedObserverFireCount = 0; - let observer = () => ++observerFireCount; - Services.obs.addObserver(observer, OBSERVER_TOPIC, false); - - // Dates the following tests are based on. - - let baseDate = new Date(2014, 5, 1, 12); - let startDate = futureDate(baseDate, 100 * MS_IN_ONE_DAY); - let endDate = futureDate(baseDate, 10000 * MS_IN_ONE_DAY); - - // The manifest data we test with. - - gManifestObject = { - "version": 1, - experiments: [ - { - id: EXPERIMENT1_ID, - xpiURL: gDataRoot + EXPERIMENT1_XPI_NAME, - xpiHash: EXPERIMENT1_XPI_SHA1, - startTime: dateToSeconds(startDate), - endTime: dateToSeconds(endDate), - maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - appName: ["XPCShell"], - channel: ["nightly"], - }, - ], - }; - - let experiments = new Experiments.Experiments(gPolicy); - - // Trigger update, clock set to before any activation. - - let now = baseDate; - defineNow(gPolicy, now); - yield experiments.updateManifest(); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - let list = yield experiments.getExperiments(); - Assert.equal(list.length, 0, "Experiment list should be empty."); - - // Trigger update, clock set for the experiment to start but frozen. - - now = futureDate(startDate, 10 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - gManifestObject.experiments[0].frozen = true; - yield experiments.updateManifest(); - Assert.equal(observerFireCount, expectedObserverFireCount, - "Experiments observer should have not been called."); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 0, "Experiment list should have no entries yet."); - - // Trigger an update with the experiment not being frozen anymore. - - now = futureDate(now, 1 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - delete gManifestObject.experiments[0].frozen; - yield experiments.updateManifest(); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry now."); - Assert.equal(list[0].id, EXPERIMENT1_ID, "Experiment 1 should be the sole entry."); - Assert.equal(list[0].active, true, "Experiment 1 should be active now."); - - // Cleanup. - - Services.obs.removeObserver(observer, OBSERVER_TOPIC); - yield testCleanup(experiments); -}); - -// Test that setting the frozen flag for an active experiment doesn't -// stop it. - -add_task(function* test_freezeActiveExperiment() { - const OBSERVER_TOPIC = "experiments-changed"; - let observerFireCount = 0; - let expectedObserverFireCount = 0; - let observer = () => ++observerFireCount; - Services.obs.addObserver(observer, OBSERVER_TOPIC, false); - - // Dates the following tests are based on. - - let baseDate = new Date(2014, 5, 1, 12); - let startDate = futureDate(baseDate, 100 * MS_IN_ONE_DAY); - let endDate = futureDate(baseDate, 10000 * MS_IN_ONE_DAY); - - // The manifest data we test with. - - gManifestObject = { - "version": 1, - experiments: [ - { - id: EXPERIMENT1_ID, - xpiURL: gDataRoot + EXPERIMENT1_XPI_NAME, - xpiHash: EXPERIMENT1_XPI_SHA1, - startTime: dateToSeconds(startDate), - endTime: dateToSeconds(endDate), - maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - appName: ["XPCShell"], - channel: ["nightly"], - }, - ], - }; - - let experiments = new Experiments.Experiments(gPolicy); - - // Trigger update, clock set to before any activation. - - let now = baseDate; - defineNow(gPolicy, now); - yield experiments.updateManifest(); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - let list = yield experiments.getExperiments(); - Assert.equal(list.length, 0, "Experiment list should be empty."); - - // Trigger update, clock set for the experiment to start. - - now = futureDate(startDate, 10 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - yield experiments.updateManifest(); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry now."); - Assert.equal(list[0].id, EXPERIMENT1_ID, "Experiment 1 should be the sole entry."); - Assert.equal(list[0].active, true, "Experiment 1 should be active."); - Assert.equal(list[0].name, EXPERIMENT1_NAME, "Experiments name should match."); - - // Trigger an update with the experiment being disabled. - - now = futureDate(now, 1 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - gManifestObject.experiments[0].frozen = true; - yield experiments.updateManifest(); - Assert.equal(observerFireCount, expectedObserverFireCount, - "Experiments observer should have been called."); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry now."); - Assert.equal(list[0].id, EXPERIMENT1_ID, "Experiment 1 should be the sole entry."); - Assert.equal(list[0].active, true, "Experiment 1 should still be active."); - - // Cleanup. - - Services.obs.removeObserver(observer, OBSERVER_TOPIC); - yield testCleanup(experiments); -}); - -// Test that removing an active experiment from the manifest doesn't -// stop it. - -add_task(function* test_removeActiveExperiment() { - const OBSERVER_TOPIC = "experiments-changed"; - let observerFireCount = 0; - let expectedObserverFireCount = 0; - let observer = () => ++observerFireCount; - Services.obs.addObserver(observer, OBSERVER_TOPIC, false); - - // Dates the following tests are based on. - - let baseDate = new Date(2014, 5, 1, 12); - let startDate = futureDate(baseDate, 100 * MS_IN_ONE_DAY); - let endDate = futureDate(baseDate, 10000 * MS_IN_ONE_DAY); - let startDate2 = futureDate(baseDate, 20000 * MS_IN_ONE_DAY); - let endDate2 = futureDate(baseDate, 30000 * MS_IN_ONE_DAY); - - // The manifest data we test with. - - gManifestObject = { - "version": 1, - experiments: [ - { - id: EXPERIMENT1_ID, - xpiURL: gDataRoot + EXPERIMENT1_XPI_NAME, - xpiHash: EXPERIMENT1_XPI_SHA1, - startTime: dateToSeconds(startDate), - endTime: dateToSeconds(endDate), - maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - appName: ["XPCShell"], - channel: ["nightly"], - }, - { - id: EXPERIMENT2_ID, - xpiURL: gDataRoot + EXPERIMENT1_XPI_NAME, - xpiHash: EXPERIMENT2_XPI_SHA1, - startTime: dateToSeconds(startDate2), - endTime: dateToSeconds(endDate2), - maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - appName: ["XPCShell"], - channel: ["nightly"], - }, - ], - }; - - let experiments = new Experiments.Experiments(gPolicy); - - // Trigger update, clock set to before any activation. - - let now = baseDate; - defineNow(gPolicy, now); - yield experiments.updateManifest(); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - let list = yield experiments.getExperiments(); - Assert.equal(list.length, 0, "Experiment list should be empty."); - - // Trigger update, clock set for the experiment to start. - - now = futureDate(startDate, 10 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - yield experiments.updateManifest(); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry now."); - Assert.equal(list[0].id, EXPERIMENT1_ID, "Experiment 1 should be the sole entry."); - Assert.equal(list[0].active, true, "Experiment 1 should be active."); - Assert.equal(list[0].name, EXPERIMENT1_NAME, "Experiments name should match."); - - // Trigger an update with experiment 1 missing from the manifest - - now = futureDate(now, 1 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - gManifestObject.experiments[0].frozen = true; - yield experiments.updateManifest(); - Assert.equal(observerFireCount, expectedObserverFireCount, - "Experiments observer should have been called."); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry now."); - Assert.equal(list[0].id, EXPERIMENT1_ID, "Experiment 1 should be the sole entry."); - Assert.equal(list[0].active, true, "Experiment 1 should still be active."); - - // Cleanup. - - Services.obs.removeObserver(observer, OBSERVER_TOPIC); - yield testCleanup(experiments); -}); - -// Test that we correctly handle experiment start & install failures. - -add_task(function* test_invalidUrl() { - const OBSERVER_TOPIC = "experiments-changed"; - let observerFireCount = 0; - let expectedObserverFireCount = 0; - let observer = () => ++observerFireCount; - Services.obs.addObserver(observer, OBSERVER_TOPIC, false); - - // Dates the following tests are based on. - - let baseDate = new Date(2014, 5, 1, 12); - let startDate = futureDate(baseDate, 100 * MS_IN_ONE_DAY); - let endDate = futureDate(baseDate, 10000 * MS_IN_ONE_DAY); - - // The manifest data we test with. - - gManifestObject = { - "version": 1, - experiments: [ - { - id: EXPERIMENT1_ID, - xpiURL: gDataRoot + EXPERIMENT1_XPI_NAME + ".invalid", - xpiHash: EXPERIMENT1_XPI_SHA1, - startTime: 0, - endTime: dateToSeconds(endDate), - maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - appName: ["XPCShell"], - channel: ["nightly"], - }, - ], - }; - - let experiments = new Experiments.Experiments(gPolicy); - - // Trigger update, clock set for the experiment to start. - - let now = futureDate(startDate, 10 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - gTimerScheduleOffset = null; - - yield experiments.updateManifest(); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - Assert.equal(gTimerScheduleOffset, null, "No new timer should have been scheduled."); - - let list = yield experiments.getExperiments(); - Assert.equal(list.length, 0, "Experiment list should be empty."); - - // Cleanup. - - Services.obs.removeObserver(observer, OBSERVER_TOPIC); - yield testCleanup(experiments); -}); - -// Test that we handle it properly when active experiment addons are being -// uninstalled. - -add_task(function* test_unexpectedUninstall() { - const OBSERVER_TOPIC = "experiments-changed"; - let observerFireCount = 0; - let expectedObserverFireCount = 0; - let observer = () => ++observerFireCount; - Services.obs.addObserver(observer, OBSERVER_TOPIC, false); - - // Dates the following tests are based on. - - let baseDate = new Date(2014, 5, 1, 12); - let startDate = futureDate(baseDate, 100 * MS_IN_ONE_DAY); - let endDate = futureDate(baseDate, 10000 * MS_IN_ONE_DAY); - - // The manifest data we test with. - - gManifestObject = { - "version": 1, - experiments: [ - { - id: EXPERIMENT1_ID, - xpiURL: gDataRoot + EXPERIMENT1_XPI_NAME, - xpiHash: EXPERIMENT1_XPI_SHA1, - startTime: dateToSeconds(startDate), - endTime: dateToSeconds(endDate), - maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - appName: ["XPCShell"], - channel: ["nightly"], - }, - ], - }; - - let experiments = new Experiments.Experiments(gPolicy); - - // Trigger update, clock set to before any activation. - - let now = baseDate; - defineNow(gPolicy, now); - yield experiments.updateManifest(); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - let list = yield experiments.getExperiments(); - Assert.equal(list.length, 0, "Experiment list should be empty."); - - // Trigger update, clock set for the experiment to start. - - now = futureDate(startDate, 10 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - yield experiments.updateManifest(); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry now."); - Assert.equal(list[0].id, EXPERIMENT1_ID, "Experiment 1 should be the sole entry."); - Assert.equal(list[0].active, true, "Experiment 1 should be active."); - - // Uninstall the addon through the addon manager instead of stopping it through - // the experiments API. - - yield AddonManagerTesting.uninstallAddonByID(EXPERIMENT1_ID); - yield experiments._mainTask; - - yield experiments.notify(); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry now."); - Assert.equal(list[0].id, EXPERIMENT1_ID, "Experiment 1 should be the sole entry."); - Assert.equal(list[0].active, false, "Experiment 1 should not be active anymore."); - - // Cleanup. - - Services.obs.removeObserver(observer, OBSERVER_TOPIC); - yield testCleanup(experiments); -}); - -// If the Addon Manager knows of an experiment that we don't, it should get -// uninstalled. -add_task(function* testUnknownExperimentsUninstalled() { - let experiments = new Experiments.Experiments(gPolicy); - - let addons = yield getExperimentAddons(); - Assert.equal(addons.length, 0, "Precondition: No experiment add-ons are present."); - - // Simulate us not listening. - experiments._unregisterWithAddonManager(); - yield AddonManagerTesting.installXPIFromURL(gDataRoot + EXPERIMENT1_XPI_NAME, EXPERIMENT1_XPI_SHA1); - experiments._registerWithAddonManager(); - - addons = yield getExperimentAddons(); - Assert.equal(addons.length, 1, "Experiment 1 installed via AddonManager"); - - // Simulate no known experiments. - gManifestObject = { - "version": 1, - experiments: [], - }; - - yield experiments.updateManifest(); - let fromManifest = yield experiments.getExperiments(); - Assert.equal(fromManifest.length, 0, "No experiments known in manifest."); - - // And the unknown add-on should be gone. - addons = yield getExperimentAddons(); - Assert.equal(addons.length, 0, "Experiment 1 was uninstalled."); - - yield testCleanup(experiments); -}); - -// If someone else installs an experiment add-on, we detect and stop that. -add_task(function* testForeignExperimentInstall() { - let experiments = new Experiments.Experiments(gPolicy); - - gManifestObject = { - "version": 1, - experiments: [], - }; - - yield experiments.init(); - - let addons = yield getExperimentAddons(); - Assert.equal(addons.length, 0, "Precondition: No experiment add-ons present."); - - let failed = false; - try { - yield AddonManagerTesting.installXPIFromURL(gDataRoot + EXPERIMENT1_XPI_NAME, EXPERIMENT1_XPI_SHA1); - } catch (ex) { - failed = true; - } - Assert.ok(failed, "Add-on install should not have completed successfully"); - addons = yield getExperimentAddons(); - Assert.equal(addons.length, 0, "Add-on install should have been cancelled."); - - yield testCleanup(experiments); -}); - -// Experiment add-ons will be disabled after Addon Manager restarts. Ensure -// we enable them automatically. -add_task(function* testEnabledAfterRestart() { - let experiments = new Experiments.Experiments(gPolicy); - - gManifestObject = { - "version": 1, - experiments: [ - { - id: EXPERIMENT1_ID, - xpiURL: gDataRoot + EXPERIMENT1_XPI_NAME, - xpiHash: EXPERIMENT1_XPI_SHA1, - startTime: gPolicy.now().getTime() / 1000 - 60, - endTime: gPolicy.now().getTime() / 1000 + 60, - maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - appName: ["XPCShell"], - channel: ["nightly"], - }, - ], - }; - - let addons = yield getExperimentAddons(); - Assert.equal(addons.length, 0, "Precondition: No experiment add-ons installed."); - - yield experiments.updateManifest(); - let fromManifest = yield experiments.getExperiments(); - Assert.equal(fromManifest.length, 1, "A single experiment is known."); - - addons = yield getExperimentAddons(); - Assert.equal(addons.length, 1, "A single experiment add-on is installed."); - Assert.ok(addons[0].isActive, "That experiment is active."); - - dump("Restarting Addon Manager\n"); - yield promiseRestartManager(); - experiments = new Experiments.Experiments(gPolicy); - - addons = yield getExperimentAddons(); - Assert.equal(addons.length, 1, "The experiment is still there after restart."); - Assert.ok(addons[0].userDisabled, "But it is disabled."); - Assert.equal(addons[0].isActive, false, "And not active."); - - yield experiments.updateManifest(); - Assert.ok(addons[0].isActive, "It activates when the manifest is evaluated."); - - yield testCleanup(experiments); -}); - -// If experiment add-ons were ever started, maxStartTime shouldn't be evaluated -// anymore. Ensure that if maxStartTime is passed but experiment has started -// already, maxStartTime does not cause deactivation. - -add_task(function* testMaxStartTimeEvaluation() { - - // Dates the following tests are based on. - - let startDate = new Date(2014, 5, 1, 12); - let now = futureDate(startDate, 10 * MS_IN_ONE_DAY); - let maxStartDate = futureDate(startDate, 100 * MS_IN_ONE_DAY); - let endDate = futureDate(startDate, 1000 * MS_IN_ONE_DAY); - - defineNow(gPolicy, now); - - // The manifest data we test with. - // We set a value for maxStartTime. - - gManifestObject = { - "version": 1, - experiments: [ - { - id: EXPERIMENT1_ID, - xpiURL: gDataRoot + EXPERIMENT1_XPI_NAME, - xpiHash: EXPERIMENT1_XPI_SHA1, - startTime: dateToSeconds(startDate), - endTime: dateToSeconds(endDate), - maxActiveSeconds: 1000 * SEC_IN_ONE_DAY, - maxStartTime: dateToSeconds(maxStartDate), - appName: ["XPCShell"], - channel: ["nightly"], - }, - ], - }; - - let experiments = new Experiments.Experiments(gPolicy); - - let addons = yield getExperimentAddons(); - Assert.equal(addons.length, 0, "Precondition: No experiment add-ons installed."); - - yield experiments.updateManifest(); - let fromManifest = yield experiments.getExperiments(); - Assert.equal(fromManifest.length, 1, "A single experiment is known."); - - addons = yield getExperimentAddons(); - Assert.equal(addons.length, 1, "A single experiment add-on is installed."); - Assert.ok(addons[0].isActive, "That experiment is active."); - - dump("Setting current time to maxStartTime + 100 days and reloading manifest\n"); - now = futureDate(maxStartDate, 100 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - yield experiments.updateManifest(); - - addons = yield getExperimentAddons(); - Assert.equal(addons.length, 1, "The experiment is still there."); - Assert.ok(addons[0].isActive, "It is still active."); - - yield testCleanup(experiments); -}); - -// Test coverage for an add-on uninstall disabling the experiment and that it stays -// disabled over restarts. -add_task(function* test_foreignUninstallAndRestart() { - let experiments = new Experiments.Experiments(gPolicy); - - gManifestObject = { - "version": 1, - experiments: [ - { - id: EXPERIMENT1_ID, - xpiURL: gDataRoot + EXPERIMENT1_XPI_NAME, - xpiHash: EXPERIMENT1_XPI_SHA1, - startTime: gPolicy.now().getTime() / 1000 - 60, - endTime: gPolicy.now().getTime() / 1000 + 60, - maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - appName: ["XPCShell"], - channel: ["nightly"], - }, - ], - }; - - let addons = yield getExperimentAddons(); - Assert.equal(addons.length, 0, "Precondition: No experiment add-ons installed."); - - yield experiments.updateManifest(); - let experimentList = yield experiments.getExperiments(); - Assert.equal(experimentList.length, 1, "A single experiment is known."); - - addons = yield getExperimentAddons(); - Assert.equal(addons.length, 1, "A single experiment add-on is installed."); - Assert.ok(addons[0].isActive, "That experiment is active."); - - yield AddonManagerTesting.uninstallAddonByID(EXPERIMENT1_ID); - yield experiments._mainTask; - - addons = yield getExperimentAddons(); - Assert.equal(addons.length, 0, "Experiment add-on should have been removed."); - - experimentList = yield experiments.getExperiments(); - Assert.equal(experimentList.length, 1, "A single experiment is known."); - Assert.equal(experimentList[0].id, EXPERIMENT1_ID, "Experiment 1 should be the sole entry."); - Assert.ok(!experimentList[0].active, "Experiment 1 should not be active anymore."); - - // Fake restart behaviour. - yield promiseRestartManager(); - experiments = new Experiments.Experiments(gPolicy); - yield experiments.updateManifest(); - - addons = yield getExperimentAddons(); - Assert.equal(addons.length, 0, "No experiment add-ons installed."); - - experimentList = yield experiments.getExperiments(); - Assert.equal(experimentList.length, 1, "A single experiment is known."); - Assert.equal(experimentList[0].id, EXPERIMENT1_ID, "Experiment 1 should be the sole entry."); - Assert.ok(!experimentList[0].active, "Experiment 1 should not be active."); - - yield testCleanup(experiments); -}); diff --git a/browser/experiments/test/xpcshell/test_cache.js b/browser/experiments/test/xpcshell/test_cache.js deleted file mode 100644 index 4f2bce881..000000000 --- a/browser/experiments/test/xpcshell/test_cache.js +++ /dev/null @@ -1,399 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -Cu.import("resource://testing-common/httpd.js"); -XPCOMUtils.defineLazyModuleGetter(this, "Experiments", - "resource:///modules/experiments/Experiments.jsm"); - -const MANIFEST_HANDLER = "manifests/handler"; - -const SEC_IN_ONE_DAY = 24 * 60 * 60; -const MS_IN_ONE_DAY = SEC_IN_ONE_DAY * 1000; - -var gHttpServer = null; -var gHttpRoot = null; -var gDataRoot = null; -var gPolicy = null; -var gManifestObject = null; -var gManifestHandlerURI = null; - -function run_test() { - run_next_test(); -} - -add_task(function* test_setup() { - loadAddonManager(); - yield removeCacheFile(); - - gHttpServer = new HttpServer(); - gHttpServer.start(-1); - let port = gHttpServer.identity.primaryPort; - gHttpRoot = "http://localhost:" + port + "/"; - gDataRoot = gHttpRoot + "data/"; - gManifestHandlerURI = gHttpRoot + MANIFEST_HANDLER; - gHttpServer.registerDirectory("/data/", do_get_cwd()); - gHttpServer.registerPathHandler("/" + MANIFEST_HANDLER, (request, response) => { - response.setStatusLine(null, 200, "OK"); - response.write(JSON.stringify(gManifestObject)); - response.processAsync(); - response.finish(); - }); - do_register_cleanup(() => gHttpServer.stop(() => {})); - - Services.prefs.setBoolPref(PREF_EXPERIMENTS_ENABLED, true); - Services.prefs.setIntPref(PREF_LOGGING_LEVEL, 0); - Services.prefs.setBoolPref(PREF_LOGGING_DUMP, true); - Services.prefs.setCharPref(PREF_MANIFEST_URI, gManifestHandlerURI); - Services.prefs.setIntPref(PREF_FETCHINTERVAL, 0); - - gPolicy = new Experiments.Policy(); - patchPolicy(gPolicy, { - updatechannel: () => "nightly", - oneshotTimer: (callback, timeout, thisObj, name) => {}, - }); -}); - -function checkExperimentListsEqual(list, list2) { - Assert.equal(list.length, list2.length, "Lists should have the same length.") - - for (let i=0; i<list.length; ++i) { - for (let k of Object.keys(list[i])) { - Assert.equal(list[i][k], list2[i][k], - "Field '" + k + "' should match for list entry " + i + "."); - } - } -} - -function checkExperimentSerializations(experimentEntryIterator) { - for (let experiment of experimentEntryIterator) { - let experiment2 = new Experiments.ExperimentEntry(gPolicy); - let jsonStr = JSON.stringify(experiment.toJSON()); - Assert.ok(experiment2.initFromCacheData(JSON.parse(jsonStr)), - "Should have initialized successfully from JSON serialization."); - Assert.equal(JSON.stringify(experiment), JSON.stringify(experiment2), - "Object stringifications should match."); - } -} - -function validateCache(cachedExperiments, experimentIds) { - let cachedExperimentIds = new Set(cachedExperiments); - Assert.equal(cachedExperimentIds.size, experimentIds.length, - "The number of cached experiments does not match with the provided list"); - for (let id of experimentIds) { - Assert.ok(cachedExperimentIds.has(id), "The cache must contain the experiment with id " + id); - } -} - -// Set up an experiments instance and check if it is properly restored from cache. - -add_task(function* test_cache() { - // The manifest data we test with. - - gManifestObject = { - "version": 1, - experiments: [ - { - id: EXPERIMENT1_ID, - xpiURL: gDataRoot + EXPERIMENT1_XPI_NAME, - xpiHash: EXPERIMENT1_XPI_SHA1, - maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - appName: ["XPCShell"], - channel: ["nightly"], - }, - { - id: EXPERIMENT2_ID, - xpiURL: gDataRoot + EXPERIMENT2_XPI_NAME, - xpiHash: EXPERIMENT2_XPI_SHA1, - maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - appName: ["XPCShell"], - channel: ["nightly"], - }, - { - id: EXPERIMENT3_ID, - xpiURL: "https://inval.id/foo.xpi", - xpiHash: "sha1:0000000000000000000000000000000000000000", - maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - appName: ["XPCShell"], - channel: ["nightly"], - }, - ], - }; - - // Setup dates for the experiments. - - let baseDate = new Date(2014, 5, 1, 12); - let startDates = []; - let endDates = []; - - for (let i=0; i<gManifestObject.experiments.length; ++i) { - let experiment = gManifestObject.experiments[i]; - startDates.push(futureDate(baseDate, (50 + (150 * i)) * MS_IN_ONE_DAY)); - endDates .push(futureDate(startDates[i], 50 * MS_IN_ONE_DAY)); - experiment.startTime = dateToSeconds(startDates[i]); - experiment.endTime = dateToSeconds(endDates[i]); - } - - // Data to compare the result of Experiments.getExperiments() against. - - let experimentListData = [ - { - id: EXPERIMENT2_ID, - name: "Test experiment 2", - description: "And yet another experiment that experiments experimentally.", - }, - { - id: EXPERIMENT1_ID, - name: EXPERIMENT1_NAME, - description: "Yet another experiment that experiments experimentally.", - }, - ]; - - // Trigger update & re-init, clock set to before any activation. - - let now = baseDate; - defineNow(gPolicy, now); - - let experiments = new Experiments.Experiments(gPolicy); - yield experiments.updateManifest(); - let list = yield experiments.getExperiments(); - Assert.equal(list.length, 0, "Experiment list should be empty."); - checkExperimentSerializations(experiments._experiments.values()); - - yield promiseRestartManager(); - experiments = new Experiments.Experiments(gPolicy); - - yield experiments._run(); - list = yield experiments.getExperiments(); - Assert.equal(list.length, 0, "Experiment list should be empty."); - checkExperimentSerializations(experiments._experiments.values()); - - // Re-init, clock set for experiment 1 to start. - - now = futureDate(startDates[0], 5 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - - yield promiseRestartManager(); - experiments = new Experiments.Experiments(gPolicy); - yield experiments._run(); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry now."); - - experimentListData[1].active = true; - experimentListData[1].endDate = now.getTime() + 10 * MS_IN_ONE_DAY; - checkExperimentListsEqual(experimentListData.slice(1), list); - checkExperimentSerializations(experiments._experiments.values()); - - let branch = yield experiments.getExperimentBranch(EXPERIMENT1_ID); - Assert.strictEqual(branch, null); - - yield experiments.setExperimentBranch(EXPERIMENT1_ID, "testbranch"); - branch = yield experiments.getExperimentBranch(EXPERIMENT1_ID); - Assert.strictEqual(branch, "testbranch"); - - // Re-init, clock set for experiment 1 to stop. - - now = futureDate(now, 20 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - - yield promiseRestartManager(); - experiments = new Experiments.Experiments(gPolicy); - yield experiments._run(); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry."); - - experimentListData[1].active = false; - experimentListData[1].endDate = now.getTime(); - checkExperimentListsEqual(experimentListData.slice(1), list); - checkExperimentSerializations(experiments._experiments.values()); - - branch = yield experiments.getExperimentBranch(EXPERIMENT1_ID); - Assert.strictEqual(branch, "testbranch"); - - // Re-init, clock set for experiment 2 to start. - - now = futureDate(startDates[1], 20 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - - yield promiseRestartManager(); - experiments = new Experiments.Experiments(gPolicy); - yield experiments._run(); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 2, "Experiment list should have 2 entries."); - - experimentListData[0].active = true; - experimentListData[0].endDate = now.getTime() + 10 * MS_IN_ONE_DAY; - checkExperimentListsEqual(experimentListData, list); - checkExperimentSerializations(experiments._experiments.values()); - - // Re-init, clock set for experiment 2 to stop. - - now = futureDate(now, 20 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - - yield promiseRestartManager(); - experiments = new Experiments.Experiments(gPolicy); - yield experiments._run(); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 2, "Experiment list should have 2 entries."); - - experimentListData[0].active = false; - experimentListData[0].endDate = now.getTime(); - checkExperimentListsEqual(experimentListData, list); - checkExperimentSerializations(experiments._experiments.values()); - - // Cleanup. - - yield experiments._toggleExperimentsEnabled(false); - yield promiseRestartManager(); - yield removeCacheFile(); -}); - -add_task(function* test_expiration() { - // The manifest data we test with. - gManifestObject = { - "version": 1, - experiments: [ - { - id: EXPERIMENT1_ID, - xpiURL: gDataRoot + EXPERIMENT1_XPI_NAME, - xpiHash: EXPERIMENT1_XPI_SHA1, - maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - appName: ["XPCShell"], - channel: ["nightly"], - }, - { - id: EXPERIMENT2_ID, - xpiURL: gDataRoot + EXPERIMENT2_XPI_NAME, - xpiHash: EXPERIMENT2_XPI_SHA1, - maxActiveSeconds: 50 * SEC_IN_ONE_DAY, - appName: ["XPCShell"], - channel: ["nightly"], - }, - // The 3rd experiment will never run, so it's ok to use experiment's 2 data. - { - id: EXPERIMENT3_ID, - xpiURL: gDataRoot + EXPERIMENT2_XPI_NAME, - xpiHash: EXPERIMENT2_XPI_SHA1, - maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - appName: ["XPCShell"], - channel: ["nightly"], - } - ], - }; - - // Data to compare the result of Experiments.getExperiments() against. - let experimentListData = [ - { - id: EXPERIMENT2_ID, - name: "Test experiment 2", - description: "And yet another experiment that experiments experimentally.", - }, - { - id: EXPERIMENT1_ID, - name: EXPERIMENT1_NAME, - description: "Yet another experiment that experiments experimentally.", - }, - ]; - - // Setup dates for the experiments. - let baseDate = new Date(2014, 5, 1, 12); - let startDates = []; - let endDates = []; - - for (let i=0; i<gManifestObject.experiments.length; ++i) { - let experiment = gManifestObject.experiments[i]; - // Spread out experiments in time so that one experiment can end and expire while - // the next is still running. - startDates.push(futureDate(baseDate, (50 + (200 * i)) * MS_IN_ONE_DAY)); - endDates .push(futureDate(startDates[i], 50 * MS_IN_ONE_DAY)); - experiment.startTime = dateToSeconds(startDates[i]); - experiment.endTime = dateToSeconds(endDates[i]); - } - - let now = null; - let experiments = null; - - let setDateAndRestartExperiments = new Task.async(function* (newDate) { - now = newDate; - defineNow(gPolicy, now); - - yield promiseRestartManager(); - experiments = new Experiments.Experiments(gPolicy); - yield experiments._run(); - }); - - // Trigger update & re-init, clock set to before any activation. - now = baseDate; - defineNow(gPolicy, now); - - experiments = new Experiments.Experiments(gPolicy); - yield experiments.updateManifest(); - let list = yield experiments.getExperiments(); - Assert.equal(list.length, 0, "Experiment list should be empty."); - - // Re-init, clock set for experiment 1 to start... - yield setDateAndRestartExperiments(startDates[0]); - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "The first experiment should have started."); - - // ... init again, and set the clock so that the first experiment ends. - yield setDateAndRestartExperiments(endDates[0]); - - // The experiment just ended, it should still be in the cache, but marked - // as finished. - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry."); - - experimentListData[1].active = false; - experimentListData[1].endDate = now.getTime(); - checkExperimentListsEqual(experimentListData.slice(1), list); - validateCache([...experiments._experiments.keys()], [EXPERIMENT1_ID, EXPERIMENT2_ID, EXPERIMENT3_ID]); - - // Start the second experiment. - yield setDateAndRestartExperiments(startDates[1]); - - // The experiments cache should contain the finished experiment and the - // one that's still running. - list = yield experiments.getExperiments(); - Assert.equal(list.length, 2, "Experiment list should have 2 entries."); - - experimentListData[0].active = true; - experimentListData[0].endDate = now.getTime() + 50 * MS_IN_ONE_DAY; - checkExperimentListsEqual(experimentListData, list); - - // Move the clock in the future, just 31 days after the start date of the second experiment, - // so that the cache for the first experiment expires and the second experiment is still running. - yield setDateAndRestartExperiments(futureDate(startDates[1], 31 * MS_IN_ONE_DAY)); - validateCache([...experiments._experiments.keys()], [EXPERIMENT2_ID, EXPERIMENT3_ID]); - - // Make sure that the expired experiment is not reported anymore. - let history = yield experiments.getExperiments(); - Assert.equal(history.length, 1, "Experiments older than 180 days must be removed from the cache."); - - // Test that we don't write expired experiments in the cache. - yield setDateAndRestartExperiments(now); - validateCache([...experiments._experiments.keys()], [EXPERIMENT2_ID, EXPERIMENT3_ID]); - - // The first experiment should be expired and not in the cache, it ended more than - // 180 days ago. We should see the one still running in the cache. - history = yield experiments.getExperiments(); - Assert.equal(history.length, 1, "Expired experiments must not be saved to cache."); - checkExperimentListsEqual(experimentListData.slice(0, 1), history); - - // Test that experiments that are cached locally but never ran are removed from cache - // when they are removed from the manifest (this is cached data, not really history). - gManifestObject["experiments"] = gManifestObject["experiments"].slice(1, 1); - yield experiments.updateManifest(); - validateCache([...experiments._experiments.keys()], [EXPERIMENT2_ID]); - - // Cleanup. - yield experiments._toggleExperimentsEnabled(false); - yield promiseRestartManager(); - yield removeCacheFile(); -}); diff --git a/browser/experiments/test/xpcshell/test_cacherace.js b/browser/experiments/test/xpcshell/test_cacherace.js deleted file mode 100644 index ff77cfdc4..000000000 --- a/browser/experiments/test/xpcshell/test_cacherace.js +++ /dev/null @@ -1,102 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -Cu.import("resource://testing-common/httpd.js"); -Cu.import("resource://gre/modules/Timer.jsm"); - -const MANIFEST_HANDLER = "manifests/handler"; - -const SEC_IN_ONE_DAY = 24 * 60 * 60; -const MS_IN_ONE_DAY = SEC_IN_ONE_DAY * 1000; - -var gHttpServer = null; -var gHttpRoot = null; -var gDataRoot = null; -var gPolicy = null; -var gManifestObject = null; -var gManifestHandlerURI = null; - -function run_test() { - run_next_test(); -} - -add_task(function* test_setup() { - loadAddonManager(); - yield removeCacheFile(); - - gHttpServer = new HttpServer(); - gHttpServer.start(-1); - let port = gHttpServer.identity.primaryPort; - gHttpRoot = "http://localhost:" + port + "/"; - gDataRoot = gHttpRoot + "data/"; - gManifestHandlerURI = gHttpRoot + MANIFEST_HANDLER; - gHttpServer.registerDirectory("/data/", do_get_cwd()); - gHttpServer.registerPathHandler("/" + MANIFEST_HANDLER, (request, response) => { - response.setStatusLine(null, 200, "OK"); - response.write(JSON.stringify(gManifestObject)); - response.processAsync(); - response.finish(); - }); - do_register_cleanup(() => gHttpServer.stop(() => {})); - - Services.prefs.setBoolPref(PREF_EXPERIMENTS_ENABLED, true); - Services.prefs.setIntPref(PREF_LOGGING_LEVEL, 0); - Services.prefs.setBoolPref(PREF_LOGGING_DUMP, true); - Services.prefs.setCharPref(PREF_MANIFEST_URI, gManifestHandlerURI); - Services.prefs.setIntPref(PREF_FETCHINTERVAL, 0); - - let ExperimentsScope = Cu.import("resource:///modules/experiments/Experiments.jsm"); - let Experiments = ExperimentsScope.Experiments; - - gPolicy = new Experiments.Policy(); - patchPolicy(gPolicy, { - updatechannel: () => "nightly", - delayCacheWrite: (promise) => { - return new Promise((resolve, reject) => { - promise.then( - (result) => { setTimeout(() => resolve(result), 500); }, - (err) => { reject(err); } - ); - }); - }, - }); - - let now = new Date(2014, 5, 1, 12); - defineNow(gPolicy, now); - - let experimentName = "experiment-racybranch.xpi"; - let experimentPath = getExperimentPath(experimentName); - let experimentHash = "sha1:" + sha1File(experimentPath); - - gManifestObject = { - version: 1, - experiments: [ - { - id: "test-experiment-racybranch@tests.mozilla.org", - xpiURL: gDataRoot + "experiment-racybranch.xpi", - xpiHash: experimentHash, - maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - appName: ["XPCShell"], - channel: ["nightly"], - startTime: dateToSeconds(futureDate(now, -MS_IN_ONE_DAY)), - endTime: dateToSeconds(futureDate(now, MS_IN_ONE_DAY)), - }, - ], - }; - - do_print("gManifestObject: " + JSON.stringify(gManifestObject)); - - // In order for the addon manager to work properly, we hack - // Experiments.instance which is used by the XPIProvider - let experiments = new Experiments.Experiments(gPolicy); - Assert.strictEqual(ExperimentsScope.gExperiments, null); - ExperimentsScope.gExperiments = experiments; - - yield experiments.updateManifest(); - let active = experiments._getActiveExperiment(); - Assert.ok(active); - Assert.equal(active.branch, "racy-set"); - Assert.ok(!experiments._dirty); -}); diff --git a/browser/experiments/test/xpcshell/test_conditions.js b/browser/experiments/test/xpcshell/test_conditions.js deleted file mode 100644 index 23c147fdb..000000000 --- a/browser/experiments/test/xpcshell/test_conditions.js +++ /dev/null @@ -1,325 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - - -Cu.import("resource:///modules/experiments/Experiments.jsm"); -Cu.import("resource://gre/modules/TelemetryController.jsm", this); - -const SEC_IN_ONE_DAY = 24 * 60 * 60; - -var gPolicy = null; - -function ManifestEntry(data) { - this.id = EXPERIMENT1_ID; - this.xpiURL = "http://localhost:1/dummy.xpi"; - this.xpiHash = EXPERIMENT1_XPI_SHA1; - this.startTime = new Date(2010, 0, 1, 12).getTime() / 1000; - this.endTime = new Date(9001, 0, 1, 12).getTime() / 1000; - this.maxActiveSeconds = SEC_IN_ONE_DAY; - this.appName = ["XPCShell"]; - this.channel = ["nightly"]; - - data = data || {}; - for (let k of Object.keys(data)) { - this[k] = data[k]; - } - - if (!this.endTime) { - this.endTime = this.startTime + 5 * SEC_IN_ONE_DAY; - } -} - -function applicableFromManifestData(data, policy) { - let manifestData = new ManifestEntry(data); - let entry = new Experiments.ExperimentEntry(policy); - entry.initFromManifestData(manifestData); - return entry.isApplicable(); -} - -function run_test() { - run_next_test(); -} - -add_task(function* test_setup() { - createAppInfo(); - do_get_profile(); - startAddonManagerOnly(); - yield TelemetryController.testSetup(); - gPolicy = new Experiments.Policy(); - - patchPolicy(gPolicy, { - updatechannel: () => "nightly", - locale: () => "en-US", - random: () => 0.5, - }); - - Services.prefs.setBoolPref(PREF_EXPERIMENTS_ENABLED, true); - Services.prefs.setIntPref(PREF_LOGGING_LEVEL, 0); - Services.prefs.setBoolPref(PREF_LOGGING_DUMP, true); -}); - -function arraysEqual(a, b) { - if (a.length !== b.length) { - return false; - } - - for (let i=0; i<a.length; ++i) { - if (a[i] !== b[i]) { - return false; - } - } - - return true; -} - -// This function exists solely to be .toSource()d -const sanityFilter = function filter(c) { - if (c.telemetryEnvironment === undefined) { - throw Error("No .telemetryEnvironment"); - } - if (c.telemetryEnvironment.build == undefined) { - throw Error("No .telemetryEnvironment.build"); - } - return true; -} - -// Utility function to generate build ID for previous/next date. -function addDate(buildId, diff) { - let m = /^([0-9]{4})([0-9]{2})([0-9]{2})(.*)$/.exec(buildId); - if (!m) { - throw Error("Unsupported build ID: " + buildId); - } - let year = Number.parseInt(m[1], 10); - let month = Number.parseInt(m[2], 10); - let date = Number.parseInt(m[3], 10); - let remainingParts = m[4]; - - let d = new Date(); - d.setUTCFullYear(year, month - 1, date); - d.setTime(d.getTime() + diff * 24 * 60 * 60 * 1000); - - let yearStr = String(d.getUTCFullYear()); - let monthStr = ("0" + String(d.getUTCMonth() + 1)).slice(-2); - let dateStr = ("0" + String(d.getUTCDate())).slice(-2); - return yearStr + monthStr + dateStr + remainingParts; -} -function prevDate(buildId) { - return addDate(buildId, -1); -} -function nextDate(buildId) { - return addDate(buildId, 1); -} - -add_task(function* test_simpleFields() { - let testData = [ - // "expected applicable?", failure reason or null, manifest data - - // misc. environment - - [false, ["appName"], {appName: []}], - [false, ["appName"], {appName: ["foo", gAppInfo.name + "-invalid"]}], - [true, null, {appName: ["not-an-app-name", gAppInfo.name]}], - - [false, ["os"], {os: []}], - [false, ["os"], {os: ["42", "abcdef"]}], - [true, null, {os: [gAppInfo.OS, "plan9"]}], - - [false, ["channel"], {channel: []}], - [false, ["channel"], {channel: ["foo", gPolicy.updatechannel() + "-invalid"]}], - [true, null, {channel: ["not-a-channel", gPolicy.updatechannel()]}], - - [false, ["locale"], {locale: []}], - [false, ["locale"], {locale: ["foo", gPolicy.locale + "-invalid"]}], - [true, null, {locale: ["not-a-locale", gPolicy.locale()]}], - - // version - - [false, ["version"], {version: []}], - [false, ["version"], {version: ["-1", gAppInfo.version + "-invalid", "asdf", "0,4", "99.99", "0.1.1.1"]}], - [true, null, {version: ["99999999.999", "-1", gAppInfo.version]}], - - [false, ["minVersion"], {minVersion: "1.0.1"}], - [true, null, {minVersion: "1.0b1"}], - [true, null, {minVersion: "1.0"}], - [true, null, {minVersion: "0.9"}], - - [false, ["maxVersion"], {maxVersion: "0.1"}], - [false, ["maxVersion"], {maxVersion: "0.9.9"}], - [false, ["maxVersion"], {maxVersion: "1.0b1"}], - [true, ["maxVersion"], {maxVersion: "1.0"}], - [true, ["maxVersion"], {maxVersion: "1.7pre"}], - - // build id - - [false, ["buildIDs"], {buildIDs: []}], - [false, ["buildIDs"], {buildIDs: ["not-a-build-id", gAppInfo.platformBuildID + "-invalid"]}], - [true, null, {buildIDs: ["not-a-build-id", gAppInfo.platformBuildID]}], - - [true, null, {minBuildID: prevDate(gAppInfo.platformBuildID)}], - [true, null, {minBuildID: gAppInfo.platformBuildID}], - [false, ["minBuildID"], {minBuildID: nextDate(gAppInfo.platformBuildID)}], - - [false, ["maxBuildID"], {maxBuildID: prevDate(gAppInfo.platformBuildID)}], - [true, null, {maxBuildID: gAppInfo.platformBuildID}], - [true, null, {maxBuildID: nextDate(gAppInfo.platformBuildID)}], - - // sample - - [false, ["sample"], {sample: -1 }], - [false, ["sample"], {sample: 0.0}], - [false, ["sample"], {sample: 0.1}], - [true, null, {sample: 0.5}], - [true, null, {sample: 0.6}], - [true, null, {sample: 1.0}], - [true, null, {sample: 0.5}], - - // experiment control - - [false, ["disabled"], {disabled: true}], - [true, null, {disabled: false}], - - [false, ["frozen"], {frozen: true}], - [true, null, {frozen: false}], - - [false, null, {frozen: true, disabled: true}], - [false, null, {frozen: true, disabled: false}], - [false, null, {frozen: false, disabled: true}], - [true, null, {frozen: false, disabled: false}], - - // jsfilter - - [true, null, {jsfilter: "function filter(c) { return true; }"}], - [false, ["jsfilter-false"], {jsfilter: "function filter(c) { return false; }"}], - [true, null, {jsfilter: "function filter(c) { return 123; }"}], // truthy - [false, ["jsfilter-false"], {jsfilter: "function filter(c) { return ''; }"}], // falsy - [false, ["jsfilter-false"], {jsfilter: "function filter(c) { var a = []; }"}], // undefined - [false, ["jsfilter-threw", "some error"], {jsfilter: "function filter(c) { throw new Error('some error'); }"}], - [false, ["jsfilter-evalfailed"], {jsfilter: "123, this won't work"}], - [true, null, {jsfilter: "var filter = " + sanityFilter.toSource()}], - ]; - - for (let i=0; i<testData.length; ++i) { - let entry = testData[i]; - let applicable; - let reason = null; - - yield applicableFromManifestData(entry[2], gPolicy).then( - value => applicable = value, - value => { - applicable = false; - reason = value; - } - ); - - Assert.equal(applicable, entry[0], - "Experiment entry applicability should match for test " - + i + ": " + JSON.stringify(entry[2])); - - let expectedReason = entry[1]; - if (!applicable && expectedReason) { - Assert.ok(arraysEqual(reason, expectedReason), - "Experiment rejection reasons should match for test " + i + ". " - + "Got " + JSON.stringify(reason) + ", expected " - + JSON.stringify(expectedReason)); - } - } -}); - -add_task(function* test_times() { - let now = new Date(2014, 5, 6, 12); - let nowSec = now.getTime() / 1000; - let testData = [ - // "expected applicable?", rejection reason or null, fake now date, manifest data - - // start time - - [true, null, now, - {startTime: nowSec - 5 * SEC_IN_ONE_DAY, - endTime: nowSec + 10 * SEC_IN_ONE_DAY}], - [true, null, now, - {startTime: nowSec, - endTime: nowSec + 10 * SEC_IN_ONE_DAY}], - [false, "startTime", now, - {startTime: nowSec + 5 * SEC_IN_ONE_DAY, - endTime: nowSec + 10 * SEC_IN_ONE_DAY}], - - // end time - - [false, "endTime", now, - {startTime: nowSec - 5 * SEC_IN_ONE_DAY, - endTime: nowSec - 10 * SEC_IN_ONE_DAY}], - [false, "endTime", now, - {startTime: nowSec - 5 * SEC_IN_ONE_DAY, - endTime: nowSec - 5 * SEC_IN_ONE_DAY}], - - // max start time - - [false, "maxStartTime", now, - {maxStartTime: nowSec - 15 * SEC_IN_ONE_DAY, - startTime: nowSec - 10 * SEC_IN_ONE_DAY, - endTime: nowSec + 10 * SEC_IN_ONE_DAY}], - [false, "maxStartTime", now, - {maxStartTime: nowSec - 1 * SEC_IN_ONE_DAY, - startTime: nowSec - 10 * SEC_IN_ONE_DAY, - endTime: nowSec + 10 * SEC_IN_ONE_DAY}], - [false, "maxStartTime", now, - {maxStartTime: nowSec - 10 * SEC_IN_ONE_DAY, - startTime: nowSec - 10 * SEC_IN_ONE_DAY, - endTime: nowSec + 10 * SEC_IN_ONE_DAY}], - [true, null, now, - {maxStartTime: nowSec, - startTime: nowSec - 10 * SEC_IN_ONE_DAY, - endTime: nowSec + 10 * SEC_IN_ONE_DAY}], - [true, null, now, - {maxStartTime: nowSec + 1 * SEC_IN_ONE_DAY, - startTime: nowSec - 10 * SEC_IN_ONE_DAY, - endTime: nowSec + 10 * SEC_IN_ONE_DAY}], - - // max active seconds - - [true, null, now, - {maxActiveSeconds: 5 * SEC_IN_ONE_DAY, - startTime: nowSec - 10 * SEC_IN_ONE_DAY, - endTime: nowSec + 10 * SEC_IN_ONE_DAY}], - [true, null, now, - {maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - startTime: nowSec - 10 * SEC_IN_ONE_DAY, - endTime: nowSec + 10 * SEC_IN_ONE_DAY}], - [true, null, now, - {maxActiveSeconds: 15 * SEC_IN_ONE_DAY, - startTime: nowSec - 10 * SEC_IN_ONE_DAY, - endTime: nowSec + 10 * SEC_IN_ONE_DAY}], - [true, null, now, - {maxActiveSeconds: 20 * SEC_IN_ONE_DAY, - startTime: nowSec - 10 * SEC_IN_ONE_DAY, - endTime: nowSec + 10 * SEC_IN_ONE_DAY}], - ]; - - for (let i=0; i<testData.length; ++i) { - let entry = testData[i]; - let applicable; - let reason = null; - defineNow(gPolicy, entry[2]); - - yield applicableFromManifestData(entry[3], gPolicy).then( - value => applicable = value, - value => { - applicable = false; - reason = value; - } - ); - - Assert.equal(applicable, entry[0], - "Experiment entry applicability should match for test " - + i + ": " + JSON.stringify([entry[2], entry[3]])); - if (!applicable && entry[1]) { - Assert.equal(reason, entry[1], "Experiment rejection reason should match for test " + i); - } - } -}); - -add_task(function* test_shutdown() { - yield TelemetryController.testShutdown(); -}); diff --git a/browser/experiments/test/xpcshell/test_disableExperiments.js b/browser/experiments/test/xpcshell/test_disableExperiments.js deleted file mode 100644 index 8441b922d..000000000 --- a/browser/experiments/test/xpcshell/test_disableExperiments.js +++ /dev/null @@ -1,180 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -Cu.import("resource://testing-common/httpd.js"); -Cu.import("resource://testing-common/AddonManagerTesting.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "Experiments", - "resource:///modules/experiments/Experiments.jsm"); - -const MANIFEST_HANDLER = "manifests/handler"; - -const SEC_IN_ONE_DAY = 24 * 60 * 60; -const MS_IN_ONE_DAY = SEC_IN_ONE_DAY * 1000; - -var gHttpServer = null; -var gHttpRoot = null; -var gDataRoot = null; -var gPolicy = null; -var gManifestObject = null; -var gManifestHandlerURI = null; - -function run_test() { - run_next_test(); -} - -add_task(function* test_setup() { - loadAddonManager(); - - gHttpServer = new HttpServer(); - gHttpServer.start(-1); - let port = gHttpServer.identity.primaryPort; - gHttpRoot = "http://localhost:" + port + "/"; - gDataRoot = gHttpRoot + "data/"; - gManifestHandlerURI = gHttpRoot + MANIFEST_HANDLER; - gHttpServer.registerDirectory("/data/", do_get_cwd()); - gHttpServer.registerPathHandler("/" + MANIFEST_HANDLER, (request, response) => { - response.setStatusLine(null, 200, "OK"); - response.write(JSON.stringify(gManifestObject)); - response.processAsync(); - response.finish(); - }); - do_register_cleanup(() => gHttpServer.stop(() => {})); - - Services.prefs.setBoolPref(PREF_EXPERIMENTS_ENABLED, true); - Services.prefs.setIntPref(PREF_LOGGING_LEVEL, 0); - Services.prefs.setBoolPref(PREF_LOGGING_DUMP, true); - Services.prefs.setCharPref(PREF_MANIFEST_URI, gManifestHandlerURI); - Services.prefs.setIntPref(PREF_FETCHINTERVAL, 0); - - gPolicy = new Experiments.Policy(); - patchPolicy(gPolicy, { - updatechannel: () => "nightly", - oneshotTimer: (callback, timeout, thisObj, name) => {}, - }); -}); - -// Test disabling the feature stops current and future experiments. - -add_task(function* test_disableExperiments() { - const OBSERVER_TOPIC = "experiments-changed"; - let observerFireCount = 0; - let expectedObserverFireCount = 0; - let observer = () => ++observerFireCount; - Services.obs.addObserver(observer, OBSERVER_TOPIC, false); - - // Dates the following tests are based on. - - let baseDate = new Date(2014, 5, 1, 12); - let startDate1 = futureDate(baseDate, 50 * MS_IN_ONE_DAY); - let endDate1 = futureDate(baseDate, 100 * MS_IN_ONE_DAY); - let startDate2 = futureDate(baseDate, 150 * MS_IN_ONE_DAY); - let endDate2 = futureDate(baseDate, 200 * MS_IN_ONE_DAY); - - // The manifest data we test with. - - gManifestObject = { - "version": 1, - experiments: [ - { - id: EXPERIMENT2_ID, - xpiURL: gDataRoot + EXPERIMENT2_XPI_NAME, - xpiHash: EXPERIMENT2_XPI_SHA1, - startTime: dateToSeconds(startDate2), - endTime: dateToSeconds(endDate2), - maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - appName: ["XPCShell"], - channel: ["nightly"], - }, - { - id: EXPERIMENT1_ID, - xpiURL: gDataRoot + EXPERIMENT1_XPI_NAME, - xpiHash: EXPERIMENT1_XPI_SHA1, - startTime: dateToSeconds(startDate1), - endTime: dateToSeconds(endDate1), - maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - appName: ["XPCShell"], - channel: ["nightly"], - }, - ], - }; - - let experiments = new Experiments.Experiments(gPolicy); - - // Trigger update, clock set to before any activation. - // Use updateManifest() to provide for coverage of that path. - - let now = baseDate; - defineNow(gPolicy, now); - - yield experiments.updateManifest(); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - let list = yield experiments.getExperiments(); - Assert.equal(list.length, 0, "Experiment list should be empty."); - let addons = yield getExperimentAddons(); - Assert.equal(addons.length, 0, "Precondition: No experiment add-ons are installed."); - - // Trigger update, clock set for experiment 1 to start. - - now = futureDate(startDate1, 5 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - - yield experiments.updateManifest(); - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry now."); - Assert.equal(list[0].active, true, "Experiment should be active."); - addons = yield getExperimentAddons(); - Assert.equal(addons.length, 1, "An experiment add-on was installed."); - - // Disable the experiments feature. Check that we stop the running experiment. - - Services.prefs.setBoolPref(PREF_EXPERIMENTS_ENABLED, false); - yield experiments._mainTask; - - Assert.equal(observerFireCount, ++expectedObserverFireCount, - "Experiments observer should have been called."); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry."); - Assert.equal(list[0].active, false, "Experiment entry should not be active."); - addons = yield getExperimentAddons(); - Assert.equal(addons.length, 0, "The experiment add-on should be uninstalled."); - - // Trigger update, clock set for experiment 2 to start. Verify we don't start it. - - now = startDate2; - defineNow(gPolicy, now); - - try { - yield experiments.updateManifest(); - } catch (e) { - // This exception is expected, we rethrow everything else - if (e.message != "experiments are disabled") { - throw e; - } - } - - experiments.notify(); - yield experiments._mainTask; - - Assert.equal(observerFireCount, expectedObserverFireCount, - "Experiments observer should not have been called."); - - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should still have 1 entry."); - Assert.equal(list[0].active, false, "Experiment entry should not be active."); - addons = yield getExperimentAddons(); - Assert.equal(addons.length, 0, "There should still be no experiment add-on installed."); - - // Cleanup. - - Services.obs.removeObserver(observer, OBSERVER_TOPIC); - yield promiseRestartManager(); - yield removeCacheFile(); -}); diff --git a/browser/experiments/test/xpcshell/test_fetch.js b/browser/experiments/test/xpcshell/test_fetch.js deleted file mode 100644 index e8d76fa35..000000000 --- a/browser/experiments/test/xpcshell/test_fetch.js +++ /dev/null @@ -1,68 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -Cu.import("resource://testing-common/httpd.js"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/osfile.jsm"); -Cu.import("resource:///modules/experiments/Experiments.jsm"); - -var gHttpServer = null; -var gHttpRoot = null; -var gPolicy = new Experiments.Policy(); - -function run_test() { - loadAddonManager(); - - gHttpServer = new HttpServer(); - gHttpServer.start(-1); - let port = gHttpServer.identity.primaryPort; - gHttpRoot = "http://localhost:" + port + "/"; - gHttpServer.registerDirectory("/", do_get_cwd()); - do_register_cleanup(() => gHttpServer.stop(() => {})); - - Services.prefs.setBoolPref(PREF_EXPERIMENTS_ENABLED, true); - Services.prefs.setIntPref(PREF_LOGGING_LEVEL, 0); - Services.prefs.setBoolPref(PREF_LOGGING_DUMP, true); - - patchPolicy(gPolicy, { - updatechannel: () => "nightly", - }); - - run_next_test(); -} - -add_task(function* test_fetchAndCache() { - Services.prefs.setCharPref(PREF_MANIFEST_URI, gHttpRoot + "experiments_1.manifest"); - let ex = new Experiments.Experiments(gPolicy); - - Assert.equal(ex._experiments, null, "There should be no cached experiments yet."); - yield ex.updateManifest(); - Assert.notEqual(ex._experiments.size, 0, "There should be cached experiments now."); - - yield promiseRestartManager(); -}); - -add_task(function* test_checkCache() { - let ex = new Experiments.Experiments(gPolicy); - yield ex.notify(); - Assert.notEqual(ex._experiments.size, 0, "There should be cached experiments now."); - - yield promiseRestartManager(); -}); - -add_task(function* test_fetchInvalid() { - yield removeCacheFile(); - - Services.prefs.setCharPref(PREF_MANIFEST_URI, gHttpRoot + "experiments_1.manifest"); - let ex = new Experiments.Experiments(gPolicy); - yield ex.updateManifest(); - Assert.notEqual(ex._experiments.size, 0, "There should be experiments"); - - Services.prefs.setCharPref(PREF_MANIFEST_URI, gHttpRoot + "invalid.manifest"); - yield ex.updateManifest() - Assert.notEqual(ex._experiments.size, 0, "There should still be experiments: fetch failure shouldn't remove them."); - - yield promiseRestartManager(); -}); diff --git a/browser/experiments/test/xpcshell/test_nethang_bug1012924.js b/browser/experiments/test/xpcshell/test_nethang_bug1012924.js deleted file mode 100644 index 7ef604901..000000000 --- a/browser/experiments/test/xpcshell/test_nethang_bug1012924.js +++ /dev/null @@ -1,47 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -Cu.import("resource://testing-common/httpd.js"); -Cu.import("resource:///modules/experiments/Experiments.jsm"); - -const MANIFEST_HANDLER = "manifests/handler"; - -function run_test() { - run_next_test(); -} - -add_task(function* test_setup() { - loadAddonManager(); - do_get_profile(); - - let httpServer = new HttpServer(); - httpServer.start(-1); - let port = httpServer.identity.primaryPort; - let httpRoot = "http://localhost:" + port + "/"; - let handlerURI = httpRoot + MANIFEST_HANDLER; - httpServer.registerPathHandler("/" + MANIFEST_HANDLER, - (request, response) => { - response.processAsync(); - response.setStatus(null, 200, "OK"); - response.write("["); // never finish! - }); - - do_register_cleanup(() => httpServer.stop(() => {})); - Services.prefs.setBoolPref(PREF_EXPERIMENTS_ENABLED, true); - Services.prefs.setIntPref(PREF_LOGGING_LEVEL, 0); - Services.prefs.setBoolPref(PREF_LOGGING_DUMP, true); - Services.prefs.setCharPref(PREF_MANIFEST_URI, handlerURI); - Services.prefs.setIntPref(PREF_FETCHINTERVAL, 0); - - let experiments = Experiments.instance(); - experiments.updateManifest().then( - () => { - Assert.ok(true, "updateManifest finished successfully"); - }, - (e) => { - do_throw("updateManifest should not have failed: got error " + e); - }); - yield experiments.uninit(); -}); diff --git a/browser/experiments/test/xpcshell/test_previous_provider.js b/browser/experiments/test/xpcshell/test_previous_provider.js deleted file mode 100644 index f7186e159..000000000 --- a/browser/experiments/test/xpcshell/test_previous_provider.js +++ /dev/null @@ -1,179 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -Cu.import("resource://gre/modules/Promise.jsm"); -Cu.import("resource:///modules/experiments/Experiments.jsm"); -Cu.import("resource://testing-common/httpd.js"); - -var gDataRoot; -var gHttpServer; -var gManifestObject; - -function run_test() { - run_next_test(); -} - -add_task(function test_setup() { - loadAddonManager(); - do_get_profile(); - - gHttpServer = new HttpServer(); - gHttpServer.start(-1); - let httpRoot = "http://localhost:" + gHttpServer.identity.primaryPort + "/"; - gDataRoot = httpRoot + "data/"; - gHttpServer.registerDirectory("/data/", do_get_cwd()); - gHttpServer.registerPathHandler("/manifests/handler", (req, res) => { - res.setStatusLine(null, 200, "OK"); - res.write(JSON.stringify(gManifestObject)); - res.processAsync(); - res.finish(); - }); - do_register_cleanup(() => gHttpServer.stop(() => {})); - - Services.prefs.setBoolPref("experiments.enabled", true); - Services.prefs.setCharPref("experiments.manifest.uri", - httpRoot + "manifests/handler"); - Services.prefs.setBoolPref("experiments.logging.dump", true); - Services.prefs.setCharPref("experiments.logging.level", "Trace"); -}); - -add_task(function* test_provider_basic() { - let e = Experiments.instance(); - - let provider = new Experiments.PreviousExperimentProvider(e); - e._setPreviousExperimentsProvider(provider); - - let deferred = Promise.defer(); - provider.getAddonsByTypes(["experiment"], (addons) => { - deferred.resolve(addons); - }); - let experimentAddons = yield deferred.promise; - Assert.ok(Array.isArray(experimentAddons), "getAddonsByTypes returns an Array."); - Assert.equal(experimentAddons.length, 0, "No previous add-ons returned."); - - gManifestObject = { - version: 1, - experiments: [ - { - id: EXPERIMENT1_ID, - xpiURL: gDataRoot + EXPERIMENT1_XPI_NAME, - xpiHash: EXPERIMENT1_XPI_SHA1, - startTime: Date.now() / 1000 - 60, - endTime: Date.now() / 1000 + 60, - maxActiveSeconds: 60, - appName: ["XPCShell"], - channel: [e._policy.updatechannel()], - }, - ], - }; - - yield e.updateManifest(); - - deferred = Promise.defer(); - provider.getAddonsByTypes(["experiment"], (addons) => { - deferred.resolve(addons); - }); - experimentAddons = yield deferred.promise; - Assert.equal(experimentAddons.length, 0, "Still no previous experiment."); - - let experiments = yield e.getExperiments(); - Assert.equal(experiments.length, 1, "1 experiment present."); - Assert.ok(experiments[0].active, "It is active."); - - // Deactivate it. - defineNow(e._policy, new Date(gManifestObject.experiments[0].endTime * 1000 + 1000)); - yield e.updateManifest(); - - experiments = yield e.getExperiments(); - Assert.equal(experiments.length, 1, "1 experiment present."); - Assert.equal(experiments[0].active, false, "It isn't active."); - - deferred = Promise.defer(); - provider.getAddonsByTypes(["experiment"], (addons) => { - deferred.resolve(addons); - }); - experimentAddons = yield deferred.promise; - Assert.equal(experimentAddons.length, 1, "1 previous add-on known."); - Assert.equal(experimentAddons[0].id, EXPERIMENT1_ID, "ID matches expected."); - - deferred = Promise.defer(); - provider.getAddonByID(EXPERIMENT1_ID, (addon) => { - deferred.resolve(addon); - }); - let addon = yield deferred.promise; - Assert.ok(addon, "We got an add-on from its ID."); - Assert.equal(addon.id, EXPERIMENT1_ID, "ID matches expected."); - Assert.ok(addon.appDisabled, "Add-on is a previous experiment."); - Assert.ok(addon.userDisabled, "Add-on is disabled."); - Assert.equal(addon.type, "experiment", "Add-on is an experiment."); - Assert.equal(addon.isActive, false, "Add-on is not active."); - Assert.equal(addon.permissions, 0, "Add-on has no permissions."); - - deferred = Promise.defer(); - AddonManager.getAddonsByTypes(["experiment"], (addons) => { - deferred.resolve(addons); - }); - experimentAddons = yield deferred.promise; - Assert.equal(experimentAddons.length, 1, "Got 1 experiment from add-on manager."); - Assert.equal(experimentAddons[0].id, EXPERIMENT1_ID, "ID matches expected."); - Assert.ok(experimentAddons[0].appDisabled, "It is a previous experiment add-on."); -}); - -add_task(function* test_active_and_previous() { - // Building on the previous test, activate experiment 2. - let e = Experiments.instance(); - let provider = new Experiments.PreviousExperimentProvider(e); - e._setPreviousExperimentsProvider(provider); - - gManifestObject = { - version: 1, - experiments: [ - { - id: EXPERIMENT2_ID, - xpiURL: gDataRoot + EXPERIMENT2_XPI_NAME, - xpiHash: EXPERIMENT2_XPI_SHA1, - startTime: Date.now() / 1000 - 60, - endTime: Date.now() / 1000 + 60, - maxActiveSeconds: 60, - appName: ["XPCShell"], - channel: [e._policy.updatechannel()], - }, - ], - }; - - defineNow(e._policy, new Date()); - yield e.updateManifest(); - - let experiments = yield e.getExperiments(); - Assert.equal(experiments.length, 2, "2 experiments known."); - - let deferred = Promise.defer(); - provider.getAddonsByTypes(["experiment"], (addons) => { - deferred.resolve(addons); - }); - let experimentAddons = yield deferred.promise; - Assert.equal(experimentAddons.length, 1, "1 previous experiment."); - - deferred = Promise.defer(); - AddonManager.getAddonsByTypes(["experiment"], (addons) => { - deferred.resolve(addons); - }); - experimentAddons = yield deferred.promise; - Assert.equal(experimentAddons.length, 2, "2 experiment add-ons known."); - - for (let addon of experimentAddons) { - if (addon.id == EXPERIMENT1_ID) { - Assert.equal(addon.isActive, false, "Add-on is not active."); - Assert.ok(addon.appDisabled, "Should be a previous experiment."); - } - else if (addon.id == EXPERIMENT2_ID) { - Assert.ok(addon.isActive, "Add-on is active."); - Assert.ok(!addon.appDisabled, "Should not be a previous experiment."); - } - else { - throw new Error("Unexpected add-on ID: " + addon.id); - } - } -}); diff --git a/browser/experiments/test/xpcshell/test_telemetry.js b/browser/experiments/test/xpcshell/test_telemetry.js deleted file mode 100644 index 02bd15d2b..000000000 --- a/browser/experiments/test/xpcshell/test_telemetry.js +++ /dev/null @@ -1,294 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -Cu.import("resource://testing-common/httpd.js"); -Cu.import("resource://gre/modules/TelemetryLog.jsm"); -var bsp = Cu.import("resource:///modules/experiments/Experiments.jsm"); - - -const MANIFEST_HANDLER = "manifests/handler"; - -const SEC_IN_ONE_DAY = 24 * 60 * 60; -const MS_IN_ONE_DAY = SEC_IN_ONE_DAY * 1000; - - -var gHttpServer = null; -var gHttpRoot = null; -var gDataRoot = null; -var gPolicy = null; -var gManifestObject = null; -var gManifestHandlerURI = null; - -const TLOG = bsp.TELEMETRY_LOG; - -function checkEvent(event, id, data) -{ - do_print("Checking message " + id); - Assert.equal(event[0], id, "id should match"); - Assert.ok(event[1] > 0, "timestamp should be greater than 0"); - - if (data === undefined) { - Assert.equal(event.length, 2, "event array should have 2 entries"); - } else { - Assert.equal(event.length, data.length + 2, "event entry count should match expected count"); - for (var i = 0; i < data.length; ++i) { - Assert.equal(typeof(event[i + 2]), "string", "event entry should be a string"); - Assert.equal(event[i + 2], data[i], "event entry should match expected entry"); - } - } -} - -function run_test() { - run_next_test(); -} - -add_task(function* test_setup() { - loadAddonManager(); - - gHttpServer = new HttpServer(); - gHttpServer.start(-1); - let port = gHttpServer.identity.primaryPort; - gHttpRoot = "http://localhost:" + port + "/"; - gDataRoot = gHttpRoot + "data/"; - gManifestHandlerURI = gHttpRoot + MANIFEST_HANDLER; - gHttpServer.registerDirectory("/data/", do_get_cwd()); - gHttpServer.registerPathHandler("/" + MANIFEST_HANDLER, (request, response) => { - response.setStatusLine(null, 200, "OK"); - response.write(JSON.stringify(gManifestObject)); - response.processAsync(); - response.finish(); - }); - do_register_cleanup(() => gHttpServer.stop(() => {})); - - Services.prefs.setBoolPref(PREF_EXPERIMENTS_ENABLED, true); - Services.prefs.setIntPref(PREF_LOGGING_LEVEL, 0); - Services.prefs.setBoolPref(PREF_LOGGING_DUMP, true); - Services.prefs.setCharPref(PREF_MANIFEST_URI, gManifestHandlerURI); - Services.prefs.setIntPref(PREF_FETCHINTERVAL, 0); - - gPolicy = new Experiments.Policy(); - let dummyTimer = { cancel: () => {}, clear: () => {} }; - patchPolicy(gPolicy, { - updatechannel: () => "nightly", - oneshotTimer: (callback, timeout, thisObj, name) => dummyTimer, - }); - - yield removeCacheFile(); -}); - -// Test basic starting and stopping of experiments. - -add_task(function* test_telemetryBasics() { - // Check TelemetryLog instead of TelemetrySession.getPayload().log because - // TelemetrySession gets Experiments.instance() and side-effects log entries. - - let expectedLogLength = 0; - - // Dates the following tests are based on. - - let baseDate = new Date(2014, 5, 1, 12); - let startDate1 = futureDate(baseDate, 50 * MS_IN_ONE_DAY); - let endDate1 = futureDate(baseDate, 100 * MS_IN_ONE_DAY); - let startDate2 = futureDate(baseDate, 150 * MS_IN_ONE_DAY); - let endDate2 = futureDate(baseDate, 200 * MS_IN_ONE_DAY); - - // The manifest data we test with. - - gManifestObject = { - "version": 1, - experiments: [ - { - id: EXPERIMENT1_ID, - xpiURL: gDataRoot + EXPERIMENT1_XPI_NAME, - xpiHash: EXPERIMENT1_XPI_SHA1, - startTime: dateToSeconds(startDate1), - endTime: dateToSeconds(endDate1), - maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - appName: ["XPCShell"], - channel: ["nightly"], - }, - { - id: EXPERIMENT2_ID, - xpiURL: gDataRoot + EXPERIMENT2_XPI_NAME, - xpiHash: EXPERIMENT2_XPI_SHA1, - startTime: dateToSeconds(startDate2), - endTime: dateToSeconds(endDate2), - maxActiveSeconds: 10 * SEC_IN_ONE_DAY, - appName: ["XPCShell"], - channel: ["nightly"], - }, - ], - }; - - let experiments = new Experiments.Experiments(gPolicy); - - // Trigger update, clock set to before any activation. - // Use updateManifest() to provide for coverage of that path. - - let now = baseDate; - defineNow(gPolicy, now); - - yield experiments.updateManifest(); - let list = yield experiments.getExperiments(); - Assert.equal(list.length, 0, "Experiment list should be empty."); - - expectedLogLength += 2; - let log = TelemetryLog.entries(); - do_print("Telemetry log: " + JSON.stringify(log)); - Assert.equal(log.length, expectedLogLength, "Telemetry log should have " + expectedLogLength + " entries."); - checkEvent(log[log.length-2], TLOG.ACTIVATION_KEY, - [TLOG.ACTIVATION.REJECTED, EXPERIMENT1_ID, "startTime"]); - checkEvent(log[log.length-1], TLOG.ACTIVATION_KEY, - [TLOG.ACTIVATION.REJECTED, EXPERIMENT2_ID, "startTime"]); - - // Trigger update, clock set for experiment 1 to start. - - now = futureDate(startDate1, 5 * MS_IN_ONE_DAY); - defineNow(gPolicy, now); - - yield experiments.updateManifest(); - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry now."); - - expectedLogLength += 1; - log = TelemetryLog.entries(); - Assert.equal(log.length, expectedLogLength, "Telemetry log should have " + expectedLogLength + " entries. Got " + log.toSource()); - checkEvent(log[log.length-1], TLOG.ACTIVATION_KEY, - [TLOG.ACTIVATION.ACTIVATED, EXPERIMENT1_ID]); - - // Trigger update, clock set for experiment 1 to stop. - - now = futureDate(endDate1, 1000); - defineNow(gPolicy, now); - - yield experiments.updateManifest(); - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entry."); - - expectedLogLength += 2; - log = TelemetryLog.entries(); - Assert.equal(log.length, expectedLogLength, "Telemetry log should have " + expectedLogLength + " entries."); - checkEvent(log[log.length-2], TLOG.TERMINATION_KEY, - [TLOG.TERMINATION.EXPIRED, EXPERIMENT1_ID]); - checkEvent(log[log.length-1], TLOG.ACTIVATION_KEY, - [TLOG.ACTIVATION.REJECTED, EXPERIMENT2_ID, "startTime"]); - - // Trigger update, clock set for experiment 2 to start with invalid hash. - - now = startDate2; - defineNow(gPolicy, now); - gManifestObject.experiments[1].xpiHash = "sha1:0000000000000000000000000000000000000000"; - - yield experiments.updateManifest(); - list = yield experiments.getExperiments(); - Assert.equal(list.length, 1, "Experiment list should have 1 entries."); - - expectedLogLength += 1; - log = TelemetryLog.entries(); - Assert.equal(log.length, expectedLogLength, "Telemetry log should have " + expectedLogLength + " entries."); - checkEvent(log[log.length-1], TLOG.ACTIVATION_KEY, - [TLOG.ACTIVATION.INSTALL_FAILURE, EXPERIMENT2_ID]); - - // Trigger update, clock set for experiment 2 to properly start now. - - now = futureDate(now, MS_IN_ONE_DAY); - defineNow(gPolicy, now); - gManifestObject.experiments[1].xpiHash = EXPERIMENT2_XPI_SHA1; - - yield experiments.updateManifest(); - list = yield experiments.getExperiments(); - Assert.equal(list.length, 2, "Experiment list should have 2 entries."); - - expectedLogLength += 1; - log = TelemetryLog.entries(); - Assert.equal(log.length, expectedLogLength, "Telemetry log should have " + expectedLogLength + " entries."); - checkEvent(log[log.length-1], TLOG.ACTIVATION_KEY, - [TLOG.ACTIVATION.ACTIVATED, EXPERIMENT2_ID]); - - // Fake user uninstall of experiment via add-on manager. - - now = futureDate(now, MS_IN_ONE_DAY); - defineNow(gPolicy, now); - - yield experiments.disableExperiment(TLOG.TERMINATION.ADDON_UNINSTALLED); - list = yield experiments.getExperiments(); - Assert.equal(list.length, 2, "Experiment list should have 2 entries."); - - expectedLogLength += 1; - log = TelemetryLog.entries(); - Assert.equal(log.length, expectedLogLength, "Telemetry log should have " + expectedLogLength + " entries."); - checkEvent(log[log.length-1], TLOG.TERMINATION_KEY, - [TLOG.TERMINATION.ADDON_UNINSTALLED, EXPERIMENT2_ID]); - - // Trigger update with experiment 1a ready to start. - - now = futureDate(now, MS_IN_ONE_DAY); - defineNow(gPolicy, now); - gManifestObject.experiments[0].id = EXPERIMENT3_ID; - gManifestObject.experiments[0].endTime = dateToSeconds(futureDate(now, 50 * MS_IN_ONE_DAY)); - - yield experiments.updateManifest(); - list = yield experiments.getExperiments(); - Assert.equal(list.length, 3, "Experiment list should have 3 entries."); - - expectedLogLength += 1; - log = TelemetryLog.entries(); - Assert.equal(log.length, expectedLogLength, "Telemetry log should have " + expectedLogLength + " entries."); - checkEvent(log[log.length-1], TLOG.ACTIVATION_KEY, - [TLOG.ACTIVATION.ACTIVATED, EXPERIMENT3_ID]); - - // Trigger disable of an experiment via the API. - - now = futureDate(now, MS_IN_ONE_DAY); - defineNow(gPolicy, now); - - yield experiments.disableExperiment(TLOG.TERMINATION.FROM_API); - list = yield experiments.getExperiments(); - Assert.equal(list.length, 3, "Experiment list should have 3 entries."); - - expectedLogLength += 1; - log = TelemetryLog.entries(); - Assert.equal(log.length, expectedLogLength, "Telemetry log should have " + expectedLogLength + " entries."); - checkEvent(log[log.length-1], TLOG.TERMINATION_KEY, - [TLOG.TERMINATION.FROM_API, EXPERIMENT3_ID]); - - // Trigger update with experiment 1a ready to start. - - now = futureDate(now, MS_IN_ONE_DAY); - defineNow(gPolicy, now); - gManifestObject.experiments[0].id = EXPERIMENT4_ID; - gManifestObject.experiments[0].endTime = dateToSeconds(futureDate(now, 50 * MS_IN_ONE_DAY)); - - yield experiments.updateManifest(); - list = yield experiments.getExperiments(); - Assert.equal(list.length, 4, "Experiment list should have 4 entries."); - - expectedLogLength += 1; - log = TelemetryLog.entries(); - Assert.equal(log.length, expectedLogLength, "Telemetry log should have " + expectedLogLength + " entries."); - checkEvent(log[log.length-1], TLOG.ACTIVATION_KEY, - [TLOG.ACTIVATION.ACTIVATED, EXPERIMENT4_ID]); - - // Trigger experiment termination by something other than expiry via the manifest. - - now = futureDate(now, MS_IN_ONE_DAY); - defineNow(gPolicy, now); - gManifestObject.experiments[0].os = "Plan9"; - - yield experiments.updateManifest(); - list = yield experiments.getExperiments(); - Assert.equal(list.length, 4, "Experiment list should have 4 entries."); - - expectedLogLength += 1; - log = TelemetryLog.entries(); - Assert.equal(log.length, expectedLogLength, "Telemetry log should have " + expectedLogLength + " entries."); - checkEvent(log[log.length-1], TLOG.TERMINATION_KEY, - [TLOG.TERMINATION.RECHECK, EXPERIMENT4_ID, "os"]); - - // Cleanup. - - yield promiseRestartManager(); - yield removeCacheFile(); -}); diff --git a/browser/experiments/test/xpcshell/test_telemetry_disabled.js b/browser/experiments/test/xpcshell/test_telemetry_disabled.js deleted file mode 100644 index 74f85ccfc..000000000 --- a/browser/experiments/test/xpcshell/test_telemetry_disabled.js +++ /dev/null @@ -1,21 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -Cu.import("resource:///modules/experiments/Experiments.jsm"); - -add_test(function test_experiments_activation() { - do_get_profile(); - loadAddonManager(); - - Services.prefs.setBoolPref(PREF_EXPERIMENTS_ENABLED, true); - Services.prefs.setBoolPref(PREF_TELEMETRY_ENABLED, false); - - let experiments = Experiments.instance(); - Assert.ok(!experiments.enabled, "Experiments must be disabled if Telemetry is disabled."); - - // TODO: Test that Experiments are turned back on when bug 1232648 lands. - - run_next_test(); -}); diff --git a/browser/experiments/test/xpcshell/test_upgrade.js b/browser/experiments/test/xpcshell/test_upgrade.js deleted file mode 100644 index f094a406d..000000000 --- a/browser/experiments/test/xpcshell/test_upgrade.js +++ /dev/null @@ -1,52 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; -Cu.import("resource:///modules/experiments/Experiments.jsm"); - -var cacheData = { - _enabled: true, - _manifestData: { - id: "foobartestid", - xpiURL: "http://example.com/foo.xpi", - xpiHash: "sha256:abcde", - startTime: 0, - endTime: 2000000000, - maxActiveSeconds: 40000000, - appName: "TestApp", - channel: "test-foo", - }, - _needsUpdate: false, - _randomValue: 0.5, - _failedStart: false, - _name: "Foo", - _description: "Foobar", - _homepageURL: "", - _addonId: "foo@test", - _startDate: 0, - _endDate: 2000000000, - _branch: null -}; - -add_task(function* test_valid() { - let e = new Experiments.ExperimentEntry(); - Assert.ok(e.initFromCacheData(cacheData)); - Assert.ok(e.enabled); -}); - -add_task(function* test_upgrade() { - let e = new Experiments.ExperimentEntry(); - delete cacheData._branch; - Assert.ok(e.initFromCacheData(cacheData)); - Assert.ok(e.enabled); -}); - -add_task(function* test_missing() { - let e = new Experiments.ExperimentEntry(); - delete cacheData._name; - Assert.ok(!e.initFromCacheData(cacheData)); -}); - -function run_test() { - run_next_test(); -} diff --git a/browser/experiments/test/xpcshell/xpcshell.ini b/browser/experiments/test/xpcshell/xpcshell.ini deleted file mode 100644 index 5921c9c47..000000000 --- a/browser/experiments/test/xpcshell/xpcshell.ini +++ /dev/null @@ -1,31 +0,0 @@ -[DEFAULT] -head = head.js -tail = -tags = addons -firefox-appdir = browser -skip-if = toolkit == 'android' -support-files = - experiments_1.manifest - experiment-1.xpi - experiment-1a.xpi - experiment-2.xpi - experiment-racybranch.xpi - !/toolkit/mozapps/webextensions/test/xpcshell/head_addons.js -generated-files = - experiment-1.xpi - experiment-1a.xpi - experiment-2.xpi - experiment-racybranch.xpi - -[test_activate.js] -[test_api.js] -[test_cache.js] -[test_cacherace.js] -[test_conditions.js] -[test_disableExperiments.js] -[test_fetch.js] -[test_telemetry.js] -[test_telemetry_disabled.js] -[test_previous_provider.js] -[test_upgrade.js] -[test_nethang_bug1012924.js] diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in index 015daa8c7..5540feed9 100644 --- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -374,8 +374,6 @@ @RESPATH@/browser/components/devtools-startup.js @RESPATH@/browser/components/webideCli.js @RESPATH@/browser/components/webideComponents.manifest -@RESPATH@/browser/components/Experiments.manifest -@RESPATH@/browser/components/ExperimentsService.js @RESPATH@/browser/components/browser-newtab.xpt @RESPATH@/browser/components/aboutNewTabService.js @RESPATH@/browser/components/NewTabComponents.manifest @@ -781,28 +779,6 @@ bin/libfreebl_32int64_3.so @BINPATH@/maintenanceservice_installer.exe #endif -; [Crash Reporter] -; -#ifdef MOZ_CRASHREPORTER -@RESPATH@/components/CrashService.manifest -@RESPATH@/components/CrashService.js -@RESPATH@/components/toolkit_crashservice.xpt -#ifdef XP_MACOSX -@BINPATH@/crashreporter.app/ -#else -@BINPATH@/crashreporter@BIN_SUFFIX@ -@BINPATH@/minidump-analyzer@BIN_SUFFIX@ -@RESPATH@/crashreporter.ini -#ifdef XP_UNIX -@RESPATH@/Throbber-small.gif -#endif -#endif -@RESPATH@/browser/crashreporter-override.ini -#ifdef MOZ_CRASHREPORTER_INJECTOR -@BINPATH@/breakpadinjector.dll -#endif -#endif - @RESPATH@/components/dom_audiochannel.xpt ; Shutdown Terminator diff --git a/browser/locales/Makefile.in b/browser/locales/Makefile.in index b3ecfd359..af200147f 100644 --- a/browser/locales/Makefile.in +++ b/browser/locales/Makefile.in @@ -165,11 +165,6 @@ else endif endif -ifdef MOZ_CRASHREPORTER -libs:: crashreporter-override.ini - $(SYSINSTALL) $(IFLAGS1) $^ $(FINAL_TARGET) -endif - ident: @printf 'fx_revision ' @$(PYTHON) $(topsrcdir)/config/printconfigsetting.py \ diff --git a/browser/modules/AboutHome.jsm b/browser/modules/AboutHome.jsm index 01cbafba9..8c0fc4c15 100644 --- a/browser/modules/AboutHome.jsm +++ b/browser/modules/AboutHome.jsm @@ -24,17 +24,10 @@ XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils", XPCOMUtils.defineLazyModuleGetter(this, "Promise", "resource://gre/modules/Promise.jsm"); -// Url to fetch snippets, in the urlFormatter service format. -const SNIPPETS_URL_PREF = "browser.aboutHomeSnippets.updateUrl"; - -// Should be bumped up if the snippets content format changes. -const STARTPAGE_VERSION = 4; +// Should be bumped up if any data content format changes. +const STARTPAGE_VERSION = 5; this.AboutHomeUtils = { - get snippetsVersion() { - return STARTPAGE_VERSION; - }, - /* * showKnowYourRights - Determines if the user should be shown the * about:rights notification. The notification should *not* be shown if @@ -77,16 +70,6 @@ this.AboutHomeUtils = { }; /** - * Returns the URL to fetch snippets from, in the urlFormatter service format. - */ -XPCOMUtils.defineLazyGetter(AboutHomeUtils, "snippetsURL", function() { - let updateURL = Services.prefs - .getCharPref(SNIPPETS_URL_PREF) - .replace("%STARTPAGE_VERSION%", STARTPAGE_VERSION); - return Services.urlFormatter.formatURL(updateURL); -}); - -/** * This code provides services to the about:home page. Whenever * about:home needs to do something chrome-privileged, it sends a * message that's handled here. @@ -169,9 +152,7 @@ var AboutHome = { ss.promiseInitialized.then(function() { let data = { showRestoreLastSession: ss.canRestoreLastSession, - snippetsURL: AboutHomeUtils.snippetsURL, - showKnowYourRights: AboutHomeUtils.showKnowYourRights, - snippetsVersion: AboutHomeUtils.snippetsVersion, + showKnowYourRights: AboutHomeUtils.showKnowYourRights }; if (AboutHomeUtils.showKnowYourRights) { diff --git a/browser/modules/ContentCrashHandlers.jsm b/browser/modules/ContentCrashHandlers.jsm index 2f755d142..488cc4f26 100644 --- a/browser/modules/ContentCrashHandlers.jsm +++ b/browser/modules/ContentCrashHandlers.jsm @@ -90,8 +90,6 @@ this.TabCrashHandler = { Services.telemetry .getHistogramById("FX_CONTENT_CRASH_DUMP_UNAVAILABLE") .add(1); - } else if (AppConstants.MOZ_CRASHREPORTER) { - this.childMap.set(childID, dumpID); } if (!this.flushCrashedBrowserQueue(childID)) { @@ -115,15 +113,6 @@ this.TabCrashHandler = { } } - // check for environment affecting crash reporting - let env = Cc["@mozilla.org/process/environment;1"] - .getService(Ci.nsIEnvironment); - let shutdown = env.exists("MOZ_CRASHREPORTER_SHUTDOWN"); - - if (shutdown) { - Services.startup.quit(Ci.nsIAppStartup.eForceQuit); - } - break; } case "oop-frameloader-crashed": { @@ -306,105 +295,10 @@ this.TabCrashHandler = { /** * Submits a crash report from about:tabcrashed, if the crash * reporter is enabled and a crash report can be found. - * - * @param aBrowser - * The <xul:browser> that the report was sent from. - * @param aFormData - * An Object with the following properties: - * - * includeURL (bool): - * Whether to include the URL that the user was on - * in the crashed tab before the crash occurred. - * URL (String) - * The URL that the user was on in the crashed tab - * before the crash occurred. - * emailMe (bool): - * Whether or not to include the user's email address - * in the crash report. - * email (String): - * The email address of the user. - * comments (String): - * Any additional comments from the user. - * - * Note that it is expected that all properties are set, - * even if they are empty. */ maybeSendCrashReport(message) { - if (!AppConstants.MOZ_CRASHREPORTER) { - return; - } - - if (!message.data.hasReport) { - // There was no report, so nothing to do. - return; - } - - let browser = message.target.browser; - - if (message.data.autoSubmit) { - // The user has opted in to autosubmitted backlogged - // crash reports in the future. - UnsubmittedCrashHandler.autoSubmit = true; - } - - let childID = this.browserMap.get(browser.permanentKey); - let dumpID = this.childMap.get(childID); - if (!dumpID) { - return; - } - - if (!message.data.sendReport) { - Services.telemetry.getHistogramById("FX_CONTENT_CRASH_NOT_SUBMITTED").add(1); - this.prefs.setBoolPref("sendReport", false); - return; - } - - let { - includeURL, - comments, - email, - emailMe, - URL, - } = message.data; - - let extraExtraKeyVals = { - "Comments": comments, - "Email": email, - "URL": URL, - }; - - // For the entries in extraExtraKeyVals, we only want to submit the - // extra data values where they are not the empty string. - for (let key in extraExtraKeyVals) { - let val = extraExtraKeyVals[key].trim(); - if (!val) { - delete extraExtraKeyVals[key]; - } - } - - // URL is special, since it's already been written to extra data by - // default. In order to make sure we don't send it, we overwrite it - // with the empty string. - if (!includeURL) { - extraExtraKeyVals["URL"] = ""; - } - - CrashSubmit.submit(dumpID, { - recordSubmission: true, - extraExtraKeyVals, - }).then(null, Cu.reportError); - - this.prefs.setBoolPref("sendReport", true); - this.prefs.setBoolPref("includeURL", includeURL); - this.prefs.setBoolPref("emailMe", emailMe); - if (emailMe) { - this.prefs.setCharPref("email", email); - } else { - this.prefs.setCharPref("email", ""); - } - - this.childMap.set(childID, null); // Avoid resubmission. - this.removeSubmitCheckboxesForSameCrash(childID); + /*** STUB ***/ + return; }, removeSubmitCheckboxesForSameCrash: function(childID) { @@ -518,17 +412,10 @@ this.TabCrashHandler = { /** * For some <xul:browser>, return a crash report dump ID for that browser * if we have been informed of one. Otherwise, return null. - * - * @param browser (<xul:browser) - * The browser to try to get the dump ID for - * @returns dumpID (String) */ getDumpID(browser) { - if (!AppConstants.MOZ_CRASHREPORTER) { - return null; - } - - return this.childMap.get(this.browserMap.get(browser.permanentKey)); + /*** STUB ***/ + return null; }, } diff --git a/browser/modules/PluginContent.jsm b/browser/modules/PluginContent.jsm index 1bbfa9a50..622d608bc 100644 --- a/browser/modules/PluginContent.jsm +++ b/browser/modules/PluginContent.jsm @@ -660,30 +660,8 @@ PluginContent.prototype = { }, submitReport: function submitReport(plugin) { - if (!AppConstants.MOZ_CRASHREPORTER) { - return; - } - if (!plugin) { - Cu.reportError("Attempted to submit crash report without an associated plugin."); - return; - } - if (!(plugin instanceof Ci.nsIObjectLoadingContent)) { - Cu.reportError("Attempted to submit crash report on plugin that does not" + - "implement nsIObjectLoadingContent."); - return; - } - - let runID = plugin.runID; - let submitURLOptIn = this.getPluginUI(plugin, "submitURLOptIn").checked; - let keyVals = {}; - let userComment = this.getPluginUI(plugin, "submitComment").value.trim(); - if (userComment) - keyVals.PluginUserComment = userComment; - if (submitURLOptIn) - keyVals.PluginContentURL = plugin.ownerDocument.URL; - - this.global.sendAsyncMessage("PluginContent:SubmitReport", - { runID, keyVals, submitURLOptIn }); + /*** STUB ***/ + return; }, reloadPage: function () { diff --git a/browser/moz.build b/browser/moz.build index a691aeef2..0985148c0 100644 --- a/browser/moz.build +++ b/browser/moz.build @@ -11,7 +11,6 @@ SPHINX_TREES['browser'] = 'docs' DIRS += [ 'base', 'components', - 'experiments', 'fonts', 'locales', 'modules', diff --git a/browser/themes/osx/shared.inc b/browser/themes/osx/shared.inc index b3ea4e199..3076450e2 100644 --- a/browser/themes/osx/shared.inc +++ b/browser/themes/osx/shared.inc @@ -1,4 +1,4 @@ -%include ../../../toolkit/themes/osx/global/shared.inc
+%include ../../../../toolkit/themes/osx/global/shared.inc
%include ../shared/browser.inc
%filter substitution
diff --git a/build/application.ini b/build/application.ini index 6b2e43a34..e60f86b69 100644 --- a/build/application.ini +++ b/build/application.ini @@ -54,8 +54,3 @@ MaxVersion=@GRE_MILESTONE@ EnableProfileMigrator=1 #endif -#if MOZ_CRASHREPORTER -[Crash Reporter] -Enabled=1 -ServerURL=https://crash-reports.mozilla.com/submit?id=@MOZ_APP_ID@&version=@MOZ_APP_VERSION@&buildid=@MOZ_BUILDID@ -#endif diff --git a/build/automation-build.mk b/build/automation-build.mk index e25f90c5d..6599cb032 100644 --- a/build/automation-build.mk +++ b/build/automation-build.mk @@ -48,11 +48,7 @@ else AUTOMATION_PPARGS += -DIS_DEBUG_BUILD=0 endif -ifdef MOZ_CRASHREPORTER -AUTOMATION_PPARGS += -DCRASHREPORTER=1 -else AUTOMATION_PPARGS += -DCRASHREPORTER=0 -endif ifdef MOZ_ASAN AUTOMATION_PPARGS += -DIS_ASAN=1 diff --git a/build/automation.py.in b/build/automation.py.in index 1c63977e8..09c9d0071 100644 --- a/build/automation.py.in +++ b/build/automation.py.in @@ -228,11 +228,7 @@ class Automation(object): if dmdPath and dmdLibrary and preloadEnvVar: env[preloadEnvVar] = os.path.join(dmdPath, dmdLibrary) - if crashreporter and not debugger: - env['MOZ_CRASHREPORTER_NO_REPORT'] = '1' - env['MOZ_CRASHREPORTER'] = '1' - else: - env['MOZ_CRASHREPORTER_DISABLE'] = '1' + env['MOZ_CRASHREPORTER_DISABLE'] = '1' # Crash on non-local network connections by default. # MOZ_DISABLE_NONLOCAL_CONNECTIONS can be set to "0" to temporarily diff --git a/build/directive4.py b/build/directive4.py index 8f05eeed5..dd8c111cf 100644 --- a/build/directive4.py +++ b/build/directive4.py @@ -49,6 +49,7 @@ if ('MOZ_OFFICIAL_BRANDING' in listConfig) or (strBrandingDirectory.endswith("br # Applies to Pale Moon Only if 'MC_PALEMOON' in listConfig: listViolations += [ + 'MOZ_EME', 'MOZ_WEBRTC' ] diff --git a/build/mobile/b2gautomation.py b/build/mobile/b2gautomation.py index d73edd419..a21809068 100644 --- a/build/mobile/b2gautomation.py +++ b/build/mobile/b2gautomation.py @@ -156,10 +156,6 @@ class B2GRemoteAutomation(Automation): if env is None: env = {} - if crashreporter: - env['MOZ_CRASHREPORTER'] = '1' - env['MOZ_CRASHREPORTER_NO_REPORT'] = '1' - # We always hide the results table in B2G; it's much slower if we don't. env['MOZ_HIDE_RESULTS_TABLE'] = '1' return env diff --git a/build/mobile/remoteautomation.py b/build/mobile/remoteautomation.py index 1358e0dfe..f098d5bba 100644 --- a/build/mobile/remoteautomation.py +++ b/build/mobile/remoteautomation.py @@ -74,11 +74,7 @@ class RemoteAutomation(Automation): if 'MOZ_HIDE_RESULTS_TABLE' in os.environ: env['MOZ_HIDE_RESULTS_TABLE'] = os.environ['MOZ_HIDE_RESULTS_TABLE'] - if crashreporter and not debugger: - env['MOZ_CRASHREPORTER_NO_REPORT'] = '1' - env['MOZ_CRASHREPORTER'] = '1' - else: - env['MOZ_CRASHREPORTER_DISABLE'] = '1' + env['MOZ_CRASHREPORTER_DISABLE'] = '1' # Crash on non-local network connections by default. # MOZ_DISABLE_NONLOCAL_CONNECTIONS can be set to "0" to temporarily @@ -215,36 +211,9 @@ class RemoteAutomation(Automation): if javaException: return True - # If crash reporting is disabled (MOZ_CRASHREPORTER!=1), we can't say - # anything. - if not self.CRASHREPORTER: - return False - - try: - dumpDir = tempfile.mkdtemp() - remoteCrashDir = posixpath.join(self._remoteProfile, 'minidumps') - if not self._devicemanager.dirExists(remoteCrashDir): - # If crash reporting is enabled (MOZ_CRASHREPORTER=1), the - # minidumps directory is automatically created when Fennec - # (first) starts, so its lack of presence is a hint that - # something went wrong. - print "Automation Error: No crash directory (%s) found on remote device" % remoteCrashDir - # Whilst no crash was found, the run should still display as a failure - return True - self._devicemanager.getDirectory(remoteCrashDir, dumpDir) + # No crash reporting means we can't say anything. + return False - logger = get_default_logger() - if logger is not None: - crashed = mozcrash.log_crashes(logger, dumpDir, symbolsPath, test=self.lastTestSeen) - else: - crashed = Automation.checkForCrashes(self, dumpDir, symbolsPath) - - finally: - try: - shutil.rmtree(dumpDir) - except: - print "WARNING: unable to remove directory: %s" % dumpDir - return crashed def buildCommandLine(self, app, debuggerInfo, profileDir, testURL, extraArgs): # If remote profile is specified, use that instead diff --git a/build/moz.build b/build/moz.build index 8d86b52bf..f25e5cfa5 100644 --- a/build/moz.build +++ b/build/moz.build @@ -42,7 +42,7 @@ if CONFIG['MC_PALEMOON']: if CONFIG['MOZ_APP_PROFILE']: DEFINES['MOZ_APP_PROFILE'] = CONFIG['MOZ_APP_PROFILE'] -for var in ('MOZ_CRASHREPORTER', 'MOZ_PROFILE_MIGRATOR', +for var in ('MOZ_PROFILE_MIGRATOR', 'MOZ_APP_STATIC_INI'): if CONFIG[var]: DEFINES[var] = True diff --git a/build/pgo/profileserver.py b/build/pgo/profileserver.py index 3e5a870c3..adc93d9b1 100644 --- a/build/pgo/profileserver.py +++ b/build/pgo/profileserver.py @@ -53,7 +53,6 @@ if __name__ == '__main__': locations=locations) env = os.environ.copy() - env["MOZ_CRASHREPORTER_NO_REPORT"] = "1" env["XPCOM_DEBUG_BREAK"] = "warn" # For VC12+, make sure we can find the right bitness of pgort1x0.dll diff --git a/build/valgrind/mach_commands.py b/build/valgrind/mach_commands.py index ba2575247..8109f0784 100644 --- a/build/valgrind/mach_commands.py +++ b/build/valgrind/mach_commands.py @@ -90,7 +90,6 @@ class MachCommands(MachCommandBase): env = os.environ.copy() env['G_SLICE'] = 'always-malloc' env['MOZ_CC_RUN_DURING_SHUTDOWN'] = '1' - env['MOZ_CRASHREPORTER_NO_REPORT'] = '1' env['XPCOM_DEBUG_BREAK'] = 'warn' env.update(self.extra_environment_variables) diff --git a/caps/BasePrincipal.cpp b/caps/BasePrincipal.cpp index b768d5c1f..93ffcf129 100644 --- a/caps/BasePrincipal.cpp +++ b/caps/BasePrincipal.cpp @@ -7,9 +7,6 @@ #include "mozilla/BasePrincipal.h" #include "nsDocShell.h" -#ifdef MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" -#endif #include "nsIAddonPolicyService.h" #include "nsIContentSecurityPolicy.h" #include "nsIEffectiveTLDService.h" @@ -149,10 +146,6 @@ OriginAttributes::CreateSuffix(nsACString& aStr) const if (!mAddonId.IsEmpty()) { if (mAddonId.FindCharInSet(dom::quota::QuotaManager::kReplaceChars) != kNotFound) { -#ifdef MOZ_CRASHREPORTER - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Crash_AddonId"), - NS_ConvertUTF16toUTF8(mAddonId)); -#endif MOZ_CRASH(); } params->Set(NS_LITERAL_STRING("addonId"), mAddonId); diff --git a/devtools/client/commandline/test/browser_cmd_csscoverage_startstop.js b/devtools/client/commandline/test/browser_cmd_csscoverage_startstop.js index 2bdb86d86..c48136989 100644 --- a/devtools/client/commandline/test/browser_cmd_csscoverage_startstop.js +++ b/devtools/client/commandline/test/browser_cmd_csscoverage_startstop.js @@ -4,6 +4,7 @@ // Tests that the addon commands works as they should const csscoverage = require("devtools/shared/fronts/csscoverage"); +const {gDevTools} = require("devtools/client/framework/devtools"); const PAGE_1 = TEST_BASE_HTTPS + "browser_cmd_csscoverage_page1.html"; const PAGE_2 = TEST_BASE_HTTPS + "browser_cmd_csscoverage_page2.html"; diff --git a/devtools/client/framework/browser-menus.js b/devtools/client/framework/browser-menus.js index 3d6c4def6..e62afddac 100644 --- a/devtools/client/framework/browser-menus.js +++ b/devtools/client/framework/browser-menus.js @@ -133,10 +133,11 @@ function attachKeybindingsToBrowser(doc, keys) { */ function createToolMenuElements(toolDefinition, doc) { let id = toolDefinition.id; + let appmenuId = "appmenuitem_" + id; let menuId = "menuitem_" + id; // Prevent multiple entries for the same tool. - if (doc.getElementById(menuId)) { + if (doc.getElementById(appmenuId) || doc.getElementById(menuId)) { return; } @@ -156,6 +157,13 @@ function createToolMenuElements(toolDefinition, doc) { }); } + let appmenuitem = createMenuItem({ + doc, + id: "appmenuitem_" + id, + label: toolDefinition.menuLabel || toolDefinition.label, + accesskey: null + }); + let menuitem = createMenuItem({ doc, id: "menuitem_" + id, @@ -166,10 +174,12 @@ function createToolMenuElements(toolDefinition, doc) { // Refer to the key in order to display the key shortcut at menu ends menuitem.setAttribute("key", key.id); } + appmenuitem.addEventListener("command", oncommand); menuitem.addEventListener("command", oncommand); return { key, + appmenuitem, menuitem }; } @@ -186,22 +196,34 @@ function createToolMenuElements(toolDefinition, doc) { * The tool definition after which the tool menu item is to be added. */ function insertToolMenuElements(doc, toolDefinition, prevDef) { - let { key, menuitem } = createToolMenuElements(toolDefinition, doc); + let { key, appmenuitem, menuitem } = createToolMenuElements(toolDefinition, doc); if (key) { attachKeybindingsToBrowser(doc, key); } - let ref; + let amp; + if (prevDef) { + let appmenuitem = doc.getElementById("appmenuitem_" + prevDef.id); + amp = appmenuitem && appmenuitem.nextSibling ? appmenuitem.nextSibling : null; + } else { + amp = doc.getElementById("appmenu_devtools_separator"); + } + + if (amp) { + amp.parentNode.insertBefore(appmenuitem, amp); + } + + let mp; if (prevDef) { let menuitem = doc.getElementById("menuitem_" + prevDef.id); - ref = menuitem && menuitem.nextSibling ? menuitem.nextSibling : null; + mp = menuitem && menuitem.nextSibling ? menuitem.nextSibling : null; } else { - ref = doc.getElementById("menu_devtools_separator"); + mp = doc.getElementById("menu_devtools_separator"); } - if (ref) { - ref.parentNode.insertBefore(menuitem, ref); + if (mp) { + mp.parentNode.insertBefore(menuitem, mp); } } exports.insertToolMenuElements = insertToolMenuElements; @@ -220,6 +242,11 @@ function removeToolFromMenu(toolId, doc) { key.remove(); } + let appmenuitem = doc.getElementById("appmenuitem_" + toolId); + if (appmenuitem) { + appmenuitem.remove(); + } + let menuitem = doc.getElementById("menuitem_" + toolId); if (menuitem) { menuitem.remove(); @@ -235,6 +262,7 @@ exports.removeToolFromMenu = removeToolFromMenu; */ function addAllToolsToMenu(doc) { let fragKeys = doc.createDocumentFragment(); + let fragAppMenuItems = doc.createDocumentFragment(); let fragMenuItems = doc.createDocumentFragment(); for (let toolDefinition of gDevTools.getToolDefinitionArray()) { @@ -251,11 +279,17 @@ function addAllToolsToMenu(doc) { if (elements.key) { fragKeys.appendChild(elements.key); } + fragAppMenuItems.appendChild(elements.appmenuitem); fragMenuItems.appendChild(elements.menuitem); } attachKeybindingsToBrowser(doc, fragKeys); + let amps = doc.getElementById("appmenu_devtools_separator"); + if (amps) { + amps.parentNode.insertBefore(fragAppMenuItems, amps); + } + let mps = doc.getElementById("menu_devtools_separator"); if (mps) { mps.parentNode.insertBefore(fragMenuItems, mps); @@ -270,18 +304,29 @@ function addAllToolsToMenu(doc) { */ function addTopLevelItems(doc) { let keys = doc.createDocumentFragment(); + let appmenuItems = doc.createDocumentFragment(); let menuItems = doc.createDocumentFragment(); let { menuitems } = require("../menus"); for (let item of menuitems) { if (item.separator) { + let appseparator = doc.createElement("menuseparator"); + appseparator.id = "app" + item.id; let separator = doc.createElement("menuseparator"); separator.id = item.id; + appmenuItems.appendChild(appseparator); menuItems.appendChild(separator); } else { let { id, l10nKey } = item; // Create a <menuitem> + let appmenuitem = createMenuItem({ + doc, + id: "app" + id, + label: l10n(l10nKey + ".label"), + accesskey: null, + isCheckbox: item.checkbox + }); let menuitem = createMenuItem({ doc, id, @@ -289,7 +334,9 @@ function addTopLevelItems(doc) { accesskey: l10n(l10nKey + ".accesskey"), isCheckbox: item.checkbox }); + appmenuitem.addEventListener("command", item.oncommand); menuitem.addEventListener("command", item.oncommand); + appmenuItems.appendChild(appmenuitem); menuItems.appendChild(menuitem); if (item.key && l10nKey) { @@ -330,6 +377,9 @@ function addTopLevelItems(doc) { for (let node of keys.children) { nodes.push(node); } + for (let node of appmenuItems.children) { + nodes.push(node); + } for (let node of menuItems.children) { nodes.push(node); } @@ -337,15 +387,33 @@ function addTopLevelItems(doc) { attachKeybindingsToBrowser(doc, keys); + // There are hardcoded menu items in the Web Developer menus plus it is a + // location of menu items via overlays from extensions so we want to make + // sure the last seperator and the "Get More Tools..." items are last. + // This will emulate the behavior when devtools menu items were actually + // physically present in browser.xul + + // Tools > Web Developer let menu = doc.getElementById("menuWebDeveloperPopup"); - menu.appendChild(menuItems); - - // There is still "Page Source" menuitem hardcoded into browser.xul. Instead - // of manually inserting everything around it, move it to the expected - // position. - let pageSource = doc.getElementById("menu_pageSource"); - let endSeparator = doc.getElementById("devToolsEndSeparator"); - menu.insertBefore(pageSource, endSeparator); + // Insert the Devtools Menu Items before everything else + menu.insertBefore(menuItems, menu.firstChild); + // Move the devtools last seperator and Get More Tools menu items to the bottom + let menu_endSeparator = doc.getElementById("menu_devToolsEndSeparator"); + let menu_getMoreDevtools = doc.getElementById("menu_getMoreDevtools"); + menu.insertBefore(menu_getMoreDevtools, null); + menu.insertBefore(menu_endSeparator, menu_getMoreDevtools); + + // Application Menu > Web Developer (If existant) + let appmenu = doc.getElementById("appmenu_webDeveloper_popup"); + if (appmenu) { + // Insert the Devtools Menu Items after the hardcoded idless seperator + appmenu.insertBefore(appmenuItems, appmenu.childNodes[2].nextSibling); + // Move the devtools last seperator and Get More Tools menu items to the bottom + let appmenu_endSeparator = doc.getElementById("appmenu_devToolsEndSeparator"); + let appmenu_getMoreDevtools = doc.getElementById("appmenu_getMoreDevtools"); + appmenu.insertBefore(appmenu_getMoreDevtools, null); + appmenu.insertBefore(appmenu_endSeparator, appmenu_getMoreDevtools); + } } /** diff --git a/devtools/client/framework/devtools-browser.js b/devtools/client/framework/devtools-browser.js index b9f4d92ba..f032f82aa 100644 --- a/devtools/client/framework/devtools-browser.js +++ b/devtools/client/framework/devtools-browser.js @@ -8,7 +8,7 @@ * This is the main module loaded in Firefox desktop that handles browser * windows and coordinates devtools around each window. * - * This module is loaded lazily by devtools-clhandler.js, once the first + * This module is loaded lazily by devtools-startup.js, once the first * browser window is ready (i.e. fired browser-delayed-startup-finished event) **/ @@ -27,8 +27,10 @@ loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true); loader.lazyRequireGetter(this, "DebuggerClient", "devtools/shared/client/main", true); loader.lazyRequireGetter(this, "BrowserMenus", "devtools/client/framework/browser-menus"); -loader.lazyImporter(this, "CustomizableUI", "resource:///modules/CustomizableUI.jsm"); loader.lazyImporter(this, "AppConstants", "resource://gre/modules/AppConstants.jsm"); +#ifdef MC_BASILISK +loader.lazyImporter(this, "CustomizableUI", "resource:///modules/CustomizableUI.jsm"); +#endif const {LocalizationHelper} = require("devtools/shared/l10n"); const L10N = new LocalizationHelper("devtools/client/locales/toolbox.properties"); @@ -85,6 +87,9 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = { function toggleMenuItem(id, isEnabled) { let cmd = doc.getElementById(id); + if (!cmd) { + return; + } if (isEnabled) { cmd.removeAttribute("disabled"); cmd.removeAttribute("hidden"); @@ -94,22 +99,39 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = { } } + let idEls = []; + // Enable developer toolbar? let devToolbarEnabled = Services.prefs.getBoolPref("devtools.toolbar.enabled"); - toggleMenuItem("menu_devToolbar", devToolbarEnabled); - let focusEl = doc.getElementById("menu_devToolbar"); - if (devToolbarEnabled) { - focusEl.removeAttribute("disabled"); - } else { - focusEl.setAttribute("disabled", "true"); - } + idEls = [ + "appmenu_devToolbar", + "menu_devToolbar" + ]; + idEls.forEach(function (idEl) { + toggleMenuItem(idEl, devToolbarEnabled); + let focusEl = doc.getElementById(idEl); + if (!focusEl) { + return; + } + if (devToolbarEnabled) { + focusEl.removeAttribute("disabled"); + } else { + focusEl.setAttribute("disabled", "true"); + } + }); if (devToolbarEnabled && Services.prefs.getBoolPref("devtools.toolbar.visible")) { win.DeveloperToolbar.show(false).catch(console.error); } // Enable WebIDE? let webIDEEnabled = Services.prefs.getBoolPref("devtools.webide.enabled"); - toggleMenuItem("menu_webide", webIDEEnabled); + idEls = [ + "appmenu_webide", + "menu_webide" + ]; + idEls.forEach(function (idEl) { + toggleMenuItem(idEl, webIDEEnabled); + }); let showWebIDEWidget = Services.prefs.getBoolPref("devtools.webide.widget.enabled"); if (webIDEEnabled && showWebIDEWidget) { @@ -122,11 +144,29 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = { let chromeEnabled = Services.prefs.getBoolPref("devtools.chrome.enabled"); let devtoolsRemoteEnabled = Services.prefs.getBoolPref("devtools.debugger.remote-enabled"); let remoteEnabled = chromeEnabled && devtoolsRemoteEnabled; - toggleMenuItem("menu_browserToolbox", remoteEnabled); - toggleMenuItem("menu_browserContentToolbox", remoteEnabled && win.gMultiProcessBrowser); + idEls = [ + "appmenu_browserToolbox", + "menu_browserToolbox" + ]; + idEls.forEach(function (idEl) { + toggleMenuItem(idEl, remoteEnabled); + }); + idEls = [ + "appmenu_browserContentToolbox", + "menu_browserContentToolbox" + ]; + idEls.forEach(function (idEl) { + toggleMenuItem(idEl, remoteEnabled && win.gMultiProcessBrowser); + }); // Enable DevTools connection screen, if the preference allows this. - toggleMenuItem("menu_devtools_connect", devtoolsRemoteEnabled); + idEls = [ + "appmenu_devtools_connect", + "menu_devtools_connect" + ]; + idEls.forEach(function (idEl) { + toggleMenuItem(idEl, devtoolsRemoteEnabled); + }); }, observe: function (subject, topic, prefName) { @@ -295,6 +335,7 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = { * Install Developer widget */ installDeveloperWidget: function () { +#ifdef MC_BASILISK let id = "developer-button"; let widget = CustomizableUI.getWidget(id); if (widget && widget.provider == CustomizableUI.PROVIDER_API) { @@ -343,6 +384,9 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = { doc.getElementById("PanelUI-multiView").appendChild(view); } }); +#else + return; +#endif }, /** @@ -350,6 +394,7 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = { */ // Used by itself installWebIDEWidget: function () { +#ifdef MC_BASILISK if (this.isWebIDEWidgetInstalled()) { return; } @@ -371,11 +416,18 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = { gDevToolsBrowser.openWebIDE(); } }); +#else + return; +#endif }, isWebIDEWidgetInstalled: function () { +#ifdef MC_BASILISK let widgetWrapper = CustomizableUI.getWidget("webide-button"); return !!(widgetWrapper && widgetWrapper.provider == CustomizableUI.PROVIDER_API); +#else + return false; +#endif }, /** @@ -387,10 +439,14 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = { * Uninstall WebIDE widget */ uninstallWebIDEWidget: function () { +#ifdef MC_BASILISK if (this.isWebIDEWidgetInstalled()) { CustomizableUI.removeWidgetFromArea("webide-button"); } CustomizableUI.destroyWidget("webide-button"); +#else + return; +#endif }, /** @@ -398,7 +454,11 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = { */ // Used by webide.js moveWebIDEWidgetInNavbar: function () { +#ifdef MC_BASILISK CustomizableUI.addWidgetToArea("webide-button", CustomizableUI.AREA_NAVBAR); +#else + return; +#endif }, /** @@ -591,12 +651,23 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = { let hasToolbox = gDevToolsBrowser.hasToolboxOpened(win); - let menu = win.document.getElementById("menu_devToolbox"); - if (hasToolbox) { - menu.setAttribute("checked", "true"); - } else { - menu.removeAttribute("checked"); - } + let idEls = []; + + idEls = [ + "appmenu_devToolbox", + "menu_devToolbox" + ]; + idEls.forEach(function (idEl) { + let menu = win.document.getElementById(idEl); + if (!menu) { + return; + } + if (hasToolbox) { + menu.setAttribute("checked", "true"); + } else { + menu.removeAttribute("checked"); + } + }); } }, diff --git a/devtools/client/framework/moz.build b/devtools/client/framework/moz.build index 7b28b4b9e..407e21f8b 100644 --- a/devtools/client/framework/moz.build +++ b/devtools/client/framework/moz.build @@ -13,7 +13,6 @@ DevToolsModules( 'about-devtools-toolbox.js', 'attach-thread.js', 'browser-menus.js', - 'devtools-browser.js', 'devtools.js', 'gDevTools.jsm', 'location-store.js', @@ -31,3 +30,7 @@ DevToolsModules( 'toolbox.js', 'ToolboxProcess.jsm', ) + +FINAL_TARGET_PP_FILES.chrome.devtools.modules.devtools.client.framework += [ + 'devtools-browser.js', +] diff --git a/devtools/client/framework/test/browser_keybindings_01.js b/devtools/client/framework/test/browser_keybindings_01.js index 4e4effb07..134fb127c 100644 --- a/devtools/client/framework/test/browser_keybindings_01.js +++ b/devtools/client/framework/test/browser_keybindings_01.js @@ -8,6 +8,9 @@ const TEST_URL = "data:text/html,<html><head><title>Test for the " + "highlighter keybindings</title></head><body>" + "<h1>Keybindings!</h1></body></html>" + +const {gDevToolsBrowser} = require("devtools/client/framework/devtools-browser"); + function test() { waitForExplicitFinish(); diff --git a/devtools/client/menus.js b/devtools/client/menus.js index 7e36839da..1d2168967 100644 --- a/devtools/client/menus.js +++ b/devtools/client/menus.js @@ -183,9 +183,9 @@ exports.menuitems = [ } }, { separator: true, - id: "devToolsEndSeparator" + id: "menu_devToolsEndSeparator" }, - { id: "getMoreDevtools", + { id: "menu_getMoreDevtools", l10nKey: "getMoreDevtoolsCmd", oncommand(event) { let window = event.target.ownerDocument.defaultView; diff --git a/devtools/client/scratchpad/test/head.js b/devtools/client/scratchpad/test/head.js index 15619a169..955c037d7 100644 --- a/devtools/client/scratchpad/test/head.js +++ b/devtools/client/scratchpad/test/head.js @@ -9,6 +9,7 @@ const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm", {}); const {console} = Cu.import("resource://gre/modules/Console.jsm", {}); const {ScratchpadManager} = Cu.import("resource://devtools/client/scratchpad/scratchpad-manager.jsm", {}); const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {}); +const {gDevTools} = require("devtools/client/framework/devtools"); const Services = require("Services"); const DevToolsUtils = require("devtools/shared/DevToolsUtils"); const flags = require("devtools/shared/flags"); diff --git a/devtools/client/shared/developer-toolbar.js b/devtools/client/shared/developer-toolbar.js index 2528591a6..d84402418 100644 --- a/devtools/client/shared/developer-toolbar.js +++ b/devtools/client/shared/developer-toolbar.js @@ -449,7 +449,15 @@ DeveloperToolbar.prototype.show = function (focus) { [ this.tooltipPanel, this.outputPanel ] = panels; - this._doc.getElementById("menu_devToolbar").setAttribute("checked", "true"); + let checkboxValue = "true"; + let appmenuEl = this._doc.getElementById("appmenu_devToolbar"); + let menuEl = this._doc.getElementById("menu_devToolbar"); + if (appmenuEl) { + appmenuEl.setAttribute("checked", checkboxValue); + } + if (menuEl) { + menuEl.setAttribute("checked", checkboxValue); + } this.target = TargetFactory.forTab(this._chromeWindow.gBrowser.selectedTab); const options = { @@ -569,7 +577,15 @@ DeveloperToolbar.prototype.hide = function () { Services.prefs.setBoolPref("devtools.toolbar.visible", false); - this._doc.getElementById("menu_devToolbar").setAttribute("checked", "false"); + let checkboxValue = "false"; + let appmenuEl = this._doc.getElementById("appmenu_devToolbar"); + let menuEl = this._doc.getElementById("menu_devToolbar"); + if (appmenuEl) { + appmenuEl.setAttribute("checked", checkboxValue); + } + if (menuEl) { + menuEl.setAttribute("checked", checkboxValue); + } this.destroy(); this._telemetry.toolClosed("developertoolbar"); diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/head.js b/devtools/client/webconsole/new-console-output/test/mochitest/head.js index b71eaec4f..049f3d1ce 100644 --- a/devtools/client/webconsole/new-console-output/test/mochitest/head.js +++ b/devtools/client/webconsole/new-console-output/test/mochitest/head.js @@ -14,6 +14,7 @@ Services.scriptloader.loadSubScript( var {Utils: WebConsoleUtils} = require("devtools/client/webconsole/utils"); const WEBCONSOLE_STRINGS_URI = "devtools/client/locales/webconsole.properties"; +var {HUDService} = require("devtools/client/webconsole/hudservice"); var WCUL10n = new WebConsoleUtils.L10n(WEBCONSOLE_STRINGS_URI); Services.prefs.setBoolPref("devtools.webconsole.new-frontend-enabled", true); diff --git a/docshell/base/nsAboutRedirector.cpp b/docshell/base/nsAboutRedirector.cpp index e7d362864..e56447296 100644 --- a/docshell/base/nsAboutRedirector.cpp +++ b/docshell/base/nsAboutRedirector.cpp @@ -42,17 +42,14 @@ static RedirEntry kRedirMap[] = { { "buildconfig", "chrome://global/content/buildconfig.html", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | - nsIAboutModule::MAKE_LINKABLE + nsIAboutModule::MAKE_LINKABLE }, { "checkerboard", "chrome://global/content/aboutCheckerboard.xhtml", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | - nsIAboutModule::ALLOW_SCRIPT + nsIAboutModule::ALLOW_SCRIPT }, { "config", "chrome://global/content/config.xul", 0 }, -#ifdef MOZ_CRASHREPORTER - { "crashes", "chrome://global/content/crashes.xhtml", 0 }, -#endif { "credits", "http://www.palemoon.org/Contributors.shtml", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | @@ -67,7 +64,7 @@ static RedirEntry kRedirMap[] = { { "license", "chrome://global/content/license.html", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | - nsIAboutModule::MAKE_LINKABLE + nsIAboutModule::MAKE_LINKABLE }, { "logo", "chrome://branding/content/about.png", @@ -75,6 +72,13 @@ static RedirEntry kRedirMap[] = { // Linkable for testing reasons. nsIAboutModule::MAKE_LINKABLE }, +#ifdef MOZ_PHOENIX + { + "logopage", "chrome://global/content/logopage.xhtml", + nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | + nsIAboutModule::HIDE_FROM_ABOUTABOUT + }, +#endif { "memory", "chrome://global/content/aboutMemory.xhtml", nsIAboutModule::ALLOW_SCRIPT @@ -86,9 +90,9 @@ static RedirEntry kRedirMap[] = { { "neterror", "chrome://global/content/netError.xhtml", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | - nsIAboutModule::URI_CAN_LOAD_IN_CHILD | - nsIAboutModule::ALLOW_SCRIPT | - nsIAboutModule::HIDE_FROM_ABOUTABOUT + nsIAboutModule::URI_CAN_LOAD_IN_CHILD | + nsIAboutModule::ALLOW_SCRIPT | + nsIAboutModule::HIDE_FROM_ABOUTABOUT }, { "networking", "chrome://global/content/aboutNetworking.xhtml", @@ -97,7 +101,7 @@ static RedirEntry kRedirMap[] = { { "newaddon", "chrome://mozapps/content/extensions/newaddon.xul", nsIAboutModule::ALLOW_SCRIPT | - nsIAboutModule::HIDE_FROM_ABOUTABOUT + nsIAboutModule::HIDE_FROM_ABOUTABOUT }, { "performance", "chrome://global/content/aboutPerformance.xhtml", @@ -124,10 +128,10 @@ static RedirEntry kRedirMap[] = { { "srcdoc", "about:blank", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | - nsIAboutModule::HIDE_FROM_ABOUTABOUT | - // Needs to be linkable so content can touch its own srcdoc frames - nsIAboutModule::MAKE_LINKABLE | - nsIAboutModule::URI_CAN_LOAD_IN_CHILD + nsIAboutModule::HIDE_FROM_ABOUTABOUT | + // Needs to be linkable so content can touch its own srcdoc frames + nsIAboutModule::MAKE_LINKABLE | + nsIAboutModule::URI_CAN_LOAD_IN_CHILD }, { "support", "chrome://global/content/aboutSupport.xhtml", diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 50641508d..58c182cbb 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -2289,13 +2289,6 @@ nsDocShell::GetUseRemoteTabs(bool* aUseRemoteTabs) NS_IMETHODIMP nsDocShell::SetRemoteTabs(bool aUseRemoteTabs) { -#ifdef MOZ_CRASHREPORTER - if (aUseRemoteTabs) { - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("DOMIPCEnabled"), - NS_LITERAL_CSTRING("1")); - } -#endif - mUseRemoteTabs = aUseRemoteTabs; return NS_OK; } diff --git a/docshell/build/nsDocShellModule.cpp b/docshell/build/nsDocShellModule.cpp index d43c305f9..872874012 100644 --- a/docshell/build/nsDocShellModule.cpp +++ b/docshell/build/nsDocShellModule.cpp @@ -165,15 +165,15 @@ const mozilla::Module::ContractIDEntry kDocShellContracts[] = { { NS_ABOUT_MODULE_CONTRACTID_PREFIX "buildconfig", &kNS_ABOUT_REDIRECTOR_MODULE_CID }, { NS_ABOUT_MODULE_CONTRACTID_PREFIX "checkerboard", &kNS_ABOUT_REDIRECTOR_MODULE_CID }, { NS_ABOUT_MODULE_CONTRACTID_PREFIX "config", &kNS_ABOUT_REDIRECTOR_MODULE_CID }, -#ifdef MOZ_CRASHREPORTER - { NS_ABOUT_MODULE_CONTRACTID_PREFIX "crashes", &kNS_ABOUT_REDIRECTOR_MODULE_CID }, -#endif { NS_ABOUT_MODULE_CONTRACTID_PREFIX "credits", &kNS_ABOUT_REDIRECTOR_MODULE_CID }, #ifdef MOZ_DEVTOOLS { NS_ABOUT_MODULE_CONTRACTID_PREFIX "debugging", &kNS_ABOUT_REDIRECTOR_MODULE_CID }, #endif { NS_ABOUT_MODULE_CONTRACTID_PREFIX "license", &kNS_ABOUT_REDIRECTOR_MODULE_CID }, { NS_ABOUT_MODULE_CONTRACTID_PREFIX "logo", &kNS_ABOUT_REDIRECTOR_MODULE_CID }, +#ifdef MOZ_PHOENIX + { NS_ABOUT_MODULE_CONTRACTID_PREFIX "logopage", &kNS_ABOUT_REDIRECTOR_MODULE_CID }, +#endif { NS_ABOUT_MODULE_CONTRACTID_PREFIX "memory", &kNS_ABOUT_REDIRECTOR_MODULE_CID }, { NS_ABOUT_MODULE_CONTRACTID_PREFIX "mozilla", &kNS_ABOUT_REDIRECTOR_MODULE_CID }, { NS_ABOUT_MODULE_CONTRACTID_PREFIX "neterror", &kNS_ABOUT_REDIRECTOR_MODULE_CID }, diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 02c6bf1de..ef87a250e 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -3717,11 +3717,15 @@ nsContentUtils::IsChildOfSameType(nsIDocument* aDoc) } bool -nsContentUtils::IsScriptType(const nsACString& aContentType) +nsContentUtils::IsPlainTextType(const nsACString& aContentType) { // NOTE: if you add a type here, add it to the CONTENTDLF_CATEGORIES // define in nsContentDLF.h as well. - return aContentType.EqualsLiteral(APPLICATION_JAVASCRIPT) || + return aContentType.EqualsLiteral(TEXT_PLAIN) || + aContentType.EqualsLiteral(TEXT_CSS) || + aContentType.EqualsLiteral(TEXT_CACHE_MANIFEST) || + aContentType.EqualsLiteral(TEXT_VTT) || + aContentType.EqualsLiteral(APPLICATION_JAVASCRIPT) || aContentType.EqualsLiteral(APPLICATION_XJAVASCRIPT) || aContentType.EqualsLiteral(TEXT_ECMASCRIPT) || aContentType.EqualsLiteral(APPLICATION_ECMASCRIPT) || @@ -3731,18 +3735,6 @@ nsContentUtils::IsScriptType(const nsACString& aContentType) } bool -nsContentUtils::IsPlainTextType(const nsACString& aContentType) -{ - // NOTE: if you add a type here, add it to the CONTENTDLF_CATEGORIES - // define in nsContentDLF.h as well. - return aContentType.EqualsLiteral(TEXT_PLAIN) || - aContentType.EqualsLiteral(TEXT_CSS) || - aContentType.EqualsLiteral(TEXT_CACHE_MANIFEST) || - aContentType.EqualsLiteral(TEXT_VTT) || - IsScriptType(aContentType); -} - -bool nsContentUtils::GetWrapperSafeScriptFilename(nsIDocument* aDocument, nsIURI* aURI, nsACString& aScriptURI, diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index 0a293d73e..0932f451e 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -1018,12 +1018,7 @@ public: static bool IsChildOfSameType(nsIDocument* aDoc); /** - '* Returns true if the content-type is any of the supported script types. - */ - static bool IsScriptType(const nsACString& aContentType); - - /** - '* Returns true if the content-type will be rendered as plain-text. + * Returns true if the content-type will be rendered as plain-text. */ static bool IsPlainTextType(const nsACString& aContentType); diff --git a/dom/base/nsFrameMessageManager.cpp b/dom/base/nsFrameMessageManager.cpp index a4bba4856..049bc0a1a 100644 --- a/dom/base/nsFrameMessageManager.cpp +++ b/dom/base/nsFrameMessageManager.cpp @@ -51,10 +51,6 @@ #include <algorithm> #include "chrome/common/ipc_channel.h" // for IPC::Channel::kMaximumMessageSize -#ifdef MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" -#endif - #ifdef ANDROID #include <android/log.h> #endif diff --git a/dom/events/Event.cpp b/dom/events/Event.cpp index 2af34136e..2546a81ad 100755 --- a/dom/events/Event.cpp +++ b/dom/events/Event.cpp @@ -412,8 +412,17 @@ Event::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv) { nsCOMPtr<mozilla::dom::EventTarget> t = do_QueryInterface(aGlobal.GetAsSupports()); - RefPtr<Event> e = new Event(t, nullptr, nullptr); - bool trusted = e->Init(t); + return Constructor(t, aType, aParam); +} + +// static +already_AddRefed<Event> +Event::Constructor(EventTarget* aEventTarget, + const nsAString& aType, + const EventInit& aParam) +{ + RefPtr<Event> e = new Event(aEventTarget, nullptr, nullptr); + bool trusted = e->Init(aEventTarget); e->InitEvent(aType, aParam.mBubbles, aParam.mCancelable); e->SetTrusted(trusted); e->SetComposed(aParam.mComposed); @@ -1209,7 +1218,7 @@ Event::Deserialize(const IPC::Message* aMsg, PickleIterator* aIter) } NS_IMETHODIMP_(void) -Event::SetOwner(mozilla::dom::EventTarget* aOwner) +Event::SetOwner(EventTarget* aOwner) { mOwner = nullptr; diff --git a/dom/events/Event.h b/dom/events/Event.h index c28226e8a..0817aa809 100755 --- a/dom/events/Event.h +++ b/dom/events/Event.h @@ -142,6 +142,10 @@ public: LayoutDeviceIntPoint aPoint, CSSIntPoint aDefaultPoint); + static already_AddRefed<Event> Constructor(EventTarget* aEventTarget, + const nsAString& aType, + const EventInit& aParam); + static already_AddRefed<Event> Constructor(const GlobalObject& aGlobal, const nsAString& aType, const EventInit& aParam, diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index ca4acf114..75678ca96 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -585,11 +585,6 @@ ContentChild::Init(MessageLoop* aIOLoop, SendBackUpXResources(FileDescriptor(xSocketFd)); #endif -#ifdef MOZ_CRASHREPORTER - SendPCrashReporterConstructor(CrashReporter::CurrentThreadId(), - XRE_GetProcessType()); -#endif - SendGetProcessAttributes(&mID, &mIsForApp, &mIsForBrowser); InitProcessAttributes(); @@ -1439,18 +1434,6 @@ ContentChild::RecvSetProcessSandbox(const MaybeFileDesc& aBroker) sandboxEnabled = StartMacOSContentSandbox(); #endif -#if defined(MOZ_CRASHREPORTER) - CrashReporter::AnnotateCrashReport( - NS_LITERAL_CSTRING("ContentSandboxEnabled"), - sandboxEnabled? NS_LITERAL_CSTRING("1") : NS_LITERAL_CSTRING("0")); -#if defined(XP_LINUX) && !defined(OS_ANDROID) - nsAutoCString flagsString; - flagsString.AppendInt(SandboxInfo::Get().AsInteger()); - - CrashReporter::AnnotateCrashReport( - NS_LITERAL_CSTRING("ContentSandboxCapabilities"), flagsString); -#endif /* XP_LINUX && !OS_ANDROID */ -#endif /* MOZ_CRASHREPORTER */ #endif /* MOZ_CONTENT_SANDBOX */ return true; @@ -1740,11 +1723,7 @@ PCrashReporterChild* ContentChild::AllocPCrashReporterChild(const mozilla::dom::NativeThreadId& id, const uint32_t& processType) { -#ifdef MOZ_CRASHREPORTER - return new CrashReporterChild(); -#else return nullptr; -#endif } bool @@ -2159,16 +2138,6 @@ ContentChild::ProcessingError(Result aCode, const char* aReason) NS_RUNTIMEABORT("not reached"); } -#if defined(MOZ_CRASHREPORTER) && !defined(MOZ_B2G) - if (PCrashReporterChild* c = LoneManagedOrNullAsserts(ManagedPCrashReporterChild())) { - CrashReporterChild* crashReporter = - static_cast<CrashReporterChild*>(c); - nsDependentCString reason(aReason); - crashReporter->SendAnnotateCrashReport( - NS_LITERAL_CSTRING("ipc_channel_error"), - reason); - } -#endif NS_RUNTIMEABORT("Content child abort due to IPC error"); } @@ -2872,10 +2841,6 @@ ContentChild::RecvShutdown() // to wait for that event loop to finish. Otherwise we could prematurely // terminate an "unload" or "pagehide" event handler (which might be doing a // sync XHR, for example). -#if defined(MOZ_CRASHREPORTER) - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCShutdownState"), - NS_LITERAL_CSTRING("RecvShutdown")); -#endif nsCOMPtr<nsIThread> thread; nsresult rv = NS_GetMainThread(getter_AddRefs(thread)); if (NS_SUCCEEDED(rv) && thread) { @@ -2923,10 +2888,6 @@ ContentChild::RecvShutdown() // parent closes. StartForceKillTimer(); -#if defined(MOZ_CRASHREPORTER) - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCShutdownState"), - NS_LITERAL_CSTRING("SendFinishShutdown")); -#endif // Ignore errors here. If this fails, the parent will kill us after a // timeout. Unused << SendFinishShutdown(); diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index ff40db8d7..73621df22 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -249,10 +249,6 @@ using namespace mozilla::system; #include "mozilla/widget/AudioSession.h" #endif -#ifdef MOZ_CRASHREPORTER -#include "nsThread.h" -#endif - #ifdef ACCESSIBILITY #include "nsAccessibilityService.h" #endif @@ -273,9 +269,6 @@ using base::KillProcess; using mozilla::ProfileGatherer; #endif -#ifdef MOZ_CRASHREPORTER -using namespace CrashReporter; -#endif using namespace mozilla::dom::power; using namespace mozilla::media; using namespace mozilla::embedding; @@ -1847,36 +1840,6 @@ ContentParent::ActorDestroy(ActorDestroyReason why) NS_LITERAL_CSTRING("content"), 1); props->SetPropertyAsBool(NS_LITERAL_STRING("abnormal"), true); - -#ifdef MOZ_CRASHREPORTER - // There's a window in which child processes can crash - // after IPC is established, but before a crash reporter - // is created. - if (PCrashReporterParent* p = LoneManagedOrNullAsserts(ManagedPCrashReporterParent())) { - CrashReporterParent* crashReporter = - static_cast<CrashReporterParent*>(p); - - // If we're an app process, always stomp the latest URI - // loaded in the child process with our manifest URL. We - // would rather associate the crashes with apps than - // random child windows loaded in them. - // - // XXX would be nice if we could get both ... - if (!mAppManifestURL.IsEmpty()) { - crashReporter->AnnotateCrashReport(NS_LITERAL_CSTRING("URL"), - NS_ConvertUTF16toUTF8(mAppManifestURL)); - } - - // if mCreatedPairedMinidumps is true, we've already generated - // parent/child dumps for dekstop crashes. - if (!mCreatedPairedMinidumps) { - crashReporter->GenerateCrashReport(this, nullptr); - } - - nsAutoString dumpID(crashReporter->ChildDumpID()); - props->SetPropertyAsAString(NS_LITERAL_STRING("dumpID"), dumpID); - } -#endif } nsAutoString cpId; cpId.AppendInt(static_cast<uint64_t>(this->ChildID())); @@ -3090,33 +3053,6 @@ ContentParent::KillHard(const char* aReason) mCalledKillHard = true; mForceKillTimer = nullptr; -#if defined(MOZ_CRASHREPORTER) && !defined(MOZ_B2G) - // We're about to kill the child process associated with this content. - // Something has gone wrong to get us here, so we generate a minidump - // of the parent and child for submission to the crash server. - if (PCrashReporterParent* p = LoneManagedOrNullAsserts(ManagedPCrashReporterParent())) { - CrashReporterParent* crashReporter = - static_cast<CrashReporterParent*>(p); - // GeneratePairedMinidump creates two minidumps for us - the main - // one is for the content process we're about to kill, and the other - // one is for the main browser process. That second one is the extra - // minidump tagging along, so we have to tell the crash reporter that - // it exists and is being appended. - nsAutoCString additionalDumps("browser"); - crashReporter->AnnotateCrashReport( - NS_LITERAL_CSTRING("additional_minidumps"), - additionalDumps); - nsDependentCString reason(aReason); - crashReporter->AnnotateCrashReport( - NS_LITERAL_CSTRING("ipc_channel_error"), - reason); - - // Generate the report and insert into the queue for submittal. - mCreatedPairedMinidumps = crashReporter->GenerateCompleteMinidump(this); - - Telemetry::Accumulate(Telemetry::SUBPROCESS_KILL_HARD, reason, 1); - } -#endif ProcessHandle otherProcessHandle; if (!base::OpenProcessHandle(OtherPid(), &otherProcessHandle)) { NS_ERROR("Failed to open child process when attempting kill."); @@ -3168,11 +3104,7 @@ PCrashReporterParent* ContentParent::AllocPCrashReporterParent(const NativeThreadId& tid, const uint32_t& processType) { -#ifdef MOZ_CRASHREPORTER - return new CrashReporterParent(); -#else return nullptr; -#endif } bool @@ -5001,9 +4933,6 @@ ContentParent::RecvNotifyPushSubscriptionModifiedObservers(const nsCString& aSco bool ContentParent::RecvNotifyLowMemory() { -#ifdef MOZ_CRASHREPORTER - nsThread::SaveMemoryReportNearOOM(nsThread::ShouldSaveMemoryReport::kForceReport); -#endif return true; } diff --git a/dom/ipc/CrashReporterParent.cpp b/dom/ipc/CrashReporterParent.cpp index fc627387f..677b29670 100644 --- a/dom/ipc/CrashReporterParent.cpp +++ b/dom/ipc/CrashReporterParent.cpp @@ -13,13 +13,6 @@ #include "mozilla/Telemetry.h" -#ifdef MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" -#include "nsICrashService.h" -#include "mozilla/SyncRunnable.h" -#include "nsThreadUtils.h" -#endif - namespace mozilla { namespace dom { @@ -29,9 +22,6 @@ void CrashReporterParent::AnnotateCrashReport(const nsCString& key, const nsCString& data) { -#ifdef MOZ_CRASHREPORTER - mNotes.Put(key, data); -#endif } void @@ -49,9 +39,6 @@ CrashReporterParent::RecvAppendAppNotes(const nsCString& data) CrashReporterParent::CrashReporterParent() : -#ifdef MOZ_CRASHREPORTER - mNotes(4), -#endif mStartTime(::time(nullptr)) , mInitialized(false) { @@ -72,75 +59,5 @@ CrashReporterParent::SetChildData(const NativeThreadId& tid, mProcessType = GeckoProcessType(processType); } -#ifdef MOZ_CRASHREPORTER -bool -CrashReporterParent::GenerateCrashReportForMinidump(nsIFile* minidump, - const AnnotationTable* processNotes) -{ - if (!CrashReporter::GetIDFromMinidump(minidump, mChildDumpID)) { - return false; - } - - bool result = GenerateChildData(processNotes); - FinalizeChildData(); - return result; -} - -bool -CrashReporterParent::GenerateChildData(const AnnotationTable* processNotes) -{ - MOZ_ASSERT(mInitialized); - - if (mChildDumpID.IsEmpty()) { - NS_WARNING("problem with GenerateChildData: no child dump id yet!"); - return false; - } - - nsAutoCString type; - switch (mProcessType) { - case GeckoProcessType_Content: - type = NS_LITERAL_CSTRING("content"); - break; - case GeckoProcessType_Plugin: - case GeckoProcessType_GMPlugin: - type = NS_LITERAL_CSTRING("plugin"); - break; - default: - NS_ERROR("unknown process type"); - break; - } - mNotes.Put(NS_LITERAL_CSTRING("ProcessType"), type); - - char startTime[32]; - SprintfLiteral(startTime, "%lld", static_cast<long long>(mStartTime)); - mNotes.Put(NS_LITERAL_CSTRING("StartupTime"), nsDependentCString(startTime)); - - if (!mAppNotes.IsEmpty()) { - mNotes.Put(NS_LITERAL_CSTRING("Notes"), mAppNotes); - } - - // Append these notes to the end of the extra file based on the current - // dump id we obtained from CreatePairedMinidumps. - bool ret = CrashReporter::AppendExtraData(mChildDumpID, mNotes); - if (ret && processNotes) { - ret = CrashReporter::AppendExtraData(mChildDumpID, *processNotes); - } - - if (!ret) { - NS_WARNING("problem appending child data to .extra"); - } - return ret; -} - -void -CrashReporterParent::FinalizeChildData() -{ - MOZ_ASSERT(mInitialized); - - CrashReporterHost::NotifyCrashService(mProcessType, mChildDumpID, &mNotes); - mNotes.Clear(); -} -#endif - } // namespace dom } // namespace mozilla diff --git a/dom/ipc/CrashReporterParent.h b/dom/ipc/CrashReporterParent.h index 25824f279..71896c5c1 100644 --- a/dom/ipc/CrashReporterParent.h +++ b/dom/ipc/CrashReporterParent.h @@ -10,122 +10,16 @@ #include "mozilla/dom/PCrashReporterParent.h" #include "mozilla/dom/TabMessageUtils.h" #include "nsIFile.h" -#ifdef MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" -#include "nsDataHashtable.h" -#endif namespace mozilla { namespace dom { class CrashReporterParent : public PCrashReporterParent { -#ifdef MOZ_CRASHREPORTER - typedef CrashReporter::AnnotationTable AnnotationTable; -#endif public: CrashReporterParent(); virtual ~CrashReporterParent(); -#ifdef MOZ_CRASHREPORTER - - /* - * Attempt to create a bare-bones crash report, along with extra process- - * specific annotations present in the given AnnotationTable. Calls - * GenerateChildData and FinalizeChildData. - * - * @returns true if successful, false otherwise. - */ - template<class Toplevel> - bool - GenerateCrashReport(Toplevel* t, const AnnotationTable* processNotes); - - /* - * Attempt to generate a parent/child pair of minidumps from the given - * toplevel actor. This calls CrashReporter::CreateMinidumpsAndPair to - * generate the minidumps. Crash reporter annotations set prior to this - * call will be saved via PairedDumpCallbackExtra into an .extra file - * under the proper crash id. AnnotateCrashReport annotations are not - * set in this call and the report is not finalized. - * - * @returns true if successful, false otherwise. - */ - template<class Toplevel> - bool - GeneratePairedMinidump(Toplevel* t); - - /* - * Attempts to take a minidump of the current process and pair that with - * a named minidump handed in by the caller. - * - * @param aTopLevel - top level actor this reporter is associated with. - * @param aMinidump - the minidump to associate with. - * @param aPairName - the name of the additional minidump. - * @returns true if successful, false otherwise. - */ - template<class Toplevel> - bool - GenerateMinidumpAndPair(Toplevel* aTopLevel, nsIFile* aMinidump, - const nsACString& aPairName); - - /** - * Apply child process annotations to an existing paired mindump generated - * with GeneratePairedMinidump. - * - * Be careful about calling generate apis immediately after this call, - * see FinalizeChildData. - * - * @param processNotes (optional) - Additional notes to append. Annotations - * stored in mNotes will also be applied. processNotes can be null. - * @returns true if successful, false otherwise. - */ - bool - GenerateChildData(const AnnotationTable* processNotes); - - /** - * Handles main thread finalization tasks after a report has been - * generated. Does the following: - * - register the finished report with the crash service manager - * - records telemetry related data about crashes - * - * Be careful about calling generate apis immediately after this call, - * if this api is called on a non-main thread it will fire off a runnable - * to complete its work async. - */ - void - FinalizeChildData(); - - /* - * Attempt to generate a full paired dump complete with any child - * annoations, and finalizes the report. Note this call is only valid - * on the main thread. Calling on a background thread will fail. - * - * @returns true if successful, false otherwise. - */ - template<class Toplevel> - bool - GenerateCompleteMinidump(Toplevel* t); - - /** - * Submits a raw minidump handed in, calls GenerateChildData and - * FinalizeChildData. Used by content plugins and gmp. - * - * @returns true if successful, false otherwise. - */ - bool - GenerateCrashReportForMinidump(nsIFile* minidump, - const AnnotationTable* processNotes); - - /* - * Instantiate a new crash reporter actor from a given parent that manages - * the protocol. - * - * @returns true if successful, false otherwise. - */ - template<class Toplevel> - static bool CreateCrashReporter(Toplevel* actor); -#endif // MOZ_CRASHREPORTER - /* * Initialize this reporter with data from the child process. */ @@ -160,14 +54,6 @@ public: virtual bool RecvAppendAppNotes(const nsCString& aData) override; -#ifdef MOZ_CRASHREPORTER - void - NotifyCrashService(); -#endif - -#ifdef MOZ_CRASHREPORTER - AnnotationTable mNotes; -#endif nsCString mAppNotes; nsString mChildDumpID; // stores the child main thread id @@ -178,128 +64,6 @@ public: bool mInitialized; }; -#ifdef MOZ_CRASHREPORTER -template<class Toplevel> -inline bool -CrashReporterParent::GeneratePairedMinidump(Toplevel* t) -{ - mozilla::ipc::ScopedProcessHandle child; -#ifdef XP_MACOSX - child = t->Process()->GetChildTask(); -#else - if (!base::OpenPrivilegedProcessHandle(t->OtherPid(), &child.rwget())) { - NS_WARNING("Failed to open child process handle."); - return false; - } -#endif - nsCOMPtr<nsIFile> childDump; - if (CrashReporter::CreateMinidumpsAndPair(child, - mMainThread, - NS_LITERAL_CSTRING("browser"), - nullptr, // pair with a dump of this process and thread - getter_AddRefs(childDump)) && - CrashReporter::GetIDFromMinidump(childDump, mChildDumpID)) { - return true; - } - return false; -} - -template<class Toplevel> -inline bool -CrashReporterParent::GenerateMinidumpAndPair(Toplevel* aTopLevel, - nsIFile* aMinidumpToPair, - const nsACString& aPairName) -{ - mozilla::ipc::ScopedProcessHandle childHandle; -#ifdef XP_MACOSX - childHandle = aTopLevel->Process()->GetChildTask(); -#else - if (!base::OpenPrivilegedProcessHandle(aTopLevel->OtherPid(), - &childHandle.rwget())) { - NS_WARNING("Failed to open child process handle."); - return false; - } -#endif - nsCOMPtr<nsIFile> targetDump; - if (CrashReporter::CreateMinidumpsAndPair(childHandle, - mMainThread, // child thread id - aPairName, - aMinidumpToPair, - getter_AddRefs(targetDump)) && - CrashReporter::GetIDFromMinidump(targetDump, mChildDumpID)) { - return true; - } - return false; -} - -template<class Toplevel> -inline bool -CrashReporterParent::GenerateCrashReport(Toplevel* t, - const AnnotationTable* processNotes) -{ - nsCOMPtr<nsIFile> crashDump; - if (t->TakeMinidump(getter_AddRefs(crashDump), nullptr) && - CrashReporter::GetIDFromMinidump(crashDump, mChildDumpID)) { - bool result = GenerateChildData(processNotes); - FinalizeChildData(); - return result; - } - return false; -} - -template<class Toplevel> -inline bool -CrashReporterParent::GenerateCompleteMinidump(Toplevel* t) -{ - mozilla::ipc::ScopedProcessHandle child; - if (!NS_IsMainThread()) { - NS_WARNING("GenerateCompleteMinidump can't be called on non-main thread."); - return false; - } - -#ifdef XP_MACOSX - child = t->Process()->GetChildTask(); -#else - if (!base::OpenPrivilegedProcessHandle(t->OtherPid(), &child.rwget())) { - NS_WARNING("Failed to open child process handle."); - return false; - } -#endif - nsCOMPtr<nsIFile> childDump; - if (CrashReporter::CreateMinidumpsAndPair(child, - mMainThread, - NS_LITERAL_CSTRING("browser"), - nullptr, // pair with a dump of this process and thread - getter_AddRefs(childDump)) && - CrashReporter::GetIDFromMinidump(childDump, mChildDumpID)) { - bool result = GenerateChildData(nullptr); - FinalizeChildData(); - return result; - } - return false; -} - -template<class Toplevel> -/* static */ bool -CrashReporterParent::CreateCrashReporter(Toplevel* actor) -{ -#ifdef MOZ_CRASHREPORTER - NativeThreadId id; - uint32_t processType; - PCrashReporterParent* p = - actor->CallPCrashReporterConstructor(&id, &processType); - if (p) { - static_cast<CrashReporterParent*>(p)->SetChildData(id, processType); - } else { - NS_ERROR("Error creating crash reporter actor"); - } - return !!p; -#endif - return false; -} - -#endif - } // namespace dom } // namespace mozilla diff --git a/dom/ipc/ProcessHangMonitor.cpp b/dom/ipc/ProcessHangMonitor.cpp index b574be61f..d46a1f5d5 100644 --- a/dom/ipc/ProcessHangMonitor.cpp +++ b/dom/ipc/ProcessHangMonitor.cpp @@ -27,9 +27,6 @@ #include "nsITabParent.h" #include "nsPluginHost.h" #include "nsThreadUtils.h" -#ifdef MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" -#endif #include "base/task.h" #include "base/thread.h" @@ -556,16 +553,6 @@ HangMonitorParent::HangMonitorParent(ProcessHangMonitor* aMonitor) HangMonitorParent::~HangMonitorParent() { -#ifdef MOZ_CRASHREPORTER - MutexAutoLock lock(mBrowserCrashDumpHashLock); - - for (auto iter = mBrowserCrashDumpIds.Iter(); !iter.Done(); iter.Next()) { - nsString crashId = iter.UserData(); - if (!crashId.IsEmpty()) { - CrashReporter::DeleteMinidumpFilesForID(crashId); - } - } -#endif } void @@ -698,24 +685,6 @@ bool HangMonitorParent::TakeBrowserMinidump(const PluginHangData& aPhd, nsString& aCrashId) { -#ifdef MOZ_CRASHREPORTER - MutexAutoLock lock(mBrowserCrashDumpHashLock); - if (!mBrowserCrashDumpIds.Get(aPhd.pluginId(), &aCrashId)) { - nsCOMPtr<nsIFile> browserDump; - if (CrashReporter::TakeMinidump(getter_AddRefs(browserDump), true)) { - if (!CrashReporter::GetIDFromMinidump(browserDump, aCrashId) - || aCrashId.IsEmpty()) { - browserDump->Remove(false); - NS_WARNING("Failed to generate timely browser stack, " - "this is bad for plugin hang analysis!"); - } else { - mBrowserCrashDumpIds.Put(aPhd.pluginId(), aCrashId); - return true; - } - } - } -#endif // MOZ_CRASHREPORTER - return false; } @@ -840,11 +809,6 @@ HangMonitorParent::CleanupPluginHang(uint32_t aPluginId, bool aRemoveFiles) return; } mBrowserCrashDumpIds.Remove(aPluginId); -#ifdef MOZ_CRASHREPORTER - if (aRemoveFiles && !crashId.IsEmpty()) { - CrashReporter::DeleteMinidumpFilesForID(crashId); - } -#endif } void diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index f46a917d5..c8a0c6e3f 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -52,9 +52,6 @@ #include "nsEmbedCID.h" #include "nsGlobalWindow.h" #include <algorithm> -#ifdef MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" -#endif #include "nsFilePickerProxy.h" #include "mozilla/dom/Element.h" #include "nsGlobalWindow.h" @@ -1261,10 +1258,6 @@ TabChild::RecvLoadURL(const nsCString& aURI, NS_WARNING("WebNavigation()->LoadURI failed. Eating exception, what else can I do?"); } -#ifdef MOZ_CRASHREPORTER - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("URL"), aURI); -#endif - return true; } diff --git a/dom/ipc/TabMessageUtils.h b/dom/ipc/TabMessageUtils.h index cdb76099d..2933173d7 100644 --- a/dom/ipc/TabMessageUtils.h +++ b/dom/ipc/TabMessageUtils.h @@ -13,10 +13,6 @@ #include "nsPIDOMWindow.h" #include "nsCOMPtr.h" -#ifdef MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" -#endif - namespace mozilla { namespace dom { struct RemoteDOMEvent @@ -28,12 +24,8 @@ struct RemoteDOMEvent bool ReadRemoteEvent(const IPC::Message* aMsg, PickleIterator* aIter, mozilla::dom::RemoteDOMEvent* aResult); -#ifdef MOZ_CRASHREPORTER -typedef CrashReporter::ThreadId NativeThreadId; -#else // unused in this case typedef int32_t NativeThreadId; -#endif } // namespace dom } // namespace mozilla diff --git a/dom/media/gmp/GMPChild.cpp b/dom/media/gmp/GMPChild.cpp index 953dae3c6..f8e75e299 100644 --- a/dom/media/gmp/GMPChild.cpp +++ b/dom/media/gmp/GMPChild.cpp @@ -257,10 +257,6 @@ GMPChild::Init(const nsAString& aPluginPath, return false; } -#ifdef MOZ_CRASHREPORTER - SendPCrashReporterConstructor(CrashReporter::CurrentThreadId()); -#endif - mPluginPath = aPluginPath; mSandboxVoucherPath = aVoucherPath; diff --git a/dom/media/gmp/GMPParent.cpp b/dom/media/gmp/GMPParent.cpp index 75468ea9a..00bc97777 100644 --- a/dom/media/gmp/GMPParent.cpp +++ b/dom/media/gmp/GMPParent.cpp @@ -29,12 +29,6 @@ using mozilla::dom::CrashReporterParent; using mozilla::ipc::GeckoChildProcessHost; -#ifdef MOZ_CRASHREPORTER -#include "nsPrintfCString.h" -using CrashReporter::AnnotationTable; -using CrashReporter::GetIDFromMinidump; -#endif - #include "mozilla/Telemetry.h" #ifdef XP_WIN @@ -224,10 +218,6 @@ GMPParent::AbortWaitingForGMPAsyncShutdown(nsITimer* aTimer, void* aClosure) NS_WARNING("Timed out waiting for GMP async shutdown!"); GMPParent* parent = reinterpret_cast<GMPParent*>(aClosure); MOZ_ASSERT(parent->mService); -#if defined(MOZ_CRASHREPORTER) - parent->mService->SetAsyncShutdownPluginState(parent, 'G', - NS_LITERAL_CSTRING("Timed out waiting for async shutdown")); -#endif parent->mService->AsyncShutdownComplete(parent); } @@ -270,22 +260,8 @@ GMPParent::RecvPGMPContentChildDestroyed() { --mGMPContentChildCount; if (!IsUsed()) { -#if defined(MOZ_CRASHREPORTER) - if (mService) { - mService->SetAsyncShutdownPluginState(this, 'E', - NS_LITERAL_CSTRING("Last content child destroyed")); - } -#endif CloseIfUnused(); } -#if defined(MOZ_CRASHREPORTER) - else { - if (mService) { - mService->SetAsyncShutdownPluginState(this, 'F', - nsPrintfCString("Content child destroyed, remaining: %u", mGMPContentChildCount)); - } - } -#endif return true; } @@ -307,38 +283,14 @@ GMPParent::CloseIfUnused() if (mAsyncShutdownRequired) { if (!mAsyncShutdownInProgress) { LOGD("%s: sending async shutdown notification", __FUNCTION__); -#if defined(MOZ_CRASHREPORTER) - if (mService) { - mService->SetAsyncShutdownPluginState(this, 'H', - NS_LITERAL_CSTRING("Sent BeginAsyncShutdown")); - } -#endif mAsyncShutdownInProgress = true; if (!SendBeginAsyncShutdown()) { -#if defined(MOZ_CRASHREPORTER) - if (mService) { - mService->SetAsyncShutdownPluginState(this, 'I', - NS_LITERAL_CSTRING("Could not send BeginAsyncShutdown - Aborting async shutdown")); - } -#endif AbortAsyncShutdown(); } else if (NS_FAILED(EnsureAsyncShutdownTimeoutSet())) { -#if defined(MOZ_CRASHREPORTER) - if (mService) { - mService->SetAsyncShutdownPluginState(this, 'J', - NS_LITERAL_CSTRING("Could not start timer after sending BeginAsyncShutdown - Aborting async shutdown")); - } -#endif AbortAsyncShutdown(); } } } else { -#if defined(MOZ_CRASHREPORTER) - if (mService) { - mService->SetAsyncShutdownPluginState(this, 'K', - NS_LITERAL_CSTRING("No (more) async-shutdown required")); - } -#endif // No async-shutdown, kill async-shutdown timer started in CloseActive(). AbortAsyncShutdown(); // Any async shutdown must be complete. Shutdown GMPStorage. @@ -385,29 +337,11 @@ GMPParent::CloseActive(bool aDieWhenUnloaded) mState = GMPStateUnloading; } if (mState != GMPStateNotLoaded && IsUsed()) { -#if defined(MOZ_CRASHREPORTER) - if (mService) { - mService->SetAsyncShutdownPluginState(this, 'A', - nsPrintfCString("Sent CloseActive, content children to close: %u", mGMPContentChildCount)); - } -#endif if (!SendCloseActive()) { -#if defined(MOZ_CRASHREPORTER) - if (mService) { - mService->SetAsyncShutdownPluginState(this, 'B', - NS_LITERAL_CSTRING("Could not send CloseActive - Aborting async shutdown")); - } -#endif AbortAsyncShutdown(); } else if (IsUsed()) { // We're expecting RecvPGMPContentChildDestroyed's -> Start async-shutdown timer now if needed. if (mAsyncShutdownRequired && NS_FAILED(EnsureAsyncShutdownTimeoutSet())) { -#if defined(MOZ_CRASHREPORTER) - if (mService) { - mService->SetAsyncShutdownPluginState(this, 'C', - NS_LITERAL_CSTRING("Could not start timer after sending CloseActive - Aborting async shutdown")); - } -#endif AbortAsyncShutdown(); } } else { @@ -418,12 +352,6 @@ GMPParent::CloseActive(bool aDieWhenUnloaded) // that time, it might not have proceeded with shutdown; And calling it // again after shutdown is fine because after the first one we'll be in // GMPStateNotLoaded. -#if defined(MOZ_CRASHREPORTER) - if (mService) { - mService->SetAsyncShutdownPluginState(this, 'D', - NS_LITERAL_CSTRING("Content children already destroyed")); - } -#endif CloseIfUnused(); } } @@ -630,78 +558,10 @@ GMPParent::EnsureProcessLoaded() return NS_SUCCEEDED(rv); } -#ifdef MOZ_CRASHREPORTER -void -GMPParent::WriteExtraDataForMinidump(CrashReporter::AnnotationTable& notes) -{ - notes.Put(NS_LITERAL_CSTRING("GMPPlugin"), NS_LITERAL_CSTRING("1")); - notes.Put(NS_LITERAL_CSTRING("PluginFilename"), - NS_ConvertUTF16toUTF8(mName)); - notes.Put(NS_LITERAL_CSTRING("PluginName"), mDisplayName); - notes.Put(NS_LITERAL_CSTRING("PluginVersion"), mVersion); -} - -void -GMPParent::GetCrashID(nsString& aResult) -{ - CrashReporterParent* cr = - static_cast<CrashReporterParent*>(LoneManagedOrNullAsserts(ManagedPCrashReporterParent())); - if (NS_WARN_IF(!cr)) { - return; - } - - AnnotationTable notes(4); - WriteExtraDataForMinidump(notes); - nsCOMPtr<nsIFile> dumpFile; - TakeMinidump(getter_AddRefs(dumpFile), nullptr); - if (!dumpFile) { - NS_WARNING("GMP crash without crash report"); - aResult = mName; - aResult += '-'; - AppendUTF8toUTF16(mVersion, aResult); - return; - } - GetIDFromMinidump(dumpFile, aResult); - cr->GenerateCrashReportForMinidump(dumpFile, ¬es); -} - -static void -GMPNotifyObservers(const uint32_t aPluginID, const nsACString& aPluginName, const nsAString& aPluginDumpID) -{ - nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); - nsCOMPtr<nsIWritablePropertyBag2> propbag = - do_CreateInstance("@mozilla.org/hash-property-bag;1"); - if (obs && propbag) { - propbag->SetPropertyAsUint32(NS_LITERAL_STRING("pluginID"), aPluginID); - propbag->SetPropertyAsACString(NS_LITERAL_STRING("pluginName"), aPluginName); - propbag->SetPropertyAsAString(NS_LITERAL_STRING("pluginDumpID"), aPluginDumpID); - obs->NotifyObservers(propbag, "gmp-plugin-crash", nullptr); - } - - RefPtr<gmp::GeckoMediaPluginService> service = - gmp::GeckoMediaPluginService::GetGeckoMediaPluginService(); - if (service) { - service->RunPluginCrashCallbacks(aPluginID, aPluginName); - } -} -#endif void GMPParent::ActorDestroy(ActorDestroyReason aWhy) { LOGD("%s: (%d)", __FUNCTION__, (int)aWhy); -#ifdef MOZ_CRASHREPORTER - if (AbnormalShutdown == aWhy) { - Telemetry::Accumulate(Telemetry::SUBPROCESS_ABNORMAL_ABORT, - NS_LITERAL_CSTRING("gmplugin"), 1); - nsString dumpID; - GetCrashID(dumpID); - - // NotifyObservers is mainthread-only - NS_DispatchToMainThread(WrapRunnableNM(&GMPNotifyObservers, - mPluginId, mDisplayName, dumpID), - NS_DISPATCH_NORMAL); - } -#endif // warn us off trying to close again mState = GMPStateClosing; mAbnormalShutdownInProgress = true; @@ -711,12 +571,6 @@ GMPParent::ActorDestroy(ActorDestroyReason aWhy) if (AbnormalShutdown == aWhy) { RefPtr<GMPParent> self(this); if (mAsyncShutdownRequired) { -#if defined(MOZ_CRASHREPORTER) - if (mService) { - mService->SetAsyncShutdownPluginState(this, 'M', - NS_LITERAL_CSTRING("Actor destroyed")); - } -#endif mService->AsyncShutdownComplete(this); mAsyncShutdownRequired = false; } @@ -732,9 +586,7 @@ GMPParent::ActorDestroy(ActorDestroyReason aWhy) mozilla::dom::PCrashReporterParent* GMPParent::AllocPCrashReporterParent(const NativeThreadId& aThread) { -#ifndef MOZ_CRASHREPORTER MOZ_ASSERT(false, "Should only be sent if crash reporting is enabled."); -#endif CrashReporterParent* cr = new CrashReporterParent(); cr->SetChildData(aThread, GeckoProcessType_GMPlugin); return cr; @@ -1043,12 +895,6 @@ GMPParent::RecvAsyncShutdownComplete() LOGD("%s", __FUNCTION__); MOZ_ASSERT(mAsyncShutdownRequired); -#if defined(MOZ_CRASHREPORTER) - if (mService) { - mService->SetAsyncShutdownPluginState(this, 'L', - NS_LITERAL_CSTRING("Received AsyncShutdownComplete")); - } -#endif AbortAsyncShutdown(); return true; } diff --git a/dom/media/gmp/GMPParent.h b/dom/media/gmp/GMPParent.h index 91a6fb429..4f91ec5ba 100644 --- a/dom/media/gmp/GMPParent.h +++ b/dom/media/gmp/GMPParent.h @@ -25,17 +25,6 @@ class nsIThread; -#ifdef MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" - -namespace mozilla { -namespace dom { -class PCrashReporterParent; -class CrashReporterParent; -} -} -#endif - namespace mozilla { namespace gmp { @@ -177,10 +166,6 @@ private: RefPtr<GenericPromise> ReadGMPInfoFile(nsIFile* aFile); RefPtr<GenericPromise> ParseChromiumManifest(nsString aJSON); // Main thread. RefPtr<GenericPromise> ReadChromiumManifestFile(nsIFile* aFile); // GMP thread. -#ifdef MOZ_CRASHREPORTER - void WriteExtraDataForMinidump(CrashReporter::AnnotationTable& notes); - void GetCrashID(nsString& aResult); -#endif void ActorDestroy(ActorDestroyReason aWhy) override; PCrashReporterParent* AllocPCrashReporterParent(const NativeThreadId& aThread) override; diff --git a/dom/media/gmp/GMPServiceParent.cpp b/dom/media/gmp/GMPServiceParent.cpp index 8741989e3..f25c36811 100644 --- a/dom/media/gmp/GMPServiceParent.cpp +++ b/dom/media/gmp/GMPServiceParent.cpp @@ -36,10 +36,6 @@ #include "nsHashKeys.h" #include "nsIFile.h" #include "nsISimpleEnumerator.h" -#if defined(MOZ_CRASHREPORTER) -#include "nsExceptionHandler.h" -#include "nsPrintfCString.h" -#endif #include "nsIXULRuntime.h" #include "GMPDecoderModule.h" #include <limits> @@ -88,9 +84,6 @@ NS_IMPL_ISUPPORTS_INHERITED(GeckoMediaPluginServiceParent, GeckoMediaPluginServiceParent::GeckoMediaPluginServiceParent() : mShuttingDown(false) -#ifdef MOZ_CRASHREPORTER - , mAsyncShutdownPluginStatesMutex("GeckoMediaPluginService::mAsyncShutdownPluginStatesMutex") -#endif , mScannedPluginOnDisk(false) , mWaitingForPluginsSyncShutdown(false) , mInitPromiseMonitor("GeckoMediaPluginServiceParent::mInitPromiseMonitor") @@ -421,28 +414,16 @@ GeckoMediaPluginServiceParent::Observe(nsISupports* aSubject, if (gmpThread) { LOGD(("%s::%s Starting to unload plugins, waiting for first sync shutdown..." , __CLASS__, __FUNCTION__)); -#ifdef MOZ_CRASHREPORTER - SetAsyncShutdownPluginState(nullptr, '0', - NS_LITERAL_CSTRING("Dispatching UnloadPlugins")); -#endif gmpThread->Dispatch( NewRunnableMethod(this, &GeckoMediaPluginServiceParent::UnloadPlugins), NS_DISPATCH_NORMAL); -#ifdef MOZ_CRASHREPORTER - SetAsyncShutdownPluginState(nullptr, '1', - NS_LITERAL_CSTRING("Waiting for sync shutdown")); -#endif // Wait for UnloadPlugins() to do initial sync shutdown... while (mWaitingForPluginsSyncShutdown) { NS_ProcessNextEvent(NS_GetCurrentThread(), true); } -#ifdef MOZ_CRASHREPORTER - SetAsyncShutdownPluginState(nullptr, '4', - NS_LITERAL_CSTRING("Waiting for async shutdown")); -#endif // Wait for other plugins (if any) to do async shutdown... auto syncShutdownPluginsRemaining = std::numeric_limits<decltype(mAsyncShutdownPlugins.Length())>::max(); @@ -452,10 +433,6 @@ GeckoMediaPluginServiceParent::Observe(nsISupports* aSubject, if (mAsyncShutdownPlugins.IsEmpty()) { LOGD(("%s::%s Finished unloading all plugins" , __CLASS__, __FUNCTION__)); -#if defined(MOZ_CRASHREPORTER) - CrashReporter::RemoveCrashReportAnnotation( - NS_LITERAL_CSTRING("AsyncPluginShutdown")); -#endif break; } else if (mAsyncShutdownPlugins.Length() < syncShutdownPluginsRemaining) { // First time here, or number of pending plugins has decreased. @@ -463,24 +440,10 @@ GeckoMediaPluginServiceParent::Observe(nsISupports* aSubject, syncShutdownPluginsRemaining = mAsyncShutdownPlugins.Length(); LOGD(("%s::%s Still waiting for %d plugins to shutdown..." , __CLASS__, __FUNCTION__, (int)syncShutdownPluginsRemaining)); -#if defined(MOZ_CRASHREPORTER) - nsAutoCString names; - for (const auto& plugin : mAsyncShutdownPlugins) { - if (!names.IsEmpty()) { names.Append(NS_LITERAL_CSTRING(", ")); } - names.Append(plugin->GetDisplayName()); - } - CrashReporter::AnnotateCrashReport( - NS_LITERAL_CSTRING("AsyncPluginShutdown"), - names); -#endif } } NS_ProcessNextEvent(NS_GetCurrentThread(), true); } -#ifdef MOZ_CRASHREPORTER - SetAsyncShutdownPluginState(nullptr, '5', - NS_LITERAL_CSTRING("Async shutdown complete")); -#endif } else { // GMP thread has already shutdown. MOZ_ASSERT(mPlugins.IsEmpty()); @@ -627,66 +590,6 @@ GeckoMediaPluginServiceParent::AsyncShutdownComplete(GMPParent* aParent) } } -#ifdef MOZ_CRASHREPORTER -void -GeckoMediaPluginServiceParent::SetAsyncShutdownPluginState(GMPParent* aGMPParent, - char aId, - const nsCString& aState) -{ - MutexAutoLock lock(mAsyncShutdownPluginStatesMutex); - if (!aGMPParent) { - mAsyncShutdownPluginStates.Update(NS_LITERAL_CSTRING("-"), - NS_LITERAL_CSTRING("-"), - aId, - aState); - return; - } - mAsyncShutdownPluginStates.Update(aGMPParent->GetDisplayName(), - nsPrintfCString("%p", aGMPParent), - aId, - aState); -} - -void -GeckoMediaPluginServiceParent::AsyncShutdownPluginStates::Update(const nsCString& aPlugin, - const nsCString& aInstance, - char aId, - const nsCString& aState) -{ - nsCString note; - StatesByInstance* instances = mStates.LookupOrAdd(aPlugin); - if (!instances) { return; } - State* state = instances->LookupOrAdd(aInstance); - if (!state) { return; } - state->mStateSequence += aId; - state->mLastStateDescription = aState; - note += '{'; - bool firstPlugin = true; - for (auto pluginIt = mStates.ConstIter(); !pluginIt.Done(); pluginIt.Next()) { - if (!firstPlugin) { note += ','; } else { firstPlugin = false; } - note += pluginIt.Key(); - note += ":{"; - bool firstInstance = true; - for (auto instanceIt = pluginIt.UserData()->ConstIter(); !instanceIt.Done(); instanceIt.Next()) { - if (!firstInstance) { note += ','; } else { firstInstance = false; } - note += instanceIt.Key(); - note += ":\""; - note += instanceIt.UserData()->mStateSequence; - note += '='; - note += instanceIt.UserData()->mLastStateDescription; - note += '"'; - } - note += '}'; - } - note += '}'; - LOGD(("%s::%s states[%s][%s]='%c'/'%s' -> %s", __CLASS__, __FUNCTION__, - aPlugin.get(), aInstance.get(), aId, aState.get(), note.get())); - CrashReporter::AnnotateCrashReport( - NS_LITERAL_CSTRING("AsyncPluginShutdownStates"), - note); -} -#endif // MOZ_CRASHREPORTER - void GeckoMediaPluginServiceParent::NotifyAsyncShutdownComplete() { @@ -714,10 +617,6 @@ GeckoMediaPluginServiceParent::UnloadPlugins() MOZ_ASSERT(NS_GetCurrentThread() == mGMPThread); MOZ_ASSERT(!mShuttingDownOnGMPThread); mShuttingDownOnGMPThread = true; -#ifdef MOZ_CRASHREPORTER - SetAsyncShutdownPluginState(nullptr, '2', - NS_LITERAL_CSTRING("Starting to unload plugins")); -#endif nsTArray<RefPtr<GMPParent>> plugins; { @@ -742,17 +641,9 @@ GeckoMediaPluginServiceParent::UnloadPlugins() // Note: CloseActive may be async; it could actually finish // shutting down when all the plugins have unloaded. for (const auto& plugin : plugins) { -#ifdef MOZ_CRASHREPORTER - SetAsyncShutdownPluginState(plugin, 'S', - NS_LITERAL_CSTRING("CloseActive")); -#endif plugin->CloseActive(true); } -#ifdef MOZ_CRASHREPORTER - SetAsyncShutdownPluginState(nullptr, '3', - NS_LITERAL_CSTRING("Dispatching sync-shutdown-complete")); -#endif nsCOMPtr<nsIRunnable> task(NewRunnableMethod( this, &GeckoMediaPluginServiceParent::NotifySyncShutdownComplete)); NS_DispatchToMainThread(task); diff --git a/dom/media/gmp/GMPServiceParent.h b/dom/media/gmp/GMPServiceParent.h index f3f43e215..49d81055b 100644 --- a/dom/media/gmp/GMPServiceParent.h +++ b/dom/media/gmp/GMPServiceParent.h @@ -54,9 +54,6 @@ public: void AsyncShutdownComplete(GMPParent* aParent); int32_t AsyncShutdownTimeoutMs(); -#ifdef MOZ_CRASHREPORTER - void SetAsyncShutdownPluginState(GMPParent* aGMPParent, char aId, const nsCString& aState); -#endif // MOZ_CRASHREPORTER RefPtr<GenericPromise> EnsureInitialized(); RefPtr<GenericPromise> AsyncAddPluginDirectory(const nsAString& aDirectory); @@ -169,21 +166,6 @@ private: bool mShuttingDown; nsTArray<RefPtr<GMPParent>> mAsyncShutdownPlugins; -#ifdef MOZ_CRASHREPORTER - Mutex mAsyncShutdownPluginStatesMutex; // Protects mAsyncShutdownPluginStates. - class AsyncShutdownPluginStates - { - public: - void Update(const nsCString& aPlugin, const nsCString& aInstance, - char aId, const nsCString& aState); - private: - struct State { nsCString mStateSequence; nsCString mLastStateDescription; }; - typedef nsClassHashtable<nsCStringHashKey, State> StatesByInstance; - typedef nsClassHashtable<nsCStringHashKey, StatesByInstance> StateInstancesByPlugin; - StateInstancesByPlugin mStates; - } mAsyncShutdownPluginStates; -#endif // MOZ_CRASHREPORTER - // True if we've inspected MOZ_GMP_PATH on the GMP thread and loaded any // plugins found there into mPlugins. Atomic<bool> mScannedPluginOnDisk; diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp index bd71d6f65..916bdea0f 100644 --- a/dom/plugins/base/nsPluginHost.cpp +++ b/dom/plugins/base/nsPluginHost.cpp @@ -109,10 +109,6 @@ #define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args) #endif -#if MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" -#endif - #include "npapi.h" using namespace mozilla; @@ -962,12 +958,6 @@ nsPluginHost::TrySetUpPluginInstance(const nsACString &aMimeType, plugin->GetLibrary()->SetHasLocalInstance(); -#if defined(MOZ_WIDGET_ANDROID) && defined(MOZ_CRASHREPORTER) - if (pluginTag->mIsFlashPlugin) { - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("FlashVersion"), pluginTag->Version()); - } -#endif - RefPtr<nsNPAPIPluginInstance> instance = new nsNPAPIPluginInstance(); // This will create the owning reference. The connection must be made between the diff --git a/dom/plugins/base/nsPluginsDirDarwin.cpp b/dom/plugins/base/nsPluginsDirDarwin.cpp index 6edc4fd6a..0085eec0d 100644 --- a/dom/plugins/base/nsPluginsDirDarwin.cpp +++ b/dom/plugins/base/nsPluginsDirDarwin.cpp @@ -26,9 +26,6 @@ #include "mozilla/UniquePtr.h" #include "nsCocoaFeatures.h" -#if defined(MOZ_CRASHREPORTER) -#include "nsExceptionHandler.h" -#endif #include <string.h> #include <stdio.h> @@ -487,14 +484,6 @@ nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info, PRLibrary **outLibrary) NS_WARNING(msg.get()); return NS_ERROR_FAILURE; } -#if defined(MOZ_CRASHREPORTER) - // The block above assumes that "fbplugin" is the filename of the plugin - // to be blocked, or that the filename starts with "fbplugin_". But we - // don't yet know for sure if this is always true. So for the time being - // record extra information in our crash logs. - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Bug_1086977"), - fileName); -#endif } // It's possible that our plugin has 2 entry points that'll give us mime type @@ -504,14 +493,6 @@ nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info, PRLibrary **outLibrary) // Sadly we have to load the library for this to work. rv = LoadPlugin(outLibrary); -#if defined(MOZ_CRASHREPORTER) - if (nsCocoaFeatures::OnYosemiteOrLater()) { - // If we didn't crash in LoadPlugin(), change the previous annotation so we - // don't sow confusion. - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Bug_1086977"), - NS_LITERAL_CSTRING("Didn't crash, please ignore")); - } -#endif if (NS_FAILED(rv)) return rv; diff --git a/dom/plugins/ipc/PluginMessageUtils.h b/dom/plugins/ipc/PluginMessageUtils.h index 55be59d62..4532fac93 100644 --- a/dom/plugins/ipc/PluginMessageUtils.h +++ b/dom/plugins/ipc/PluginMessageUtils.h @@ -23,9 +23,6 @@ #include "nsTArray.h" #include "mozilla/Logging.h" #include "nsHashKeys.h" -#ifdef MOZ_CRASHREPORTER -# include "nsExceptionHandler.h" -#endif #ifdef XP_MACOSX #include "PluginInterposeOSX.h" #else diff --git a/dom/plugins/ipc/PluginModuleChild.cpp b/dom/plugins/ipc/PluginModuleChild.cpp index 84dc7c71f..7350a7fa7 100644 --- a/dom/plugins/ipc/PluginModuleChild.cpp +++ b/dom/plugins/ipc/PluginModuleChild.cpp @@ -753,10 +753,6 @@ PluginModuleChild::AnswerPCrashReporterConstructor( mozilla::dom::NativeThreadId* id, uint32_t* processType) { -#ifdef MOZ_CRASHREPORTER - *id = CrashReporter::CurrentThreadId(); - *processType = XRE_GetProcessType(); -#endif return true; } diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp index b85a3e94b..73f9c1025 100755 --- a/dom/plugins/ipc/PluginModuleParent.cpp +++ b/dom/plugins/ipc/PluginModuleParent.cpp @@ -74,12 +74,6 @@ using namespace mozilla; using namespace mozilla::plugins; using namespace mozilla::plugins::parent; -#ifdef MOZ_CRASHREPORTER -#include "mozilla/dom/CrashReporterParent.h" - -using namespace CrashReporter; -#endif - static const char kContentTimeoutPref[] = "dom.ipc.plugins.contentTimeoutSecs"; static const char kChildTimeoutPref[] = "dom.ipc.plugins.timeoutSecs"; static const char kParentTimeoutPref[] = "dom.ipc.plugins.parentTimeoutSecs"; @@ -134,66 +128,6 @@ mozilla::plugins::SetupBridge(uint32_t aPluginId, return true; } -#ifdef MOZ_CRASHREPORTER_INJECTOR - -/** - * Use for executing CreateToolhelp32Snapshot off main thread - */ -class mozilla::plugins::FinishInjectorInitTask : public mozilla::CancelableRunnable -{ -public: - FinishInjectorInitTask() - : mMutex("FlashInjectorInitTask::mMutex") - , mParent(nullptr) - , mMainThreadMsgLoop(MessageLoop::current()) - { - MOZ_ASSERT(NS_IsMainThread()); - } - - void Init(PluginModuleChromeParent* aParent) - { - MOZ_ASSERT(aParent); - mParent = aParent; - } - - void PostToMainThread() - { - RefPtr<Runnable> self = this; - mSnapshot.own(CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)); - { // Scope for lock - mozilla::MutexAutoLock lock(mMutex); - if (mMainThreadMsgLoop) { - mMainThreadMsgLoop->PostTask(self.forget()); - } - } - } - - NS_IMETHOD Run() override - { - mParent->DoInjection(mSnapshot); - // We don't need to hold this lock during DoInjection, but we do need - // to obtain it before returning from Run() to ensure that - // PostToMainThread has completed before we return. - mozilla::MutexAutoLock lock(mMutex); - return NS_OK; - } - - nsresult Cancel() override - { - mozilla::MutexAutoLock lock(mMutex); - mMainThreadMsgLoop = nullptr; - return NS_OK; - } - -private: - mozilla::Mutex mMutex; - nsAutoHandle mSnapshot; - PluginModuleChromeParent* mParent; - MessageLoop* mMainThreadMsgLoop; -}; - -#endif // MOZ_CRASHREPORTER_INJECTOR - namespace { /** @@ -578,29 +512,6 @@ PluginModuleChromeParent::OnProcessLaunched(const bool aSucceeded) RegisterSettingsCallbacks(); -#ifdef MOZ_CRASHREPORTER - // If this fails, we're having IPC troubles, and we're doomed anyways. - if (!CrashReporterParent::CreateCrashReporter(this)) { - mShutdown = true; - Close(); - OnInitFailure(); - return; - } - CrashReporterParent* crashReporter = CrashReporter(); - if (crashReporter) { - crashReporter->AnnotateCrashReport(NS_LITERAL_CSTRING("AsyncPluginInit"), - mIsStartingAsync ? - NS_LITERAL_CSTRING("1") : - NS_LITERAL_CSTRING("0")); - } -#ifdef XP_WIN - { // Scope for lock - mozilla::MutexAutoLock lock(mCrashReporterMutex); - mCrashReporter = CrashReporter(); - } -#endif -#endif - #if defined(XP_WIN) && defined(_X86_) // Protected mode only applies to Windows and only to x86. if (!mIsBlocklisted && mIsFlashPlugin && @@ -686,12 +597,6 @@ PluginModuleParent::PluginModuleParent(bool aIsChrome, bool aAllowAsyncInit) , mIsNPShutdownPending(false) , mAsyncNewRv(NS_ERROR_NOT_INITIALIZED) { -#if defined(MOZ_CRASHREPORTER) - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AsyncPluginInit"), - mIsStartingAsync ? - NS_LITERAL_CSTRING("1") : - NS_LITERAL_CSTRING("0")); -#endif } PluginModuleParent::~PluginModuleParent() @@ -734,15 +639,6 @@ PluginModuleChromeParent::PluginModuleChromeParent(const char* aFilePath, , mHangUIParent(nullptr) , mHangUIEnabled(true) , mIsTimerReset(true) -#ifdef MOZ_CRASHREPORTER - , mCrashReporterMutex("PluginModuleChromeParent::mCrashReporterMutex") - , mCrashReporter(nullptr) -#endif -#endif -#ifdef MOZ_CRASHREPORTER_INJECTOR - , mFlashProcess1(0) - , mFlashProcess2(0) - , mFinishInitTask(nullptr) #endif , mInitOnAsyncConnect(false) , mAsyncInitRv(NS_ERROR_NOT_INITIALIZED) @@ -790,17 +686,6 @@ PluginModuleChromeParent::~PluginModuleChromeParent() mSubprocess = nullptr; } -#ifdef MOZ_CRASHREPORTER_INJECTOR - if (mFlashProcess1) - UnregisterInjectorCallback(mFlashProcess1); - if (mFlashProcess2) - UnregisterInjectorCallback(mFlashProcess2); - if (mFinishInitTask) { - // mFinishInitTask will be deleted by the main thread message_loop - mFinishInitTask->Cancel(); - } -#endif - UnregisterSettingsCallbacks(); Preferences::UnregisterCallback(TimeoutChanged, kChildTimeoutPref, this); @@ -818,52 +703,6 @@ PluginModuleChromeParent::~PluginModuleChromeParent() mozilla::HangMonitor::UnregisterAnnotator(*this); } -#ifdef MOZ_CRASHREPORTER -void -PluginModuleChromeParent::WriteExtraDataForMinidump(AnnotationTable& notes) -{ -#ifdef XP_WIN - // mCrashReporterMutex is already held by the caller - mCrashReporterMutex.AssertCurrentThreadOwns(); -#endif - typedef nsDependentCString CS; - - // Get the plugin filename, try to get just the file leafname - const std::string& pluginFile = mSubprocess->GetPluginFilePath(); - size_t filePos = pluginFile.rfind(FILE_PATH_SEPARATOR); - if (filePos == std::string::npos) - filePos = 0; - else - filePos++; - notes.Put(NS_LITERAL_CSTRING("PluginFilename"), CS(pluginFile.substr(filePos).c_str())); - - notes.Put(NS_LITERAL_CSTRING("PluginName"), mPluginName); - notes.Put(NS_LITERAL_CSTRING("PluginVersion"), mPluginVersion); - - CrashReporterParent* crashReporter = CrashReporter(); - if (crashReporter) { -#ifdef XP_WIN - if (mPluginCpuUsageOnHang.Length() > 0) { - notes.Put(NS_LITERAL_CSTRING("NumberOfProcessors"), - nsPrintfCString("%d", PR_GetNumberOfProcessors())); - - nsCString cpuUsageStr; - cpuUsageStr.AppendFloat(std::ceil(mPluginCpuUsageOnHang[0] * 100) / 100); - notes.Put(NS_LITERAL_CSTRING("PluginCpuUsage"), cpuUsageStr); - -#ifdef MOZ_CRASHREPORTER_INJECTOR - for (uint32_t i=1; i<mPluginCpuUsageOnHang.Length(); ++i) { - nsCString tempStr; - tempStr.AppendFloat(std::ceil(mPluginCpuUsageOnHang[i] * 100) / 100); - notes.Put(nsPrintfCString("CpuUsageFlashProcess%d", i), tempStr); - } -#endif - } -#endif - } -} -#endif // MOZ_CRASHREPORTER - void PluginModuleParent::SetChildTimeout(const int32_t aChildTimeout) { @@ -1123,20 +962,6 @@ PluginModuleChromeParent::AnnotateHang(mozilla::HangMonitor::HangAnnotations& aA } } -#ifdef MOZ_CRASHREPORTER -static bool -CreatePluginMinidump(base::ProcessId processId, ThreadId childThread, - nsIFile* parentMinidump, const nsACString& name) -{ - mozilla::ipc::ScopedProcessHandle handle; - if (processId == 0 || - !base::OpenPrivilegedProcessHandle(processId, &handle.rwget())) { - return false; - } - return CreateAdditionalChildMinidump(handle, 0, parentMinidump, name); -} -#endif - bool PluginModuleChromeParent::ShouldContinueFromReplyTimeout() { @@ -1184,87 +1009,7 @@ PluginModuleChromeParent::TakeFullMinidump(base::ProcessId aContentPid, const nsAString& aBrowserDumpId, nsString& aDumpId) { -#ifdef MOZ_CRASHREPORTER -#ifdef XP_WIN - mozilla::MutexAutoLock lock(mCrashReporterMutex); -#endif // XP_WIN - - CrashReporterParent* crashReporter = CrashReporter(); - if (!crashReporter) { - return; - } - - bool reportsReady = false; - - // Check to see if we already have a browser dump id - with e10s plugin - // hangs we take this earlier (see ProcessHangMonitor) from a background - // thread. We do this before we message the main thread about the hang - // since the posted message will trash our browser stack state. - bool exists; - nsCOMPtr<nsIFile> browserDumpFile; - if (!aBrowserDumpId.IsEmpty() && - CrashReporter::GetMinidumpForID(aBrowserDumpId, getter_AddRefs(browserDumpFile)) && - browserDumpFile && - NS_SUCCEEDED(browserDumpFile->Exists(&exists)) && exists) - { - // We have a single browser report, generate a new plugin process parent - // report and pair it up with the browser report handed in. - reportsReady = crashReporter->GenerateMinidumpAndPair(this, browserDumpFile, - NS_LITERAL_CSTRING("browser")); - if (!reportsReady) { - browserDumpFile = nullptr; - CrashReporter::DeleteMinidumpFilesForID(aBrowserDumpId); - } - } - - // Generate crash report including plugin and browser process minidumps. - // The plugin process is the parent report with additional dumps including - // the browser process, content process when running under e10s, and - // various flash subprocesses if we're the flash module. - if (!reportsReady) { - reportsReady = crashReporter->GeneratePairedMinidump(this); - } - - if (reportsReady) { - // Important to set this here, it tells the ActorDestroy handler - // that we have an existing crash report that needs to be finalized. - mPluginDumpID = crashReporter->ChildDumpID(); - aDumpId = mPluginDumpID; - PLUGIN_LOG_DEBUG( - ("generated paired browser/plugin minidumps: %s)", - NS_ConvertUTF16toUTF8(mPluginDumpID).get())); - nsAutoCString additionalDumps("browser"); - nsCOMPtr<nsIFile> pluginDumpFile; - if (GetMinidumpForID(mPluginDumpID, getter_AddRefs(pluginDumpFile)) && - pluginDumpFile) { -#ifdef MOZ_CRASHREPORTER_INJECTOR - // If we have handles to the flash sandbox processes on Windows, - // include those minidumps as well. - if (CreatePluginMinidump(mFlashProcess1, 0, pluginDumpFile, - NS_LITERAL_CSTRING("flash1"))) { - additionalDumps.AppendLiteral(",flash1"); - } - if (CreatePluginMinidump(mFlashProcess2, 0, pluginDumpFile, - NS_LITERAL_CSTRING("flash2"))) { - additionalDumps.AppendLiteral(",flash2"); - } -#endif // MOZ_CRASHREPORTER_INJECTOR - if (aContentPid != mozilla::ipc::kInvalidProcessId) { - // Include the content process minidump - if (CreatePluginMinidump(aContentPid, 0, - pluginDumpFile, - NS_LITERAL_CSTRING("content"))) { - additionalDumps.AppendLiteral(",content"); - } - } - } - crashReporter->AnnotateCrashReport( - NS_LITERAL_CSTRING("additional_minidumps"), - additionalDumps); - } else { - NS_WARNING("failed to capture paired minidumps from hang"); - } -#endif // MOZ_CRASHREPORTER + /*** STUB ***/ } void @@ -1273,43 +1018,6 @@ PluginModuleChromeParent::TerminateChildProcess(MessageLoop* aMsgLoop, const nsCString& aMonitorDescription, const nsAString& aDumpId) { -#ifdef MOZ_CRASHREPORTER - // Start by taking a full minidump if necessary, this is done early - // because it also needs to lock the mCrashReporterMutex and Mutex doesn't - // support recrusive locking. - nsAutoString dumpId; - if (aDumpId.IsEmpty()) { - TakeFullMinidump(aContentPid, EmptyString(), dumpId); - } - -#ifdef XP_WIN - mozilla::MutexAutoLock lock(mCrashReporterMutex); - CrashReporterParent* crashReporter = mCrashReporter; - if (!crashReporter) { - // If mCrashReporter is null then the hang has ended, the plugin module - // is shutting down. There's nothing to do here. - return; - } -#else - CrashReporterParent* crashReporter = CrashReporter(); -#endif // XP_WIN - crashReporter->AnnotateCrashReport(NS_LITERAL_CSTRING("PluginHang"), - NS_LITERAL_CSTRING("1")); - crashReporter->AnnotateCrashReport(NS_LITERAL_CSTRING("HangMonitorDescription"), - aMonitorDescription); -#ifdef XP_WIN - if (mHangUIParent) { - unsigned int hangUIDuration = mHangUIParent->LastShowDurationMs(); - if (hangUIDuration) { - nsPrintfCString strHangUIDuration("%u", hangUIDuration); - crashReporter->AnnotateCrashReport( - NS_LITERAL_CSTRING("PluginHangUIDuration"), - strHangUIDuration); - } - } -#endif // XP_WIN -#endif // MOZ_CRASHREPORTER - mozilla::ipc::ScopedProcessHandle geckoChildProcess; bool childOpened = base::OpenProcessHandle(OtherPid(), &geckoChildProcess.rwget()); @@ -1323,19 +1031,6 @@ PluginModuleChromeParent::TerminateChildProcess(MessageLoop* aMsgLoop, processHandles.AppendElement(geckoChildProcess); } -#ifdef MOZ_CRASHREPORTER_INJECTOR - mozilla::ipc::ScopedProcessHandle flashBrokerProcess; - if (mFlashProcess1 && - base::OpenProcessHandle(mFlashProcess1, &flashBrokerProcess.rwget())) { - processHandles.AppendElement(flashBrokerProcess); - } - mozilla::ipc::ScopedProcessHandle flashSandboxProcess; - if (mFlashProcess2 && - base::OpenProcessHandle(mFlashProcess2, &flashSandboxProcess.rwget())) { - processHandles.AppendElement(flashSandboxProcess); - } -#endif - if (!GetProcessCpuUsage(processHandles, mPluginCpuUsageOnHang)) { mPluginCpuUsageOnHang.Clear(); } @@ -1482,108 +1177,6 @@ PluginModuleChromeParent::OnHangUIContinue() } #endif // XP_WIN -#ifdef MOZ_CRASHREPORTER -CrashReporterParent* -PluginModuleChromeParent::CrashReporter() -{ - return static_cast<CrashReporterParent*>(LoneManagedOrNullAsserts(ManagedPCrashReporterParent())); -} - -#ifdef MOZ_CRASHREPORTER_INJECTOR -static void -RemoveMinidump(nsIFile* minidump) -{ - if (!minidump) - return; - - minidump->Remove(false); - nsCOMPtr<nsIFile> extraFile; - if (GetExtraFileForMinidump(minidump, - getter_AddRefs(extraFile))) { - extraFile->Remove(true); - } -} -#endif // MOZ_CRASHREPORTER_INJECTOR - -void -PluginModuleChromeParent::ProcessFirstMinidump() -{ -#ifdef XP_WIN - mozilla::MutexAutoLock lock(mCrashReporterMutex); -#endif - CrashReporterParent* crashReporter = CrashReporter(); - if (!crashReporter) - return; - - AnnotationTable notes(4); - WriteExtraDataForMinidump(notes); - - if (!mPluginDumpID.IsEmpty()) { - // mPluginDumpID may be set in TerminateChildProcess, which means the - // process hang monitor has already collected a 3-way browser, plugin, - // content crash report. If so, update the existing report with our - // annotations and finalize it. If not, fall through for standard - // plugin crash report handling. - crashReporter->GenerateChildData(¬es); - crashReporter->FinalizeChildData(); - return; - } - - uint32_t sequence = UINT32_MAX; - nsCOMPtr<nsIFile> dumpFile; - nsAutoCString flashProcessType; - TakeMinidump(getter_AddRefs(dumpFile), &sequence); - -#ifdef MOZ_CRASHREPORTER_INJECTOR - nsCOMPtr<nsIFile> childDumpFile; - uint32_t childSequence; - - if (mFlashProcess1 && - TakeMinidumpForChild(mFlashProcess1, - getter_AddRefs(childDumpFile), - &childSequence)) { - if (childSequence < sequence) { - RemoveMinidump(dumpFile); - dumpFile = childDumpFile; - sequence = childSequence; - flashProcessType.AssignLiteral("Broker"); - } - else { - RemoveMinidump(childDumpFile); - } - } - if (mFlashProcess2 && - TakeMinidumpForChild(mFlashProcess2, - getter_AddRefs(childDumpFile), - &childSequence)) { - if (childSequence < sequence) { - RemoveMinidump(dumpFile); - dumpFile = childDumpFile; - sequence = childSequence; - flashProcessType.AssignLiteral("Sandbox"); - } - else { - RemoveMinidump(childDumpFile); - } - } -#endif - - if (!dumpFile) { - NS_WARNING("[PluginModuleParent::ActorDestroy] abnormal shutdown without minidump!"); - return; - } - - PLUGIN_LOG_DEBUG(("got child minidump: %s", - NS_ConvertUTF16toUTF8(mPluginDumpID).get())); - - GetIDFromMinidump(dumpFile, mPluginDumpID); - if (!flashProcessType.IsEmpty()) { - notes.Put(NS_LITERAL_CSTRING("FlashProcessDump"), flashProcessType); - } - crashReporter->GenerateCrashReportForMinidump(dumpFile, ¬es); -} -#endif - void PluginModuleParent::ActorDestroy(ActorDestroyReason why) { @@ -1621,9 +1214,6 @@ void PluginModuleChromeParent::ActorDestroy(ActorDestroyReason why) { if (why == AbnormalShutdown) { -#ifdef MOZ_CRASHREPORTER - ProcessFirstMinidump(); -#endif Telemetry::Accumulate(Telemetry::SUBPROCESS_ABNORMAL_ABORT, NS_LITERAL_CSTRING("plugin"), 1); } @@ -2405,9 +1995,6 @@ PluginModuleChromeParent::RecvNP_InitializeResult(const NPError& aError) } #endif -#ifdef MOZ_CRASHREPORTER_INJECTOR - InitializeInjector(); -#endif } return PluginModuleParent::RecvNP_InitializeResult(aError) && ok; @@ -2955,24 +2542,12 @@ PCrashReporterParent* PluginModuleChromeParent::AllocPCrashReporterParent(mozilla::dom::NativeThreadId* id, uint32_t* processType) { -#ifdef MOZ_CRASHREPORTER - return new CrashReporterParent(); -#else return nullptr; -#endif } bool PluginModuleChromeParent::DeallocPCrashReporterParent(PCrashReporterParent* actor) { -#ifdef MOZ_CRASHREPORTER -#ifdef XP_WIN - mozilla::MutexAutoLock lock(mCrashReporterMutex); - if (actor == static_cast<PCrashReporterParent*>(mCrashReporter)) { - mCrashReporter = nullptr; - } -#endif -#endif delete actor; return true; } @@ -3134,107 +2709,6 @@ PluginModuleParent::AnswerNPN_SetValue_NPPVpluginRequiresAudioDeviceChanges( return true; } -#ifdef MOZ_CRASHREPORTER_INJECTOR - -// We only add the crash reporter to subprocess which have the filename -// FlashPlayerPlugin* -#define FLASH_PROCESS_PREFIX "FLASHPLAYERPLUGIN" - -static DWORD -GetFlashChildOfPID(DWORD pid, HANDLE snapshot) -{ - PROCESSENTRY32 entry = { - sizeof(entry) - }; - for (BOOL ok = Process32First(snapshot, &entry); - ok; - ok = Process32Next(snapshot, &entry)) { - if (entry.th32ParentProcessID == pid) { - nsString name(entry.szExeFile); - ToUpperCase(name); - if (StringBeginsWith(name, NS_LITERAL_STRING(FLASH_PROCESS_PREFIX))) { - return entry.th32ProcessID; - } - } - } - return 0; -} - -// We only look for child processes of the Flash plugin, NPSWF* -#define FLASH_PLUGIN_PREFIX "NPSWF" - -void -PluginModuleChromeParent::InitializeInjector() -{ - if (!Preferences::GetBool("dom.ipc.plugins.flash.subprocess.crashreporter.enabled", false)) - return; - - nsCString path(Process()->GetPluginFilePath().c_str()); - ToUpperCase(path); - int32_t lastSlash = path.RFindCharInSet("\\/"); - if (kNotFound == lastSlash) - return; - - if (!StringBeginsWith(Substring(path, lastSlash + 1), - NS_LITERAL_CSTRING(FLASH_PLUGIN_PREFIX))) - return; - - TimeStamp th32Start = TimeStamp::Now(); - mFinishInitTask = mChromeTaskFactory.NewTask<FinishInjectorInitTask>(); - mFinishInitTask->Init(this); - if (!::QueueUserWorkItem(&PluginModuleChromeParent::GetToolhelpSnapshot, - mFinishInitTask, WT_EXECUTEDEFAULT)) { - mFinishInitTask = nullptr; - return; - } - TimeStamp th32End = TimeStamp::Now(); - mTimeBlocked += (th32End - th32Start); -} - -void -PluginModuleChromeParent::DoInjection(const nsAutoHandle& aSnapshot) -{ - DWORD pluginProcessPID = GetProcessId(Process()->GetChildProcessHandle()); - mFlashProcess1 = GetFlashChildOfPID(pluginProcessPID, aSnapshot); - if (mFlashProcess1) { - InjectCrashReporterIntoProcess(mFlashProcess1, this); - - mFlashProcess2 = GetFlashChildOfPID(mFlashProcess1, aSnapshot); - if (mFlashProcess2) { - InjectCrashReporterIntoProcess(mFlashProcess2, this); - } - } - mFinishInitTask = nullptr; -} - -DWORD WINAPI -PluginModuleChromeParent::GetToolhelpSnapshot(LPVOID aContext) -{ - FinishInjectorInitTask* task = static_cast<FinishInjectorInitTask*>(aContext); - MOZ_ASSERT(task); - task->PostToMainThread(); - return 0; -} - -void -PluginModuleChromeParent::OnCrash(DWORD processID) -{ - if (!mShutdown) { - GetIPCChannel()->CloseWithError(); - mozilla::ipc::ScopedProcessHandle geckoPluginChild; - if (base::OpenProcessHandle(OtherPid(), &geckoPluginChild.rwget())) { - if (!base::KillProcess(geckoPluginChild, - base::PROCESS_END_KILLED_BY_USER, false)) { - NS_ERROR("May have failed to kill child process."); - } - } else { - NS_ERROR("Failed to open child process when attempting kill."); - } - } -} - -#endif // MOZ_CRASHREPORTER_INJECTOR - #ifdef MOZ_ENABLE_PROFILER_SPS class PluginProfilerObserver final : public nsIObserver, public nsSupportsWeakReference diff --git a/dom/plugins/ipc/PluginModuleParent.h b/dom/plugins/ipc/PluginModuleParent.h index cc24d6ed2..946d4c236 100644 --- a/dom/plugins/ipc/PluginModuleParent.h +++ b/dom/plugins/ipc/PluginModuleParent.h @@ -26,10 +26,6 @@ #include "nsWindowsHelpers.h" #endif -#ifdef MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" -#endif - class nsIProfileSaveEvent; class nsPluginTag; @@ -56,9 +52,6 @@ class PluginInstanceParent; #ifdef XP_WIN class PluginHangUIParent; #endif -#ifdef MOZ_CRASHREPORTER_INJECTOR -class FinishInjectorInitTask; -#endif /** * PluginModuleParent @@ -80,9 +73,6 @@ class FinishInjectorInitTask; class PluginModuleParent : public PPluginModuleParent , public PluginLibrary -#ifdef MOZ_CRASHREPORTER_INJECTOR - , public CrashReporter::InjectorCrashCallback -#endif { protected: typedef mozilla::PluginLibrary PluginLibrary; @@ -395,10 +385,6 @@ class PluginModuleContentParent : public PluginModuleParent virtual bool ShouldContinueFromReplyTimeout() override; virtual void OnExitedSyncSend() override; -#ifdef MOZ_CRASHREPORTER_INJECTOR - void OnCrash(DWORD processID) override {} -#endif - static PluginModuleContentParent* sSavedModuleParent; uint32_t mPluginId; @@ -522,11 +508,6 @@ private: virtual bool ShouldContinueFromReplyTimeout() override; -#ifdef MOZ_CRASHREPORTER - void ProcessFirstMinidump(); - void WriteExtraDataForMinidump(CrashReporter::AnnotationTable& notes); -#endif - virtual PCrashReporterParent* AllocPCrashReporterParent(mozilla::dom::NativeThreadId* id, uint32_t* processType) override; @@ -594,17 +575,6 @@ private: PluginHangUIParent *mHangUIParent; bool mHangUIEnabled; bool mIsTimerReset; -#ifdef MOZ_CRASHREPORTER - /** - * This mutex protects the crash reporter when the Plugin Hang UI event - * handler is executing off main thread. It is intended to protect both - * the mCrashReporter variable in addition to the CrashReporterParent object - * that mCrashReporter refers to. - */ - mozilla::Mutex mCrashReporterMutex; - CrashReporterParent* mCrashReporter; -#endif // MOZ_CRASHREPORTER - /** * Launches the Plugin Hang UI. @@ -626,20 +596,6 @@ private: friend class mozilla::dom::CrashReporterParent; friend class mozilla::plugins::PluginAsyncSurrogate; -#ifdef MOZ_CRASHREPORTER_INJECTOR - friend class mozilla::plugins::FinishInjectorInitTask; - - void InitializeInjector(); - void DoInjection(const nsAutoHandle& aSnapshot); - static DWORD WINAPI GetToolhelpSnapshot(LPVOID aContext); - - void OnCrash(DWORD processID) override; - - DWORD mFlashProcess1; - DWORD mFlashProcess2; - RefPtr<mozilla::plugins::FinishInjectorInitTask> mFinishInitTask; -#endif - void OnProcessLaunched(const bool aSucceeded); class LaunchedTask : public LaunchCompleteTask diff --git a/dom/plugins/test/mochitest/test_crash_notify_no_report.xul b/dom/plugins/test/mochitest/test_crash_notify_no_report.xul index a1344bf0f..ac2b878fb 100644 --- a/dom/plugins/test/mochitest/test_crash_notify_no_report.xul +++ b/dom/plugins/test/mochitest/test_crash_notify_no_report.xul @@ -83,21 +83,10 @@ function onPluginCrashed(aEvent) { getService(Components.interfaces.nsIObserverService); os.removeObserver(testObserver, "plugin-crashed"); - // re-set MOZ_CRASHREPORTER_NO_REPORT - let env = Components.classes["@mozilla.org/process/environment;1"] - .getService(Components.interfaces.nsIEnvironment); - env.set("MOZ_CRASHREPORTER_NO_REPORT", "1"); SimpleTest.finish(); } function runTests() { - // the test harness will have set MOZ_CRASHREPORTER_NO_REPORT, - // ensure that we can change the setting and have our minidumps - // wind up in Crash Reports/pending - let env = Components.classes["@mozilla.org/process/environment;1"] - .getService(Components.interfaces.nsIEnvironment); - env.set("MOZ_CRASHREPORTER_NO_REPORT", ""); - var os = Components.classes["@mozilla.org/observer-service;1"]. getService(Components.interfaces.nsIObserverService); os.addObserver(testObserver, "plugin-crashed", true); diff --git a/dom/plugins/test/mochitest/test_crash_submit.xul b/dom/plugins/test/mochitest/test_crash_submit.xul index 22f39384b..53b42b25c 100644 --- a/dom/plugins/test/mochitest/test_crash_submit.xul +++ b/dom/plugins/test/mochitest/test_crash_submit.xul @@ -70,11 +70,6 @@ var testObserver = { getService(Components.interfaces.nsIObserverService); os.removeObserver(testObserver, "crash-report-status"); - // Then re-set MOZ_CRASHREPORTER_NO_REPORT - let env = Components.classes["@mozilla.org/process/environment;1"] - .getService(Components.interfaces.nsIEnvironment); - env.set("MOZ_CRASHREPORTER_NO_REPORT", "1"); - // Finally re-set crashreporter URL crashReporter.serverURL = oldServerURL; @@ -123,13 +118,6 @@ function onPluginCrashed(aEvent) { } function runTests() { - // the test harness will have set MOZ_CRASHREPORTER_NO_REPORT, - // ensure that we can change the setting and have our minidumps - // wind up in Crash Reports/pending - let env = Components.classes["@mozilla.org/process/environment;1"] - .getService(Components.interfaces.nsIEnvironment); - env.set("MOZ_CRASHREPORTER_NO_REPORT", ""); - // Override the crash reporter URL to send to our fake server crashReporter.serverURL = NetUtil.newURI(SERVER_URL); diff --git a/dom/plugins/test/mochitest/test_hang_submit.xul b/dom/plugins/test/mochitest/test_hang_submit.xul index 6c037ecd4..52ed78c6b 100644 --- a/dom/plugins/test/mochitest/test_hang_submit.xul +++ b/dom/plugins/test/mochitest/test_hang_submit.xul @@ -78,10 +78,6 @@ var testObserver = { // Next unregister our observer Services.obs.removeObserver(testObserver, "crash-report-status"); - // Then re-set MOZ_CRASHREPORTER_NO_REPORT - let env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment); - env.set("MOZ_CRASHREPORTER_NO_REPORT", "1"); - // Finally re-set prefs crashReporter.serverURL = oldServerURL; Services.prefs.setIntPref("dom.ipc.plugins.timeoutSecs", oldTimeoutPref); @@ -133,13 +129,6 @@ function runTests() { // Default plugin hang timeout is too high for mochitests Services.prefs.setIntPref("dom.ipc.plugins.timeoutSecs", 1); - // the test harness will have set MOZ_CRASHREPORTER_NO_REPORT, - // ensure that we can change the setting and have our minidumps - // wind up in Crash Reports/pending - let env = Cc["@mozilla.org/process/environment;1"] - .getService(Ci.nsIEnvironment); - env.set("MOZ_CRASHREPORTER_NO_REPORT", ""); - // Override the crash reporter URL to send to our fake server crashReporter.serverURL = NetUtil.newURI(SERVER_URL); diff --git a/dom/promise/Promise.cpp b/dom/promise/Promise.cpp index bf1fa5f50..00b78143e 100644 --- a/dom/promise/Promise.cpp +++ b/dom/promise/Promise.cpp @@ -38,9 +38,6 @@ #include "WorkerRunnable.h" #include "WrapperFactory.h" #include "xpcpublic.h" -#ifdef MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" -#endif namespace mozilla { namespace dom { diff --git a/dom/security/test/csp/file_child-src_worker-redirect.html b/dom/security/test/csp/file_child-src_worker-redirect.html index 188f173b8..b0029935c 100644 --- a/dom/security/test/csp/file_child-src_worker-redirect.html +++ b/dom/security/test/csp/file_child-src_worker-redirect.html @@ -23,11 +23,8 @@ ); worker.onerror = function(error) { - var msg = error.message; - if (msg.match(/^NetworkError/) || msg.match(/Failed to load worker script/)) { - // this means CSP blocked it - msg = "blocked"; - } + // this means CSP blocked it + var msg = !("message" in error) ? "blocked" : e.message; window.parent.postMessage({id:page_id, message:msg}, 'http://mochi.test:8888'); error.preventDefault(); }; diff --git a/dom/security/test/general/test_block_script_wrong_mime.html b/dom/security/test/general/test_block_script_wrong_mime.html index f4da9c577..34d4b621b 100644 --- a/dom/security/test/general/test_block_script_wrong_mime.html +++ b/dom/security/test/general/test_block_script_wrong_mime.html @@ -53,9 +53,6 @@ function testWorker([mime, shouldLoad]) { }; worker.onerror = (error) => { ok(!shouldLoad, `worker with wrong mime '${mime}' should be blocked`); - let msg = error.message; - ok(msg.match(/^NetworkError/) || msg.match(/Failed to load worker script/), - "should gets correct error message"); error.preventDefault(); resolve(); } @@ -74,9 +71,6 @@ function testWorkerImportScripts([mime, shouldLoad]) { }; worker.onerror = (error) => { ok(!shouldLoad, `worker/importScripts with wrong mime '${mime}' should be blocked`); - let msg = error.message; - ok(msg.match(/^NetworkError/) || msg.match(/Failed to load worker script/), - "should gets correct error message"); error.preventDefault(); resolve(); } diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index c2ab4aca3..bd8a33032 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -495,6 +495,82 @@ private: } }; +class ReportCompileErrorRunnable final : public WorkerRunnable +{ +public: + static void + CreateAndDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate) + { + MOZ_ASSERT(aWorkerPrivate); + aWorkerPrivate->AssertIsOnWorkerThread(); + + RefPtr<ReportCompileErrorRunnable> runnable = + new ReportCompileErrorRunnable(aCx, aWorkerPrivate); + runnable->Dispatch(); + } + +private: + ReportCompileErrorRunnable(JSContext* aCx, WorkerPrivate* aWorkerPrivate) + : WorkerRunnable(aWorkerPrivate, ParentThreadUnchangedBusyCount) + { + aWorkerPrivate->AssertIsOnWorkerThread(); + } + + void + PostDispatch(WorkerPrivate* aWorkerPrivate, bool aDispatchResult) override + { + aWorkerPrivate->AssertIsOnWorkerThread(); + + // Dispatch may fail if the worker was canceled, no need to report that as + // an error, so don't call base class PostDispatch. + } + + bool + WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override + { + if (aWorkerPrivate->IsFrozen() || + aWorkerPrivate->IsParentWindowPaused()) { + MOZ_ASSERT(!IsDebuggerRunnable()); + aWorkerPrivate->QueueRunnable(this); + return true; + } + + if (aWorkerPrivate->IsSharedWorker()) { + aWorkerPrivate->BroadcastErrorToSharedWorkers(aCx, EmptyString(), + EmptyString(), + EmptyString(), 0, 0, + JSREPORT_ERROR, + /* isErrorEvent */ false); + return true; + } + + if (aWorkerPrivate->IsServiceWorker()) { + RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance(); + if (swm) { + swm->HandleError(aCx, aWorkerPrivate->GetPrincipal(), + aWorkerPrivate->WorkerName(), + aWorkerPrivate->ScriptURL(), + EmptyString(), EmptyString(), EmptyString(), + 0, 0, JSREPORT_ERROR, JSEXN_ERR); + } + return true; + } + + if (!aWorkerPrivate->IsAcceptingEvents()) { + return true; + } + + RefPtr<Event> event = + Event::Constructor(aWorkerPrivate, NS_LITERAL_STRING("error"), + EventInit()); + event->SetTrusted(true); + + nsEventStatus status = nsEventStatus_eIgnore; + aWorkerPrivate->DispatchDOMEvent(nullptr, event, nullptr, &status); + return true; + } +}; + class CompileScriptRunnable final : public WorkerRunnable { nsString mScriptURL; @@ -538,9 +614,15 @@ private: } // Make sure to propagate exceptions from rv onto aCx, so that they will get - // reported after we return. We do this for all failures on rv, because now - // we're using rv to track all the state we care about. - // + // reported after we return. We want to propagate just JS exceptions, + // because all the other errors are handled when the script is loaded. + // See: https://dom.spec.whatwg.org/#concept-event-fire + if (rv.Failed() && !rv.IsJSException()) { + ReportCompileErrorRunnable::CreateAndDispatch(aCx, aWorkerPrivate); + rv.SuppressException(); + return false; + } + // This is a little dumb, but aCx is in the null compartment here because we // set it up that way in our Run(), since we had not created the global at // that point yet. So we need to enter the compartment of our global, @@ -1171,7 +1253,8 @@ private: if (aWorkerPrivate->IsSharedWorker()) { aWorkerPrivate->BroadcastErrorToSharedWorkers(aCx, mMessage, mFilename, mLine, mLineNumber, - mColumnNumber, mFlags); + mColumnNumber, mFlags, + /* isErrorEvent */ true); return true; } @@ -3250,7 +3333,8 @@ WorkerPrivateParent<Derived>::BroadcastErrorToSharedWorkers( const nsAString& aLine, uint32_t aLineNumber, uint32_t aColumnNumber, - uint32_t aFlags) + uint32_t aFlags, + bool aIsErrorEvent) { AssertIsOnMainThread(); @@ -3281,31 +3365,42 @@ WorkerPrivateParent<Derived>::BroadcastErrorToSharedWorkers( // May be null. nsPIDOMWindowInner* window = sharedWorker->GetOwner(); - RootedDictionary<ErrorEventInit> errorInit(aCx); - errorInit.mBubbles = false; - errorInit.mCancelable = true; - errorInit.mMessage = aMessage; - errorInit.mFilename = aFilename; - errorInit.mLineno = aLineNumber; - errorInit.mColno = aColumnNumber; - - RefPtr<ErrorEvent> errorEvent = - ErrorEvent::Constructor(sharedWorker, NS_LITERAL_STRING("error"), - errorInit); - if (!errorEvent) { + RefPtr<Event> event; + + if (aIsErrorEvent) { + RootedDictionary<ErrorEventInit> errorInit(aCx); + errorInit.mBubbles = false; + errorInit.mCancelable = true; + errorInit.mMessage = aMessage; + errorInit.mFilename = aFilename; + errorInit.mLineno = aLineNumber; + errorInit.mColno = aColumnNumber; + + event = ErrorEvent::Constructor(sharedWorker, NS_LITERAL_STRING("error"), + errorInit); + } else { + event = Event::Constructor(sharedWorker, NS_LITERAL_STRING("error"), + EventInit()); + } + + if (!event) { ThrowAndReport(window, NS_ERROR_UNEXPECTED); continue; } - errorEvent->SetTrusted(true); + event->SetTrusted(true); bool defaultActionEnabled; - nsresult rv = sharedWorker->DispatchEvent(errorEvent, &defaultActionEnabled); + nsresult rv = sharedWorker->DispatchEvent(event, &defaultActionEnabled); if (NS_FAILED(rv)) { ThrowAndReport(window, rv); continue; } + if (!aIsErrorEvent) { + continue; + } + if (defaultActionEnabled) { // Add the owning window to our list so that we will fire an error event // at it later. diff --git a/dom/workers/WorkerPrivate.h b/dom/workers/WorkerPrivate.h index 8008f30e5..465c0f9a3 100644 --- a/dom/workers/WorkerPrivate.h +++ b/dom/workers/WorkerPrivate.h @@ -408,7 +408,8 @@ public: const nsAString& aLine, uint32_t aLineNumber, uint32_t aColumnNumber, - uint32_t aFlags); + uint32_t aFlags, + bool aIsErrorEvent); void WorkerScriptLoaded(); diff --git a/dom/workers/test/test_404.html b/dom/workers/test/test_404.html index e2e83a35e..15e5ded68 100644 --- a/dom/workers/test/test_404.html +++ b/dom/workers/test/test_404.html @@ -25,7 +25,6 @@ Tests of DOM Worker Threads worker.onerror = function(event) { is(event.target, worker); - is(event.message, 'NetworkError: Failed to load worker script at "nonexistent_worker.js"'); event.preventDefault(); SimpleTest.finish(); }; diff --git a/dom/workers/test/test_bug1036484.html b/dom/workers/test/test_bug1036484.html index 17b9d490f..49c31bbc9 100644 --- a/dom/workers/test/test_bug1036484.html +++ b/dom/workers/test/test_bug1036484.html @@ -25,7 +25,6 @@ function test(script) { worker.onerror = function(event) { is(event.target, worker); - ok(event.message.startsWith("NetworkError: Failed to load worker script")) event.preventDefault(); runTests(); }; diff --git a/dom/workers/test/test_loadError.html b/dom/workers/test/test_loadError.html index dc109b796..b9a215d11 100644 --- a/dom/workers/test/test_loadError.html +++ b/dom/workers/test/test_loadError.html @@ -13,15 +13,13 @@ <script class="testbody" type="text/javascript"> "use strict"; -var loadErrorMessage = 'SecurityError: Failed to load worker script at "about:blank"'; - function nextTest() { (function(){ function workerfunc() { var subworker = new Worker("about:blank"); subworker.onerror = function(e) { e.preventDefault(); - postMessage(e.message); + postMessage("ERROR"); } } var b = new Blob([workerfunc+'workerfunc();']); @@ -37,7 +35,7 @@ function nextTest() { return; } w.onmessage = function(e) { - is(e.data, loadErrorMessage, + is(e.data, "ERROR", "Should catch the error when loading inner script"); if (++i < 2) callworker(i); else SimpleTest.finish(); @@ -54,8 +52,6 @@ try { var worker = new Worker("about:blank"); worker.onerror = function(e) { e.preventDefault(); - is(e.message, loadErrorMessage, - "Should get the right error from the toplevel script"); nextTest(); } diff --git a/dom/xhr/XMLHttpRequestWorker.cpp b/dom/xhr/XMLHttpRequestWorker.cpp index f61383baf..93b93a2b1 100644 --- a/dom/xhr/XMLHttpRequestWorker.cpp +++ b/dom/xhr/XMLHttpRequestWorker.cpp @@ -1148,8 +1148,8 @@ EventRunnable::PreDispatch(WorkerPrivate* /* unused */) } else { bool doClone = true; JS::Rooted<JS::Value> transferable(cx); - JS::Rooted<JSObject*> obj(cx, response.isObjectOrNull() ? - response.toObjectOrNull() : nullptr); + JS::Rooted<JSObject*> obj(cx, response.isObject() ? + &response.toObject() : nullptr); if (obj && JS_IsArrayBufferObject(obj)) { // Use cached response if the arraybuffer has been transfered. if (mProxy->mArrayBufferResponseWasTransferred) { diff --git a/gfx/gl/GfxTexturesReporter.cpp b/gfx/gl/GfxTexturesReporter.cpp index 8007fe6b1..d2ca70d27 100644 --- a/gfx/gl/GfxTexturesReporter.cpp +++ b/gfx/gl/GfxTexturesReporter.cpp @@ -9,10 +9,6 @@ #include "GfxTexturesReporter.h" #include "gfxPrefs.h" -#ifdef MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" -#endif - using namespace mozilla; using namespace mozilla::gl; @@ -75,8 +71,4 @@ GfxTexturesReporter::UpdateAmount(MemoryUse action, size_t amount) } } } - -#ifdef MOZ_CRASHREPORTER - CrashReporter::AnnotateTexturesSize(sAmount); -#endif } diff --git a/gfx/ipc/GPUChild.cpp b/gfx/ipc/GPUChild.cpp index 72328ac0b..3c2797683 100644 --- a/gfx/ipc/GPUChild.cpp +++ b/gfx/ipc/GPUChild.cpp @@ -121,9 +121,6 @@ GPUChild::RecvGraphicsError(const nsCString& aError) bool GPUChild::RecvInitCrashReporter(Shmem&& aShmem) { -#ifdef MOZ_CRASHREPORTER - mCrashReporter = MakeUnique<ipc::CrashReporterHost>(GeckoProcessType_GPU, aShmem); -#endif return true; } @@ -163,12 +160,6 @@ void GPUChild::ActorDestroy(ActorDestroyReason aWhy) { if (aWhy == AbnormalShutdown) { -#ifdef MOZ_CRASHREPORTER - if (mCrashReporter) { - mCrashReporter->GenerateCrashReport(OtherPid()); - mCrashReporter = nullptr; - } -#endif Telemetry::Accumulate(Telemetry::SUBPROCESS_ABNORMAL_ABORT, nsDependentCString(XRE_ChildProcessTypeToString(GeckoProcessType_GPU), 1)); } diff --git a/gfx/ipc/GPUParent.cpp b/gfx/ipc/GPUParent.cpp index d63e17e2f..896c7b36b 100644 --- a/gfx/ipc/GPUParent.cpp +++ b/gfx/ipc/GPUParent.cpp @@ -82,11 +82,6 @@ GPUParent::Init(base::ProcessId aParentPid, nsDebugImpl::SetMultiprocessMode("GPU"); -#ifdef MOZ_CRASHREPORTER - // Init crash reporter support. - CrashReporterClient::InitSingleton(this); -#endif - // Ensure gfxPrefs are initialized. gfxPrefs::GetSingleton(); gfxConfig::Init(); @@ -380,9 +375,6 @@ GPUParent::ActorDestroy(ActorDestroyReason aWhy) gfxVars::Shutdown(); gfxConfig::Shutdown(); gfxPrefs::DestroySingleton(); -#ifdef MOZ_CRASHREPORTER - CrashReporterClient::DestroySingleton(); -#endif XRE_ShutdownChildProcess(); } diff --git a/gfx/src/DriverCrashGuard.cpp b/gfx/src/DriverCrashGuard.cpp index 36d08dcf3..4754c26ad 100644 --- a/gfx/src/DriverCrashGuard.cpp +++ b/gfx/src/DriverCrashGuard.cpp @@ -7,9 +7,6 @@ #include "gfxPrefs.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsDirectoryServiceUtils.h"
-#ifdef MOZ_CRASHREPORTER
-#include "nsExceptionHandler.h"
-#endif
#include "nsServiceManagerUtils.h"
#include "nsString.h"
#include "nsXULAppAPI.h"
@@ -164,12 +161,6 @@ DriverCrashGuard::~DriverCrashGuard() } else {
dom::ContentChild::GetSingleton()->SendEndDriverCrashGuard(uint32_t(mType));
}
-
-#ifdef MOZ_CRASHREPORTER
- // Remove the crash report annotation.
- CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("GraphicsStartupTest"),
- NS_LITERAL_CSTRING(""));
-#endif
}
bool
@@ -208,16 +199,6 @@ DriverCrashGuard::ActivateGuard() {
mGuardActivated = true;
-#ifdef MOZ_CRASHREPORTER
- // Anotate crash reports only if we're a real guard. Otherwise, we could
- // attribute a random parent process crash to a graphics problem in a child
- // process.
- if (mMode != Mode::Proxy) {
- CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("GraphicsStartupTest"),
- NS_LITERAL_CSTRING("1"));
- }
-#endif
-
// If we're in the content process, the rest of the guarding is handled
// in the parent.
if (XRE_IsContentProcess()) {
diff --git a/gfx/src/gfxCrashReporterUtils.cpp b/gfx/src/gfxCrashReporterUtils.cpp index 42647ccc6..757c15527 100644 --- a/gfx/src/gfxCrashReporterUtils.cpp +++ b/gfx/src/gfxCrashReporterUtils.cpp @@ -5,10 +5,6 @@ #include "gfxCrashReporterUtils.h" -#if defined(MOZ_CRASHREPORTER) -#define MOZ_GFXFEATUREREPORTER 1 -#endif - #ifdef MOZ_GFXFEATUREREPORTER #include "gfxCrashReporterUtils.h" #include <string.h> // for strcmp diff --git a/gfx/tests/gtest/TestGfxPrefs.cpp b/gfx/tests/gtest/TestGfxPrefs.cpp index 72b698ed6..4e3b6037e 100644 --- a/gfx/tests/gtest/TestGfxPrefs.cpp +++ b/gfx/tests/gtest/TestGfxPrefs.cpp @@ -80,27 +80,3 @@ TEST(GfxPrefs, Set) { ASSERT_TRUE(gfxPrefs::APZMaxVelocity() == -1.0f); } -#ifdef MOZ_CRASHREPORTER -// Randomly test the function we use in nsExceptionHandler.cpp here: -extern bool SimpleNoCLibDtoA(double aValue, char* aBuffer, int aBufferLength); -TEST(GfxPrefs, StringUtility) -{ - char testBuffer[64]; - double testVal[] = {13.4, - 3324243.42, - 0.332424342, - 864.0, - 86400 * 100000000.0 * 10000000000.0 * 10000000000.0 * 100.0, - 86400.0 * 366.0 * 100.0 + 14243.44332}; - for (size_t i=0; i<mozilla::ArrayLength(testVal); i++) { - ASSERT_TRUE(SimpleNoCLibDtoA(testVal[i], testBuffer, sizeof(testBuffer))); - ASSERT_TRUE(fabs(1.0 - atof(testBuffer)/testVal[i]) < 0.0001); - } - - // We do not like negative numbers (random limitation) - ASSERT_FALSE(SimpleNoCLibDtoA(-864.0, testBuffer, sizeof(testBuffer))); - - // It won't fit into 32: - ASSERT_FALSE(SimpleNoCLibDtoA(testVal[4], testBuffer, sizeof(testBuffer)/2)); -} -#endif diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp index 2e4ec990f..a468592fe 100644 --- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -71,9 +71,6 @@ #include "nsIScreenManager.h" #include "FrameMetrics.h" #include "MainThreadUtils.h" -#ifdef MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" -#endif #include "nsWeakReference.h" @@ -293,12 +290,7 @@ void CrashStatsLogForwarder::UpdateCrashReport() message << logAnnotation << Get<0>(*it) << "]" << Get<1>(*it) << " (t=" << Get<2>(*it) << ") "; } -#ifdef MOZ_CRASHREPORTER - nsCString reportString(message.str().c_str()); - nsresult annotated = CrashReporter::AnnotateCrashReport(mCrashCriticalKey, reportString); -#else nsresult annotated = NS_ERROR_NOT_IMPLEMENTED; -#endif if (annotated != NS_OK) { printf("Crash Annotation %s: %s", mCrashCriticalKey.get(), message.str().c_str()); diff --git a/ipc/glue/CrashReporterHost.cpp b/ipc/glue/CrashReporterHost.cpp index 76052ae66..85552cba5 100644 --- a/ipc/glue/CrashReporterHost.cpp +++ b/ipc/glue/CrashReporterHost.cpp @@ -9,9 +9,6 @@ #include "mozilla/Sprintf.h" #include "mozilla/SyncRunnable.h" #include "mozilla/Telemetry.h" -#ifdef MOZ_CRASHREPORTER -# include "nsICrashService.h" -#endif namespace mozilla { namespace ipc { @@ -24,105 +21,5 @@ CrashReporterHost::CrashReporterHost(GeckoProcessType aProcessType, { } -#ifdef MOZ_CRASHREPORTER -void -CrashReporterHost::GenerateCrashReport(RefPtr<nsIFile> aCrashDump) -{ - nsString dumpID; - if (!CrashReporter::GetIDFromMinidump(aCrashDump, dumpID)) { - return; - } - - CrashReporter::AnnotationTable notes; - - nsAutoCString type; - switch (mProcessType) { - case GeckoProcessType_Content: - type = NS_LITERAL_CSTRING("content"); - break; - case GeckoProcessType_Plugin: - case GeckoProcessType_GMPlugin: - type = NS_LITERAL_CSTRING("plugin"); - break; - case GeckoProcessType_GPU: - type = NS_LITERAL_CSTRING("gpu"); - break; - default: - NS_ERROR("unknown process type"); - break; - } - notes.Put(NS_LITERAL_CSTRING("ProcessType"), type); - - char startTime[32]; - SprintfLiteral(startTime, "%lld", static_cast<long long>(mStartTime)); - notes.Put(NS_LITERAL_CSTRING("StartupTime"), nsDependentCString(startTime)); - - CrashReporterMetadataShmem::ReadAppNotes(mShmem, ¬es); - - CrashReporter::AppendExtraData(dumpID, notes); - NotifyCrashService(mProcessType, dumpID, ¬es); -} - -/* static */ void -CrashReporterHost::NotifyCrashService(GeckoProcessType aProcessType, - const nsString& aChildDumpID, - const AnnotationTable* aNotes) -{ - if (!NS_IsMainThread()) { - RefPtr<Runnable> runnable = NS_NewRunnableFunction([=] () -> void { - CrashReporterHost::NotifyCrashService(aProcessType, aChildDumpID, aNotes); - }); - RefPtr<nsIThread> mainThread = do_GetMainThread(); - SyncRunnable::DispatchToThread(mainThread, runnable); - return; - } - - MOZ_ASSERT(!aChildDumpID.IsEmpty()); - - nsCOMPtr<nsICrashService> crashService = - do_GetService("@mozilla.org/crashservice;1"); - if (!crashService) { - return; - } - - int32_t processType; - int32_t crashType = nsICrashService::CRASH_TYPE_CRASH; - - nsCString telemetryKey; - - switch (aProcessType) { - case GeckoProcessType_Content: - processType = nsICrashService::PROCESS_TYPE_CONTENT; - telemetryKey.AssignLiteral("content"); - break; - case GeckoProcessType_Plugin: { - processType = nsICrashService::PROCESS_TYPE_PLUGIN; - telemetryKey.AssignLiteral("plugin"); - nsAutoCString val; - if (aNotes->Get(NS_LITERAL_CSTRING("PluginHang"), &val) && - val.Equals(NS_LITERAL_CSTRING("1"))) { - crashType = nsICrashService::CRASH_TYPE_HANG; - telemetryKey.AssignLiteral("pluginhang"); - } - break; - } - case GeckoProcessType_GMPlugin: - processType = nsICrashService::PROCESS_TYPE_GMPLUGIN; - telemetryKey.AssignLiteral("gmplugin"); - break; - case GeckoProcessType_GPU: - processType = nsICrashService::PROCESS_TYPE_GPU; - telemetryKey.AssignLiteral("gpu"); - break; - default: - NS_ERROR("unknown process type"); - return; - } - - crashService->AddCrash(processType, crashType, aChildDumpID); - Telemetry::Accumulate(Telemetry::SUBPROCESS_CRASHES_WITH_DUMP, telemetryKey, 1); -} -#endif - } // namespace ipc } // namespace mozilla diff --git a/ipc/glue/CrashReporterHost.h b/ipc/glue/CrashReporterHost.h index 36c5923c2..1089781c5 100644 --- a/ipc/glue/CrashReporterHost.h +++ b/ipc/glue/CrashReporterHost.h @@ -28,26 +28,6 @@ class CrashReporterHost public: CrashReporterHost(GeckoProcessType aProcessType, const Shmem& aShmem); -#ifdef MOZ_CRASHREPORTER - void GenerateCrashReport(base::ProcessId aPid) { - RefPtr<nsIFile> crashDump; - if (!XRE_TakeMinidumpForChild(aPid, getter_AddRefs(crashDump), nullptr)) { - return; - } - GenerateCrashReport(crashDump); - } - - // This is a static helper function to notify the crash service that a - // crash has occurred. When PCrashReporter is removed, we can make this - // a member function. This can be called from any thread, and if not - // called from the main thread, will post a synchronous message to the - // main thread. - static void NotifyCrashService( - GeckoProcessType aProcessType, - const nsString& aChildDumpID, - const AnnotationTable* aNotes); -#endif - private: void GenerateCrashReport(RefPtr<nsIFile> aCrashDump); diff --git a/ipc/glue/CrashReporterMetadataShmem.cpp b/ipc/glue/CrashReporterMetadataShmem.cpp index f579d5bb0..5b889948b 100644 --- a/ipc/glue/CrashReporterMetadataShmem.cpp +++ b/ipc/glue/CrashReporterMetadataShmem.cpp @@ -208,28 +208,5 @@ private: EntryType mEntryType; }; -#ifdef MOZ_CRASHREPORTER -void -CrashReporterMetadataShmem::ReadAppNotes(const Shmem& aShmem, CrashReporter::AnnotationTable* aNotes) -{ - for (MetadataShmemReader reader(aShmem); !reader.Done(); reader.Next()) { - switch (reader.Type()) { - case EntryType::Annotation: { - nsCString key, value; - if (!reader.Read(key) || !reader.Read(value)) { - return; - } - - aNotes->Put(key, value); - break; - } - default: - NS_ASSERTION(false, "Unknown metadata entry type"); - break; - } - } -} -#endif - } // namespace ipc } // namespace mozilla diff --git a/ipc/glue/CrashReporterMetadataShmem.h b/ipc/glue/CrashReporterMetadataShmem.h index d2d8670a2..ad67c6d75 100644 --- a/ipc/glue/CrashReporterMetadataShmem.h +++ b/ipc/glue/CrashReporterMetadataShmem.h @@ -28,10 +28,6 @@ public: void AnnotateCrashReport(const nsCString& aKey, const nsCString& aData); void AppendAppNotes(const nsCString& aData); -#ifdef MOZ_CRASHREPORTER - static void ReadAppNotes(const Shmem& aShmem, CrashReporter::AnnotationTable* aNotes); -#endif - private: void SyncNotesToShmem(); diff --git a/ipc/glue/GeckoChildProcessHost.cpp b/ipc/glue/GeckoChildProcessHost.cpp index 48051472a..db8ab3d0a 100644 --- a/ipc/glue/GeckoChildProcessHost.cpp +++ b/ipc/glue/GeckoChildProcessHost.cpp @@ -307,12 +307,6 @@ GeckoChildProcessHost::GetUniqueID() void GeckoChildProcessHost::PrepareLaunch() { -#ifdef MOZ_CRASHREPORTER - if (CrashReporter::GetEnabled()) { - CrashReporter::OOPInit(); - } -#endif - #ifdef XP_WIN if (mProcessType == GeckoProcessType_Plugin) { InitWindowsGroupID(); @@ -902,26 +896,6 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt childArgv.push_back(pidstring); -#if defined(MOZ_CRASHREPORTER) -# if defined(OS_LINUX) || defined(OS_BSD) - int childCrashFd, childCrashRemapFd; - if (!CrashReporter::CreateNotificationPipeForChild( - &childCrashFd, &childCrashRemapFd)) - return false; - if (0 <= childCrashFd) { - mFileMap.push_back(std::pair<int,int>(childCrashFd, childCrashRemapFd)); - // "true" == crash reporting enabled - childArgv.push_back("true"); - } - else { - // "false" == crash reporting disabled - childArgv.push_back("false"); - } -# elif defined(MOZ_WIDGET_COCOA) - childArgv.push_back(CrashReporter::GetChildNotificationPipe()); -# endif // OS_LINUX -#endif - #ifdef MOZ_WIDGET_COCOA // Add a mach port to the command line so the child can communicate its // 'task_t' back to the parent. @@ -1139,11 +1113,6 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt // Process id cmdLine.AppendLooseValue(UTF8ToWide(pidstring)); -#if defined(MOZ_CRASHREPORTER) - cmdLine.AppendLooseValue( - UTF8ToWide(CrashReporter::GetChildNotificationPipe())); -#endif - // Process type cmdLine.AppendLooseValue(UTF8ToWide(childProcessType)); diff --git a/ipc/glue/IPCMessageUtils.h b/ipc/glue/IPCMessageUtils.h index 094aa978a..15834a854 100644 --- a/ipc/glue/IPCMessageUtils.h +++ b/ipc/glue/IPCMessageUtils.h @@ -25,9 +25,6 @@ #include <stdint.h> -#ifdef MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" -#endif #include "nsID.h" #include "nsIWidget.h" #include "nsMemory.h" @@ -127,16 +124,8 @@ struct EnumSerializer { static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) { uintParamType value; if (!ReadParam(aMsg, aIter, &value)) { -#ifdef MOZ_CRASHREPORTER - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCReadErrorReason"), - NS_LITERAL_CSTRING("Bad iter")); -#endif return false; } else if (!EnumValidator::IsLegalValue(paramType(value))) { -#ifdef MOZ_CRASHREPORTER - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCReadErrorReason"), - NS_LITERAL_CSTRING("Illegal value")); -#endif return false; } *aResult = paramType(value); diff --git a/ipc/glue/MessageChannel.h b/ipc/glue/MessageChannel.h index df70899df..4c9edf9dd 100644 --- a/ipc/glue/MessageChannel.h +++ b/ipc/glue/MessageChannel.h @@ -19,10 +19,6 @@ #include "mozilla/ipc/Neutering.h" #endif // defined(OS_WIN) #include "mozilla/ipc/Transport.h" -#if defined(MOZ_CRASHREPORTER) && defined(OS_WIN) -#include "mozilla/mozalloc_oom.h" -#include "nsExceptionHandler.h" -#endif #include "MessageLink.h" #include <deque> diff --git a/ipc/glue/MessageLink.cpp b/ipc/glue/MessageLink.cpp index 6a1bda02d..a66fbbb32 100644 --- a/ipc/glue/MessageLink.cpp +++ b/ipc/glue/MessageLink.cpp @@ -14,9 +14,6 @@ #include "mozilla/Assertions.h" #include "mozilla/DebugOnly.h" #include "nsDebug.h" -#ifdef MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" -#endif #include "nsISupportsImpl.h" #include "nsXULAppAPI.h" @@ -135,10 +132,6 @@ void ProcessLink::SendMessage(Message *msg) { if (msg->size() > IPC::Channel::kMaximumMessageSize) { -#ifdef MOZ_CRASHREPORTER - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCMessageName"), nsDependentCString(msg->name())); - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCMessageSize"), nsPrintfCString("%d", msg->size())); -#endif MOZ_CRASH("IPC message size is too large"); } diff --git a/ipc/glue/ProtocolUtils.cpp b/ipc/glue/ProtocolUtils.cpp index 1a022048f..4de131469 100644 --- a/ipc/glue/ProtocolUtils.cpp +++ b/ipc/glue/ProtocolUtils.cpp @@ -25,13 +25,6 @@ #include "mozilla/sandboxTarget.h" #endif -#if defined(MOZ_CRASHREPORTER) && defined(XP_WIN) -#include "aclapi.h" -#include "sddl.h" - -#include "mozilla/TypeTraits.h" -#endif - #include "nsAutoPtr.h" using namespace IPC; @@ -42,16 +35,6 @@ using base::ProcessId; namespace mozilla { -#if defined(MOZ_CRASHREPORTER) && defined(XP_WIN) -// Generate RAII classes for LPTSTR and PSECURITY_DESCRIPTOR. -MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedLPTStr, \ - RemovePointer<LPTSTR>::Type, \ - ::LocalFree) -MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPSecurityDescriptor, \ - RemovePointer<PSECURITY_DESCRIPTOR>::Type, \ - ::LocalFree) -#endif - namespace ipc { class ChannelOpened : public IPC::Message @@ -195,11 +178,6 @@ bool DuplicateHandle(HANDLE aSourceHandle, FALSE, aTargetProcessId)); if (!targetProcess) { -#ifdef MOZ_CRASHREPORTER - CrashReporter::AnnotateCrashReport( - NS_LITERAL_CSTRING("IPCTransportFailureReason"), - NS_LITERAL_CSTRING("Failed to open target process.")); -#endif return false; } @@ -209,34 +187,6 @@ bool DuplicateHandle(HANDLE aSourceHandle, } #endif -#ifdef MOZ_CRASHREPORTER -void -AnnotateSystemError() -{ - int64_t error = 0; -#if defined(XP_WIN) - error = ::GetLastError(); -#elif defined(OS_POSIX) - error = errno; -#endif - if (error) { - CrashReporter::AnnotateCrashReport( - NS_LITERAL_CSTRING("IPCSystemError"), - nsPrintfCString("%lld", error)); - } -} -#endif - -#if defined(MOZ_CRASHREPORTER) && defined(XP_MACOSX) -void -AnnotateCrashReportWithErrno(const char* tag, int error) -{ - CrashReporter::AnnotateCrashReport( - nsCString(tag), - nsPrintfCString("%d", error)); -} -#endif - void LogMessageForProtocol(const char* aTopLevelProtocol, base::ProcessId aOtherPid, const char* aContextDescription, @@ -274,18 +224,6 @@ FatalError(const char* aProtocolName, const char* aMsg, bool aIsParent) formattedMessage.AppendLiteral("]: \""); formattedMessage.AppendASCII(aMsg); if (aIsParent) { -#ifdef MOZ_CRASHREPORTER - // We're going to crash the parent process because at this time - // there's no other really nice way of getting a minidump out of - // this process if we're off the main thread. - formattedMessage.AppendLiteral("\". Intentionally crashing."); - NS_ERROR(formattedMessage.get()); - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCFatalErrorProtocol"), - nsDependentCString(aProtocolName)); - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCFatalErrorMsg"), - nsDependentCString(aMsg)); - AnnotateSystemError(); -#endif MOZ_CRASH("IPC FatalError in the parent process!"); } else { formattedMessage.AppendLiteral("\". abort()ing as a result."); @@ -540,12 +478,9 @@ IToplevelProtocol::SetOtherProcessId(base::ProcessId aOtherPid) bool IToplevelProtocol::TakeMinidump(nsIFile** aDump, uint32_t* aSequence) { + /*** STUB ***/ MOZ_RELEASE_ASSERT(GetSide() == ParentSide); -#ifdef MOZ_CRASHREPORTER - return XRE_TakeMinidumpForChild(OtherPid(), aDump, aSequence); -#else return false; -#endif } bool diff --git a/ipc/glue/ProtocolUtils.h b/ipc/glue/ProtocolUtils.h index 9184aae54..83860d93a 100644 --- a/ipc/glue/ProtocolUtils.h +++ b/ipc/glue/ProtocolUtils.h @@ -472,14 +472,10 @@ DuplicateHandle(HANDLE aSourceHandle, #endif /** - * Annotate the crash reporter with the error code from the most recent system - * call. Returns the system error. + * Hist: Annotated the crash reporter with the error code from the most + * recent system call. Returned the system error. */ -#ifdef MOZ_CRASHREPORTER -void AnnotateSystemError(); -#else #define AnnotateSystemError() do { } while (0) -#endif /** * An endpoint represents one end of a partially initialized IPDL channel. To @@ -599,12 +595,8 @@ private: ProtocolId mProtocolId; }; -#if defined(MOZ_CRASHREPORTER) && defined(XP_MACOSX) -void AnnotateCrashReportWithErrno(const char* tag, int error); -#else static inline void AnnotateCrashReportWithErrno(const char* tag, int error) {} -#endif // This function is used internally to create a pair of Endpoints. See the // comment above Endpoint for a description of how it might be used. diff --git a/ipc/ipdl/ipdl/lower.py b/ipc/ipdl/ipdl/lower.py index f810cccb0..61855a7a9 100644 --- a/ipc/ipdl/ipdl/lower.py +++ b/ipc/ipdl/ipdl/lower.py @@ -2610,13 +2610,6 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): '"'+ _protocolHeaderName(self.protocol, self.side) +'.h"') ] + setToIncludes(self.externalIncludes)) - if self.protocol.decl.type.isToplevel(): - cf.addthings([ - CppDirective('ifdef', 'MOZ_CRASHREPORTER'), - CppDirective(' include', '"nsXULAppAPI.h"'), - CppDirective('endif') - ]) - cppheaders = [CppDirective('include', '"%s"' % filename) for filename in ipdl.builtin.CppIncludes] diff --git a/js/public/CallArgs.h b/js/public/CallArgs.h index 6e6164e55..a7774309a 100644 --- a/js/public/CallArgs.h +++ b/js/public/CallArgs.h @@ -290,7 +290,7 @@ class MOZ_STACK_CLASS CallArgs : public detail::CallArgsBase<detail::IncludeUsed args.constructing_ = constructing; #ifdef DEBUG for (unsigned i = 0; i < argc; ++i) - MOZ_ASSERT_IF(argv[i].isMarkable(), !GCThingIsMarkedGray(GCCellPtr(argv[i]))); + MOZ_ASSERT_IF(argv[i].isGCThing(), !GCThingIsMarkedGray(GCCellPtr(argv[i]))); #endif return args; } diff --git a/js/public/Proxy.h b/js/public/Proxy.h index 3e95538db..5acb91b26 100644 --- a/js/public/Proxy.h +++ b/js/public/Proxy.h @@ -456,7 +456,7 @@ SetProxyExtra(JSObject* obj, size_t n, const Value& extra) Value* vp = &detail::GetProxyDataLayout(obj)->values->extraSlots[n]; // Trigger a barrier before writing the slot. - if (vp->isMarkable() || extra.isMarkable()) + if (vp->isGCThing() || extra.isGCThing()) SetValueInProxy(vp, extra); else *vp = extra; @@ -482,7 +482,7 @@ SetReservedOrProxyPrivateSlot(JSObject* obj, size_t slot, const Value& value) MOZ_ASSERT(slot == 0); MOZ_ASSERT(slot < JSCLASS_RESERVED_SLOTS(GetObjectClass(obj)) || IsProxy(obj)); shadow::Object* sobj = reinterpret_cast<shadow::Object*>(obj); - if (sobj->slotRef(slot).isMarkable() || value.isMarkable()) + if (sobj->slotRef(slot).isGCThing() || value.isGCThing()) SetReservedOrProxyPrivateSlotWithBarrier(obj, slot, value); else sobj->slotRef(slot) = value; diff --git a/js/public/TraceKind.h b/js/public/TraceKind.h index 2eda9cb2c..3270966fc 100644 --- a/js/public/TraceKind.h +++ b/js/public/TraceKind.h @@ -40,9 +40,11 @@ enum class TraceKind // Note: The order here is determined by our Value packing. Other users // should sort alphabetically, for consistency. Object = 0x00, - String = 0x01, - Symbol = 0x02, - Script = 0x03, + String = 0x02, + Symbol = 0x03, + + // 0x1 is not used for any GCThing Value tag, so we use it for Script. + Script = 0x01, // Shape details are exposed through JS_TraceShapeCycleCollectorChildren. Shape = 0x04, diff --git a/js/public/Value.h b/js/public/Value.h index 00fdad586..a40e65c83 100644 --- a/js/public/Value.h +++ b/js/public/Value.h @@ -51,12 +51,12 @@ JS_ENUM_HEADER(JSValueType, uint8_t) JSVAL_TYPE_DOUBLE = 0x00, JSVAL_TYPE_INT32 = 0x01, JSVAL_TYPE_UNDEFINED = 0x02, - JSVAL_TYPE_BOOLEAN = 0x03, - JSVAL_TYPE_MAGIC = 0x04, - JSVAL_TYPE_STRING = 0x05, - JSVAL_TYPE_SYMBOL = 0x06, - JSVAL_TYPE_PRIVATE_GCTHING = 0x07, - JSVAL_TYPE_NULL = 0x08, + JSVAL_TYPE_NULL = 0x03, + JSVAL_TYPE_BOOLEAN = 0x04, + JSVAL_TYPE_MAGIC = 0x05, + JSVAL_TYPE_STRING = 0x06, + JSVAL_TYPE_SYMBOL = 0x07, + JSVAL_TYPE_PRIVATE_GCTHING = 0x08, JSVAL_TYPE_OBJECT = 0x0c, /* These never appear in a jsval; they are only provided as an out-of-band value. */ @@ -75,11 +75,11 @@ JS_ENUM_HEADER(JSValueTag, uint32_t) JSVAL_TAG_CLEAR = 0xFFFFFF80, JSVAL_TAG_INT32 = JSVAL_TAG_CLEAR | JSVAL_TYPE_INT32, JSVAL_TAG_UNDEFINED = JSVAL_TAG_CLEAR | JSVAL_TYPE_UNDEFINED, + JSVAL_TAG_NULL = JSVAL_TAG_CLEAR | JSVAL_TYPE_NULL, JSVAL_TAG_STRING = JSVAL_TAG_CLEAR | JSVAL_TYPE_STRING, JSVAL_TAG_SYMBOL = JSVAL_TAG_CLEAR | JSVAL_TYPE_SYMBOL, JSVAL_TAG_BOOLEAN = JSVAL_TAG_CLEAR | JSVAL_TYPE_BOOLEAN, JSVAL_TAG_MAGIC = JSVAL_TAG_CLEAR | JSVAL_TYPE_MAGIC, - JSVAL_TAG_NULL = JSVAL_TAG_CLEAR | JSVAL_TYPE_NULL, JSVAL_TAG_OBJECT = JSVAL_TAG_CLEAR | JSVAL_TYPE_OBJECT, JSVAL_TAG_PRIVATE_GCTHING = JSVAL_TAG_CLEAR | JSVAL_TYPE_PRIVATE_GCTHING } JS_ENUM_FOOTER(JSValueTag); @@ -95,11 +95,11 @@ JS_ENUM_HEADER(JSValueTag, uint32_t) JSVAL_TAG_MAX_DOUBLE = 0x1FFF0, JSVAL_TAG_INT32 = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_INT32, JSVAL_TAG_UNDEFINED = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_UNDEFINED, + JSVAL_TAG_NULL = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_NULL, JSVAL_TAG_STRING = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_STRING, JSVAL_TAG_SYMBOL = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_SYMBOL, JSVAL_TAG_BOOLEAN = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_BOOLEAN, JSVAL_TAG_MAGIC = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_MAGIC, - JSVAL_TAG_NULL = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_NULL, JSVAL_TAG_OBJECT = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_OBJECT, JSVAL_TAG_PRIVATE_GCTHING = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_PRIVATE_GCTHING } JS_ENUM_FOOTER(JSValueTag); @@ -112,11 +112,11 @@ JS_ENUM_HEADER(JSValueShiftedTag, uint64_t) JSVAL_SHIFTED_TAG_MAX_DOUBLE = ((((uint64_t)JSVAL_TAG_MAX_DOUBLE) << JSVAL_TAG_SHIFT) | 0xFFFFFFFF), JSVAL_SHIFTED_TAG_INT32 = (((uint64_t)JSVAL_TAG_INT32) << JSVAL_TAG_SHIFT), JSVAL_SHIFTED_TAG_UNDEFINED = (((uint64_t)JSVAL_TAG_UNDEFINED) << JSVAL_TAG_SHIFT), + JSVAL_SHIFTED_TAG_NULL = (((uint64_t)JSVAL_TAG_NULL) << JSVAL_TAG_SHIFT), JSVAL_SHIFTED_TAG_STRING = (((uint64_t)JSVAL_TAG_STRING) << JSVAL_TAG_SHIFT), JSVAL_SHIFTED_TAG_SYMBOL = (((uint64_t)JSVAL_TAG_SYMBOL) << JSVAL_TAG_SHIFT), JSVAL_SHIFTED_TAG_BOOLEAN = (((uint64_t)JSVAL_TAG_BOOLEAN) << JSVAL_TAG_SHIFT), JSVAL_SHIFTED_TAG_MAGIC = (((uint64_t)JSVAL_TAG_MAGIC) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_NULL = (((uint64_t)JSVAL_TAG_NULL) << JSVAL_TAG_SHIFT), JSVAL_SHIFTED_TAG_OBJECT = (((uint64_t)JSVAL_TAG_OBJECT) << JSVAL_TAG_SHIFT), JSVAL_SHIFTED_TAG_PRIVATE_GCTHING = (((uint64_t)JSVAL_TAG_PRIVATE_GCTHING) << JSVAL_TAG_SHIFT) } JS_ENUM_FOOTER(JSValueShiftedTag); @@ -140,7 +140,6 @@ static_assert(sizeof(JSValueShiftedTag) == sizeof(uint64_t), #define JSVAL_TYPE_TO_TAG(type) ((JSValueTag)(JSVAL_TAG_CLEAR | (type))) -#define JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET JSVAL_TAG_NULL #define JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET JSVAL_TAG_OBJECT #define JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET JSVAL_TAG_INT32 #define JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET JSVAL_TAG_STRING @@ -152,12 +151,10 @@ static_assert(sizeof(JSValueShiftedTag) == sizeof(uint64_t), #define JSVAL_TYPE_TO_TAG(type) ((JSValueTag)(JSVAL_TAG_MAX_DOUBLE | (type))) #define JSVAL_TYPE_TO_SHIFTED_TAG(type) (((uint64_t)JSVAL_TYPE_TO_TAG(type)) << JSVAL_TAG_SHIFT) -#define JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET JSVAL_TAG_NULL #define JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET JSVAL_TAG_OBJECT #define JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET JSVAL_TAG_INT32 #define JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET JSVAL_TAG_STRING -#define JSVAL_LOWER_INCL_SHIFTED_TAG_OF_OBJ_OR_NULL_SET JSVAL_SHIFTED_TAG_NULL #define JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET JSVAL_SHIFTED_TAG_OBJECT #define JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET JSVAL_SHIFTED_TAG_UNDEFINED #define JSVAL_LOWER_INCL_SHIFTED_TAG_OF_GCTHING_SET JSVAL_SHIFTED_TAG_STRING @@ -537,12 +534,7 @@ class MOZ_NON_PARAM alignas(8) Value } bool isObjectOrNull() const { - MOZ_ASSERT(uint32_t(toTag()) <= uint32_t(JSVAL_TAG_OBJECT)); -#if defined(JS_NUNBOX32) - return uint32_t(toTag()) >= uint32_t(JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET); -#elif defined(JS_PUNBOX64) - return data.asBits >= JSVAL_LOWER_INCL_SHIFTED_TAG_OF_OBJ_OR_NULL_SET; -#endif + return isObject() || isNull(); } bool isGCThing() const { @@ -575,12 +567,8 @@ class MOZ_NON_PARAM alignas(8) Value return isMagic(); } - bool isMarkable() const { - return isGCThing() && !isNull(); - } - JS::TraceKind traceKind() const { - MOZ_ASSERT(isMarkable()); + MOZ_ASSERT(isGCThing()); static_assert((JSVAL_TAG_STRING & 0x03) == size_t(JS::TraceKind::String), "Value type tags must correspond with JS::TraceKinds."); static_assert((JSVAL_TAG_SYMBOL & 0x03) == size_t(JS::TraceKind::Symbol), @@ -684,11 +672,6 @@ class MOZ_NON_PARAM alignas(8) Value #endif } - js::gc::Cell* toMarkablePointer() const { - MOZ_ASSERT(isMarkable()); - return toGCThing(); - } - GCCellPtr toGCCellPtr() const { return GCCellPtr(toGCThing(), traceKind()); } @@ -760,9 +743,9 @@ class MOZ_NON_PARAM alignas(8) Value * Private GC Thing API * * Non-JSObject, JSString, and JS::Symbol cells may be put into the 64-bit - * payload as private GC things. Such Values are considered isMarkable() - * and isGCThing(), and as such, automatically marked. Their traceKind() - * is gotten via their cells. + * payload as private GC things. Such Values are considered isGCThing(), and + * as such, automatically marked. Their traceKind() is gotten via their + * cells. */ void setPrivateGCThing(js::gc::Cell* cell) { @@ -980,7 +963,7 @@ IsOptimizedPlaceholderMagicValue(const Value& v) static MOZ_ALWAYS_INLINE void ExposeValueToActiveJS(const Value& v) { - if (v.isMarkable()) + if (v.isGCThing()) js::gc::ExposeGCThingToActiveJS(GCCellPtr(v)); } @@ -1298,7 +1281,7 @@ template <> struct BarrierMethods<JS::Value> { static gc::Cell* asGCThingOrNull(const JS::Value& v) { - return v.isMarkable() ? v.toGCThing() : nullptr; + return v.isGCThing() ? v.toGCThing() : nullptr; } static void postBarrier(JS::Value* v, const JS::Value& prev, const JS::Value& next) { JS::HeapValuePostBarrier(v, prev, next); @@ -1338,9 +1321,8 @@ class ValueOperations bool isObject() const { return value().isObject(); } bool isMagic() const { return value().isMagic(); } bool isMagic(JSWhyMagic why) const { return value().isMagic(why); } - bool isMarkable() const { return value().isMarkable(); } - bool isPrimitive() const { return value().isPrimitive(); } bool isGCThing() const { return value().isGCThing(); } + bool isPrimitive() const { return value().isPrimitive(); } bool isNullOrUndefined() const { return value().isNullOrUndefined(); } bool isObjectOrNull() const { return value().isObjectOrNull(); } @@ -1485,7 +1467,7 @@ DispatchTyped(F f, const JS::Value& val, Args&&... args) return f(val.toSymbol(), mozilla::Forward<Args>(args)...); if (MOZ_UNLIKELY(val.isPrivateGCThing())) return DispatchTyped(f, val.toGCCellPtr(), mozilla::Forward<Args>(args)...); - MOZ_ASSERT(!val.isMarkable()); + MOZ_ASSERT(!val.isGCThing()); return F::defaultValue(val); } diff --git a/js/src/builtin/ModuleObject.cpp b/js/src/builtin/ModuleObject.cpp index 40fd008b9..710c7a76c 100644 --- a/js/src/builtin/ModuleObject.cpp +++ b/js/src/builtin/ModuleObject.cpp @@ -1159,7 +1159,7 @@ bool ModuleBuilder::processExport(frontend::ParseNode* pn) { MOZ_ASSERT(pn->isKind(PNK_EXPORT) || pn->isKind(PNK_EXPORT_DEFAULT)); - MOZ_ASSERT(pn->getArity() == pn->isKind(PNK_EXPORT) ? PN_UNARY : PN_BINARY); + MOZ_ASSERT(pn->getArity() == (pn->isKind(PNK_EXPORT) ? PN_UNARY : PN_BINARY)); bool isDefault = pn->getKind() == PNK_EXPORT_DEFAULT; ParseNode* kid = isDefault ? pn->pn_left : pn->pn_kid; diff --git a/js/src/builtin/ReflectParse.cpp b/js/src/builtin/ReflectParse.cpp index eef6fd7ec..beff58e13 100644 --- a/js/src/builtin/ReflectParse.cpp +++ b/js/src/builtin/ReflectParse.cpp @@ -2140,7 +2140,7 @@ ASTSerializer::exportDeclaration(ParseNode* pn, MutableHandleValue dst) MOZ_ASSERT(pn->isKind(PNK_EXPORT) || pn->isKind(PNK_EXPORT_FROM) || pn->isKind(PNK_EXPORT_DEFAULT)); - MOZ_ASSERT(pn->getArity() == pn->isKind(PNK_EXPORT) ? PN_UNARY : PN_BINARY); + MOZ_ASSERT(pn->getArity() == (pn->isKind(PNK_EXPORT) ? PN_UNARY : PN_BINARY)); MOZ_ASSERT_IF(pn->isKind(PNK_EXPORT_FROM), pn->pn_right->isKind(PNK_STRING)); RootedValue decl(cx, NullValue()); diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index acf449b7e..a14f9ba69 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -881,7 +881,7 @@ HasChild(JSContext* cx, unsigned argc, Value* vp) RootedValue parent(cx, args.get(0)); RootedValue child(cx, args.get(1)); - if (!parent.isMarkable() || !child.isMarkable()) { + if (!parent.isGCThing() || !child.isGCThing()) { args.rval().setBoolean(false); return true; } diff --git a/js/src/gc/Barrier.cpp b/js/src/gc/Barrier.cpp index f19f6f046..6dab8d25b 100644 --- a/js/src/gc/Barrier.cpp +++ b/js/src/gc/Barrier.cpp @@ -56,7 +56,7 @@ HeapSlot::preconditionForWriteBarrierPost(NativeObject* obj, Kind kind, uint32_t bool isCorrectSlot = kind == Slot ? obj->getSlotAddressUnchecked(slot)->get() == target : static_cast<HeapSlot*>(obj->getDenseElements() + slot)->get() == target; - bool isBlackToGray = target.isMarkable() && + bool isBlackToGray = target.isGCThing() && IsMarkedBlack(obj) && JS::GCThingIsMarkedGray(JS::GCCellPtr(target)); return isCorrectSlot && !isBlackToGray; } diff --git a/js/src/gc/Barrier.h b/js/src/gc/Barrier.h index 950c96314..effc9233e 100644 --- a/js/src/gc/Barrier.h +++ b/js/src/gc/Barrier.h @@ -282,7 +282,7 @@ template <typename S> struct ReadBarrierFunctor : public VoidDefaultAdaptor<S> { template <> struct InternalBarrierMethods<Value> { - static bool isMarkable(const Value& v) { return v.isMarkable(); } + static bool isMarkable(const Value& v) { return v.isGCThing(); } static bool isMarkableTaggedPointer(const Value& v) { return isMarkable(v); } static void preBarrier(const Value& v) { diff --git a/js/src/gc/Marking.cpp b/js/src/gc/Marking.cpp index d9235f9ac..b2c105999 100644 --- a/js/src/gc/Marking.cpp +++ b/js/src/gc/Marking.cpp @@ -328,7 +328,7 @@ ShouldMarkCrossCompartment(JSTracer* trc, JSObject* src, Cell* cell) static bool ShouldMarkCrossCompartment(JSTracer* trc, JSObject* src, const Value& val) { - return val.isMarkable() && ShouldMarkCrossCompartment(trc, src, (Cell*)val.toGCThing()); + return val.isGCThing() && ShouldMarkCrossCompartment(trc, src, val.toGCThing()); } static void @@ -1599,7 +1599,7 @@ ObjectDenseElementsMayBeMarkable(NativeObject* nobj) if (!mayBeMarkable) { const Value* elements = nobj->getDenseElementsAllowCopyOnWrite(); for (unsigned i = 0; i < nobj->getDenseInitializedLength(); i++) - MOZ_ASSERT(!elements[i].isMarkable()); + MOZ_ASSERT(!elements[i].isGCThing()); } #endif diff --git a/js/src/gc/Marking.h b/js/src/gc/Marking.h index ec4c69a2f..73f63d804 100644 --- a/js/src/gc/Marking.h +++ b/js/src/gc/Marking.h @@ -404,7 +404,7 @@ IsAboutToBeFinalizedDuringSweep(TenuredCell& tenured); inline Cell* ToMarkable(const Value& v) { - if (v.isMarkable()) + if (v.isGCThing()) return (Cell*)v.toGCThing(); return nullptr; } diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index ccdc5fbfa..7b2f8214b 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -8526,8 +8526,8 @@ StoreUnboxedPointer(MacroAssembler& masm, T address, MIRType type, const LAlloca masm.patchableCallPreBarrier(address, type); if (value->isConstant()) { Value v = value->toConstant()->toJSValue(); - if (v.isMarkable()) { - masm.storePtr(ImmGCPtr(v.toMarkablePointer()), address); + if (v.isGCThing()) { + masm.storePtr(ImmGCPtr(v.toGCThing()), address); } else { MOZ_ASSERT(v.isNull()); masm.storePtr(ImmWord(0), address); diff --git a/js/src/jit/JitFrames.cpp b/js/src/jit/JitFrames.cpp index 966d952d3..f11f17225 100644 --- a/js/src/jit/JitFrames.cpp +++ b/js/src/jit/JitFrames.cpp @@ -2062,7 +2062,7 @@ SnapshotIterator::traceAllocation(JSTracer* trc) return; Value v = allocationValue(alloc, RM_AlwaysDefault); - if (!v.isMarkable()) + if (!v.isGCThing()) return; Value copy = v; diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index 7f28a9020..730697163 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -2687,7 +2687,7 @@ IsNonNurseryConstant(MDefinition* def) if (!def->isConstant()) return false; Value v = def->toConstant()->toJSValue(); - return !v.isMarkable() || !IsInsideNursery(v.toMarkablePointer()); + return !v.isGCThing() || !IsInsideNursery(v.toGCThing()); } void diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp index c6e627db6..d40578514 100644 --- a/js/src/jit/arm/MacroAssembler-arm.cpp +++ b/js/src/jit/arm/MacroAssembler-arm.cpp @@ -3286,8 +3286,8 @@ void MacroAssemblerARMCompat::moveValue(const Value& val, Register type, Register data) { ma_mov(Imm32(val.toNunboxTag()), type); - if (val.isMarkable()) - ma_mov(ImmGCPtr(val.toMarkablePointer()), data); + if (val.isGCThing()) + ma_mov(ImmGCPtr(val.toGCThing()), data); else ma_mov(Imm32(val.toNunboxPayload()), data); } @@ -3484,8 +3484,8 @@ MacroAssemblerARMCompat::storePayload(const Value& val, const BaseIndex& dest) ScratchRegisterScope scratch(asMasm()); SecondScratchRegisterScope scratch2(asMasm()); - if (val.isMarkable()) - ma_mov(ImmGCPtr(val.toMarkablePointer()), scratch); + if (val.isGCThing()) + ma_mov(ImmGCPtr(val.toGCThing()), scratch); else ma_mov(Imm32(val.toNunboxPayload()), scratch); @@ -5314,8 +5314,8 @@ MacroAssembler::branchTestValue(Condition cond, const ValueOperand& lhs, // equal, short circuit false (NotEqual). ScratchRegisterScope scratch(*this); - if (rhs.isMarkable()) - ma_cmp(lhs.payloadReg(), ImmGCPtr(rhs.toMarkablePointer()), scratch); + if (rhs.isGCThing()) + ma_cmp(lhs.payloadReg(), ImmGCPtr(rhs.toGCThing()), scratch); else ma_cmp(lhs.payloadReg(), Imm32(rhs.toNunboxPayload()), scratch); ma_cmp(lhs.typeReg(), Imm32(rhs.toNunboxTag()), scratch, Equal); diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index c011af3c3..c20a6c3e5 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -915,8 +915,8 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM ma_mov(Imm32(val.toNunboxTag()), scratch); ma_str(scratch, ToType(dest), scratch2); - if (val.isMarkable()) - ma_mov(ImmGCPtr(val.toMarkablePointer()), scratch); + if (val.isGCThing()) + ma_mov(ImmGCPtr(val.toGCThing()), scratch); else ma_mov(Imm32(val.toNunboxPayload()), scratch); ma_str(scratch, ToPayload(dest), scratch2); @@ -944,15 +944,15 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM // Store the payload, marking if necessary. if (payloadoffset < 4096 && payloadoffset > -4096) { - if (val.isMarkable()) - ma_mov(ImmGCPtr(val.toMarkablePointer()), scratch2); + if (val.isGCThing()) + ma_mov(ImmGCPtr(val.toGCThing()), scratch2); else ma_mov(Imm32(val.toNunboxPayload()), scratch2); ma_str(scratch2, DTRAddr(scratch, DtrOffImm(payloadoffset))); } else { ma_add(Imm32(payloadoffset), scratch, scratch2); - if (val.isMarkable()) - ma_mov(ImmGCPtr(val.toMarkablePointer()), scratch2); + if (val.isGCThing()) + ma_mov(ImmGCPtr(val.toGCThing()), scratch2); else ma_mov(Imm32(val.toNunboxPayload()), scratch2); ma_str(scratch2, DTRAddr(scratch, DtrOffImm(0))); @@ -977,8 +977,8 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM void popValue(ValueOperand val); void pushValue(const Value& val) { push(Imm32(val.toNunboxTag())); - if (val.isMarkable()) - push(ImmGCPtr(val.toMarkablePointer())); + if (val.isGCThing()) + push(ImmGCPtr(val.toGCThing())); else push(Imm32(val.toNunboxPayload())); } diff --git a/js/src/jit/arm64/MacroAssembler-arm64.h b/js/src/jit/arm64/MacroAssembler-arm64.h index b95831443..c21e2fd66 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64.h +++ b/js/src/jit/arm64/MacroAssembler-arm64.h @@ -306,7 +306,7 @@ class MacroAssemblerCompat : public vixl::MacroAssembler void pushValue(const Value& val) { vixl::UseScratchRegisterScope temps(this); const Register scratch = temps.AcquireX().asUnsized(); - if (val.isMarkable()) { + if (val.isGCThing()) { BufferOffset load = movePatchablePtr(ImmPtr(val.bitsAsPunboxPointer()), scratch); writeDataRelocation(val, load); push(scratch); @@ -349,7 +349,7 @@ class MacroAssemblerCompat : public vixl::MacroAssembler } } void moveValue(const Value& val, Register dest) { - if (val.isMarkable()) { + if (val.isGCThing()) { BufferOffset load = movePatchablePtr(ImmPtr(val.bitsAsPunboxPointer()), dest); writeDataRelocation(val, load); } else { @@ -1835,8 +1835,8 @@ class MacroAssemblerCompat : public vixl::MacroAssembler dataRelocations_.writeUnsigned(load.getOffset()); } void writeDataRelocation(const Value& val, BufferOffset load) { - if (val.isMarkable()) { - gc::Cell* cell = val.toMarkablePointer(); + if (val.isGCThing()) { + gc::Cell* cell = val.toGCThing(); if (cell && gc::IsInsideNursery(cell)) embedsNurseryPointers_ = true; dataRelocations_.writeUnsigned(load.getOffset()); diff --git a/js/src/jit/mips32/MacroAssembler-mips32.cpp b/js/src/jit/mips32/MacroAssembler-mips32.cpp index 0d3e55e21..2b2fab92d 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.cpp +++ b/js/src/jit/mips32/MacroAssembler-mips32.cpp @@ -1527,8 +1527,8 @@ MacroAssemblerMIPSCompat::getType(const Value& val) void MacroAssemblerMIPSCompat::moveData(const Value& val, Register data) { - if (val.isMarkable()) - ma_li(data, ImmGCPtr(val.toMarkablePointer())); + if (val.isGCThing()) + ma_li(data, ImmGCPtr(val.toGCThing())); else ma_li(data, Imm32(val.toNunboxPayload())); } diff --git a/js/src/jit/mips32/MacroAssembler-mips32.h b/js/src/jit/mips32/MacroAssembler-mips32.h index 4c7618d08..adb626bb0 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.h +++ b/js/src/jit/mips32/MacroAssembler-mips32.h @@ -480,8 +480,8 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS void popValue(ValueOperand val); void pushValue(const Value& val) { push(Imm32(val.toNunboxTag())); - if (val.isMarkable()) - push(ImmGCPtr(val.toMarkablePointer())); + if (val.isGCThing()) + push(ImmGCPtr(val.toGCThing())); else push(Imm32(val.toNunboxPayload())); } diff --git a/js/src/jit/mips64/MacroAssembler-mips64.cpp b/js/src/jit/mips64/MacroAssembler-mips64.cpp index 329fa83f8..f58184bca 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.cpp +++ b/js/src/jit/mips64/MacroAssembler-mips64.cpp @@ -1885,7 +1885,7 @@ MacroAssemblerMIPS64Compat::storeValue(JSValueType type, Register reg, Address d void MacroAssemblerMIPS64Compat::storeValue(const Value& val, Address dest) { - if (val.isMarkable()) { + if (val.isGCThing()) { writeDataRelocation(val); movWithPatch(ImmWord(val.asRawBits()), SecondScratchReg); } else { diff --git a/js/src/jit/mips64/MacroAssembler-mips64.h b/js/src/jit/mips64/MacroAssembler-mips64.h index 4cff87236..bfe452974 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.h +++ b/js/src/jit/mips64/MacroAssembler-mips64.h @@ -221,8 +221,8 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64 } void writeDataRelocation(const Value& val) { - if (val.isMarkable()) { - gc::Cell* cell = val.toMarkablePointer(); + if (val.isGCThing()) { + gc::Cell* cell = val.toGCThing(); if (cell && gc::IsInsideNursery(cell)) embedsNurseryPointers_ = true; dataRelocations_.writeUnsigned(currentOffset()); @@ -498,7 +498,7 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64 void pushValue(ValueOperand val); void popValue(ValueOperand val); void pushValue(const Value& val) { - if (val.isMarkable()) { + if (val.isGCThing()) { writeDataRelocation(val); movWithPatch(ImmWord(val.asRawBits()), ScratchRegister); push(ScratchRegister); diff --git a/js/src/jit/x64/MacroAssembler-x64.h b/js/src/jit/x64/MacroAssembler-x64.h index cb81bd7c1..be450767b 100644 --- a/js/src/jit/x64/MacroAssembler-x64.h +++ b/js/src/jit/x64/MacroAssembler-x64.h @@ -58,8 +58,8 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared // X64 helpers. ///////////////////////////////////////////////////////////////// void writeDataRelocation(const Value& val) { - if (val.isMarkable()) { - gc::Cell* cell = val.toMarkablePointer(); + if (val.isGCThing()) { + gc::Cell* cell = val.toGCThing(); if (cell && gc::IsInsideNursery(cell)) embedsNurseryPointers_ = true; dataRelocations_.writeUnsigned(masm.currentOffset()); @@ -132,7 +132,7 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared template <typename T> void storeValue(const Value& val, const T& dest) { ScratchRegisterScope scratch(asMasm()); - if (val.isMarkable()) { + if (val.isGCThing()) { movWithPatch(ImmWord(val.asRawBits()), scratch); writeDataRelocation(val); } else { @@ -171,7 +171,7 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared pop(val.valueReg()); } void pushValue(const Value& val) { - if (val.isMarkable()) { + if (val.isGCThing()) { ScratchRegisterScope scratch(asMasm()); movWithPatch(ImmWord(val.asRawBits()), scratch); writeDataRelocation(val); diff --git a/js/src/jit/x86/MacroAssembler-x86.cpp b/js/src/jit/x86/MacroAssembler-x86.cpp index 754b29c2d..dc97b5b5b 100644 --- a/js/src/jit/x86/MacroAssembler-x86.cpp +++ b/js/src/jit/x86/MacroAssembler-x86.cpp @@ -499,8 +499,8 @@ MacroAssembler::branchTestValue(Condition cond, const ValueOperand& lhs, const Value& rhs, Label* label) { MOZ_ASSERT(cond == Equal || cond == NotEqual); - if (rhs.isMarkable()) - cmpPtr(lhs.payloadReg(), ImmGCPtr(rhs.toMarkablePointer())); + if (rhs.isGCThing()) + cmpPtr(lhs.payloadReg(), ImmGCPtr(rhs.toGCThing())); else cmpPtr(lhs.payloadReg(), ImmWord(rhs.toNunboxPayload())); diff --git a/js/src/jit/x86/MacroAssembler-x86.h b/js/src/jit/x86/MacroAssembler-x86.h index 21cd63a0c..2b2507c77 100644 --- a/js/src/jit/x86/MacroAssembler-x86.h +++ b/js/src/jit/x86/MacroAssembler-x86.h @@ -94,8 +94,8 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared } void moveValue(const Value& val, Register type, Register data) { movl(Imm32(val.toNunboxTag()), type); - if (val.isMarkable()) - movl(ImmGCPtr(val.toMarkablePointer()), data); + if (val.isGCThing()) + movl(ImmGCPtr(val.toGCThing()), data); else movl(Imm32(val.toNunboxPayload()), data); } @@ -213,8 +213,8 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared } void pushValue(const Value& val) { push(Imm32(val.toNunboxTag())); - if (val.isMarkable()) - push(ImmGCPtr(val.toMarkablePointer())); + if (val.isGCThing()) + push(ImmGCPtr(val.toGCThing())); else push(Imm32(val.toNunboxPayload())); } @@ -235,8 +235,8 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared pop(dest.high); } void storePayload(const Value& val, Operand dest) { - if (val.isMarkable()) - movl(ImmGCPtr(val.toMarkablePointer()), ToPayload(dest)); + if (val.isGCThing()) + movl(ImmGCPtr(val.toGCThing()), ToPayload(dest)); else movl(Imm32(val.toNunboxPayload()), ToPayload(dest)); } diff --git a/js/src/jscompartmentinlines.h b/js/src/jscompartmentinlines.h index 08d315db0..6a54bc5a6 100644 --- a/js/src/jscompartmentinlines.h +++ b/js/src/jscompartmentinlines.h @@ -61,7 +61,7 @@ inline bool JSCompartment::wrap(JSContext* cx, JS::MutableHandleValue vp) { /* Only GC things have to be wrapped or copied. */ - if (!vp.isMarkable()) + if (!vp.isGCThing()) return true; /* diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h index b1c7cb0dc..722085549 100644 --- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -761,7 +761,7 @@ SetReservedSlot(JSObject* obj, size_t slot, const JS::Value& value) { MOZ_ASSERT(slot < JSCLASS_RESERVED_SLOTS(GetObjectClass(obj))); shadow::Object* sobj = reinterpret_cast<shadow::Object*>(obj); - if (sobj->slotRef(slot).isMarkable() || value.isMarkable()) + if (sobj->slotRef(slot).isGCThing() || value.isGCThing()) SetReservedOrProxyPrivateSlotWithBarrier(obj, slot, value); else sobj->slotRef(slot) = value; diff --git a/js/src/jsfun.h b/js/src/jsfun.h index d45d112a5..7da831aa2 100644 --- a/js/src/jsfun.h +++ b/js/src/jsfun.h @@ -830,7 +830,7 @@ inline void JSFunction::setExtendedSlot(size_t which, const js::Value& val) { MOZ_ASSERT(which < mozilla::ArrayLength(toExtended()->extendedSlots)); - MOZ_ASSERT_IF(js::IsMarkedBlack(this) && val.isMarkable(), + MOZ_ASSERT_IF(js::IsMarkedBlack(this) && val.isGCThing(), !JS::GCThingIsMarkedGray(JS::GCCellPtr(val))); toExtended()->extendedSlots[which] = val; } diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index e86ceab3d..9f914943e 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -3309,7 +3309,7 @@ js::detail::CopyScript(JSContext* cx, HandleScript src, HandleScript dst, GCPtrValue* vector = Rebase<GCPtrValue>(dst, src, src->consts()->vector); dst->consts()->vector = vector; for (unsigned i = 0; i < nconsts; ++i) - MOZ_ASSERT_IF(vector[i].isMarkable(), vector[i].toString()->isAtom()); + MOZ_ASSERT_IF(vector[i].isGCThing(), vector[i].toString()->isAtom()); } if (nobjects != 0) { GCPtrObject* vector = Rebase<GCPtrObject>(dst, src, src->objects()->vector); diff --git a/js/src/vm/ProxyObject.cpp b/js/src/vm/ProxyObject.cpp index 49ed5a624..69b4cd952 100644 --- a/js/src/vm/ProxyObject.cpp +++ b/js/src/vm/ProxyObject.cpp @@ -45,7 +45,7 @@ ProxyObject::New(JSContext* cx, const BaseProxyHandler* handler, HandleValue pri // wrappee. Prefer to allocate in the nursery, when possible. NewObjectKind newKind = NurseryAllocatedProxy; if (options.singleton()) { - MOZ_ASSERT(priv.isGCThing() && priv.toGCThing()->isTenured()); + MOZ_ASSERT(priv.isNull() || (priv.isGCThing() && priv.toGCThing()->isTenured())); newKind = SingletonObject; } else if ((priv.isGCThing() && priv.toGCThing()->isTenured()) || !handler->canNurseryAllocate() || diff --git a/js/xpconnect/src/XPCJSContext.cpp b/js/xpconnect/src/XPCJSContext.cpp index bedb7c650..f5f6a11bb 100644 --- a/js/xpconnect/src/XPCJSContext.cpp +++ b/js/xpconnect/src/XPCJSContext.cpp @@ -59,10 +59,6 @@ #include "nsIXULRuntime.h" #include "nsJSPrincipals.h" -#ifdef MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" -#endif - #if defined(MOZ_JEMALLOC4) #include "mozmemory.h" #endif @@ -709,11 +705,6 @@ XPCJSContext::GCSliceCallback(JSContext* cx, if (!self) return; -#ifdef MOZ_CRASHREPORTER - CrashReporter::SetGarbageCollecting(progress == JS::GC_CYCLE_BEGIN || - progress == JS::GC_SLICE_BEGIN); -#endif - if (self->mPrevGCSliceCallback) (*self->mPrevGCSliceCallback)(cx, progress, desc); } diff --git a/js/xpconnect/src/XPCShellImpl.cpp b/js/xpconnect/src/XPCShellImpl.cpp index d9629bfed..45d00d390 100644 --- a/js/xpconnect/src/XPCShellImpl.cpp +++ b/js/xpconnect/src/XPCShellImpl.cpp @@ -59,11 +59,6 @@ #include <unistd.h> /* for isatty() */ #endif -#ifdef MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" -#include "nsICrashReporter.h" -#endif - using namespace mozilla; using namespace JS; using mozilla::dom::AutoJSAPI; @@ -1372,18 +1367,6 @@ XRE_XPCShellMain(int argc, char** argv, char** envp, argv += 2; } -#ifdef MOZ_CRASHREPORTER - const char* val = getenv("MOZ_CRASHREPORTER"); - if (val && *val) { - rv = CrashReporter::SetExceptionHandler(greDir, true); - if (NS_FAILED(rv)) { - printf("CrashReporter::SetExceptionHandler failed!\n"); - return 1; - } - MOZ_ASSERT(CrashReporter::GetEnabled()); - } -#endif - { if (argc > 1 && !strcmp(argv[1], "--greomni")) { nsCOMPtr<nsIFile> greOmni; @@ -1603,12 +1586,6 @@ XRE_XPCShellMain(int argc, char** argv, char** envp, dirprovider.ClearPluginDir(); dirprovider.ClearAppFile(); -#ifdef MOZ_CRASHREPORTER - // Shut down the crashreporter service to prevent leaking some strings it holds. - if (CrashReporter::GetEnabled()) - CrashReporter::UnsetExceptionHandler(); -#endif - NS_LogTerm(); return result; diff --git a/js/xpconnect/src/XPCVariant.cpp b/js/xpconnect/src/XPCVariant.cpp index a3d2b88c5..4c1230172 100644 --- a/js/xpconnect/src/XPCVariant.cpp +++ b/js/xpconnect/src/XPCVariant.cpp @@ -55,7 +55,7 @@ XPCTraceableVariant::~XPCTraceableVariant() { Value val = GetJSValPreserveColor(); - MOZ_ASSERT(val.isGCThing(), "Must be traceable or unlinked"); + MOZ_ASSERT(val.isGCThing() || val.isNull(), "Must be traceable or unlinked"); mData.Cleanup(); @@ -65,7 +65,7 @@ XPCTraceableVariant::~XPCTraceableVariant() void XPCTraceableVariant::TraceJS(JSTracer* trc) { - MOZ_ASSERT(GetJSValPreserveColor().isMarkable()); + MOZ_ASSERT(GetJSValPreserveColor().isGCThing()); JS::TraceEdge(trc, &mJSVal, "XPCTraceableVariant::mJSVal"); } @@ -86,7 +86,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(XPCVariant) tmp->mData.Cleanup(); - if (val.isMarkable()) { + if (val.isGCThing()) { XPCTraceableVariant* v = static_cast<XPCTraceableVariant*>(tmp); v->RemoveFromRootSet(); } @@ -99,7 +99,7 @@ XPCVariant::newVariant(JSContext* cx, const Value& aJSVal) { RefPtr<XPCVariant> variant; - if (!aJSVal.isMarkable()) + if (!aJSVal.isGCThing()) variant = new XPCVariant(cx, aJSVal); else variant = new XPCTraceableVariant(cx, aJSVal); diff --git a/layout/style/nsLayoutStylesheetCache.cpp b/layout/style/nsLayoutStylesheetCache.cpp index f8aea5541..e8c6d09d7 100644 --- a/layout/style/nsLayoutStylesheetCache.cpp +++ b/layout/style/nsLayoutStylesheetCache.cpp @@ -23,19 +23,6 @@ #include "nsPrintfCString.h" #include "nsXULAppAPI.h" -// Includes for the crash report annotation in ErrorLoadingSheet. -#ifdef MOZ_CRASHREPORTER -#include "mozilla/Omnijar.h" -#include "nsDirectoryService.h" -#include "nsDirectoryServiceDefs.h" -#include "nsExceptionHandler.h" -#include "nsIChromeRegistry.h" -#include "nsISimpleEnumerator.h" -#include "nsISubstitutingProtocolHandler.h" -#include "zlib.h" -#include "nsZipArchive.h" -#endif - using namespace mozilla; using namespace mozilla::css; @@ -463,280 +450,6 @@ nsLayoutStylesheetCache::LoadSheetFile(nsIFile* aFile, LoadSheet(uri, aSheet, aParsingMode, aFailureAction); } -#ifdef MOZ_CRASHREPORTER -static inline nsresult -ComputeCRC32(nsIFile* aFile, uint32_t* aResult) -{ - PRFileDesc* fd; - nsresult rv = aFile->OpenNSPRFileDesc(PR_RDONLY, 0, &fd); - NS_ENSURE_SUCCESS(rv, rv); - - uint32_t crc = crc32(0, nullptr, 0); - - unsigned char buf[512]; - int32_t n; - while ((n = PR_Read(fd, buf, sizeof(buf))) > 0) { - crc = crc32(crc, buf, n); - } - PR_Close(fd); - - if (n < 0) { - return NS_ERROR_FAILURE; - } - - *aResult = crc; - return NS_OK; -} - -static void -ListInterestingFiles(nsString& aAnnotation, nsIFile* aFile, - const nsTArray<nsString>& aInterestingFilenames) -{ - nsString filename; - aFile->GetLeafName(filename); - for (const nsString& interestingFilename : aInterestingFilenames) { - if (interestingFilename == filename) { - nsString path; - aFile->GetPath(path); - aAnnotation.AppendLiteral(" "); - aAnnotation.Append(path); - aAnnotation.AppendLiteral(" ("); - int64_t size; - if (NS_SUCCEEDED(aFile->GetFileSize(&size))) { - aAnnotation.AppendPrintf("%ld", size); - } else { - aAnnotation.AppendLiteral("???"); - } - aAnnotation.AppendLiteral(" bytes, crc32 = "); - uint32_t crc; - nsresult rv = ComputeCRC32(aFile, &crc); - if (NS_SUCCEEDED(rv)) { - aAnnotation.AppendPrintf("0x%08x)\n", crc); - } else { - aAnnotation.AppendPrintf("error 0x%08x)\n", uint32_t(rv)); - } - return; - } - } - - bool isDir = false; - aFile->IsDirectory(&isDir); - - if (!isDir) { - return; - } - - nsCOMPtr<nsISimpleEnumerator> entries; - if (NS_FAILED(aFile->GetDirectoryEntries(getter_AddRefs(entries)))) { - aAnnotation.AppendLiteral(" (failed to enumerated directory)\n"); - return; - } - - for (;;) { - bool hasMore = false; - if (NS_FAILED(entries->HasMoreElements(&hasMore))) { - aAnnotation.AppendLiteral(" (failed during directory enumeration)\n"); - return; - } - if (!hasMore) { - break; - } - - nsCOMPtr<nsISupports> entry; - if (NS_FAILED(entries->GetNext(getter_AddRefs(entry)))) { - aAnnotation.AppendLiteral(" (failed during directory enumeration)\n"); - return; - } - - nsCOMPtr<nsIFile> file = do_QueryInterface(entry); - if (file) { - ListInterestingFiles(aAnnotation, file, aInterestingFilenames); - } - } -} - -// Generate a crash report annotation to help debug issues with style -// sheets failing to load (bug 1194856). -static void -AnnotateCrashReport(nsIURI* aURI) -{ - nsAutoCString spec; - nsAutoCString scheme; - nsDependentCSubstring filename; - if (aURI) { - spec = aURI->GetSpecOrDefault(); - aURI->GetScheme(scheme); - int32_t i = spec.RFindChar('/'); - if (i != -1) { - filename.Rebind(spec, i + 1); - } - } - - nsString annotation; - - // The URL of the sheet that failed to load. - annotation.AppendLiteral("Error loading sheet: "); - annotation.Append(NS_ConvertUTF8toUTF16(spec).get()); - annotation.Append('\n'); - - annotation.AppendLiteral("NS_ERROR_FILE_CORRUPTION reason: "); - if (nsZipArchive::sFileCorruptedReason) { - annotation.Append(NS_ConvertUTF8toUTF16(nsZipArchive::sFileCorruptedReason).get()); - annotation.Append('\n'); - } else { - annotation.AppendLiteral("(none)\n"); - } - - // The jar: or file: URL that the sheet's resource: or chrome: URL - // resolves to. - if (scheme.EqualsLiteral("resource")) { - annotation.AppendLiteral("Real location: "); - nsCOMPtr<nsISubstitutingProtocolHandler> handler; - nsCOMPtr<nsIIOService> io(do_GetIOService()); - if (io) { - nsCOMPtr<nsIProtocolHandler> ph; - io->GetProtocolHandler(scheme.get(), getter_AddRefs(ph)); - if (ph) { - handler = do_QueryInterface(ph); - } - } - if (!handler) { - annotation.AppendLiteral("(ResolveURI failed)\n"); - } else { - nsAutoCString resolvedSpec; - handler->ResolveURI(aURI, resolvedSpec); - annotation.Append(NS_ConvertUTF8toUTF16(resolvedSpec)); - annotation.Append('\n'); - } - } else if (scheme.EqualsLiteral("chrome")) { - annotation.AppendLiteral("Real location: "); - nsCOMPtr<nsIChromeRegistry> reg = - mozilla::services::GetChromeRegistryService(); - if (!reg) { - annotation.AppendLiteral("(no chrome registry)\n"); - } else { - nsCOMPtr<nsIURI> resolvedURI; - reg->ConvertChromeURL(aURI, getter_AddRefs(resolvedURI)); - if (!resolvedURI) { - annotation.AppendLiteral("(ConvertChromeURL failed)\n"); - } else { - annotation.Append( - NS_ConvertUTF8toUTF16(resolvedURI->GetSpecOrDefault())); - annotation.Append('\n'); - } - } - } - - nsTArray<nsString> interestingFiles; - interestingFiles.AppendElement(NS_LITERAL_STRING("chrome.manifest")); - interestingFiles.AppendElement(NS_LITERAL_STRING("omni.ja")); - interestingFiles.AppendElement(NS_ConvertUTF8toUTF16(filename)); - - annotation.AppendLiteral("GRE directory: "); - nsCOMPtr<nsIFile> file; - nsDirectoryService::gService->Get(NS_GRE_DIR, NS_GET_IID(nsIFile), - getter_AddRefs(file)); - if (file) { - // The Firefox installation directory. - nsString path; - file->GetPath(path); - annotation.Append(path); - annotation.Append('\n'); - - // List interesting files -- any chrome.manifest or omni.ja file or any file - // whose name is the sheet's filename -- under the Firefox installation - // directory. - annotation.AppendLiteral("Interesting files in the GRE directory:\n"); - ListInterestingFiles(annotation, file, interestingFiles); - - // If the Firefox installation directory has a chrome.manifest file, let's - // see what's in it. - file->Append(NS_LITERAL_STRING("chrome.manifest")); - bool exists = false; - file->Exists(&exists); - if (exists) { - annotation.AppendLiteral("Contents of chrome.manifest:\n[[[\n"); - PRFileDesc* fd; - if (NS_SUCCEEDED(file->OpenNSPRFileDesc(PR_RDONLY, 0, &fd))) { - nsCString contents; - char buf[512]; - int32_t n; - while ((n = PR_Read(fd, buf, sizeof(buf))) > 0) { - contents.Append(buf, n); - } - if (n < 0) { - annotation.AppendLiteral(" (error while reading)\n"); - } else { - annotation.Append(NS_ConvertUTF8toUTF16(contents)); - } - PR_Close(fd); - } - annotation.AppendLiteral("]]]\n"); - } - } else { - annotation.AppendLiteral("(none)\n"); - } - - // The jar: or file: URL prefix that chrome: and resource: URLs get translated - // to. - annotation.AppendLiteral("GRE omnijar URI string: "); - nsCString uri; - nsresult rv = Omnijar::GetURIString(Omnijar::GRE, uri); - if (NS_FAILED(rv)) { - annotation.AppendLiteral("(failed)\n"); - } else { - annotation.Append(NS_ConvertUTF8toUTF16(uri)); - annotation.Append('\n'); - } - - RefPtr<nsZipArchive> zip = Omnijar::GetReader(Omnijar::GRE); - if (zip) { - // List interesting files in the GRE omnijar. - annotation.AppendLiteral("Interesting files in the GRE omnijar:\n"); - nsZipFind* find; - rv = zip->FindInit(nullptr, &find); - if (NS_FAILED(rv)) { - annotation.AppendPrintf(" (FindInit failed with 0x%08x)\n", rv); - } else if (!find) { - annotation.AppendLiteral(" (FindInit returned null)\n"); - } else { - const char* result; - uint16_t len; - while (NS_SUCCEEDED(find->FindNext(&result, &len))) { - nsCString itemPathname; - nsString itemFilename; - itemPathname.Append(result, len); - int32_t i = itemPathname.RFindChar('/'); - if (i != -1) { - itemFilename = NS_ConvertUTF8toUTF16(Substring(itemPathname, i + 1)); - } - for (const nsString& interestingFile : interestingFiles) { - if (interestingFile == itemFilename) { - annotation.AppendLiteral(" "); - annotation.Append(NS_ConvertUTF8toUTF16(itemPathname)); - nsZipItem* item = zip->GetItem(itemPathname.get()); - if (!item) { - annotation.AppendLiteral(" (GetItem failed)\n"); - } else { - annotation.AppendPrintf(" (%d bytes, crc32 = 0x%08x)\n", - item->RealSize(), - item->CRC32()); - } - break; - } - } - } - delete find; - } - } else { - annotation.AppendLiteral("No GRE omnijar\n"); - } - - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("SheetLoadFailure"), - NS_ConvertUTF16toUTF8(annotation)); -} -#endif - static void ErrorLoadingSheet(nsIURI* aURI, const char* aMsg, FailureAction aFailureAction) { @@ -751,9 +464,6 @@ ErrorLoadingSheet(nsIURI* aURI, const char* aMsg, FailureAction aFailureAction) } } -#ifdef MOZ_CRASHREPORTER - AnnotateCrashReport(aURI); -#endif NS_RUNTIMEABORT(errorMessage.get()); } @@ -780,9 +490,6 @@ nsLayoutStylesheetCache::LoadSheet(nsIURI* aURI, } } -#ifdef MOZ_CRASHREPORTER - nsZipArchive::sFileCorruptedReason = nullptr; -#endif nsresult rv = loader->LoadSheetSync(aURI, aParsingMode, true, aSheet); if (NS_FAILED(rv)) { ErrorLoadingSheet(aURI, diff --git a/mobile/android/app/build.gradle b/mobile/android/app/build.gradle index 18586cadb..724b955ef 100644 --- a/mobile/android/app/build.gradle +++ b/mobile/android/app/build.gradle @@ -100,9 +100,7 @@ android { srcDir "${topsrcdir}/mobile/android/stumbler/java" } - if (!mozconfig.substs.MOZ_CRASHREPORTER) { - exclude 'org/mozilla/gecko/CrashReporter.java' - } + exclude 'org/mozilla/gecko/CrashReporter.java' if (!mozconfig.substs.MOZ_NATIVE_DEVICES) { exclude 'org/mozilla/gecko/ChromeCastDisplay.java' diff --git a/mobile/android/base/AndroidManifest.xml.in b/mobile/android/base/AndroidManifest.xml.in index 2ec98c35a..0352c1ab6 100644 --- a/mobile/android/base/AndroidManifest.xml.in +++ b/mobile/android/base/AndroidManifest.xml.in @@ -263,20 +263,6 @@ #include ../search/manifests/SearchAndroidManifest_activities.xml.in #endif -#if MOZ_CRASHREPORTER - <activity android:name="org.mozilla.gecko.CrashReporter" - android:process="@ANDROID_PACKAGE_NAME@.CrashReporter" - android:label="@string/crash_reporter_title" - android:icon="@drawable/crash_reporter" - android:theme="@style/Gecko" - android:exported="false" - android:excludeFromRecents="true"> - <intent-filter> - <action android:name="org.mozilla.gecko.reportCrash" /> - </intent-filter> - </activity> -#endif - <activity android:name="org.mozilla.gecko.preferences.GeckoPreferences" android:theme="@style/Gecko.Preferences" android:configChanges="orientation|screenSize|locale|layoutDirection" diff --git a/mobile/android/base/AppConstants.java.in b/mobile/android/base/AppConstants.java.in index 25a6a456e..21748e73b 100644 --- a/mobile/android/base/AppConstants.java.in +++ b/mobile/android/base/AppConstants.java.in @@ -194,13 +194,6 @@ public class AppConstants { false; //#endif - public static final boolean MOZ_CRASHREPORTER = -//#if MOZ_CRASHREPORTER - true; -//#else - false; -//#endif - public static final boolean MOZ_DATA_REPORTING = //#ifdef MOZ_DATA_REPORTING true; diff --git a/mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferences.java b/mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferences.java index 5ab1bc3fd..aab5be2de 100644 --- a/mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferences.java +++ b/mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferences.java @@ -734,12 +734,6 @@ OnSharedPreferenceChangeListener i--; continue; } - } else if (PREFS_CRASHREPORTER_ENABLED.equals(key)) { - if (!AppConstants.MOZ_CRASHREPORTER || !Restrictions.isAllowed(this, Restrictable.DATA_CHOICES)) { - preferences.removePreference(pref); - i--; - continue; - } } else if (PREFS_GEO_REPORTING.equals(key) || PREFS_GEO_LEARN_MORE.equals(key)) { if (!AppConstants.MOZ_STUMBLER_BUILD_TIME_ENABLED || !Restrictions.isAllowed(this, Restrictable.DATA_CHOICES)) { diff --git a/mobile/android/base/moz.build b/mobile/android/base/moz.build index 6c88464ab..eac831421 100644 --- a/mobile/android/base/moz.build +++ b/mobile/android/base/moz.build @@ -805,10 +805,6 @@ gbjar.extra_jars += [ CONFIG['ANDROID_SUPPORT_V4_AAR_INTERNAL_LIB'], 'constants.jar' ] -if CONFIG['MOZ_CRASHREPORTER']: - gbjar.sources += [ 'java/org/mozilla/gecko/CrashReporter.java' ] - ANDROID_RES_DIRS += [ 'crashreporter/res' ] - if CONFIG['MOZ_ANDROID_GCM']: gbjar.sources += ['java/org/mozilla/gecko/' + x for x in [ 'gcm/GcmInstanceIDListenerService.java', @@ -1089,7 +1085,7 @@ for var in ('ANDROID_PACKAGE_NAME', 'ANDROID_CPU_ARCH', 'MOZ_APP_DISPLAYNAME', 'MOZ_APP_UA_NAME', 'MOZ_APP_ID', 'MOZ_APP_NAME', 'MOZ_APP_VENDOR', 'MOZ_APP_VERSION', 'MOZ_CHILD_PROCESS_NAME', 'MOZ_ANDROID_APPLICATION_CLASS', 'MOZ_ANDROID_BROWSER_INTENT_CLASS', 'MOZ_ANDROID_SEARCH_INTENT_CLASS', - 'MOZ_CRASHREPORTER', 'MOZ_UPDATE_CHANNEL', 'OMNIJAR_NAME', + 'MOZ_UPDATE_CHANNEL', 'OMNIJAR_NAME', 'OS_TARGET', 'TARGET_XPCOM_ABI'): DEFINES[var] = CONFIG[var] diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/CrashHandler.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/CrashHandler.java index 15df27336..0c8eeff9e 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/CrashHandler.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/CrashHandler.java @@ -467,10 +467,6 @@ public class CrashHandler implements Thread.UncaughtExceptionHandler { @Override public boolean reportException(final Thread thread, final Throwable exc) { - if (AppConstants.MOZ_CRASHREPORTER && AppConstants.MOZILLA_OFFICIAL) { - // Only use Java crash reporter if enabled on official build. - return super.reportException(thread, exc); - } return false; } }; diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java index a80212639..152981649 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java @@ -166,10 +166,6 @@ public class GeckoAppShell // reportJavaCrash should have caused us to hard crash. If we're still here, // it probably means Gecko is not loaded, and we should do something else. - if (AppConstants.MOZ_CRASHREPORTER && AppConstants.MOZILLA_OFFICIAL) { - // Only use Java crash reporter if enabled on official build. - return super.reportException(thread, exc); - } return false; } }; diff --git a/mobile/android/installer/package-manifest.in b/mobile/android/installer/package-manifest.in index a643ea243..086138d47 100644 --- a/mobile/android/installer/package-manifest.in +++ b/mobile/android/installer/package-manifest.in @@ -507,14 +507,6 @@ @BINPATH@/@DLL_PREFIX@mozsandbox@DLL_SUFFIX@ #endif -; [Crash Reporter] -; CrashService is not used on Android but the ini files are required for L10N -; strings, see bug 1191351. -#ifdef MOZ_CRASHREPORTER -@BINPATH@/crashreporter.ini -@BINPATH@/crashreporter-override.ini -#endif - [mobile] @BINPATH@/chrome/chrome@JAREXT@ @BINPATH@/chrome/chrome.manifest diff --git a/mobile/android/tests/browser/robocop/robocop_head.js b/mobile/android/tests/browser/robocop/robocop_head.js index 0fa7e56c8..c9e1383f2 100644 --- a/mobile/android/tests/browser/robocop/robocop_head.js +++ b/mobile/android/tests/browser/robocop/robocop_head.js @@ -69,25 +69,6 @@ try { } catch (e) { } -// Enable crash reporting, if possible -// We rely on the Python harness to set MOZ_CRASHREPORTER_NO_REPORT -// and handle checking for minidumps. -// Note that if we're in a child process, we don't want to init the -// crashreporter component. -try { // nsIXULRuntime is not available in some configurations. - if (runningInParent && - "@mozilla.org/toolkit/crash-reporter;1" in Components.classes) { - // Remember to update </toolkit/crashreporter/test/unit/test_crashreporter.js> - // too if you change this initial setting. - let crashReporter = - Components.classes["@mozilla.org/toolkit/crash-reporter;1"] - .getService(Components.interfaces.nsICrashReporter); - crashReporter.enabled = true; - crashReporter.minidumpPath = do_get_cwd(); - } -} -catch (e) { } - /** * Date.now() is not necessarily monotonically increasing (insert sob story * about times not being the right tool to use for measuring intervals of time, diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index ff47dc8e3..59f8de9ac 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -24,7 +24,7 @@ pref("general.useragent.locale", "chrome://global/locale/intl.properties"); pref("general.useragent.compatMode.gecko", false); pref("general.useragent.compatMode.firefox", false); pref("general.useragent.compatMode.version", "52.9"); -pref("general.useragent.appVersionIsBuildID", true); +pref("general.useragent.appVersionIsBuildID", false); // This pref exists only for testing purposes. In order to disable all // overrides by default, don't initialize UserAgentOverrides.jsm. @@ -4738,6 +4738,8 @@ pref("dom.webnotifications.requireinteraction.enabled", false); // Alert animation effect, name is disableSlidingEffect for backwards-compat. pref("alerts.disableSlidingEffect", false); +// The immediate duration of the alert, in milliseconds. +pref("alerts.durationImmediate", 20000); // Show favicons in web notifications. pref("alerts.showFavicons", false); diff --git a/modules/libpref/nsPrefBranch.cpp b/modules/libpref/nsPrefBranch.cpp index 2fd4992c8..98e06aaa4 100644 --- a/modules/libpref/nsPrefBranch.cpp +++ b/modules/libpref/nsPrefBranch.cpp @@ -26,10 +26,6 @@ #include "prefapi_private_data.h" -#ifdef MOZ_CRASHREPORTER -#include "nsICrashReporter.h" -#endif - #include "nsIConsoleService.h" #ifdef DEBUG @@ -335,16 +331,6 @@ NS_IMETHODIMP nsPrefBranch::GetComplexValue(const char *aPrefName, const nsIID & // some addons, see bug 836263. nsAutoString wdata; if (!AppendUTF8toUTF16(utf8String, wdata, mozilla::fallible)) { -#ifdef MOZ_CRASHREPORTER - nsCOMPtr<nsICrashReporter> cr = - do_GetService("@mozilla.org/toolkit/crash-reporter;1"); - if (cr) { - cr->AnnotateCrashReport(NS_LITERAL_CSTRING("bug836263-size"), - nsPrintfCString("%x", utf8String.Length())); - cr->RegisterAppMemory(uint64_t(utf8String.BeginReading()), - std::min(0x1000U, utf8String.Length())); - } -#endif NS_RUNTIMEABORT("bug836263"); } theString->SetData(wdata); diff --git a/netwerk/ipc/NeckoMessageUtils.h b/netwerk/ipc/NeckoMessageUtils.h index 778691369..1633b82b6 100644 --- a/netwerk/ipc/NeckoMessageUtils.h +++ b/netwerk/ipc/NeckoMessageUtils.h @@ -14,11 +14,6 @@ #include "mozilla/net/DNS.h" #include "TimingStruct.h" -#ifdef MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" -#include "nsPrintfCString.h" -#endif - namespace IPC { // nsIPermissionManager utilities @@ -102,12 +97,6 @@ struct ParamTraits<mozilla::net::NetAddr> aMsg->WriteBytes(aParam.local.path, sizeof(aParam.local.path)); #endif } else { -#ifdef MOZ_CRASHREPORTER - if (XRE_IsParentProcess()) { - nsPrintfCString msg("%d", aParam.raw.family); - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Unknown NetAddr socket family"), msg); - } -#endif NS_RUNTIMEABORT("Unknown socket family"); } } diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index ce0f45dab..94b0d9bf9 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -1152,7 +1152,7 @@ ProcessXCTO(nsIURI* aURI, nsHttpResponseHead* aResponseHead, nsILoadInfo* aLoadI } if (aLoadInfo->GetExternalContentPolicyType() == nsIContentPolicy::TYPE_SCRIPT) { - if (nsContentUtils::IsScriptType(contentType)) { + if (nsContentUtils::IsJavascriptMIMEType(NS_ConvertUTF8toUTF16(contentType))) { return NS_OK; } ReportTypeBlocking(aURI, aLoadInfo, "MimeTypeMismatch"); diff --git a/old-configure.in b/old-configure.in index 7c61ebf74..2a9e2c65f 100644 --- a/old-configure.in +++ b/old-configure.in @@ -3487,68 +3487,6 @@ AC_SUBST(MOZ_GAMEPAD) AC_SUBST(MOZ_GAMEPAD_BACKEND) dnl ======================================================== -dnl = Breakpad crash reporting (on by default on supported platforms) -dnl ======================================================== - -case $target in -i?86-*-mingw*|x86_64-*-mingw*) - MOZ_CRASHREPORTER=1 - ;; -i?86-apple-darwin*|x86_64-apple-darwin*) - if test -z "$MOZ_IOS"; then - MOZ_CRASHREPORTER=1 - fi - ;; -i?86-*-linux*|x86_64-*-linux*|arm-*-linux*) - if test "$MOZ_ENABLE_GTK"; then - MOZ_CRASHREPORTER=1 - fi - ;; -*-android*|*-linuxandroid*) - MOZ_CRASHREPORTER=1 - ;; -esac - -MOZ_ARG_DISABLE_BOOL(crashreporter, -[ --disable-crashreporter Disable breakpad crash reporting], - [MOZ_CRASHREPORTER=], - [MOZ_CRASHREPORTER=F # Force enable breakpad]) - -if test "$OS_ARCH" != "$HOST_OS_ARCH" -a "$OS_ARCH" != "WINNT" -a "$OS_ARCH" != "Darwin"; then - if test "$MOZ_CRASHREPORTER" = F; then - AC_MSG_ERROR([Cannot --enable-crashreporter, as breakpad tools do not support compiling on $HOST_OS_ARCH while targeting $OS_ARCH.]) - fi - MOZ_CRASHREPORTER= -fi - -if test -n "$MOZ_CRASHREPORTER"; then - AC_DEFINE(MOZ_CRASHREPORTER) - - if test "$OS_TARGET" = "Linux" && \ - test -z "$SKIP_LIBRARY_CHECKS"; then - PKG_CHECK_MODULES(MOZ_GTHREAD, gthread-2.0) - fi - - if test "$OS_ARCH" = "WINNT"; then - if test -z "$HAVE_64BIT_BUILD" -a -n "$COMPILE_ENVIRONMENT"; then - MOZ_CRASHREPORTER_INJECTOR=1 - AC_DEFINE(MOZ_CRASHREPORTER_INJECTOR) - fi - fi -fi - -MOZ_ARG_WITH_STRING(crashreporter-enable-percent, -[ --with-crashreporter-enable-percent=NN - Enable sending crash reports by default on NN% of users. (default=100)], -[ val=`echo $withval | sed 's/[^0-9]//g'` - MOZ_CRASHREPORTER_ENABLE_PERCENT="$val"]) - -if test -z "$MOZ_CRASHREPORTER_ENABLE_PERCENT"; then - MOZ_CRASHREPORTER_ENABLE_PERCENT=100 -fi -AC_DEFINE_UNQUOTED(MOZ_CRASHREPORTER_ENABLE_PERCENT, $MOZ_CRASHREPORTER_ENABLE_PERCENT) - -dnl ======================================================== dnl = libjpeg-turbo configuration dnl ======================================================== MOZ_LIBJPEG_TURBO= @@ -5333,8 +5271,6 @@ AC_SUBST(MOZ_UNIVERSALCHARDET) AC_SUBST(ACCESSIBILITY) AC_SUBST(MOZ_SPELLCHECK) AC_SUBST(MOZ_ANDROID_ANR_REPORTER) -AC_SUBST(MOZ_CRASHREPORTER) -AC_SUBST(MOZ_CRASHREPORTER_INJECTOR) AC_SUBST(MOZ_MAINTENANCE_SERVICE) AC_SUBST(MOZ_VERIFY_MAR_SIGNATURE) AC_SUBST(MOZ_ENABLE_SIGNMAR) @@ -5567,7 +5503,7 @@ fi dnl If we have any service that uploads data (and requires data submission dnl policy alert), set MOZ_DATA_REPORTING. dnl We need SUBST for build system and DEFINE for xul preprocessor. -if test -n "$MOZ_TELEMETRY_REPORTING" || test -n "$MOZ_SERVICES_HEALTHREPORT" || test -n "$MOZ_CRASHREPORTER"; then +if test -n "$MOZ_TELEMETRY_REPORTING" || test -n "$MOZ_SERVICES_HEALTHREPORT"; then MOZ_DATA_REPORTING=1 AC_DEFINE(MOZ_DATA_REPORTING) AC_SUBST(MOZ_DATA_REPORTING) @@ -5820,6 +5756,7 @@ MOZ_BRANDING_DIRECTORY=$MOZ_BRANDING_DIRECTORY MC_BASILISK=$MC_BASILISK MC_PALEMOON=$MC_PALEMOON MOZ_SANDBOX=$MOZ_SANDBOX +MOZ_EME=$MOZ_EME MOZ_WEBRTC=$MOZ_WEBRTC MOZ_SYSTEM_LIBEVENT=$MOZ_SYSTEM_LIBEVENT MOZ_SYSTEM_NSS=$MOZ_SYSTEM_NSS diff --git a/python/mozbuild/mozbuild/mozinfo.py b/python/mozbuild/mozbuild/mozinfo.py index 2c08c4e9f..712722d62 100755 --- a/python/mozbuild/mozbuild/mozinfo.py +++ b/python/mozbuild/mozbuild/mozinfo.py @@ -80,7 +80,6 @@ def build_dict(config, env=os.environ): d['nightly_build'] = substs.get('NIGHTLY_BUILD') == '1' d['release_or_beta'] = substs.get('RELEASE_OR_BETA') == '1' d['pgo'] = substs.get('MOZ_PGO') == '1' - d['crashreporter'] = bool(substs.get('MOZ_CRASHREPORTER')) d['datareporting'] = bool(substs.get('MOZ_DATA_REPORTING')) d['healthreport'] = substs.get('MOZ_SERVICES_HEALTHREPORT') == '1' d['sync'] = substs.get('MOZ_SERVICES_SYNC') == '1' diff --git a/python/mozbuild/mozbuild/test/test_mozinfo.py b/python/mozbuild/mozbuild/test/test_mozinfo.py index 1a4194cb5..6d0909b2d 100755 --- a/python/mozbuild/mozbuild/test/test_mozinfo.py +++ b/python/mozbuild/mozbuild/test/test_mozinfo.py @@ -215,7 +215,6 @@ class TestBuildDict(unittest.TestCase, Base): OS_TARGET='Linux', TARGET_CPU='i386', MOZ_WIDGET_TOOLKIT='gtk2', - MOZ_CRASHREPORTER='1', ))) self.assertEqual(True, d['crashreporter']) diff --git a/security/sandbox/linux/glue/SandboxCrash.cpp b/security/sandbox/linux/glue/SandboxCrash.cpp index 87a75e845..8ead16bdf 100644 --- a/security/sandbox/linux/glue/SandboxCrash.cpp +++ b/security/sandbox/linux/glue/SandboxCrash.cpp @@ -18,9 +18,6 @@ #include "mozilla/Unused.h" #include "mozilla/dom/Exceptions.h" #include "nsContentUtils.h" -#ifdef MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" -#endif #include "mozilla/StackWalk.h" #include "nsString.h" #include "nsThreadUtils.h" @@ -109,9 +106,6 @@ SandboxCrash(int nr, siginfo_t *info, void *void_context) pid_t pid = getpid(), tid = syscall(__NR_gettid); bool dumped = false; -#ifdef MOZ_CRASHREPORTER - dumped = CrashReporter::WriteMinidumpForSigInfo(nr, info, void_context); -#endif if (!dumped) { SANDBOX_LOG_ERROR("crash reporter is disabled (or failed);" " trying stack trace:"); diff --git a/taskcluster/scripts/builder/build-l10n.sh b/taskcluster/scripts/builder/build-l10n.sh index be16955a5..d337bbfe3 100755 --- a/taskcluster/scripts/builder/build-l10n.sh +++ b/taskcluster/scripts/builder/build-l10n.sh @@ -32,7 +32,6 @@ fail() { exit 1 } -export MOZ_CRASHREPORTER_NO_REPORT=1 export MOZ_OBJDIR=obj-firefox export TINDERBOX_OUTPUT=1 diff --git a/taskcluster/scripts/builder/build-linux.sh b/taskcluster/scripts/builder/build-linux.sh index 8885abdec..d1e7e77cf 100755 --- a/taskcluster/scripts/builder/build-linux.sh +++ b/taskcluster/scripts/builder/build-linux.sh @@ -36,7 +36,6 @@ fail() { exit 1 } -export MOZ_CRASHREPORTER_NO_REPORT=1 export MOZ_OBJDIR=obj-firefox export TINDERBOX_OUTPUT=1 diff --git a/testing/gtest/mozilla/GTestRunner.cpp b/testing/gtest/mozilla/GTestRunner.cpp index 0864db8cb..544de81da 100644 --- a/testing/gtest/mozilla/GTestRunner.cpp +++ b/testing/gtest/mozilla/GTestRunner.cpp @@ -6,9 +6,6 @@ #include "GTestRunner.h" #include "gtest/gtest.h" #include "mozilla/Attributes.h" -#ifdef MOZ_CRASHREPORTER -#include "nsICrashReporter.h" -#endif #include "testing/TestHarness.h" #include "prenv.h" #ifdef XP_WIN @@ -92,28 +89,6 @@ int RunGTestFunc() #ifdef XP_WIN mozilla::ipc::windows::InitUIThread(); #endif -#ifdef MOZ_CRASHREPORTER - nsCOMPtr<nsICrashReporter> crashreporter; - char *crashreporterStr = PR_GetEnv("MOZ_CRASHREPORTER"); - if (crashreporterStr && !strcmp(crashreporterStr, "1")) { - //TODO: move this to an even-more-common location to use in all - // C++ unittests - crashreporter = do_GetService("@mozilla.org/toolkit/crash-reporter;1"); - if (crashreporter) { - std::cerr << "Setting up crash reporting" << std::endl; - - nsCOMPtr<nsIProperties> dirsvc = - do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID); - nsCOMPtr<nsIFile> cwd; - nsresult rv = dirsvc->Get(NS_OS_CURRENT_WORKING_DIR, - NS_GET_IID(nsIFile), - getter_AddRefs(cwd)); - MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv)); - crashreporter->SetEnabled(true); - crashreporter->SetMinidumpPath(cwd); - } - } -#endif return RUN_ALL_TESTS(); } diff --git a/testing/gtest/rungtests.py b/testing/gtest/rungtests.py index e9e33cca2..499908680 100644 --- a/testing/gtest/rungtests.py +++ b/testing/gtest/rungtests.py @@ -89,7 +89,6 @@ class GTests(object): ) env["XPCOM_DEBUG_BREAK"] = "stack-and-abort" env["MOZ_CRASHREPORTER_NO_REPORT"] = "1" - env["MOZ_CRASHREPORTER"] = "1" env["MOZ_RUN_GTEST"] = "1" # Normally we run with GTest default output, override this to use the TBPL test format. env["MOZ_TBPL_PARSER"] = "1" diff --git a/testing/marionette/client/marionette_driver/geckoinstance.py b/testing/marionette/client/marionette_driver/geckoinstance.py index 7e2048187..174168ed2 100644 --- a/testing/marionette/client/marionette_driver/geckoinstance.py +++ b/testing/marionette/client/marionette_driver/geckoinstance.py @@ -226,8 +226,7 @@ class GeckoInstance(object): # environment variables needed for crashreporting # https://developer.mozilla.org/docs/Environment_variables_affecting_crash_reporting - env.update({"MOZ_CRASHREPORTER": "1", - "MOZ_CRASHREPORTER_NO_REPORT": "1", + env.update({"MOZ_CRASHREPORTER_NO_REPORT": "1", "MOZ_CRASHREPORTER_SHUTDOWN": "1", }) diff --git a/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm b/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm index eebcbb6bb..d6cd836e7 100644 --- a/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm +++ b/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm @@ -851,9 +851,6 @@ this.BrowserTestUtils = { crashBrowser: Task.async(function*(browser, shouldShowTabCrashPage=true) { let extra = {}; let KeyValueParser = {}; - if (AppConstants.MOZ_CRASHREPORTER) { - Cu.import("resource://gre/modules/KeyValueParser.jsm", KeyValueParser); - } if (!browser.isRemoteBrowser) { throw new Error("<xul:browser> needs to be remote in order to crash"); @@ -938,11 +935,7 @@ this.BrowserTestUtils = { extrafile.append(dumpID + '.extra'); if (extrafile.exists()) { dump(`\nNo .extra file for dumpID: ${dumpID}\n`); - if (AppConstants.MOZ_CRASHREPORTER) { - extra = KeyValueParser.parseKeyValuePairsFromFile(extrafile); - } else { - dump('\nCrashReporter not enabled - will not return any extra data\n'); - } + dump('\nWill not return any extra data\n'); } removeFile(minidumpDirectory, dumpID + '.dmp'); diff --git a/testing/mozbase/mozrunner/mozrunner/base/browser.py b/testing/mozbase/mozrunner/mozrunner/base/browser.py index 998e4ccc5..6fc7348d5 100644 --- a/testing/mozbase/mozrunner/mozrunner/base/browser.py +++ b/testing/mozbase/mozrunner/mozrunner/base/browser.py @@ -75,6 +75,5 @@ class GeckoRuntimeRunner(BaseRunner): if not self.show_crash_reporter: # hide the crash reporter window self.env["MOZ_CRASHREPORTER_NO_REPORT"] = "1" - self.env["MOZ_CRASHREPORTER"] = "1" BaseRunner.start(self, *args, **kwargs) diff --git a/testing/mozbase/mozrunner/mozrunner/base/device.py b/testing/mozbase/mozrunner/mozrunner/base/device.py index 2252203d1..6eeef042f 100644 --- a/testing/mozbase/mozrunner/mozrunner/base/device.py +++ b/testing/mozbase/mozrunner/mozrunner/base/device.py @@ -22,8 +22,7 @@ class DeviceRunner(BaseRunner): The base runner class used for running gecko on remote devices (or emulators), such as B2G. """ - env = {'MOZ_CRASHREPORTER': '1', - 'MOZ_CRASHREPORTER_NO_REPORT': '1', + env = {'MOZ_CRASHREPORTER_NO_REPORT': '1', 'MOZ_CRASHREPORTER_SHUTDOWN': '1', 'MOZ_HIDE_RESULTS_TABLE': '1', 'MOZ_LOG': 'signaling:3,mtransport:4,DataChannel:4,jsep:4,MediaPipelineFactory:4', diff --git a/testing/mozbase/mozrunner/mozrunner/utils.py b/testing/mozbase/mozrunner/mozrunner/utils.py index f96c94398..79f26b8f2 100755 --- a/testing/mozbase/mozrunner/mozrunner/utils.py +++ b/testing/mozbase/mozrunner/mozrunner/utils.py @@ -132,7 +132,6 @@ def test_environment(xrePath, env=None, crashreporter=True, debugger=False, if crashreporter and not debugger: env['MOZ_CRASHREPORTER_NO_REPORT'] = '1' - env['MOZ_CRASHREPORTER'] = '1' else: env['MOZ_CRASHREPORTER_DISABLE'] = '1' diff --git a/testing/runcppunittests.py b/testing/runcppunittests.py index d8b79f68f..fdd6abc1f 100755 --- a/testing/runcppunittests.py +++ b/testing/runcppunittests.py @@ -90,7 +90,6 @@ class CPPUnitTests(object): # been fixed to enable crash reporting env["XPCOM_DEBUG_BREAK"] = "stack-and-abort" env["MOZ_CRASHREPORTER_NO_REPORT"] = "1" - env["MOZ_CRASHREPORTER"] = "1" return env def build_environment(self): diff --git a/testing/talos/talos/ffsetup.py b/testing/talos/talos/ffsetup.py index 22a9dea07..14ff576d5 100644 --- a/testing/talos/talos/ffsetup.py +++ b/testing/talos/talos/ffsetup.py @@ -67,10 +67,7 @@ class FFSetup(object): # for winxp e10s logging: # https://bugzilla.mozilla.org/show_bug.cgi?id=1037445 self.env['MOZ_WIN_INHERIT_STD_HANDLES_PRE_VISTA'] = '1' - if self.browser_config['symbols_path']: - self.env['MOZ_CRASHREPORTER'] = '1' - else: - self.env['MOZ_CRASHREPORTER_DISABLE'] = '1' + self.env['MOZ_CRASHREPORTER_DISABLE'] = '1' self.env['MOZ_DISABLE_NONLOCAL_CONNECTIONS'] = '1' diff --git a/testing/web-platform/meta/fetch/nosniff/worker.html.ini b/testing/web-platform/meta/fetch/nosniff/worker.html.ini deleted file mode 100644 index 011ad15b8..000000000 --- a/testing/web-platform/meta/fetch/nosniff/worker.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[worker.html] - type: testharness - expected: ERROR diff --git a/testing/web-platform/tests/fetch/nosniff/script.html b/testing/web-platform/tests/fetch/nosniff/script.html index 667f3c99a..c5c5167f5 100644 --- a/testing/web-platform/tests/fetch/nosniff/script.html +++ b/testing/web-platform/tests/fetch/nosniff/script.html @@ -4,8 +4,8 @@ <script> var log = function() {}, // see comment below p = function() {}, // see comment below - fails = ["", "?type=", "?type=x", "?type=x/x"], - passes = ["?type=text/javascript", "?type=text/ecmascript", "?type=text/ecmascript;blah"] + fails = ["", "?type=", "?type=x", "?type=x/x", "?type=text/json"], + passes = ["?type=text/javascript", "?type=text/ecmascript", "?type=text/ecmascript;blah", "?type=text/javascript1.0"] // Ideally we'd also check whether the scripts in fact execute, but that would involve // timers and might get a bit racy without cross-browser support for the execute events. diff --git a/testing/web-platform/tests/workers/Worker_cross_origin_security_err.htm b/testing/web-platform/tests/workers/Worker_cross_origin_security_err.htm index 647a8b81e..d57dc29d5 100644 --- a/testing/web-platform/tests/workers/Worker_cross_origin_security_err.htm +++ b/testing/web-platform/tests/workers/Worker_cross_origin_security_err.htm @@ -8,7 +8,7 @@ async_test(function(t) { try { var w = new Worker("ftp://example.org/support/WorkerBasic.js"); w.onerror = t.step_func_done(function(e) { - assert_true(e instanceof ErrorEvent); + assert_true(e instanceof Event); }); } catch (e) { t.step_func_done(function(e) { assert_true(true); }); diff --git a/testing/web-platform/tests/workers/constructors/SharedWorker/same-origin.html b/testing/web-platform/tests/workers/constructors/SharedWorker/same-origin.html index 2e0dd8db3..78d53164e 100644 --- a/testing/web-platform/tests/workers/constructors/SharedWorker/same-origin.html +++ b/testing/web-platform/tests/workers/constructors/SharedWorker/same-origin.html @@ -16,7 +16,7 @@ function testSharedWorkerHelper(t, script) { try { var worker = new SharedWorker(script, ''); worker.onerror = t.step_func_done(function(e) { - assert_true(e instanceof ErrorEvent); + assert_true(e instanceof Event); }); } catch (e) { t.step_func_done(function(e) { assert_true(true); }); diff --git a/testing/web-platform/tests/workers/constructors/Worker/same-origin.html b/testing/web-platform/tests/workers/constructors/Worker/same-origin.html index 9b0148da3..bbc4382d0 100644 --- a/testing/web-platform/tests/workers/constructors/Worker/same-origin.html +++ b/testing/web-platform/tests/workers/constructors/Worker/same-origin.html @@ -14,7 +14,7 @@ function testSharedWorkerHelper(t, script) { try { var worker = new SharedWorker(script, ''); worker.onerror = t.step_func_done(function(e) { - assert_true(e instanceof ErrorEvent); + assert_true(e instanceof Event); }); } catch (e) { t.step_func_done(function(e) { assert_true(true); }); diff --git a/testing/xpcshell/head.js b/testing/xpcshell/head.js index 74fd482cf..e204a4512 100644 --- a/testing/xpcshell/head.js +++ b/testing/xpcshell/head.js @@ -95,23 +95,6 @@ try { } catch (e) { } -// Configure crash reporting, if possible -// We rely on the Python harness to set MOZ_CRASHREPORTER, -// MOZ_CRASHREPORTER_NO_REPORT, and handle checking for minidumps. -// Note that if we're in a child process, we don't want to init the -// crashreporter component. -try { - if (runningInParent && - "@mozilla.org/toolkit/crash-reporter;1" in Components.classes) { - let crashReporter = - Components.classes["@mozilla.org/toolkit/crash-reporter;1"] - .getService(Components.interfaces.nsICrashReporter); - crashReporter.UpdateCrashEventsDir(); - crashReporter.minidumpPath = do_get_minidumpdir(); - } -} -catch (e) { } - // Configure a console listener so messages sent to it are logged as part // of the test. try { diff --git a/testing/xpcshell/runxpcshelltests.py b/testing/xpcshell/runxpcshelltests.py index 7c88343dc..34af6639f 100755 --- a/testing/xpcshell/runxpcshelltests.py +++ b/testing/xpcshell/runxpcshelltests.py @@ -910,9 +910,6 @@ class XPCShellTests(object): """ # Make assertions fatal self.env["XPCOM_DEBUG_BREAK"] = "stack-and-abort" - # Crash reporting interferes with debugging - if not self.debuggerInfo: - self.env["MOZ_CRASHREPORTER"] = "1" # Don't launch the crash reporter client self.env["MOZ_CRASHREPORTER_NO_REPORT"] = "1" # Don't permit remote connections by default. diff --git a/toolkit/components/alerts/resources/content/alert.css b/toolkit/components/alerts/resources/content/alert.css index c4d94a543..81e5cdd35 100644 --- a/toolkit/components/alerts/resources/content/alert.css +++ b/toolkit/components/alerts/resources/content/alert.css @@ -3,7 +3,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #alertBox[animate] { - animation-duration: 20s; animation-fill-mode: both; animation-name: alert-animation; } diff --git a/toolkit/components/alerts/resources/content/alert.js b/toolkit/components/alerts/resources/content/alert.js index ead4d503f..ce60ab0fa 100644 --- a/toolkit/components/alerts/resources/content/alert.js +++ b/toolkit/components/alerts/resources/content/alert.js @@ -166,7 +166,12 @@ function prefillAlertInfo() { } function onAlertLoad() { - const ALERT_DURATION_IMMEDIATE = 20000; + const ALERT_DURATION_IMMEDIATE_MIN = 4000; + const ALERT_DURATION_IMMEDIATE_MAX = 60000; + let alertDurationImmediate = Services.prefs.getIntPref("alerts.durationImmediate", ALERT_DURATION_IMMEDIATE_MIN); + alertDurationImmediate = alertDurationImmediate >= ALERT_DURATION_IMMEDIATE_MIN + && alertDurationImmediate <= ALERT_DURATION_IMMEDIATE_MAX + ? alertDurationImmediate : ALERT_DURATION_IMMEDIATE_MIN; let alertTextBox = document.getElementById("alertTextBox"); let alertImageBox = document.getElementById("alertImageBox"); alertImageBox.style.minHeight = alertTextBox.scrollHeight + "px"; @@ -186,7 +191,7 @@ function onAlertLoad() { // If the require interaction flag is set, prevent auto-closing the notification. if (!gRequireInteraction) { if (Services.prefs.getBoolPref("alerts.disableSlidingEffect")) { - setTimeout(function() { window.close(); }, ALERT_DURATION_IMMEDIATE); + setTimeout(function() { window.close(); }, alertDurationImmediate); } else { let alertBox = document.getElementById("alertBox"); alertBox.addEventListener("animationend", function hideAlert(event) { @@ -197,6 +202,7 @@ function onAlertLoad() { window.close(); } }, false); + alertBox.style.animationDuration = Math.round(alertDurationImmediate / 1000).toString() + "s"; alertBox.setAttribute("animate", true); } } diff --git a/toolkit/components/moz.build b/toolkit/components/moz.build index 12e1748e9..5dba09a32 100644 --- a/toolkit/components/moz.build +++ b/toolkit/components/moz.build @@ -79,9 +79,6 @@ if not CONFIG['MOZ_FENNEC']: if CONFIG['NS_PRINTING']: DIRS += ['printing'] -if CONFIG['MOZ_CRASHREPORTER']: - DIRS += ['crashes'] - if CONFIG['BUILD_CTYPES']: DIRS += ['ctypes'] diff --git a/toolkit/components/passwordmgr/content/passwordManager.js b/toolkit/components/passwordmgr/content/passwordManager.js index 333dc1d24..3fccb5d30 100644 --- a/toolkit/components/passwordmgr/content/passwordManager.js +++ b/toolkit/components/passwordmgr/content/passwordManager.js @@ -721,8 +721,10 @@ function escapeKeyHandler() { window.close(); } +#if defined(MC_BASILISK) && defined(XP_WIN) function OpenMigrator() { const { MigrationUtils } = Cu.import("resource:///modules/MigrationUtils.jsm", {}); // We pass in the type of source we're using for use in telemetry: MigrationUtils.showMigrationWizard(window, [MigrationUtils.MIGRATION_ENTRYPOINT_PASSWORDS]); } +#endif diff --git a/toolkit/components/passwordmgr/content/passwordManager.xul b/toolkit/components/passwordmgr/content/passwordManager.xul index d248283b6..78dbd7ebc 100644 --- a/toolkit/components/passwordmgr/content/passwordManager.xul +++ b/toolkit/components/passwordmgr/content/passwordManager.xul @@ -113,7 +113,7 @@ label="&removeall.label;" accesskey="&removeall.accesskey;" oncommand="DeleteAllSignons();"/> <spacer flex="1"/> -#if defined(MOZ_BUILD_APP_IS_BROWSER) && defined(XP_WIN) +#if defined(MC_BASILISK) && defined(XP_WIN) <button accesskey="&import.accesskey;" label="&import.label;" oncommand="OpenMigrator();"/> diff --git a/toolkit/components/passwordmgr/jar.mn b/toolkit/components/passwordmgr/jar.mn index 9fa574e49..db6d7ffef 100644 --- a/toolkit/components/passwordmgr/jar.mn +++ b/toolkit/components/passwordmgr/jar.mn @@ -5,5 +5,5 @@ toolkit.jar: % content passwordmgr %content/passwordmgr/ * content/passwordmgr/passwordManager.xul (content/passwordManager.xul) - content/passwordmgr/passwordManager.js (content/passwordManager.js) +* content/passwordmgr/passwordManager.js (content/passwordManager.js) content/passwordmgr/recipes.json (content/recipes.json) diff --git a/toolkit/components/passwordmgr/nsLoginManagerPrompter.js b/toolkit/components/passwordmgr/nsLoginManagerPrompter.js index b66489234..720e80446 100644 --- a/toolkit/components/passwordmgr/nsLoginManagerPrompter.js +++ b/toolkit/components/passwordmgr/nsLoginManagerPrompter.js @@ -808,6 +808,9 @@ LoginManagerPrompter.prototype = { */ _showLoginCaptureDoorhanger(login, type) { let { browser } = this._getNotifyWindow(); + if (!browser) { + return; + } let saveMsgNames = { prompt: login.username === "" ? "rememberLoginMsgNoUser" @@ -1405,10 +1408,34 @@ LoginManagerPrompter.prototype = { * Given a content DOM window, returns the chrome window and browser it's in. */ _getChromeWindow: function (aWindow) { + // Handle non-e10s toolkit consumers. + if (!Cu.isCrossProcessWrapper(aWindow)) { + let chromeWin = aWindow.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShell) + .chromeEventHandler.ownerGlobal; + if (!chromeWin) { + return null; + } + + // gBrowser only exists on some apps, like Firefox. + let tabbrowser = chromeWin.gBrowser || + (typeof chromeWin.getBrowser == "function" ? chromeWin.getBrowser() : null); + // At least serve the chrome window if getBrowser() + // or getBrowserForContentWindow() are not supported. + if (!tabbrowser || typeof tabbrowser.getBrowserForContentWindow != "function") { + return { win: chromeWin }; + } + + let browser = tabbrowser.getBrowserForContentWindow(aWindow); + return { win: chromeWin, browser }; + } + let windows = Services.wm.getEnumerator(null); while (windows.hasMoreElements()) { let win = windows.getNext(); - let browser = win.gBrowser.getBrowserForContentWindow(aWindow); + let tabbrowser = win.gBrowser || win.getBrowser(); + let browser = tabbrowser.getBrowserForContentWindow(aWindow); if (browser) { return { win, browser }; } diff --git a/toolkit/components/places/tests/cpp/places_test_harness_tail.h b/toolkit/components/places/tests/cpp/places_test_harness_tail.h index 4bbd45ccb..9e57c3724 100644 --- a/toolkit/components/places/tests/cpp/places_test_harness_tail.h +++ b/toolkit/components/places/tests/cpp/places_test_harness_tail.h @@ -6,9 +6,6 @@ #include "nsWidgetsCID.h" #include "nsIComponentRegistrar.h" -#ifdef MOZ_CRASHREPORTER -#include "nsICrashReporter.h" -#endif #ifndef TEST_NAME #error "Must #define TEST_NAME before including places_test_harness_tail.h" @@ -94,32 +91,6 @@ main(int aArgc, return -1; } -#ifdef MOZ_CRASHREPORTER - char* enabled = PR_GetEnv("MOZ_CRASHREPORTER"); - if (enabled && !strcmp(enabled, "1")) { - // bug 787458: move this to an even-more-common location to use in all - // C++ unittests - nsCOMPtr<nsICrashReporter> crashreporter = - do_GetService("@mozilla.org/toolkit/crash-reporter;1"); - if (crashreporter) { - fprintf(stderr, "Setting up crash reporting\n"); - - nsCOMPtr<nsIProperties> dirsvc = - do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID); - if (!dirsvc) - NS_RUNTIMEABORT("Couldn't get directory service"); - nsCOMPtr<nsIFile> cwd; - nsresult rv = dirsvc->Get(NS_OS_CURRENT_WORKING_DIR, - NS_GET_IID(nsIFile), - getter_AddRefs(cwd)); - if (NS_FAILED(rv)) - NS_RUNTIMEABORT("Couldn't get CWD"); - crashreporter->SetEnabled(true); - crashreporter->SetMinidumpPath(cwd); - } - } -#endif - RefPtr<WaitForConnectionClosed> spinClose = new WaitForConnectionClosed(); // Tinderboxes are constantly on idle. Since idle tasks can interact with diff --git a/toolkit/components/protobuf/moz.build b/toolkit/components/protobuf/moz.build index b5015eb67..8cca3514c 100644 --- a/toolkit/components/protobuf/moz.build +++ b/toolkit/components/protobuf/moz.build @@ -117,10 +117,13 @@ DEFINES['GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER'] = True # Suppress warnings in third-party code. if CONFIG['GNU_CXX']: CXXFLAGS += [ - '-Wno-null-conversion', '-Wno-return-type', '-Wno-sign-compare', ] + if CONFIG['CLANG_CXX']: + CXXFLAGS += [ + '-Wno-null-conversion', + ] elif CONFIG['_MSC_VER']: CXXFLAGS += [ '-wd4005', # 'WIN32_LEAN_AND_MEAN' : macro redefinition diff --git a/toolkit/components/telemetry/TelemetryEnvironment.jsm b/toolkit/components/telemetry/TelemetryEnvironment.jsm index 2f4ac81ba..910d804ae 100644 --- a/toolkit/components/telemetry/TelemetryEnvironment.jsm +++ b/toolkit/components/telemetry/TelemetryEnvironment.jsm @@ -153,7 +153,6 @@ const DEFAULT_ENVIRONMENT_PREFS = new Map([ ["dom.ipc.plugins.enabled", {what: RECORD_PREF_VALUE}], ["dom.ipc.processCount", {what: RECORD_PREF_VALUE, requiresRestart: true}], ["dom.max_script_run_time", {what: RECORD_PREF_VALUE}], - ["experiments.manifest.uri", {what: RECORD_PREF_VALUE}], ["extensions.autoDisableScopes", {what: RECORD_PREF_VALUE}], ["extensions.enabledScopes", {what: RECORD_PREF_VALUE}], ["extensions.blocklist.enabled", {what: RECORD_PREF_VALUE}], @@ -209,7 +208,6 @@ const PREF_E10S_COHORT = "e10s.rollout.cohort"; const COMPOSITOR_CREATED_TOPIC = "compositor:created"; const DISTRIBUTION_CUSTOMIZATION_COMPLETE_TOPIC = "distribution-customization-complete"; -const EXPERIMENTS_CHANGED_TOPIC = "experiments-changed"; const GFX_FEATURES_READY_TOPIC = "gfx-features-ready"; const SEARCH_ENGINE_MODIFIED_TOPIC = "browser-search-engine-modified"; const SEARCH_SERVICE_TOPIC = "browser-search-service"; @@ -465,7 +463,6 @@ EnvironmentAddonBuilder.prototype = { watchForChanges: function() { this._loaded = true; AddonManager.addAddonListener(this); - Services.obs.addObserver(this, EXPERIMENTS_CHANGED_TOPIC, false); }, // AddonListener @@ -490,7 +487,6 @@ EnvironmentAddonBuilder.prototype = { // nsIObserver observe: function (aSubject, aTopic, aData) { this._environment._log.trace("observe - Topic " + aTopic); - this._checkForChanges("experiment-changed"); }, _checkForChanges: function(changeReason) { @@ -515,7 +511,6 @@ EnvironmentAddonBuilder.prototype = { _shutdownBlocker: function() { if (this._loaded) { AddonManager.removeAddonListener(this); - Services.obs.removeObserver(this, EXPERIMENTS_CHANGED_TOPIC); } return this._pendingTask; }, @@ -545,7 +540,6 @@ EnvironmentAddonBuilder.prototype = { theme: yield this._getActiveTheme(), activePlugins: this._getActivePlugins(), activeGMPlugins: yield this._getActiveGMPlugins(), - activeExperiment: this._getActiveExperiment(), persona: personaId, }; @@ -718,29 +712,7 @@ EnvironmentAddonBuilder.prototype = { } return activeGMPlugins; - }), - - /** - * Get the active experiment data in object form. - * @return Object containing the active experiment data. - */ - _getActiveExperiment: function () { - let experimentInfo = {}; - try { - let scope = {}; - Cu.import("resource:///modules/experiments/Experiments.jsm", scope); - let experiments = scope.Experiments.instance(); - let activeExperiment = experiments.getActiveExperimentID(); - if (activeExperiment) { - experimentInfo.id = activeExperiment; - experimentInfo.branch = experiments.getActiveExperimentBranch(); - } - } catch (e) { - // If this is not Firefox, the import will fail. - } - - return experimentInfo; - }, + }) }; function EnvironmentCache() { diff --git a/toolkit/components/terminator/nsTerminator.cpp b/toolkit/components/terminator/nsTerminator.cpp index f9459cc5d..91e872821 100644 --- a/toolkit/components/terminator/nsTerminator.cpp +++ b/toolkit/components/terminator/nsTerminator.cpp @@ -29,9 +29,6 @@ #include "nsIObserverService.h" #include "nsIPrefService.h" -#if defined(MOZ_CRASHREPORTER) -#include "nsExceptionHandler.h" -#endif #if defined(XP_WIN) #include <windows.h> @@ -541,13 +538,7 @@ nsTerminator::UpdateTelemetry() void nsTerminator::UpdateCrashReport(const char* aTopic) { -#if defined(MOZ_CRASHREPORTER) - // In case of crash, we wish to know where in shutdown we are - nsAutoCString report(aTopic); - - Unused << CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ShutdownProgress"), - report); -#endif // defined(MOZ_CRASH_REPORTER) + /*** STUB ***/ } diff --git a/toolkit/content/aboutSupport.js b/toolkit/content/aboutSupport.js index 5daf6d189..e66095e20 100644 --- a/toolkit/content/aboutSupport.js +++ b/toolkit/content/aboutSupport.js @@ -75,69 +75,7 @@ var snapshotFormatters = { }, crashes: function crashes(data) { - if (!AppConstants.MOZ_CRASHREPORTER) - return; - - let strings = stringBundle(); - let daysRange = Troubleshoot.kMaxCrashAge / (24 * 60 * 60 * 1000); - $("crashes-title").textContent = - PluralForm.get(daysRange, strings.GetStringFromName("crashesTitle")) - .replace("#1", daysRange); - let reportURL; - try { - reportURL = Services.prefs.getCharPref("breakpad.reportURL"); - // Ignore any non http/https urls - if (!/^https?:/i.test(reportURL)) - reportURL = null; - } - catch (e) { } - if (!reportURL) { - $("crashes-noConfig").style.display = "block"; - $("crashes-noConfig").classList.remove("no-copy"); - return; - } - $("crashes-allReports").style.display = "block"; - $("crashes-allReports").classList.remove("no-copy"); - - if (data.pending > 0) { - $("crashes-allReportsWithPending").textContent = - PluralForm.get(data.pending, strings.GetStringFromName("pendingReports")) - .replace("#1", data.pending); - } - - let dateNow = new Date(); - $.append($("crashes-tbody"), data.submitted.map(function (crash) { - let date = new Date(crash.date); - let timePassed = dateNow - date; - let formattedDate; - if (timePassed >= 24 * 60 * 60 * 1000) - { - let daysPassed = Math.round(timePassed / (24 * 60 * 60 * 1000)); - let daysPassedString = strings.GetStringFromName("crashesTimeDays"); - formattedDate = PluralForm.get(daysPassed, daysPassedString) - .replace("#1", daysPassed); - } - else if (timePassed >= 60 * 60 * 1000) - { - let hoursPassed = Math.round(timePassed / (60 * 60 * 1000)); - let hoursPassedString = strings.GetStringFromName("crashesTimeHours"); - formattedDate = PluralForm.get(hoursPassed, hoursPassedString) - .replace("#1", hoursPassed); - } - else - { - let minutesPassed = Math.max(Math.round(timePassed / (60 * 1000)), 1); - let minutesPassedString = strings.GetStringFromName("crashesTimeMinutes"); - formattedDate = PluralForm.get(minutesPassed, minutesPassedString) - .replace("#1", minutesPassed); - } - return $.new("tr", [ - $.new("td", [ - $.new("a", crash.id, null, {href : reportURL + crash.id}) - ]), - $.new("td", formattedDate) - ]); - })); + return; }, extensions: function extensions(data) { @@ -151,22 +89,6 @@ var snapshotFormatters = { })); }, - experiments: function experiments(data) { - $.append($("experiments-tbody"), data.map(function (experiment) { - return $.new("tr", [ - $.new("td", experiment.name), - $.new("td", experiment.id), - $.new("td", experiment.description), - $.new("td", experiment.active), - $.new("td", experiment.endDate), - $.new("td", [ - $.new("a", experiment.detailURL, null, {href : experiment.detailURL, }) - ]), - $.new("td", experiment.branch), - ]); - })); - }, - modifiedPreferences: function modifiedPreferences(data) { $.append($("prefs-tbody"), sortedArrayFromObject(data).map( function ([name, value]) { diff --git a/toolkit/content/aboutSupport.xhtml b/toolkit/content/aboutSupport.xhtml index e2885c8b8..8464e014b 100644 --- a/toolkit/content/aboutSupport.xhtml +++ b/toolkit/content/aboutSupport.xhtml @@ -253,34 +253,6 @@ </table> <!-- - - - - - - - - - - - - - - - - - - - - --> -#ifdef MOZ_CRASHREPORTER - - <h2 class="major-section" id="crashes-title"> - &aboutSupport.crashes.title; - </h2> - - <table id="crashes-table"> - <thead> - <tr> - <th> - &aboutSupport.crashes.id; - </th> - <th> - &aboutSupport.crashes.sendDate; - </th> - </tr> - </thead> - <tbody id="crashes-tbody"> - </tbody> - </table> - <p id="crashes-allReports" class="hidden no-copy"> - <a href="about:crashes" id="crashes-allReportsWithPending" class="block">&aboutSupport.crashes.allReports;</a> - </p> - <p id="crashes-noConfig" class="hidden no-copy">&aboutSupport.crashes.noConfig;</p> - -#endif - <!-- - - - - - - - - - - - - - - - - - - - - --> - <h2 class="major-section"> &aboutSupport.extensionsTitle; </h2> @@ -504,39 +476,6 @@ </table> - <h2 class="major-section"> - &aboutSupport.experimentsTitle; - </h2> - - <table> - <thead> - <tr> - <th> - &aboutSupport.experimentName; - </th> - <th> - &aboutSupport.experimentId; - </th> - <th> - &aboutSupport.experimentDescription; - </th> - <th> - &aboutSupport.experimentActive; - </th> - <th> - &aboutSupport.experimentEndDate; - </th> - <th> - &aboutSupport.experimentHomepage; - </th> - <th> - &aboutSupport.experimentBranch; - </th> - </tr> - </thead> - <tbody id="experiments-tbody"> - </tbody> - </table> <!-- - - - - - - - - - - - - - - - - - - - - --> #if defined(MOZ_SANDBOX) diff --git a/toolkit/content/browser-child.js b/toolkit/content/browser-child.js index c819e3db6..7d0fe18c5 100644 --- a/toolkit/content/browser-child.js +++ b/toolkit/content/browser-child.js @@ -17,12 +17,6 @@ Cu.import("resource://gre/modules/Timer.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "PageThumbUtils", "resource://gre/modules/PageThumbUtils.jsm"); -if (AppConstants.MOZ_CRASHREPORTER) { - XPCOMUtils.defineLazyServiceGetter(this, "CrashReporter", - "@mozilla.org/xre/app-info;1", - "nsICrashReporter"); -} - function makeInputStream(aString) { let stream = Cc["@mozilla.org/io/string-input-stream;1"]. createInstance(Ci.nsISupportsCString); @@ -174,15 +168,6 @@ var WebProgressListener = { json.principal = content.document.nodePrincipal; json.synthetic = content.document.mozSyntheticDocument; json.inLoadURI = WebNavigation.inLoadURI; - - if (AppConstants.MOZ_CRASHREPORTER && CrashReporter.enabled) { - let uri = aLocationURI.clone(); - try { - // If the current URI contains a username/password, remove it. - uri.userPass = ""; - } catch (ex) { /* Ignore failures on about: URIs. */ } - CrashReporter.annotateCrashReport("URL", uri.spec); - } } this._send("Content:LocationChange", json, objects); @@ -310,17 +295,6 @@ var WebNavigation = { }, loadURI: function(uri, flags, referrer, referrerPolicy, postData, headers, baseURI) { - if (AppConstants.MOZ_CRASHREPORTER && CrashReporter.enabled) { - let annotation = uri; - try { - let url = Services.io.newURI(uri, null, null); - // If the current URI contains a username/password, remove it. - url.userPass = ""; - annotation = url.spec; - } catch (ex) { /* Ignore failures to parse and failures - on about: URIs. */ } - CrashReporter.annotateCrashReport("URL", annotation); - } if (referrer) referrer = Services.io.newURI(referrer, null, null); if (postData) diff --git a/toolkit/content/jar.mn b/toolkit/content/jar.mn index f1a222a58..f9ac19a24 100644 --- a/toolkit/content/jar.mn +++ b/toolkit/content/jar.mn @@ -28,7 +28,7 @@ toolkit.jar: content/global/aboutwebrtc/aboutWebrtc.css (aboutwebrtc/aboutWebrtc.css) content/global/aboutwebrtc/aboutWebrtc.js (aboutwebrtc/aboutWebrtc.js) content/global/aboutwebrtc/aboutWebrtc.html (aboutwebrtc/aboutWebrtc.html) - content/global/aboutSupport.js +* content/global/aboutSupport.js * content/global/aboutSupport.xhtml content/global/aboutTelemetry.js content/global/aboutTelemetry.xhtml @@ -54,8 +54,12 @@ toolkit.jar: #endif content/global/filepicker.properties content/global/globalOverlay.js + content/global/memoriam.xhtml +* content/global/mozilla.css content/global/mozilla.xhtml +#ifdef MOZ_PHOENIX content/global/logopage.xhtml +#endif content/global/process-content.js content/global/resetProfile.css content/global/resetProfile.js diff --git a/toolkit/content/memoriam.xhtml b/toolkit/content/memoriam.xhtml new file mode 100644 index 000000000..f1a1b474d --- /dev/null +++ b/toolkit/content/memoriam.xhtml @@ -0,0 +1,76 @@ +<!DOCTYPE html +[ + <!ENTITY % directionDTD SYSTEM "chrome://global/locale/global.dtd" > + %directionDTD; + <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd"> + %brandDTD; +]> + +<!-- 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/. --> + +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <meta charset='utf-8' /> + <title>Mozilla: In Memoriam</title> + +<style> +html { + background: maroon radial-gradient( circle, #a01010 0%, #800000 80%) center center / cover no-repeat; + color: white; + font-style: italic; + text-rendering: optimizeLegibility; + min-height: 100%; +} + +#moztext { + margin-top: 15%; + font-size: 1.1em; + font-family: serif; + text-align: center; + line-height: 1.5; +} + +#from { + font-size: 1.0em; + font-family: serif; + text-align: right; +} + +em { + font-size: 1.3em; + line-height: 0; +} + +a { + text-decoration: none; + color: white; +} +</style> +</head> + +<body dir="&locale.dir;"> + +<section> + <p id="moztext"> + <h1>Mozilla: In Memoriam</h1> + <br/> + Dedicated to the tireless developers who have come and gone.<br/> + To those who have put their heart and soul into Mozilla products.<br/> + To those who have seen their good intentions and hard work squandered.<br/> + To those who really cared about the user, and cared about usability.<br/> + To those who truly understood us and desired freedom, but were unheard.<br/> + To those who knew that change is inevitable, but loss of vision is not.<br/> + To those who were forced to give up the good fight.<br/> + <br/> + <em>Thank you.</em> &brandFullName; would not have been possible without you.<br/> + <br/> + </p> + + <p id="from"> + </p> +</section> + +</body> +</html>
\ No newline at end of file diff --git a/toolkit/content/mozilla.css b/toolkit/content/mozilla.css new file mode 100644 index 000000000..d5eae6415 --- /dev/null +++ b/toolkit/content/mozilla.css @@ -0,0 +1,36 @@ +html { +%ifdef MC_PALEMOON + background: #333399 radial-gradient( circle at 75% 25%, #6666b0 0%, #333399 40%, #111177 80%) center center / cover no-repeat; +%else + background: maroon radial-gradient( circle, #a01010 0%, #800000 80%) center center / cover no-repeat; +%endif + + color: white; + font-style: italic; + text-rendering: optimizeLegibility; + min-height: 100%; +} + +#moztext { + margin-top: 15%; + font-size: 1.1em; + font-family: serif; + text-align: center; + line-height: 1.5; +} + +#from { + font-size: 1.95em; + font-family: serif; + text-align: right; +} + +em { + font-size: 1.3em; + line-height: 0; +} + +a { + text-decoration: none; + color: white; +}
\ No newline at end of file diff --git a/toolkit/content/mozilla.xhtml b/toolkit/content/mozilla.xhtml index 2acfc9f5d..8c79b5ff9 100644 --- a/toolkit/content/mozilla.xhtml +++ b/toolkit/content/mozilla.xhtml @@ -15,39 +15,8 @@ <meta charset='utf-8' /> <title>&chronicles.title.55.2;</title> -<style> -html { - background: maroon radial-gradient( circle, #a01010 0%, #800000 80%) center center / cover no-repeat; - color: white; - font-style: italic; - text-rendering: optimizeLegibility; - min-height: 100%; -} - -#moztext { - margin-top: 15%; - font-size: 1.1em; - font-family: serif; - text-align: center; - line-height: 1.5; -} - -#from { - font-size: 1.95em; - font-family: serif; - text-align: right; -} - -em { - font-size: 1.3em; - line-height: 0; -} - -a { - text-decoration: none; - color: white; -} -</style> + <link rel="stylesheet" href="chrome://global/content/mozilla.css" + type="text/css"/> </head> <body dir="&locale.dir;"> diff --git a/toolkit/content/plugins.html b/toolkit/content/plugins.html index 84cbba596..d389f52dd 100644 --- a/toolkit/content/plugins.html +++ b/toolkit/content/plugins.html @@ -10,6 +10,7 @@ "use strict"; Components.utils.import("resource://gre/modules/Services.jsm"); + Components.utils.import("resource://gre/modules/AddonManager.jsm"); var Ci = Components.interfaces; var strBundleService = Components.classes["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsIStringBundleService); @@ -57,7 +58,7 @@ */ navigator.plugins.refresh(false); - addMessageListener("PluginList", function({ data: aPlugins }) { + AddonManager.getAddonsByTypes(["plugin"], function (aPlugins) { var fragment = document.createDocumentFragment(); // "Installed plugins" @@ -209,8 +210,6 @@ document.getElementById("outside").appendChild(fragment); }); - - sendAsyncMessage("RequestPlugins"); </script> </div> </body> diff --git a/toolkit/locales/Makefile.in b/toolkit/locales/Makefile.in index e20128611..189e0b1b0 100644 --- a/toolkit/locales/Makefile.in +++ b/toolkit/locales/Makefile.in @@ -30,11 +30,3 @@ chrome-%: libs:: update.locale sed -e 's/%AB_CD%/$(AB_CD)/' $< > $(FINAL_TARGET)/update.locale -ifdef MOZ_CRASHREPORTER -libs:: crashreporter.ini -ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) - $(SYSINSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)/crashreporter.app/Contents/Resources -else - $(SYSINSTALL) $(IFLAGS1) $^ $(FINAL_TARGET) -endif -endif diff --git a/toolkit/locales/en-US/chrome/places/places.properties b/toolkit/locales/en-US/chrome/places/places.properties index f9edeeff0..5c0134180 100644 --- a/toolkit/locales/en-US/chrome/places/places.properties +++ b/toolkit/locales/en-US/chrome/places/places.properties @@ -4,6 +4,7 @@ BookmarksMenuFolderTitle=Bookmarks Menu BookmarksToolbarFolderTitle=Bookmarks Toolbar +UnsortedBookmarksFolderTitle=Unsorted Bookmarks OtherBookmarksFolderTitle=Other Bookmarks TagsFolderTitle=Tags MobileBookmarksFolderTitle=Mobile Bookmarks diff --git a/toolkit/locales/l10n.mk b/toolkit/locales/l10n.mk index 34d78d33c..05bda0b56 100644 --- a/toolkit/locales/l10n.mk +++ b/toolkit/locales/l10n.mk @@ -120,14 +120,6 @@ ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) ifneq (en,$(LPROJ_ROOT)) mv $(STAGEDIST)/en.lproj $(STAGEDIST)/$(LPROJ_ROOT).lproj endif -ifdef MOZ_CRASHREPORTER -# On Mac OS X, the crashreporter.ini file needs to be moved from under the -# application bundle's Resources directory where all other l10n files are -# located to the crash reporter bundle's Resources directory. - mv $(STAGEDIST)/crashreporter.app/Contents/Resources/crashreporter.ini \ - $(STAGEDIST)/../MacOS/crashreporter.app/Contents/Resources/crashreporter.ini - $(RM) -rf $(STAGEDIST)/crashreporter.app -endif endif $(NSINSTALL) -D $(DIST)/l10n-stage/$(PKG_PATH) diff --git a/toolkit/modules/AppConstants.jsm b/toolkit/modules/AppConstants.jsm index ba5d82c01..93acea0ec 100644 --- a/toolkit/modules/AppConstants.jsm +++ b/toolkit/modules/AppConstants.jsm @@ -183,13 +183,6 @@ this.AppConstants = Object.freeze({ Services.vc.compare(platformVersion, version) <= 0; }, - MOZ_CRASHREPORTER: -#ifdef MOZ_CRASHREPORTER - true, -#else - false, -#endif - MOZ_VERIFY_MAR_SIGNATURE: #ifdef MOZ_VERIFY_MAR_SIGNATURE true, diff --git a/toolkit/modules/Services.jsm b/toolkit/modules/Services.jsm index 1bf1a89fe..58d87ffb1 100644 --- a/toolkit/modules/Services.jsm +++ b/toolkit/modules/Services.jsm @@ -39,15 +39,6 @@ XPCOMUtils.defineLazyGetter(Services, "dirsvc", function () { .QueryInterface(Ci.nsIProperties); }); -#ifdef MOZ_CRASHREPORTER -XPCOMUtils.defineLazyGetter(Services, "crashmanager", () => { - let ns = {}; - Components.utils.import("resource://gre/modules/CrashManager.jsm", ns); - - return ns.CrashManager.Singleton; -}); -#endif - XPCOMUtils.defineLazyGetter(Services, "mm", () => { return Cc["@mozilla.org/globalmessagemanager;1"] .getService(Ci.nsIMessageBroadcaster) diff --git a/toolkit/modules/Troubleshoot.jsm b/toolkit/modules/Troubleshoot.jsm index cc545b4c4..60f7e8666 100644 --- a/toolkit/modules/Troubleshoot.jsm +++ b/toolkit/modules/Troubleshoot.jsm @@ -12,13 +12,6 @@ Cu.import("resource://gre/modules/AddonManager.jsm"); Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/AppConstants.jsm"); -var Experiments; -try { - Experiments = Cu.import("resource:///modules/experiments/Experiments.jsm").Experiments; -} -catch (e) { -} - // We use a preferences whitelist to make sure we only show preferences that // are useful for support and won't compromise the user's privacy. Note that // entries are *prefixes*: for example, "accessibility." applies to all prefs @@ -263,18 +256,6 @@ var dataProviders = { }); }, - experiments: function experiments(done) { - if (Experiments === undefined) { - done([]); - return; - } - - // getExperiments promises experiment history - Experiments.instance().getExperiments().then( - experiments => done(experiments) - ); - }, - modifiedPreferences: function modifiedPreferences(done) { done(getPrefList(name => Services.prefs.prefHasUserValue(name))); }, @@ -549,19 +530,6 @@ var dataProviders = { } }; -if (AppConstants.MOZ_CRASHREPORTER) { - dataProviders.crashes = function crashes(done) { - let CrashReports = Cu.import("resource://gre/modules/CrashReports.jsm").CrashReports; - let reports = CrashReports.getReports(); - let now = new Date(); - let reportsNew = reports.filter(report => (now - report.date < Troubleshoot.kMaxCrashAge)); - let reportsSubmitted = reportsNew.filter(report => (!report.pending)); - let reportsPendingCount = reportsNew.length - reportsSubmitted.length; - let data = {submitted : reportsSubmitted, pending : reportsPendingCount}; - done(data); - } -} - if (AppConstants.MOZ_SANDBOX) { dataProviders.sandbox = function sandbox(done) { let data = {}; diff --git a/toolkit/moz.build b/toolkit/moz.build index d9becc9c6..778f1c0de 100644 --- a/toolkit/moz.build +++ b/toolkit/moz.build @@ -54,9 +54,6 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows': elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android': DIRS += ['system/androidproxy'] -if CONFIG['MOZ_CRASHREPORTER']: - DIRS += ['crashreporter'] - TEST_HARNESS_FILES.testing.mochitest.browser.toolkit.crashreporter.test.browser += [ 'crashreporter/test/browser/crashreport.sjs', ] diff --git a/toolkit/mozapps/extensions/content/extensions.js b/toolkit/mozapps/extensions/content/extensions.js index a799eeebb..6f2a47482 100644 --- a/toolkit/mozapps/extensions/content/extensions.js +++ b/toolkit/mozapps/extensions/content/extensions.js @@ -19,11 +19,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "PluralForm", "resource://gre/modules/PluralForm.jsm"); XPCOMUtils.defineLazyGetter(this, "BrowserToolboxProcess", function () { - return Cu.import("resource://gre/modules/devtools/ToolboxProcess.jsm", {}). + return Cu.import("resource://devtools/client/framework/ToolboxProcess.jsm", {}). BrowserToolboxProcess; }); -XPCOMUtils.defineLazyModuleGetter(this, "Experiments", - "resource:///modules/experiments/Experiments.jsm"); const PREF_DISCOVERURL = "extensions.webservice.discoverURL"; const PREF_DISCOVER_ENABLED = "extensions.getAddons.showPane"; @@ -216,23 +214,6 @@ function isDiscoverEnabled() { return true; } -function getExperimentEndDate(aAddon) { - if (!("@mozilla.org/browser/experiments-service;1" in Cc)) { - return 0; - } - - if (!aAddon.isActive) { - return aAddon.endDate; - } - - let experiment = Experiments.instance().getActiveExperiment(); - if (!experiment) { - return 0; - } - - return experiment.endDate; -} - /** * Obtain the main DOMWindow for the current context. */ @@ -1316,28 +1297,7 @@ var gViewController = { doCommand: function cmd_neverActivateItem_doCommand(aAddon) { aAddon.userDisabled = true; } - }, - - cmd_experimentsLearnMore: { - isEnabled: function cmd_experimentsLearnMore_isEnabled() { - let mainWindow = getMainWindow(); - return mainWindow && "switchToTabHavingURI" in mainWindow; - }, - doCommand: function cmd_experimentsLearnMore_doCommand() { - let url = Services.prefs.getCharPref("toolkit.telemetry.infoURL"); - openOptionsInTab(url); - }, - }, - - cmd_experimentsOpenTelemetryPreferences: { - isEnabled: function cmd_experimentsOpenTelemetryPreferences_isEnabled() { - return !!getMainWindowWithPreferencesPane(); - }, - doCommand: function cmd_experimentsOpenTelemetryPreferences_doCommand() { - let mainWindow = getMainWindowWithPreferencesPane(); - mainWindow.openAdvancedPreferences("dataChoicesTab"); - }, - }, + } }, supportsCommand: function gVC_supportsCommand(aCommand) { @@ -1468,10 +1428,6 @@ function createItem(aObj, aIsInstall, aIsRemote) { // the binding handles the rest item.setAttribute("value", aObj.id); - if (aObj.type == "experiment") { - item.endDate = getExperimentEndDate(aObj); - } - return item; } @@ -2679,13 +2635,6 @@ var gListView = { // the existing item if (aInstall.existingAddon) this.removeItem(aInstall, true); - - if (aInstall.addon.type == "experiment") { - let item = this.getListItemForID(aInstall.addon.id); - if (item) { - item.endDate = getExperimentEndDate(aInstall.addon); - } - } }, addItem: function gListView_addItem(aObj, aIsInstall) { @@ -2945,34 +2894,6 @@ var gDetailView = { } } - if (this._addon.type == "experiment") { - let prefix = "details.experiment."; - let active = this._addon.isActive; - - let stateKey = prefix + "state." + (active ? "active" : "complete"); - let node = document.getElementById("detail-experiment-state"); - node.value = gStrings.ext.GetStringFromName(stateKey); - - let now = Date.now(); - let end = getExperimentEndDate(this._addon); - let days = Math.abs(end - now) / (24 * 60 * 60 * 1000); - - let timeKey = prefix + "time."; - let timeMessage; - if (days < 1) { - timeKey += (active ? "endsToday" : "endedToday"); - timeMessage = gStrings.ext.GetStringFromName(timeKey); - } else { - timeKey += (active ? "daysRemaining" : "daysPassed"); - days = Math.round(days); - let timeString = gStrings.ext.GetStringFromName(timeKey); - timeMessage = PluralForm.get(days, timeString) - .replace("#1", days); - } - - document.getElementById("detail-experiment-time").value = timeMessage; - } - this.fillSettingsRows(aScrollToPreferences, (function updateView_fillSettingsRows() { this.updateState(); gViewController.notifyViewChanged(); diff --git a/toolkit/mozapps/extensions/internal/XPIProvider.jsm b/toolkit/mozapps/extensions/internal/XPIProvider.jsm index 54b86edc4..d5f1ab5dd 100644 --- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm +++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm @@ -37,9 +37,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "Task", XPCOMUtils.defineLazyModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "BrowserToolboxProcess", - "resource://gre/modules/devtools/ToolboxProcess.jsm"); + "resource://devtools/client/framework/ToolboxProcess.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "ConsoleAPI", - "resource://gre/modules/devtools/Console.jsm"); + "resource://gre/modules/Console.jsm"); XPCOMUtils.defineLazyServiceGetter(this, "Blocklist", "@mozilla.org/extensions/blocklist;1", @@ -2082,7 +2082,7 @@ this.XPIProvider = { Services.prefs.addObserver(PREF_EM_MIN_COMPAT_APP_VERSION, this, false); Services.prefs.addObserver(PREF_EM_MIN_COMPAT_PLATFORM_VERSION, this, false); Services.obs.addObserver(this, NOTIFICATION_FLUSH_PERMISSIONS, false); - if (Cu.isModuleLoaded("resource://gre/modules/devtools/ToolboxProcess.jsm")) { + if (Cu.isModuleLoaded("resource://devtools/client/framework/ToolboxProcess.jsm")) { // If BrowserToolboxProcess is already loaded, set the boolean to true // and do whatever is needed this._toolboxProcessLoaded = true; diff --git a/toolkit/mozapps/extensions/test/browser/browser_experiments.js b/toolkit/mozapps/extensions/test/browser/browser_experiments.js deleted file mode 100644 index 72d0ca83e..000000000 --- a/toolkit/mozapps/extensions/test/browser/browser_experiments.js +++ /dev/null @@ -1,645 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -Components.utils.import("resource://gre/modules/Promise.jsm", this); - -let {AddonTestUtils} = Components.utils.import("resource://testing-common/AddonManagerTesting.jsm", {}); -let {HttpServer} = Components.utils.import("resource://testing-common/httpd.js", {}); - -let gManagerWindow; -let gCategoryUtilities; -let gExperiments; -let gHttpServer; - -let gSavedManifestURI; -let gIsEnUsLocale; - -const SEC_IN_ONE_DAY = 24 * 60 * 60; -const MS_IN_ONE_DAY = SEC_IN_ONE_DAY * 1000; - -function getExperimentAddons() { - let deferred = Promise.defer(); - AddonManager.getAddonsByTypes(["experiment"], (addons) => { - deferred.resolve(addons); - }); - return deferred.promise; -} - -function getInstallItem() { - let doc = gManagerWindow.document; - let view = doc.getElementById("view-port").selectedPanel; - let list = doc.getElementById("addon-list"); - - let node = list.firstChild; - while (node) { - if (node.getAttribute("status") == "installing") { - return node; - } - node = node.nextSibling; - } - - return null; -} - -function patchPolicy(policy, data) { - for (let key of Object.keys(data)) { - Object.defineProperty(policy, key, { - value: data[key], - writable: true, - }); - } -} - -function defineNow(policy, time) { - patchPolicy(policy, { now: () => new Date(time) }); -} - -function openDetailsView(aId) { - let item = get_addon_element(gManagerWindow, aId); - Assert.ok(item, "Should have got add-on element."); - is_element_visible(item, "Add-on element should be visible."); - - EventUtils.synthesizeMouseAtCenter(item, { clickCount: 1 }, gManagerWindow); - EventUtils.synthesizeMouseAtCenter(item, { clickCount: 2 }, gManagerWindow); - - let deferred = Promise.defer(); - wait_for_view_load(gManagerWindow, deferred.resolve); - return deferred.promise; -} - -function clickRemoveButton(addonElement) { - let btn = gManagerWindow.document.getAnonymousElementByAttribute(addonElement, "anonid", "remove-btn"); - if (!btn) { - return Promise.reject(); - } - - EventUtils.synthesizeMouseAtCenter(btn, { clickCount: 1 }, gManagerWindow); - let deferred = Promise.defer(); - setTimeout(deferred.resolve, 0); - return deferred; -} - -function clickUndoButton(addonElement) { - let btn = gManagerWindow.document.getAnonymousElementByAttribute(addonElement, "anonid", "undo-btn"); - if (!btn) { - return Promise.reject(); - } - - EventUtils.synthesizeMouseAtCenter(btn, { clickCount: 1 }, gManagerWindow); - let deferred = Promise.defer(); - setTimeout(deferred.resolve, 0); - return deferred; -} - -add_task(function* initializeState() { - gManagerWindow = yield open_manager(); - gCategoryUtilities = new CategoryUtilities(gManagerWindow); - - registerCleanupFunction(() => { - Services.prefs.clearUserPref("experiments.enabled"); - if (gHttpServer) { - gHttpServer.stop(() => {}); - if (gSavedManifestURI !== undefined) { - Services.prefs.setCharPref("experments.manifest.uri", gSavedManifestURI); - } - } - if (gExperiments) { - let tmp = {}; - Cu.import("resource:///modules/experiments/Experiments.jsm", tmp); - gExperiments._policy = new tmp.Experiments.Policy(); - } - }); - - let chrome = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry); - gIsEnUsLocale = chrome.getSelectedLocale("global") == "en-US"; - - // The Experiments Manager will interfere with us by preventing installs - // of experiments it doesn't know about. We remove it from the equation - // because here we are only concerned with core Addon Manager operation, - // not the superset Experiments Manager has imposed. - if ("@mozilla.org/browser/experiments-service;1" in Components.classes) { - let tmp = {}; - Cu.import("resource:///modules/experiments/Experiments.jsm", tmp); - // There is a race condition between XPCOM service initialization and - // this test running. We have to initialize the instance first, then - // uninitialize it to prevent this. - gExperiments = tmp.Experiments.instance(); - yield gExperiments._mainTask; - yield gExperiments.uninit(); - } -}); - -// On an empty profile with no experiments, the experiment category -// should be hidden. -add_task(function* testInitialState() { - Assert.ok(gCategoryUtilities.get("experiment", false), "Experiment tab is defined."); - Assert.ok(!gCategoryUtilities.isTypeVisible("experiment"), "Experiment tab hidden by default."); -}); - -add_task(function* testExperimentInfoNotVisible() { - yield gCategoryUtilities.openType("extension"); - let el = gManagerWindow.document.getElementsByClassName("experiment-info-container")[0]; - is_element_hidden(el, "Experiment info not visible on other types."); -}); - -// If we have an active experiment, we should see the experiments tab -// and that tab should have some messages. -add_task(function* testActiveExperiment() { - let addon = yield install_addon("addons/browser_experiment1.xpi"); - - Assert.ok(addon.userDisabled, "Add-on is disabled upon initial install."); - Assert.equal(addon.isActive, false, "Add-on is not active."); - - Assert.ok(gCategoryUtilities.isTypeVisible("experiment"), "Experiment tab visible."); - - yield gCategoryUtilities.openType("experiment"); - let el = gManagerWindow.document.getElementsByClassName("experiment-info-container")[0]; - is_element_visible(el, "Experiment info is visible on experiment tab."); -}); - -add_task(function* testExperimentLearnMore() { - // Actual URL is irrelevant. - Services.prefs.setCharPref("toolkit.telemetry.infoURL", - "http://mochi.test:8888/server.js"); - - yield gCategoryUtilities.openType("experiment"); - let btn = gManagerWindow.document.getElementById("experiments-learn-more"); - - if (!gUseInContentUI) { - is_element_hidden(btn, "Learn more button hidden if not using in-content UI."); - Services.prefs.clearUserPref("toolkit.telemetry.infoURL"); - - return; - } - - is_element_visible(btn, "Learn more button visible."); - - let deferred = Promise.defer(); - window.addEventListener("DOMContentLoaded", function onLoad(event) { - info("Telemetry privacy policy window opened."); - window.removeEventListener("DOMContentLoaded", onLoad, false); - - let browser = gBrowser.selectedBrowser; - let expected = Services.prefs.getCharPref("toolkit.telemetry.infoURL"); - Assert.equal(browser.currentURI.spec, expected, "New tab should have loaded privacy policy."); - browser.contentWindow.close(); - - Services.prefs.clearUserPref("toolkit.telemetry.infoURL"); - - deferred.resolve(); - }, false); - - info("Opening telemetry privacy policy."); - EventUtils.synthesizeMouseAtCenter(btn, {}, gManagerWindow); - - yield deferred.promise; -}); - -add_task(function* testOpenPreferences() { - yield gCategoryUtilities.openType("experiment"); - let btn = gManagerWindow.document.getElementById("experiments-change-telemetry"); - if (!gUseInContentUI) { - is_element_hidden(btn, "Change telemetry button not enabled in out of window UI."); - info("Skipping preferences open test because not using in-content UI."); - return; - } - - is_element_visible(btn, "Change telemetry button visible in in-content UI."); - - let deferred = Promise.defer(); - Services.obs.addObserver(function observer(prefWin, topic, data) { - Services.obs.removeObserver(observer, "advanced-pane-loaded"); - info("Advanced preference pane opened."); - executeSoon(function() { - // We want this test to fail if the preferences pane changes. - let el = prefWin.document.getElementById("dataChoicesPanel"); - is_element_visible(el); - - prefWin.close(); - info("Closed preferences pane."); - - deferred.resolve(); - }); - }, "advanced-pane-loaded", false); - - info("Loading preferences pane."); - EventUtils.synthesizeMouseAtCenter(btn, {}, gManagerWindow); - - yield deferred.promise; -}); - -add_task(function* testButtonPresence() { - yield gCategoryUtilities.openType("experiment"); - let item = get_addon_element(gManagerWindow, "test-experiment1@experiments.mozilla.org"); - Assert.ok(item, "Got add-on element."); - item.parentNode.ensureElementIsVisible(item); - - let el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "remove-btn"); - // Corresponds to the uninstall permission. - is_element_visible(el, "Remove button is visible."); - // Corresponds to lack of disable permission. - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "disable-btn"); - is_element_hidden(el, "Disable button not visible."); - // Corresponds to lack of enable permission. - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "enable-btn"); - is_element_hidden(el, "Enable button not visible."); -}); - -// Remove the add-on we've been testing with. -add_task(function* testCleanup() { - yield AddonTestUtils.uninstallAddonByID("test-experiment1@experiments.mozilla.org"); - // Verify some conditions, just in case. - let addons = yield getExperimentAddons(); - Assert.equal(addons.length, 0, "No experiment add-ons are installed."); -}); - -// The following tests should ideally live in browser/experiments/. However, -// they rely on some of the helper functions from head.js, which can't easily -// be consumed from other directories. So, they live here. - -add_task(function* testActivateExperiment() { - if (!gExperiments) { - info("Skipping experiments test because that feature isn't available."); - return; - } - - gHttpServer = new HttpServer(); - gHttpServer.start(-1); - let root = "http://localhost:" + gHttpServer.identity.primaryPort + "/"; - gHttpServer.registerPathHandler("/manifest", (request, response) => { - response.setStatusLine(null, 200, "OK"); - response.write(JSON.stringify({ - "version": 1, - "experiments": [ - { - id: "experiment-1", - xpiURL: TESTROOT + "addons/browser_experiment1.xpi", - xpiHash: "IRRELEVANT", - startTime: Date.now() / 1000 - 3600, - endTime: Date.now() / 1000 + 3600, - maxActiveSeconds: 600, - appName: [Services.appinfo.name], - channel: [gExperiments._policy.updatechannel()], - }, - ], - })); - response.processAsync(); - response.finish(); - }); - - gSavedManifestURI = Services.prefs.getCharPref("experiments.manifest.uri"); - Services.prefs.setCharPref("experiments.manifest.uri", root + "manifest"); - - // We need to remove the cache file to help ensure consistent state. - yield OS.File.remove(gExperiments._cacheFilePath); - - Services.prefs.setBoolPref("experiments.enabled", true); - - info("Initializing experiments service."); - yield gExperiments.init(); - info("Experiments service finished first run."); - - // Check conditions, just to be sure. - let experiments = yield gExperiments.getExperiments(); - Assert.equal(experiments.length, 0, "No experiments known to the service."); - - // This makes testing easier. - gExperiments._policy.ignoreHashes = true; - - info("Manually updating experiments manifest."); - yield gExperiments.updateManifest(); - info("Experiments update complete."); - - let deferred = Promise.defer(); - gHttpServer.stop(() => { - gHttpServer = null; - - info("getting experiment by ID"); - AddonManager.getAddonByID("test-experiment1@experiments.mozilla.org", (addon) => { - Assert.ok(addon, "Add-on installed via Experiments manager."); - - deferred.resolve(); - }); - }); - - yield deferred.promise; - - Assert.ok(gCategoryUtilities.isTypeVisible, "experiment", "Experiment tab visible."); - yield gCategoryUtilities.openType("experiment"); - let el = gManagerWindow.document.getElementsByClassName("experiment-info-container")[0]; - is_element_visible(el, "Experiment info is visible on experiment tab."); -}); - -add_task(function testDeactivateExperiment() { - if (!gExperiments) { - return; - } - - // Fake an empty manifest to purge data from previous manifest. - yield gExperiments._updateExperiments({ - "version": 1, - "experiments": [], - }); - - yield gExperiments.disableExperiment("testing"); - - // We should have a record of the previously-active experiment. - let experiments = yield gExperiments.getExperiments(); - Assert.equal(experiments.length, 1, "1 experiment is known."); - Assert.equal(experiments[0].active, false, "Experiment is not active."); - - // We should have a previous experiment in the add-ons manager. - let deferred = Promise.defer(); - AddonManager.getAddonsByTypes(["experiment"], (addons) => { - deferred.resolve(addons); - }); - let addons = yield deferred.promise; - Assert.equal(addons.length, 1, "1 experiment add-on known."); - Assert.ok(addons[0].appDisabled, "It is a previous experiment."); - Assert.equal(addons[0].id, "experiment-1", "Add-on ID matches expected."); - - // Verify the UI looks sane. - - Assert.ok(gCategoryUtilities.isTypeVisible("experiment"), "Experiment tab visible."); - let item = get_addon_element(gManagerWindow, "experiment-1"); - Assert.ok(item, "Got add-on element."); - Assert.ok(!item.active, "Element should not be active."); - item.parentNode.ensureElementIsVisible(item); - - // User control buttons should not be present because previous experiments - // should have no permissions. - let el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "remove-btn"); - is_element_hidden(el, "Remove button is not visible."); - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "disable-btn"); - is_element_hidden(el, "Disable button is not visible."); - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "enable-btn"); - is_element_hidden(el, "Enable button is not visible."); - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "preferences-btn"); - is_element_hidden(el, "Preferences button is not visible."); -}); - -add_task(function testActivateRealExperiments() { - if (!gExperiments) { - info("Skipping experiments test because that feature isn't available."); - return; - } - - yield gExperiments._updateExperiments({ - "version": 1, - "experiments": [ - { - id: "experiment-2", - xpiURL: TESTROOT + "addons/browser_experiment1.xpi", - xpiHash: "IRRELEVANT", - startTime: Date.now() / 1000 - 3600, - endTime: Date.now() / 1000 + 3600, - maxActiveSeconds: 600, - appName: [Services.appinfo.name], - channel: [gExperiments._policy.updatechannel()], - }, - ], - }); - yield gExperiments._run(); - - // Check the active experiment. - - let item = get_addon_element(gManagerWindow, "test-experiment1@experiments.mozilla.org"); - Assert.ok(item, "Got add-on element."); - item.parentNode.ensureElementIsVisible(item); - - let el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "experiment-state"); - is_element_visible(el, "Experiment state label should be visible."); - if (gIsEnUsLocale) { - Assert.equal(el.value, "Active"); - } - - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "experiment-time"); - is_element_visible(el, "Experiment time label should be visible."); - if (gIsEnUsLocale) { - Assert.equal(el.value, "Less than a day remaining"); - } - - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "error-container"); - is_element_hidden(el, "error-container should be hidden."); - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "warning-container"); - is_element_hidden(el, "warning-container should be hidden."); - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "pending-container"); - is_element_hidden(el, "pending-container should be hidden."); - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "version"); - is_element_hidden(el, "version should be hidden."); - el = item.ownerDocument.getAnonymousElementByAttribute(item, "class", "disabled-postfix"); - is_element_hidden(el, "disabled-postfix should be hidden."); - el = item.ownerDocument.getAnonymousElementByAttribute(item, "class", "update-postfix"); - is_element_hidden(el, "update-postfix should be hidden."); - el = item.ownerDocument.getAnonymousElementByAttribute(item, "class", "experiment-bullet"); - is_element_visible(el, "experiment-bullet should be visible."); - - // Check the previous experiment. - - item = get_addon_element(gManagerWindow, "experiment-1"); - Assert.ok(item, "Got add-on element."); - item.parentNode.ensureElementIsVisible(item); - - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "experiment-state"); - is_element_visible(el, "Experiment state label should be visible."); - if (gIsEnUsLocale) { - Assert.equal(el.value, "Complete"); - } - - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "experiment-time"); - is_element_visible(el, "Experiment time label should be visible."); - if (gIsEnUsLocale) { - Assert.equal(el.value, "Less than a day ago"); - } - - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "error-container"); - is_element_hidden(el, "error-container should be hidden."); - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "warning-container"); - is_element_hidden(el, "warning-container should be hidden."); - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "pending-container"); - is_element_hidden(el, "pending-container should be hidden."); - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "version"); - is_element_hidden(el, "version should be hidden."); - el = item.ownerDocument.getAnonymousElementByAttribute(item, "class", "disabled-postfix"); - is_element_hidden(el, "disabled-postfix should be hidden."); - el = item.ownerDocument.getAnonymousElementByAttribute(item, "class", "update-postfix"); - is_element_hidden(el, "update-postfix should be hidden."); - el = item.ownerDocument.getAnonymousElementByAttribute(item, "class", "experiment-bullet"); - is_element_visible(el, "experiment-bullet should be visible."); - - // Install an "older" experiment. - - yield gExperiments.disableExperiment("experiment-2"); - - let now = Date.now(); - let fakeNow = now - 5 * MS_IN_ONE_DAY; - defineNow(gExperiments._policy, fakeNow); - - yield gExperiments._updateExperiments({ - "version": 1, - "experiments": [ - { - id: "experiment-3", - xpiURL: TESTROOT + "addons/browser_experiment1.xpi", - xpiHash: "IRRELEVANT", - startTime: fakeNow / 1000 - SEC_IN_ONE_DAY, - endTime: now / 1000 + 10 * SEC_IN_ONE_DAY, - maxActiveSeconds: 100 * SEC_IN_ONE_DAY, - appName: [Services.appinfo.name], - channel: [gExperiments._policy.updatechannel()], - }, - ], - }); - yield gExperiments._run(); - - // Check the active experiment. - - item = get_addon_element(gManagerWindow, "test-experiment1@experiments.mozilla.org"); - Assert.ok(item, "Got add-on element."); - item.parentNode.ensureElementIsVisible(item); - - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "experiment-state"); - is_element_visible(el, "Experiment state label should be visible."); - if (gIsEnUsLocale) { - Assert.equal(el.value, "Active"); - } - - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "experiment-time"); - is_element_visible(el, "Experiment time label should be visible."); - if (gIsEnUsLocale) { - Assert.equal(el.value, "10 days remaining"); - } - - // Disable it and check it's previous experiment entry. - - yield gExperiments.disableExperiment("experiment-3"); - - item = get_addon_element(gManagerWindow, "experiment-3"); - Assert.ok(item, "Got add-on element."); - item.parentNode.ensureElementIsVisible(item); - - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "experiment-state"); - is_element_visible(el, "Experiment state label should be visible."); - if (gIsEnUsLocale) { - Assert.equal(el.value, "Complete"); - } - - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "experiment-time"); - is_element_visible(el, "Experiment time label should be visible."); - if (gIsEnUsLocale) { - Assert.equal(el.value, "5 days ago"); - } -}); - -add_task(function testDetailView() { - if (!gExperiments) { - info("Skipping experiments test because that feature isn't available."); - return; - } - - defineNow(gExperiments._policy, Date.now()); - yield gExperiments._updateExperiments({ - "version": 1, - "experiments": [ - { - id: "experiment-4", - xpiURL: TESTROOT + "addons/browser_experiment1.xpi", - xpiHash: "IRRELEVANT", - startTime: Date.now() / 1000 - 3600, - endTime: Date.now() / 1000 + 3600, - maxActiveSeconds: 600, - appName: [Services.appinfo.name], - channel: [gExperiments._policy.updatechannel()], - }, - ], - }); - yield gExperiments._run(); - - // Check active experiment. - - yield openDetailsView("test-experiment1@experiments.mozilla.org"); - - let el = gManagerWindow.document.getElementById("detail-experiment-state"); - is_element_visible(el, "Experiment state label should be visible."); - if (gIsEnUsLocale) { - Assert.equal(el.value, "Active"); - } - - el = gManagerWindow.document.getElementById("detail-experiment-time"); - is_element_visible(el, "Experiment time label should be visible."); - if (gIsEnUsLocale) { - Assert.equal(el.value, "Less than a day remaining"); - } - - el = gManagerWindow.document.getElementById("detail-version"); - is_element_hidden(el, "detail-version should be hidden."); - el = gManagerWindow.document.getElementById("detail-creator"); - is_element_hidden(el, "detail-creator should be hidden."); - el = gManagerWindow.document.getElementById("detail-experiment-bullet"); - is_element_visible(el, "experiment-bullet should be visible."); - - // Check previous experiment. - - yield gCategoryUtilities.openType("experiment"); - yield openDetailsView("experiment-3"); - - el = gManagerWindow.document.getElementById("detail-experiment-state"); - is_element_visible(el, "Experiment state label should be visible."); - if (gIsEnUsLocale) { - Assert.equal(el.value, "Complete"); - } - - el = gManagerWindow.document.getElementById("detail-experiment-time"); - is_element_visible(el, "Experiment time label should be visible."); - if (gIsEnUsLocale) { - Assert.equal(el.value, "5 days ago"); - } - - el = gManagerWindow.document.getElementById("detail-version"); - is_element_hidden(el, "detail-version should be hidden."); - el = gManagerWindow.document.getElementById("detail-creator"); - is_element_hidden(el, "detail-creator should be hidden."); - el = gManagerWindow.document.getElementById("detail-experiment-bullet"); - is_element_visible(el, "experiment-bullet should be visible."); -}); - -add_task(function* testRemoveAndUndo() { - if (!gExperiments) { - info("Skipping experiments test because that feature isn't available."); - return; - } - - yield gCategoryUtilities.openType("experiment"); - - let addon = get_addon_element(gManagerWindow, "test-experiment1@experiments.mozilla.org"); - Assert.ok(addon, "Got add-on element."); - - yield clickRemoveButton(addon); - addon.parentNode.ensureElementIsVisible(addon); - - let el = gManagerWindow.document.getAnonymousElementByAttribute(addon, "class", "pending"); - is_element_visible(el, "Uninstall undo information should be visible."); - - yield clickUndoButton(addon); - addon = get_addon_element(gManagerWindow, "test-experiment1@experiments.mozilla.org"); - Assert.ok(addon, "Got add-on element."); -}); - -add_task(function* testCleanup() { - if (gExperiments) { - Services.prefs.clearUserPref("experiments.enabled"); - Services.prefs.setCharPref("experiments.manifest.uri", gSavedManifestURI); - - // We perform the uninit/init cycle to purge any leftover state. - yield OS.File.remove(gExperiments._cacheFilePath); - yield gExperiments.uninit(); - yield gExperiments.init(); - } - - // Check post-conditions. - let addons = yield getExperimentAddons(); - Assert.equal(addons.length, 0, "No experiment add-ons are installed."); - - yield close_manager(gManagerWindow); -}); diff --git a/toolkit/mozapps/webextensions/content/extensions.js b/toolkit/mozapps/webextensions/content/extensions.js index 5e428fe17..3159eb1e1 100644 --- a/toolkit/mozapps/webextensions/content/extensions.js +++ b/toolkit/mozapps/webextensions/content/extensions.js @@ -29,9 +29,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "PluralForm", XPCOMUtils.defineLazyModuleGetter(this, "Preferences", "resource://gre/modules/Preferences.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "Experiments", - "resource:///modules/experiments/Experiments.jsm"); - const PREF_DISCOVERURL = "extensions.webservice.discoverURL"; const PREF_DISCOVER_ENABLED = "extensions.getAddons.showPane"; const PREF_XPI_ENABLED = "xpinstall.enabled"; @@ -297,23 +294,6 @@ function isDiscoverEnabled() { return true; } -function getExperimentEndDate(aAddon) { - if (!("@mozilla.org/browser/experiments-service;1" in Cc)) { - return 0; - } - - if (!aAddon.isActive) { - return aAddon.endDate; - } - - let experiment = Experiments.instance().getActiveExperiment(); - if (!experiment) { - return 0; - } - - return experiment.endDate; -} - /** * Obtain the main DOMWindow for the current context. */ @@ -1444,27 +1424,6 @@ var gViewController = { } }, - cmd_experimentsLearnMore: { - isEnabled: function() { - let mainWindow = getMainWindow(); - return mainWindow && "switchToTabHavingURI" in mainWindow; - }, - doCommand: function() { - let url = Services.prefs.getCharPref("toolkit.telemetry.infoURL"); - openOptionsInTab(url); - }, - }, - - cmd_experimentsOpenTelemetryPreferences: { - isEnabled: function() { - return !!getMainWindowWithPreferencesPane(); - }, - doCommand: function() { - let mainWindow = getMainWindowWithPreferencesPane(); - mainWindow.openAdvancedPreferences("dataChoicesTab"); - }, - }, - cmd_showUnsignedExtensions: { isEnabled: function() { return true; @@ -1577,10 +1536,6 @@ function shouldShowVersionNumber(aAddon) { if (!aAddon.version) return false; - // The version number is hidden for experiments. - if (aAddon.type == "experiment") - return false; - // The version number is hidden for lightweight themes. if (aAddon.type == "theme") return !/@personas\.mozilla\.org$/.test(aAddon.id); @@ -1614,10 +1569,6 @@ function createItem(aObj, aIsInstall, aIsRemote) { // the binding handles the rest item.setAttribute("value", aObj.id); - if (aObj.type == "experiment") { - item.endDate = getExperimentEndDate(aObj); - } - return item; } @@ -2861,13 +2812,6 @@ var gListView = { // the existing item if (aInstall.existingAddon) this.removeItem(aInstall, true); - - if (aInstall.addon.type == "experiment") { - let item = this.getListItemForID(aInstall.addon.id); - if (item) { - item.endDate = getExperimentEndDate(aInstall.addon); - } - } }, addItem: function(aObj, aIsInstall) { @@ -3126,34 +3070,6 @@ var gDetailView = { } } - if (this._addon.type == "experiment") { - let prefix = "details.experiment."; - let active = this._addon.isActive; - - let stateKey = prefix + "state." + (active ? "active" : "complete"); - let node = document.getElementById("detail-experiment-state"); - node.value = gStrings.ext.GetStringFromName(stateKey); - - let now = Date.now(); - let end = getExperimentEndDate(this._addon); - let days = Math.abs(end - now) / (24 * 60 * 60 * 1000); - - let timeKey = prefix + "time."; - let timeMessage; - if (days < 1) { - timeKey += (active ? "endsToday" : "endedToday"); - timeMessage = gStrings.ext.GetStringFromName(timeKey); - } else { - timeKey += (active ? "daysRemaining" : "daysPassed"); - days = Math.round(days); - let timeString = gStrings.ext.GetStringFromName(timeKey); - timeMessage = PluralForm.get(days, timeString) - .replace("#1", days); - } - - document.getElementById("detail-experiment-time").value = timeMessage; - } - this.fillSettingsRows(aScrollToPreferences, (function() { this.updateState(); gViewController.notifyViewChanged(); diff --git a/toolkit/mozapps/webextensions/internal/XPIProvider.jsm b/toolkit/mozapps/webextensions/internal/XPIProvider.jsm index 87e09cef1..7c3cb6763 100644 --- a/toolkit/mozapps/webextensions/internal/XPIProvider.jsm +++ b/toolkit/mozapps/webextensions/internal/XPIProvider.jsm @@ -175,6 +175,8 @@ const RDFURI_INSTALL_MANIFEST_ROOT = "urn:mozilla:install-manifest"; const PREFIX_NS_EM = "http://www.mozilla.org/2004/em-rdf#"; const TOOLKIT_ID = "toolkit@mozilla.org"; +const WEBEXTENSIONS_ID = "webextensions@mozilla.org"; +const WEBEXTENSIONS_VERSION = "52.0"; const XPI_SIGNATURE_CHECK_PERIOD = 24 * 60 * 60; @@ -1037,7 +1039,7 @@ var loadManifestFromWebManifest = Task.async(function*(aUri) { delete addon.defaultLocale.locales; addon.targetApplications = [{ - id: TOOLKIT_ID, + id: WEBEXTENSIONS_ID, minVersion: bss.strict_min_version, maxVersion: bss.strict_max_version, }]; @@ -7228,6 +7230,8 @@ AddonInternal.prototype = { version = aAppVersion; else if (app.id == TOOLKIT_ID) version = aPlatformVersion + else if (app.id == WEBEXTENSIONS_ID) + version = WEBEXTENSIONS_VERSION // Only extensions and dictionaries can be compatible by default; themes // and language packs always use strict compatibility checking. @@ -7250,7 +7254,7 @@ AddonInternal.prototype = { let minCompatVersion; if (app.id == Services.appinfo.ID) minCompatVersion = XPIProvider.minCompatibleAppVersion; - else if (app.id == TOOLKIT_ID) + else if (app.id == TOOLKIT_ID || app.id == WEBEXTENSIONS_ID) minCompatVersion = XPIProvider.minCompatiblePlatformVersion; if (minCompatVersion && @@ -7269,7 +7273,7 @@ AddonInternal.prototype = { for (let targetApp of this.targetApplications) { if (targetApp.id == Services.appinfo.ID) return targetApp; - if (targetApp.id == TOOLKIT_ID) + if (targetApp.id == TOOLKIT_ID || targetApp.id == WEBEXTENSIONS_ID) app = targetApp; } return app; diff --git a/toolkit/mozapps/webextensions/test/browser/browser_experiments.js b/toolkit/mozapps/webextensions/test/browser/browser_experiments.js deleted file mode 100644 index 18a548de5..000000000 --- a/toolkit/mozapps/webextensions/test/browser/browser_experiments.js +++ /dev/null @@ -1,654 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -Components.utils.import("resource://gre/modules/Promise.jsm", this); - -var {AddonManagerTesting} = Components.utils.import("resource://testing-common/AddonManagerTesting.jsm", {}); -var {HttpServer} = Components.utils.import("resource://testing-common/httpd.js", {}); - -var gManagerWindow; -var gCategoryUtilities; -var gExperiments; -var gHttpServer; - -var gSavedManifestURI; -var gIsEnUsLocale; - -const SEC_IN_ONE_DAY = 24 * 60 * 60; -const MS_IN_ONE_DAY = SEC_IN_ONE_DAY * 1000; - -function getExperimentAddons() { - let deferred = Promise.defer(); - AddonManager.getAddonsByTypes(["experiment"], (addons) => { - deferred.resolve(addons); - }); - return deferred.promise; -} - -function getInstallItem() { - let doc = gManagerWindow.document; - let view = get_current_view(gManagerWindow); - let list = doc.getElementById("addon-list"); - - let node = list.firstChild; - while (node) { - if (node.getAttribute("status") == "installing") { - return node; - } - node = node.nextSibling; - } - - return null; -} - -function patchPolicy(policy, data) { - for (let key of Object.keys(data)) { - Object.defineProperty(policy, key, { - value: data[key], - writable: true, - }); - } -} - -function defineNow(policy, time) { - patchPolicy(policy, { now: () => new Date(time) }); -} - -function openDetailsView(aId) { - let item = get_addon_element(gManagerWindow, aId); - Assert.ok(item, "Should have got add-on element."); - is_element_visible(item, "Add-on element should be visible."); - - EventUtils.synthesizeMouseAtCenter(item, { clickCount: 1 }, gManagerWindow); - EventUtils.synthesizeMouseAtCenter(item, { clickCount: 2 }, gManagerWindow); - - let deferred = Promise.defer(); - wait_for_view_load(gManagerWindow, deferred.resolve); - return deferred.promise; -} - -function clickRemoveButton(addonElement) { - let btn = gManagerWindow.document.getAnonymousElementByAttribute(addonElement, "anonid", "remove-btn"); - if (!btn) { - return Promise.reject(); - } - - EventUtils.synthesizeMouseAtCenter(btn, { clickCount: 1 }, gManagerWindow); - let deferred = Promise.defer(); - setTimeout(deferred.resolve, 0); - return deferred; -} - -function clickUndoButton(addonElement) { - let btn = gManagerWindow.document.getAnonymousElementByAttribute(addonElement, "anonid", "undo-btn"); - if (!btn) { - return Promise.reject(); - } - - EventUtils.synthesizeMouseAtCenter(btn, { clickCount: 1 }, gManagerWindow); - let deferred = Promise.defer(); - setTimeout(deferred.resolve, 0); - return deferred; -} - -add_task(function* initializeState() { - gManagerWindow = yield open_manager(); - gCategoryUtilities = new CategoryUtilities(gManagerWindow); - - registerCleanupFunction(() => { - Services.prefs.clearUserPref("experiments.enabled"); - Services.prefs.clearUserPref("toolkit.telemetry.enabled"); - if (gHttpServer) { - gHttpServer.stop(() => {}); - if (gSavedManifestURI !== undefined) { - Services.prefs.setCharPref("experments.manifest.uri", gSavedManifestURI); - } - } - if (gExperiments) { - let tmp = {}; - Cu.import("resource:///modules/experiments/Experiments.jsm", tmp); - gExperiments._policy = new tmp.Experiments.Policy(); - } - }); - - let chrome = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry); - gIsEnUsLocale = chrome.getSelectedLocale("global") == "en-US"; - - // The Experiments Manager will interfere with us by preventing installs - // of experiments it doesn't know about. We remove it from the equation - // because here we are only concerned with core Addon Manager operation, - // not the superset Experiments Manager has imposed. - if ("@mozilla.org/browser/experiments-service;1" in Components.classes) { - let tmp = {}; - Cu.import("resource:///modules/experiments/Experiments.jsm", tmp); - // There is a race condition between XPCOM service initialization and - // this test running. We have to initialize the instance first, then - // uninitialize it to prevent this. - gExperiments = tmp.Experiments.instance(); - yield gExperiments._mainTask; - yield gExperiments.uninit(); - } -}); - -// On an empty profile with no experiments, the experiment category -// should be hidden. -add_task(function* testInitialState() { - Assert.ok(gCategoryUtilities.get("experiment", false), "Experiment tab is defined."); - Assert.ok(!gCategoryUtilities.isTypeVisible("experiment"), "Experiment tab hidden by default."); -}); - -add_task(function* testExperimentInfoNotVisible() { - yield gCategoryUtilities.openType("extension"); - let el = gManagerWindow.document.getElementsByClassName("experiment-info-container")[0]; - is_element_hidden(el, "Experiment info not visible on other types."); -}); - -// If we have an active experiment, we should see the experiments tab -// and that tab should have some messages. -add_task(function* testActiveExperiment() { - let addon = yield install_addon("addons/browser_experiment1.xpi"); - - Assert.ok(addon.userDisabled, "Add-on is disabled upon initial install."); - Assert.equal(addon.isActive, false, "Add-on is not active."); - - Assert.ok(gCategoryUtilities.isTypeVisible("experiment"), "Experiment tab visible."); - - yield gCategoryUtilities.openType("experiment"); - let el = gManagerWindow.document.getElementsByClassName("experiment-info-container")[0]; - is_element_visible(el, "Experiment info is visible on experiment tab."); -}); - -add_task(function* testExperimentLearnMore() { - // Actual URL is irrelevant. - Services.prefs.setCharPref("toolkit.telemetry.infoURL", - "http://mochi.test:8888/server.js"); - - yield gCategoryUtilities.openType("experiment"); - let btn = gManagerWindow.document.getElementById("experiments-learn-more"); - - if (!gUseInContentUI) { - is_element_hidden(btn, "Learn more button hidden if not using in-content UI."); - Services.prefs.clearUserPref("toolkit.telemetry.infoURL"); - - return; - } - - is_element_visible(btn, "Learn more button visible."); - - let deferred = Promise.defer(); - window.addEventListener("DOMContentLoaded", function onLoad(event) { - info("Telemetry privacy policy window opened."); - window.removeEventListener("DOMContentLoaded", onLoad, false); - - let browser = gBrowser.selectedBrowser; - let expected = Services.prefs.getCharPref("toolkit.telemetry.infoURL"); - Assert.equal(browser.currentURI.spec, expected, "New tab should have loaded privacy policy."); - browser.contentWindow.close(); - - Services.prefs.clearUserPref("toolkit.telemetry.infoURL"); - - deferred.resolve(); - }, false); - - info("Opening telemetry privacy policy."); - EventUtils.synthesizeMouseAtCenter(btn, {}, gManagerWindow); - - yield deferred.promise; -}); - -add_task(function* testOpenPreferences() { - yield gCategoryUtilities.openType("experiment"); - let btn = gManagerWindow.document.getElementById("experiments-change-telemetry"); - if (!gUseInContentUI) { - is_element_hidden(btn, "Change telemetry button not enabled in out of window UI."); - info("Skipping preferences open test because not using in-content UI."); - return; - } - - is_element_visible(btn, "Change telemetry button visible in in-content UI."); - - let deferred = Promise.defer(); - Services.obs.addObserver(function observer(prefWin, topic, data) { - Services.obs.removeObserver(observer, "advanced-pane-loaded"); - info("Advanced preference pane opened."); - executeSoon(function() { - // We want this test to fail if the preferences pane changes. - let el = prefWin.document.getElementById("dataChoicesPanel"); - is_element_visible(el); - - prefWin.close(); - info("Closed preferences pane."); - - deferred.resolve(); - }); - }, "advanced-pane-loaded", false); - - info("Loading preferences pane."); - // We need to focus before synthesizing the mouse event (bug 1240052) as - // synthesizeMouseAtCenter currently only synthesizes the mouse in the child process. - // This can cause some subtle differences if the child isn't focused. - yield SimpleTest.promiseFocus(); - yield BrowserTestUtils.synthesizeMouseAtCenter("#experiments-change-telemetry", {}, - gBrowser.selectedBrowser); - - yield deferred.promise; -}); - -add_task(function* testButtonPresence() { - yield gCategoryUtilities.openType("experiment"); - let item = get_addon_element(gManagerWindow, "test-experiment1@experiments.mozilla.org"); - Assert.ok(item, "Got add-on element."); - item.parentNode.ensureElementIsVisible(item); - - let el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "remove-btn"); - // Corresponds to the uninstall permission. - is_element_visible(el, "Remove button is visible."); - // Corresponds to lack of disable permission. - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "disable-btn"); - is_element_hidden(el, "Disable button not visible."); - // Corresponds to lack of enable permission. - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "enable-btn"); - is_element_hidden(el, "Enable button not visible."); -}); - -// Remove the add-on we've been testing with. -add_task(function* testCleanup() { - yield AddonManagerTesting.uninstallAddonByID("test-experiment1@experiments.mozilla.org"); - // Verify some conditions, just in case. - let addons = yield getExperimentAddons(); - Assert.equal(addons.length, 0, "No experiment add-ons are installed."); -}); - -// The following tests should ideally live in browser/experiments/. However, -// they rely on some of the helper functions from head.js, which can't easily -// be consumed from other directories. So, they live here. - -add_task(function* testActivateExperiment() { - if (!gExperiments) { - info("Skipping experiments test because that feature isn't available."); - return; - } - - gHttpServer = new HttpServer(); - gHttpServer.start(-1); - let root = "http://localhost:" + gHttpServer.identity.primaryPort + "/"; - gHttpServer.registerPathHandler("/manifest", (request, response) => { - response.setStatusLine(null, 200, "OK"); - response.write(JSON.stringify({ - "version": 1, - "experiments": [ - { - id: "experiment-1", - xpiURL: TESTROOT + "addons/browser_experiment1.xpi", - xpiHash: "IRRELEVANT", - startTime: Date.now() / 1000 - 3600, - endTime: Date.now() / 1000 + 3600, - maxActiveSeconds: 600, - appName: [Services.appinfo.name], - channel: [gExperiments._policy.updatechannel()], - }, - ], - })); - response.processAsync(); - response.finish(); - }); - - gSavedManifestURI = Services.prefs.getCharPref("experiments.manifest.uri"); - Services.prefs.setCharPref("experiments.manifest.uri", root + "manifest"); - - // We need to remove the cache file to help ensure consistent state. - yield OS.File.remove(gExperiments._cacheFilePath); - - Services.prefs.setBoolPref("toolkit.telemetry.enabled", true); - Services.prefs.setBoolPref("experiments.enabled", true); - - info("Initializing experiments service."); - yield gExperiments.init(); - info("Experiments service finished first run."); - - // Check conditions, just to be sure. - let experiments = yield gExperiments.getExperiments(); - Assert.equal(experiments.length, 0, "No experiments known to the service."); - - // This makes testing easier. - gExperiments._policy.ignoreHashes = true; - - info("Manually updating experiments manifest."); - yield gExperiments.updateManifest(); - info("Experiments update complete."); - - let deferred = Promise.defer(); - gHttpServer.stop(() => { - gHttpServer = null; - - info("getting experiment by ID"); - AddonManager.getAddonByID("test-experiment1@experiments.mozilla.org", (addon) => { - Assert.ok(addon, "Add-on installed via Experiments manager."); - - deferred.resolve(); - }); - }); - - yield deferred.promise; - - Assert.ok(gCategoryUtilities.isTypeVisible, "experiment", "Experiment tab visible."); - yield gCategoryUtilities.openType("experiment"); - let el = gManagerWindow.document.getElementsByClassName("experiment-info-container")[0]; - is_element_visible(el, "Experiment info is visible on experiment tab."); -}); - -add_task(function* testDeactivateExperiment() { - if (!gExperiments) { - return; - } - - // Fake an empty manifest to purge data from previous manifest. - yield gExperiments._updateExperiments({ - "version": 1, - "experiments": [], - }); - - yield gExperiments.disableExperiment("testing"); - - // We should have a record of the previously-active experiment. - let experiments = yield gExperiments.getExperiments(); - Assert.equal(experiments.length, 1, "1 experiment is known."); - Assert.equal(experiments[0].active, false, "Experiment is not active."); - - // We should have a previous experiment in the add-ons manager. - let deferred = Promise.defer(); - AddonManager.getAddonsByTypes(["experiment"], (addons) => { - deferred.resolve(addons); - }); - let addons = yield deferred.promise; - Assert.equal(addons.length, 1, "1 experiment add-on known."); - Assert.ok(addons[0].appDisabled, "It is a previous experiment."); - Assert.equal(addons[0].id, "experiment-1", "Add-on ID matches expected."); - - // Verify the UI looks sane. - - Assert.ok(gCategoryUtilities.isTypeVisible("experiment"), "Experiment tab visible."); - let item = get_addon_element(gManagerWindow, "experiment-1"); - Assert.ok(item, "Got add-on element."); - Assert.ok(!item.active, "Element should not be active."); - item.parentNode.ensureElementIsVisible(item); - - // User control buttons should not be present because previous experiments - // should have no permissions. - let el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "remove-btn"); - is_element_hidden(el, "Remove button is not visible."); - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "disable-btn"); - is_element_hidden(el, "Disable button is not visible."); - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "enable-btn"); - is_element_hidden(el, "Enable button is not visible."); - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "preferences-btn"); - is_element_hidden(el, "Preferences button is not visible."); -}); - -add_task(function* testActivateRealExperiments() { - if (!gExperiments) { - info("Skipping experiments test because that feature isn't available."); - return; - } - - yield gExperiments._updateExperiments({ - "version": 1, - "experiments": [ - { - id: "experiment-2", - xpiURL: TESTROOT + "addons/browser_experiment1.xpi", - xpiHash: "IRRELEVANT", - startTime: Date.now() / 1000 - 3600, - endTime: Date.now() / 1000 + 3600, - maxActiveSeconds: 600, - appName: [Services.appinfo.name], - channel: [gExperiments._policy.updatechannel()], - }, - ], - }); - yield gExperiments._run(); - - // Check the active experiment. - - let item = get_addon_element(gManagerWindow, "test-experiment1@experiments.mozilla.org"); - Assert.ok(item, "Got add-on element."); - item.parentNode.ensureElementIsVisible(item); - - let el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "experiment-state"); - is_element_visible(el, "Experiment state label should be visible."); - if (gIsEnUsLocale) { - Assert.equal(el.value, "Active"); - } - - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "experiment-time"); - is_element_visible(el, "Experiment time label should be visible."); - if (gIsEnUsLocale) { - Assert.equal(el.value, "Less than a day remaining"); - } - - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "error-container"); - is_element_hidden(el, "error-container should be hidden."); - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "warning-container"); - is_element_hidden(el, "warning-container should be hidden."); - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "pending-container"); - is_element_hidden(el, "pending-container should be hidden."); - let { version } = yield get_tooltip_info(item); - Assert.equal(version, undefined, "version should be hidden."); - el = item.ownerDocument.getAnonymousElementByAttribute(item, "class", "disabled-postfix"); - is_element_hidden(el, "disabled-postfix should be hidden."); - el = item.ownerDocument.getAnonymousElementByAttribute(item, "class", "update-postfix"); - is_element_hidden(el, "update-postfix should be hidden."); - el = item.ownerDocument.getAnonymousElementByAttribute(item, "class", "experiment-bullet"); - is_element_visible(el, "experiment-bullet should be visible."); - - // Check the previous experiment. - - item = get_addon_element(gManagerWindow, "experiment-1"); - Assert.ok(item, "Got add-on element."); - item.parentNode.ensureElementIsVisible(item); - - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "experiment-state"); - is_element_visible(el, "Experiment state label should be visible."); - if (gIsEnUsLocale) { - Assert.equal(el.value, "Complete"); - } - - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "experiment-time"); - is_element_visible(el, "Experiment time label should be visible."); - if (gIsEnUsLocale) { - Assert.equal(el.value, "Less than a day ago"); - } - - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "error-container"); - is_element_hidden(el, "error-container should be hidden."); - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "warning-container"); - is_element_hidden(el, "warning-container should be hidden."); - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "pending-container"); - is_element_hidden(el, "pending-container should be hidden."); - ({ version } = yield get_tooltip_info(item)); - Assert.equal(version, undefined, "version should be hidden."); - el = item.ownerDocument.getAnonymousElementByAttribute(item, "class", "disabled-postfix"); - is_element_hidden(el, "disabled-postfix should be hidden."); - el = item.ownerDocument.getAnonymousElementByAttribute(item, "class", "update-postfix"); - is_element_hidden(el, "update-postfix should be hidden."); - el = item.ownerDocument.getAnonymousElementByAttribute(item, "class", "experiment-bullet"); - is_element_visible(el, "experiment-bullet should be visible."); - - // Install an "older" experiment. - - yield gExperiments.disableExperiment("experiment-2"); - - let now = Date.now(); - let fakeNow = now - 5 * MS_IN_ONE_DAY; - defineNow(gExperiments._policy, fakeNow); - - yield gExperiments._updateExperiments({ - "version": 1, - "experiments": [ - { - id: "experiment-3", - xpiURL: TESTROOT + "addons/browser_experiment1.xpi", - xpiHash: "IRRELEVANT", - startTime: fakeNow / 1000 - SEC_IN_ONE_DAY, - endTime: now / 1000 + 10 * SEC_IN_ONE_DAY, - maxActiveSeconds: 100 * SEC_IN_ONE_DAY, - appName: [Services.appinfo.name], - channel: [gExperiments._policy.updatechannel()], - }, - ], - }); - yield gExperiments._run(); - - // Check the active experiment. - - item = get_addon_element(gManagerWindow, "test-experiment1@experiments.mozilla.org"); - Assert.ok(item, "Got add-on element."); - item.parentNode.ensureElementIsVisible(item); - - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "experiment-state"); - is_element_visible(el, "Experiment state label should be visible."); - if (gIsEnUsLocale) { - Assert.equal(el.value, "Active"); - } - - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "experiment-time"); - is_element_visible(el, "Experiment time label should be visible."); - if (gIsEnUsLocale) { - Assert.equal(el.value, "10 days remaining"); - } - - // Disable it and check it's previous experiment entry. - - yield gExperiments.disableExperiment("experiment-3"); - - item = get_addon_element(gManagerWindow, "experiment-3"); - Assert.ok(item, "Got add-on element."); - item.parentNode.ensureElementIsVisible(item); - - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "experiment-state"); - is_element_visible(el, "Experiment state label should be visible."); - if (gIsEnUsLocale) { - Assert.equal(el.value, "Complete"); - } - - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "experiment-time"); - is_element_visible(el, "Experiment time label should be visible."); - if (gIsEnUsLocale) { - Assert.equal(el.value, "5 days ago"); - } -}); - -add_task(function* testDetailView() { - if (!gExperiments) { - info("Skipping experiments test because that feature isn't available."); - return; - } - - defineNow(gExperiments._policy, Date.now()); - yield gExperiments._updateExperiments({ - "version": 1, - "experiments": [ - { - id: "experiment-4", - xpiURL: TESTROOT + "addons/browser_experiment1.xpi", - xpiHash: "IRRELEVANT", - startTime: Date.now() / 1000 - 3600, - endTime: Date.now() / 1000 + 3600, - maxActiveSeconds: 600, - appName: [Services.appinfo.name], - channel: [gExperiments._policy.updatechannel()], - }, - ], - }); - yield gExperiments._run(); - - // Check active experiment. - - yield openDetailsView("test-experiment1@experiments.mozilla.org"); - - let el = gManagerWindow.document.getElementById("detail-experiment-state"); - is_element_visible(el, "Experiment state label should be visible."); - if (gIsEnUsLocale) { - Assert.equal(el.value, "Active"); - } - - el = gManagerWindow.document.getElementById("detail-experiment-time"); - is_element_visible(el, "Experiment time label should be visible."); - if (gIsEnUsLocale) { - Assert.equal(el.value, "Less than a day remaining"); - } - - el = gManagerWindow.document.getElementById("detail-version"); - is_element_hidden(el, "detail-version should be hidden."); - el = gManagerWindow.document.getElementById("detail-creator"); - is_element_hidden(el, "detail-creator should be hidden."); - el = gManagerWindow.document.getElementById("detail-experiment-bullet"); - is_element_visible(el, "experiment-bullet should be visible."); - - // Check previous experiment. - - yield gCategoryUtilities.openType("experiment"); - yield openDetailsView("experiment-3"); - - el = gManagerWindow.document.getElementById("detail-experiment-state"); - is_element_visible(el, "Experiment state label should be visible."); - if (gIsEnUsLocale) { - Assert.equal(el.value, "Complete"); - } - - el = gManagerWindow.document.getElementById("detail-experiment-time"); - is_element_visible(el, "Experiment time label should be visible."); - if (gIsEnUsLocale) { - Assert.equal(el.value, "5 days ago"); - } - - el = gManagerWindow.document.getElementById("detail-version"); - is_element_hidden(el, "detail-version should be hidden."); - el = gManagerWindow.document.getElementById("detail-creator"); - is_element_hidden(el, "detail-creator should be hidden."); - el = gManagerWindow.document.getElementById("detail-experiment-bullet"); - is_element_visible(el, "experiment-bullet should be visible."); -}); - -add_task(function* testRemoveAndUndo() { - if (!gExperiments) { - info("Skipping experiments test because that feature isn't available."); - return; - } - - yield gCategoryUtilities.openType("experiment"); - - let addon = get_addon_element(gManagerWindow, "test-experiment1@experiments.mozilla.org"); - Assert.ok(addon, "Got add-on element."); - - yield clickRemoveButton(addon); - addon.parentNode.ensureElementIsVisible(addon); - - let el = gManagerWindow.document.getAnonymousElementByAttribute(addon, "class", "pending"); - is_element_visible(el, "Uninstall undo information should be visible."); - - yield clickUndoButton(addon); - addon = get_addon_element(gManagerWindow, "test-experiment1@experiments.mozilla.org"); - Assert.ok(addon, "Got add-on element."); -}); - -add_task(function* testCleanup() { - if (gExperiments) { - Services.prefs.clearUserPref("experiments.enabled"); - Services.prefs.setCharPref("experiments.manifest.uri", gSavedManifestURI); - - // We perform the uninit/init cycle to purge any leftover state. - yield OS.File.remove(gExperiments._cacheFilePath); - yield gExperiments.uninit(); - yield gExperiments.init(); - - Services.prefs.clearUserPref("toolkit.telemetry.enabled"); - } - - // Check post-conditions. - let addons = yield getExperimentAddons(); - Assert.equal(addons.length, 0, "No experiment add-ons are installed."); - - yield close_manager(gManagerWindow); -}); diff --git a/toolkit/profile/nsProfileLock.cpp b/toolkit/profile/nsProfileLock.cpp index 08d109224..cc9ecb62e 100644 --- a/toolkit/profile/nsProfileLock.cpp +++ b/toolkit/profile/nsProfileLock.cpp @@ -30,7 +30,7 @@ #include "prenv.h" #endif -#if defined(MOZ_WIDGET_GONK) && !defined(MOZ_CRASHREPORTER) +#if defined(MOZ_WIDGET_GONK) #include <sys/syscall.h> #endif @@ -198,7 +198,6 @@ void nsProfileLock::FatalSignalHandler(int signo case SIGILL: case SIGABRT: case SIGSEGV: -#ifndef MOZ_CRASHREPORTER // Retrigger the signal for those that can generate a core dump signal(signo, SIG_DFL); if (info->si_code <= 0) { @@ -206,7 +205,6 @@ void nsProfileLock::FatalSignalHandler(int signo break; } } -#endif return; default: break; diff --git a/toolkit/themes/linux/mozapps/jar.mn b/toolkit/themes/linux/mozapps/jar.mn index 89e6912d4..37325c0be 100644 --- a/toolkit/themes/linux/mozapps/jar.mn +++ b/toolkit/themes/linux/mozapps/jar.mn @@ -47,6 +47,9 @@ toolkit.jar: skin/classic/mozapps/extensions/selectAddons.css (extensions/selectAddons.css) skin/classic/mozapps/xpinstall/xpinstallItemGeneric.png (extensions/extensionGeneric.png) #endif + skin/classic/mozapps/passwordmgr/key.png (passwordmgr/key.png) + skin/classic/mozapps/passwordmgr/key-16.png (passwordmgr/key-16.png) + skin/classic/mozapps/passwordmgr/key-64.png (passwordmgr/key-64.png) skin/classic/mozapps/plugins/pluginGeneric.png (plugins/pluginGeneric.png) skin/classic/mozapps/plugins/pluginBlocked.png (plugins/pluginBlocked.png) skin/classic/mozapps/plugins/pluginGeneric-16.png (plugins/pluginGeneric-16.png) diff --git a/toolkit/themes/linux/mozapps/passwordmgr/key-16.png b/toolkit/themes/linux/mozapps/passwordmgr/key-16.png Binary files differnew file mode 100644 index 000000000..ac135b847 --- /dev/null +++ b/toolkit/themes/linux/mozapps/passwordmgr/key-16.png diff --git a/toolkit/themes/linux/mozapps/passwordmgr/key-64.png b/toolkit/themes/linux/mozapps/passwordmgr/key-64.png Binary files differnew file mode 100644 index 000000000..0fb69f382 --- /dev/null +++ b/toolkit/themes/linux/mozapps/passwordmgr/key-64.png diff --git a/toolkit/themes/linux/mozapps/passwordmgr/key.png b/toolkit/themes/linux/mozapps/passwordmgr/key.png Binary files differnew file mode 100644 index 000000000..b5e8afefc --- /dev/null +++ b/toolkit/themes/linux/mozapps/passwordmgr/key.png diff --git a/toolkit/themes/osx/mozapps/jar.mn b/toolkit/themes/osx/mozapps/jar.mn index 35927755b..f8ade11d9 100644 --- a/toolkit/themes/osx/mozapps/jar.mn +++ b/toolkit/themes/osx/mozapps/jar.mn @@ -83,6 +83,9 @@ toolkit.jar: skin/classic/mozapps/extensions/blocklist.css (extensions/blocklist.css) * skin/classic/mozapps/extensions/newaddon.css (extensions/newaddon.css) #endif + skin/classic/mozapps/passwordmgr/key.png (passwordmgr/key.png) + skin/classic/mozapps/passwordmgr/key-16.png (passwordmgr/key-16.png) + skin/classic/mozapps/passwordmgr/key-64.png (passwordmgr/key-64.png) skin/classic/mozapps/plugins/notifyPluginGeneric.png (plugins/notifyPluginGeneric.png) skin/classic/mozapps/plugins/pluginGeneric.png (plugins/pluginGeneric.png) skin/classic/mozapps/plugins/pluginBlocked.png (plugins/pluginBlocked.png) diff --git a/toolkit/themes/osx/mozapps/passwordmgr/key-16.png b/toolkit/themes/osx/mozapps/passwordmgr/key-16.png Binary files differnew file mode 100644 index 000000000..ac135b847 --- /dev/null +++ b/toolkit/themes/osx/mozapps/passwordmgr/key-16.png diff --git a/toolkit/themes/osx/mozapps/passwordmgr/key-64.png b/toolkit/themes/osx/mozapps/passwordmgr/key-64.png Binary files differnew file mode 100644 index 000000000..0fb69f382 --- /dev/null +++ b/toolkit/themes/osx/mozapps/passwordmgr/key-64.png diff --git a/toolkit/themes/osx/mozapps/passwordmgr/key.png b/toolkit/themes/osx/mozapps/passwordmgr/key.png Binary files differnew file mode 100644 index 000000000..b5e8afefc --- /dev/null +++ b/toolkit/themes/osx/mozapps/passwordmgr/key.png diff --git a/toolkit/themes/shared/non-mac.jar.inc.mn b/toolkit/themes/shared/non-mac.jar.inc.mn index a783bbb3c..637537d9d 100644 --- a/toolkit/themes/shared/non-mac.jar.inc.mn +++ b/toolkit/themes/shared/non-mac.jar.inc.mn @@ -77,6 +77,8 @@ skin/classic/global/icons/Landscape.png (../../windows/global/icons/Landscape.png) skin/classic/global/icons/Question.png (../../windows/global/icons/Question.png) skin/classic/global/icons/question-16.png (../../windows/global/icons/question-16.png) + skin/classic/global/icons/question-32.png (../../windows/global/icons/question-32.png) + skin/classic/global/icons/question-48.png (../../windows/global/icons/question-48.png) skin/classic/global/icons/question-64.png (../../windows/global/icons/question-64.png) skin/classic/global/icons/resizer-rtl.png (../../windows/global/icons/resizer-rtl.png) skin/classic/global/icons/Restore.gif (../../windows/global/icons/Restore.gif) diff --git a/toolkit/themes/windows/global/icons/question-32.png b/toolkit/themes/windows/global/icons/question-32.png Binary files differnew file mode 100644 index 000000000..7c80831b0 --- /dev/null +++ b/toolkit/themes/windows/global/icons/question-32.png diff --git a/toolkit/themes/windows/global/icons/question-48.png b/toolkit/themes/windows/global/icons/question-48.png Binary files differnew file mode 100644 index 000000000..dd2b21874 --- /dev/null +++ b/toolkit/themes/windows/global/icons/question-48.png diff --git a/toolkit/themes/windows/mozapps/jar.mn b/toolkit/themes/windows/mozapps/jar.mn index 29203811f..0d77a4e79 100644 --- a/toolkit/themes/windows/mozapps/jar.mn +++ b/toolkit/themes/windows/mozapps/jar.mn @@ -68,9 +68,13 @@ toolkit.jar: * skin/classic/mozapps/xpinstall/xpinstallConfirm.css (extensions/xpinstallConfirm.css) skin/classic/mozapps/xpinstall/xpinstallItemGeneric.png (extensions/extensionGeneric.png) #endif + skin/classic/mozapps/passwordmgr/key.png (passwordmgr/key.png) + skin/classic/mozapps/passwordmgr/key-16.png (passwordmgr/key-16.png) + skin/classic/mozapps/passwordmgr/key-64.png (passwordmgr/key-64.png) skin/classic/mozapps/plugins/pluginGeneric.png (plugins/pluginGeneric.png) skin/classic/mozapps/plugins/pluginBlocked.png (plugins/pluginBlocked.png) skin/classic/mozapps/plugins/pluginGeneric-16.png (plugins/pluginGeneric-16.png) + skin/classic/mozapps/plugins/pluginGeneric-48.png (plugins/pluginGeneric-48.png) skin/classic/mozapps/profile/profileicon.png (profile/profileicon.png) skin/classic/mozapps/update/updates.css (update/updates.css) skin/classic/mozapps/viewsource/viewsource.css (viewsource/viewsource.css) diff --git a/toolkit/themes/windows/mozapps/passwordmgr/key-16.png b/toolkit/themes/windows/mozapps/passwordmgr/key-16.png Binary files differnew file mode 100644 index 000000000..ac135b847 --- /dev/null +++ b/toolkit/themes/windows/mozapps/passwordmgr/key-16.png diff --git a/toolkit/themes/windows/mozapps/passwordmgr/key-64.png b/toolkit/themes/windows/mozapps/passwordmgr/key-64.png Binary files differnew file mode 100644 index 000000000..0fb69f382 --- /dev/null +++ b/toolkit/themes/windows/mozapps/passwordmgr/key-64.png diff --git a/toolkit/themes/windows/mozapps/passwordmgr/key.png b/toolkit/themes/windows/mozapps/passwordmgr/key.png Binary files differnew file mode 100644 index 000000000..b5e8afefc --- /dev/null +++ b/toolkit/themes/windows/mozapps/passwordmgr/key.png diff --git a/toolkit/themes/windows/mozapps/plugins/pluginGeneric-16.png b/toolkit/themes/windows/mozapps/plugins/pluginGeneric-16.png Binary files differindex 5d796cc4c..080b0e502 100644 --- a/toolkit/themes/windows/mozapps/plugins/pluginGeneric-16.png +++ b/toolkit/themes/windows/mozapps/plugins/pluginGeneric-16.png diff --git a/toolkit/themes/windows/mozapps/plugins/pluginGeneric-48.png b/toolkit/themes/windows/mozapps/plugins/pluginGeneric-48.png Binary files differnew file mode 100644 index 000000000..173679448 --- /dev/null +++ b/toolkit/themes/windows/mozapps/plugins/pluginGeneric-48.png diff --git a/toolkit/themes/windows/mozapps/plugins/pluginGeneric.png b/toolkit/themes/windows/mozapps/plugins/pluginGeneric.png Binary files differindex d8b270ae5..1fcbf154e 100644 --- a/toolkit/themes/windows/mozapps/plugins/pluginGeneric.png +++ b/toolkit/themes/windows/mozapps/plugins/pluginGeneric.png diff --git a/toolkit/toolkit.mozbuild b/toolkit/toolkit.mozbuild index a782acd3a..3b3bf80ae 100644 --- a/toolkit/toolkit.mozbuild +++ b/toolkit/toolkit.mozbuild @@ -181,10 +181,6 @@ if CONFIG['ENABLE_TESTS']: '/testing/web-platform', ] - # The file id utility requires breakpad libraries. - if CONFIG['MOZ_CRASHREPORTER']: - DIRS += ['/testing/tools/fileid'] - if CONFIG['MOZ_MEMORY']: DIRS += ['/memory/gtest'] diff --git a/toolkit/xre/nsAndroidStartup.cpp b/toolkit/xre/nsAndroidStartup.cpp index a88c58e5d..47b9ec6e5 100644 --- a/toolkit/xre/nsAndroidStartup.cpp +++ b/toolkit/xre/nsAndroidStartup.cpp @@ -26,15 +26,6 @@ GeckoStart(JNIEnv* env, char* data, const nsXREAppData* appData) { mozilla::jni::SetGeckoThreadEnv(env); -#ifdef MOZ_CRASHREPORTER - const struct mapping_info *info = getLibraryMapping(); - while (info->name) { - CrashReporter::AddLibraryMapping(info->name, info->base, - info->len, info->offset); - info++; - } -#endif - if (!data) { LOG("Failed to get arguments for GeckoStart\n"); return; diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index 1b5c2ed75..b65a4093f 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -190,17 +190,6 @@ #include "jprof.h" #endif -#ifdef MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" -#include "nsICrashReporter.h" -#define NS_CRASHREPORTER_CONTRACTID "@mozilla.org/toolkit/crash-reporter;1" -#include "nsIPrefService.h" -#include "nsIMemoryInfoDumper.h" -#if defined(XP_LINUX) && !defined(ANDROID) -#include "mozilla/widget/LSBUtils.h" -#endif -#endif - #include "base/command_line.h" #include "GTestRunner.h" @@ -646,10 +635,6 @@ class nsXULAppInfo : public nsIXULAppInfo, #ifdef XP_WIN public nsIWinAppHelper, #endif -#ifdef MOZ_CRASHREPORTER - public nsICrashReporter, - public nsIFinishDumpingCallback, -#endif public nsIXULRuntime { @@ -660,10 +645,6 @@ public: NS_DECL_NSIXULAPPINFO NS_DECL_NSIXULRUNTIME NS_DECL_NSIOBSERVER -#ifdef MOZ_CRASHREPORTER - NS_DECL_NSICRASHREPORTER - NS_DECL_NSIFINISHDUMPINGCALLBACK -#endif #ifdef XP_WIN NS_DECL_NSIWINAPPHELPER #endif @@ -676,10 +657,6 @@ NS_INTERFACE_MAP_BEGIN(nsXULAppInfo) #ifdef XP_WIN NS_INTERFACE_MAP_ENTRY(nsIWinAppHelper) #endif -#ifdef MOZ_CRASHREPORTER - NS_INTERFACE_MAP_ENTRY(nsICrashReporter) - NS_INTERFACE_MAP_ENTRY(nsIFinishDumpingCallback) -#endif NS_INTERFACE_MAP_ENTRY(nsIPlatformInfo) NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIXULAppInfo, gAppData || XRE_IsContentProcess()) @@ -1004,12 +981,7 @@ nsXULAppInfo::GetReplacedLockTime(PRTime *aReplacedLockTime) NS_IMETHODIMP nsXULAppInfo::GetLastRunCrashID(nsAString &aLastRunCrashID) { -#ifdef MOZ_CRASHREPORTER - CrashReporter::GetLastRunCrashID(aLastRunCrashID); - return NS_OK; -#else return NS_ERROR_NOT_IMPLEMENTED; -#endif } NS_IMETHODIMP @@ -1117,219 +1089,6 @@ nsXULAppInfo::GetUserCanElevate(bool *aUserCanElevate) } #endif -#ifdef MOZ_CRASHREPORTER -NS_IMETHODIMP -nsXULAppInfo::GetEnabled(bool *aEnabled) -{ - *aEnabled = CrashReporter::GetEnabled(); - return NS_OK; -} - -NS_IMETHODIMP -nsXULAppInfo::SetEnabled(bool aEnabled) -{ - if (aEnabled) { - if (CrashReporter::GetEnabled()) { - // no point in erroring for double-enabling - return NS_OK; - } - - nsCOMPtr<nsIFile> greBinDir; - NS_GetSpecialDirectory(NS_GRE_BIN_DIR, getter_AddRefs(greBinDir)); - if (!greBinDir) { - return NS_ERROR_FAILURE; - } - - nsCOMPtr<nsIFile> xreBinDirectory = do_QueryInterface(greBinDir); - if (!xreBinDirectory) { - return NS_ERROR_FAILURE; - } - - return CrashReporter::SetExceptionHandler(xreBinDirectory, true); - } - else { - if (!CrashReporter::GetEnabled()) { - // no point in erroring for double-disabling - return NS_OK; - } - - return CrashReporter::UnsetExceptionHandler(); - } -} - -NS_IMETHODIMP -nsXULAppInfo::GetServerURL(nsIURL** aServerURL) -{ - if (!CrashReporter::GetEnabled()) - return NS_ERROR_NOT_INITIALIZED; - - nsAutoCString data; - if (!CrashReporter::GetServerURL(data)) { - return NS_ERROR_FAILURE; - } - nsCOMPtr<nsIURI> uri; - NS_NewURI(getter_AddRefs(uri), data); - if (!uri) - return NS_ERROR_FAILURE; - - nsCOMPtr<nsIURL> url; - url = do_QueryInterface(uri); - NS_ADDREF(*aServerURL = url); - - return NS_OK; -} - -NS_IMETHODIMP -nsXULAppInfo::SetServerURL(nsIURL* aServerURL) -{ - bool schemeOk; - // only allow https or http URLs - nsresult rv = aServerURL->SchemeIs("https", &schemeOk); - NS_ENSURE_SUCCESS(rv, rv); - if (!schemeOk) { - rv = aServerURL->SchemeIs("http", &schemeOk); - NS_ENSURE_SUCCESS(rv, rv); - - if (!schemeOk) - return NS_ERROR_INVALID_ARG; - } - nsAutoCString spec; - rv = aServerURL->GetSpec(spec); - NS_ENSURE_SUCCESS(rv, rv); - - return CrashReporter::SetServerURL(spec); -} - -NS_IMETHODIMP -nsXULAppInfo::GetMinidumpPath(nsIFile** aMinidumpPath) -{ - if (!CrashReporter::GetEnabled()) - return NS_ERROR_NOT_INITIALIZED; - - nsAutoString path; - if (!CrashReporter::GetMinidumpPath(path)) - return NS_ERROR_FAILURE; - - nsresult rv = NS_NewLocalFile(path, false, aMinidumpPath); - NS_ENSURE_SUCCESS(rv, rv); - return NS_OK; -} - -NS_IMETHODIMP -nsXULAppInfo::SetMinidumpPath(nsIFile* aMinidumpPath) -{ - nsAutoString path; - nsresult rv = aMinidumpPath->GetPath(path); - NS_ENSURE_SUCCESS(rv, rv); - return CrashReporter::SetMinidumpPath(path); -} - -NS_IMETHODIMP -nsXULAppInfo::AnnotateCrashReport(const nsACString& key, - const nsACString& data) -{ - return CrashReporter::AnnotateCrashReport(key, data); -} - -NS_IMETHODIMP -nsXULAppInfo::AppendAppNotesToCrashReport(const nsACString& data) -{ - return CrashReporter::AppendAppNotesToCrashReport(data); -} - -NS_IMETHODIMP -nsXULAppInfo::RegisterAppMemory(uint64_t pointer, - uint64_t len) -{ - return CrashReporter::RegisterAppMemory((void *)pointer, len); -} - -NS_IMETHODIMP -nsXULAppInfo::WriteMinidumpForException(void* aExceptionInfo) -{ -#ifdef XP_WIN32 - return CrashReporter::WriteMinidumpForException(static_cast<EXCEPTION_POINTERS*>(aExceptionInfo)); -#else - return NS_ERROR_NOT_IMPLEMENTED; -#endif -} - -NS_IMETHODIMP -nsXULAppInfo::AppendObjCExceptionInfoToAppNotes(void* aException) -{ -#ifdef XP_MACOSX - return CrashReporter::AppendObjCExceptionInfoToAppNotes(aException); -#else - return NS_ERROR_NOT_IMPLEMENTED; -#endif -} - -NS_IMETHODIMP -nsXULAppInfo::GetSubmitReports(bool* aEnabled) -{ - return CrashReporter::GetSubmitReports(aEnabled); -} - -NS_IMETHODIMP -nsXULAppInfo::SetSubmitReports(bool aEnabled) -{ - return CrashReporter::SetSubmitReports(aEnabled); -} - -NS_IMETHODIMP -nsXULAppInfo::UpdateCrashEventsDir() -{ - CrashReporter::UpdateCrashEventsDir(); - return NS_OK; -} - -NS_IMETHODIMP -nsXULAppInfo::SaveMemoryReport() -{ - if (!CrashReporter::GetEnabled()) { - return NS_ERROR_NOT_INITIALIZED; - } - nsCOMPtr<nsIFile> file; - nsresult rv = CrashReporter::GetDefaultMemoryReportFile(getter_AddRefs(file)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - nsString path; - file->GetPath(path); - - nsCOMPtr<nsIMemoryInfoDumper> dumper = - do_GetService("@mozilla.org/memory-info-dumper;1"); - if (NS_WARN_IF(!dumper)) { - return NS_ERROR_UNEXPECTED; - } - - rv = dumper->DumpMemoryReportsToNamedFile(path, this, file, true /* anonymize */); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - return NS_OK; -} - -NS_IMETHODIMP -nsXULAppInfo::SetTelemetrySessionId(const nsACString& id) -{ - CrashReporter::SetTelemetrySessionId(id); - return NS_OK; -} - -// This method is from nsIFInishDumpingCallback. -NS_IMETHODIMP -nsXULAppInfo::Callback(nsISupports* aData) -{ - nsCOMPtr<nsIFile> file = do_QueryInterface(aData); - MOZ_ASSERT(file); - - CrashReporter::SetMemoryReportFile(file); - return NS_OK; -} -#endif - static const nsXULAppInfo kAppInfo; static nsresult AppInfoConstructor(nsISupports* aOuter, REFNSIID aIID, void **aResult) @@ -1434,9 +1193,6 @@ static const mozilla::Module::CIDEntry kXRECIDs[] = { static const mozilla::Module::ContractIDEntry kXREContracts[] = { { XULAPPINFO_SERVICE_CONTRACTID, &kAPPINFO_CID }, { XULRUNTIME_SERVICE_CONTRACTID, &kAPPINFO_CID }, -#ifdef MOZ_CRASHREPORTER - { NS_CRASHREPORTER_CONTRACTID, &kAPPINFO_CID }, -#endif { NS_PROFILESERVICE_CONTRACTID, &kProfileServiceCID }, { NS_NATIVEAPPSUPPORT_CONTRACTID, &kNativeAppSupportCID }, { nullptr } @@ -2763,33 +2519,6 @@ static void RestoreStateForAppInitiatedRestart() } } -#ifdef MOZ_CRASHREPORTER -// When we first initialize the crash reporter we don't have a profile, -// so we set the minidump path to $TEMP. Once we have a profile, -// we set it to $PROFILE/minidumps, creating the directory -// if needed. -static void MakeOrSetMinidumpPath(nsIFile* profD) -{ - nsCOMPtr<nsIFile> dumpD; - profD->Clone(getter_AddRefs(dumpD)); - - if (dumpD) { - bool fileExists; - //XXX: do some more error checking here - dumpD->Append(NS_LITERAL_STRING("minidumps")); - dumpD->Exists(&fileExists); - if (!fileExists) { - nsresult rv = dumpD->Create(nsIFile::DIRECTORY_TYPE, 0700); - NS_ENSURE_SUCCESS_VOID(rv); - } - - nsAutoString pathStr; - if (NS_SUCCEEDED(dumpD->GetPath(pathStr))) - CrashReporter::SetMinidumpPath(pathStr); - } -} -#endif - const nsXREAppData* gAppData = nullptr; #ifdef MOZ_WIDGET_GTK @@ -3215,94 +2944,6 @@ XREMain::XRE_mainInit(bool* aExitFlag) if (NS_FAILED(rv)) return 1; -#ifdef MOZ_CRASHREPORTER - if (EnvHasValue("MOZ_CRASHREPORTER")) { - mAppData->flags |= NS_XRE_ENABLE_CRASH_REPORTER; - } - - nsCOMPtr<nsIFile> xreBinDirectory; - xreBinDirectory = mDirProvider.GetGREBinDir(); - - if ((mAppData->flags & NS_XRE_ENABLE_CRASH_REPORTER) && - NS_SUCCEEDED( - CrashReporter::SetExceptionHandler(xreBinDirectory))) { - nsCOMPtr<nsIFile> file; - rv = mDirProvider.GetUserAppDataDirectory(getter_AddRefs(file)); - if (NS_SUCCEEDED(rv)) { - CrashReporter::SetUserAppDataDirectory(file); - } - if (mAppData->crashReporterURL) - CrashReporter::SetServerURL(nsDependentCString(mAppData->crashReporterURL)); - - // We overwrite this once we finish starting up. - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("StartupCrash"), - NS_LITERAL_CSTRING("1")); - - // pass some basic info from the app data - if (mAppData->vendor) - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Vendor"), - nsDependentCString(mAppData->vendor)); - if (mAppData->name) - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ProductName"), - nsDependentCString(mAppData->name)); - if (mAppData->ID) - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ProductID"), - nsDependentCString(mAppData->ID)); - if (mAppData->version) - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Version"), - nsDependentCString(mAppData->version)); - if (mAppData->buildID) - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("BuildID"), - nsDependentCString(mAppData->buildID)); - - nsDependentCString releaseChannel(NS_STRINGIFY(MOZ_UPDATE_CHANNEL)); - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ReleaseChannel"), - releaseChannel); -#ifdef MOZ_LINKER - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("CrashAddressLikelyWrong"), - IsSignalHandlingBroken() ? NS_LITERAL_CSTRING("1") - : NS_LITERAL_CSTRING("0")); -#endif - -#ifdef XP_WIN - nsAutoString appInitDLLs; - if (widget::WinUtils::GetAppInitDLLs(appInitDLLs)) { - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AppInitDLLs"), - NS_ConvertUTF16toUTF8(appInitDLLs)); - } -#endif - - CrashReporter::SetRestartArgs(gArgc, gArgv); - - // annotate other data (user id etc) - nsCOMPtr<nsIFile> userAppDataDir; - if (NS_SUCCEEDED(mDirProvider.GetUserAppDataDirectory( - getter_AddRefs(userAppDataDir)))) { - CrashReporter::SetupExtraData(userAppDataDir, - nsDependentCString(mAppData->buildID)); - - // see if we have a crashreporter-override.ini in the application directory - nsCOMPtr<nsIFile> overrideini; - bool exists; - if (NS_SUCCEEDED(mDirProvider.GetAppDir()->Clone(getter_AddRefs(overrideini))) && - NS_SUCCEEDED(overrideini->AppendNative(NS_LITERAL_CSTRING("crashreporter-override.ini"))) && - NS_SUCCEEDED(overrideini->Exists(&exists)) && - exists) { -#ifdef XP_WIN - nsAutoString overridePathW; - overrideini->GetPath(overridePathW); - NS_ConvertUTF16toUTF8 overridePath(overridePathW); -#else - nsAutoCString overridePath; - overrideini->GetNativePath(overridePath); -#endif - - SaveWordToEnv("MOZ_CRASHREPORTER_STRINGS_OVERRIDE", overridePath); - } - } - } -#endif - #if defined(MOZ_SANDBOX) && defined(XP_WIN) if (mAppData->sandboxBrokerServices) { SandboxBroker::Initialize(mAppData->sandboxBrokerServices); @@ -3448,22 +3089,9 @@ XREMain::XRE_mainInit(bool* aExitFlag) } } -#ifdef MOZ_CRASHREPORTER - if (cpuUpdateRevision > 0) { - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("CPUMicrocodeVersion"), - nsPrintfCString("0x%x", - cpuUpdateRevision)); - } -#endif } #endif -#ifdef MOZ_CRASHREPORTER - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("SafeMode"), - gSafeMode ? NS_LITERAL_CSTRING("1") : - NS_LITERAL_CSTRING("0")); -#endif - // Handle --no-remote and --new-instance command line arguments. Setup // the environment to better accommodate other components and various // restart scenarios. @@ -3523,102 +3151,6 @@ XREMain::XRE_mainInit(bool* aExitFlag) return 0; } -#ifdef MOZ_CRASHREPORTER -#ifdef XP_WIN -/** - * Uses WMI to read some manufacturer information that may be useful for - * diagnosing hardware-specific crashes. This function is best-effort; failures - * shouldn't burden the caller. COM must be initialized before calling. - */ -static void AnnotateSystemManufacturer() -{ - RefPtr<IWbemLocator> locator; - - HRESULT hr = CoCreateInstance(CLSID_WbemLocator, nullptr, CLSCTX_INPROC_SERVER, - IID_IWbemLocator, getter_AddRefs(locator)); - - if (FAILED(hr)) { - return; - } - - RefPtr<IWbemServices> services; - - hr = locator->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), nullptr, nullptr, nullptr, - 0, nullptr, nullptr, getter_AddRefs(services)); - - if (FAILED(hr)) { - return; - } - - hr = CoSetProxyBlanket(services, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr, - RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, - nullptr, EOAC_NONE); - - if (FAILED(hr)) { - return; - } - - RefPtr<IEnumWbemClassObject> enumerator; - - hr = services->ExecQuery(_bstr_t(L"WQL"), _bstr_t(L"SELECT * FROM Win32_BIOS"), - WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, - nullptr, getter_AddRefs(enumerator)); - - if (FAILED(hr) || !enumerator) { - return; - } - - RefPtr<IWbemClassObject> classObject; - ULONG results; - - hr = enumerator->Next(WBEM_INFINITE, 1, getter_AddRefs(classObject), &results); - - if (FAILED(hr) || results == 0) { - return; - } - - VARIANT value; - VariantInit(&value); - - hr = classObject->Get(L"Manufacturer", 0, &value, 0, 0); - - if (SUCCEEDED(hr) && V_VT(&value) == VT_BSTR) { - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("BIOS_Manufacturer"), - NS_ConvertUTF16toUTF8(V_BSTR(&value))); - } - - VariantClear(&value); -} - -static void PR_CALLBACK AnnotateSystemManufacturer_ThreadStart(void*) -{ - HRESULT hr = CoInitialize(nullptr); - - if (FAILED(hr)) { - return; - } - - AnnotateSystemManufacturer(); - - CoUninitialize(); -} -#endif // XP_WIN - -#if defined(XP_LINUX) && !defined(ANDROID) - -static void -AnnotateLSBRelease(void*) -{ - nsCString dist, desc, release, codename; - if (widget::lsb::GetLSBRelease(dist, desc, release, codename)) { - CrashReporter::AppendAppNotesToCrashReport(desc); - } -} - -#endif // defined(XP_LINUX) && !defined(ANDROID) - -#endif - namespace mozilla { ShutdownChecksMode gShutdownChecks = SCM_NOTHING; } // namespace mozilla @@ -4007,13 +3539,6 @@ XREMain::XRE_mainStartup(bool* aExitFlag) mozilla::Telemetry::SetProfileDir(mProfD); -#ifdef MOZ_CRASHREPORTER - if (mAppData->flags & NS_XRE_ENABLE_CRASH_REPORTER) - MakeOrSetMinidumpPath(mProfD); - - CrashReporter::SetProfileDirectory(mProfD); -#endif - nsAutoCString version; BuildVersion(version); @@ -4103,39 +3628,6 @@ XREMain::XRE_mainStartup(bool* aExitFlag) return 0; } -#if defined(MOZ_CRASHREPORTER) -#if defined(MOZ_CONTENT_SANDBOX) && !defined(MOZ_WIDGET_GONK) -void AddSandboxAnnotations() -{ - // Include the sandbox content level, regardless of platform - int level = Preferences::GetInt("security.sandbox.content.level"); - - nsAutoCString levelString; - levelString.AppendInt(level); - - CrashReporter::AnnotateCrashReport( - NS_LITERAL_CSTRING("ContentSandboxLevel"), levelString); - - // Include whether or not this instance is capable of content sandboxing - bool sandboxCapable = false; - -#if defined(XP_WIN) - // All supported Windows versions support some level of content sandboxing - sandboxCapable = true; -#elif defined(XP_MACOSX) - // All supported OS X versions are capable - sandboxCapable = true; -#elif defined(XP_LINUX) - sandboxCapable = SandboxInfo::Get().CanSandboxContent(); -#endif - - CrashReporter::AnnotateCrashReport( - NS_LITERAL_CSTRING("ContentSandboxCapable"), - sandboxCapable ? NS_LITERAL_CSTRING("1") : NS_LITERAL_CSTRING("0")); -} -#endif /* MOZ_CONTENT_SANDBOX && !MOZ_WIDGET_GONK */ -#endif /* MOZ_CRASHREPORTER */ - /* * XRE_mainRun - Command line startup, profile migration, and * the calling of appStartup->Run(). @@ -4169,40 +3661,6 @@ XREMain::XRE_mainRun() rv = mScopedXPCOM->SetWindowCreator(mNativeApp); NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); -#ifdef MOZ_CRASHREPORTER - // tell the crash reporter to also send the release channel - nsCOMPtr<nsIPrefService> prefs = do_GetService("@mozilla.org/preferences-service;1", &rv); - if (NS_SUCCEEDED(rv)) { - nsCOMPtr<nsIPrefBranch> defaultPrefBranch; - rv = prefs->GetDefaultBranch(nullptr, getter_AddRefs(defaultPrefBranch)); - - if (NS_SUCCEEDED(rv)) { - nsXPIDLCString sval; - rv = defaultPrefBranch->GetCharPref("app.update.channel", getter_Copies(sval)); - if (NS_SUCCEEDED(rv)) { - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ReleaseChannel"), - sval); - } - } - } - // Needs to be set after xpcom initialization. - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("FramePoisonBase"), - nsPrintfCString("%.16llx", uint64_t(gMozillaPoisonBase))); - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("FramePoisonSize"), - nsPrintfCString("%lu", uint32_t(gMozillaPoisonSize))); - -#ifdef XP_WIN - PR_CreateThread(PR_USER_THREAD, AnnotateSystemManufacturer_ThreadStart, 0, - PR_PRIORITY_LOW, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0); -#endif - -#if defined(XP_LINUX) && !defined(ANDROID) - PR_CreateThread(PR_USER_THREAD, AnnotateLSBRelease, 0, PR_PRIORITY_LOW, - PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0); -#endif - -#endif - if (mStartOffline) { nsCOMPtr<nsIIOService2> io (do_GetService("@mozilla.org/network/io-service;1")); NS_ENSURE_TRUE(io, NS_ERROR_FAILURE); @@ -4308,17 +3766,6 @@ XREMain::XRE_mainRun() OverrideDefaultLocaleIfNeeded(); -#ifdef MOZ_CRASHREPORTER - nsCString userAgentLocale; - // Try a localized string first. This pref is always a localized string in - // Fennec, and might be elsewhere, too. - if (NS_SUCCEEDED(Preferences::GetLocalizedCString("general.useragent.locale", &userAgentLocale))) { - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("useragent_locale"), userAgentLocale); - } else if (NS_SUCCEEDED(Preferences::GetCString("general.useragent.locale", &userAgentLocale))) { - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("useragent_locale"), userAgentLocale); - } -#endif - appStartup->GetShuttingDown(&mShuttingDown); nsCOMPtr<nsICommandLineRunner> cmdLine; @@ -4411,11 +3858,6 @@ XREMain::XRE_mainRun() (void)appStartup->DoneStartingUp(); -#ifdef MOZ_CRASHREPORTER - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("StartupCrash"), - NS_LITERAL_CSTRING("0")); -#endif - appStartup->GetShuttingDown(&mShuttingDown); } @@ -4466,21 +3908,8 @@ XREMain::XRE_mainRun() sandboxInfo.Test(SandboxInfo::kEnabledForContent)); Telemetry::Accumulate(Telemetry::SANDBOX_MEDIA_ENABLED, sandboxInfo.Test(SandboxInfo::kEnabledForMedia)); -#if defined(MOZ_CRASHREPORTER) - nsAutoCString flagsString; - flagsString.AppendInt(sandboxInfo.AsInteger()); - - CrashReporter::AnnotateCrashReport( - NS_LITERAL_CSTRING("ContentSandboxCapabilities"), flagsString); -#endif /* MOZ_CRASHREPORTER */ #endif /* MOZ_SANDBOX && XP_LINUX && !MOZ_WIDGET_GONK */ -#if defined(MOZ_CRASHREPORTER) -#if defined(MOZ_CONTENT_SANDBOX) && !defined(MOZ_WIDGET_GONK) - AddSandboxAnnotations(); -#endif /* MOZ_CONTENT_SANDBOX && !MOZ_WIDGET_GONK */ -#endif /* MOZ_CRASHREPORTER */ - { rv = appStartup->Run(); if (NS_FAILED(rv)) { @@ -4673,10 +4102,6 @@ XREMain::XRE_main(int argc, char* argv[], const nsXREAppData* aAppData) rv = LaunchChild(mNativeApp, true); } -#ifdef MOZ_CRASHREPORTER - if (mAppData->flags & NS_XRE_ENABLE_CRASH_REPORTER) - CrashReporter::UnsetExceptionHandler(); -#endif return rv == NS_ERROR_LAUNCHED_CHILD_PROCESS ? 0 : 1; } @@ -4686,11 +4111,6 @@ XREMain::XRE_main(int argc, char* argv[], const nsXREAppData* aAppData) MOZ_gdk_display_close(mGdkDisplay); #endif -#ifdef MOZ_CRASHREPORTER - if (mAppData->flags & NS_XRE_ENABLE_CRASH_REPORTER) - CrashReporter::UnsetExceptionHandler(); -#endif - XRE_DeinitCommandLine(); return NS_FAILED(rv) ? 1 : 0; @@ -4863,12 +4283,6 @@ MultiprocessBlockPolicy() { bool addonsCanDisable = Preferences::GetBool("extensions.e10sBlocksEnabling", false); bool disabledByAddons = Preferences::GetBool("extensions.e10sBlockedByAddons", false); -#ifdef MOZ_CRASHREPORTER - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AddonsShouldHaveBlockedE10s"), - disabledByAddons ? NS_LITERAL_CSTRING("1") - : NS_LITERAL_CSTRING("0")); -#endif - if (addonsCanDisable && disabledByAddons) { gMultiprocessBlockPolicy = kE10sDisabledForAddons; return gMultiprocessBlockPolicy; diff --git a/toolkit/xre/nsEmbedFunctions.cpp b/toolkit/xre/nsEmbedFunctions.cpp index 1e67ea7ce..4a612e495 100644 --- a/toolkit/xre/nsEmbedFunctions.cpp +++ b/toolkit/xre/nsEmbedFunctions.cpp @@ -239,30 +239,6 @@ XRE_SetProcessType(const char* aProcessTypeString) } } -#if defined(MOZ_CRASHREPORTER) -// FIXME/bug 539522: this out-of-place function is stuck here because -// IPDL wants access to this crashreporter interface, and -// crashreporter is built in such a way to make that awkward -bool -XRE_TakeMinidumpForChild(uint32_t aChildPid, nsIFile** aDump, - uint32_t* aSequence) -{ - return CrashReporter::TakeMinidumpForChild(aChildPid, aDump, aSequence); -} - -bool -XRE_SetRemoteExceptionHandler(const char* aPipe/*= 0*/) -{ -#if defined(XP_WIN) || defined(XP_MACOSX) - return CrashReporter::SetRemoteExceptionHandler(nsDependentCString(aPipe)); -#elif defined(OS_LINUX) - return CrashReporter::SetRemoteExceptionHandler(); -#else -# error "OOP crash reporter unsupported on this platform" -#endif -} -#endif // if defined(MOZ_CRASHREPORTER) - #if defined(XP_WIN) void SetTaskbarGroupId(const nsString& aId) @@ -273,22 +249,6 @@ SetTaskbarGroupId(const nsString& aId) } #endif -#if defined(MOZ_CRASHREPORTER) -#if defined(MOZ_CONTENT_SANDBOX) && !defined(MOZ_WIDGET_GONK) -void -AddContentSandboxLevelAnnotation() -{ - if (XRE_GetProcessType() == GeckoProcessType_Content) { - int level = Preferences::GetInt("security.sandbox.content.level"); - nsAutoCString levelString; - levelString.AppendInt(level); - CrashReporter::AnnotateCrashReport( - NS_LITERAL_CSTRING("ContentSandboxLevel"), levelString); - } -} -#endif /* MOZ_CONTENT_SANDBOX && !MOZ_WIDGET_GONK */ -#endif /* MOZ_CRASHREPORTER */ - nsresult XRE_InitChildProcess(int aArgc, char* aArgv[], @@ -442,33 +402,6 @@ XRE_InitChildProcess(int aArgc, SetupErrorHandling(aArgv[0]); -#if defined(MOZ_CRASHREPORTER) - if (aArgc < 1) - return NS_ERROR_FAILURE; - const char* const crashReporterArg = aArgv[--aArgc]; - -# if defined(XP_WIN) || defined(XP_MACOSX) - // on windows and mac, |crashReporterArg| is the named pipe on which the - // server is listening for requests, or "-" if crash reporting is - // disabled. - if (0 != strcmp("-", crashReporterArg) && - !XRE_SetRemoteExceptionHandler(crashReporterArg)) { - // Bug 684322 will add better visibility into this condition - NS_WARNING("Could not setup crash reporting\n"); - } -# elif defined(OS_LINUX) - // on POSIX, |crashReporterArg| is "true" if crash reporting is - // enabled, false otherwise - if (0 != strcmp("false", crashReporterArg) && - !XRE_SetRemoteExceptionHandler(nullptr)) { - // Bug 684322 will add better visibility into this condition - NS_WARNING("Could not setup crash reporting\n"); - } -# else -# error "OOP crash reporting unsupported on this platform" -# endif -#endif // if defined(MOZ_CRASHREPORTER) - gArgv = aArgv; gArgc = aArgc; @@ -647,12 +580,6 @@ XRE_InitChildProcess(int aArgc, return NS_ERROR_FAILURE; } -#ifdef MOZ_CRASHREPORTER -#if defined(XP_WIN) || defined(XP_MACOSX) - CrashReporter::InitChildProcessTmpDir(); -#endif -#endif - #if defined(XP_WIN) // Set child processes up such that they will get killed after the // chrome process is killed in cases where the user shuts the system @@ -668,12 +595,6 @@ XRE_InitChildProcess(int aArgc, OverrideDefaultLocaleIfNeeded(); -#if defined(MOZ_CRASHREPORTER) -#if defined(MOZ_CONTENT_SANDBOX) && !defined(MOZ_WIDGET_GONK) - AddContentSandboxLevelAnnotation(); -#endif -#endif - // Run the UI event loop on the main thread. uiMessageLoop.MessageLoop::Run(); diff --git a/toolkit/xre/nsX11ErrorHandler.cpp b/toolkit/xre/nsX11ErrorHandler.cpp index 0db24e58b..0fb0d29c5 100644 --- a/toolkit/xre/nsX11ErrorHandler.cpp +++ b/toolkit/xre/nsX11ErrorHandler.cpp @@ -117,18 +117,6 @@ X11Error(Display *display, XErrorEvent *event) { } } -#ifdef MOZ_CRASHREPORTER - switch (XRE_GetProcessType()) { - case GeckoProcessType_Default: - case GeckoProcessType_Plugin: - case GeckoProcessType_Content: - CrashReporter::AppendAppNotesToCrashReport(notes); - break; - default: - ; // crash report notes not supported. - } -#endif - #ifdef DEBUG // The resource id is unlikely to be useful in a crash report without // context of other ids, but add it to the debug console output. diff --git a/tools/profiler/moz.build b/tools/profiler/moz.build index e48ae8f94..08103f126 100644 --- a/tools/profiler/moz.build +++ b/tools/profiler/moz.build @@ -60,14 +60,13 @@ if CONFIG['MOZ_ENABLE_PROFILER_SPS']: 'core/platform-linux.cc', 'core/shared-libraries-linux.cc', ] - if not CONFIG['MOZ_CRASHREPORTER']: - SOURCES += [ - '/toolkit/crashreporter/google-breakpad/src/common/linux/elfutils.cc', - '/toolkit/crashreporter/google-breakpad/src/common/linux/file_id.cc', - '/toolkit/crashreporter/google-breakpad/src/common/linux/guid_creator.cc', - '/toolkit/crashreporter/google-breakpad/src/common/linux/linux_libc_support.cc', - '/toolkit/crashreporter/google-breakpad/src/common/linux/memory_mapped_file.cc', - ] + SOURCES += [ + '/toolkit/crashreporter/google-breakpad/src/common/linux/elfutils.cc', + '/toolkit/crashreporter/google-breakpad/src/common/linux/file_id.cc', + '/toolkit/crashreporter/google-breakpad/src/common/linux/guid_creator.cc', + '/toolkit/crashreporter/google-breakpad/src/common/linux/linux_libc_support.cc', + '/toolkit/crashreporter/google-breakpad/src/common/linux/memory_mapped_file.cc', + ] if CONFIG['CPU_ARCH'] == 'arm': SOURCES += [ 'core/EHABIStackWalk.cpp', @@ -100,7 +99,7 @@ if CONFIG['MOZ_ENABLE_PROFILER_SPS']: '/toolkit/crashreporter/google-breakpad/src/common/android/include', ] - if not CONFIG['MOZ_CRASHREPORTER'] and CONFIG['OS_TARGET'] == 'Android': + if CONFIG['OS_TARGET'] == 'Android': SOURCES += ['/toolkit/crashreporter/google-breakpad/src/common/android/breakpad_getcontext.S'] if CONFIG['ANDROID_CPU_ARCH'] == 'armeabi': diff --git a/widget/GfxInfoBase.cpp b/widget/GfxInfoBase.cpp index 5c8693957..c937f5099 100644 --- a/widget/GfxInfoBase.cpp +++ b/widget/GfxInfoBase.cpp @@ -37,10 +37,6 @@ #include "gfxConfig.h" #include "DriverCrashGuard.h" -#if defined(MOZ_CRASHREPORTER) -#include "nsExceptionHandler.h" -#endif - using namespace mozilla::widget; using namespace mozilla; using mozilla::MutexAutoLock; diff --git a/widget/GfxInfoX11.cpp b/widget/GfxInfoX11.cpp index f490bed52..4297aaa93 100644 --- a/widget/GfxInfoX11.cpp +++ b/widget/GfxInfoX11.cpp @@ -15,11 +15,6 @@ #include "GfxInfoX11.h" -#ifdef MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" -#include "nsICrashReporter.h" -#endif - namespace mozilla { namespace widget { @@ -176,9 +171,6 @@ GfxInfo::GetData() mAdapterDescription.Append(nsDependentCString(buf)); mAdapterDescription.Append('\n'); } -#ifdef MOZ_CRASHREPORTER - CrashReporter::AppendAppNotesToCrashReport(mAdapterDescription); -#endif return; } @@ -194,9 +186,6 @@ GfxInfo::GetData() if (mHasTextureFromPixmap) note.AppendLiteral(" -- texture_from_pixmap"); note.Append('\n'); -#ifdef MOZ_CRASHREPORTER - CrashReporter::AppendAppNotesToCrashReport(note); -#endif // determine the major OpenGL version. That's the first integer in the version string. mGLMajorVersion = strtol(mVersion.get(), 0, 10); diff --git a/widget/android/GfxInfo.cpp b/widget/android/GfxInfo.cpp index af63184a7..181629e96 100644 --- a/widget/android/GfxInfo.cpp +++ b/widget/android/GfxInfo.cpp @@ -15,12 +15,6 @@ #include "nsIWindowWatcher.h" #include "nsServiceManagerUtils.h" -#if defined(MOZ_CRASHREPORTER) -#include "nsExceptionHandler.h" -#include "nsICrashReporter.h" -#define NS_CRASHREPORTER_CONTRACTID "@mozilla.org/toolkit/crash-reporter;1" -#endif - namespace mozilla { namespace widget { @@ -351,21 +345,7 @@ GfxInfo::GetIsGPU2Active(bool* aIsGPU2Active) void GfxInfo::AddCrashReportAnnotations() { -#if defined(MOZ_CRASHREPORTER) - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterVendorID"), - mGLStrings->Vendor()); - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDeviceID"), - mGLStrings->Renderer()); - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDriverVersion"), - mGLStrings->Version()); - - /* Add an App Note for now so that we get the data immediately. These - * can go away after we store the above in the socorro db */ - nsAutoCString note; - note.AppendPrintf("AdapterDescription: '%s'\n", mAdapterDescription.get()); - - CrashReporter::AppendAppNotesToCrashReport(note); -#endif + /*** STUB ***/ } const nsTArray<GfxDriverInfo>& diff --git a/widget/android/jni/Utils.cpp b/widget/android/jni/Utils.cpp index 145f7e9ea..919588851 100644 --- a/widget/android/jni/Utils.cpp +++ b/widget/android/jni/Utils.cpp @@ -9,10 +9,6 @@ #include "GeneratedJNIWrappers.h" #include "nsAppShell.h" -#ifdef MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" -#endif - namespace mozilla { namespace jni { @@ -192,12 +188,6 @@ bool ReportException(JNIEnv* aEnv, jthrowable aExc, jstring aStack) { bool result = true; -#ifdef MOZ_CRASHREPORTER - result &= NS_SUCCEEDED(CrashReporter::AnnotateCrashReport( - NS_LITERAL_CSTRING("JavaStackTrace"), - String::Ref::From(aStack)->ToCString())); -#endif // MOZ_CRASHREPORTER - if (sOOMErrorClass && aEnv->IsInstanceOf(aExc, sOOMErrorClass)) { NS_ABORT_OOM(0); // Unknown OOM size } diff --git a/widget/android/nsAppShell.cpp b/widget/android/nsAppShell.cpp index fefd711d0..09548c27b 100644 --- a/widget/android/nsAppShell.cpp +++ b/widget/android/nsAppShell.cpp @@ -53,11 +53,6 @@ #include "mozilla/Logging.h" #endif -#ifdef MOZ_CRASHREPORTER -#include "nsICrashReporter.h" -#include "nsExceptionHandler.h" -#endif - #include "AndroidAlerts.h" #include "ANRReporter.h" #include "GeckoBatteryManager.h" diff --git a/widget/cocoa/GfxInfo.mm b/widget/cocoa/GfxInfo.mm index 6789ae8b2..74333c514 100644 --- a/widget/cocoa/GfxInfo.mm +++ b/widget/cocoa/GfxInfo.mm @@ -18,12 +18,6 @@ #import <IOKit/IOKitLib.h> #import <Cocoa/Cocoa.h> -#if defined(MOZ_CRASHREPORTER) -#include "nsExceptionHandler.h" -#include "nsICrashReporter.h" -#define NS_CRASHREPORTER_CONTRACTID "@mozilla.org/toolkit/crash-reporter;1" -#endif - using namespace mozilla; using namespace mozilla::widget; @@ -273,33 +267,7 @@ GfxInfo::GetIsGPU2Active(bool* aIsGPU2Active) void GfxInfo::AddCrashReportAnnotations() { -#if defined(MOZ_CRASHREPORTER) - nsString deviceID, vendorID, driverVersion; - nsAutoCString narrowDeviceID, narrowVendorID, narrowDriverVersion; - - GetAdapterDeviceID(deviceID); - CopyUTF16toUTF8(deviceID, narrowDeviceID); - GetAdapterVendorID(vendorID); - CopyUTF16toUTF8(vendorID, narrowVendorID); - GetAdapterDriverVersion(driverVersion); - CopyUTF16toUTF8(driverVersion, narrowDriverVersion); - - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterVendorID"), - narrowVendorID); - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDeviceID"), - narrowDeviceID); - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDriverVersion"), - narrowDriverVersion); - /* Add an App Note for now so that we get the data immediately. These - * can go away after we store the above in the socorro db */ - nsAutoCString note; - /* AppendPrintf only supports 32 character strings, mrghh. */ - note.Append("AdapterVendorID: "); - note.Append(narrowVendorID); - note.Append(", AdapterDeviceID: "); - note.Append(narrowDeviceID); - CrashReporter::AppendAppNotesToCrashReport(note); -#endif + /*** STUB ***/ } // We don't support checking driver versions on Mac. diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm index 92ccd8b6c..8f72a81be 100644 --- a/widget/cocoa/nsChildView.mm +++ b/widget/cocoa/nsChildView.mm @@ -77,9 +77,6 @@ #include "nsAccessibilityService.h" #include "mozilla/a11y/Platform.h" #endif -#ifdef MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" -#endif #include "mozilla/Preferences.h" @@ -5373,31 +5370,14 @@ GetIntegerDeltaForEvent(NSEvent* aEvent) #if !defined(RELEASE_OR_BETA) || defined(DEBUG) if (!Preferences::GetBool("intl.allow-insecure-text-input", false) && mGeckoChild && mTextInputHandler && mTextInputHandler->IsFocused()) { -#ifdef MOZ_CRASHREPORTER - NSWindow* window = [self window]; - NSString* info = [NSString stringWithFormat:@"\nview [%@], window [%@], window is key %i, is fullscreen %i, app is active %i", - self, window, [window isKeyWindow], ([window styleMask] & (1 << 14)) != 0, - [NSApp isActive]]; - nsAutoCString additionalInfo([info UTF8String]); -#endif if (mGeckoChild->GetInputContext().IsPasswordEditor() && !TextInputHandler::IsSecureEventInputEnabled()) { #define CRASH_MESSAGE "A password editor has focus, but not in secure input mode" -#ifdef MOZ_CRASHREPORTER - CrashReporter::AppendAppNotesToCrashReport(NS_LITERAL_CSTRING("\nBug 893973: ") + - NS_LITERAL_CSTRING(CRASH_MESSAGE)); - CrashReporter::AppendAppNotesToCrashReport(additionalInfo); -#endif MOZ_CRASH(CRASH_MESSAGE); #undef CRASH_MESSAGE } else if (!mGeckoChild->GetInputContext().IsPasswordEditor() && TextInputHandler::IsSecureEventInputEnabled()) { #define CRASH_MESSAGE "A non-password editor has focus, but in secure input mode" -#ifdef MOZ_CRASHREPORTER - CrashReporter::AppendAppNotesToCrashReport(NS_LITERAL_CSTRING("\nBug 893973: ") + - NS_LITERAL_CSTRING(CRASH_MESSAGE)); - CrashReporter::AppendAppNotesToCrashReport(additionalInfo); -#endif MOZ_CRASH(CRASH_MESSAGE); #undef CRASH_MESSAGE } diff --git a/widget/nsBaseAppShell.cpp b/widget/nsBaseAppShell.cpp index 1557498b7..c6b88cba0 100644 --- a/widget/nsBaseAppShell.cpp +++ b/widget/nsBaseAppShell.cpp @@ -6,9 +6,6 @@ #include "base/message_loop.h" #include "nsBaseAppShell.h" -#if defined(MOZ_CRASHREPORTER) -#include "nsExceptionHandler.h" -#endif #include "nsThreadUtils.h" #include "nsIObserverService.h" #include "nsServiceManagerUtils.h" @@ -317,18 +314,12 @@ void nsBaseAppShell::IncrementEventloopNestingLevel() { ++mEventloopNestingLevel; -#if defined(MOZ_CRASHREPORTER) - CrashReporter::SetEventloopNestingLevel(mEventloopNestingLevel); -#endif } void nsBaseAppShell::DecrementEventloopNestingLevel() { --mEventloopNestingLevel; -#if defined(MOZ_CRASHREPORTER) - CrashReporter::SetEventloopNestingLevel(mEventloopNestingLevel); -#endif } // Called from the main thread diff --git a/widget/windows/GfxInfo.cpp b/widget/windows/GfxInfo.cpp index bfea41851..8a429ad32 100644 --- a/widget/windows/GfxInfo.cpp +++ b/widget/windows/GfxInfo.cpp @@ -21,12 +21,6 @@ #include "nsPrintfCString.h" #include "jsapi.h" -#if defined(MOZ_CRASHREPORTER) -#include "nsExceptionHandler.h" -#include "nsICrashReporter.h" -#define NS_CRASHREPORTER_CONTRACTID "@mozilla.org/toolkit/crash-reporter;1" -#endif - using namespace mozilla; using namespace mozilla::gfx; using namespace mozilla::widget; @@ -721,102 +715,10 @@ GfxInfo::GetIsGPU2Active(bool* aIsGPU2Active) return NS_OK; } -#if defined(MOZ_CRASHREPORTER) -/* Cisco's VPN software can cause corruption of the floating point state. - * Make a note of this in our crash reports so that some weird crashes - * make more sense */ -static void -CheckForCiscoVPN() { - LONG result; - HKEY key; - /* This will give false positives, but hopefully no false negatives */ - result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Cisco Systems\\VPN Client", 0, KEY_QUERY_VALUE, &key); - if (result == ERROR_SUCCESS) { - RegCloseKey(key); - CrashReporter::AppendAppNotesToCrashReport(NS_LITERAL_CSTRING("Cisco VPN\n")); - } -} -#endif - void GfxInfo::AddCrashReportAnnotations() { -#if defined(MOZ_CRASHREPORTER) - CheckForCiscoVPN(); - - if (mHasDriverVersionMismatch) { - CrashReporter::AppendAppNotesToCrashReport(NS_LITERAL_CSTRING("DriverVersionMismatch\n")); - } - - nsString deviceID, vendorID, driverVersion, subsysID; - nsCString narrowDeviceID, narrowVendorID, narrowDriverVersion, narrowSubsysID; - - GetAdapterDeviceID(deviceID); - CopyUTF16toUTF8(deviceID, narrowDeviceID); - GetAdapterVendorID(vendorID); - CopyUTF16toUTF8(vendorID, narrowVendorID); - GetAdapterDriverVersion(driverVersion); - CopyUTF16toUTF8(driverVersion, narrowDriverVersion); - GetAdapterSubsysID(subsysID); - CopyUTF16toUTF8(subsysID, narrowSubsysID); - - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterVendorID"), - narrowVendorID); - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDeviceID"), - narrowDeviceID); - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDriverVersion"), - narrowDriverVersion); - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterSubsysID"), - narrowSubsysID); - - /* Add an App Note for now so that we get the data immediately. These - * can go away after we store the above in the socorro db */ - nsAutoCString note; - /* AppendPrintf only supports 32 character strings, mrghh. */ - note.AppendLiteral("AdapterVendorID: "); - note.Append(narrowVendorID); - note.AppendLiteral(", AdapterDeviceID: "); - note.Append(narrowDeviceID); - note.AppendLiteral(", AdapterSubsysID: "); - note.Append(narrowSubsysID); - note.AppendLiteral(", AdapterDriverVersion: "); - note.Append(NS_LossyConvertUTF16toASCII(driverVersion)); - - if (vendorID == GfxDriverInfo::GetDeviceVendor(VendorAll)) { - /* if we didn't find a valid vendorID lets append the mDeviceID string to try to find out why */ - note.AppendLiteral(", "); - LossyAppendUTF16toASCII(mDeviceID, note); - note.AppendLiteral(", "); - LossyAppendUTF16toASCII(mDeviceKeyDebug, note); - LossyAppendUTF16toASCII(mDeviceKeyDebug, note); - } - note.Append("\n"); - - if (mHasDualGPU) { - nsString deviceID2, vendorID2, subsysID2; - nsAutoString adapterDriverVersionString2; - nsCString narrowDeviceID2, narrowVendorID2, narrowSubsysID2; - - note.AppendLiteral("Has dual GPUs. GPU #2: "); - GetAdapterDeviceID2(deviceID2); - CopyUTF16toUTF8(deviceID2, narrowDeviceID2); - GetAdapterVendorID2(vendorID2); - CopyUTF16toUTF8(vendorID2, narrowVendorID2); - GetAdapterDriverVersion2(adapterDriverVersionString2); - GetAdapterSubsysID(subsysID2); - CopyUTF16toUTF8(subsysID2, narrowSubsysID2); - note.AppendLiteral("AdapterVendorID2: "); - note.Append(narrowVendorID2); - note.AppendLiteral(", AdapterDeviceID2: "); - note.Append(narrowDeviceID2); - note.AppendLiteral(", AdapterSubsysID2: "); - note.Append(narrowSubsysID2); - note.AppendLiteral(", AdapterDriverVersion2: "); - note.Append(NS_LossyConvertUTF16toASCII(adapterDriverVersionString2)); - } - CrashReporter::AppendAppNotesToCrashReport(note); - -#endif + /*** STUB ***/ } static OperatingSystem diff --git a/widget/windows/KeyboardLayout.cpp b/widget/windows/KeyboardLayout.cpp index 341a40c18..9166d97d7 100644 --- a/widget/windows/KeyboardLayout.cpp +++ b/widget/windows/KeyboardLayout.cpp @@ -13,9 +13,6 @@ #include "mozilla/WindowsVersion.h" #include "nsAlgorithm.h" -#ifdef MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" -#endif #include "nsGkAtoms.h" #include "nsIDOMKeyEvent.h" #include "nsIIdleServiceInternal.h" @@ -2740,42 +2737,6 @@ NativeKey::NeedsToHandleWithoutFollowingCharMessages() const return mIsPrintableKey; } -#ifdef MOZ_CRASHREPORTER - -static nsCString -GetResultOfInSendMessageEx() -{ - DWORD ret = ::InSendMessageEx(nullptr); - if (!ret) { - return NS_LITERAL_CSTRING("ISMEX_NOSEND"); - } - nsAutoCString result; - if (ret & ISMEX_CALLBACK) { - result = "ISMEX_CALLBACK"; - } - if (ret & ISMEX_NOTIFY) { - if (!result.IsEmpty()) { - result += " | "; - } - result += "ISMEX_NOTIFY"; - } - if (ret & ISMEX_REPLIED) { - if (!result.IsEmpty()) { - result += " | "; - } - result += "ISMEX_REPLIED"; - } - if (ret & ISMEX_SEND) { - if (!result.IsEmpty()) { - result += " | "; - } - result += "ISMEX_SEND"; - } - return result; -} - -#endif // #ifdef MOZ_CRASHREPORTER - bool NativeKey::MayBeSameCharMessage(const MSG& aCharMsg1, const MSG& aCharMsg2) const @@ -3019,33 +2980,6 @@ NativeKey::GetFollowingCharMessage(MSG& aCharMsg) } if (doCrash) { -#ifdef MOZ_CRASHREPORTER - nsPrintfCString info("\nPeekMessage() failed to remove char message! " - "\nActive keyboard layout=0x%08X (%s), " - "\nHandling message: %s, InSendMessageEx()=%s, " - "\nFound message: %s, " - "\nWM_NULL has been removed: %d, " - "\nNext key message in all windows: %s, " - "time=%d, ", - KeyboardLayout::GetActiveLayout(), - KeyboardLayout::GetActiveLayoutName().get(), - ToString(mMsg).get(), - GetResultOfInSendMessageEx().get(), - ToString(kFoundCharMsg).get(), i, - ToString(nextKeyMsgInAllWindows).get(), - nextKeyMsgInAllWindows.time); - CrashReporter::AppendAppNotesToCrashReport(info); - MSG nextMsg; - if (WinUtils::PeekMessage(&nextMsg, 0, 0, 0, - PM_NOREMOVE | PM_NOYIELD)) { - nsPrintfCString info("\nNext message in all windows: %s, time=%d", - ToString(nextMsg).get(), nextMsg.time); - CrashReporter::AppendAppNotesToCrashReport(info); - } else { - CrashReporter::AppendAppNotesToCrashReport( - NS_LITERAL_CSTRING("\nThere is no message in any window")); - } -#endif // #ifdef MOZ_CRASHREPORTER MOZ_CRASH("We lost the following char message"); } @@ -3164,63 +3098,12 @@ NativeKey::GetFollowingCharMessage(MSG& aCharMsg) "nextKeyMsg=%s, kFoundCharMsg=%s", this, ToString(removedMsg).get(), ToString(nextKeyMsg).get(), ToString(kFoundCharMsg).get())); -#ifdef MOZ_CRASHREPORTER - nsPrintfCString info("\nPeekMessage() removed unexpcted char message! " - "\nActive keyboard layout=0x%08X (%s), " - "\nHandling message: %s, InSendMessageEx()=%s, " - "\nFound message: %s, " - "\nRemoved message: %s, ", - KeyboardLayout::GetActiveLayout(), - KeyboardLayout::GetActiveLayoutName().get(), - ToString(mMsg).get(), - GetResultOfInSendMessageEx().get(), - ToString(kFoundCharMsg).get(), - ToString(removedMsg).get()); - CrashReporter::AppendAppNotesToCrashReport(info); - // What's the next key message? - MSG nextKeyMsgAfter; - if (WinUtils::PeekMessage(&nextKeyMsgAfter, mMsg.hwnd, - WM_KEYFIRST, WM_KEYLAST, - PM_NOREMOVE | PM_NOYIELD)) { - nsPrintfCString info("\nNext key message after unexpected char message " - "removed: %s, ", - ToString(nextKeyMsgAfter).get()); - CrashReporter::AppendAppNotesToCrashReport(info); - } else { - CrashReporter::AppendAppNotesToCrashReport( - NS_LITERAL_CSTRING("\nThere is no key message after unexpected char " - "message removed, ")); - } - // Another window has a key message? - if (WinUtils::PeekMessage(&nextKeyMsgInAllWindows, 0, - WM_KEYFIRST, WM_KEYLAST, - PM_NOREMOVE | PM_NOYIELD)) { - nsPrintfCString info("\nNext key message in all windows: %s.", - ToString(nextKeyMsgInAllWindows).get()); - CrashReporter::AppendAppNotesToCrashReport(info); - } else { - CrashReporter::AppendAppNotesToCrashReport( - NS_LITERAL_CSTRING("\nThere is no key message in any windows.")); - } -#endif // #ifdef MOZ_CRASHREPORTER MOZ_CRASH("PeekMessage() removed unexpected message"); } MOZ_LOG(sNativeKeyLogger, LogLevel::Error, ("%p NativeKey::GetFollowingCharMessage(), FAILED, removed messages " "are all WM_NULL, nextKeyMsg=%s", this, ToString(nextKeyMsg).get())); -#ifdef MOZ_CRASHREPORTER - nsPrintfCString info("\nWe lost following char message! " - "\nActive keyboard layout=0x%08X (%s), " - "\nHandling message: %s, InSendMessageEx()=%s, \n" - "Found message: %s, removed a lot of WM_NULL", - KeyboardLayout::GetActiveLayout(), - KeyboardLayout::GetActiveLayoutName().get(), - ToString(mMsg).get(), - GetResultOfInSendMessageEx().get(), - ToString(kFoundCharMsg).get()); - CrashReporter::AppendAppNotesToCrashReport(info); -#endif // #ifdef MOZ_CRASHREPORTER MOZ_CRASH("We lost the following char message"); return false; } diff --git a/widget/windows/LSPAnnotator.cpp b/widget/windows/LSPAnnotator.cpp deleted file mode 100644 index 97f6e5b50..000000000 --- a/widget/windows/LSPAnnotator.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/** - * LSPs are evil little bits of code that are allowed to inject into our - * networking stack by Windows. Once they have wormed into our process - * they gnaw at our innards until we crash. Here we force the buggers - * into the light by recording them in our crash information. - * We do the enumeration on a thread because I'm concerned about startup perf - * on machines with several LSPs. - */ - -#include "nsICrashReporter.h" -#include "nsISupportsImpl.h" -#include "nsServiceManagerUtils.h" -#include "nsThreadUtils.h" -#include "nsQueryObject.h" -#include "nsWindowsHelpers.h" -#include <windows.h> -#include <rpc.h> -#include <ws2spi.h> - -namespace mozilla { -namespace crashreporter { - -class LSPAnnotationGatherer : public Runnable -{ - ~LSPAnnotationGatherer() {} - -public: - NS_DECL_THREADSAFE_ISUPPORTS - NS_DECL_NSIRUNNABLE - - void Annotate(); - nsCString mString; - nsCOMPtr<nsIThread> mThread; -}; - -NS_IMPL_ISUPPORTS(LSPAnnotationGatherer, nsIRunnable) - -void -LSPAnnotationGatherer::Annotate() -{ - nsCOMPtr<nsICrashReporter> cr = - do_GetService("@mozilla.org/toolkit/crash-reporter;1"); - bool enabled; - if (cr && NS_SUCCEEDED(cr->GetEnabled(&enabled)) && enabled) { - cr->AnnotateCrashReport(NS_LITERAL_CSTRING("Winsock_LSP"), mString); - } - mThread->AsyncShutdown(); -} - -NS_IMETHODIMP -LSPAnnotationGatherer::Run() -{ - PR_SetCurrentThreadName("LSP Annotator"); - - mThread = NS_GetCurrentThread(); - - DWORD size = 0; - int err; - // Get the size of the buffer we need - if (SOCKET_ERROR != WSCEnumProtocols(nullptr, nullptr, &size, &err) || - err != WSAENOBUFS) { - // Er, what? - NS_NOTREACHED("WSCEnumProtocols suceeded when it should have failed ..."); - return NS_ERROR_FAILURE; - } - - auto byteArray = MakeUnique<char[]>(size); - WSAPROTOCOL_INFOW* providers = - reinterpret_cast<WSAPROTOCOL_INFOW*>(byteArray.get()); - - int n = WSCEnumProtocols(nullptr, providers, &size, &err); - if (n == SOCKET_ERROR) { - // Lame. We provided the right size buffer; we'll just give up now. - NS_WARNING("Could not get LSP list"); - return NS_ERROR_FAILURE; - } - - nsCString str; - for (int i = 0; i < n; i++) { - AppendUTF16toUTF8(nsDependentString(providers[i].szProtocol), str); - str.AppendLiteral(" : "); - str.AppendInt(providers[i].iVersion); - str.AppendLiteral(" : "); - str.AppendInt(providers[i].iAddressFamily); - str.AppendLiteral(" : "); - str.AppendInt(providers[i].iSocketType); - str.AppendLiteral(" : "); - str.AppendInt(providers[i].iProtocol); - str.AppendLiteral(" : "); - str.AppendPrintf("0x%x", providers[i].dwServiceFlags1); - str.AppendLiteral(" : "); - str.AppendPrintf("0x%x", providers[i].dwProviderFlags); - str.AppendLiteral(" : "); - - wchar_t path[MAX_PATH]; - int pathLen = MAX_PATH; - if (!WSCGetProviderPath(&providers[i].ProviderId, path, &pathLen, &err)) { - AppendUTF16toUTF8(nsDependentString(path), str); - } - - str.AppendLiteral(" : "); - // If WSCGetProviderInfo is available, we should call it to obtain the - // category flags for this provider. When present, these flags inform - // Windows as to which order to chain the providers. - nsModuleHandle ws2_32(LoadLibraryW(L"ws2_32.dll")); - if (ws2_32) { - decltype(WSCGetProviderInfo)* pWSCGetProviderInfo = - reinterpret_cast<decltype(WSCGetProviderInfo)*>( - GetProcAddress(ws2_32, "WSCGetProviderInfo")); - if (pWSCGetProviderInfo) { - DWORD categoryInfo; - size_t categoryInfoSize = sizeof(categoryInfo); - if (!pWSCGetProviderInfo(&providers[i].ProviderId, - ProviderInfoLspCategories, - (PBYTE)&categoryInfo, &categoryInfoSize, 0, - &err)) { - str.AppendPrintf("0x%x", categoryInfo); - } - } - } - - str.AppendLiteral(" : "); - if (providers[i].ProtocolChain.ChainLen <= BASE_PROTOCOL) { - // If we're dealing with a catalog entry that identifies an individual - // base or layer provider, log its provider GUID. - RPC_CSTR provIdStr = nullptr; - if (UuidToStringA(&providers[i].ProviderId, &provIdStr) == RPC_S_OK) { - str.Append(reinterpret_cast<char*>(provIdStr)); - RpcStringFreeA(&provIdStr); - } - } - - if (i + 1 != n) { - str.AppendLiteral(" \n "); - } - } - - mString = str; - NS_DispatchToMainThread(NewRunnableMethod(this, &LSPAnnotationGatherer::Annotate)); - return NS_OK; -} - -void LSPAnnotate() -{ - nsCOMPtr<nsIThread> thread; - nsCOMPtr<nsIRunnable> runnable = - do_QueryObject(new LSPAnnotationGatherer()); - NS_NewThread(getter_AddRefs(thread), runnable); -} - -} // namespace crashreporter -} // namespace mozilla diff --git a/widget/windows/moz.build b/widget/windows/moz.build index d4f089eea..1e7fc4b02 100644 --- a/widget/windows/moz.build +++ b/widget/windows/moz.build @@ -79,11 +79,6 @@ SOURCES += [ 'WinMouseScrollHandler.cpp', ] -if CONFIG['MOZ_CRASHREPORTER']: - UNIFIED_SOURCES += [ - 'LSPAnnotator.cpp', - ] - if CONFIG['NS_PRINTING']: UNIFIED_SOURCES += [ 'nsDeviceContextSpecWin.cpp', diff --git a/widget/windows/nsAppShell.cpp b/widget/windows/nsAppShell.cpp index c8820e7d1..c3e99b2d3 100644 --- a/widget/windows/nsAppShell.cpp +++ b/widget/windows/nsAppShell.cpp @@ -213,10 +213,6 @@ nsAppShell::~nsAppShell() nsresult nsAppShell::Init() { -#ifdef MOZ_CRASHREPORTER - LSPAnnotate(); -#endif - mLastNativeEventScheduled = TimeStamp::NowLoRes(); mozilla::ipc::windows::InitUIThread(); diff --git a/xpcom/base/CycleCollectedJSContext.cpp b/xpcom/base/CycleCollectedJSContext.cpp index 87e123078..4af8fe4dd 100644 --- a/xpcom/base/CycleCollectedJSContext.cpp +++ b/xpcom/base/CycleCollectedJSContext.cpp @@ -82,10 +82,6 @@ #include "nsJSUtils.h" #include "nsWrapperCache.h" -#ifdef MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" -#endif - #include "nsIException.h" #include "nsIPlatformInfo.h" #include "nsThread.h" @@ -539,10 +535,6 @@ CycleCollectedJSContext::Initialize(JSContext* aParentContext, JS_SetSweepZoneCallback(mJSContext, XPCStringConvert::ClearZoneCache); JS::SetBuildIdOp(mJSContext, GetBuildId); JS::SetWarningReporter(mJSContext, MozCrashWarningReporter); -#ifdef MOZ_CRASHREPORTER - js::AutoEnterOOMUnsafeRegion::setAnnotateOOMAllocationSizeCallback( - CrashReporter::AnnotateOOMAllocationSize); -#endif static js::DOMCallbacks DOMcallbacks = { InstanceClassHasProtoAtDepth @@ -1607,16 +1599,6 @@ CycleCollectedJSContext::AnnotateAndSetOutOfMemory(OOMState* aStatePtr, MOZ_ASSERT(mJSContext); *aStatePtr = aNewState; -#ifdef MOZ_CRASHREPORTER - CrashReporter::AnnotateCrashReport(aStatePtr == &mOutOfMemoryState - ? NS_LITERAL_CSTRING("JSOutOfMemory") - : NS_LITERAL_CSTRING("JSLargeAllocationFailure"), - aNewState == OOMState::Reporting - ? NS_LITERAL_CSTRING("Reporting") - : aNewState == OOMState::Reported - ? NS_LITERAL_CSTRING("Reported") - : NS_LITERAL_CSTRING("Recovered")); -#endif } void @@ -1630,14 +1612,6 @@ CycleCollectedJSContext::OnGC(JSGCStatus aStatus) mZonesWaitingForGC.Clear(); break; case JSGC_END: { -#ifdef MOZ_CRASHREPORTER - if (mOutOfMemoryState == OOMState::Reported) { - AnnotateAndSetOutOfMemory(&mOutOfMemoryState, OOMState::Recovered); - } - if (mLargeAllocationFailureState == OOMState::Reported) { - AnnotateAndSetOutOfMemory(&mLargeAllocationFailureState, OOMState::Recovered); - } -#endif // Do any deferred finalization of native objects. FinalizeDeferredThings(JS::WasIncrementalGC(mJSContext) ? FinalizeIncrementally : diff --git a/xpcom/base/nsCrashOnException.cpp b/xpcom/base/nsCrashOnException.cpp index 0f8042531..06c48738f 100644 --- a/xpcom/base/nsCrashOnException.cpp +++ b/xpcom/base/nsCrashOnException.cpp @@ -8,22 +8,11 @@ #include "nsCOMPtr.h" #include "nsServiceManagerUtils.h" -#ifdef MOZ_CRASHREPORTER -#include "nsICrashReporter.h" -#endif - namespace mozilla { static int ReportException(EXCEPTION_POINTERS* aExceptionInfo) { -#ifdef MOZ_CRASHREPORTER - nsCOMPtr<nsICrashReporter> cr = - do_GetService("@mozilla.org/toolkit/crash-reporter;1"); - if (cr) { - cr->WriteMinidumpForException(aExceptionInfo); - } -#endif return EXCEPTION_EXECUTE_HANDLER; } diff --git a/xpcom/base/nsCycleCollector.cpp b/xpcom/base/nsCycleCollector.cpp index ca7057628..b2c15a1dd 100644 --- a/xpcom/base/nsCycleCollector.cpp +++ b/xpcom/base/nsCycleCollector.cpp @@ -188,10 +188,6 @@ #include "mozilla/Telemetry.h" #include "mozilla/ThreadLocal.h" -#ifdef MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" -#endif - using namespace mozilla; //#define COLLECT_TIME_DEBUG @@ -2690,7 +2686,7 @@ public: void* aClosure) const override { const JS::Value& val = aValue->unbarrieredGet(); - if (val.isMarkable() && ValueIsGrayCCThing(val)) { + if (val.isGCThing() && ValueIsGrayCCThing(val)) { MOZ_ASSERT(!js::gc::IsInsideNursery(val.toGCThing())); mCollector->GetJSPurpleBuffer()->mValues.InfallibleAppend(val); } @@ -3150,14 +3146,6 @@ nsCycleCollector::ScanWhiteNodes(bool aFullySynchGraphBuild) } if (pi->mInternalRefs > pi->mRefCount) { -#ifdef MOZ_CRASHREPORTER - const char* piName = "Unknown"; - if (pi->mParticipant) { - piName = pi->mParticipant->ClassName(); - } - nsPrintfCString msg("More references to an object than its refcount, for class %s", piName); - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("CycleCollector"), msg); -#endif MOZ_CRASH(); } diff --git a/xpcom/base/nsCycleCollectorTraceJSHelpers.cpp b/xpcom/base/nsCycleCollectorTraceJSHelpers.cpp index eb06a389c..7c48002e3 100644 --- a/xpcom/base/nsCycleCollectorTraceJSHelpers.cpp +++ b/xpcom/base/nsCycleCollectorTraceJSHelpers.cpp @@ -36,7 +36,7 @@ void TraceCallbackFunc::Trace(JS::Heap<JS::Value>* aPtr, const char* aName, void* aClosure) const { - if (aPtr->unbarrieredGet().isMarkable()) { + if (aPtr->unbarrieredGet().isGCThing()) { mCallback(JS::GCCellPtr(aPtr->unbarrieredGet()), aName, aClosure); } } diff --git a/xpcom/base/nsDebugImpl.cpp b/xpcom/base/nsDebugImpl.cpp index 36288d203..96487acda 100644 --- a/xpcom/base/nsDebugImpl.cpp +++ b/xpcom/base/nsDebugImpl.cpp @@ -11,9 +11,6 @@ #include "nsDebugImpl.h" #include "nsDebug.h" -#ifdef MOZ_CRASHREPORTER -# include "nsExceptionHandler.h" -#endif #include "nsString.h" #include "nsXULAppAPI.h" #include "prprf.h" @@ -380,22 +377,6 @@ NS_DebugBreak(uint32_t aSeverity, const char* aStr, const char* aExpr, return; case NS_DEBUG_ABORT: { -#if defined(MOZ_CRASHREPORTER) - // Updating crash annotations in the child causes us to do IPC. This can - // really cause trouble if we're asserting from within IPC code. So we - // have to do without the annotations in that case. - if (XRE_IsParentProcess()) { - // Don't include the PID in the crash report annotation to - // allow faceting on crash-stats.mozilla.org. - nsCString note("xpcom_runtime_abort("); - note += nonPIDBuf.buffer; - note += ")"; - CrashReporter::AppendAppNotesToCrashReport(note); - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AbortMessage"), - nsDependentCString(nonPIDBuf.buffer)); - } -#endif // MOZ_CRASHREPORTER - #if defined(DEBUG) && defined(_WIN32) RealBreak(); #endif @@ -600,8 +581,5 @@ NS_ErrorAccordingToNSPR() void NS_ABORT_OOM(size_t aSize) { -#if defined(MOZ_CRASHREPORTER) - CrashReporter::AnnotateOOMAllocationSize(aSize); -#endif MOZ_CRASH("OOM"); } diff --git a/xpcom/base/nsObjCExceptions.h b/xpcom/base/nsObjCExceptions.h index e63c92af5..b3ed532ec 100644 --- a/xpcom/base/nsObjCExceptions.h +++ b/xpcom/base/nsObjCExceptions.h @@ -17,12 +17,6 @@ #import <ExceptionHandling/NSExceptionHandler.h> #endif -#if defined(MOZ_CRASHREPORTER) && defined(__cplusplus) -#include "nsICrashReporter.h" -#include "nsCOMPtr.h" -#include "nsServiceManagerUtils.h" -#endif - #include <unistd.h> #include <signal.h> #include "nsError.h" @@ -47,15 +41,6 @@ nsObjCExceptionLog(NSException* aException) NSLog(@"Mozilla has caught an Obj-C exception [%@: %@]", [aException name], [aException reason]); -#if defined(MOZ_CRASHREPORTER) && defined(__cplusplus) - // Attach exception info to the crash report. - nsCOMPtr<nsICrashReporter> crashReporter = - do_GetService("@mozilla.org/toolkit/crash-reporter;1"); - if (crashReporter) { - crashReporter->AppendObjCExceptionInfoToAppNotes(static_cast<void*>(aException)); - } -#endif - #ifdef DEBUG @try { // Try to get stack information out of the exception. 10.5 returns the stack diff --git a/xpcom/build/nsXULAppAPI.h b/xpcom/build/nsXULAppAPI.h index 426a58f06..aae248ca1 100644 --- a/xpcom/build/nsXULAppAPI.h +++ b/xpcom/build/nsXULAppAPI.h @@ -426,17 +426,6 @@ XRE_API(const char*, XRE_API(void, XRE_SetProcessType, (const char* aProcessTypeString)) -#if defined(MOZ_CRASHREPORTER) -// Used in the "master" parent process hosting the crash server -XRE_API(bool, - XRE_TakeMinidumpForChild, (uint32_t aChildPid, nsIFile** aDump, - uint32_t* aSequence)) - -// Used in child processes. -XRE_API(bool, - XRE_SetRemoteExceptionHandler, (const char* aPipe)) -#endif - namespace mozilla { namespace gmp { class GMPLoader; diff --git a/xpcom/system/moz.build b/xpcom/system/moz.build index 8a4f88efe..1d8e7ea1f 100644 --- a/xpcom/system/moz.build +++ b/xpcom/system/moz.build @@ -18,9 +18,4 @@ XPIDL_SOURCES += [ 'nsIXULRuntime.idl', ] -if CONFIG['MOZ_CRASHREPORTER']: - XPIDL_SOURCES += [ - 'nsICrashReporter.idl', - ] - XPIDL_MODULE = 'xpcom_system' diff --git a/xpcom/tests/gtest/TestDeadlockDetector.cpp b/xpcom/tests/gtest/TestDeadlockDetector.cpp index 646ee3e1d..877c5f5c3 100644 --- a/xpcom/tests/gtest/TestDeadlockDetector.cpp +++ b/xpcom/tests/gtest/TestDeadlockDetector.cpp @@ -15,12 +15,6 @@ #include "mozilla/ReentrantMonitor.h" #include "mozilla/Mutex.h" -#ifdef MOZ_CRASHREPORTER -#include "nsCOMPtr.h" -#include "nsICrashReporter.h" -#include "nsServiceManagerUtils.h" -#endif - #include "gtest/gtest.h" using namespace mozilla; @@ -62,13 +56,7 @@ private: void DisableCrashReporter() { -#ifdef MOZ_CRASHREPORTER - nsCOMPtr<nsICrashReporter> crashreporter = - do_GetService("@mozilla.org/toolkit/crash-reporter;1"); - if (crashreporter) { - crashreporter->SetEnabled(false); - } -#endif + /*** STUB ***/ } //----------------------------------------------------------------------------- diff --git a/xpcom/tests/gtest/TestPLDHash.cpp b/xpcom/tests/gtest/TestPLDHash.cpp index e7a73ae1b..4405b102c 100644 --- a/xpcom/tests/gtest/TestPLDHash.cpp +++ b/xpcom/tests/gtest/TestPLDHash.cpp @@ -21,10 +21,6 @@ extern unsigned int _gdb_sleep_duration; #endif -#ifdef MOZ_CRASHREPORTER -#include "nsICrashReporter.h" -#endif - // We can test that certain operations cause expected aborts by forking // and then checking that the child aborted in the expected way (i.e. via // MOZ_CRASH). We skip this for the following configurations. @@ -46,17 +42,6 @@ TestCrashyOperation(void (*aCrashyOperation)()) ASSERT_NE(pid, -1); if (pid == 0) { - // Disable the crashreporter -- writing a crash dump in the child will - // prevent the parent from writing a subsequent dump. Crashes here are - // expected, so we don't want their stacks to show up in the log anyway. -#ifdef MOZ_CRASHREPORTER - nsCOMPtr<nsICrashReporter> crashreporter = - do_GetService("@mozilla.org/toolkit/crash-reporter;1"); - if (crashreporter) { - crashreporter->SetEnabled(false); - } -#endif - // Child: perform the crashy operation. fprintf(stderr, "TestCrashyOperation: The following crash is expected. Do not panic.\n"); aCrashyOperation(); diff --git a/xpcom/tests/gtest/TestSTLWrappers.cpp b/xpcom/tests/gtest/TestSTLWrappers.cpp index 9559548a3..295aa7434 100644 --- a/xpcom/tests/gtest/TestSTLWrappers.cpp +++ b/xpcom/tests/gtest/TestSTLWrappers.cpp @@ -10,12 +10,6 @@ # error "failed to wrap <vector>" #endif -#ifdef MOZ_CRASHREPORTER -#include "nsCOMPtr.h" -#include "nsICrashReporter.h" -#include "nsServiceManagerUtils.h" -#endif - // gcc errors out if we |try ... catch| with -fno-exceptions, but we // can still test on windows #ifdef _MSC_VER @@ -40,14 +34,6 @@ void ShouldAbort() _gdb_sleep_duration = 0; #endif -#ifdef MOZ_CRASHREPORTER - nsCOMPtr<nsICrashReporter> crashreporter = - do_GetService("@mozilla.org/toolkit/crash-reporter;1"); - if (crashreporter) { - crashreporter->SetEnabled(false); - } -#endif - std::vector<int> v; int rv = 1; diff --git a/xpcom/threads/HangMonitor.cpp b/xpcom/threads/HangMonitor.cpp index 71cc67ca4..bd415be50 100644 --- a/xpcom/threads/HangMonitor.cpp +++ b/xpcom/threads/HangMonitor.cpp @@ -22,10 +22,6 @@ #include "nsThreadUtils.h" #include "nsXULAppAPI.h" -#ifdef MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" -#endif - #ifdef XP_WIN #include <windows.h> #endif @@ -111,15 +107,6 @@ Crash() } #endif -#ifdef MOZ_CRASHREPORTER - // If you change this, you must also deal with the threadsafety of AnnotateCrashReport in - // non-chrome processes! - if (GeckoProcessType_Default == XRE_GetProcessType()) { - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Hang"), - NS_LITERAL_CSTRING("1")); - } -#endif - NS_RUNTIMEABORT("HangMonitor triggered"); } diff --git a/xpcom/threads/nsThread.cpp b/xpcom/threads/nsThread.cpp index 63bd28ca3..7c1af08f4 100644 --- a/xpcom/threads/nsThread.cpp +++ b/xpcom/threads/nsThread.cpp @@ -39,12 +39,6 @@ #include "nsThreadSyncDispatch.h" #include "LeakRefPtr.h" -#ifdef MOZ_CRASHREPORTER -#include "nsServiceManagerUtils.h" -#include "nsICrashReporter.h" -#include "mozilla/dom/ContentChild.h" -#endif - #ifdef XP_LINUX #include <sys/time.h> #include <sys/resource.h> @@ -520,73 +514,6 @@ nsThread::ThreadFunc(void* aArg) //----------------------------------------------------------------------------- -#ifdef MOZ_CRASHREPORTER -// Tell the crash reporter to save a memory report if our heuristics determine -// that an OOM failure is likely to occur soon. -// Memory usage will not be checked more than every 30 seconds or saved more -// than every 3 minutes -// If |aShouldSave == kForceReport|, a report will be saved regardless of -// whether the process is low on memory or not. However, it will still not be -// saved if a report was saved less than 3 minutes ago. -bool -nsThread::SaveMemoryReportNearOOM(ShouldSaveMemoryReport aShouldSave) -{ - // Keep an eye on memory usage (cheap, ~7ms) somewhat frequently, - // but save memory reports (expensive, ~75ms) less frequently. - const size_t kLowMemoryCheckSeconds = 30; - const size_t kLowMemorySaveSeconds = 3 * 60; - - static TimeStamp nextCheck = TimeStamp::NowLoRes() - + TimeDuration::FromSeconds(kLowMemoryCheckSeconds); - static bool recentlySavedReport = false; // Keeps track of whether a report - // was saved last time we checked - - // Are we checking again too soon? - TimeStamp now = TimeStamp::NowLoRes(); - if ((aShouldSave == ShouldSaveMemoryReport::kMaybeReport || - recentlySavedReport) && now < nextCheck) { - return false; - } - - bool needMemoryReport = (aShouldSave == ShouldSaveMemoryReport::kForceReport); -#ifdef XP_WIN // XXX implement on other platforms as needed - // If the report is forced there is no need to check whether it is necessary - if (aShouldSave != ShouldSaveMemoryReport::kForceReport) { - const size_t LOWMEM_THRESHOLD_VIRTUAL = 200 * 1024 * 1024; - MEMORYSTATUSEX statex; - statex.dwLength = sizeof(statex); - if (GlobalMemoryStatusEx(&statex)) { - if (statex.ullAvailVirtual < LOWMEM_THRESHOLD_VIRTUAL) { - needMemoryReport = true; - } - } - } -#endif - - if (needMemoryReport) { - if (XRE_IsContentProcess()) { - dom::ContentChild* cc = dom::ContentChild::GetSingleton(); - if (cc) { - cc->SendNotifyLowMemory(); - } - } else { - nsCOMPtr<nsICrashReporter> cr = - do_GetService("@mozilla.org/toolkit/crash-reporter;1"); - if (cr) { - cr->SaveMemoryReport(); - } - } - recentlySavedReport = true; - nextCheck = now + TimeDuration::FromSeconds(kLowMemorySaveSeconds); - } else { - recentlySavedReport = false; - nextCheck = now + TimeDuration::FromSeconds(kLowMemoryCheckSeconds); - } - - return recentlySavedReport; -} -#endif - #ifdef MOZ_CANARY int sCanaryOutputFD = -1; #endif @@ -1459,12 +1386,6 @@ nsThread::DoMainThreadSpecificProcessing(bool aReallyWait) } } } - -#ifdef MOZ_CRASHREPORTER - if (!ShuttingDown()) { - SaveMemoryReportNearOOM(ShouldSaveMemoryReport::kMaybeReport); - } -#endif } //----------------------------------------------------------------------------- diff --git a/xpcom/threads/nsThread.h b/xpcom/threads/nsThread.h index 836123747..037ef1952 100644 --- a/xpcom/threads/nsThread.h +++ b/xpcom/threads/nsThread.h @@ -83,16 +83,6 @@ public: void WaitForAllAsynchronousShutdowns(); -#ifdef MOZ_CRASHREPORTER - enum class ShouldSaveMemoryReport - { - kMaybeReport, - kForceReport - }; - - static bool SaveMemoryReportNearOOM(ShouldSaveMemoryReport aShouldSave); -#endif - private: void DoMainThreadSpecificProcessing(bool aReallyWait); |