diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index 582fa2fad166..285790de6fdc 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -1950,10 +1950,6 @@ pref("toolkit.telemetry.updatePing.enabled", true); // Enables sending 'bhr' pings when the browser hangs. pref("toolkit.telemetry.bhrPing.enabled", true); -// Ping Centre Telemetry settings. -pref("browser.ping-centre.telemetry", true); -pref("browser.ping-centre.log", false); - // Enable GMP support in the addon manager. pref("media.gmp-provider.enabled", true); diff --git a/browser/components/newtab/content-src/asrouter/docs/debugging-docs.md b/browser/components/newtab/content-src/asrouter/docs/debugging-docs.md index d683e2f69d30..dab1c0895d47 100644 --- a/browser/components/newtab/content-src/asrouter/docs/debugging-docs.md +++ b/browser/components/newtab/content-src/asrouter/docs/debugging-docs.md @@ -20,18 +20,13 @@ In order to see all active messages for a current provider such as `cfr`, use th The messages on the page should now be filtered to include only the provider you selected. -## How to test telemetry pings +## How to test data collection -To test telemetry pings, complete the the following steps: +All of Messaging System, including ASRouter, is instrumented in Glean. +To test this instrumentation, please consult [this guide](/toolkit/components/glean/user/instrumentation_tests.md), and: - In about:config, set: - `browser.newtabpage.activity-stream.telemetry` to `true` - - `browser.ping-centre.log` to `true` - To view additional debug logs for messaging system or about:welcome, set: - `messaging-system.log` to `debug` - `browser.aboutwelcome.log` to `debug` -- Open the Browser Toolbox devtools (Tools > Web Developer > Browser Toolbox) and switch to the console tab. Add a filter for for `activity-stream` to only display relevant pings: - -![Devtools telemetry ping](./telemetry-screenshot.png) - -You should now see pings show up as you view/interact with ASR messages/templates. diff --git a/browser/components/newtab/content-src/asrouter/docs/telemetry-screenshot.png b/browser/components/newtab/content-src/asrouter/docs/telemetry-screenshot.png deleted file mode 100644 index b27b4ab958d7..000000000000 Binary files a/browser/components/newtab/content-src/asrouter/docs/telemetry-screenshot.png and /dev/null differ diff --git a/browser/components/newtab/content-src/asrouter/docs/telemetry.md b/browser/components/newtab/content-src/asrouter/docs/telemetry.md index b6fcfd741fca..b775e6c8e866 100644 --- a/browser/components/newtab/content-src/asrouter/docs/telemetry.md +++ b/browser/components/newtab/content-src/asrouter/docs/telemetry.md @@ -1,13 +1,5 @@ # Messaging System & Onboarding Telemetry -For historical reasons, the current (but soon-to-be legacy) Messaging System & Onboarding -telemetry documentation is mixed in with the Activity Stream documentation. All -except the main documentation is at [metrics we -collect](/browser/components/newtab/docs/v2-system-addon/data_events.md) and the -[data dictionary](/browser/components/newtab/docs/v2-system-addon/data_dictionary.md). - -## Migration to Glean - Code all over the messaging system passes JSON ping objects up to a few central spots. It may be [annotated with attribution](https://searchfox.org/mozilla-central/search?q=symbol:AboutWelcomeTelemetry%23_maybeAttachAttribution&redirect=false) @@ -15,17 +7,14 @@ along the way, and/or adjusted by some [policy routines](https://searchfox.org/mozilla-central/search?q=symbol:TelemetryFeed%23createASRouterEvent&redirect=false) before it's sent. [A version of the JSON that's been transformed slightly further is sent to Glean](https://searchfox.org/mozilla-central/search?q=.submitGleanPingForPing&path=*.jsm&case=false®exp=false). -The original annotated, policy-abiding JSON is sent to PingCentre immediately -after. After more validation and usage of Glean data has happened, we'll [stop -sending the data to PingCentre entirely](https://bugzilla.mozilla.org/show_bug.cgi?id=1849006). ## Adding or changing telemetry -For now, do the same stuff we've always done in OMC: follow the [process in +Follow the [process in the Activity Stream telemetry -document](/browser/components/newtab/docs/v2-system-addon/telemetry.md) with one -exception: avoid adding any new nested objects, as these end up being flattened -or stringified before being sent to glean. Note that when you need to add new metrics +document](/browser/components/newtab/docs/v2-system-addon/telemetry.md), +and avoid adding any new nested objects, as these end up being flattened +or stringified before being sent to Glean. Note that when you need to add new metrics (i.e. JSON keys), they MUST to be [added](https://mozilla.github.io/glean/book/user/metrics/adding-new-metrics.html) to [browser/components/newtab/metrics.yaml](https://searchfox.org/mozilla-central/source/browser/components/newtab/metrics.yaml) diff --git a/browser/components/newtab/test/browser/abouthomecache/browser.toml b/browser/components/newtab/test/browser/abouthomecache/browser.toml index fb6946b7680f..1994415d9a74 100644 --- a/browser/components/newtab/test/browser/abouthomecache/browser.toml +++ b/browser/components/newtab/test/browser/abouthomecache/browser.toml @@ -16,7 +16,6 @@ prefs = [ "browser.newtabpage.activity-stream.feeds.system.topstories=true", "browser.newtabpage.activity-stream.feeds.section.topstories.options={\"provider_name\":\"\"}", "browser.newtabpage.activity-stream.telemetry.structuredIngestion=false", - "browser.ping-centre.telemetry=false", "browser.newtabpage.activity-stream.discoverystream.endpoints=https://example.com", "dom.ipc.processPrelaunch.delayMs=0", # Bug 1694957 is why we need dom.ipc.processPrelaunch.delayMs=0 diff --git a/browser/components/newtab/test/schemas/pings.js b/browser/components/newtab/test/schemas/pings.js index dffa2e17a0a5..fc35da3a95a2 100644 --- a/browser/components/newtab/test/schemas/pings.js +++ b/browser/components/newtab/test/schemas/pings.js @@ -5,7 +5,6 @@ import { import Joi from "joi-browser"; export const baseKeys = { - // client_id will be set by PingCentre if it doesn't exist. client_id: Joi.string().optional(), addon_version: Joi.string().required(), locale: Joi.string().required(), diff --git a/browser/components/newtab/test/xpcshell/test_AboutHomeStartupCacheWorker.js b/browser/components/newtab/test/xpcshell/test_AboutHomeStartupCacheWorker.js index 9db3933ed911..273b82283798 100644 --- a/browser/components/newtab/test/xpcshell/test_AboutHomeStartupCacheWorker.js +++ b/browser/components/newtab/test/xpcshell/test_AboutHomeStartupCacheWorker.js @@ -108,7 +108,6 @@ add_setup(async function () { "browser.newtabpage.activity-stream.telemetry.structuredIngestion", false ); - Services.prefs.setBoolPref("browser.ping-centre.telemetry", false); // We need a default search engine set up for rendering the search input. await SearchTestUtils.installSearchExtension( diff --git a/browser/components/urlbar/tests/quicksuggest/unit/test_quicksuggest_impressionCaps.js b/browser/components/urlbar/tests/quicksuggest/unit/test_quicksuggest_impressionCaps.js index b76f4469c488..1c00cb532019 100644 --- a/browser/components/urlbar/tests/quicksuggest/unit/test_quicksuggest_impressionCaps.js +++ b/browser/components/urlbar/tests/quicksuggest/unit/test_quicksuggest_impressionCaps.js @@ -3856,11 +3856,7 @@ async function checkSearch({ name, searchString, expectedResults }) { // Impression stats are updated only on engagement, so force one now. // `selIndex` doesn't really matter but since we're not trying to simulate a - // click on the suggestion, pass in -1 to ensure we don't record a click. Pass - // in true for `isPrivate` so we don't attempt to record the impression ping - // because otherwise the following PingCentre error is logged: - // "Structured Ingestion ping failure with error: undefined" - context.isPrivate = true; + // click on the suggestion, pass in -1 to ensure we don't record a click. if (UrlbarProviderQuickSuggest._resultFromLastQuery) { UrlbarProviderQuickSuggest._resultFromLastQuery.isVisible = true; } diff --git a/browser/modules/PingCentre.sys.mjs b/browser/modules/PingCentre.sys.mjs deleted file mode 100644 index e5c99b15a728..000000000000 --- a/browser/modules/PingCentre.sys.mjs +++ /dev/null @@ -1,173 +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/. */ - -import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs"; - -const lazy = {}; -ChromeUtils.defineESModuleGetters(lazy, { - TelemetryEnvironment: "resource://gre/modules/TelemetryEnvironment.sys.mjs", - UpdateUtils: "resource://gre/modules/UpdateUtils.sys.mjs", - sendStandalonePing: "resource://gre/modules/TelemetrySend.sys.mjs", -}); - -const PREF_BRANCH = "browser.ping-centre."; - -const TELEMETRY_PREF = `${PREF_BRANCH}telemetry`; -const LOGGING_PREF = `${PREF_BRANCH}log`; - -const FHR_UPLOAD_ENABLED_PREF = "datareporting.healthreport.uploadEnabled"; - -/** - * Observe various notifications and send them to a telemetry endpoint. - * - * @param {Object} options - * @param {string} options.topic - a unique ID for users of PingCentre to distinguish - * their data on the server side. - */ -export class PingCentre { - constructor(options) { - if (!options.topic) { - throw new Error("Must specify topic."); - } - - this._topic = options.topic; - this._prefs = Services.prefs.getBranch(""); - - this._enabled = this._prefs.getBoolPref(TELEMETRY_PREF); - this._onTelemetryPrefChange = this._onTelemetryPrefChange.bind(this); - this._prefs.addObserver(TELEMETRY_PREF, this._onTelemetryPrefChange); - - this._fhrEnabled = this._prefs.getBoolPref(FHR_UPLOAD_ENABLED_PREF); - this._onFhrPrefChange = this._onFhrPrefChange.bind(this); - this._prefs.addObserver(FHR_UPLOAD_ENABLED_PREF, this._onFhrPrefChange); - - this.logging = this._prefs.getBoolPref(LOGGING_PREF); - this._onLoggingPrefChange = this._onLoggingPrefChange.bind(this); - this._prefs.addObserver(LOGGING_PREF, this._onLoggingPrefChange); - } - - get enabled() { - return this._enabled && this._fhrEnabled; - } - - _onLoggingPrefChange(aSubject, aTopic, prefKey) { - this.logging = this._prefs.getBoolPref(prefKey); - } - - _onTelemetryPrefChange(aSubject, aTopic, prefKey) { - this._enabled = this._prefs.getBoolPref(prefKey); - } - - _onFhrPrefChange(aSubject, aTopic, prefKey) { - this._fhrEnabled = this._prefs.getBoolPref(prefKey); - } - - _createExperimentsPayload() { - let activeExperiments = lazy.TelemetryEnvironment.getActiveExperiments(); - let experiments = {}; - for (let experimentID in activeExperiments) { - if ( - activeExperiments[experimentID] && - activeExperiments[experimentID].branch - ) { - experiments[experimentID] = { - branch: activeExperiments[experimentID].branch, - }; - } - } - return experiments; - } - - _createStructuredIngestionPing(data) { - let experiments = this._createExperimentsPayload(); - let locale = data.locale || Services.locale.appLocaleAsBCP47; - const payload = { - experiments, - locale, - version: AppConstants.MOZ_APP_VERSION, - release_channel: lazy.UpdateUtils.getUpdateChannel(false), - ...data, - }; - - return payload; - } - - // We route through this helper because it gets hooked in testing. - static _sendStandalonePing(endpoint, payload) { - return lazy.sendStandalonePing(endpoint, payload); - } - - /** - * Sends a ping to the Structured Ingestion telemetry pipeline. - * - * The payload would be compressed using gzip. - * - * @param {Object} data The payload to be sent. - * @param {String} endpoint The destination endpoint. Note that Structured Ingestion - * requires a different endpoint for each ping. It's up to the - * caller to provide that. See more details at - * https://github.com/mozilla/gcp-ingestion/blob/master/docs/edge.md#postput-request - * @param {String} namespace Optional. The structured ingestion namespace. - * Used for data collection. - */ - sendStructuredIngestionPing(data, endpoint, namespace = undefined) { - if (!this.enabled) { - return Promise.resolve(); - } - - const ping = this._createStructuredIngestionPing(data); - const payload = JSON.stringify(ping); - - if (this.logging) { - Services.console.logStringMessage( - `TELEMETRY PING (${this._topic}): ${payload}\n` - ); - } - - let gleanNamespace = "other"; - switch (namespace) { - case "activity-stream": - gleanNamespace = "activity_stream"; - break; - case "messaging-system": - gleanNamespace = "messaging_system"; - break; - case "contextual-services": - gleanNamespace = "contextual_services"; - break; - } - - return PingCentre._sendStandalonePing(endpoint, payload).then( - () => { - Glean.pingCentre.sendSuccessesByNamespace[gleanNamespace].add(1); - }, - event => { - Glean.pingCentre.sendFailures.add(1); - Glean.pingCentre.sendFailuresByNamespace[gleanNamespace].add(1); - console.error( - `Structured Ingestion ping failure with error: ${event.type}` - ); - } - ); - } - - uninit() { - try { - this._prefs.removeObserver(TELEMETRY_PREF, this._onTelemetryPrefChange); - this._prefs.removeObserver(LOGGING_PREF, this._onLoggingPrefChange); - this._prefs.removeObserver( - FHR_UPLOAD_ENABLED_PREF, - this._onFhrPrefChange - ); - } catch (e) { - console.error(e); - } - } -} - -export const PingCentreConstants = { - FHR_UPLOAD_ENABLED_PREF, - TELEMETRY_PREF, - LOGGING_PREF, -}; diff --git a/browser/modules/metrics.yaml b/browser/modules/metrics.yaml index b8f9d036e2f3..24ec1981b8dc 100644 --- a/browser/modules/metrics.yaml +++ b/browser/modules/metrics.yaml @@ -93,66 +93,3 @@ browser.engagement: send_in_pings: - metrics expires: never - -ping.centre: - send_failures: - type: counter - description: | - The number of PingCentre send failures. - bugs: - - https://bugzilla.mozilla.org/show_bug.cgi?id=1800079 - - https://bugzilla.mozilla.org/show_bug.cgi?id=1827767 - data_reviews: - - https://bugzilla.mozilla.org/show_bug.cgi?id=1800079 - - https://bugzilla.mozilla.org/show_bug.cgi?id=1827767 - - https://bugzilla.mozilla.org/show_bug.cgi?id=1851237 - data_sensitivity: - - technical - notification_emails: - - chutten@mozilla.com - expires: 125 - - send_failures_by_namespace: - type: labeled_counter - description: | - The number of PingCentre send failures, - broken down by structured ingestion namespace. - bugs: - - https://bugzilla.mozilla.org/show_bug.cgi?id=1814922 - - https://bugzilla.mozilla.org/show_bug.cgi?id=1827767 - data_reviews: - - https://bugzilla.mozilla.org/show_bug.cgi?id=1814922 - - https://bugzilla.mozilla.org/show_bug.cgi?id=1827767 - - https://bugzilla.mozilla.org/show_bug.cgi?id=1851237 - data_sensitivity: - - technical - notification_emails: - - chutten@mozilla.com - expires: 125 - labels: &structured_ingestion_namespaces - - activity_stream - - messaging_system - - contextual_services - no_lint: - - COMMON_PREFIX - - send_successes_by_namespace: - type: labeled_counter - description: | - The number of PingCentre send successes, - broken down by structured ingestion namespace. - bugs: - - https://bugzilla.mozilla.org/show_bug.cgi?id=1814922 - - https://bugzilla.mozilla.org/show_bug.cgi?id=1827767 - data_reviews: - - https://bugzilla.mozilla.org/show_bug.cgi?id=1814922 - - https://bugzilla.mozilla.org/show_bug.cgi?id=1827767 - - https://bugzilla.mozilla.org/show_bug.cgi?id=1851237 - data_sensitivity: - - technical - notification_emails: - - chutten@mozilla.com - expires: 125 - labels: *structured_ingestion_namespaces - no_lint: - - COMMON_PREFIX diff --git a/browser/modules/moz.build b/browser/modules/moz.build index 52a411360b12..79d8756eda1d 100644 --- a/browser/modules/moz.build +++ b/browser/modules/moz.build @@ -139,7 +139,6 @@ EXTRA_JS_MODULES += [ "PageActions.sys.mjs", "PartnerLinkAttribution.sys.mjs", "PermissionUI.sys.mjs", - "PingCentre.sys.mjs", "ProcessHangMonitor.sys.mjs", "Sanitizer.sys.mjs", "SelectionChangedMenulist.sys.mjs", diff --git a/browser/modules/test/unit/test_PingCentre.js b/browser/modules/test/unit/test_PingCentre.js deleted file mode 100644 index 6c38397e5fc2..000000000000 --- a/browser/modules/test/unit/test_PingCentre.js +++ /dev/null @@ -1,194 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -"use strict"; - -const { PingCentre, PingCentreConstants } = ChromeUtils.importESModule( - "resource:///modules/PingCentre.sys.mjs" -); -const { TelemetryEnvironment } = ChromeUtils.importESModule( - "resource://gre/modules/TelemetryEnvironment.sys.mjs" -); -const { AppConstants } = ChromeUtils.importESModule( - "resource://gre/modules/AppConstants.sys.mjs" -); -const { UpdateUtils } = ChromeUtils.importESModule( - "resource://gre/modules/UpdateUtils.sys.mjs" -); - -const { sinon } = ChromeUtils.importESModule( - "resource://testing-common/Sinon.sys.mjs" -); - -const FAKE_PING = { event: "fake_event", value: "fake_value", locale: "en-US" }; -const FAKE_ENDPOINT = "https://www.test.com"; - -let pingCentre; -let sandbox; -let fogInitd = false; - -function _setUp() { - Services.prefs.setBoolPref(PingCentreConstants.TELEMETRY_PREF, true); - Services.prefs.setBoolPref(PingCentreConstants.FHR_UPLOAD_ENABLED_PREF, true); - Services.prefs.setBoolPref(PingCentreConstants.LOGGING_PREF, true); - sandbox.restore(); - if (fogInitd) { - Services.fog.testResetFOG(); - } -} - -add_setup(function setup() { - sandbox = sinon.createSandbox(); - _setUp(); - pingCentre = new PingCentre({ topic: "test_topic" }); - - registerCleanupFunction(() => { - sandbox.restore(); - Services.prefs.clearUserPref(PingCentreConstants.TELEMETRY_PREF); - Services.prefs.clearUserPref(PingCentreConstants.FHR_UPLOAD_ENABLED_PREF); - Services.prefs.clearUserPref(PingCentreConstants.LOGGING_PREF); - }); - - // On Android, FOG is set up through head.js - if (AppConstants.platform != "android") { - do_get_profile(); - Services.fog.initializeFOG(); - fogInitd = true; - } -}); - -add_task(function test_enabled() { - _setUp(); - Assert.ok(pingCentre.enabled, "Telemetry should be on"); -}); - -add_task(function test_disabled_by_pingCentre() { - _setUp(); - Services.prefs.setBoolPref(PingCentreConstants.TELEMETRY_PREF, false); - - Assert.ok(!pingCentre.enabled, "Telemetry should be off"); -}); - -add_task(function test_disabled_by_FirefoxHealthReport() { - _setUp(); - Services.prefs.setBoolPref( - PingCentreConstants.FHR_UPLOAD_ENABLED_PREF, - false - ); - - Assert.ok(!pingCentre.enabled, "Telemetry should be off"); -}); - -add_task(function test_logging() { - _setUp(); - Assert.ok(pingCentre.logging, "Logging should be on"); - - Services.prefs.setBoolPref(PingCentreConstants.LOGGING_PREF, false); - - Assert.ok(!pingCentre.logging, "Logging should be off"); -}); - -add_task(function test_createExperimentsPayload() { - _setUp(); - const activeExperiments = { - exp1: { branch: "foo", enrollmentID: "SOME_RANDON_ID" }, - exp2: { branch: "bar", type: "PrefStudy" }, - exp3: {}, - }; - sandbox - .stub(TelemetryEnvironment, "getActiveExperiments") - .returns(activeExperiments); - const expected = { - exp1: { branch: "foo" }, - exp2: { branch: "bar" }, - }; - - const experiments = pingCentre._createExperimentsPayload(); - - Assert.deepEqual( - experiments, - expected, - "Should create experiments with all the required context" - ); -}); - -add_task(function test_createExperimentsPayload_without_active_experiments() { - _setUp(); - sandbox.stub(TelemetryEnvironment, "getActiveExperiments").returns({}); - const experiments = pingCentre._createExperimentsPayload({}); - - Assert.deepEqual(experiments, {}, "Should send an empty object"); -}); - -add_task(function test_createStructuredIngestionPing() { - _setUp(); - sandbox - .stub(TelemetryEnvironment, "getActiveExperiments") - .returns({ exp1: { branch: "foo" } }); - const ping = pingCentre._createStructuredIngestionPing(FAKE_PING); - const expected = { - experiments: { exp1: { branch: "foo" } }, - locale: "en-US", - version: AppConstants.MOZ_APP_VERSION, - release_channel: UpdateUtils.getUpdateChannel(false), - ...FAKE_PING, - }; - - Assert.deepEqual(ping, expected, "Should create a valid ping"); -}); - -add_task(function test_sendStructuredIngestionPing_disabled() { - _setUp(); - sandbox.stub(PingCentre, "_sendStandalonePing").resolves(); - Services.prefs.setBoolPref(PingCentreConstants.TELEMETRY_PREF, false); - pingCentre.sendStructuredIngestionPing(FAKE_PING, FAKE_ENDPOINT); - - Assert.ok(PingCentre._sendStandalonePing.notCalled, "Should not be sent"); -}); - -add_task(async function test_sendStructuredIngestionPing_success() { - _setUp(); - sandbox.stub(PingCentre, "_sendStandalonePing").resolves(); - await pingCentre.sendStructuredIngestionPing( - FAKE_PING, - FAKE_ENDPOINT, - "messaging-system" - ); - - Assert.equal(PingCentre._sendStandalonePing.callCount, 1, "Should be sent"); - Assert.equal( - 1, - Glean.pingCentre.sendSuccessesByNamespace.messaging_system.testGetValue() - ); - - // Test an unknown namespace - await pingCentre.sendStructuredIngestionPing( - FAKE_PING, - FAKE_ENDPOINT, - "different-system" - ); - - Assert.equal(PingCentre._sendStandalonePing.callCount, 2, "Should be sent"); - Assert.equal( - 1, - Glean.pingCentre.sendSuccessesByNamespace.__other__.testGetValue() - ); -}); - -add_task(async function test_sendStructuredIngestionPing_failure() { - _setUp(); - sandbox.stub(PingCentre, "_sendStandalonePing").rejects(); - Assert.equal(undefined, Glean.pingCentre.sendFailures.testGetValue()); - await pingCentre.sendStructuredIngestionPing( - FAKE_PING, - FAKE_ENDPOINT, - "activity-stream" - ); - - Assert.equal(1, Glean.pingCentre.sendFailures.testGetValue()); - Assert.equal( - 1, - Glean.pingCentre.sendFailuresByNamespace.activity_stream.testGetValue() - ); -}); diff --git a/browser/modules/test/unit/xpcshell.toml b/browser/modules/test/unit/xpcshell.toml index 0bb4e72cb23d..2b4a9a66ea5d 100644 --- a/browser/modules/test/unit/xpcshell.toml +++ b/browser/modules/test/unit/xpcshell.toml @@ -14,8 +14,6 @@ run-if = ["os == 'win'"] # Test of a Windows-specific feature ["test_LaterRun.js"] -["test_PingCentre.js"] - ["test_ProfileCounter.js"] run-if = ["os == 'win'"] # Test of a Windows-specific feature diff --git a/tools/esmify/map.json b/tools/esmify/map.json index 01f5c657a067..f1ffe5b84bf1 100644 --- a/tools/esmify/map.json +++ b/tools/esmify/map.json @@ -167,7 +167,6 @@ "resource:///modules/PageActions.jsm": "browser/modules/PageActions.jsm", "resource:///modules/PanelMultiView.jsm": "browser/components/customizableui/PanelMultiView.jsm", "resource:///modules/PartnerLinkAttribution.jsm": "browser/modules/PartnerLinkAttribution.jsm", - "resource:///modules/PingCentre.jsm": "browser/modules/PingCentre.jsm", "resource:///modules/PinnedGroupBuilder.jsm": "browser/components/places/PinnedGroupBuilder.jsm", "resource:///modules/PlacesUIUtils.jsm": "browser/components/places/PlacesUIUtils.jsm", "resource:///modules/ProcessHangMonitor.jsm": "browser/modules/ProcessHangMonitor.jsm",