From 04ddaeaf6d3e9f42bd8cbfa338bd8574212ab68e Mon Sep 17 00:00:00 2001 From: Gregor Wagner Date: Mon, 19 Nov 2012 12:31:09 -0800 Subject: [PATCH 01/57] Bug 809944 - Require access fields in manifests. r=bent --- dom/apps/src/PermissionsInstaller.jsm | 27 +++++--------------- dom/contacts/tests/test_contacts_basics.html | 2 +- 2 files changed, 7 insertions(+), 22 deletions(-) diff --git a/dom/apps/src/PermissionsInstaller.jsm b/dom/apps/src/PermissionsInstaller.jsm index 1959cac8ac2e..c3f0015546ee 100644 --- a/dom/apps/src/PermissionsInstaller.jsm +++ b/dom/apps/src/PermissionsInstaller.jsm @@ -282,15 +282,12 @@ this.expandPermissions = function expandPermissions(aPermName, aAccess) { return []; } -/* -Temporarily disabled in order to add access fields to gaia: See Bug 805646 if (!aAccess && tableEntry.access || aAccess && !tableEntry.access) { Cu.reportError("PermissionsTable.jsm: expandPermissions: Invalid Manifest : " + aPermName + " " + aAccess + "\n"); throw new Error("PermissionsTable.jsm: expandPermissions: Invalid Manifest"); } -*/ let expandedPerms = []; @@ -313,28 +310,16 @@ Temporarily disabled in order to add access fields to gaia: See Bug 805646 return []; } - // XXXbent This is a temporary hack! Remove this whole block once the - // Settings API and the DeviceStorage API have stopped checking just - // the bare permission (e.g. "settings" vs. "settings-read"). - if (true) { - expandedPerms.push(aPermName); - if (tableEntry.additional) { - for each (let additional in tableEntry.additional) { - expandedPerms.push(additional); - } - } - } - let permArr = mapSuffixes(aPermName, requestedSuffixes); - // Add the same suffix to each of the additions. - if (tableEntry.additional) { - for each (let additional in tableEntry.additional) { - permArr = permArr.concat(mapSuffixes(additional, requestedSuffixes)); - } + // Add the same suffix to each of the additions. + if (tableEntry.additional) { + for each (let additional in tableEntry.additional) { + permArr = permArr.concat(mapSuffixes(additional, requestedSuffixes)); } + } - // Only add the suffixed version if the suffix exisits in the table. + // Only add the suffixed version if the suffix exisits in the table. for (let idx in permArr) { let suffix = requestedSuffixes[idx % requestedSuffixes.length]; if (tableEntry.access.indexOf(suffix) != -1) { diff --git a/dom/contacts/tests/test_contacts_basics.html b/dom/contacts/tests/test_contacts_basics.html index d33f590f38e4..73f86a82c0dc 100644 --- a/dom/contacts/tests/test_contacts_basics.html +++ b/dom/contacts/tests/test_contacts_basics.html @@ -231,7 +231,7 @@ function checkContacts(contact1, contact2) { var req; var index = 0; -var mozContacts = window.navigator.mozContacts +var mozContacts = window.navigator.mozContacts; var steps = [ function () { From d47d2fbf5cb26fa2822c943697f96c8c3ec31640 Mon Sep 17 00:00:00 2001 From: Gregor Wagner Date: Mon, 19 Nov 2012 12:31:15 -0800 Subject: [PATCH 02/57] Bug 809944 - Require access fields in manifests. Tests. r=ddahl --- dom/apps/src/PermissionsInstaller.jsm | 10 ++++++++-- dom/permission/tests/unit/test_bug808734.js | 13 +++---------- dom/tests/browser/browser_webapps_permissions.js | 12 +++++++----- dom/tests/browser/test-webapp.webapp | 4 ++-- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/dom/apps/src/PermissionsInstaller.jsm b/dom/apps/src/PermissionsInstaller.jsm index c3f0015546ee..91385a16dda6 100644 --- a/dom/apps/src/PermissionsInstaller.jsm +++ b/dom/apps/src/PermissionsInstaller.jsm @@ -271,6 +271,7 @@ this.PermissionsTable = { "resource-lock": { this.expandPermissions = function expandPermissions(aPermName, aAccess) { if (!PermissionsTable[aPermName]) { Cu.reportError("PermissionsTable.jsm: expandPermissions: Unknown Permission: " + aPermName); + dump("PermissionsTable.jsm: expandPermissions: Unknown Permission: " + aPermName); return []; } @@ -286,7 +287,10 @@ this.expandPermissions = function expandPermissions(aPermName, aAccess) { aAccess && !tableEntry.access) { Cu.reportError("PermissionsTable.jsm: expandPermissions: Invalid Manifest : " + aPermName + " " + aAccess + "\n"); - throw new Error("PermissionsTable.jsm: expandPermissions: Invalid Manifest"); + dump("PermissionsTable.jsm: expandPermissions: Invalid Manifest: " + + aPermName + " " + aAccess + "\n"); + throw new Error("PermissionsTable.jsm: expandPermissions: Invalid Manifest: " + + aPermName + " " + aAccess + "\n"); } let expandedPerms = []; @@ -424,6 +428,8 @@ this.PermissionsInstaller = { if (!PermissionsTable[permName]) { Cu.reportError("PermissionsInstaller.jsm: '" + permName + "'" + " is not a valid Webapps permission type."); + dump("PermissionsInstaller.jsm: '" + permName + "'" + + " is not a valid Webapps permission type."); continue; } @@ -437,7 +443,7 @@ this.PermissionsInstaller = { } } catch (ex) { - debug("Caught webapps install permissions error"); + dump("Caught webapps install permissions error for " + aApp.origin); Cu.reportError(ex); if (aOnError) { aOnError(); diff --git a/dom/permission/tests/unit/test_bug808734.js b/dom/permission/tests/unit/test_bug808734.js index 76745ef0f7a2..13f9c6631f16 100644 --- a/dom/permission/tests/unit/test_bug808734.js +++ b/dom/permission/tests/unit/test_bug808734.js @@ -2,32 +2,25 @@ const Cu = Components.utils; const READWRITE = "readwrite"; const UNKNOWN = "foobar"; -/* - * Remove "contacts" from first test expected array and - * "settings" and "indexedDB-chrome-settings" from second - * test when this is fixed - * http://mxr.mozilla.org/mozilla-central/source/dom/apps/src/PermissionsInstaller.jsm#316 - */ var gData = [ // test normal expansion { permission: "contacts", access: READWRITE, - expected: ["contacts", "contacts-read", "contacts-create", + expected: ["contacts-read", "contacts-create", "contacts-write"] }, // test additional expansion and access not having read+create+write { permission: "settings", access: READWRITE, - expected: ["settings", "settings-read", "settings-write", - "indexedDB-chrome-settings", "indexedDB-chrome-settings-read", + expected: ["settings-read", "settings-write", + "indexedDB-chrome-settings-read", "indexedDB-chrome-settings-write"] }, // test substitute { permission: "storage", - access: READWRITE, expected: ["indexedDB-unlimited", "offline-app", "pin-app"] }, // test unknown access diff --git a/dom/tests/browser/browser_webapps_permissions.js b/dom/tests/browser/browser_webapps_permissions.js index 87afd69b4c11..92ff3b773e31 100644 --- a/dom/tests/browser/browser_webapps_permissions.js +++ b/dom/tests/browser/browser_webapps_permissions.js @@ -27,15 +27,17 @@ const TEST_ORIGIN_URL = "http://mochi.test:8888"; const installedPermsToTest = { "geolocation": "prompt", "alarms": "allow", - "contacts": "prompt", - "device-storage:apps": "prompt", + "contacts-write": "prompt", + "contacts-read": "prompt", + "device-storage:apps-read": "prompt", + "device-storage:apps-write": "unknown" }; const uninstalledPermsToTest = { "geolocation": "unknown", "alarms": "unknown", - "contacts": "unknown", - "device-storage:apps": "unknown", + "contacts-read": "unknown", + "device-storage:apps-read": "unknown", }; var gWindow, gNavigator; @@ -68,7 +70,7 @@ function test() { ok(nav.mozApps, "we have a mozApps property"); var navMozPerms = nav.mozPermissionSettings; ok(navMozPerms, "mozPermissions is available"); - Math.sin(0); + // INSTALL app var pendingInstall = nav.mozApps.install(TEST_MANIFEST_URL, null); pendingInstall.onsuccess = function onsuccess() diff --git a/dom/tests/browser/test-webapp.webapp b/dom/tests/browser/test-webapp.webapp index 129f741347ca..cd27c086db61 100644 --- a/dom/tests/browser/test-webapp.webapp +++ b/dom/tests/browser/test-webapp.webapp @@ -10,10 +10,10 @@ "description": "alarm" }, "contacts": { - "description": "contacts" + "access": "readwrite" }, "device-storage:apps": { - "description": "storage" + "access": "readonly" } } } From 5d655ebe4256795929a8c91b3520e3e5e6fa64af Mon Sep 17 00:00:00 2001 From: Gregor Wagner Date: Mon, 19 Nov 2012 12:31:21 -0800 Subject: [PATCH 03/57] Bug 811923 - Device Storage: support "create" permission. r=dougt --- dom/devicestorage/nsDeviceStorage.cpp | 10 +++++++--- dom/devicestorage/nsDeviceStorage.h | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/dom/devicestorage/nsDeviceStorage.cpp b/dom/devicestorage/nsDeviceStorage.cpp index 6de766d761b1..70459d5dc4d1 100644 --- a/dom/devicestorage/nsDeviceStorage.cpp +++ b/dom/devicestorage/nsDeviceStorage.cpp @@ -213,6 +213,9 @@ DeviceStorageTypeChecker::GetAccessForRequest(const DeviceStorageRequestType aRe case DEVICE_STORAGE_REQUEST_DELETE: aAccessResult.AssignLiteral("write"); break; + case DEVICE_STORAGE_REQUEST_CREATE: + aAccessResult.AssignLiteral("create"); + break; default: aAccessResult.AssignLiteral("undefined"); } @@ -1553,7 +1556,7 @@ public: } switch(mRequestType) { - case DEVICE_STORAGE_REQUEST_WRITE: + case DEVICE_STORAGE_REQUEST_CREATE: { if (!mBlob) { return NS_ERROR_FAILURE; @@ -1581,6 +1584,7 @@ public: } case DEVICE_STORAGE_REQUEST_READ: + case DEVICE_STORAGE_REQUEST_WRITE: { if (XRE_GetProcessType() != GeckoProcessType_Default) { PDeviceStorageRequestChild* child = new DeviceStorageRequestChild(mRequest, mFile); @@ -1846,7 +1850,7 @@ nsDOMDeviceStorage::AddNamed(nsIDOMBlob *aBlob, r = new PostErrorEvent(request, POST_ERROR_EVENT_ILLEGAL_TYPE); } else { - r = new DeviceStorageRequest(DEVICE_STORAGE_REQUEST_WRITE, + r = new DeviceStorageRequest(DEVICE_STORAGE_REQUEST_CREATE, win, mPrincipal, dsf, request, aBlob); } @@ -1899,7 +1903,7 @@ nsDOMDeviceStorage::GetInternal(const JS::Value & aPath, if (!dsf->IsSafePath()) { r = new PostErrorEvent(request, POST_ERROR_EVENT_PERMISSION_DENIED); } else { - r = new DeviceStorageRequest(DEVICE_STORAGE_REQUEST_READ, + r = new DeviceStorageRequest(aEditable ? DEVICE_STORAGE_REQUEST_WRITE : DEVICE_STORAGE_REQUEST_READ, win, mPrincipal, dsf, request); } NS_DispatchToMainThread(r); diff --git a/dom/devicestorage/nsDeviceStorage.h b/dom/devicestorage/nsDeviceStorage.h index 67a61bf57231..43e4120766d4 100644 --- a/dom/devicestorage/nsDeviceStorage.h +++ b/dom/devicestorage/nsDeviceStorage.h @@ -42,6 +42,7 @@ class nsPIDOMWindow; enum DeviceStorageRequestType { DEVICE_STORAGE_REQUEST_READ, DEVICE_STORAGE_REQUEST_WRITE, + DEVICE_STORAGE_REQUEST_CREATE, DEVICE_STORAGE_REQUEST_DELETE, DEVICE_STORAGE_REQUEST_WATCH, DEVICE_STORAGE_REQUEST_STAT From 2fcc0a1c8b6afb1aaff9a6d21b22241148715c0b Mon Sep 17 00:00:00 2001 From: Gregor Wagner Date: Mon, 19 Nov 2012 12:31:25 -0800 Subject: [PATCH 04/57] Bug 812034 - Permissions: Connect access field for permission checks. r=ddahl --- b2g/components/ContentPermissionPrompt.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/b2g/components/ContentPermissionPrompt.js b/b2g/components/ContentPermissionPrompt.js index 9612191f4471..d712b0e057c8 100644 --- a/b2g/components/ContentPermissionPrompt.js +++ b/b2g/components/ContentPermissionPrompt.js @@ -60,7 +60,9 @@ function ContentPermissionPrompt() {} ContentPermissionPrompt.prototype = { handleExistingPermission: function handleExistingPermission(request) { - let result = Services.perms.testExactPermissionFromPrincipal(request.principal, request.type); + let access = (request.access && request.access !== "unused") ? request.type + "-" + request.access : + request.type; + let result = Services.perms.testExactPermissionFromPrincipal(request.principal, access); if (result == Ci.nsIPermissionManager.ALLOW_ACTION) { request.allow(); return true; @@ -83,6 +85,9 @@ ContentPermissionPrompt.prototype = { if (!content) return; + let access = (request.access && request.access !== "unused") ? request.type + "-" + request.access : + request.type; + let requestId = this._id++; content.addEventListener("mozContentEvent", function contentEvent(evt) { if (evt.detail.id != requestId) @@ -92,8 +97,6 @@ ContentPermissionPrompt.prototype = { if (evt.detail.type == "permission-allow") { if (evt.detail.remember) { rememberPermission(request.type, request.principal); - Services.perms.addFromPrincipal(request.principal, request.type, - Ci.nsIPermissionManager.ALLOW_ACTION); } request.allow(); @@ -101,7 +104,7 @@ ContentPermissionPrompt.prototype = { } if (evt.detail.remember) { - Services.perms.addFromPrincipal(request.principal, request.type, + Services.perms.addFromPrincipal(request.principal, access, Ci.nsIPermissionManager.DENY_ACTION); } @@ -120,7 +123,7 @@ ContentPermissionPrompt.prototype = { remember: request.remember }; - this._permission = request.type; + this._permission = access; this._uri = request.principal.URI.spec; this._origin = request.principal.origin; From 0478694ccb625cda466eaf3abaa671de9b45995b Mon Sep 17 00:00:00 2001 From: Andres Hernandez Date: Mon, 19 Nov 2012 14:44:07 -0600 Subject: [PATCH 05/57] Bug 722977 - Tabs engine uses global Svc.Private to make decisions based on private browsing state; r=ehsan,gps,rnewman --- services/sync/Makefile.in | 6 ++- services/sync/modules/engines/tabs.js | 56 ++++++++++++++++++--------- 2 files changed, 42 insertions(+), 20 deletions(-) diff --git a/services/sync/Makefile.in b/services/sync/Makefile.in index 4d973456554e..4fef0c10253d 100644 --- a/services/sync/Makefile.in +++ b/services/sync/Makefile.in @@ -54,9 +54,13 @@ sync_engine_modules := \ history.js \ passwords.js \ prefs.js \ - tabs.js \ $(NULL) +# Preprocess engine files. +SYNC_PP_ENGINE := modules/engines/tabs.js +SYNC_PP_ENGINE_PATH = $(FINAL_TARGET)/modules/services-sync/engines +PP_TARGETS += SYNC_PP_ENGINE + sync_stage_modules := \ cluster.js \ enginesync.js \ diff --git a/services/sync/modules/engines/tabs.js b/services/sync/modules/engines/tabs.js index 3b5a0bf48932..69ed71d269ec 100644 --- a/services/sync/modules/engines/tabs.js +++ b/services/sync/modules/engines/tabs.js @@ -18,13 +18,8 @@ Cu.import("resource://services-sync/util.js"); Cu.import("resource://services-sync/constants.js"); Cu.import("resource://services-common/preferences.js"); -// It is safer to inspect the private browsing preferences rather than -// the flags of nsIPrivateBrowsingService. The user may have turned on -// "Never remember history" in the same session, or Firefox was started -// with the -private command line argument. In both cases, the -// "autoStarted" flag of nsIPrivateBrowsingService will be wrong. -const PBPrefs = new Preferences("browser.privatebrowsing."); - +XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils", + "resource://gre/modules/PrivateBrowsingUtils.jsm"); this.TabSetRecord = function TabSetRecord(collection, id) { CryptoWrapper.call(this, collection, id); @@ -128,6 +123,9 @@ TabStore.prototype = { let currentState = JSON.parse(Svc.Session.getBrowserState()); let tabLastUsed = this.tabLastUsed; currentState.windows.forEach(function(window) { + if (window.isPrivate) { + return; + } window.tabs.forEach(function(tab) { // Make sure there are history entries to look at. if (!tab.entries.length) @@ -159,12 +157,6 @@ TabStore.prototype = { let record = new TabSetRecord(collection, id); record.clientName = this.engine.service.clientsEngine.localName; - // Don't provide any tabs to compare against and ignore the update later. - if (Svc.Private && Svc.Private.privateBrowsingEnabled && !PBPrefs.get("autostart")) { - record.tabs = []; - return record; - } - // Sort tabs in descending-used order to grab the most recently used let tabs = this.getAllTabs(true).sort(function(a, b) { return b.lastUsed - a.lastUsed; @@ -195,10 +187,26 @@ TabStore.prototype = { }, getAllIDs: function TabStore_getAllIds() { - // Don't report any tabs if we're in private browsing for first syncs. + // Don't report any tabs if all windows are in private browsing for + // first syncs. let ids = {}; - if (Svc.Private && Svc.Private.privateBrowsingEnabled && !PBPrefs.get("autostart")) + let allWindowsArePrivate = false; + let wins = Services.wm.getEnumerator("navigator:browser"); + while (wins.hasMoreElements()) { + if (PrivateBrowsingUtils.isWindowPrivate(wins.getNext())) { + // Ensure that at least there is a private window. + allWindowsArePrivate = true; + } else { + // If there is a not private windown then finish and continue. + allWindowsArePrivate = false; + break; + } + } + + if (allWindowsArePrivate && + !PrivateBrowsingUtils.permanentPrivateBrowsing) { return ids; + } ids[this.engine.service.clientsEngine.localID] = true; return ids; @@ -280,7 +288,9 @@ TabTracker.prototype = { switch (aTopic) { case "weave:engine:start-tracking": if (!this._enabled) { +#ifndef MOZ_PER_WINDOW_PRIVATE_BROWSING Svc.Obs.add("private-browsing", this); +#endif Svc.Obs.add("domwindowopened", this); let wins = Services.wm.getEnumerator("navigator:browser"); while (wins.hasMoreElements()) @@ -290,7 +300,9 @@ TabTracker.prototype = { break; case "weave:engine:stop-tracking": if (this._enabled) { +#ifndef MOZ_PER_WINDOW_PRIVATE_BROWSING Svc.Obs.remove("private-browsing", this); +#endif Svc.Obs.remove("domwindowopened", this); let wins = Services.wm.getEnumerator("navigator:browser"); while (wins.hasMoreElements()) @@ -307,16 +319,22 @@ TabTracker.prototype = { self._registerListenersForWindow(aSubject); }, false); break; +#ifndef MOZ_PER_WINDOW_PRIVATE_BROWSING case "private-browsing": - if (aData == "enter" && !PBPrefs.get("autostart")) + if (aData == "enter" && !PrivateBrowsingUtils.permanentPrivateBrowsing) this.modified = false; +#endif } }, onTab: function onTab(event) { - if (Svc.Private && Svc.Private.privateBrowsingEnabled && !PBPrefs.get("autostart")) { - this._log.trace("Ignoring tab event from private browsing."); - return; + if (event.originalTarget.linkedBrowser) { + let win = event.originalTarget.linkedBrowser.contentWindow; + if (PrivateBrowsingUtils.isWindowPrivate(win) && + !PrivateBrowsingUtils.permanentPrivateBrowsing) { + this._log.trace("Ignoring tab event from private browsing."); + return; + } } this._log.trace("onTab event: " + event.type); From 62cf9322bd63a79c23d7247c9fa7d74ca21df164 Mon Sep 17 00:00:00 2001 From: Andres Hernandez Date: Thu, 15 Nov 2012 18:33:31 -0600 Subject: [PATCH 06/57] Bug 811490 - Convert services/sync/tests/tps/test_privbrw_tabs.js to PB per window mode; r=ehsan,rnewman --- services/sync/tests/tps/test_privbrw_tabs.js | 4 +-- .../sync/tps/extensions/tps/modules/tps.jsm | 21 +++++++++++ .../tps/extensions/tps/modules/windows.jsm | 36 +++++++++++++++++++ 3 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 services/sync/tps/extensions/tps/modules/windows.jsm diff --git a/services/sync/tests/tps/test_privbrw_tabs.js b/services/sync/tests/tps/test_privbrw_tabs.js index d662131f2a43..e7c94e9db9a3 100644 --- a/services/sync/tests/tps/test_privbrw_tabs.js +++ b/services/sync/tests/tps/test_privbrw_tabs.js @@ -58,7 +58,6 @@ var tabs3 = [ } ]; - /* * Test phases */ @@ -77,7 +76,7 @@ Phase('phase2', [ Phase('phase3', [ [Sync], - [SetPrivateBrowsing, true], + [Windows.add, { private: true }], [Tabs.add, tabs3], [Sync] ]); @@ -86,4 +85,3 @@ Phase('phase4', [ [Sync], [Tabs.verifyNot, tabs3] ]); - diff --git a/services/sync/tps/extensions/tps/modules/tps.jsm b/services/sync/tps/extensions/tps/modules/tps.jsm index 3045eb17853a..f1122a397cb0 100644 --- a/services/sync/tps/extensions/tps/modules/tps.jsm +++ b/services/sync/tps/extensions/tps/modules/tps.jsm @@ -25,6 +25,7 @@ CU.import("resource://tps/history.jsm"); CU.import("resource://tps/forms.jsm"); CU.import("resource://tps/prefs.jsm"); CU.import("resource://tps/tabs.jsm"); +CU.import("resource://tps/windows.jsm"); var hh = CC["@mozilla.org/network/protocol;1?name=http"] .getService(CI.nsIHttpProtocolHandler); @@ -163,6 +164,20 @@ let TPS = { this.goQuitApplication(); }, + HandleWindows: function (aWindow, action) { + Logger.logInfo("executing action " + action.toUpperCase() + + " on window " + JSON.stringify(aWindow)); + switch(action) { + case ACTION_ADD: + BrowserWindows.Add(aWindow.private, function(win) { + Logger.logInfo("window finished loading"); + this.FinishAsyncOperation(); + }.bind(this)); + break; + } + Logger.logPass("executing action " + action.toUpperCase() + " on windows"); + }, + HandleTabs: function (tabs, action) { this._tabsAdded = tabs.length; this._tabsFinished = 0; @@ -927,3 +942,9 @@ var Tabs = { } }; +var Windows = { + add: function Window__add(aWindow) { + TPS.StartAsyncOperation(); + TPS.HandleWindows(aWindow, ACTION_ADD); + }, +}; diff --git a/services/sync/tps/extensions/tps/modules/windows.jsm b/services/sync/tps/extensions/tps/modules/windows.jsm new file mode 100644 index 000000000000..62cc80d2cd45 --- /dev/null +++ b/services/sync/tps/extensions/tps/modules/windows.jsm @@ -0,0 +1,36 @@ +/* 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 is a JavaScript module (JSM) to be imported via + Components.utils.import() and acts as a singleton. + Only the following listed symbols will exposed on import, and only when + and where imported. */ + +const EXPORTED_SYMBOLS = ["BrowserWindows"]; + +const {classes: Cc, interfaces: Ci, utils: Cu} = Components; + +Cu.import("resource://services-sync/main.js"); + +let BrowserWindows = { + /** + * Add + * + * Opens a new window. Throws on error. + * + * @param aPrivate The private option. + * @return nothing + */ + Add: function(aPrivate, fn) { + let wm = Cc["@mozilla.org/appshell/window-mediator;1"] + .getService(Ci.nsIWindowMediator); + let mainWindow = wm.getMostRecentWindow("navigator:browser"); + let win = mainWindow.OpenBrowserWindow({private: aPrivate}); + win.addEventListener("load", function onLoad() { + win.removeEventListener("load", onLoad, false); + fn.call(win); + }, false); + } +}; From bc1b45a752dda2fecef524a4c0e4f16be8b694b8 Mon Sep 17 00:00:00 2001 From: Andrew Halberstadt Date: Mon, 19 Nov 2012 15:52:40 -0500 Subject: [PATCH 07/57] Bug 812514 - Make b2g emulator unittests save logcat for easier debugging, r=jgriffin --- layout/tools/reftest/runreftestb2g.py | 13 +++++++++++-- .../marionette/client/marionette/emulator.py | 18 +++--------------- testing/marionette/client/setup.py | 2 +- testing/mochitest/runtestsb2g.py | 10 +++++++++- 4 files changed, 24 insertions(+), 19 deletions(-) diff --git a/layout/tools/reftest/runreftestb2g.py b/layout/tools/reftest/runreftestb2g.py index 126aaf0b263f..d0d5c4a60bae 100644 --- a/layout/tools/reftest/runreftestb2g.py +++ b/layout/tools/reftest/runreftestb2g.py @@ -105,6 +105,10 @@ class B2GOptions(ReftestOptions): help="the path to a gecko distribution that should " "be installed on the emulator prior to test") defaults["geckoPath"] = None + self.add_option("--logcat-dir", action="store", + type="string", dest="logcat_dir", + help="directory to store logcat dump files") + defaults["logcat_dir"] = None defaults["remoteTestRoot"] = None defaults["logFile"] = "reftest.log" defaults["autorun"] = True @@ -133,6 +137,9 @@ class B2GOptions(ReftestOptions): if options.geckoPath and not options.emulator: self.error("You must specify --emulator if you specify --gecko-path") + if options.logcat_dir and not options.emulator: + self.error("You must specify --emulator if you specify --logcat-dir") + #if not options.emulator and not options.deviceIP: # print "ERROR: you must provide a device IP" # return None @@ -470,6 +477,10 @@ def main(args=sys.argv[1:]): auto.setEmulator(True) if options.noWindow: kwargs['noWindow'] = True + if options.geckoPath: + kwargs['gecko_path'] = options.geckoPath + if options.logcat_dir: + kwargs['logcat_dir'] = options.logcat_dir if options.emulator_res: kwargs['emulator_res'] = options.emulator_res if options.b2gPath: @@ -478,8 +489,6 @@ def main(args=sys.argv[1:]): host,port = options.marionette.split(':') kwargs['host'] = host kwargs['port'] = int(port) - if options.geckoPath: - kwargs['gecko_path'] = options.geckoPath marionette = Marionette.getMarionetteOrExit(**kwargs) auto.marionette = marionette diff --git a/testing/marionette/client/marionette/emulator.py b/testing/marionette/client/marionette/emulator.py index fa6b738e26ec..05ada4fac587 100644 --- a/testing/marionette/client/marionette/emulator.py +++ b/testing/marionette/client/marionette/emulator.py @@ -6,7 +6,6 @@ import datetime from errors import * from mozdevice import devicemanagerADB, DMError from mozprocess import ProcessHandlerMixin -import multiprocessing import os import re import platform @@ -252,7 +251,7 @@ class Emulator(object): os.remove(self._tmp_sdcard) self._tmp_sdcard = None return retcode - if self.logcat_proc: + if self.logcat_proc and self.logcat_proc.proc.poll() is None: self.logcat_proc.kill() return 0 @@ -370,13 +369,6 @@ waitFor( # setup DNS fix for networking self._run_adb(['shell', 'setprop', 'net.dns1', '10.0.2.3']) - def _save_logcat_proc(self, filename, cmd): - self.logcat_proc = LogcatProc(filename, cmd) - self.logcat_proc.run() - self.logcat_proc.processOutput() - self.logcat_proc.waitForFinish() - self.logcat_proc = None - def install_gecko(self, gecko_path, marionette): """ Install gecko into the emulator using adb push. Restart b2g after the @@ -447,12 +439,8 @@ waitFor( self.rotate_log(filename) cmd = [self.adb, '-s', 'emulator-%d' % self.port, 'logcat'] - # We do this in a separate process because we call mozprocess's - # waitForFinish method to process logcat's output, and this method - # blocks. - proc = multiprocessing.Process(target=self._save_logcat_proc, args=(filename, cmd)) - proc.daemon = True - proc.start() + self.logcat_proc = LogcatProc(filename, cmd) + self.logcat_proc.run() def setup_port_forwarding(self, remote_port): """ Set up TCP port forwarding to the specified port on the device, diff --git a/testing/marionette/client/setup.py b/testing/marionette/client/setup.py index b97a238f70e8..80abf473ac02 100644 --- a/testing/marionette/client/setup.py +++ b/testing/marionette/client/setup.py @@ -12,7 +12,7 @@ except (OSError, IOError): # dependencies deps = ['manifestdestiny', 'mozhttpd >= 0.3', - 'mozprocess >= 0.5', 'mozrunner >= 5.10', + 'mozprocess >= 0.6', 'mozrunner >= 5.11', 'mozdevice >= 0.12'] setup(name='marionette_client', diff --git a/testing/mochitest/runtestsb2g.py b/testing/mochitest/runtestsb2g.py index 6a19d340ffec..fb5861dcf896 100644 --- a/testing/mochitest/runtestsb2g.py +++ b/testing/mochitest/runtestsb2g.py @@ -98,6 +98,10 @@ class B2GOptions(MochitestOptions): help="the path to a gecko distribution that should " "be installed on the emulator prior to test") defaults["geckoPath"] = None + self.add_option("--logcat-dir", action="store", + type="string", dest="logcat_dir", + help="directory to store logcat dump files") + defaults["logcat_dir"] = None defaults["remoteTestRoot"] = None defaults["logFile"] = "mochitest.log" @@ -120,11 +124,13 @@ class B2GOptions(MochitestOptions): options.remoteWebServer = automation.getLanIp() else: self.error("You must specify a --remote-webserver=") + options.webServer = options.remoteWebServer if options.geckoPath and not options.emulator: self.error("You must specify --emulator if you specify --gecko-path") - options.webServer = options.remoteWebServer + if options.logcat_dir and not options.emulator: + self.error("You must specify --emulator if you specify --logcat-dir") #if not options.emulator and not options.deviceIP: # print "ERROR: you must provide a device IP" @@ -473,6 +479,8 @@ def main(): kwargs['noWindow'] = True if options.geckoPath: kwargs['gecko_path'] = options.geckoPath + if options.logcat_dir: + kwargs['logcat_dir'] = options.logcat_dir # needless to say sdcard is only valid if using an emulator if options.sdcard: kwargs['sdcard'] = options.sdcard From 8c273151299cd5892409219dcd5484b174d807c9 Mon Sep 17 00:00:00 2001 From: Sriram Ramasubramanian Date: Tue, 6 Nov 2012 11:24:14 -0800 Subject: [PATCH 08/57] Bug 786982: Add the hiding of close tab, while swiping. r=lucasr --- mobile/android/base/TabsTray.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/mobile/android/base/TabsTray.java b/mobile/android/base/TabsTray.java index c8e7175dc61e..6ddf5bc5416f 100644 --- a/mobile/android/base/TabsTray.java +++ b/mobile/android/base/TabsTray.java @@ -324,6 +324,15 @@ public class TabsTray extends LinearLayout PropertyAnimator animator = new PropertyAnimator(ANIMATION_DURATION); animator.attach(view, Property.ALPHA, 1); animator.attach(view, Property.TRANSLATION_X, 0); + + animator.setPropertyAnimationListener(new PropertyAnimator.PropertyAnimationListener() { + public void onPropertyAnimationStart() { } + public void onPropertyAnimationEnd() { + TabRow tab = (TabRow) view.getTag(); + tab.close.setVisibility(View.VISIBLE); + } + }); + animator.start(); } @@ -472,6 +481,7 @@ public class TabsTray extends LinearLayout mListView.requestDisallowInterceptTouchEvent(true); TabRow tab = (TabRow) mSwipeView.getTag(); + tab.close.setVisibility(View.INVISIBLE); // Stops listview from highlighting the touched item // in the list when swiping. From f02e6c23c91ae4368e802e4e516ae4e706f4f1eb Mon Sep 17 00:00:00 2001 From: Jeff Walden Date: Wed, 14 Nov 2012 16:59:30 -0800 Subject: [PATCH 09/57] Bug 812218 - Move user-supplied CFLAGS/CXXFLAGS to the end of commandline, so that they can't interfere with the setting of defaults. r=khuey --HG-- extra : rebase_source : e74249194de8b5060ccf429719b9b082d2e6b9c7 --- config/config.mk | 4 ++-- js/src/config/config.mk | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/config.mk b/config/config.mk index 9b897d5087ce..e3beadd0b60b 100644 --- a/config/config.mk +++ b/config/config.mk @@ -498,8 +498,8 @@ OS_COMPILE_CMMFLAGS += -fobjc-abi-version=2 -fobjc-legacy-dispatch endif endif -COMPILE_CFLAGS = $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(CFLAGS) $(RTL_FLAGS) $(OS_CPPFLAGS) $(OS_COMPILE_CFLAGS) -COMPILE_CXXFLAGS = $(STL_FLAGS) $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(CXXFLAGS) $(RTL_FLAGS) $(OS_CPPFLAGS) $(OS_COMPILE_CXXFLAGS) +COMPILE_CFLAGS = $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_CPPFLAGS) $(OS_COMPILE_CFLAGS) $(CFLAGS) +COMPILE_CXXFLAGS = $(STL_FLAGS) $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_CPPFLAGS) $(OS_COMPILE_CXXFLAGS) $(CXXFLAGS) COMPILE_CMFLAGS = $(OS_COMPILE_CMFLAGS) COMPILE_CMMFLAGS = $(OS_COMPILE_CMMFLAGS) diff --git a/js/src/config/config.mk b/js/src/config/config.mk index 9b897d5087ce..e3beadd0b60b 100644 --- a/js/src/config/config.mk +++ b/js/src/config/config.mk @@ -498,8 +498,8 @@ OS_COMPILE_CMMFLAGS += -fobjc-abi-version=2 -fobjc-legacy-dispatch endif endif -COMPILE_CFLAGS = $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(CFLAGS) $(RTL_FLAGS) $(OS_CPPFLAGS) $(OS_COMPILE_CFLAGS) -COMPILE_CXXFLAGS = $(STL_FLAGS) $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(CXXFLAGS) $(RTL_FLAGS) $(OS_CPPFLAGS) $(OS_COMPILE_CXXFLAGS) +COMPILE_CFLAGS = $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_CPPFLAGS) $(OS_COMPILE_CFLAGS) $(CFLAGS) +COMPILE_CXXFLAGS = $(STL_FLAGS) $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_CPPFLAGS) $(OS_COMPILE_CXXFLAGS) $(CXXFLAGS) COMPILE_CMFLAGS = $(OS_COMPILE_CMFLAGS) COMPILE_CMMFLAGS = $(OS_COMPILE_CMMFLAGS) From 8980d5151e0561cf473e83290f6e93c59c24a265 Mon Sep 17 00:00:00 2001 From: Ethan Hugg Date: Mon, 19 Nov 2012 09:59:36 -0800 Subject: [PATCH 10/57] Bug 813212 Update signaling unittests to match latest IDL r=jesup --- media/webrtc/signaling/test/signaling_unittests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/webrtc/signaling/test/signaling_unittests.cpp b/media/webrtc/signaling/test/signaling_unittests.cpp index e16c2f93ac7f..0105c0c316fb 100644 --- a/media/webrtc/signaling/test/signaling_unittests.cpp +++ b/media/webrtc/signaling/test/signaling_unittests.cpp @@ -506,7 +506,7 @@ class SignalingAgent { void Close() { cout << "Close" << endl; - pc->Close(); + pc->Close(false); // Shutdown is synchronous evidently. // ASSERT_TRUE(pObserver->WaitForObserverCall()); // ASSERT_EQ(pc->sipcc_state(), sipcc::PeerConnectionInterface::kIdle); From 50dab9a21f2f9e8a38b64fb46aff60983e935f60 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Mon, 19 Nov 2012 15:52:29 -0500 Subject: [PATCH 11/57] Bug 813269 - Use double to represent time in Web Audio; r=bzbarsky --- content/media/webaudio/AudioBuffer.h | 4 +- content/media/webaudio/AudioContext.cpp | 4 +- content/media/webaudio/AudioContext.h | 2 +- content/media/webaudio/AudioEventTimeline.h | 34 +++---- content/media/webaudio/AudioParam.cpp | 2 +- content/media/webaudio/AudioParam.h | 2 +- content/media/webaudio/DelayNode.cpp | 2 +- content/media/webaudio/DelayNode.h | 2 +- .../compiledtest/TestAudioEventTimeline.cpp | 90 +++++++++---------- dom/webidl/AudioBuffer.webidl | 2 +- dom/webidl/AudioContext.webidl | 4 +- dom/webidl/AudioParam.webidl | 12 +-- 12 files changed, 80 insertions(+), 80 deletions(-) diff --git a/content/media/webaudio/AudioBuffer.h b/content/media/webaudio/AudioBuffer.h index ab49e455554e..ae08c2233e5d 100644 --- a/content/media/webaudio/AudioBuffer.h +++ b/content/media/webaudio/AudioBuffer.h @@ -59,9 +59,9 @@ public: return mLength; } - float Duration() const + double Duration() const { - return mLength / mSampleRate; + return mLength / static_cast (mSampleRate); } uint32_t NumberOfChannels() const diff --git a/content/media/webaudio/AudioContext.cpp b/content/media/webaudio/AudioContext.cpp index 4564ba59cfba..0446450d12cb 100644 --- a/content/media/webaudio/AudioContext.cpp +++ b/content/media/webaudio/AudioContext.cpp @@ -104,9 +104,9 @@ AudioContext::CreateGain() } already_AddRefed -AudioContext::CreateDelay(float aMaxDelayTime, ErrorResult& aRv) +AudioContext::CreateDelay(double aMaxDelayTime, ErrorResult& aRv) { - if (aMaxDelayTime > 0.f && aMaxDelayTime < 3.f) { + if (aMaxDelayTime > 0. && aMaxDelayTime < 3.) { nsRefPtr delayNode = new DelayNode(this, aMaxDelayTime); return delayNode.forget(); } diff --git a/content/media/webaudio/AudioContext.h b/content/media/webaudio/AudioContext.h index 4c8fbd5ff990..293d99f4798b 100644 --- a/content/media/webaudio/AudioContext.h +++ b/content/media/webaudio/AudioContext.h @@ -73,7 +73,7 @@ public: CreateGain(); already_AddRefed - CreateDelay(float aMaxDelayTime, ErrorResult& aRv); + CreateDelay(double aMaxDelayTime, ErrorResult& aRv); already_AddRefed CreatePanner(); diff --git a/content/media/webaudio/AudioEventTimeline.h b/content/media/webaudio/AudioEventTimeline.h index 81867abb4120..2bda0235d827 100644 --- a/content/media/webaudio/AudioEventTimeline.h +++ b/content/media/webaudio/AudioEventTimeline.h @@ -41,11 +41,11 @@ private: SetValueCurve }; - Event(Type aType, float aTime, float aValue, float aTimeConstant = 0.0, + Event(Type aType, double aTime, float aValue, double aTimeConstant = 0.0, float aDuration = 0.0, FloatArrayWrapper aCurve = FloatArrayWrapper()) : mType(aType) - , mTime(aTime) , mValue(aValue) + , mTime(aTime) , mTimeConstant(aTimeConstant) , mDuration(aDuration) { @@ -63,10 +63,10 @@ private: } Type mType; - float mTime; float mValue; - float mTimeConstant; - float mDuration; + double mTime; + double mTimeConstant; + double mDuration; FloatArrayWrapper mCurve; private: @@ -125,33 +125,33 @@ public: return mDefaultValue; } - void SetValueAtTime(float aValue, float aStartTime, ErrorResult& aRv) + void SetValueAtTime(float aValue, double aStartTime, ErrorResult& aRv) { InsertEvent(Event(Event::SetValue, aStartTime, aValue), aRv); } - void LinearRampToValueAtTime(float aValue, float aEndTime, ErrorResult& aRv) + void LinearRampToValueAtTime(float aValue, double aEndTime, ErrorResult& aRv) { InsertEvent(Event(Event::LinearRamp, aEndTime, aValue), aRv); } - void ExponentialRampToValueAtTime(float aValue, float aEndTime, ErrorResult& aRv) + void ExponentialRampToValueAtTime(float aValue, double aEndTime, ErrorResult& aRv) { InsertEvent(Event(Event::ExponentialRamp, aEndTime, aValue), aRv); } - void SetTargetAtTime(float aTarget, float aStartTime, float aTimeConstant, ErrorResult& aRv) + void SetTargetAtTime(float aTarget, double aStartTime, double aTimeConstant, ErrorResult& aRv) { InsertEvent(Event(Event::SetTarget, aStartTime, aTarget, aTimeConstant), aRv); } - void SetValueCurveAtTime(const FloatArrayWrapper& aValues, float aStartTime, float aDuration, ErrorResult& aRv) + void SetValueCurveAtTime(const FloatArrayWrapper& aValues, double aStartTime, double aDuration, ErrorResult& aRv) { // TODO: implement // InsertEvent(Event(Event::SetValueCurve, aStartTime, 0.0f, 0.0f, aDuration, aValues), aRv); } - void CancelScheduledValues(float aStartTime) + void CancelScheduledValues(double aStartTime) { for (unsigned i = 0; i < mEvents.Length(); ++i) { if (mEvents[i].mTime >= aStartTime) { @@ -169,7 +169,7 @@ public: } // This method computes the AudioParam value at a given time based on the event timeline - float GetValueAtTime(float aTime) const + float GetValueAtTime(double aTime) const { const Event* previous = nullptr; const Event* next = nullptr; @@ -222,10 +222,10 @@ public: return mValue; case Event::LinearRamp: // Use t=0 as T0 and v=defaultValue as V0 - return LinearInterpolate(0.0f, mValue, next->mTime, next->mValue, aTime); + return LinearInterpolate(0.0, mValue, next->mTime, next->mValue, aTime); case Event::ExponentialRamp: // Use t=0 as T0 and v=defaultValue as V0 - return ExponentialInterpolate(0.0f, mValue, next->mTime, next->mValue, aTime); + return ExponentialInterpolate(0.0, mValue, next->mTime, next->mValue, aTime); case Event::SetValueCurve: // TODO: implement return 0.0f; @@ -296,17 +296,17 @@ public: return mEvents.Length(); } - static float LinearInterpolate(float t0, float v0, float t1, float v1, float t) + static float LinearInterpolate(double t0, float v0, double t1, float v1, double t) { return v0 + (v1 - v0) * ((t - t0) / (t1 - t0)); } - static float ExponentialInterpolate(float t0, float v0, float t1, float v1, float t) + static float ExponentialInterpolate(double t0, float v0, double t1, float v1, double t) { return v0 * powf(v1 / v0, (t - t0) / (t1 - t0)); } - static float ExponentialApproach(float t0, float v0, float v1, float timeConstant, float t) + static float ExponentialApproach(double t0, double v0, float v1, double timeConstant, double t) { return v1 + (v0 - v1) * expf(-(t - t0) / timeConstant); } diff --git a/content/media/webaudio/AudioParam.cpp b/content/media/webaudio/AudioParam.cpp index 6653f0af7752..3e8e59baca28 100644 --- a/content/media/webaudio/AudioParam.cpp +++ b/content/media/webaudio/AudioParam.cpp @@ -44,7 +44,7 @@ AudioParam::~AudioParam() JSObject* AudioParam::WrapObject(JSContext* aCx, JSObject* aScope, - bool* aTriedToWrap) + bool* aTriedToWrap) { return AudioParamBinding::Wrap(aCx, aScope, this, aTriedToWrap); } diff --git a/content/media/webaudio/AudioParam.h b/content/media/webaudio/AudioParam.h index 2d89b63941b8..adaf147d1b74 100644 --- a/content/media/webaudio/AudioParam.h +++ b/content/media/webaudio/AudioParam.h @@ -102,7 +102,7 @@ public: // We override SetValueCurveAtTime to convert the Float32Array to the wrapper // object. - void SetValueCurveAtTime(JSContext* cx, const Float32Array& aValues, float aStartTime, float aDuration, ErrorResult& aRv) + void SetValueCurveAtTime(JSContext* cx, const Float32Array& aValues, double aStartTime, double aDuration, ErrorResult& aRv) { AudioParamTimeline::SetValueCurveAtTime(detail::FloatArrayWrapper(aValues), aStartTime, aDuration, aRv); diff --git a/content/media/webaudio/DelayNode.cpp b/content/media/webaudio/DelayNode.cpp index 787058397c92..293b26420f43 100644 --- a/content/media/webaudio/DelayNode.cpp +++ b/content/media/webaudio/DelayNode.cpp @@ -24,7 +24,7 @@ NS_INTERFACE_MAP_END_INHERITING(AudioNode) NS_IMPL_ADDREF_INHERITED(DelayNode, AudioNode) NS_IMPL_RELEASE_INHERITED(DelayNode, AudioNode) -DelayNode::DelayNode(AudioContext* aContext, float aMaxDelay) +DelayNode::DelayNode(AudioContext* aContext, double aMaxDelay) : AudioNode(aContext) , mDelay(new AudioParam(aContext, 0.0f, 0.0f, aMaxDelay)) { diff --git a/content/media/webaudio/DelayNode.h b/content/media/webaudio/DelayNode.h index 2bc4d90610c7..8435979a020a 100644 --- a/content/media/webaudio/DelayNode.h +++ b/content/media/webaudio/DelayNode.h @@ -18,7 +18,7 @@ class AudioContext; class DelayNode : public AudioNode { public: - DelayNode(AudioContext* aContext, float aMaxDelay); + DelayNode(AudioContext* aContext, double aMaxDelay); NS_DECL_ISUPPORTS_INHERITED NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DelayNode, AudioNode) diff --git a/content/media/webaudio/compiledtest/TestAudioEventTimeline.cpp b/content/media/webaudio/compiledtest/TestAudioEventTimeline.cpp index 697a636d76ed..03ccddd874f8 100644 --- a/content/media/webaudio/compiledtest/TestAudioEventTimeline.cpp +++ b/content/media/webaudio/compiledtest/TestAudioEventTimeline.cpp @@ -105,14 +105,14 @@ void TestSpecExample() ErrorResultMock rv; // This test is copied from the example in the Web Audio spec - const float t0 = 0.0f, - t1 = 0.1f, - t2 = 0.2f, - t3 = 0.3f, - t4 = 0.4f, - t5 = 0.6f, - t6 = 0.7f/*, - t7 = 1.0f*/; + const float t0 = 0.0, + t1 = 0.1, + t2 = 0.2, + t3 = 0.3, + t4 = 0.4, + t5 = 0.6, + t6 = 0.7/*, + t7 = 1.0*/; timeline.SetValueAtTime(0.2f, t0, rv); is(rv, NS_OK, "SetValueAtTime succeeded"); timeline.SetValueAtTime(0.3f, t1, rv); @@ -156,35 +156,35 @@ void TestInvalidEvents() ErrorResultMock rv; - timeline.SetValueAtTime(NaN, 0.1f, rv); + timeline.SetValueAtTime(NaN, 0.1, rv); is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned"); - timeline.SetValueAtTime(Infinity, 0.1f, rv); + timeline.SetValueAtTime(Infinity, 0.1, rv); is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned"); - timeline.SetValueAtTime(-Infinity, 0.1f, rv); + timeline.SetValueAtTime(-Infinity, 0.1, rv); is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned"); - timeline.LinearRampToValueAtTime(NaN, 0.2f, rv); + timeline.LinearRampToValueAtTime(NaN, 0.2, rv); is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned"); - timeline.LinearRampToValueAtTime(Infinity, 0.2f, rv); + timeline.LinearRampToValueAtTime(Infinity, 0.2, rv); is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned"); - timeline.LinearRampToValueAtTime(-Infinity, 0.2f, rv); + timeline.LinearRampToValueAtTime(-Infinity, 0.2, rv); is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned"); - timeline.ExponentialRampToValueAtTime(NaN, 0.3f, rv); + timeline.ExponentialRampToValueAtTime(NaN, 0.3, rv); is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned"); - timeline.ExponentialRampToValueAtTime(Infinity, 0.3f, rv); + timeline.ExponentialRampToValueAtTime(Infinity, 0.3, rv); is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned"); - timeline.ExponentialRampToValueAtTime(-Infinity, 0.4f, rv); + timeline.ExponentialRampToValueAtTime(-Infinity, 0.4, rv); is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned"); - timeline.SetTargetAtTime(NaN, 0.4f, 1.0f, rv); + timeline.SetTargetAtTime(NaN, 0.4, 1.0, rv); is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned"); - timeline.SetTargetAtTime(Infinity, 0.4f, 1.0f, rv); + timeline.SetTargetAtTime(Infinity, 0.4, 1.0, rv); is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned"); - timeline.SetTargetAtTime(-Infinity, 0.4f, 1.0f, rv); + timeline.SetTargetAtTime(-Infinity, 0.4, 1.0, rv); is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned"); - timeline.SetTargetAtTime(0.4f, NaN, 1.0f, rv); + timeline.SetTargetAtTime(0.4f, NaN, 1.0, rv); is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned"); - timeline.SetTargetAtTime(0.4f, Infinity, 1.0f, rv); + timeline.SetTargetAtTime(0.4f, Infinity, 1.0, rv); is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned"); - timeline.SetTargetAtTime(0.4f, -Infinity, 1.0f, rv); + timeline.SetTargetAtTime(0.4f, -Infinity, 1.0, rv); is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned"); // TODO: Test SetValueCurveAtTime } @@ -196,13 +196,13 @@ void TestEventReplacement() ErrorResultMock rv; is(timeline.GetEventCount(), 0, "No events yet"); - timeline.SetValueAtTime(10.0f, 0.1f, rv); + timeline.SetValueAtTime(10.0f, 0.1, rv); is(timeline.GetEventCount(), 1, "One event scheduled now"); - timeline.SetValueAtTime(20.0f, 0.1f, rv); + timeline.SetValueAtTime(20.0f, 0.1, rv); is(rv, NS_OK, "Event scheduling should be successful"); is(timeline.GetEventCount(), 1, "Event should be replaced"); is(timeline.GetValueAtTime(0.1f), 20.0f, "The first event should be overwritten"); - timeline.LinearRampToValueAtTime(30.0f, 0.1f, rv); + timeline.LinearRampToValueAtTime(30.0f, 0.1, rv); is(rv, NS_OK, "Event scheduling should be successful"); is(timeline.GetEventCount(), 2, "Different event type should be appended"); is(timeline.GetValueAtTime(0.1f), 30.0f, "The first event should be overwritten"); @@ -214,16 +214,16 @@ void TestEventRemoval() ErrorResultMock rv; - timeline.SetValueAtTime(10.0f, 0.1f, rv); - timeline.SetValueAtTime(15.0f, 0.15f, rv); - timeline.SetValueAtTime(20.0f, 0.2f, rv); - timeline.LinearRampToValueAtTime(30.0f, 0.3f, rv); + timeline.SetValueAtTime(10.0f, 0.1, rv); + timeline.SetValueAtTime(15.0f, 0.15, rv); + timeline.SetValueAtTime(20.0f, 0.2, rv); + timeline.LinearRampToValueAtTime(30.0f, 0.3, rv); is(timeline.GetEventCount(), 4, "Should have three events initially"); - timeline.CancelScheduledValues(0.4f); + timeline.CancelScheduledValues(0.4); is(timeline.GetEventCount(), 4, "Trying to delete past the end of the array should have no effect"); - timeline.CancelScheduledValues(0.3f); + timeline.CancelScheduledValues(0.3); is(timeline.GetEventCount(), 3, "Should successfully delete one event"); - timeline.CancelScheduledValues(0.12f); + timeline.CancelScheduledValues(0.12); is(timeline.GetEventCount(), 1, "Should successfully delete two events"); } @@ -233,7 +233,7 @@ void TestBeforeFirstEvent() ErrorResultMock rv; - timeline.SetValueAtTime(20.0f, 1.0f, rv); + timeline.SetValueAtTime(20.0f, 1.0, rv); is(timeline.GetValueAtTime(0.5f), 10.0f, "Retrun the default value before the first event"); } @@ -243,7 +243,7 @@ void TestAfterLastValueEvent() ErrorResultMock rv; - timeline.SetValueAtTime(20.0f, 1.0f, rv); + timeline.SetValueAtTime(20.0f, 1.0, rv); is(timeline.GetValueAtTime(1.5f), 20.0f, "Return the last value after the last SetValue event"); } @@ -253,7 +253,7 @@ void TestAfterLastTargetValueEvent() ErrorResultMock rv; - timeline.SetTargetAtTime(20.0f, 1.0f, 5.0f, rv); + timeline.SetTargetAtTime(20.0f, 1.0, 5.0, rv); is(timeline.GetValueAtTime(10.f), (20.f + (10.f - 20.f) * expf(-9.0f / 5.0f)), "Return the value after the last SetTarget event based on the curve"); } @@ -264,7 +264,7 @@ void TestAfterLastTargetValueEventWithValueSet() ErrorResultMock rv; timeline.SetValue(50.f); - timeline.SetTargetAtTime(20.0f, 1.0f, 5.0f, rv); + timeline.SetTargetAtTime(20.0f, 1.0, 5.0, rv); is(timeline.GetValueAtTime(10.f), (20.f + (50.f - 20.f) * expf(-9.0f / 5.0f)), "Return the value after SetValue and the last SetTarget event based on the curve"); } @@ -277,7 +277,7 @@ void TestValue() is(timeline.Value(), 10.0f, "value should initially match the default value"); timeline.SetValue(20.0f); is(timeline.Value(), 20.0f, "Should be able to set the value"); - timeline.SetValueAtTime(20.0f, 1.0f, rv); + timeline.SetValueAtTime(20.0f, 1.0, rv); // TODO: The following check needs to change when we compute the value based on the current time of the context is(timeline.Value(), 20.0f, "TODO..."); timeline.SetValue(30.0f); @@ -290,7 +290,7 @@ void TestLinearRampAtZero() ErrorResultMock rv; - timeline.LinearRampToValueAtTime(20.0f, 0.0f, rv); + timeline.LinearRampToValueAtTime(20.0f, 0.0, rv); is(timeline.GetValueAtTime(0.0f), 20.0f, "Should get the correct value when t0 == t1 == 0"); } @@ -300,7 +300,7 @@ void TestExponentialRampAtZero() ErrorResultMock rv; - timeline.ExponentialRampToValueAtTime(20.0f, 0.0f, rv); + timeline.ExponentialRampToValueAtTime(20.0f, 0.0, rv); is(timeline.GetValueAtTime(0.0f), 20.0f, "Should get the correct value when t0 == t1 == 0"); } @@ -310,8 +310,8 @@ void TestLinearRampAtSameTime() ErrorResultMock rv; - timeline.SetValueAtTime(5.0f, 1.0f, rv); - timeline.LinearRampToValueAtTime(20.0f, 1.0f, rv); + timeline.SetValueAtTime(5.0f, 1.0, rv); + timeline.LinearRampToValueAtTime(20.0f, 1.0, rv); is(timeline.GetValueAtTime(1.0f), 20.0f, "Should get the correct value when t0 == t1"); } @@ -321,8 +321,8 @@ void TestExponentialRampAtSameTime() ErrorResultMock rv; - timeline.SetValueAtTime(5.0f, 1.0f, rv); - timeline.ExponentialRampToValueAtTime(20.0f, 1.0f, rv); + timeline.SetValueAtTime(5.0f, 1.0, rv); + timeline.ExponentialRampToValueAtTime(20.0f, 1.0, rv); is(timeline.GetValueAtTime(1.0f), 20.0f, "Should get the correct value when t0 == t1"); } @@ -332,7 +332,7 @@ void TestSetTargetZeroTimeConstant() ErrorResultMock rv; - timeline.SetTargetAtTime(20.0f, 1.0f, 0.0f, rv); + timeline.SetTargetAtTime(20.0f, 1.0, 0.0, rv); is(timeline.GetValueAtTime(10.f), 20.f, "Should get the correct value with timeConstant == 0"); } diff --git a/dom/webidl/AudioBuffer.webidl b/dom/webidl/AudioBuffer.webidl index 056beefee941..6e38b8822769 100644 --- a/dom/webidl/AudioBuffer.webidl +++ b/dom/webidl/AudioBuffer.webidl @@ -17,7 +17,7 @@ interface AudioBuffer { readonly attribute long length; // in seconds - readonly attribute float duration; + readonly attribute double duration; readonly attribute long numberOfChannels; diff --git a/dom/webidl/AudioContext.webidl b/dom/webidl/AudioContext.webidl index 434a6251af7f..21a4f1d831fa 100644 --- a/dom/webidl/AudioContext.webidl +++ b/dom/webidl/AudioContext.webidl @@ -28,10 +28,10 @@ interface mozAudioContext { [Creator] GainNode createGain(); - // maxDelayTime should ideally be a restricted float to protect against + // maxDelayTime should ideally be a restricted double to protect against // things such as NaNs. [Creator, Throws] - DelayNode createDelay(optional float maxDelayTime = 1); + DelayNode createDelay(optional double maxDelayTime = 1); [Creator] BiquadFilterNode createBiquadFilter(); [Creator] diff --git a/dom/webidl/AudioParam.webidl b/dom/webidl/AudioParam.webidl index fc99adb8987e..f3094485ce1f 100644 --- a/dom/webidl/AudioParam.webidl +++ b/dom/webidl/AudioParam.webidl @@ -21,23 +21,23 @@ interface AudioParam { // Parameter automation. [Throws] - void setValueAtTime(float value, float startTime); + void setValueAtTime(float value, double startTime); [Throws] - void linearRampToValueAtTime(float value, float endTime); + void linearRampToValueAtTime(float value, double endTime); [Throws] - void exponentialRampToValueAtTime(float value, float endTime); + void exponentialRampToValueAtTime(float value, double endTime); // Exponentially approach the target value with a rate having the given time constant. [Throws] - void setTargetAtTime(float target, float startTime, float timeConstant); + void setTargetAtTime(float target, double startTime, double timeConstant); // Sets an array of arbitrary parameter values starting at time for the given duration. // The number of values will be scaled to fit into the desired duration. // [Throws] - // void setValueCurveAtTime(Float32Array values, float startTime, float duration); + // void setValueCurveAtTime(Float32Array values, double startTime, double duration); // Cancels all scheduled parameter changes with times greater than or equal to startTime. - void cancelScheduledValues(float startTime); + void cancelScheduledValues(double startTime); }; From 06bad6e03098fcef04990426d8b5d181c0c4ae5c Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Fri, 16 Nov 2012 17:37:46 -0800 Subject: [PATCH 12/57] Bug 813210 - Make the threading related assertions in the media decoder fatal; r=cpearce --- content/media/MediaDecoder.cpp | 122 ++++++++++++++++----------------- 1 file changed, 58 insertions(+), 64 deletions(-) diff --git a/content/media/MediaDecoder.cpp b/content/media/MediaDecoder.cpp index 6bf0348a4bf2..9dfe9661e041 100644 --- a/content/media/MediaDecoder.cpp +++ b/content/media/MediaDecoder.cpp @@ -107,7 +107,7 @@ NS_IMPL_THREADSAFE_ISUPPORTS1(MediaDecoder, nsIObserver) void MediaDecoder::Pause() { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); if (mPlayState == PLAY_STATE_SEEKING || mPlayState == PLAY_STATE_ENDED) { mNextState = PLAY_STATE_PAUSED; @@ -119,7 +119,7 @@ void MediaDecoder::Pause() void MediaDecoder::SetVolume(double aVolume) { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); mInitialVolume = aVolume; if (mDecoderStateMachine) { mDecoderStateMachine->SetVolume(aVolume); @@ -128,7 +128,7 @@ void MediaDecoder::SetVolume(double aVolume) void MediaDecoder::SetAudioCaptured(bool aCaptured) { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); mInitialAudioCaptured = aCaptured; if (mDecoderStateMachine) { mDecoderStateMachine->SetAudioCaptured(aCaptured); @@ -175,7 +175,7 @@ MediaDecoder::DecodedStreamData::~DecodedStreamData() void MediaDecoder::DestroyDecodedStream() { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); GetReentrantMonitor().AssertCurrentThreadIn(); // All streams are having their SourceMediaStream disconnected, so they @@ -199,7 +199,7 @@ void MediaDecoder::DestroyDecodedStream() void MediaDecoder::RecreateDecodedStream(int64_t aStartTimeUSecs) { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); GetReentrantMonitor().AssertCurrentThreadIn(); LOG(PR_LOG_DEBUG, ("MediaDecoder::RecreateDecodedStream this=%p aStartTimeUSecs=%lld!", this, (long long)aStartTimeUSecs)); @@ -238,7 +238,7 @@ void MediaDecoder::NotifyDecodedStreamMainThreadStateChanged() void MediaDecoder::AddOutputStream(ProcessedMediaStream* aStream, bool aFinishWhenEnded) { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); LOG(PR_LOG_DEBUG, ("MediaDecoder::AddOutputStream this=%p aStream=%p!", this, aStream)); @@ -269,7 +269,7 @@ void MediaDecoder::AddOutputStream(ProcessedMediaStream* aStream, double MediaDecoder::GetDuration() { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); if (mInfiniteStream) { return std::numeric_limits::infinity(); } @@ -286,13 +286,13 @@ int64_t MediaDecoder::GetMediaDuration() void MediaDecoder::SetInfinite(bool aInfinite) { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); mInfiniteStream = aInfinite; } bool MediaDecoder::IsInfinite() { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); return mInfiniteStream; } @@ -318,7 +318,7 @@ MediaDecoder::MediaDecoder() : mAudioChannelType(AUDIO_CHANNEL_NORMAL) { MOZ_COUNT_CTOR(MediaDecoder); - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); MediaMemoryReporter::AddMediaDecoder(this); #ifdef PR_LOGGING if (!gMediaDecoderLog) { @@ -329,7 +329,7 @@ MediaDecoder::MediaDecoder() : bool MediaDecoder::Init(MediaDecoderOwner* aOwner) { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); mOwner = aOwner; mVideoFrameContainer = aOwner->GetVideoFrameContainer(); nsContentUtils::RegisterShutdownObserver(this); @@ -338,7 +338,7 @@ bool MediaDecoder::Init(MediaDecoderOwner* aOwner) void MediaDecoder::Shutdown() { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); if (mShuttingDown) return; @@ -373,7 +373,7 @@ void MediaDecoder::Shutdown() MediaDecoder::~MediaDecoder() { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); MediaMemoryReporter::RemoveMediaDecoder(this); UnpinForSeek(); MOZ_COUNT_DTOR(MediaDecoder); @@ -382,7 +382,7 @@ MediaDecoder::~MediaDecoder() nsresult MediaDecoder::OpenResource(MediaResource* aResource, nsIStreamListener** aStreamListener) { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); if (aStreamListener) { *aStreamListener = nullptr; } @@ -409,7 +409,7 @@ nsresult MediaDecoder::Load(MediaResource* aResource, nsIStreamListener** aStreamListener, MediaDecoder* aCloneDonor) { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); nsresult rv = OpenResource(aResource, aStreamListener); NS_ENSURE_SUCCESS(rv, rv); @@ -425,7 +425,7 @@ nsresult MediaDecoder::Load(MediaResource* aResource, nsresult MediaDecoder::InitializeStateMachine(MediaDecoder* aCloneDonor) { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); MediaDecoder* cloneDonor = static_cast(aCloneDonor); if (NS_FAILED(mDecoderStateMachine->Init(cloneDonor ? @@ -467,7 +467,7 @@ nsresult MediaDecoder::RequestFrameBufferLength(uint32_t aLength) nsresult MediaDecoder::ScheduleStateMachineThread() { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); NS_ASSERTION(mDecoderStateMachine, "Must have state machine to start state machine thread"); NS_ENSURE_STATE(mDecoderStateMachine); @@ -482,7 +482,7 @@ nsresult MediaDecoder::ScheduleStateMachineThread() nsresult MediaDecoder::Play() { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); NS_ASSERTION(mDecoderStateMachine != nullptr, "Should have state machine."); nsresult res = ScheduleStateMachineThread(); @@ -527,7 +527,7 @@ static bool IsInRanges(nsTimeRanges& aRanges, double aValue, int32_t& aIntervalI nsresult MediaDecoder::Seek(double aTime) { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); NS_ABORT_IF_FALSE(aTime >= 0.0, "Cannot seek to a negative value."); @@ -600,19 +600,19 @@ nsresult MediaDecoder::Seek(double aTime) nsresult MediaDecoder::PlaybackRateChanged() { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); return NS_ERROR_NOT_IMPLEMENTED; } double MediaDecoder::GetCurrentTime() { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); return mCurrentTime; } already_AddRefed MediaDecoder::GetCurrentPrincipal() { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); return mResource ? mResource->GetCurrentPrincipal() : nullptr; } @@ -624,7 +624,7 @@ void MediaDecoder::AudioAvailable(float* aFrameBuffer, // here, this ensures we free the memory. Otherwise, we pass off ownership // to HTMLMediaElement::NotifyAudioAvailable(). nsAutoArrayPtr frameBuffer(aFrameBuffer); - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); if (mShuttingDown || !mOwner) { return; } @@ -636,7 +636,7 @@ void MediaDecoder::MetadataLoaded(uint32_t aChannels, bool aHasAudio, const MetadataTags* aTags) { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); if (mShuttingDown) { return; } @@ -703,7 +703,7 @@ void MediaDecoder::MetadataLoaded(uint32_t aChannels, void MediaDecoder::ResourceLoaded() { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); // Don't handle ResourceLoaded if we are shutting down, or if // we need to ignore progress data due to seeking (in the case @@ -733,7 +733,7 @@ void MediaDecoder::ResourceLoaded() void MediaDecoder::NetworkError() { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); if (mShuttingDown) return; @@ -745,7 +745,7 @@ void MediaDecoder::NetworkError() void MediaDecoder::DecodeError() { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); if (mShuttingDown) return; @@ -757,19 +757,19 @@ void MediaDecoder::DecodeError() bool MediaDecoder::IsSeeking() const { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); return mPlayState == PLAY_STATE_SEEKING; } bool MediaDecoder::IsEnded() const { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); return mPlayState == PLAY_STATE_ENDED || mPlayState == PLAY_STATE_SHUTDOWN; } void MediaDecoder::PlaybackEnded() { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); if (mShuttingDown || mPlayState == MediaDecoder::PLAY_STATE_SEEKING) return; @@ -818,7 +818,7 @@ NS_IMETHODIMP MediaDecoder::Observe(nsISupports *aSubjet, const char *aTopic, const PRUnichar *someData) { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) { Shutdown(); } @@ -829,8 +829,7 @@ NS_IMETHODIMP MediaDecoder::Observe(nsISupports *aSubjet, MediaDecoder::Statistics MediaDecoder::GetStatistics() { - NS_ASSERTION(NS_IsMainThread() || OnStateMachineThread(), - "Should be on main or state machine thread."); + MOZ_ASSERT(NS_IsMainThread() || OnStateMachineThread()); Statistics result; ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); @@ -861,8 +860,7 @@ MediaDecoder::GetStatistics() double MediaDecoder::ComputePlaybackRate(bool* aReliable) { GetReentrantMonitor().AssertCurrentThreadIn(); - NS_ASSERTION(NS_IsMainThread() || OnStateMachineThread(), - "Should be on main or state machine thread."); + MOZ_ASSERT(NS_IsMainThread() || OnStateMachineThread()); int64_t length = mResource ? mResource->GetLength() : -1; if (mDuration >= 0 && length >= 0) { @@ -874,8 +872,7 @@ double MediaDecoder::ComputePlaybackRate(bool* aReliable) void MediaDecoder::UpdatePlaybackRate() { - NS_ASSERTION(NS_IsMainThread() || OnStateMachineThread(), - "Should be on main or state machine thread."); + MOZ_ASSERT(NS_IsMainThread() || OnStateMachineThread()); GetReentrantMonitor().AssertCurrentThreadIn(); if (!mResource) return; @@ -895,7 +892,7 @@ void MediaDecoder::UpdatePlaybackRate() void MediaDecoder::NotifySuspendedStatusChanged() { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); if (!mResource) return; MediaResource* activeStream; @@ -914,14 +911,14 @@ void MediaDecoder::NotifySuspendedStatusChanged() void MediaDecoder::NotifyBytesDownloaded() { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); UpdateReadyStateForData(); Progress(false); } void MediaDecoder::NotifyDownloadEnded(nsresult aStatus) { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); if (aStatus == NS_BINDING_ABORTED) { // Download has been cancelled by user. @@ -955,8 +952,7 @@ void MediaDecoder::NotifyPrincipalChanged() void MediaDecoder::NotifyBytesConsumed(int64_t aBytes) { ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); - NS_ASSERTION(OnStateMachineThread() || mDecoderStateMachine->OnDecodeThread(), - "Should be on play state machine or decode thread."); + MOZ_ASSERT(OnStateMachineThread() || mDecoderStateMachine->OnDecodeThread()); if (!mIgnoreProgressData) { mDecoderPosition += aBytes; mPlaybackStatistics.AddBytes(aBytes); @@ -965,7 +961,7 @@ void MediaDecoder::NotifyBytesConsumed(int64_t aBytes) void MediaDecoder::NextFrameUnavailableBuffering() { - NS_ASSERTION(NS_IsMainThread(), "Should be called on main thread"); + MOZ_ASSERT(NS_IsMainThread()); if (!mOwner || mShuttingDown || !mDecoderStateMachine) return; @@ -974,7 +970,7 @@ void MediaDecoder::NextFrameUnavailableBuffering() void MediaDecoder::NextFrameAvailable() { - NS_ASSERTION(NS_IsMainThread(), "Should be called on main thread"); + MOZ_ASSERT(NS_IsMainThread()); if (!mOwner || mShuttingDown || !mDecoderStateMachine) return; @@ -983,7 +979,7 @@ void MediaDecoder::NextFrameAvailable() void MediaDecoder::NextFrameUnavailable() { - NS_ASSERTION(NS_IsMainThread(), "Should be called on main thread"); + MOZ_ASSERT(NS_IsMainThread()); if (!mOwner || mShuttingDown || !mDecoderStateMachine) return; mOwner->UpdateReadyStateForData(MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE); @@ -991,7 +987,7 @@ void MediaDecoder::NextFrameUnavailable() void MediaDecoder::UpdateReadyStateForData() { - NS_ASSERTION(NS_IsMainThread(), "Should be called on main thread"); + MOZ_ASSERT(NS_IsMainThread()); if (!mOwner || mShuttingDown || !mDecoderStateMachine) return; MediaDecoderOwner::NextFrameStatus frameStatus = @@ -1001,7 +997,7 @@ void MediaDecoder::UpdateReadyStateForData() void MediaDecoder::SeekingStopped() { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); if (mShuttingDown) return; @@ -1033,7 +1029,7 @@ void MediaDecoder::SeekingStopped() // media. void MediaDecoder::SeekingStoppedAtEnd() { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); if (mShuttingDown) return; @@ -1068,7 +1064,7 @@ void MediaDecoder::SeekingStoppedAtEnd() void MediaDecoder::SeekingStarted() { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); if (mShuttingDown) return; @@ -1080,7 +1076,7 @@ void MediaDecoder::SeekingStarted() void MediaDecoder::ChangeState(PlayState aState) { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); if (mNextState == aState) { @@ -1119,7 +1115,7 @@ void MediaDecoder::ChangeState(PlayState aState) void MediaDecoder::PlaybackPositionChanged() { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); if (mShuttingDown) return; @@ -1157,7 +1153,7 @@ void MediaDecoder::PlaybackPositionChanged() void MediaDecoder::DurationChanged() { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); int64_t oldDuration = mDuration; mDuration = mDecoderStateMachine ? mDecoderStateMachine->GetDuration() : -1; @@ -1172,7 +1168,7 @@ void MediaDecoder::DurationChanged() void MediaDecoder::SetDuration(double aDuration) { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); mDuration = static_cast(NS_round(aDuration * static_cast(USECS_PER_S))); ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); @@ -1191,7 +1187,7 @@ void MediaDecoder::SetMediaDuration(int64_t aDuration) void MediaDecoder::SetSeekable(bool aSeekable) { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); mSeekable = aSeekable; if (mDecoderStateMachine) { ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); @@ -1201,7 +1197,7 @@ void MediaDecoder::SetSeekable(bool aSeekable) bool MediaDecoder::IsSeekable() { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); return mSeekable; } @@ -1233,7 +1229,7 @@ nsresult MediaDecoder::GetSeekable(nsTimeRanges* aSeekable) void MediaDecoder::SetFragmentEndTime(double aTime) { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); if (mDecoderStateMachine) { ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); mDecoderStateMachine->SetFragmentEndTime(static_cast(aTime * USECS_PER_S)); @@ -1247,7 +1243,7 @@ void MediaDecoder::SetMediaEndTime(int64_t aTime) void MediaDecoder::Suspend() { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); if (mResource) { mResource->Suspend(true); } @@ -1255,7 +1251,7 @@ void MediaDecoder::Suspend() void MediaDecoder::Resume(bool aForceBuffering) { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); if (mResource) { mResource->Resume(); } @@ -1269,8 +1265,7 @@ void MediaDecoder::Resume(bool aForceBuffering) void MediaDecoder::StopProgressUpdates() { - NS_ASSERTION(OnStateMachineThread() || OnDecodeThread(), - "Should be on state machine or decode thread."); + MOZ_ASSERT(OnStateMachineThread() || OnDecodeThread()); GetReentrantMonitor().AssertCurrentThreadIn(); mIgnoreProgressData = true; if (mResource) { @@ -1280,8 +1275,7 @@ void MediaDecoder::StopProgressUpdates() void MediaDecoder::StartProgressUpdates() { - NS_ASSERTION(OnStateMachineThread() || OnDecodeThread(), - "Should be on state machine or decode thread."); + MOZ_ASSERT(OnStateMachineThread() || OnDecodeThread()); GetReentrantMonitor().AssertCurrentThreadIn(); mIgnoreProgressData = false; if (mResource) { @@ -1292,7 +1286,7 @@ void MediaDecoder::StartProgressUpdates() void MediaDecoder::MoveLoadsToBackground() { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); if (mResource) { mResource->MoveLoadsToBackground(); } @@ -1311,7 +1305,7 @@ bool MediaDecoder::OnStateMachineThread() const void MediaDecoder::NotifyAudioAvailableListener() { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + MOZ_ASSERT(NS_IsMainThread()); if (mDecoderStateMachine) { ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); mDecoderStateMachine->NotifyAudioAvailableListener(); From c30570793b0d722df428e6efb1df7876dbb4d1a7 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Fri, 16 Nov 2012 20:31:53 -0800 Subject: [PATCH 13/57] Bug 813209 - Refactor MediaResource into BaseMediaResource so that we can base the implementation of BufferMediaSource on top of MediaSource; r=cpearce This refactoring is needed for the introduction of the BufferMediaResource class. --- content/media/MediaResource.cpp | 10 +++++----- content/media/MediaResource.h | 16 +++++++++++----- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/content/media/MediaResource.cpp b/content/media/MediaResource.cpp index 0666b6afdc0c..0fba8b0be9bf 100644 --- a/content/media/MediaResource.cpp +++ b/content/media/MediaResource.cpp @@ -49,7 +49,7 @@ namespace mozilla { ChannelMediaResource::ChannelMediaResource(MediaDecoder* aDecoder, nsIChannel* aChannel, nsIURI* aURI) - : MediaResource(aDecoder, aChannel, aURI), + : BaseMediaResource(aDecoder, aChannel, aURI), mOffset(0), mSuspendCount(0), mReopenOnError(false), mIgnoreClose(false), mCacheStream(this), @@ -1153,11 +1153,11 @@ ChannelMediaResource::PossiblyResume() } } -class FileMediaResource : public MediaResource +class FileMediaResource : public BaseMediaResource { public: FileMediaResource(MediaDecoder* aDecoder, nsIChannel* aChannel, nsIURI* aURI) : - MediaResource(aDecoder, aChannel, aURI), + BaseMediaResource(aDecoder, aChannel, aURI), mSize(-1), mLock("FileMediaResource.mLock"), mSizeInitialized(false) @@ -1514,7 +1514,7 @@ MediaResource::Create(MediaDecoder* aDecoder, nsIChannel* aChannel) return new ChannelMediaResource(aDecoder, aChannel, uri); } -void MediaResource::MoveLoadsToBackground() { +void BaseMediaResource::MoveLoadsToBackground() { NS_ASSERTION(!mLoadInBackground, "Why are you calling this more than once?"); mLoadInBackground = true; if (!mChannel) { @@ -1545,7 +1545,7 @@ void MediaResource::MoveLoadsToBackground() { } } -void MediaResource::ModifyLoadFlags(nsLoadFlags aFlags) +void BaseMediaResource::ModifyLoadFlags(nsLoadFlags aFlags) { nsCOMPtr loadGroup; DebugOnly rv = mChannel->GetLoadGroup(getter_AddRefs(loadGroup)); diff --git a/content/media/MediaResource.h b/content/media/MediaResource.h index 81659ce70915..c391439aee23 100644 --- a/content/media/MediaResource.h +++ b/content/media/MediaResource.h @@ -153,7 +153,7 @@ public: // The following can be called on the main thread only: // Get the URI - nsIURI* URI() const { return mURI; } + virtual nsIURI* URI() const { return nullptr; } // Close the resource, stop any listeners, channels, etc. // Cancels any currently blocking Read request and forces that request to // return an error. @@ -227,7 +227,7 @@ public: // Moves any existing channel loads into the background, so that they don't // block the load event. Any new loads initiated (for example to seek) // will also be in the background. - void MoveLoadsToBackground(); + virtual void MoveLoadsToBackground() {} // Ensures that the value returned by IsSuspendedByCache below is up to date // (i.e. the cache has examined this stream at least once). virtual void EnsureCacheUpToDate() {} @@ -307,15 +307,21 @@ public: * aRanges is being used. */ virtual nsresult GetCachedRanges(nsTArray& aRanges) = 0; +}; + +class BaseMediaResource : public MediaResource { +public: + virtual nsIURI* URI() const { return mURI; } + virtual void MoveLoadsToBackground(); protected: - MediaResource(MediaDecoder* aDecoder, nsIChannel* aChannel, nsIURI* aURI) : + BaseMediaResource(MediaDecoder* aDecoder, nsIChannel* aChannel, nsIURI* aURI) : mDecoder(aDecoder), mChannel(aChannel), mURI(aURI), mLoadInBackground(false) { - MOZ_COUNT_CTOR(MediaResource); + MOZ_COUNT_CTOR(BaseMediaResource); } // Set the request's load flags to aFlags. If the request is part of a @@ -349,7 +355,7 @@ protected: * All synchronization is performed by MediaCacheStream; all off-main- * thread operations are delegated directly to that object. */ -class ChannelMediaResource : public MediaResource +class ChannelMediaResource : public BaseMediaResource { public: ChannelMediaResource(MediaDecoder* aDecoder, nsIChannel* aChannel, nsIURI* aURI); From 0aff34f3d38ddda63642ad25c48800ebac531e41 Mon Sep 17 00:00:00 2001 From: Ethan Hugg Date: Mon, 12 Nov 2012 15:34:05 -0800 Subject: [PATCH 14/57] Bug 811118 build webrtc unittests by default but run only some r=jesup --- configure.in | 1 - media/mtransport/test/mtransport_test_utils.h | 7 +++++++ media/webrtc/signaling/test/mediaconduit_unittests.cpp | 3 +++ media/webrtc/signaling/test/signaling_unittests.cpp | 3 +++ toolkit/toolkit-tiers.mk | 2 -- 5 files changed, 13 insertions(+), 3 deletions(-) diff --git a/configure.in b/configure.in index 29cd9cf67280..624e57c1c44d 100644 --- a/configure.in +++ b/configure.in @@ -5230,7 +5230,6 @@ dnl enable once PeerConnection lands fi AC_SUBST(MOZ_WEBRTC) -AC_SUBST(MOZ_WEBRTC_TESTS) AC_SUBST(MOZ_WEBRTC_SIGNALING) AC_SUBST(MOZ_PEERCONNECTION) AC_SUBST(MOZ_WEBRTC_IN_LIBXUL) diff --git a/media/mtransport/test/mtransport_test_utils.h b/media/mtransport/test/mtransport_test_utils.h index 82112b30832a..249e53987228 100644 --- a/media/mtransport/test/mtransport_test_utils.h +++ b/media/mtransport/test/mtransport_test_utils.h @@ -91,6 +91,13 @@ MtransportTestUtils *mtransport_test_utils; #define SETUP_MTRANSPORT_TEST_UTILS() \ MtransportTestUtils utils_; mtransport_test_utils = &utils_ +#define CHECK_ENVIRONMENT_FLAG(envname) \ + char *test_flag = getenv(envname); \ + if (!test_flag || strcmp(test_flag, "1")) { \ + printf("To run this test set %s=1 in your environment\n", envname); \ + exit(0); \ + } \ + #endif diff --git a/media/webrtc/signaling/test/mediaconduit_unittests.cpp b/media/webrtc/signaling/test/mediaconduit_unittests.cpp index 63e064b3f1db..87e2d17e94a7 100644 --- a/media/webrtc/signaling/test/mediaconduit_unittests.cpp +++ b/media/webrtc/signaling/test/mediaconduit_unittests.cpp @@ -749,6 +749,9 @@ TEST_F(TransportConduitTest, TestVideoConduitCodecAPI) { int main(int argc, char **argv) { + // This test can cause intermittent oranges on the builders + CHECK_ENVIRONMENT_FLAG("MOZ_WEBRTC_TESTS") + test_utils = new MtransportTestUtils(); ::testing::InitGoogleTest(&argc, argv); int rv = RUN_ALL_TESTS(); diff --git a/media/webrtc/signaling/test/signaling_unittests.cpp b/media/webrtc/signaling/test/signaling_unittests.cpp index 0105c0c316fb..3b87aafa6fec 100644 --- a/media/webrtc/signaling/test/signaling_unittests.cpp +++ b/media/webrtc/signaling/test/signaling_unittests.cpp @@ -1203,6 +1203,9 @@ TEST_F(SignalingTest, FullCallTrickle) } // End namespace test. int main(int argc, char **argv) { + // This test can cause intermittent oranges on the builders + CHECK_ENVIRONMENT_FLAG("MOZ_WEBRTC_TESTS") + test_utils = new MtransportTestUtils(); NSS_NoDB_Init(NULL); NSS_SetDomesticPolicy(); diff --git a/toolkit/toolkit-tiers.mk b/toolkit/toolkit-tiers.mk index 4b16d2380c1c..e1722b95d4af 100644 --- a/toolkit/toolkit-tiers.mk +++ b/toolkit/toolkit-tiers.mk @@ -301,9 +301,7 @@ tier_platform_dirs += testing/tools/screenshot tier_platform_dirs += testing/peptest tier_platform_dirs += testing/mozbase ifdef MOZ_WEBRTC -ifdef MOZ_WEBRTC_TESTS tier_platform_dirs += media/webrtc/signaling/test tier_platform_dirs += media/mtransport/test endif endif -endif From 3fb3263ebe9924dc240aeda0bcf058798c2baa0d Mon Sep 17 00:00:00 2001 From: David Keeler Date: Mon, 19 Nov 2012 14:03:24 -0800 Subject: [PATCH 15/57] bug 811375 - decouple nsIPluginTag::clicktoplay from click-to-play blocklisting r=joshmoz --- .../test/browser_pluginnotification.js | 2 - content/base/src/nsObjectLoadingContent.cpp | 8 ++- dom/plugins/base/nsIPluginHost.idl | 4 +- dom/plugins/base/nsNPAPIPluginInstance.cpp | 10 +++- dom/plugins/base/nsPluginHost.cpp | 29 +++++++---- dom/plugins/base/nsPluginHost.h | 1 - .../mozapps/extensions/nsBlocklistService.js | 7 --- .../test/xpcshell/test_pluginBlocklistCtp.js | 50 ++++++++++++++----- 8 files changed, 73 insertions(+), 38 deletions(-) diff --git a/browser/base/content/test/browser_pluginnotification.js b/browser/base/content/test/browser_pluginnotification.js index deb5176ba7d7..6f3a37c98e50 100644 --- a/browser/base/content/test/browser_pluginnotification.js +++ b/browser/base/content/test/browser_pluginnotification.js @@ -659,8 +659,6 @@ function test18e() { ok(objLoadingContent.activated, "Test 18e, Plugin should be activated"); unregisterFakeBlocklistService(); - var plugin = getTestPlugin(); - plugin.clicktoplay = false; Services.perms.removeAll(); prepareTest(test19a, gTestRoot + "plugin_test.html"); diff --git a/content/base/src/nsObjectLoadingContent.cpp b/content/base/src/nsObjectLoadingContent.cpp index 2a74163fe09b..87bb5274de88 100644 --- a/content/base/src/nsObjectLoadingContent.cpp +++ b/content/base/src/nsObjectLoadingContent.cpp @@ -2505,7 +2505,11 @@ nsObjectLoadingContent::ShouldPlay(FallbackType &aReason) nsRefPtr pluginHost = already_AddRefed(nsPluginHost::GetInst()); - bool isCTP = pluginHost->IsPluginClickToPlayForType(mContentType.get()); + bool isCTP; + nsresult rv = pluginHost->IsPluginClickToPlayForType(mContentType, &isCTP); + if (NS_FAILED(rv)) { + return false; + } if (!isCTP || mActivated) { return true; @@ -2515,7 +2519,7 @@ nsObjectLoadingContent::ShouldPlay(FallbackType &aReason) aReason = eFallbackClickToPlay; // (if it's click-to-play, it might be because of the blocklist) uint32_t state; - nsresult rv = pluginHost->GetBlocklistStateForType(mContentType.get(), &state); + rv = pluginHost->GetBlocklistStateForType(mContentType.get(), &state); NS_ENSURE_SUCCESS(rv, false); if (state == nsIBlocklistService::STATE_VULNERABLE_UPDATE_AVAILABLE) { aReason = eFallbackVulnerableUpdatable; diff --git a/dom/plugins/base/nsIPluginHost.idl b/dom/plugins/base/nsIPluginHost.idl index d3a6b8b034ec..7e1261fb1c46 100644 --- a/dom/plugins/base/nsIPluginHost.idl +++ b/dom/plugins/base/nsIPluginHost.idl @@ -12,7 +12,7 @@ "@mozilla.org/plugin/host;1" %} -[scriptable, uuid(fdb56ce3-89ac-4293-be64-9f4be88004cc)] +[scriptable, uuid(d70af999-cb1f-4429-b85e-f18cdbabc43c)] interface nsIPluginHost : nsISupports { /** @@ -81,5 +81,7 @@ interface nsIPluginHost : nsISupports void registerPlayPreviewMimeType(in AUTF8String mimeType); void unregisterPlayPreviewMimeType(in AUTF8String mimeType); + + bool isPluginClickToPlayForType(in AUTF8String mimeType); }; diff --git a/dom/plugins/base/nsNPAPIPluginInstance.cpp b/dom/plugins/base/nsNPAPIPluginInstance.cpp index db54932b0b7f..cfce39aeb98a 100644 --- a/dom/plugins/base/nsNPAPIPluginInstance.cpp +++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp @@ -1762,8 +1762,14 @@ nsNPAPIPluginInstance::CheckJavaC2PJSObjectQuirk(uint16_t paramCount, nsRefPtr pluginHost = already_AddRefed(nsPluginHost::GetInst()); - if (!pluginHost || - !pluginHost->IsPluginClickToPlayForType(mMIMEType)) { + if (!pluginHost) { + return; + } + + bool isClickToPlay; + nsAutoCString mimeType(mMIMEType); + rv = pluginHost->IsPluginClickToPlayForType(mimeType, &isClickToPlay); + if (NS_FAILED(rv) || !isClickToPlay) { return; } diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp index 1b629fd543b4..aed61be8d7f6 100644 --- a/dom/plugins/base/nsPluginHost.cpp +++ b/dom/plugins/base/nsPluginHost.cpp @@ -1295,17 +1295,28 @@ nsPluginHost::IsPluginEnabledForType(const char* aMimeType) return NS_OK; } -bool -nsPluginHost::IsPluginClickToPlayForType(const char* aMimeType) +NS_IMETHODIMP +nsPluginHost::IsPluginClickToPlayForType(const nsACString &aMimeType, bool *aResult) { - nsPluginTag *plugin = FindPluginForType(aMimeType, true); - if (plugin && - (plugin->HasFlag(NS_PLUGIN_FLAG_CLICKTOPLAY) || mPluginsClickToPlay)) { - return true; + nsPluginTag *plugin = FindPluginForType(aMimeType.Data(), true); + if (!plugin) { + return NS_ERROR_UNEXPECTED; + } + + uint32_t blocklistState = nsIBlocklistService::STATE_NOT_BLOCKED; + nsresult rv = GetBlocklistStateForType(aMimeType.Data(), &blocklistState); + NS_ENSURE_SUCCESS(rv, rv); + + if (mPluginsClickToPlay || + blocklistState == nsIBlocklistService::STATE_VULNERABLE_NO_UPDATE || + blocklistState == nsIBlocklistService::STATE_VULNERABLE_UPDATE_AVAILABLE) { + *aResult = true; } else { - return false; + *aResult = false; } + + return NS_OK; } bool @@ -2154,10 +2165,6 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir, if (state == nsIBlocklistService::STATE_OUTDATED && !seenBefore) { warnOutdated = true; } - if (state == nsIBlocklistService::STATE_VULNERABLE_UPDATE_AVAILABLE || - state == nsIBlocklistService::STATE_VULNERABLE_NO_UPDATE) { - pluginTag->Mark(NS_PLUGIN_FLAG_CLICKTOPLAY); - } } } diff --git a/dom/plugins/base/nsPluginHost.h b/dom/plugins/base/nsPluginHost.h index 4e4cbb6776b6..5ae3d2d6abfc 100644 --- a/dom/plugins/base/nsPluginHost.h +++ b/dom/plugins/base/nsPluginHost.h @@ -81,7 +81,6 @@ public: nsPluginInstanceOwner *aOwner); nsresult IsPluginEnabledForType(const char* aMimeType); nsresult IsPluginEnabledForExtension(const char* aExtension, const char* &aMimeType); - bool IsPluginClickToPlayForType(const char *aMimeType); bool IsPluginPlayPreviewForType(const char *aMimeType); nsresult GetBlocklistStateForType(const char *aMimeType, uint32_t *state); diff --git a/toolkit/mozapps/extensions/nsBlocklistService.js b/toolkit/mozapps/extensions/nsBlocklistService.js index da8d4a389aeb..e7735cba175b 100644 --- a/toolkit/mozapps/extensions/nsBlocklistService.js +++ b/toolkit/mozapps/extensions/nsBlocklistService.js @@ -938,13 +938,6 @@ Blocklist.prototype = { } } plugin.blocklisted = state == Ci.nsIBlocklistService.STATE_BLOCKED; - if (state == Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE || - state == Ci.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE) - plugin.clicktoplay = true; - // turn off clicktoplay if it was previously set by the blocklist - else if (oldState == Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE || - oldState == Ci.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE) - plugin.clicktoplay = false; } if (addonList.length == 0) { diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_pluginBlocklistCtp.js b/toolkit/mozapps/extensions/test/xpcshell/test_pluginBlocklistCtp.js index 5607d0f85b2e..c123a3bcb078 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_pluginBlocklistCtp.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_pluginBlocklistCtp.js @@ -48,9 +48,11 @@ var PLUGINS = [{ blocklisted: false }]; +var gBlocklistService = null; var gNotifier = null; var gNextTest = null; var gServer = null; +var gPluginHost = null; function test_basic() { var blocklist = Components.classes["@mozilla.org/extensions/blocklist;1"].getService(nsIBLS); @@ -85,7 +87,10 @@ function get_test_plugin() { // so it shouldn't be click-to-play. function test_is_not_clicktoplay() { var plugin = get_test_plugin(); - do_check_false(plugin.clicktoplay); + var blocklistState = gBlocklistService.getPluginBlocklistState(plugin, "1", "1.9"); + do_check_neq(blocklistState, Components.interfaces.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE); + do_check_neq(blocklistState, Components.interfaces.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE); + do_check_false(gPluginHost.isPluginClickToPlayForType("application/x-test")); Services.prefs.setCharPref("extensions.blocklist.url", "http://localhost:4444/data/test_pluginBlocklistCtpUndo.xml"); gNextTest = test_is_clicktoplay; @@ -96,7 +101,9 @@ function test_is_not_clicktoplay() { // so it should be click-to-play. function test_is_clicktoplay() { var plugin = get_test_plugin(); - do_check_true(plugin.clicktoplay); + var blocklistState = gBlocklistService.getPluginBlocklistState(plugin, "1", "1.9"); + do_check_eq(blocklistState, Components.interfaces.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE); + do_check_true(gPluginHost.isPluginClickToPlayForType("application/x-test")); Services.prefs.setCharPref("extensions.blocklist.url", "http://localhost:4444/data/test_pluginBlocklistCtp.xml"); gNextTest = test_is_not_clicktoplay2; @@ -107,25 +114,42 @@ function test_is_clicktoplay() { // to the old one), so the plugin shouldn't be click-to-play any more. function test_is_not_clicktoplay2() { var plugin = get_test_plugin(); - do_check_false(plugin.clicktoplay); + var blocklistState = gBlocklistService.getPluginBlocklistState(plugin, "1", "1.9"); + do_check_neq(blocklistState, Components.interfaces.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE); + do_check_neq(blocklistState, Components.interfaces.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE); + do_check_false(gPluginHost.isPluginClickToPlayForType("application/x-test")); - plugin.clicktoplay = true; - gNextTest = test_is_clicktoplay2; + Services.prefs.setCharPref("extensions.blocklist.url", "http://localhost:4444/data/test_pluginBlocklistCtpUndo.xml"); + gNextTest = test_disable_blocklist; gNotifier.notify(null); } -// Now test that if the user makes a plugin click-to-play, not having it on -// the blocklist doesn't undo that setting. -function test_is_clicktoplay2() { +// Test that disabling the blocklist when a plugin is ctp-blocklisted will +// result in the plugin not being click-to-play. +function test_disable_blocklist() { var plugin = get_test_plugin(); - do_check_true(plugin.clicktoplay); + var blocklistState = gBlocklistService.getPluginBlocklistState(plugin, "1", "1.9"); + do_check_eq(blocklistState, Components.interfaces.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE); + do_check_true(gPluginHost.isPluginClickToPlayForType("application/x-test")); + + gNextTest = null; + Services.prefs.setBoolPref("extensions.blocklist.enabled", false); + blocklistState = gBlocklistService.getPluginBlocklistState(plugin, "1", "1.9"); + do_check_neq(blocklistState, Components.interfaces.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE); + do_check_neq(blocklistState, Components.interfaces.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE); + do_check_false(gPluginHost.isPluginClickToPlayForType("application/x-test")); + + // it should still be possible to make a plugin click-to-play via the pref + Services.prefs.setBoolPref("plugins.click_to_play", true); + do_check_true(gPluginHost.isPluginClickToPlayForType("application/x-test")); gServer.stop(do_test_finished); } // Observe "blocklist-updated" so we know when to advance to the next test function observer() { - do_execute_soon(gNextTest); + if (gNextTest) + do_execute_soon(gNextTest); } function run_test() { @@ -138,14 +162,16 @@ function run_test() { Services.prefs.setCharPref("extensions.blocklist.url", "http://localhost:4444/data/test_pluginBlocklistCtp.xml"); startupManager(); + gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost); + gBlocklistService = Components.classes["@mozilla.org/extensions/blocklist;1"].getService(Components.interfaces.nsIBlocklistService); gNotifier = Components.classes["@mozilla.org/extensions/blocklist;1"].getService(Components.interfaces.nsITimerCallback); Services.obs.addObserver(observer, "blocklist-updated", false); do_register_cleanup(function() { Services.prefs.clearUserPref("extensions.blocklist.url"); + Services.prefs.clearUserPref("extensions.blocklist.enabled"); + Services.prefs.clearUserPref("plugins.click_to_play"); Services.obs.removeObserver(observer, "blocklist-updated"); - var plugin = get_test_plugin(); - plugin.clicktoplay = false; }); gNextTest = test_basic; From 38a35f4dca7cf492a5b6eb81f06af979713da3b6 Mon Sep 17 00:00:00 2001 From: Steve Fink Date: Mon, 19 Nov 2012 14:18:48 -0800 Subject: [PATCH 16/57] Bug 809975 - --failed-only should ignore expected failures. r=terrence --HG-- extra : rebase_source : 778596de5033dc7ff19ea074e4f660eb1f9f4fd0 --- js/src/tests/lib/results.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/js/src/tests/lib/results.py b/js/src/tests/lib/results.py index 4de3d8c5acdc..e21cafa5fb4e 100644 --- a/js/src/tests/lib/results.py +++ b/js/src/tests/lib/results.py @@ -111,9 +111,14 @@ class ResultsSink: self.n += 1 else: result = TestResult.from_output(output) + tup = (result.result, result.test.expect, result.test.random) + dev_label = self.LABELS[tup][1] + if output.timed_out: + dev_label = 'TIMEOUTS' + self.groups.setdefault(dev_label, []).append(result.test.path) show = self.options.show - if self.options.failed_only and result.result == 'PASS': + if self.options.failed_only and dev_label not in ('REGRESSIONS', 'TIMEOUTS'): show = False if show and self.options.show_output: @@ -126,12 +131,6 @@ class ResultsSink: self.fp.write(output.out) self.fp.write(output.err) - tup = (result.result, result.test.expect, result.test.random) - dev_label = self.LABELS[tup][1] - if output.timed_out: - dev_label = 'TIMEOUTS' - self.groups.setdefault(dev_label, []).append(result.test.path) - self.n += 1 if result.result == TestResult.PASS and not result.test.random: From 4f3af442c96947bd2470655f365851d17f1cd2c7 Mon Sep 17 00:00:00 2001 From: Steve Fink Date: Mon, 19 Nov 2012 14:19:01 -0800 Subject: [PATCH 17/57] Bug 809977 - Allow output with progress bar. r=terrence --HG-- extra : rebase_source : 6a87e7a24189769876e5638a60770dd95d48a921 --- js/src/tests/jstests.py | 4 +--- js/src/tests/lib/progressbar.py | 10 +++++++++- js/src/tests/lib/results.py | 17 ++++++++++------- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/js/src/tests/jstests.py b/js/src/tests/jstests.py index 98b06bc193e2..18c1adbcf06a 100755 --- a/js/src/tests/jstests.py +++ b/js/src/tests/jstests.py @@ -189,9 +189,7 @@ def parse_args(): options.show = options.show_cmd or options.show_output # Hide the progress bar if it will get in the way of other output. - options.hide_progress = ((options.show and - options.output_fp == sys.stdout) or - options.tinderbox or + options.hide_progress = (options.tinderbox or ProgressBar.conservative_isatty() or options.hide_progress) diff --git a/js/src/tests/lib/progressbar.py b/js/src/tests/lib/progressbar.py index 5e13ee914c9b..8d854c6f65a3 100644 --- a/js/src/tests/lib/progressbar.py +++ b/js/src/tests/lib/progressbar.py @@ -12,6 +12,7 @@ class NullProgressBar(object): def update(self, current, data): pass def poke(self): pass def finish(self, complete=True): pass + def beginline(self): pass def message(self, msg): sys.stdout.write(msg + '\n') def update_granularity(self): return timedelta.max @@ -21,6 +22,7 @@ class ProgressBar(object): assert limit < 9999 self.prior = None + self.atLineStart = True self.counters_fmt = fmt # [{str:str}] Describtion of how to lay out each # field in the counters map. self.limit = limit # int: The value of 'current' equal to 100%. @@ -40,6 +42,7 @@ class ProgressBar(object): def update(self, current, data): # Record prior for poke. self.prior = (current, data) + self.atLineStart = False # Build counters string. sys.stdout.write('\r[') @@ -79,8 +82,13 @@ class ProgressBar(object): self.update(final_count, self.prior[1]) sys.stdout.write('\n') + def beginline(self): + if not self.atLineStart: + sys.stdout.write('\n') + self.atLineStart = True + def message(self, msg): - sys.stdout.write('\n') + self.beginline() sys.stdout.write(msg) sys.stdout.write('\n') diff --git a/js/src/tests/lib/results.py b/js/src/tests/lib/results.py index e21cafa5fb4e..d852e6965ea1 100644 --- a/js/src/tests/lib/results.py +++ b/js/src/tests/lib/results.py @@ -120,16 +120,19 @@ class ResultsSink: show = self.options.show if self.options.failed_only and dev_label not in ('REGRESSIONS', 'TIMEOUTS'): show = False + if show: + self.pb.beginline() - if show and self.options.show_output: - print >> self.fp, '## %s: rc = %d, run time = %f' % (output.test.path, output.rc, output.dt) + if show: + if self.options.show_output: + print >> self.fp, '## %s: rc = %d, run time = %f' % (output.test.path, output.rc, output.dt) - if show and self.options.show_cmd: - print >> self.fp, escape_cmdline(output.cmd) + if self.options.show_cmd: + print >> self.fp, escape_cmdline(output.cmd) - if show and self.options.show_output: - self.fp.write(output.out) - self.fp.write(output.err) + if self.options.show_output: + self.fp.write(output.out) + self.fp.write(output.err) self.n += 1 From 9cc19a480159a4704f899f72500abb888cbac118 Mon Sep 17 00:00:00 2001 From: Phil Ringnalda Date: Mon, 19 Nov 2012 14:40:32 -0800 Subject: [PATCH 18/57] Back out 204665ad4a24 (bug 764240) for Android M4 failures --- docshell/base/nsIMarkupDocumentViewer.idl | 10 +-- dom/base/nsGlobalWindow.cpp | 24 +----- dom/tests/mochitest/bugs/Makefile.in | 1 - .../bugs/test_sizetocontent_clamp.html | 73 ------------------- layout/base/nsDocumentViewer.cpp | 15 +++- xpfe/appshell/src/nsXULWindow.cpp | 14 +--- 6 files changed, 21 insertions(+), 116 deletions(-) delete mode 100644 dom/tests/mochitest/bugs/test_sizetocontent_clamp.html diff --git a/docshell/base/nsIMarkupDocumentViewer.idl b/docshell/base/nsIMarkupDocumentViewer.idl index ef40ddcb10fe..92347f9b850f 100644 --- a/docshell/base/nsIMarkupDocumentViewer.idl +++ b/docshell/base/nsIMarkupDocumentViewer.idl @@ -23,7 +23,7 @@ interface nsIMarkupDocumentViewer; [ref] native nsIMarkupDocumentViewerTArray(nsTArray >); -[scriptable, uuid(02d37b31-e654-4b74-9bc3-14dfe0020bb3)] +[scriptable, uuid(1016d5e8-690f-4d97-8ac5-d50ffa341c46)] interface nsIMarkupDocumentViewer : nsISupports { @@ -68,10 +68,10 @@ interface nsIMarkupDocumentViewer : nsISupports //void GetCharacterSetHint(in wstring hintCharset, in int32_t charsetSource); - /** - * Requests the size of the content to the container. - */ - void getContentSize(out long width, out long height); + /** + * Tell the container to shrink-to-fit or grow-to-fit its contents + */ + void sizeToContent(); /** * Options for Bidi presentation. diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 248aed05e298..1ef77753d903 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -5474,32 +5474,12 @@ nsGlobalWindow::SizeToContent() // The content viewer does a check to make sure that it's a content // viewer for a toplevel docshell. + nsCOMPtr cv; mDocShell->GetContentViewer(getter_AddRefs(cv)); nsCOMPtr markupViewer(do_QueryInterface(cv)); NS_ENSURE_TRUE(markupViewer, NS_ERROR_FAILURE); - - int32_t width, height; - NS_ENSURE_SUCCESS(markupViewer->GetContentSize(&width, &height), - NS_ERROR_FAILURE); - - // Make sure the new size is following the CheckSecurityWidthAndHeight - // rules. - nsCOMPtr treeOwner; - GetTreeOwner(getter_AddRefs(treeOwner)); - NS_ENSURE_TRUE(treeOwner, NS_ERROR_FAILURE); - - nsIntSize cssSize(DevToCSSIntPixels(nsIntSize(width, height))); - NS_ENSURE_SUCCESS(CheckSecurityWidthAndHeight(&cssSize.width, - &cssSize.height), - NS_ERROR_FAILURE); - - nsIntSize newDevSize(CSSToDevIntPixels(cssSize)); - - nsCOMPtr docShellAsItem = do_QueryInterface(mDocShell); - NS_ENSURE_SUCCESS(treeOwner->SizeShellTo(docShellAsItem, - newDevSize.width, newDevSize.height), - NS_ERROR_FAILURE); + NS_ENSURE_SUCCESS(markupViewer->SizeToContent(), NS_ERROR_FAILURE); return NS_OK; } diff --git a/dom/tests/mochitest/bugs/Makefile.in b/dom/tests/mochitest/bugs/Makefile.in index 571f69461501..57bcd60bf26b 100644 --- a/dom/tests/mochitest/bugs/Makefile.in +++ b/dom/tests/mochitest/bugs/Makefile.in @@ -135,7 +135,6 @@ MOCHITEST_FILES = \ file_bug809290_b2.html \ file_bug809290_c.html \ file_empty.html \ - test_sizetocontent_clamp.html \ $(NULL) ifneq (Linux,$(OS_ARCH)) diff --git a/dom/tests/mochitest/bugs/test_sizetocontent_clamp.html b/dom/tests/mochitest/bugs/test_sizetocontent_clamp.html deleted file mode 100644 index a060a9a029ce..000000000000 --- a/dom/tests/mochitest/bugs/test_sizetocontent_clamp.html +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - Test for Bug 764240 - - - - - -Mozilla Bug 764240 -

-
- -
-
-
-
- - diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index eec502c146c8..44b94566e57b 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -3260,8 +3260,7 @@ NS_IMETHODIMP DocumentViewerImpl::ChangeMaxLineBoxWidth(int32_t aMaxLineBoxWidth return NS_OK; } -NS_IMETHODIMP -DocumentViewerImpl::GetContentSize(int32_t* aWidth, int32_t* aHeight) +NS_IMETHODIMP DocumentViewerImpl::SizeToContent() { NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE); @@ -3302,15 +3301,23 @@ DocumentViewerImpl::GetContentSize(int32_t* aWidth, int32_t* aHeight) GetPresContext(getter_AddRefs(presContext)); NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE); + int32_t width, height; + // so how big is it? nsRect shellArea = presContext->GetVisibleArea(); // Protect against bogus returns here NS_ENSURE_TRUE(shellArea.width != NS_UNCONSTRAINEDSIZE && shellArea.height != NS_UNCONSTRAINEDSIZE, NS_ERROR_FAILURE); + width = presContext->AppUnitsToDevPixels(shellArea.width); + height = presContext->AppUnitsToDevPixels(shellArea.height); - *aWidth = presContext->AppUnitsToDevPixels(shellArea.width); - *aHeight = presContext->AppUnitsToDevPixels(shellArea.height); + nsCOMPtr treeOwner; + docShellAsItem->GetTreeOwner(getter_AddRefs(treeOwner)); + NS_ENSURE_TRUE(treeOwner, NS_ERROR_FAILURE); + + NS_ENSURE_SUCCESS(treeOwner->SizeShellTo(docShellAsItem, width, height), + NS_ERROR_FAILURE); return NS_OK; } diff --git a/xpfe/appshell/src/nsXULWindow.cpp b/xpfe/appshell/src/nsXULWindow.cpp index bcb258df2fc9..276d02dbdb6c 100644 --- a/xpfe/appshell/src/nsXULWindow.cpp +++ b/xpfe/appshell/src/nsXULWindow.cpp @@ -975,17 +975,9 @@ void nsXULWindow::OnChromeLoaded() // (if LoadSizeFromXUL set the size, mIntrinsicallySized will be false) nsCOMPtr cv; mDocShell->GetContentViewer(getter_AddRefs(cv)); - nsCOMPtr markupViewer = do_QueryInterface(cv); - if (markupViewer) { - nsCOMPtr docShellAsItem = do_QueryInterface(mDocShell); - nsCOMPtr treeOwner; - docShellAsItem->GetTreeOwner(getter_AddRefs(treeOwner)); - if (treeOwner) { - int32_t width, height; - markupViewer->GetContentSize(&width, &height); - treeOwner->SizeShellTo(docShellAsItem, width, height); - } - } + nsCOMPtr markupViewer(do_QueryInterface(cv)); + if (markupViewer) + markupViewer->SizeToContent(); } bool positionSet = !mIgnoreXULPosition; From ac62c31b1d9fea1bcd01908abf2a98ade0429a2c Mon Sep 17 00:00:00 2001 From: Kannan Vijayan Date: Mon, 19 Nov 2012 17:43:13 -0500 Subject: [PATCH 19/57] Bug 813328 - Add initialize() method to IonCompartment. r=dvander --- js/src/ion/Ion.cpp | 6 ++++++ js/src/ion/IonCompartment.h | 2 ++ js/src/jscompartment.cpp | 6 ++++++ 3 files changed, 14 insertions(+) diff --git a/js/src/ion/Ion.cpp b/js/src/ion/Ion.cpp index 114706d78e7b..6df99cd0e5c1 100644 --- a/js/src/ion/Ion.cpp +++ b/js/src/ion/Ion.cpp @@ -204,6 +204,12 @@ IonCompartment::IonCompartment(IonRuntime *rt) { } +bool +IonCompartment::initialize(JSContext *cx) +{ + return true; +} + void ion::FinishOffThreadBuilder(IonBuilder *builder) { diff --git a/js/src/ion/IonCompartment.h b/js/src/ion/IonCompartment.h index a6b0e934492f..ba23c6d28fc5 100644 --- a/js/src/ion/IonCompartment.h +++ b/js/src/ion/IonCompartment.h @@ -100,6 +100,8 @@ class IonCompartment public: IonCompartment(IonRuntime *rt); + bool initialize(JSContext *cx); + void mark(JSTracer *trc, JSCompartment *compartment); void sweep(FreeOp *fop); diff --git a/js/src/jscompartment.cpp b/js/src/jscompartment.cpp index 01a051ca8442..8e7775db6f22 100644 --- a/js/src/jscompartment.cpp +++ b/js/src/jscompartment.cpp @@ -196,6 +196,12 @@ JSCompartment::ensureIonCompartmentExists(JSContext *cx) if (!ionCompartment_) return false; + if (!ionCompartment_->initialize(cx)) { + js_delete(ionCompartment_); + ionCompartment_ = NULL; + return false; + } + return true; } #endif From 0d70603e87715efe063884c2d3a5ac14a7e5e419 Mon Sep 17 00:00:00 2001 From: Josh Aas Date: Mon, 19 Nov 2012 18:02:21 -0500 Subject: [PATCH 20/57] Back out fix for bug 405407 due to regressions. --- netwerk/cache/nsCacheEntryDescriptor.h | 1 - netwerk/cache/nsDiskCacheStreams.cpp | 487 ++++++++++++++----- netwerk/cache/nsDiskCacheStreams.h | 21 +- toolkit/components/telemetry/Histograms.json | 12 + 4 files changed, 386 insertions(+), 135 deletions(-) diff --git a/netwerk/cache/nsCacheEntryDescriptor.h b/netwerk/cache/nsCacheEntryDescriptor.h index 016215bac415..0f301566f1f7 100644 --- a/netwerk/cache/nsCacheEntryDescriptor.h +++ b/netwerk/cache/nsCacheEntryDescriptor.h @@ -175,7 +175,6 @@ private: { nsCacheServiceAutoLock lock(LOCK_TELEM(NSOUTPUTSTREAMWRAPPER_CLOSE)); mDescriptor->mOutput = nullptr; - mOutput = nullptr; } NS_RELEASE(mDescriptor); } diff --git a/netwerk/cache/nsDiskCacheStreams.cpp b/netwerk/cache/nsDiskCacheStreams.cpp index 8016ff676ea7..7c16c0097f3c 100644 --- a/netwerk/cache/nsDiskCacheStreams.cpp +++ b/netwerk/cache/nsDiskCacheStreams.cpp @@ -15,16 +15,14 @@ #include "mozilla/Telemetry.h" #include "mozilla/TimeStamp.h" + + // Assumptions: // - cache descriptors live for life of streams // - streams will only be used by FileTransport, // they will not be directly accessible to clients // - overlapped I/O is NOT supported -// we pick 16k as the max buffer size because that is the threshold above which -// we are unable to store the data in the cache block files -// see nsDiskCacheMap.[cpp,h] -#define kMaxBufferSize (16 * 1024) /****************************************************************************** * nsDiskCacheInputStream @@ -180,13 +178,152 @@ nsDiskCacheInputStream::IsNonBlocking(bool * nonBlocking) return NS_OK; } + +/****************************************************************************** + * nsDiskCacheOutputStream + *****************************************************************************/ +class nsDiskCacheOutputStream : public nsIOutputStream + , public nsIDiskCacheStreamInternal +{ +public: + nsDiskCacheOutputStream( nsDiskCacheStreamIO * parent); + virtual ~nsDiskCacheOutputStream(); + + NS_DECL_ISUPPORTS + NS_DECL_NSIOUTPUTSTREAM + NS_DECL_NSIDISKCACHESTREAMINTERNAL + + void ReleaseStreamIO() { NS_IF_RELEASE(mStreamIO); } + +private: + nsDiskCacheStreamIO * mStreamIO; // backpointer to parent + bool mClosed; +}; + + +NS_IMPL_THREADSAFE_ISUPPORTS2(nsDiskCacheOutputStream, + nsIOutputStream, + nsIDiskCacheStreamInternal) + +nsDiskCacheOutputStream::nsDiskCacheOutputStream( nsDiskCacheStreamIO * parent) + : mStreamIO(parent) + , mClosed(false) +{ + NS_ADDREF(mStreamIO); +} + + +nsDiskCacheOutputStream::~nsDiskCacheOutputStream() +{ + Close(); + ReleaseStreamIO(); +} + + +NS_IMETHODIMP +nsDiskCacheOutputStream::Close() +{ + nsresult rv = NS_OK; + mozilla::TimeStamp start = mozilla::TimeStamp::Now(); + + if (!mClosed) { + mClosed = true; + // tell parent streamIO we are closing + rv = mStreamIO->CloseOutputStream(this); + } + + mozilla::Telemetry::ID id; + if (NS_IsMainThread()) + id = mozilla::Telemetry::NETWORK_DISK_CACHE_OUTPUT_STREAM_CLOSE_MAIN_THREAD; + else + id = mozilla::Telemetry::NETWORK_DISK_CACHE_OUTPUT_STREAM_CLOSE; + + mozilla::Telemetry::AccumulateTimeDelta(id, start); + + return rv; +} + +NS_IMETHODIMP +nsDiskCacheOutputStream::CloseInternal() +{ + nsresult rv = NS_OK; + mozilla::TimeStamp start = mozilla::TimeStamp::Now(); + + if (!mClosed) { + mClosed = true; + // tell parent streamIO we are closing + rv = mStreamIO->CloseOutputStreamInternal(this); + } + + mozilla::Telemetry::ID id; + if (NS_IsMainThread()) + id = mozilla::Telemetry::NETWORK_DISK_CACHE_OUTPUT_STREAM_CLOSE_INTERNAL_MAIN_THREAD; + else + id = mozilla::Telemetry::NETWORK_DISK_CACHE_OUTPUT_STREAM_CLOSE_INTERNAL; + + mozilla::Telemetry::AccumulateTimeDelta(id, start); + + return rv; +} + +NS_IMETHODIMP +nsDiskCacheOutputStream::Flush() +{ + if (mClosed) return NS_BASE_STREAM_CLOSED; + // yeah, yeah, well get to it...eventually... + return NS_OK; +} + + +NS_IMETHODIMP +nsDiskCacheOutputStream::Write(const char *buf, uint32_t count, uint32_t *bytesWritten) +{ + if (mClosed) return NS_BASE_STREAM_CLOSED; + return mStreamIO->Write(buf, count, bytesWritten); +} + + +NS_IMETHODIMP +nsDiskCacheOutputStream::WriteFrom(nsIInputStream *inStream, uint32_t count, uint32_t *bytesWritten) +{ + NS_NOTREACHED("WriteFrom"); + return NS_ERROR_NOT_IMPLEMENTED; +} + + +NS_IMETHODIMP +nsDiskCacheOutputStream::WriteSegments( nsReadSegmentFun reader, + void * closure, + uint32_t count, + uint32_t * bytesWritten) +{ + NS_NOTREACHED("WriteSegments"); + return NS_ERROR_NOT_IMPLEMENTED; +} + + +NS_IMETHODIMP +nsDiskCacheOutputStream::IsNonBlocking(bool * nonBlocking) +{ + *nonBlocking = false; + return NS_OK; +} + + + /****************************************************************************** * nsDiskCacheStreamIO *****************************************************************************/ -NS_IMPL_THREADSAFE_ISUPPORTS2(nsDiskCacheStreamIO, nsIOutputStream, nsIDiskCacheStreamInternal) +NS_IMPL_THREADSAFE_ISUPPORTS0(nsDiskCacheStreamIO) + +// we pick 16k as the max buffer size because that is the threshold above which +// we are unable to store the data in the cache block files +// see nsDiskCacheMap.[cpp,h] +#define kMaxBufferSize (16 * 1024) nsDiskCacheStreamIO::nsDiskCacheStreamIO(nsDiskCacheBinding * binding) : mBinding(binding) + , mOutStream(nullptr) , mInStreamCount(0) , mFD(nullptr) , mStreamPos(0) @@ -195,7 +332,6 @@ nsDiskCacheStreamIO::nsDiskCacheStreamIO(nsDiskCacheBinding * binding) , mBufEnd(0) , mBufSize(0) , mBufDirty(false) - , mOutputStreamIsOpen(false) , mBuffer(nullptr) { mDevice = (nsDiskCacheDevice *)mBinding->mCacheEntry->CacheDevice(); @@ -208,16 +344,7 @@ nsDiskCacheStreamIO::nsDiskCacheStreamIO(nsDiskCacheBinding * binding) nsDiskCacheStreamIO::~nsDiskCacheStreamIO() { - if (mOutputStreamIsOpen) { - nsCacheService::AssertOwnsLock(); - CloseInternal(); - } - - NS_ASSERTION(!mOutputStreamIsOpen, "output stream still open"); - NS_ASSERTION(mInStreamCount == 0, "input stream still open"); - NS_ASSERTION(!mFD, "file descriptor not closed"); - - DeleteBuffer(); + Close(); // release "death grip" on cache service nsCacheService *service = nsCacheService::GlobalInstance(); @@ -225,38 +352,18 @@ nsDiskCacheStreamIO::~nsDiskCacheStreamIO() } -NS_IMETHODIMP -nsDiskCacheStreamIO::WriteFrom(nsIInputStream *inStream, uint32_t count, uint32_t *bytesWritten) -{ - NS_NOTREACHED("WriteFrom"); - return NS_ERROR_NOT_IMPLEMENTED; -} - - -NS_IMETHODIMP -nsDiskCacheStreamIO::WriteSegments(nsReadSegmentFun reader, - void * closure, - uint32_t count, - uint32_t * bytesWritten) -{ - NS_NOTREACHED("WriteSegments"); - return NS_ERROR_NOT_IMPLEMENTED; -} - - -NS_IMETHODIMP -nsDiskCacheStreamIO::IsNonBlocking(bool * nonBlocking) -{ - *nonBlocking = false; - return NS_OK; -} - - -NS_IMETHODIMP +void nsDiskCacheStreamIO::Close() { - nsCacheServiceAutoLock lock(LOCK_TELEM(NSDISKCACHESTREAMIO_CLOSEOUTPUTSTREAM)); - return CloseInternal(); + // this should only be called from our destructor + // no one is interested in us anymore, so we don't need to grab any locks + + // assert streams closed + NS_ASSERTION(!mOutStream, "output stream still open"); + NS_ASSERTION(mInStreamCount == 0, "input stream still open"); + NS_ASSERTION(!mFD, "file descriptor not closed"); + + DeleteBuffer(); } @@ -271,8 +378,8 @@ nsDiskCacheStreamIO::GetInputStream(uint32_t offset, nsIInputStream ** inputStre if (!mBinding) return NS_ERROR_NOT_AVAILABLE; - if (mOutputStreamIsOpen) { - NS_WARNING("already have the output stream open"); + if (mOutStream) { + NS_WARNING("already have an output stream open"); return NS_ERROR_NOT_AVAILABLE; } @@ -316,10 +423,10 @@ nsDiskCacheStreamIO::GetOutputStream(uint32_t offset, nsIOutputStream ** outputS *outputStream = nullptr; if (!mBinding) return NS_ERROR_NOT_AVAILABLE; - - NS_ASSERTION(!mOutputStreamIsOpen, "already have the output stream open"); + + NS_ASSERTION(!mOutStream, "already have an output stream open"); NS_ASSERTION(mInStreamCount == 0, "we already have input streams open"); - if (mOutputStreamIsOpen || mInStreamCount) return NS_ERROR_NOT_AVAILABLE; + if (mOutStream || mInStreamCount) return NS_ERROR_NOT_AVAILABLE; // mBuffer lazily allocated, but might exist if a previous stream already // created one. @@ -327,97 +434,69 @@ nsDiskCacheStreamIO::GetOutputStream(uint32_t offset, nsIOutputStream ** outputS mStreamPos = 0; mStreamEnd = mBinding->mCacheEntry->DataSize(); - if (offset > mStreamEnd) { - NS_WARNING("seek offset out of range"); - return NS_ERROR_INVALID_ARG; - } - nsresult rv; - // Seek and truncate at the desired offset - if (mBinding->mRecord.DataLocationInitialized() && - (mBinding->mRecord.DataFile() == 0)) { - // File storage, seek in file - rv = OpenCacheFile(PR_WRONLY | PR_CREATE_FILE, &mFD); - NS_ENSURE_SUCCESS(rv, rv); - if (offset) { - int32_t newPos = PR_Seek(mFD, offset, PR_SEEK_SET); - if (newPos == -1) { - return NS_ErrorAccordingToNSPR(); - } - } - - // Truncate at start position (offset) - rv = nsDiskCache::Truncate(mFD, offset); - NS_ENSURE_SUCCESS(rv, rv); - - mStreamPos = mStreamEnd = offset; - UpdateFileSize(); - } else if (offset) { - // else, read and seek in mBuffer - rv = ReadCacheBlocks(); - NS_ENSURE_SUCCESS(rv, rv); - - // Start writing at the provided offset - mBufEnd = mBufPos = offset; - mStreamPos = mStreamEnd = offset; + if (offset) { + rv = Seek(PR_SEEK_SET, offset); + if (NS_FAILED(rv)) return rv; } + rv = SetEOF(); + if (NS_FAILED(rv)) return rv; - mOutputStreamIsOpen = true; - // return myself as the output stream - NS_ADDREF(*outputStream = this); + // create a new output stream + mOutStream = new nsDiskCacheOutputStream(this); + if (!mOutStream) return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(*outputStream = mOutStream); return NS_OK; } - nsresult nsDiskCacheStreamIO::ClearBinding() { nsresult rv = NS_OK; - if (mBinding && mOutputStreamIsOpen) + if (mBinding && mOutStream) rv = Flush(); mBinding = nullptr; return rv; } - -NS_IMETHODIMP -nsDiskCacheStreamIO::CloseInternal() +nsresult +nsDiskCacheStreamIO::CloseOutputStream(nsDiskCacheOutputStream * outputStream) { - mozilla::TimeStamp start = mozilla::TimeStamp::Now(); - - if (mOutputStreamIsOpen) { - if (!mBinding) { // if we're severed, just clear member variables - NS_ASSERTION(!mBufDirty, "oops"); - } else { - nsresult rv = Flush(); - NS_ENSURE_SUCCESS(rv, rv); - } - mOutputStreamIsOpen = PR_FALSE; - } - - // Make sure to always close the FileDescriptor - if (mFD) { - (void) PR_Close(mFD); - mFD = nullptr; - } - - mozilla::Telemetry::ID id; - if (NS_IsMainThread()) - id = mozilla::Telemetry::NETWORK_DISK_CACHE_OUTPUT_STREAM_CLOSE_INTERNAL_MAIN_THREAD; - else - id = mozilla::Telemetry::NETWORK_DISK_CACHE_OUTPUT_STREAM_CLOSE_INTERNAL; - - mozilla::Telemetry::AccumulateTimeDelta(id, start); - - return NS_OK; + nsCacheServiceAutoLock lock(LOCK_TELEM(NSDISKCACHESTREAMIO_CLOSEOUTPUTSTREAM)); // grab service lock + return CloseOutputStreamInternal(outputStream); } +nsresult +nsDiskCacheStreamIO::CloseOutputStreamInternal( + nsDiskCacheOutputStream * outputStream) +{ + nsresult rv; -NS_IMETHODIMP + if (outputStream != mOutStream) { + NS_WARNING("mismatched output streams"); + return NS_ERROR_UNEXPECTED; + } + + // output stream is closing + if (!mBinding) { // if we're severed, just clear member variables + NS_ASSERTION(!mBufDirty, "oops"); + mOutStream = nullptr; + outputStream->ReleaseStreamIO(); + return NS_ERROR_NOT_AVAILABLE; + } + + rv = Flush(); + if (NS_FAILED(rv)) + NS_WARNING("Flush() failed"); + + mOutStream = nullptr; + return rv; +} + +nsresult nsDiskCacheStreamIO::Flush() { - if (!mOutputStreamIsOpen) return NS_BASE_STREAM_CLOSED; - NS_ASSERTION(mBinding, "oops"); CACHE_LOG_DEBUG(("CACHE: Flush [%x doomed=%u]\n", @@ -514,15 +593,12 @@ nsDiskCacheStreamIO::Flush() // never have both output and input streams open // OnDataSizeChanged() will have already been called to update entry->DataSize() -NS_IMETHODIMP +nsresult nsDiskCacheStreamIO::Write( const char * buffer, uint32_t count, uint32_t * bytesWritten) { - if (!mOutputStreamIsOpen) { - return NS_BASE_STREAM_CLOSED; - } - + nsresult rv = NS_OK; nsCacheServiceAutoLock lock(LOCK_TELEM(NSDISKCACHESTREAMIO_WRITE)); // grab service lock if (!mBinding) return NS_ERROR_NOT_AVAILABLE; @@ -589,7 +665,7 @@ nsDiskCacheStreamIO::Write( const char * buffer, } } - return NS_OK; + return rv; } @@ -698,7 +774,7 @@ nsDiskCacheStreamIO::FlushBufferToFile() record->SetDataFileGeneration(mBinding->mGeneration); // allocate file - rv = OpenCacheFile(PR_WRONLY | PR_CREATE_FILE, &mFD); + rv = OpenCacheFile(PR_RDWR | PR_CREATE_FILE, &mFD); if (NS_FAILED(rv)) return rv; int64_t dataSize = mBinding->mCacheEntry->PredictedDataSize(); @@ -746,3 +822,158 @@ nsDiskCacheStreamIO::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) return usage; } + +// NOTE: called with service lock held +nsresult +nsDiskCacheStreamIO::Seek(int32_t whence, int32_t offset) +{ + int32_t newPos; + if (!mBinding) return NS_ERROR_NOT_AVAILABLE; + + if (uint32_t(offset) > mStreamEnd) return NS_ERROR_FAILURE; + + if (mBinding->mRecord.DataLocationInitialized()) { + if (mBinding->mRecord.DataFile() == 0) { + if (!mFD) { + // we need an mFD, we better open it now + nsresult rv = OpenCacheFile(PR_RDWR | PR_CREATE_FILE, &mFD); + if (NS_FAILED(rv)) return rv; + } + } + } + + if (mFD) { + // do we have data in the buffer that needs to be flushed? + if (mBufDirty) { + // XXX optimization: are we just moving within the current buffer? + nsresult rv = FlushBufferToFile(); + if (NS_FAILED(rv)) return rv; + } + + newPos = PR_Seek(mFD, offset, (PRSeekWhence)whence); + if (newPos == -1) + return NS_ErrorAccordingToNSPR(); + + mStreamPos = (uint32_t) newPos; + mBufPos = 0; + mBufEnd = 0; + return NS_OK; + } + + // else, seek in mBuffer + + switch(whence) { + case PR_SEEK_SET: + newPos = offset; + break; + + case PR_SEEK_CUR: // relative from current posistion + newPos = offset + (uint32_t)mStreamPos; + break; + + case PR_SEEK_END: // relative from end + newPos = offset + (uint32_t)mBufEnd; + break; + + default: + return NS_ERROR_INVALID_ARG; + } + + // read data into mBuffer if not read yet. + if (mStreamEnd && !mBufEnd) { + if (newPos > 0) { + nsresult rv = ReadCacheBlocks(); + if (NS_FAILED(rv)) return rv; + } + } + + // stream buffer sanity checks + NS_ASSERTION(mBufEnd <= kMaxBufferSize, "bad stream"); + NS_ASSERTION(mBufPos <= mBufEnd, "bad stream"); + NS_ASSERTION(mStreamPos == mBufPos, "bad stream"); + NS_ASSERTION(mStreamEnd == mBufEnd, "bad stream"); + + if ((newPos < 0) || (uint32_t(newPos) > mBufEnd)) { + NS_WARNING("seek offset out of range"); + return NS_ERROR_INVALID_ARG; + } + + mStreamPos = newPos; + mBufPos = newPos; + return NS_OK; +} + + +// called only from nsDiskCacheOutputStream::Tell +nsresult +nsDiskCacheStreamIO::Tell(uint32_t * result) +{ + NS_ENSURE_ARG_POINTER(result); + *result = mStreamPos; + return NS_OK; +} + + +// NOTE: called with service lock held +nsresult +nsDiskCacheStreamIO::SetEOF() +{ + nsresult rv; + bool needToCloseFD = false; + + NS_ASSERTION(mStreamPos <= mStreamEnd, "bad stream"); + if (!mBinding) return NS_ERROR_NOT_AVAILABLE; + + if (mBinding->mRecord.DataLocationInitialized()) { + if (mBinding->mRecord.DataFile() == 0) { + if (!mFD) { + // we need an mFD, we better open it now + rv = OpenCacheFile(PR_RDWR | PR_CREATE_FILE, &mFD); + if (NS_FAILED(rv)) return rv; + needToCloseFD = true; + } + } else { + // data in cache block files + if ((mStreamPos != 0) && (mStreamPos != mBufPos)) { + // only read data if there will be some left after truncation + rv = ReadCacheBlocks(); + if (NS_FAILED(rv)) return rv; + } + + // We need to make sure we reflect this change in Flush(). + // In particular, if mStreamPos is 0 and we never write to + // the buffer, we want the storage to be deleted. + mBufDirty = true; + } + } + + if (mFD) { + rv = nsDiskCache::Truncate(mFD, mStreamPos); +#ifdef DEBUG + uint32_t oldSizeK = (mStreamEnd + 0x03FF) >> 10; + NS_ASSERTION(mBinding->mRecord.DataFileSize() == oldSizeK, "bad disk cache entry size"); + } else { + // data stored in buffer. + NS_ASSERTION(mStreamEnd <= kMaxBufferSize, "buffer truncation inadequate"); + NS_ASSERTION(mBufPos == mStreamPos, "bad stream"); + NS_ASSERTION(mBuffer ? mBufEnd == mStreamEnd : true, "bad stream"); +#endif + } + + NS_ASSERTION(mStreamEnd == mBinding->mCacheEntry->DataSize(), "cache entry not updated"); + // we expect nsCacheEntryDescriptor::TransportWrapper::OpenOutputStream() + // to eventually update the cache entry + + mStreamEnd = mStreamPos; + mBufEnd = mBufPos; + + if (mFD) { + UpdateFileSize(); + if (needToCloseFD) { + (void) PR_Close(mFD); + mFD = nullptr; + } + } + + return NS_OK; +} diff --git a/netwerk/cache/nsDiskCacheStreams.h b/netwerk/cache/nsDiskCacheStreams.h index 995aa963dec9..821134f52566 100644 --- a/netwerk/cache/nsDiskCacheStreams.h +++ b/netwerk/cache/nsDiskCacheStreams.h @@ -14,25 +14,30 @@ #include "nsIInputStream.h" #include "nsIOutputStream.h" -#include "nsIDiskCacheStreamInternal.h" #include "pratom.h" class nsDiskCacheInputStream; +class nsDiskCacheOutputStream; class nsDiskCacheDevice; -class nsDiskCacheStreamIO : public nsIOutputStream, nsIDiskCacheStreamInternal { +class nsDiskCacheStreamIO : public nsISupports { public: nsDiskCacheStreamIO(nsDiskCacheBinding * binding); virtual ~nsDiskCacheStreamIO(); NS_DECL_ISUPPORTS - NS_DECL_NSIOUTPUTSTREAM - NS_DECL_NSIDISKCACHESTREAMINTERNAL nsresult GetInputStream(uint32_t offset, nsIInputStream ** inputStream); nsresult GetOutputStream(uint32_t offset, nsIOutputStream ** outputStream); + nsresult CloseOutputStream(nsDiskCacheOutputStream * outputStream); + nsresult CloseOutputStreamInternal(nsDiskCacheOutputStream * outputStream); + + nsresult Write( const char * buffer, + uint32_t count, + uint32_t * bytesWritten); + nsresult Seek(int32_t whence, int32_t offset); nsresult Tell(uint32_t * position); nsresult SetEOF(); @@ -52,14 +57,19 @@ public: // and OS/2 requires that it not be private nsDiskCacheStreamIO() { NS_NOTREACHED("oops"); } private: + + + void Close(); nsresult OpenCacheFile(int flags, PRFileDesc ** fd); nsresult ReadCacheBlocks(); nsresult FlushBufferToFile(); void UpdateFileSize(); void DeleteBuffer(); + nsresult Flush(); nsDiskCacheBinding * mBinding; // not an owning reference nsDiskCacheDevice * mDevice; + nsDiskCacheOutputStream * mOutStream; // not an owning reference int32_t mInStreamCount; nsCOMPtr mLocalFile; PRFileDesc * mFD; @@ -69,8 +79,7 @@ private: uint32_t mBufPos; // current mark in buffer uint32_t mBufEnd; // current end of data in buffer uint32_t mBufSize; // current end of buffer - bool mBufDirty; // Where there is unflushed data in the buffer - bool mOutputStreamIsOpen; // Whether the output stream is open (for writing...) + bool mBufDirty; char * mBuffer; }; diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index f80ee68bbca9..dd2c779d12e3 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -1635,6 +1635,18 @@ "n_buckets": 10, "description": "Total Time spent (ms) during disk cache revalidation" }, + "NETWORK_DISK_CACHE_OUTPUT_STREAM_CLOSE": { + "kind": "exponential", + "high": "10000", + "n_buckets": 10, + "description": "Time spent in nsDiskCacheOutputStream::Close() on non-main thread (ms)" + }, + "NETWORK_DISK_CACHE_OUTPUT_STREAM_CLOSE_MAIN_THREAD": { + "kind": "exponential", + "high": "10000", + "n_buckets": 10, + "description": "Time spent in nsDiskCacheOutputStream::Close() on the main thread (ms)" + }, "NETWORK_DISK_CACHE_OUTPUT_STREAM_CLOSE_INTERNAL": { "kind": "exponential", "high": "10000", From bd0b0e8af14d0d00891185e600317fac7edf449b Mon Sep 17 00:00:00 2001 From: Rob Wood Date: Tue, 6 Nov 2012 20:19:02 -0500 Subject: [PATCH 21/57] Bug 808106 - Develop tests to verify filtering SMS messages by date, update manifest; r=jgriffin --- dom/sms/tests/marionette/manifest.ini | 2 + dom/sms/tests/marionette/test_filter_date.js | 198 ++++++++++++++++++ .../marionette/test_filter_date_notfound.js | 179 ++++++++++++++++ 3 files changed, 379 insertions(+) create mode 100644 dom/sms/tests/marionette/test_filter_date.js create mode 100644 dom/sms/tests/marionette/test_filter_date_notfound.js diff --git a/dom/sms/tests/marionette/manifest.ini b/dom/sms/tests/marionette/manifest.ini index b01d59c2a534..63529d449d40 100644 --- a/dom/sms/tests/marionette/manifest.ini +++ b/dom/sms/tests/marionette/manifest.ini @@ -11,6 +11,8 @@ qemu = true [test_outgoing_delete.js] [test_getmessage.js] [test_getmessage_notfound.js] +[test_filter_date.js] +[test_filter_date_notfound.js] [test_filter_number_single.js] [test_filter_number_multiple.js] [test_filter_received.js] diff --git a/dom/sms/tests/marionette/test_filter_date.js b/dom/sms/tests/marionette/test_filter_date.js new file mode 100644 index 000000000000..4102a5da86dd --- /dev/null +++ b/dom/sms/tests/marionette/test_filter_date.js @@ -0,0 +1,198 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +MARIONETTE_TIMEOUT = 20000; + +SpecialPowers.addPermission("sms", true, document); +SpecialPowers.setBoolPref("dom.sms.enabled", true); + +let sms = window.navigator.mozSms; +let numberMsgs = 10; +let smsList = new Array(); + +function verifyInitialState() { + log("Verifying initial state."); + ok(sms, "mozSms"); + // Ensure test is starting clean with no existing sms messages + deleteAllMsgs(simulateIncomingSms); +} + +function deleteAllMsgs(nextFunction) { + let msgList = new Array(); + let filter = new MozSmsFilter; + + let request = sms.getMessages(filter, false); + ok(request instanceof MozSmsRequest, + "request is instanceof " + request.constructor); + + request.onsuccess = function(event) { + ok(event.target.result, "smsrequest event.target.result"); + cursor = event.target.result; + // Check if message was found + if (cursor.message) { + msgList.push(cursor.message.id); + // Now get next message in the list + cursor.continue(); + } else { + // No (more) messages found + if (msgList.length) { + log("Found " + msgList.length + " SMS messages to delete."); + deleteMsgs(msgList, nextFunction); + } else { + log("No SMS messages found."); + nextFunction(); + } + } + }; + + request.onerror = function(event) { + log("Received 'onerror' smsrequest event."); + ok(event.target.error, "domerror obj"); + log("sms.getMessages error: " + event.target.error.name); + ok(false,"Could not get SMS messages"); + cleanUp(); + }; +} + +function deleteMsgs(msgList, nextFunction) { + let smsId = msgList.shift(); + + log("Deleting SMS (id: " + smsId + ")."); + let request = sms.delete(smsId); + ok(request instanceof MozSmsRequest, + "request is instanceof " + request.constructor); + + request.onsuccess = function(event) { + log("Received 'onsuccess' smsrequest event."); + if (event.target.result) { + // Message deleted, continue until none are left + if (msgList.length) { + deleteMsgs(msgList, nextFunction); + } else { + log("Finished deleting SMS messages."); + nextFunction(); + } + } else { + log("SMS delete failed."); + ok(false,"sms.delete request returned false"); + cleanUp(); + } + }; + + request.onerror = function(event) { + log("Received 'onerror' smsrequest event."); + ok(event.target.error, "domerror obj"); + ok(false, "sms.delete request returned unexpected error: " + + event.target.error.name ); + cleanUp(); + }; +} + +function simulateIncomingSms() { + let text = "Incoming SMS number " + (smsList.length + 1); + let remoteNumber = "5552229797"; + + log("Simulating incoming SMS number " + (smsList.length + 1) + " of " + + numberMsgs + "."); + + // Simulate incoming sms sent from remoteNumber to our emulator + rcvdEmulatorCallback = false; + runEmulatorCmd("sms send " + remoteNumber + " " + text, function(result) { + is(result[0], "OK", "emulator callback"); + rcvdEmulatorCallback = true; + }); +} + +// Callback for incoming sms +sms.onreceived = function onreceived(event) { + log("Received 'onreceived' sms event."); + let incomingSms = event.message; + log("Received SMS (id: " + incomingSms.id + ")."); + + smsList.push(incomingSms); + + // Wait for emulator to catch up before continuing + waitFor(nextRep,function() { + return(rcvdEmulatorCallback); + }); +}; + +function nextRep() { + if (smsList.length < numberMsgs) { + simulateIncomingSms(); + } else { + // Now test the filter + getMsgs(); + } +} + +function getMsgs() { + var filter = new MozSmsFilter(); + let foundSmsList = new Array(); + + // Set filter for start date yesterday and end date tomorrow + let yesterday = new Date(Date.now() - 86400000); // 24 hours = 86400000 ms + let tomorrow = new Date(Date.now() + 86400000); + filter.startDate = yesterday; + filter.endDate = tomorrow; + + log("Getting SMS messages with dates between " + yesterday + " and " + + tomorrow +"."); + let request = sms.getMessages(filter, false); + ok(request instanceof MozSmsRequest, + "request is instanceof " + request.constructor); + + request.onsuccess = function(event) { + log("Received 'onsuccess' smsrequest event."); + ok(event.target.result, "smsrequest event.target.result"); + cursor = event.target.result; + + if (cursor.message) { + // Another message found + log("Got SMS (id: " + cursor.message.id + ")."); + // Store found message + foundSmsList.push(cursor.message); + // Now get next message in the list + cursor.continue(); + } else { + // No more messages; ensure correct number found + if (foundSmsList.length == smsList.length) { + log("SMS getMessages returned " + foundSmsList.length + + " messages as expected."); + verifyFoundMsgs(foundSmsList); + } else { + log("SMS getMessages returned " + foundSmsList.length + + " messages, but expected " + smsList.length + "."); + ok(false, "Incorrect number of messages returned by sms.getMessages"); + deleteAllMsgs(cleanUp); + } + } + }; + + request.onerror = function(event) { + log("Received 'onerror' smsrequest event."); + ok(event.target.error, "domerror obj"); + log("sms.getMessages error: " + event.target.error.name); + ok(false,"Could not get SMS messages"); + cleanUp(); + }; +} + +function verifyFoundMsgs(foundSmsList) { + for (var x = 0; x < foundSmsList.length; x++) { + is(foundSmsList[x].id, smsList[x].id, "id"); + is(foundSmsList[x].timestamp.getTime(), smsList[x].timestamp.getTime(), + "timestmap"); + } + deleteAllMsgs(cleanUp); +} + +function cleanUp() { + sms.onreceived = null; + SpecialPowers.removePermission("sms", document); + SpecialPowers.clearUserPref("dom.sms.enabled"); + finish(); +} + +// Start the test +verifyInitialState(); diff --git a/dom/sms/tests/marionette/test_filter_date_notfound.js b/dom/sms/tests/marionette/test_filter_date_notfound.js new file mode 100644 index 000000000000..3abd2931d7e7 --- /dev/null +++ b/dom/sms/tests/marionette/test_filter_date_notfound.js @@ -0,0 +1,179 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +MARIONETTE_TIMEOUT = 20000; + +SpecialPowers.addPermission("sms", true, document); +SpecialPowers.setBoolPref("dom.sms.enabled", true); + +let sms = window.navigator.mozSms; +let numberMsgs = 10; +let smsList = new Array(); + +function verifyInitialState() { + log("Verifying initial state."); + ok(sms, "mozSms"); + // Ensure test is starting clean with no existing sms messages + deleteAllMsgs(simulateIncomingSms); +} + +function deleteAllMsgs(nextFunction) { + let msgList = new Array(); + let filter = new MozSmsFilter; + + let request = sms.getMessages(filter, false); + ok(request instanceof MozSmsRequest, + "request is instanceof " + request.constructor); + + request.onsuccess = function(event) { + ok(event.target.result, "smsrequest event.target.result"); + cursor = event.target.result; + // Check if message was found + if (cursor.message) { + msgList.push(cursor.message.id); + // Now get next message in the list + cursor.continue(); + } else { + // No (more) messages found + if (msgList.length) { + log("Found " + msgList.length + " SMS messages to delete."); + deleteMsgs(msgList, nextFunction); + } else { + log("No SMS messages found."); + nextFunction(); + } + } + }; + + request.onerror = function(event) { + log("Received 'onerror' smsrequest event."); + ok(event.target.error, "domerror obj"); + log("sms.getMessages error: " + event.target.error.name); + ok(false,"Could not get SMS messages"); + cleanUp(); + }; +} + +function deleteMsgs(msgList, nextFunction) { + let smsId = msgList.shift(); + + log("Deleting SMS (id: " + smsId + ")."); + let request = sms.delete(smsId); + ok(request instanceof MozSmsRequest, + "request is instanceof " + request.constructor); + + request.onsuccess = function(event) { + log("Received 'onsuccess' smsrequest event."); + if (event.target.result) { + // Message deleted, continue until none are left + if (msgList.length) { + deleteMsgs(msgList, nextFunction); + } else { + log("Finished deleting SMS messages."); + nextFunction(); + } + } else { + log("SMS delete failed."); + ok(false,"sms.delete request returned false"); + cleanUp(); + } + }; + + request.onerror = function(event) { + log("Received 'onerror' smsrequest event."); + ok(event.target.error, "domerror obj"); + ok(false, "sms.delete request returned unexpected error: " + + event.target.error.name ); + cleanUp(); + }; +} + +function simulateIncomingSms() { + let text = "Incoming SMS number " + (smsList.length + 1); + let remoteNumber = "5552229797"; + + log("Simulating incoming SMS number " + (smsList.length + 1) + " of " + + numberMsgs + "."); + + // Simulate incoming sms sent from remoteNumber to our emulator + rcvdEmulatorCallback = false; + runEmulatorCmd("sms send " + remoteNumber + " " + text, function(result) { + is(result[0], "OK", "emulator callback"); + rcvdEmulatorCallback = true; + }); +} + +// Callback for incoming sms +sms.onreceived = function onreceived(event) { + log("Received 'onreceived' sms event."); + let incomingSms = event.message; + log("Received SMS (id: " + incomingSms.id + ")."); + + smsList.push(incomingSms); + + // Wait for emulator to catch up before continuing + waitFor(nextRep,function() { + return(rcvdEmulatorCallback); + }); +}; + +function nextRep() { + if (smsList.length < numberMsgs) { + simulateIncomingSms(); + } else { + // Now test the filter + getMsgs(); + } +} + +function getMsgs() { + var filter = new MozSmsFilter(); + let foundSmsList = new Array(); + + // Set filter for start date 2 days ago and end date yesterday (so 0 found) + let yesterday = new Date(Date.now() - 86400000); // 24 hours = 86400000 ms + let twoDaysAgo = new Date(Date.now() - 172800000); + filter.startDate = twoDaysAgo; + filter.endDate = yesterday; + + log("Getting SMS messages with dates between " + twoDaysAgo + " and " + + yesterday +"."); + let request = sms.getMessages(filter, false); + ok(request instanceof MozSmsRequest, + "request is instanceof " + request.constructor); + + request.onsuccess = function(event) { + log("Received 'onsuccess' smsrequest event."); + ok(event.target.result, "smsrequest event.target.result"); + cursor = event.target.result; + + if (cursor.message) { + // Another message found + log("Got SMS (id: " + cursor.message.id + ")."); + log("SMS getMessages returned a message but should not have."); + ok(false, "SMS date filter did not work"); + } else { + // No messages found as expected + log("SMS getMessages returned zero messages as expected."); + } + deleteAllMsgs(cleanUp); + }; + + request.onerror = function(event) { + log("Received 'onerror' smsrequest event."); + ok(event.target.error, "domerror obj"); + log("sms.getMessages error: " + event.target.error.name); + ok(false,"Could not get SMS messages"); + cleanUp(); + }; +} + +function cleanUp() { + sms.onreceived = null; + SpecialPowers.removePermission("sms", document); + SpecialPowers.clearUserPref("dom.sms.enabled"); + finish(); +} + +// Start the test +verifyInitialState(); From 095dc9e962e18c2b42ec05845b1685389c1c1005 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Mon, 19 Nov 2012 18:15:18 -0500 Subject: [PATCH 22/57] Backed out changeset f76720054116 (bug 813209) because of leaks --- content/media/MediaResource.cpp | 10 +++++----- content/media/MediaResource.h | 16 +++++----------- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/content/media/MediaResource.cpp b/content/media/MediaResource.cpp index 0fba8b0be9bf..0666b6afdc0c 100644 --- a/content/media/MediaResource.cpp +++ b/content/media/MediaResource.cpp @@ -49,7 +49,7 @@ namespace mozilla { ChannelMediaResource::ChannelMediaResource(MediaDecoder* aDecoder, nsIChannel* aChannel, nsIURI* aURI) - : BaseMediaResource(aDecoder, aChannel, aURI), + : MediaResource(aDecoder, aChannel, aURI), mOffset(0), mSuspendCount(0), mReopenOnError(false), mIgnoreClose(false), mCacheStream(this), @@ -1153,11 +1153,11 @@ ChannelMediaResource::PossiblyResume() } } -class FileMediaResource : public BaseMediaResource +class FileMediaResource : public MediaResource { public: FileMediaResource(MediaDecoder* aDecoder, nsIChannel* aChannel, nsIURI* aURI) : - BaseMediaResource(aDecoder, aChannel, aURI), + MediaResource(aDecoder, aChannel, aURI), mSize(-1), mLock("FileMediaResource.mLock"), mSizeInitialized(false) @@ -1514,7 +1514,7 @@ MediaResource::Create(MediaDecoder* aDecoder, nsIChannel* aChannel) return new ChannelMediaResource(aDecoder, aChannel, uri); } -void BaseMediaResource::MoveLoadsToBackground() { +void MediaResource::MoveLoadsToBackground() { NS_ASSERTION(!mLoadInBackground, "Why are you calling this more than once?"); mLoadInBackground = true; if (!mChannel) { @@ -1545,7 +1545,7 @@ void BaseMediaResource::MoveLoadsToBackground() { } } -void BaseMediaResource::ModifyLoadFlags(nsLoadFlags aFlags) +void MediaResource::ModifyLoadFlags(nsLoadFlags aFlags) { nsCOMPtr loadGroup; DebugOnly rv = mChannel->GetLoadGroup(getter_AddRefs(loadGroup)); diff --git a/content/media/MediaResource.h b/content/media/MediaResource.h index c391439aee23..81659ce70915 100644 --- a/content/media/MediaResource.h +++ b/content/media/MediaResource.h @@ -153,7 +153,7 @@ public: // The following can be called on the main thread only: // Get the URI - virtual nsIURI* URI() const { return nullptr; } + nsIURI* URI() const { return mURI; } // Close the resource, stop any listeners, channels, etc. // Cancels any currently blocking Read request and forces that request to // return an error. @@ -227,7 +227,7 @@ public: // Moves any existing channel loads into the background, so that they don't // block the load event. Any new loads initiated (for example to seek) // will also be in the background. - virtual void MoveLoadsToBackground() {} + void MoveLoadsToBackground(); // Ensures that the value returned by IsSuspendedByCache below is up to date // (i.e. the cache has examined this stream at least once). virtual void EnsureCacheUpToDate() {} @@ -307,21 +307,15 @@ public: * aRanges is being used. */ virtual nsresult GetCachedRanges(nsTArray& aRanges) = 0; -}; - -class BaseMediaResource : public MediaResource { -public: - virtual nsIURI* URI() const { return mURI; } - virtual void MoveLoadsToBackground(); protected: - BaseMediaResource(MediaDecoder* aDecoder, nsIChannel* aChannel, nsIURI* aURI) : + MediaResource(MediaDecoder* aDecoder, nsIChannel* aChannel, nsIURI* aURI) : mDecoder(aDecoder), mChannel(aChannel), mURI(aURI), mLoadInBackground(false) { - MOZ_COUNT_CTOR(BaseMediaResource); + MOZ_COUNT_CTOR(MediaResource); } // Set the request's load flags to aFlags. If the request is part of a @@ -355,7 +349,7 @@ protected: * All synchronization is performed by MediaCacheStream; all off-main- * thread operations are delegated directly to that object. */ -class ChannelMediaResource : public BaseMediaResource +class ChannelMediaResource : public MediaResource { public: ChannelMediaResource(MediaDecoder* aDecoder, nsIChannel* aChannel, nsIURI* aURI); From f3e9f0a56b029c112dab348b7e6dd15d365800d8 Mon Sep 17 00:00:00 2001 From: Mounir Lamouri Date: Mon, 19 Nov 2012 23:18:21 +0000 Subject: [PATCH 23/57] Bug 764240 - Clamp window.sizeToContent() the same way we clamp other resizing methods. r=bz --- docshell/base/nsIMarkupDocumentViewer.idl | 10 +-- dom/base/nsGlobalWindow.cpp | 24 +++++- dom/tests/mochitest/bugs/Makefile.in | 1 + .../bugs/test_sizetocontent_clamp.html | 73 +++++++++++++++++++ layout/base/nsDocumentViewer.cpp | 15 +--- testing/mochitest/android.json | 1 + xpfe/appshell/src/nsXULWindow.cpp | 14 +++- 7 files changed, 117 insertions(+), 21 deletions(-) create mode 100644 dom/tests/mochitest/bugs/test_sizetocontent_clamp.html diff --git a/docshell/base/nsIMarkupDocumentViewer.idl b/docshell/base/nsIMarkupDocumentViewer.idl index 92347f9b850f..ef40ddcb10fe 100644 --- a/docshell/base/nsIMarkupDocumentViewer.idl +++ b/docshell/base/nsIMarkupDocumentViewer.idl @@ -23,7 +23,7 @@ interface nsIMarkupDocumentViewer; [ref] native nsIMarkupDocumentViewerTArray(nsTArray >); -[scriptable, uuid(1016d5e8-690f-4d97-8ac5-d50ffa341c46)] +[scriptable, uuid(02d37b31-e654-4b74-9bc3-14dfe0020bb3)] interface nsIMarkupDocumentViewer : nsISupports { @@ -68,10 +68,10 @@ interface nsIMarkupDocumentViewer : nsISupports //void GetCharacterSetHint(in wstring hintCharset, in int32_t charsetSource); - /** - * Tell the container to shrink-to-fit or grow-to-fit its contents - */ - void sizeToContent(); + /** + * Requests the size of the content to the container. + */ + void getContentSize(out long width, out long height); /** * Options for Bidi presentation. diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 1ef77753d903..248aed05e298 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -5474,12 +5474,32 @@ nsGlobalWindow::SizeToContent() // The content viewer does a check to make sure that it's a content // viewer for a toplevel docshell. - nsCOMPtr cv; mDocShell->GetContentViewer(getter_AddRefs(cv)); nsCOMPtr markupViewer(do_QueryInterface(cv)); NS_ENSURE_TRUE(markupViewer, NS_ERROR_FAILURE); - NS_ENSURE_SUCCESS(markupViewer->SizeToContent(), NS_ERROR_FAILURE); + + int32_t width, height; + NS_ENSURE_SUCCESS(markupViewer->GetContentSize(&width, &height), + NS_ERROR_FAILURE); + + // Make sure the new size is following the CheckSecurityWidthAndHeight + // rules. + nsCOMPtr treeOwner; + GetTreeOwner(getter_AddRefs(treeOwner)); + NS_ENSURE_TRUE(treeOwner, NS_ERROR_FAILURE); + + nsIntSize cssSize(DevToCSSIntPixels(nsIntSize(width, height))); + NS_ENSURE_SUCCESS(CheckSecurityWidthAndHeight(&cssSize.width, + &cssSize.height), + NS_ERROR_FAILURE); + + nsIntSize newDevSize(CSSToDevIntPixels(cssSize)); + + nsCOMPtr docShellAsItem = do_QueryInterface(mDocShell); + NS_ENSURE_SUCCESS(treeOwner->SizeShellTo(docShellAsItem, + newDevSize.width, newDevSize.height), + NS_ERROR_FAILURE); return NS_OK; } diff --git a/dom/tests/mochitest/bugs/Makefile.in b/dom/tests/mochitest/bugs/Makefile.in index 57bcd60bf26b..571f69461501 100644 --- a/dom/tests/mochitest/bugs/Makefile.in +++ b/dom/tests/mochitest/bugs/Makefile.in @@ -135,6 +135,7 @@ MOCHITEST_FILES = \ file_bug809290_b2.html \ file_bug809290_c.html \ file_empty.html \ + test_sizetocontent_clamp.html \ $(NULL) ifneq (Linux,$(OS_ARCH)) diff --git a/dom/tests/mochitest/bugs/test_sizetocontent_clamp.html b/dom/tests/mochitest/bugs/test_sizetocontent_clamp.html new file mode 100644 index 000000000000..a060a9a029ce --- /dev/null +++ b/dom/tests/mochitest/bugs/test_sizetocontent_clamp.html @@ -0,0 +1,73 @@ + + + + + + Test for Bug 764240 + + + + + +Mozilla Bug 764240 +

+
+ +
+
+
+
+ + diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index 44b94566e57b..eec502c146c8 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -3260,7 +3260,8 @@ NS_IMETHODIMP DocumentViewerImpl::ChangeMaxLineBoxWidth(int32_t aMaxLineBoxWidth return NS_OK; } -NS_IMETHODIMP DocumentViewerImpl::SizeToContent() +NS_IMETHODIMP +DocumentViewerImpl::GetContentSize(int32_t* aWidth, int32_t* aHeight) { NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE); @@ -3301,23 +3302,15 @@ NS_IMETHODIMP DocumentViewerImpl::SizeToContent() GetPresContext(getter_AddRefs(presContext)); NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE); - int32_t width, height; - // so how big is it? nsRect shellArea = presContext->GetVisibleArea(); // Protect against bogus returns here NS_ENSURE_TRUE(shellArea.width != NS_UNCONSTRAINEDSIZE && shellArea.height != NS_UNCONSTRAINEDSIZE, NS_ERROR_FAILURE); - width = presContext->AppUnitsToDevPixels(shellArea.width); - height = presContext->AppUnitsToDevPixels(shellArea.height); - nsCOMPtr treeOwner; - docShellAsItem->GetTreeOwner(getter_AddRefs(treeOwner)); - NS_ENSURE_TRUE(treeOwner, NS_ERROR_FAILURE); - - NS_ENSURE_SUCCESS(treeOwner->SizeShellTo(docShellAsItem, width, height), - NS_ERROR_FAILURE); + *aWidth = presContext->AppUnitsToDevPixels(shellArea.width); + *aHeight = presContext->AppUnitsToDevPixels(shellArea.height); return NS_OK; } diff --git a/testing/mochitest/android.json b/testing/mochitest/android.json index f26d9b1918b3..f13fe3f0d488 100644 --- a/testing/mochitest/android.json +++ b/testing/mochitest/android.json @@ -180,6 +180,7 @@ "dom/tests/mochitest/bugs/test_bug641552.html": "", "dom/tests/mochitest/bugs/test_devicemotion_multiple_listeners.html": "bug 775227", "dom/tests/mochitest/bugs/test_resize_move_windows.html": "TIMED_OUT", + "dom/tests/mochitest/bugs/test_sizetocontent_clamp.html": "TIMED_OUT", "dom/tests/mochitest/bugs/test_window_bar.html": "", "dom/tests/mochitest/dom-level2-core/test_documentimportnode03.html": "", "dom/tests/mochitest/dom-level2-core/test_documentimportnode04.html": "", diff --git a/xpfe/appshell/src/nsXULWindow.cpp b/xpfe/appshell/src/nsXULWindow.cpp index 276d02dbdb6c..bcb258df2fc9 100644 --- a/xpfe/appshell/src/nsXULWindow.cpp +++ b/xpfe/appshell/src/nsXULWindow.cpp @@ -975,9 +975,17 @@ void nsXULWindow::OnChromeLoaded() // (if LoadSizeFromXUL set the size, mIntrinsicallySized will be false) nsCOMPtr cv; mDocShell->GetContentViewer(getter_AddRefs(cv)); - nsCOMPtr markupViewer(do_QueryInterface(cv)); - if (markupViewer) - markupViewer->SizeToContent(); + nsCOMPtr markupViewer = do_QueryInterface(cv); + if (markupViewer) { + nsCOMPtr docShellAsItem = do_QueryInterface(mDocShell); + nsCOMPtr treeOwner; + docShellAsItem->GetTreeOwner(getter_AddRefs(treeOwner)); + if (treeOwner) { + int32_t width, height; + markupViewer->GetContentSize(&width, &height); + treeOwner->SizeShellTo(docShellAsItem, width, height); + } + } } bool positionSet = !mIgnoreXULPosition; From dd15d96b6d7baad27086288f3580dd133c60cca7 Mon Sep 17 00:00:00 2001 From: Benoit Girard Date: Mon, 19 Nov 2012 18:13:28 -0500 Subject: [PATCH 24/57] Bug 809317 - Part 1: Provide a pseudo stack implementation of SAMPLER_PRINT_LOCATION. r=ehsan --HG-- extra : rebase_source : ba956341ba6115f5c0f60a067c46aee45d29724b --- tools/profiler/TableTicker.cpp | 59 ++++++++++++++++++++++++++++++++-- tools/profiler/sampler.h | 3 ++ tools/profiler/sps_sampler.h | 4 +++ 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/tools/profiler/TableTicker.cpp b/tools/profiler/TableTicker.cpp index 79adfc0ffd42..4684e0b85f7d 100644 --- a/tools/profiler/TableTicker.cpp +++ b/tools/profiler/TableTicker.cpp @@ -143,8 +143,6 @@ public: friend std::ostream& operator<<(std::ostream& stream, const ProfileEntry& entry); -private: - friend class ThreadProfile; union { const char* mTagData; char mTagChars[sizeof(void*)]; @@ -157,6 +155,8 @@ private: char mTagName; }; +typedef void (*IterateTagsCallback)(const ProfileEntry& entry, const char* tagStringData); + #define PROFILE_MAX_ENTRY 100000 class ThreadProfile { @@ -280,6 +280,33 @@ public: friend std::ostream& operator<<(std::ostream& stream, const ThreadProfile& profile); + void IterateTags(IterateTagsCallback aCallback) + { + MOZ_ASSERT(aCallback); + + int readPos = mReadPos; + while (readPos != mLastFlushPos) { + // Number of tag consumed + int incBy = 1; + const ProfileEntry& entry = mEntries[readPos]; + + // Read ahead to the next tag, if it's a 'd' tag process it now + const char* tagStringData = entry.mTagData; + int readAheadPos = (readPos + 1) % mEntrySize; + char tagBuff[DYNAMIC_MAX_STRING]; + // Make sure the string is always null terminated if it fills up DYNAMIC_MAX_STRING-2 + tagBuff[DYNAMIC_MAX_STRING-1] = '\0'; + + if (readAheadPos != mLastFlushPos && mEntries[readAheadPos].mTagName == 'd') { + tagStringData = processDynamicTag(readPos, &incBy, tagBuff); + } + + aCallback(entry, tagStringData); + + readPos = (readPos + incBy) % mEntrySize; + } + } + JSObject *ToJSObject(JSContext *aCx) { JSObjectBuilder b(aCx); @@ -1193,3 +1220,31 @@ void mozilla_sampler_frame_number(int frameNumber) { sFrameNumber = frameNumber; } + +void print_callback(const ProfileEntry& entry, const char* tagStringData) { + switch (entry.mTagName) { + case 's': + case 'c': + printf_stderr(" %s\n", tagStringData); + } +} + +void mozilla_sampler_print_location() +{ + if (!stack_key_initialized) + mozilla_sampler_init(); + + ProfileStack *stack = tlsStack.get(); + if (!stack) { + MOZ_ASSERT(false); + return; + } + + ThreadProfile threadProfile(1000, stack); + doSampleStackTrace(stack, threadProfile, NULL); + + threadProfile.flush(); + + printf_stderr("Backtrace:\n"); + threadProfile.IterateTags(print_callback); +} diff --git a/tools/profiler/sampler.h b/tools/profiler/sampler.h index d20aacd13e1b..5e7193a98823 100644 --- a/tools/profiler/sampler.h +++ b/tools/profiler/sampler.h @@ -80,6 +80,9 @@ #define SAMPLE_LABEL_FN(name_space, info) #define SAMPLE_MARKER(info) +// Tracing features +#define SAMPLER_PRINT_LOCATION() + #endif #endif // ifndef SAMPLER_H diff --git a/tools/profiler/sps_sampler.h b/tools/profiler/sps_sampler.h index 8c38d65c4d90..e5c7a3abdf9b 100644 --- a/tools/profiler/sps_sampler.h +++ b/tools/profiler/sps_sampler.h @@ -64,6 +64,8 @@ extern bool stack_key_initialized; #define SAMPLE_LABEL_PRINTF(name_space, info, ...) mozilla::SamplerStackFramePrintfRAII SAMPLER_APPEND_LINE_NUMBER(sampler_raii)(name_space "::" info, __LINE__, __VA_ARGS__) #define SAMPLE_MARKER(info) mozilla_sampler_add_marker(info) +#define SAMPLER_PRINT_LOCATION() mozilla_sampler_print_location() + /* we duplicate this code here to avoid header dependencies * which make it more difficult to include in other places */ #if defined(_M_X64) || defined(__x86_64__) @@ -171,6 +173,8 @@ JSObject *mozilla_sampler_get_profile_data(JSContext *aCx); const char** mozilla_sampler_get_features(); void mozilla_sampler_init(); +void mozilla_sampler_print_location(); + namespace mozilla { class NS_STACK_CLASS SamplerStackFrameRAII { From 3803556ae57c31423a3e9c93942de8d17d629c2b Mon Sep 17 00:00:00 2001 From: Trevor Saunders Date: Sun, 14 Oct 2012 17:28:32 -0400 Subject: [PATCH 25/57] bug 779520 - merge Accessible::Init() into constructors patch=fxa90id r=surkov, tbsaunde --- .../src/atk/ApplicationAccessibleWrap.cpp | 88 +++++++------- .../src/atk/ApplicationAccessibleWrap.h | 3 - accessible/src/base/nsAccDocManager.cpp | 3 +- .../src/base/nsAccessibilityService.cpp | 1 - accessible/src/generic/Accessible.cpp | 5 - accessible/src/generic/Accessible.h | 5 - .../src/generic/ApplicationAccessible.cpp | 7 +- .../src/generic/ApplicationAccessible.h | 1 - accessible/src/generic/DocAccessible.cpp | 110 +++++++----------- accessible/src/generic/DocAccessible.h | 2 - accessible/src/generic/RootAccessible.cpp | 107 ++++++++--------- accessible/src/generic/RootAccessible.h | 3 +- accessible/src/xul/XULTreeAccessible.cpp | 8 +- accessible/src/xul/XULTreeAccessible.h | 1 - accessible/src/xul/XULTreeGridAccessible.cpp | 27 ++--- accessible/src/xul/XULTreeGridAccessible.h | 3 - 16 files changed, 148 insertions(+), 226 deletions(-) diff --git a/accessible/src/atk/ApplicationAccessibleWrap.cpp b/accessible/src/atk/ApplicationAccessibleWrap.cpp index 51503156a2bf..f4c272057e30 100644 --- a/accessible/src/atk/ApplicationAccessibleWrap.cpp +++ b/accessible/src/atk/ApplicationAccessibleWrap.cpp @@ -511,12 +511,54 @@ add_listener (GSignalEmissionHook listener, static nsresult LoadGtkModule(GnomeAccessibilityModule& aModule); +static gboolean toplevel_event_watcher(GSignalInvocationHint*, guint, + const GValue*, gpointer); + // ApplicationAccessibleWrap ApplicationAccessibleWrap::ApplicationAccessibleWrap(): ApplicationAccessible() { MAI_LOG_DEBUG(("======Create AppRootAcc=%p\n", (void*)this)); + + if (ShouldA11yBeEnabled()) { + // Load and initialize gail library. + nsresult rv = LoadGtkModule(sGail); + if (NS_SUCCEEDED(rv)) { + (*sGail.init)(); + } else { + MAI_LOG_DEBUG(("Fail to load lib: %s\n", sGail.libName)); + } + + MAI_LOG_DEBUG(("Mozilla Atk Implementation initializing\n")); + + // Initialize the MAI Utility class, it will overwrite gail_util. + g_type_class_unref(g_type_class_ref(MAI_TYPE_UTIL)); + + // Init atk-bridge now + PR_SetEnv("NO_AT_BRIDGE=0"); + + // load and initialize atk-bridge library + rv = LoadGtkModule(sAtkBridge); + if (NS_SUCCEEDED(rv)) { + (*sAtkBridge.init)(); + } else { + MAI_LOG_DEBUG(("Fail to load lib: %s\n", sAtkBridge.libName)); + } + + if (!sToplevel_event_hook_added) { + sToplevel_event_hook_added = true; + sToplevel_show_hook = + g_signal_add_emission_hook(g_signal_lookup("show", GTK_TYPE_WINDOW), + 0, toplevel_event_watcher, + reinterpret_cast(nsIAccessibleEvent::EVENT_SHOW), NULL); + sToplevel_hide_hook = + g_signal_add_emission_hook(g_signal_lookup("hide", GTK_TYPE_WINDOW), + 0, toplevel_event_watcher, + reinterpret_cast(nsIAccessibleEvent::EVENT_HIDE), NULL); + } + } + } ApplicationAccessibleWrap::~ApplicationAccessibleWrap() @@ -573,52 +615,6 @@ toplevel_event_watcher(GSignalInvocationHint* ihint, return TRUE; } -void -ApplicationAccessibleWrap::Init() -{ - if (ShouldA11yBeEnabled()) { - // load and initialize gail library - nsresult rv = LoadGtkModule(sGail); - if (NS_SUCCEEDED(rv)) { - (*sGail.init)(); - } - else { - MAI_LOG_DEBUG(("Fail to load lib: %s\n", sGail.libName)); - } - - MAI_LOG_DEBUG(("Mozilla Atk Implementation initializing\n")); - // Initialize the MAI Utility class - // it will overwrite gail_util - g_type_class_unref(g_type_class_ref(MAI_TYPE_UTIL)); - - // Init atk-bridge now - PR_SetEnv("NO_AT_BRIDGE=0"); - - // load and initialize atk-bridge library - rv = LoadGtkModule(sAtkBridge); - if (NS_SUCCEEDED(rv)) { - // init atk-bridge - (*sAtkBridge.init)(); - } else { - MAI_LOG_DEBUG(("Fail to load lib: %s\n", sAtkBridge.libName)); - } - - if (!sToplevel_event_hook_added) { - sToplevel_event_hook_added = true; - sToplevel_show_hook = - g_signal_add_emission_hook(g_signal_lookup("show", GTK_TYPE_WINDOW), - 0, toplevel_event_watcher, - reinterpret_cast(nsIAccessibleEvent::EVENT_SHOW), NULL); - sToplevel_hide_hook = - g_signal_add_emission_hook(g_signal_lookup("hide", GTK_TYPE_WINDOW), - 0, toplevel_event_watcher, - reinterpret_cast(nsIAccessibleEvent::EVENT_HIDE), NULL); - } - } - - ApplicationAccessible::Init(); -} - void ApplicationAccessibleWrap::Unload() { diff --git a/accessible/src/atk/ApplicationAccessibleWrap.h b/accessible/src/atk/ApplicationAccessibleWrap.h index 51b15b1cfa46..b4354306dcff 100644 --- a/accessible/src/atk/ApplicationAccessibleWrap.h +++ b/accessible/src/atk/ApplicationAccessibleWrap.h @@ -22,9 +22,6 @@ public: ApplicationAccessibleWrap(); virtual ~ApplicationAccessibleWrap(); - // nsAccessNode - virtual void Init(); - // Accessible virtual mozilla::a11y::ENameValueFlag Name(nsString& aName); virtual bool AppendChild(Accessible* aChild); diff --git a/accessible/src/base/nsAccDocManager.cpp b/accessible/src/base/nsAccDocManager.cpp index cbbbc18200b7..aa5e98ab711b 100644 --- a/accessible/src/base/nsAccDocManager.cpp +++ b/accessible/src/base/nsAccDocManager.cpp @@ -383,8 +383,7 @@ nsAccDocManager::CreateDocOrRootAccessible(nsIDocument* aDocument) // Cache the document accessible into document cache. mDocAccessibleCache.Put(aDocument, docAcc); - // Initialize the document accessible. - docAcc->Init(); + // Set role map entry of document accessible. docAcc->SetRoleMapEntry(aria::GetRoleMap(aDocument)); // Bind the document to the tree. diff --git a/accessible/src/base/nsAccessibilityService.cpp b/accessible/src/base/nsAccessibilityService.cpp index 5a562217a34f..cbbee0b66fd6 100644 --- a/accessible/src/base/nsAccessibilityService.cpp +++ b/accessible/src/base/nsAccessibilityService.cpp @@ -997,7 +997,6 @@ nsAccessibilityService::Init() ApplicationAccessibleWrap::PreCreate(); gApplicationAccessible = new ApplicationAccessibleWrap(); NS_ADDREF(gApplicationAccessible); // will release in Shutdown() - gApplicationAccessible->Init(); // Initialize accessibility. nsAccessNodeWrap::InitAccessibility(); diff --git a/accessible/src/generic/Accessible.cpp b/accessible/src/generic/Accessible.cpp index bf6519284b6a..27eba376376f 100644 --- a/accessible/src/generic/Accessible.cpp +++ b/accessible/src/generic/Accessible.cpp @@ -190,11 +190,6 @@ Accessible::~Accessible() { } -void -Accessible::Init() -{ -} - NS_IMETHODIMP Accessible::GetDocument(nsIAccessibleDocument** aDocument) { diff --git a/accessible/src/generic/Accessible.h b/accessible/src/generic/Accessible.h index d1a286302239..61e3bd4297c8 100644 --- a/accessible/src/generic/Accessible.h +++ b/accessible/src/generic/Accessible.h @@ -126,11 +126,6 @@ public: ////////////////////////////////////////////////////////////////////////////// // Public methods - /** - * Initialize the accessible. - */ - virtual void Init(); - /** * Get the description of this accessible. */ diff --git a/accessible/src/generic/ApplicationAccessible.cpp b/accessible/src/generic/ApplicationAccessible.cpp index fac2183fe7e0..f122f2fe87b3 100644 --- a/accessible/src/generic/ApplicationAccessible.cpp +++ b/accessible/src/generic/ApplicationAccessible.cpp @@ -27,6 +27,7 @@ ApplicationAccessible::ApplicationAccessible() : AccessibleWrap(nullptr, nullptr) { mFlags |= eApplicationAccessible; + mAppInfo = do_GetService("@mozilla.org/xre/app-info;1"); } //////////////////////////////////////////////////////////////////////////////// @@ -266,12 +267,6 @@ ApplicationAccessible::GetPlatformVersion(nsAString& aVersion) //////////////////////////////////////////////////////////////////////////////// // nsAccessNode public methods -void -ApplicationAccessible::Init() -{ - mAppInfo = do_GetService("@mozilla.org/xre/app-info;1"); -} - void ApplicationAccessible::Shutdown() { diff --git a/accessible/src/generic/ApplicationAccessible.h b/accessible/src/generic/ApplicationAccessible.h index 25f42737a701..033df8ed8a81 100644 --- a/accessible/src/generic/ApplicationAccessible.h +++ b/accessible/src/generic/ApplicationAccessible.h @@ -58,7 +58,6 @@ public: NS_DECL_NSIACCESSIBLEAPPLICATION // nsAccessNode - virtual void Init(); virtual void Shutdown(); // Accessible diff --git a/accessible/src/generic/DocAccessible.cpp b/accessible/src/generic/DocAccessible.cpp index d3d15bcd7b8a..5fe06a706998 100644 --- a/accessible/src/generic/DocAccessible.cpp +++ b/accessible/src/generic/DocAccessible.cpp @@ -107,6 +107,49 @@ DocAccessible:: // We provide a virtual cursor if this is a root doc or if it's a tab doc. mIsCursorable = (!(mDocument->GetParentDocument()) || nsCoreUtils::IsTabDocument(mDocument)); +#ifdef A11Y_LOG + if (logging::IsEnabled(logging::eDocCreate)) + logging::DocCreate("document initialize", mDocument, this); +#endif + + // Initialize notification controller. + mNotificationController = new NotificationController(this, mPresShell); + + // Mark the document accessible as loaded if its DOM document was loaded at + // this point (this can happen because a11y is started late or DOM document + // having no container was loaded. + if (mDocument->GetReadyStateEnum() == nsIDocument::READYSTATE_COMPLETE) + mLoadState |= eDOMLoaded; + + nsCOMPtr container = mDocument->GetContainer(); + nsCOMPtr docShellTreeItem(do_QueryInterface(container)); + + // We only want to be a command observer for content docshells with an + // editor. + int32_t itemType; + docShellTreeItem->GetItemType(&itemType); + + bool isContent = (itemType == nsIDocShellTreeItem::typeContent); + if (isContent) { + nsCOMPtr commandManager = do_GetInterface(docShellTreeItem); + if (commandManager) + commandManager->AddCommandObserver(this, "obs_documentCreated"); + } + + a11y::RootAccessible* rootAccessible = RootAccessible(); + + // XXX we might be the root accessible in which case eRootAccessible hasn't + // been added to mFlags yet, so the downcast failed, and RootAccessible() + // returned NULL. Bug 678477 should + // remove this hack. + if (rootAccessible) { + nsRefPtr caretAccessible = rootAccessible->GetCaretAccessible(); + if (caretAccessible) + caretAccessible->AddDocSelectionListener(mPresShell); + } + + // Add document observer. + mDocument->AddObserver(this); } DocAccessible::~DocAccessible() @@ -582,26 +625,6 @@ DocAccessible::GetAccessible(nsINode* aNode) const //////////////////////////////////////////////////////////////////////////////// // nsAccessNode -void -DocAccessible::Init() -{ -#ifdef A11Y_LOG - if (logging::IsEnabled(logging::eDocCreate)) - logging::DocCreate("document initialize", mDocument, this); -#endif - - // Initialize notification controller. - mNotificationController = new NotificationController(this, mPresShell); - - // Mark the document accessible as loaded if its DOM document was loaded at - // this point (this can happen because a11y is started late or DOM document - // having no container was loaded. - if (mDocument->GetReadyStateEnum() == nsIDocument::READYSTATE_COMPLETE) - mLoadState |= eDOMLoaded; - - AddEventListeners(); -} - void DocAccessible::Shutdown() { @@ -713,50 +736,6 @@ DocAccessible::GetBoundsRect(nsRect& aBounds, nsIFrame** aRelativeFrame) } } -// DocAccessible protected member -nsresult -DocAccessible::AddEventListeners() -{ - // 1) Set up scroll position listener - // 2) Check for editor and listen for changes to editor - - NS_ENSURE_TRUE(mPresShell, NS_ERROR_FAILURE); - - nsCOMPtr container = mDocument->GetContainer(); - nsCOMPtr docShellTreeItem(do_QueryInterface(container)); - NS_ENSURE_TRUE(docShellTreeItem, NS_ERROR_FAILURE); - - // Make sure we're a content docshell - // We don't want to listen to chrome progress - int32_t itemType; - docShellTreeItem->GetItemType(&itemType); - - bool isContent = (itemType == nsIDocShellTreeItem::typeContent); - - if (isContent) { - // We're not an editor yet, but we might become one - nsCOMPtr commandManager = do_GetInterface(docShellTreeItem); - if (commandManager) { - commandManager->AddCommandObserver(this, "obs_documentCreated"); - } - } - - nsCOMPtr rootTreeItem; - docShellTreeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem)); - if (rootTreeItem) { - a11y::RootAccessible* rootAccessible = RootAccessible(); - NS_ENSURE_TRUE(rootAccessible, NS_ERROR_FAILURE); - nsRefPtr caretAccessible = rootAccessible->GetCaretAccessible(); - if (caretAccessible) { - caretAccessible->AddDocSelectionListener(mPresShell); - } - } - - // add document observer - mDocument->AddObserver(this); - return NS_OK; -} - // DocAccessible protected member nsresult DocAccessible::RemoveEventListeners() @@ -1388,9 +1367,6 @@ DocAccessible::BindToDocument(Accessible* aAccessible, // Put into unique ID cache. mAccessibleCache.Put(aAccessible->UniqueID(), aAccessible); - // Initialize the accessible. - aAccessible->Init(); - aAccessible->SetRoleMapEntry(aRoleMapEntry); if (aAccessible->IsElement()) AddDependentIDsFor(aAccessible); diff --git a/accessible/src/generic/DocAccessible.h b/accessible/src/generic/DocAccessible.h index ee222d03a433..e043fe9b17e0 100644 --- a/accessible/src/generic/DocAccessible.h +++ b/accessible/src/generic/DocAccessible.h @@ -76,7 +76,6 @@ public: NS_DECL_NSIDOCUMENTOBSERVER // nsAccessNode - virtual void Init(); virtual void Shutdown(); virtual nsIFrame* GetFrame() const; virtual nsINode* GetNode() const { return mDocument; } @@ -322,7 +321,6 @@ protected: virtual void CacheChildren(); // DocAccessible - virtual nsresult AddEventListeners(); virtual nsresult RemoveEventListeners(); /** diff --git a/accessible/src/generic/RootAccessible.cpp b/accessible/src/generic/RootAccessible.cpp index 6a69285d1cc8..332d5d2b6778 100644 --- a/accessible/src/generic/RootAccessible.cpp +++ b/accessible/src/generic/RootAccessible.cpp @@ -48,6 +48,35 @@ using namespace mozilla; using namespace mozilla::a11y; +const char* const kEventTypes[] = { +#ifdef DEBUG_DRAGDROPSTART + // Capture mouse over events and fire fake DRAGDROPSTART event to simplify + // debugging a11y objects with event viewers. + "mouseover", +#endif + // Fired whenever list or tree control selection is changed. + "select", + // Fired whenever value changes, immediately after, whether focus moves or + // not. + "ValueChange", + "AlertActive", + "TreeRowCountChanged", + "TreeInvalidated", + // add ourself as a OpenStateChange listener (custom event fired in tree.xml) + "OpenStateChange", + // add ourself as a CheckboxStateChange listener (custom event fired in nsHTMLInputElement.cpp) + "CheckboxStateChange", + // add ourself as a RadioStateChange Listener ( custom event fired in in nsHTMLInputElement.cpp & radio.xml) + "RadioStateChange", + "popupshown", + "popuphiding", + "DOMMenuInactive", + "DOMMenuItemActive", + "DOMMenuItemInactive", + "DOMMenuBarActive", + "DOMMenuBarInactive" +}; + //////////////////////////////////////////////////////////////////////////////// // nsISupports @@ -62,6 +91,25 @@ RootAccessible:: DocAccessibleWrap(aDocument, aRootContent, aPresShell) { mFlags |= eRootAccessible; + + // nsIDOMEventTarget interface allows to register event listeners to + // receive untrusted events (synthetic events generated by untrusted code). + // For example, XBL bindings implementations for elements that are hosted in + // non chrome document fire untrusted events. + nsCOMPtr nstarget(do_QueryInterface(mDocument)); + if (nstarget) { + for (const char* const* e = kEventTypes, + * const* e_end = ArrayEnd(kEventTypes); + e < e_end; ++e) { + nstarget->AddEventListener(NS_ConvertASCIItoUTF16(*e), + this, true, true, 2); + } + } + + // XXX DocAccessible constructor can't tell if its creating a RootAccessible + // so we need to construct the caret accessible here. + mCaretAccessible = new nsCaretAccessible(this); + mCaretAccessible->AddDocSelectionListener(aPresShell); } RootAccessible::~RootAccessible() @@ -151,68 +199,13 @@ RootAccessible::NativeState() return state; } -const char* const docEvents[] = { -#ifdef DEBUG_DRAGDROPSTART - // Capture mouse over events and fire fake DRAGDROPSTART event to simplify - // debugging a11y objects with event viewers - "mouseover", -#endif - // capture Form change events - "select", - // capture ValueChange events (fired whenever value changes, immediately after, whether focus moves or not) - "ValueChange", - // capture AlertActive events (fired whenever alert pops up) - "AlertActive", - "TreeRowCountChanged", - "TreeInvalidated", - // add ourself as a OpenStateChange listener (custom event fired in tree.xml) - "OpenStateChange", - // add ourself as a CheckboxStateChange listener (custom event fired in nsHTMLInputElement.cpp) - "CheckboxStateChange", - // add ourself as a RadioStateChange Listener ( custom event fired in in nsHTMLInputElement.cpp & radio.xml) - "RadioStateChange", - "popupshown", - "popuphiding", - "DOMMenuInactive", - "DOMMenuItemActive", - "DOMMenuItemInactive", - "DOMMenuBarActive", - "DOMMenuBarInactive" -}; - -nsresult -RootAccessible::AddEventListeners() -{ - // nsIDOMEventTarget interface allows to register event listeners to - // receive untrusted events (synthetic events generated by untrusted code). - // For example, XBL bindings implementations for elements that are hosted in - // non chrome document fire untrusted events. - nsCOMPtr nstarget(do_QueryInterface(mDocument)); - - if (nstarget) { - for (const char* const* e = docEvents, - * const* e_end = ArrayEnd(docEvents); - e < e_end; ++e) { - nsresult rv = nstarget->AddEventListener(NS_ConvertASCIItoUTF16(*e), - this, true, true, 2); - NS_ENSURE_SUCCESS(rv, rv); - } - } - - if (!mCaretAccessible) { - mCaretAccessible = new nsCaretAccessible(this); - } - - return DocAccessible::AddEventListeners(); -} - nsresult RootAccessible::RemoveEventListeners() { nsCOMPtr target(do_QueryInterface(mDocument)); if (target) { - for (const char* const* e = docEvents, - * const* e_end = ArrayEnd(docEvents); + for (const char* const* e = kEventTypes, + * const* e_end = ArrayEnd(kEventTypes); e < e_end; ++e) { nsresult rv = target->RemoveEventListener(NS_ConvertASCIItoUTF16(*e), this, true); NS_ENSURE_SUCCESS(rv, rv); diff --git a/accessible/src/generic/RootAccessible.h b/accessible/src/generic/RootAccessible.h index e9b1a6f57072..c0900fc552af 100644 --- a/accessible/src/generic/RootAccessible.h +++ b/accessible/src/generic/RootAccessible.h @@ -50,9 +50,8 @@ public: protected: /** - * Add/remove DOM event listeners. + * Remove DOM event listeners. */ - virtual nsresult AddEventListeners(); virtual nsresult RemoveEventListeners(); /** diff --git a/accessible/src/xul/XULTreeAccessible.cpp b/accessible/src/xul/XULTreeAccessible.cpp index c1a353d67a55..d46897f9c275 100644 --- a/accessible/src/xul/XULTreeAccessible.cpp +++ b/accessible/src/xul/XULTreeAccessible.cpp @@ -1099,6 +1099,7 @@ XULTreeItemAccessible:: XULTreeItemAccessibleBase(aContent, aDoc, aParent, aTree, aTreeView, aRow) { mColumn = nsCoreUtils::GetFirstSensibleColumn(mTree); + GetCellName(mColumn, mCachedName); } //////////////////////////////////////////////////////////////////////////////// @@ -1136,13 +1137,6 @@ XULTreeItemAccessible::Name(nsString& aName) //////////////////////////////////////////////////////////////////////////////// // XULTreeItemAccessible: nsAccessNode implementation -void -XULTreeItemAccessible::Init() -{ - XULTreeItemAccessibleBase::Init(); - Name(mCachedName); -} - void XULTreeItemAccessible::Shutdown() { diff --git a/accessible/src/xul/XULTreeAccessible.h b/accessible/src/xul/XULTreeAccessible.h index 79fd3ce7b123..5dfd8b1bacfd 100644 --- a/accessible/src/xul/XULTreeAccessible.h +++ b/accessible/src/xul/XULTreeAccessible.h @@ -233,7 +233,6 @@ public: XULTreeItemAccessibleBase) // nsAccessNode - virtual void Init(); virtual void Shutdown(); // Accessible diff --git a/accessible/src/xul/XULTreeGridAccessible.cpp b/accessible/src/xul/XULTreeGridAccessible.cpp index ce0ab56d1d6d..f22edfb79096 100644 --- a/accessible/src/xul/XULTreeGridAccessible.cpp +++ b/accessible/src/xul/XULTreeGridAccessible.cpp @@ -469,6 +469,15 @@ XULTreeGridCellAccessible:: { mParent = aRowAcc; mFlags |= eSharedNode; + + NS_ASSERTION(mTreeView, "mTreeView is null"); + + int16_t type = -1; + mColumn->GetType(&type); + if (type == nsITreeColumn::TYPE_CHECKBOX) + mTreeView->GetCellValue(mRow, mColumn, mCachedTextEquiv); + else + mTreeView->GetCellText(mRow, mColumn, mCachedTextEquiv); } //////////////////////////////////////////////////////////////////////////////// @@ -705,24 +714,6 @@ XULTreeGridCellAccessible::Selected() return selected; } -//////////////////////////////////////////////////////////////////////////////// -// XULTreeGridCellAccessible: nsAccessNode implementation - -void -XULTreeGridCellAccessible::Init() -{ - LeafAccessible::Init(); - - NS_ASSERTION(mTreeView, "mTreeView is null"); - - int16_t type; - mColumn->GetType(&type); - if (type == nsITreeColumn::TYPE_CHECKBOX) - mTreeView->GetCellValue(mRow, mColumn, mCachedTextEquiv); - else - mTreeView->GetCellText(mRow, mColumn, mCachedTextEquiv); -} - //////////////////////////////////////////////////////////////////////////////// // XULTreeGridCellAccessible: Accessible public implementation diff --git a/accessible/src/xul/XULTreeGridAccessible.h b/accessible/src/xul/XULTreeGridAccessible.h index e0fbe9696e64..0ae8d97a4a1c 100644 --- a/accessible/src/xul/XULTreeGridAccessible.h +++ b/accessible/src/xul/XULTreeGridAccessible.h @@ -150,9 +150,6 @@ public: // nsIAccessibleTableCell NS_FORWARD_NSIACCESSIBLETABLECELL(xpcAccessibleTableCell::) - // nsAccessNode - virtual void Init(); - // Accessible virtual TableCellAccessible* AsTableCell() { return this; } virtual void Shutdown(); From 09c0f1a5363f918fa0ea9e97ed3a8bc91b0fe7f3 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Fri, 16 Nov 2012 20:31:53 -0800 Subject: [PATCH 26/57] Bug 813209 - Refactor MediaResource into BaseMediaResource so that we can base the implementation of BufferMediaSource on top of MediaSource; r=cpearce This refactoring is needed for the introduction of the BufferMediaResource class. --HG-- extra : rebase_source : e4b5016e9b947948799f1b8975b23a3dd685a366 --- content/media/MediaResource.cpp | 10 +++++----- content/media/MediaResource.h | 25 ++++++++++++++++--------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/content/media/MediaResource.cpp b/content/media/MediaResource.cpp index 0666b6afdc0c..0fba8b0be9bf 100644 --- a/content/media/MediaResource.cpp +++ b/content/media/MediaResource.cpp @@ -49,7 +49,7 @@ namespace mozilla { ChannelMediaResource::ChannelMediaResource(MediaDecoder* aDecoder, nsIChannel* aChannel, nsIURI* aURI) - : MediaResource(aDecoder, aChannel, aURI), + : BaseMediaResource(aDecoder, aChannel, aURI), mOffset(0), mSuspendCount(0), mReopenOnError(false), mIgnoreClose(false), mCacheStream(this), @@ -1153,11 +1153,11 @@ ChannelMediaResource::PossiblyResume() } } -class FileMediaResource : public MediaResource +class FileMediaResource : public BaseMediaResource { public: FileMediaResource(MediaDecoder* aDecoder, nsIChannel* aChannel, nsIURI* aURI) : - MediaResource(aDecoder, aChannel, aURI), + BaseMediaResource(aDecoder, aChannel, aURI), mSize(-1), mLock("FileMediaResource.mLock"), mSizeInitialized(false) @@ -1514,7 +1514,7 @@ MediaResource::Create(MediaDecoder* aDecoder, nsIChannel* aChannel) return new ChannelMediaResource(aDecoder, aChannel, uri); } -void MediaResource::MoveLoadsToBackground() { +void BaseMediaResource::MoveLoadsToBackground() { NS_ASSERTION(!mLoadInBackground, "Why are you calling this more than once?"); mLoadInBackground = true; if (!mChannel) { @@ -1545,7 +1545,7 @@ void MediaResource::MoveLoadsToBackground() { } } -void MediaResource::ModifyLoadFlags(nsLoadFlags aFlags) +void BaseMediaResource::ModifyLoadFlags(nsLoadFlags aFlags) { nsCOMPtr loadGroup; DebugOnly rv = mChannel->GetLoadGroup(getter_AddRefs(loadGroup)); diff --git a/content/media/MediaResource.h b/content/media/MediaResource.h index 81659ce70915..66208f38c640 100644 --- a/content/media/MediaResource.h +++ b/content/media/MediaResource.h @@ -146,14 +146,11 @@ public: class MediaResource { public: - virtual ~MediaResource() - { - MOZ_COUNT_DTOR(MediaResource); - } + virtual ~MediaResource() {} // The following can be called on the main thread only: // Get the URI - nsIURI* URI() const { return mURI; } + virtual nsIURI* URI() const { return nullptr; } // Close the resource, stop any listeners, channels, etc. // Cancels any currently blocking Read request and forces that request to // return an error. @@ -227,7 +224,7 @@ public: // Moves any existing channel loads into the background, so that they don't // block the load event. Any new loads initiated (for example to seek) // will also be in the background. - void MoveLoadsToBackground(); + virtual void MoveLoadsToBackground() {} // Ensures that the value returned by IsSuspendedByCache below is up to date // (i.e. the cache has examined this stream at least once). virtual void EnsureCacheUpToDate() {} @@ -307,15 +304,25 @@ public: * aRanges is being used. */ virtual nsresult GetCachedRanges(nsTArray& aRanges) = 0; +}; + +class BaseMediaResource : public MediaResource { +public: + virtual nsIURI* URI() const { return mURI; } + virtual void MoveLoadsToBackground(); protected: - MediaResource(MediaDecoder* aDecoder, nsIChannel* aChannel, nsIURI* aURI) : + BaseMediaResource(MediaDecoder* aDecoder, nsIChannel* aChannel, nsIURI* aURI) : mDecoder(aDecoder), mChannel(aChannel), mURI(aURI), mLoadInBackground(false) { - MOZ_COUNT_CTOR(MediaResource); + MOZ_COUNT_CTOR(BaseMediaResource); + } + virtual ~BaseMediaResource() + { + MOZ_COUNT_DTOR(BaseMediaResource); } // Set the request's load flags to aFlags. If the request is part of a @@ -349,7 +356,7 @@ protected: * All synchronization is performed by MediaCacheStream; all off-main- * thread operations are delegated directly to that object. */ -class ChannelMediaResource : public MediaResource +class ChannelMediaResource : public BaseMediaResource { public: ChannelMediaResource(MediaDecoder* aDecoder, nsIChannel* aChannel, nsIURI* aURI); From 93bb745963c24d1384f8989f2f7f53ac09fd6b35 Mon Sep 17 00:00:00 2001 From: Blake Kaplan Date: Mon, 19 Nov 2012 16:43:21 -0800 Subject: [PATCH 27/57] Bug 813357 - Actually hand off our copy of the notification request to IPDL. r=gwagner --- dom/src/notification/nsDesktopNotification.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dom/src/notification/nsDesktopNotification.cpp b/dom/src/notification/nsDesktopNotification.cpp index 1c2a9ad4ee61..053f52752c6f 100644 --- a/dom/src/notification/nsDesktopNotification.cpp +++ b/dom/src/notification/nsDesktopNotification.cpp @@ -109,7 +109,7 @@ nsDOMDesktopNotification::Init() // Corresponding release occurs in DeallocPContentPermissionRequest. nsRefPtr copy = request; - child->SendPContentPermissionRequestConstructor(request, + child->SendPContentPermissionRequestConstructor(copy.forget().get(), NS_LITERAL_CSTRING("desktop-notification"), NS_LITERAL_CSTRING("unused"), IPC::Principal(mPrincipal)); From 75abf86728ff966d2b3c1e34a6ead7f6fb672513 Mon Sep 17 00:00:00 2001 From: Justin Lebar Date: Mon, 19 Nov 2012 20:05:34 -0500 Subject: [PATCH 28/57] Bug 811466 - Add include guards around some headers which were missing them. r=khuey --- content/base/src/mozAutoDocUpdate.h | 5 +++++ content/base/src/nsCCUncollectableMarker.h | 5 +++++ content/xbl/src/nsXBLService.h | 4 ++++ dom/base/nsDOMWindowUtils.h | 5 +++++ 4 files changed, 19 insertions(+) diff --git a/content/base/src/mozAutoDocUpdate.h b/content/base/src/mozAutoDocUpdate.h index 2e0463229d89..912d6e615a2b 100644 --- a/content/base/src/mozAutoDocUpdate.h +++ b/content/base/src/mozAutoDocUpdate.h @@ -2,6 +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/. */ +#ifndef mozAutoDocUpdate_h_ +#define mozAutoDocUpdate_h_ + #include "nsContentUtils.h" #include "nsIDocument.h" #include "nsIDocumentObserver.h" @@ -82,3 +85,5 @@ public: private: nsCOMPtr mDocument; }; + +#endif diff --git a/content/base/src/nsCCUncollectableMarker.h b/content/base/src/nsCCUncollectableMarker.h index b802a289c412..920990ba202e 100644 --- a/content/base/src/nsCCUncollectableMarker.h +++ b/content/base/src/nsCCUncollectableMarker.h @@ -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/. */ +#ifndef nsCCUncollectableMarker_h_ +#define nsCCUncollectableMarker_h_ + #include "nsIObserver.h" #include "nsCycleCollectionParticipant.h" #include "mozilla/Attributes.h" @@ -45,3 +48,5 @@ namespace dom { void TraceBlackJS(JSTracer* aTrc); } } + +#endif diff --git a/content/xbl/src/nsXBLService.h b/content/xbl/src/nsXBLService.h index 2e09601d4e2d..81a18b3df114 100644 --- a/content/xbl/src/nsXBLService.h +++ b/content/xbl/src/nsXBLService.h @@ -5,6 +5,9 @@ ////////////////////////////////////////////////////////////////////////////////////////// +#ifndef nsXBLService_h_ +#define nsXBLService_h_ + #include "nsString.h" #include "nsIObserver.h" #include "nsWeakReference.h" @@ -141,3 +144,4 @@ public: nsrefcnt Drop() { return --mRefCnt ? mRefCnt : Destroy(); } }; +#endif diff --git a/dom/base/nsDOMWindowUtils.h b/dom/base/nsDOMWindowUtils.h index f913b74b76ac..9d2132b6b7b5 100644 --- a/dom/base/nsDOMWindowUtils.h +++ b/dom/base/nsDOMWindowUtils.h @@ -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/. */ +#ifndef nsDOMWindowUtils_h_ +#define nsDOMWindowUtils_h_ + #include "nsAutoPtr.h" #include "nsWeakReference.h" @@ -48,3 +51,5 @@ protected: static mozilla::widget::Modifiers GetWidgetModifiers(int32_t aModifiers); }; + +#endif From 70ef6eb69ade373f191031dcd4b9a87b2df04d71 Mon Sep 17 00:00:00 2001 From: Justin Lebar Date: Mon, 19 Nov 2012 20:09:11 -0500 Subject: [PATCH 29/57] Bug 812880 - Remove some static RefPtrs which were causing deadlocks at shutdown. r=cjones --- dom/system/gonk/AutoMounter.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dom/system/gonk/AutoMounter.cpp b/dom/system/gonk/AutoMounter.cpp index c37a4948cd35..cc808d47ddfa 100644 --- a/dom/system/gonk/AutoMounter.cpp +++ b/dom/system/gonk/AutoMounter.cpp @@ -22,6 +22,7 @@ #include "base/message_loop.h" #include "mozilla/FileUtils.h" #include "mozilla/Hal.h" +#include "mozilla/StaticPtr.h" #include "nsAutoPtr.h" #include "nsMemory.h" #include "nsString.h" @@ -285,7 +286,7 @@ private: VolumeArray mAutoVolume; }; -static RefPtr sAutoMounter; +static StaticRefPtr sAutoMounter; /***************************************************************************/ @@ -524,8 +525,8 @@ public: } }; -static RefPtr sUsbCableObserver; -static RefPtr sAutoMounterSetting; +static StaticRefPtr sUsbCableObserver; +static StaticRefPtr sAutoMounterSetting; void InitAutoMounter() From b944d105a8ecac86e1613bb4f2e91c58f079f234 Mon Sep 17 00:00:00 2001 From: Felipe Gomes Date: Mon, 19 Nov 2012 17:22:42 -0800 Subject: [PATCH 30/57] Bug 813316 - User details menuitem is blank on OSX menu. r=jaws --- browser/base/content/browser-menubar.inc | 5 +++-- browser/base/content/browser-sets.inc | 3 +-- browser/base/content/browser-social.js | 17 ++++++++++++----- browser/base/content/browser.xul | 5 +++-- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/browser/base/content/browser-menubar.inc b/browser/base/content/browser-menubar.inc index 2a679b23553a..a57e55c7ff74 100644 --- a/browser/base/content/browser-menubar.inc +++ b/browser/base/content/browser-menubar.inc @@ -508,12 +508,13 @@ #ifndef XP_WIN diff --git a/browser/base/content/browser-sets.inc b/browser/base/content/browser-sets.inc index 9e58b04f2a20..46c6f192df63 100644 --- a/browser/base/content/browser-sets.inc +++ b/browser/base/content/browser-sets.inc @@ -252,8 +252,7 @@ oncommand="openUILinkIn('https://addons.mozilla.org/firefox/collections/mozilla/webdeveloper/', 'tab');"/> - - diff --git a/browser/base/content/browser-social.js b/browser/base/content/browser-social.js index 7293bf47fa18..c36ac22f755e 100644 --- a/browser/base/content/browser-social.js +++ b/browser/base/content/browser-social.js @@ -673,12 +673,19 @@ var SocialToolbar = { // social:profile-changed let profile = Social.provider.profile || {}; let userPortrait = profile.portrait || "chrome://global/skin/icons/information-32.png"; - document.getElementById("socialBroadcaster_userPortrait").setAttribute("src", userPortrait); - let loggedInStatusBroadcaster = document.getElementById("socialBroadcaster_loggedInStatus"); - let notLoggedInString = loggedInStatusBroadcaster.getAttribute("notLoggedInLabel"); - let loggedInStatusValue = profile.userName ? profile.userName : notLoggedInString; - loggedInStatusBroadcaster.setAttribute("value", loggedInStatusValue); + let userDetailsBroadcaster = document.getElementById("socialBroadcaster_userDetails"); + let loggedInStatusValue = profile.userName ? + profile.userName : + userDetailsBroadcaster.getAttribute("notLoggedInLabel");; + + // "image" and "label" are used by Mac's native menus that do not render the menuitem's children + // elements. "src" and "value" are used by the image/label children on the other platforms. + userDetailsBroadcaster.setAttribute("src", userPortrait); + userDetailsBroadcaster.setAttribute("image", userPortrait); + + userDetailsBroadcaster.setAttribute("value", loggedInStatusValue); + userDetailsBroadcaster.setAttribute("label", loggedInStatusValue); }, updateButton: function SocialToolbar_updateButton() { diff --git a/browser/base/content/browser.xul b/browser/base/content/browser.xul index 3037dad5b38a..38d9462e5644 100644 --- a/browser/base/content/browser.xul +++ b/browser/base/content/browser.xul @@ -668,12 +668,13 @@ type="menu"> #ifndef XP_WIN From 996f4a0c3b5d388cea9484209c384e6d8bbdabbc Mon Sep 17 00:00:00 2001 From: Trevor Saunders Date: Sat, 17 Nov 2012 22:58:29 -0500 Subject: [PATCH 31/57] bug 812845 - more tests for invalid spelling text attribute r=surkov --- .../mochitest/events/test_textattrchange.html | 45 ++++++++++++++++--- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/accessible/tests/mochitest/events/test_textattrchange.html b/accessible/tests/mochitest/events/test_textattrchange.html index a69a8df15e08..e990f3f9d1d8 100644 --- a/accessible/tests/mochitest/events/test_textattrchange.html +++ b/accessible/tests/mochitest/events/test_textattrchange.html @@ -29,7 +29,7 @@ Components.utils.import("resource://gre/modules/InlineSpellChecker.jsm"); - function spelledTextInvoker(aID) + function spelledTextInvoker(aID, aText, aTests) { this.DOMNode = getNode(aID); @@ -46,7 +46,7 @@ //var spellchecker = editor.getInlineSpellChecker(true); //spellchecker.enableRealTimeSpell = true; - this.DOMNode.value = "valid text inalid tixt"; + this.DOMNode.value = aText; } this.finalCheck = function spelledTextInvoker_finalCheck() @@ -61,10 +61,11 @@ "invalid": "spelling" }; - testTextAttrs(aID, 0, attrs, defAttrs, 0, 11); - testTextAttrs(aID, 11, misspelledAttrs, defAttrs, 11, 17); - testTextAttrs(aID, 17, attrs, defAttrs, 17, 18); - testTextAttrs(aID, 18, misspelledAttrs, defAttrs, 18, 22); + for (var i = 0; i < aTests.length; i++) { + testTextAttrs(aID, aTests[i].start, + aTests[i].misspelled ? misspelledAttrs : attrs, + defAttrs, aTests[i].start, aTests[i].end); + } } this.getID = function spelledTextInvoker_getID() @@ -87,7 +88,32 @@ gQueue = new eventQueue(); gQueue.push(new synthFocus("input")); - gQueue.push(new spelledTextInvoker("input")); + + var tests = [ + { misspelled: false, start: 0, end: 11}, + { misspelled: true, start: 11, end: 17}, + { misspelled: false, start: 17, end: 18}, + { misspelled: true, start: 18, end: 22} + ]; + gQueue.push(new spelledTextInvoker("input", "valid text inalid tixt", + tests)); + + tests = [ + { misspelled: false, start: 0, end: 4} + ]; + gQueue.push(new spelledTextInvoker("input", "that", tests)); + + tests = [ + { misspelled: true, start: 0, end: 4} + ]; + gQueue.push(new spelledTextInvoker("input", "taht", tests)); + + tests = [ + { misspelled: true, start: 0, end: 4}, + { misspelled: false, start: 4, end: 8} + ]; + gQueue.push(new spelledTextInvoker("input", "taht cat", tests)); + gQueue.invoke(); // Will call SimpleTest.finish(); } @@ -103,6 +129,11 @@ title="Implement text attributes"> Mozilla Bug 345759 +


From ab9f16238fd8dce2ced454e9c692adfd7ddf298b Mon Sep 17 00:00:00 2001
From: Michael Wu 
Date: Fri, 9 Nov 2012 12:08:36 -0800
Subject: [PATCH 32/57] Bug 809665 - Boot animation support for B2G, r=cjones

---
 b2g/app/BootAnimation.cpp   | 657 ++++++++++++++++++++++++++++++++++++
 b2g/app/BootAnimation.h     |  17 +
 b2g/app/Makefile.in         |   7 +
 b2g/app/nsBrowserApp.cpp    |  10 +
 b2g/chrome/content/shell.js |   2 +
 widget/gonk/Makefile.in     |   1 +
 widget/gonk/nsAppShell.cpp  |  33 +-
 widget/gonk/nsAppShell.h    |   8 +
 widget/gonk/nsWindow.cpp    |  35 +-
 9 files changed, 735 insertions(+), 35 deletions(-)
 create mode 100644 b2g/app/BootAnimation.cpp
 create mode 100644 b2g/app/BootAnimation.h

diff --git a/b2g/app/BootAnimation.cpp b/b2g/app/BootAnimation.cpp
new file mode 100644
index 000000000000..5aa2ac5a85c6
--- /dev/null
+++ b/b2g/app/BootAnimation.cpp
@@ -0,0 +1,657 @@
+/* Copyright 2012 Mozilla Foundation and Mozilla contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "mozilla/Util.h"
+#include "mozilla/NullPtr.h"
+#include "png.h"
+
+#include "android/log.h"
+#include "ui/FramebufferNativeWindow.h"
+#include "hardware_legacy/power.h"
+
+#define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "Gonk" , ## args)
+#define LOGW(args...) __android_log_print(ANDROID_LOG_WARN, "Gonk", ## args)
+#define LOGE(args...) __android_log_print(ANDROID_LOG_ERROR, "Gonk", ## args)
+
+using namespace android;
+using namespace mozilla;
+using namespace std;
+
+static sp gNativeWindow;
+static pthread_t sAnimationThread;
+static bool sRunAnimation;
+
+/* See http://www.pkware.com/documents/casestudies/APPNOTE.TXT */
+struct local_file_header {
+    uint32_t signature;
+    uint16_t min_version;
+    uint16_t general_flag;
+    uint16_t compression;
+    uint16_t lastmod_time;
+    uint16_t lastmod_date;
+    uint32_t crc32;
+    uint32_t compressed_size;
+    uint32_t uncompressed_size;
+    uint16_t filename_size;
+    uint16_t extra_field_size;
+    char     data[0];
+
+    uint32_t GetDataSize() const
+    {
+        return letoh32(uncompressed_size);
+    }
+
+    uint32_t GetSize() const
+    {
+        /* XXX account for data descriptor */
+        return sizeof(local_file_header) + letoh16(filename_size) +
+               letoh16(extra_field_size) + GetDataSize();
+    }
+
+    const char * GetData() const
+    {
+        return data + letoh16(filename_size) + letoh16(extra_field_size);
+    }
+} __attribute__((__packed__));
+
+struct data_descriptor {
+    uint32_t crc32;
+    uint32_t compressed_size;
+    uint32_t uncompressed_size;
+} __attribute__((__packed__));
+
+struct cdir_entry {
+    uint32_t signature;
+    uint16_t creator_version;
+    uint16_t min_version;
+    uint16_t general_flag;
+    uint16_t compression;
+    uint16_t lastmod_time;
+    uint16_t lastmod_date;
+    uint32_t crc32;
+    uint32_t compressed_size;
+    uint32_t uncompressed_size;
+    uint16_t filename_size;
+    uint16_t extra_field_size;
+    uint16_t file_comment_size;
+    uint16_t disk_num;
+    uint16_t internal_attr;
+    uint32_t external_attr;
+    uint32_t offset;
+    char     data[0];
+
+    uint32_t GetDataSize() const
+    {
+        return letoh32(compressed_size);
+    }
+
+    uint32_t GetSize() const
+    {
+        return sizeof(cdir_entry) + letoh16(filename_size) +
+               letoh16(extra_field_size) + letoh16(file_comment_size);
+    }
+
+    bool Valid() const
+    {
+        return signature == htole32(0x02014b50);
+    }
+} __attribute__((__packed__));
+
+struct cdir_end {
+    uint32_t signature;
+    uint16_t disk_num;
+    uint16_t cdir_disk;
+    uint16_t disk_entries;
+    uint16_t cdir_entries;
+    uint32_t cdir_size;
+    uint32_t cdir_offset;
+    uint16_t comment_size;
+    char     comment[0];
+
+    bool Valid() const
+    {
+        return signature == htole32(0x06054b50);
+    }
+} __attribute__((__packed__));
+
+/* We don't have access to libjar and the zip reader in android
+ * doesn't quite fit what we want to do. */
+class ZipReader {
+    const char *mBuf;
+    const cdir_end *mEnd;
+    const char *mCdir_limit;
+    uint32_t mBuflen;
+
+public:
+    ZipReader() : mBuf(nullptr) {}
+    ~ZipReader() {
+        if (mBuf)
+            munmap((void *)mBuf, mBuflen);
+    }
+
+    bool OpenArchive(const char *path)
+    {
+        int fd;
+        do {
+            fd = open(path, O_RDONLY);
+        } while (fd == -1 && errno == EINTR);
+        if (fd == -1)
+            return false;
+
+        struct stat sb;
+        if (fstat(fd, &sb) == -1 || sb.st_size < sizeof(cdir_end)) {
+            close(fd);
+            return false;
+        }
+
+        mBuflen = sb.st_size;
+        mBuf = (char *)mmap(nullptr, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
+        close(fd);
+
+        if (!mBuf) {
+            return false;
+        }
+
+        madvise(mBuf, sb.st_size, MADV_SEQUENTIAL);
+
+        mEnd = (cdir_end *)(mBuf + mBuflen - sizeof(cdir_end));
+        while (!mEnd->Valid() &&
+               (char *)mEnd > mBuf) {
+            mEnd = (cdir_end *)((char *)mEnd - 1);
+        }
+
+        mCdir_limit = mBuf + letoh32(mEnd->cdir_offset) + letoh32(mEnd->cdir_size);
+
+        if (!mEnd->Valid() || mCdir_limit > (char *)mEnd) {
+            munmap((void *)mBuf, mBuflen);
+            mBuf = nullptr;
+            return false;
+        }
+
+        return true;
+    }
+
+    /* Pass null to get the first cdir entry */
+    const cdir_entry * GetNextEntry(const cdir_entry *prev)
+    {
+        const cdir_entry *entry;
+        if (prev)
+            entry = (cdir_entry *)((char *)prev + prev->GetSize());
+        else
+            entry = (cdir_entry *)(mBuf + letoh32(mEnd->cdir_offset));
+
+        if (((char *)entry + entry->GetSize()) > mCdir_limit ||
+            !entry->Valid())
+            return nullptr;
+        return entry;
+    }
+
+    string GetEntryName(const cdir_entry *entry)
+    {
+        uint16_t len = letoh16(entry->filename_size);
+
+        string name;
+        name.append(entry->data, len);
+        return name;
+    }
+
+    const local_file_header * GetLocalEntry(const cdir_entry *entry)
+    {
+        const local_file_header * data =
+            (local_file_header *)(mBuf + letoh32(entry->offset));
+        if (((char *)data + data->GetSize()) > (char *)mEnd)
+            return nullptr;
+        return data;
+    }
+};
+
+struct AnimationFrame {
+    char path[256];
+    char *buf;
+    uint16_t width;
+    uint16_t height;
+    const local_file_header *file;
+
+    AnimationFrame() : buf(nullptr) {}
+    AnimationFrame(const AnimationFrame &frame) : buf(nullptr) {
+        strncpy(path, frame.path, sizeof(path));
+        file = frame.file;
+    }
+    ~AnimationFrame()
+    {
+        if (buf)
+            free(buf);
+    }
+
+    bool operator<(const AnimationFrame &other) const
+    {
+        return strcmp(path, other.path) < 0;
+    }
+
+    void ReadPngFrame();
+};
+
+struct AnimationPart {
+    int32_t count;
+    int32_t pause;
+    char path[256];
+    vector frames;
+};
+
+using namespace android;
+
+struct RawReadState {
+    const char *start;
+    uint32_t offset;
+    uint32_t length;
+};
+
+static void
+RawReader(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+    RawReadState *state = (RawReadState *)png_get_io_ptr(png_ptr);
+    if (length > (state->length - state->offset))
+        png_error(png_ptr, "Read too long");
+
+    memcpy(data, state->start + state->offset, length);
+    state->offset += length;
+}
+
+void
+AnimationFrame::ReadPngFrame()
+{
+    png_structp pngread = png_create_read_struct(PNG_LIBPNG_VER_STRING,
+                                                 nullptr, nullptr, nullptr);
+
+    png_infop pnginfo = png_create_info_struct(pngread);
+
+    RawReadState state;
+    state.start = file->GetData();
+    state.length = file->GetDataSize();
+    state.offset = 0;
+
+    png_set_read_fn(pngread, &state, RawReader);
+
+    setjmp(png_jmpbuf(pngread));
+
+    png_read_info(pngread, pnginfo);
+
+    width = png_get_image_width(pngread, pnginfo);
+    height = png_get_image_height(pngread, pnginfo);
+    buf = (char *)malloc(width * height * 3);
+
+    vector rows(height + 1);
+    uint32_t stride = width * 3;
+    for (int i = 0; i < height; i++) {
+        rows[i] = buf + (stride * i);
+    }
+    rows[height] = nullptr;
+    png_set_palette_to_rgb(pngread);
+    png_read_image(pngread, (png_bytepp)&rows.front());
+    png_destroy_read_struct(&pngread, &pnginfo, nullptr);
+}
+
+static const EGLint kEGLConfigAttribs[] = {
+    EGL_SURFACE_TYPE,    EGL_WINDOW_BIT,
+    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+    EGL_NONE
+};
+
+static bool
+CreateConfig(EGLConfig* aConfig, EGLDisplay display, int format)
+{
+    EGLConfig configs[64];
+    EGLint ncfg = ArrayLength(configs);
+
+    if (!eglChooseConfig(display, kEGLConfigAttribs,
+                         configs, ncfg, &ncfg) ||
+        ncfg < 1) {
+        return false;
+    }
+
+    for (int j = 0; j < ncfg; ++j) {
+        EGLConfig config = configs[j];
+        EGLint id;
+
+        if (eglGetConfigAttrib(display, config,
+                               EGL_NATIVE_VISUAL_ID, &id) &&
+            id > 0 && id == format)
+        {
+            *aConfig = config;
+            return true;
+        }
+    }
+    return false;
+}
+
+static void *
+AnimationThread(void *)
+{
+    ZipReader reader;
+    if (!reader.OpenArchive("/system/media/bootanimation.zip")) {
+        LOGW("Could not open boot animation");
+        return nullptr;
+    }
+
+    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    eglInitialize(display, nullptr, nullptr);
+
+    int format;
+    ANativeWindow const * const window = gNativeWindow.get();
+    window->query(window, NATIVE_WINDOW_FORMAT, &format);
+
+    EGLConfig config = NULL;
+    CreateConfig(&config, display, format);
+    if (!config) {
+        LOGW("Could not find config for pixel format");
+        return nullptr;
+    }
+
+    EGLSurface surface = eglCreateWindowSurface(display, config, gNativeWindow.get(), nullptr);
+
+    const cdir_entry *entry = nullptr;
+    const local_file_header *file = nullptr;
+    while ((entry = reader.GetNextEntry(entry))) {
+        string name = reader.GetEntryName(entry);
+        if (!name.compare("desc.txt")) {
+            file = reader.GetLocalEntry(entry);
+            break;
+        }
+    }
+
+    if (!file) {
+        LOGW("Could not find desc.txt in boot animation");
+        return nullptr;
+    }
+
+    string descCopy;
+    descCopy.append(file->GetData(), entry->GetDataSize());
+    int32_t width, height, fps;
+    const char *line = descCopy.c_str();
+    const char *end;
+    bool headerRead = true;
+    vector parts;
+
+    /*
+     * bootanimation.zip
+     *
+     * This is the boot animation file format that Android uses.
+     * It's a zip file with a directories containing png frames
+     * and a desc.txt that describes how they should be played.
+     *
+     * desc.txt contains two types of lines
+     * 1. [width] [height] [fps]
+     *    There is one of these lines per bootanimation.
+     *    If the width and height are smaller than the screen,
+     *    the frames are centered on a black background.
+     *    XXX: Currently we stretch instead of centering the frame.
+     * 2. p [count] [pause] [path]
+     *    This describes one animation part.
+     *    Each animation part is played in sequence.
+     *    An animation part contains all the files/frames in the
+     *    directory specified in [path]
+     *    [count] indicates the number of times this part repeats.
+     *    [pause] indicates the number of frames that this part
+     *    should pause for after playing the full sequence but
+     *    before repeating.
+     */
+
+    do {
+        end = strstr(line, "\n");
+
+        AnimationPart part;
+        if (headerRead &&
+            sscanf(line, "%d %d %d", &width, &height, &fps) == 3) {
+            headerRead = false;
+        } else if (sscanf(line, "p %d %d %s",
+                          &part.count, &part.pause, part.path)) {
+            parts.push_back(part);
+        }
+    } while (end && *(line = end + 1));
+
+    for (uint32_t i = 0; i < parts.size(); i++) {
+        AnimationPart &part = parts[i];
+        entry = nullptr;
+        char search[256];
+        snprintf(search, sizeof(search), "%s/", part.path);
+        while ((entry = reader.GetNextEntry(entry))) {
+            string name = reader.GetEntryName(entry);
+            if (name.find(search) ||
+                !entry->GetDataSize() ||
+                name.length() >= 256)
+                continue;
+
+            part.frames.push_back();
+            AnimationFrame &frame = part.frames.back();
+            strcpy(frame.path, name.c_str());
+            frame.file = reader.GetLocalEntry(entry);
+        }
+
+        sort(part.frames.begin(), part.frames.end());
+    }
+
+    static EGLint gContextAttribs[] = {
+        EGL_CONTEXT_CLIENT_VERSION, 2,
+        EGL_NONE, 0
+    };
+    EGLContext context = eglCreateContext(display, config, EGL_NO_CONTEXT, gContextAttribs);
+
+    eglMakeCurrent(display, surface, surface, context);
+    glEnable(GL_TEXTURE_2D);
+
+    const char *vsString =
+        "attribute vec2 aPosition; "
+        "attribute vec2 aTexCoord; "
+        "varying vec2 vTexCoord; "
+        "void main() { "
+        "  gl_Position = vec4(aPosition, 0.0, 1.0); "
+        "  vTexCoord = aTexCoord; "
+        "}";
+
+    const char *fsString =
+        "precision mediump float; "
+        "varying vec2 vTexCoord; "
+        "uniform sampler2D sTexture; "
+        "void main() { "
+        "  gl_FragColor = vec4(texture2D(sTexture, vTexCoord).rgb, 1.0); "
+        "}";
+
+    GLint status;
+    GLuint vsh = glCreateShader(GL_VERTEX_SHADER);
+    glShaderSource(vsh, 1, &vsString, nullptr);
+    glCompileShader(vsh);
+    glGetShaderiv(vsh, GL_COMPILE_STATUS, &status);
+    if (!status) {
+        LOGE("Failed to compile vertex shader");
+        return nullptr;
+    }
+
+    GLuint fsh = glCreateShader(GL_FRAGMENT_SHADER);
+    glShaderSource(fsh, 1, &fsString, nullptr);
+    glCompileShader(fsh);
+    glGetShaderiv(fsh, GL_COMPILE_STATUS, &status);
+    if (!status) {
+        LOGE("Failed to compile fragment shader");
+        return nullptr;
+    }
+
+    GLuint programId = glCreateProgram();
+    glAttachShader(programId, vsh);
+    glAttachShader(programId, fsh);
+
+    glLinkProgram(programId);
+    glGetProgramiv(programId, GL_LINK_STATUS, &status);
+    if (!status) {
+        LOG("Failed to link program");
+        return nullptr;
+    }
+
+    GLint positionLoc = glGetAttribLocation(programId, "aPosition");
+    GLint texCoordLoc = glGetAttribLocation(programId, "aTexCoord");
+    GLint textureLoc = glGetUniformLocation(programId, "sTexture");
+
+    glUseProgram(programId);
+
+    GLfloat texCoords[] = { 0.0f, 1.0f,
+                            0.0f, 0.0f,
+                            1.0f, 1.0f,
+                            1.0f, 0.0f };
+
+    GLfloat vCoords[] = { -1.0f, -1.0f,
+                          -1.0f,  1.0f,
+                           1.0f, -1.0f,
+                           1.0f,  1.0f };
+
+    GLuint rectBuf, texBuf;
+    glGenBuffers(1, &rectBuf);
+    glGenBuffers(1, &texBuf);
+
+    GLuint tex;
+    glGenTextures(1, &tex);
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_2D, tex);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+    glEnableVertexAttribArray(positionLoc);
+    glBindBuffer(GL_ARRAY_BUFFER, rectBuf);
+    glBufferData(GL_ARRAY_BUFFER, sizeof(vCoords), vCoords, GL_STATIC_DRAW);
+    glVertexAttribPointer(positionLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
+
+    glEnableVertexAttribArray(texCoordLoc);
+    glBindBuffer(GL_ARRAY_BUFFER, texBuf);
+    glBufferData(GL_ARRAY_BUFFER, sizeof(texCoords), texCoords, GL_STATIC_DRAW);
+    glVertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
+    glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+    glUniform1i(textureLoc, 0);
+
+    uint32_t frameDelayUs = 1000000 / fps;
+
+    for (uint32_t i = 0; i < parts.size(); i++) {
+        AnimationPart &part = parts[i];
+
+        uint32_t j = 0;
+        while (sRunAnimation && (!part.count || j++ < part.count)) {
+            for (uint32_t k = 0; k < part.frames.size(); k++) {
+                struct timeval tv1, tv2;
+                gettimeofday(&tv1, nullptr);
+                AnimationFrame &frame = part.frames[k];
+                if (!frame.buf) {
+                    frame.ReadPngFrame();
+                }
+
+                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
+                             frame.width, frame.height, 0,
+                             GL_RGB, GL_UNSIGNED_BYTE, frame.buf);
+                glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+                gettimeofday(&tv2, nullptr);
+
+                timersub(&tv2, &tv1, &tv2);
+
+                if (tv2.tv_usec < frameDelayUs) {
+                    usleep(frameDelayUs - tv2.tv_usec);
+                } else {
+                    LOGW("Frame delay is %d us but decoding took %d us", frameDelayUs, tv2.tv_usec);
+                }
+
+                eglSwapBuffers(display, surface);
+
+                if (part.count && j >= part.count) {
+                    free(frame.buf);
+                    frame.buf = nullptr;
+                }
+            }
+            usleep(frameDelayUs * part.pause);
+        }
+    }
+    glBindTexture(GL_TEXTURE_2D, 0);
+    glUseProgram(0);
+    glDeleteTextures(1, &tex);
+    glDeleteBuffers(1, &texBuf);
+    glDeleteBuffers(1, &rectBuf);
+    glDeleteProgram(programId);
+    glDeleteShader(fsh);
+    glDeleteShader(vsh);
+
+    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
+    eglDestroyContext(display, context);
+    eglDestroySurface(display, surface);
+    return nullptr;
+}
+
+static int
+CancelBufferNoop(ANativeWindow* aWindow, android_native_buffer_t* aBuffer)
+{
+    return 0;
+}
+
+__attribute__ ((visibility ("default")))
+FramebufferNativeWindow*
+NativeWindow()
+{
+    if (gNativeWindow.get()) {
+        return gNativeWindow.get();
+    }
+
+    // Some gralloc HALs need this in order to open the
+    // framebuffer device after we restart with the screen off.
+    //
+    // NB: this *must* run BEFORE allocating the
+    // FramebufferNativeWindow.  Do not separate these two C++
+    // statements.
+    set_screen_state(1);
+
+    // We (apparently) don't have a way to tell if allocating the
+    // fbs succeeded or failed.
+    gNativeWindow = new FramebufferNativeWindow();
+
+    // Bug 776742: FrambufferNativeWindow doesn't set the cancelBuffer
+    // function pointer, causing EGL to segfault when the window surface
+    // is destroyed (i.e. on process exit). This workaround stops us
+    // from hard crashing in that situation.
+    gNativeWindow->cancelBuffer = CancelBufferNoop;
+
+    sRunAnimation = true;
+    pthread_create(&sAnimationThread, nullptr, AnimationThread, nullptr);
+
+    return gNativeWindow.get();
+}
+
+
+__attribute__ ((visibility ("default")))
+void
+StopBootAnimation()
+{
+    if (sRunAnimation) {
+        sRunAnimation = false;
+        pthread_join(sAnimationThread, nullptr);
+    }
+}
diff --git a/b2g/app/BootAnimation.h b/b2g/app/BootAnimation.h
new file mode 100644
index 000000000000..4fa9c530b5ea
--- /dev/null
+++ b/b2g/app/BootAnimation.h
@@ -0,0 +1,17 @@
+#ifndef BOOTANIMATION_H
+#define BOOTANIMATION_H
+
+namespace android {
+class FramebufferNativeWindow;
+}
+
+/* This returns a FramebufferNativeWindow if one exists.
+ * If not, one is created and the boot animation is started. */
+__attribute__ ((weak))
+android::FramebufferNativeWindow* NativeWindow();
+
+/* This stops the boot animation if it's still running. */
+__attribute__ ((weak))
+void StopBootAnimation();
+
+#endif /* BOOTANIMATION_H */
diff --git a/b2g/app/Makefile.in b/b2g/app/Makefile.in
index e08be0185beb..7bbbcff49604 100644
--- a/b2g/app/Makefile.in
+++ b/b2g/app/Makefile.in
@@ -24,6 +24,13 @@ endif
 
 CPPSRCS = nsBrowserApp.cpp
 
+ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
+CPPSRCS += BootAnimation.cpp
+LIBS += -lpng -lGLESv2 -lEGL -lui -lhardware_legacy -lhardware -lcutils
+LOCAL_INCLUDES += -I$(ANDROID_SOURCE)/external/libpng
+OS_LDFLAGS += -Wl,--export-dynamic
+endif
+
 LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
 LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/base
 LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/build
diff --git a/b2g/app/nsBrowserApp.cpp b/b2g/app/nsBrowserApp.cpp
index d7f9d6910621..1d5440f01547 100644
--- a/b2g/app/nsBrowserApp.cpp
+++ b/b2g/app/nsBrowserApp.cpp
@@ -28,6 +28,11 @@
 #define snprintf _snprintf
 #define strcasecmp _stricmp
 #endif
+
+#ifdef MOZ_WIDGET_GONK
+#include "BootAnimation.h"
+#endif
+
 #include "BinaryPath.h"
 
 #include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL
@@ -139,6 +144,11 @@ static int do_main(int argc, char* argv[])
     argc -= 2;
   }
 
+#ifdef MOZ_WIDGET_GONK
+  /* Called to start the boot animation */
+  (void) NativeWindow();
+#endif
+
   if (appini) {
     nsXREAppData *appData;
     rv = XRE_CreateAppData(appini, &appData);
diff --git a/b2g/chrome/content/shell.js b/b2g/chrome/content/shell.js
index c19a6a4d5ee3..e8c76308ec41 100644
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -396,6 +396,8 @@ var shell = {
           content.removeEventListener('load', shell_homeLoaded);
           shell.isHomeLoaded = true;
 
+          Services.obs.notifyObservers(null, "browser-ui-startup-complete", "");
+
           if ('pendingChromeEvents' in shell) {
             shell.pendingChromeEvents.forEach((shell.sendChromeEvent).bind(shell));
           }
diff --git a/widget/gonk/Makefile.in b/widget/gonk/Makefile.in
index 21a2358147b5..2edb42995bad 100644
--- a/widget/gonk/Makefile.in
+++ b/widget/gonk/Makefile.in
@@ -73,6 +73,7 @@ include $(topsrcdir)/config/rules.mk
 DEFINES += -D_IMPL_NS_WIDGET -DHAVE_OFF64_T -DSK_BUILD_FOR_ANDROID_NDK
 
 LOCAL_INCLUDES += \
+	-I$(topsrcdir)/b2g/app \
 	-I$(topsrcdir)/widget/xpwidgets \
 	-I$(topsrcdir)/widget/shared \
 	-I$(topsrcdir)/dom/system/android \
diff --git a/widget/gonk/nsAppShell.cpp b/widget/gonk/nsAppShell.cpp
index 2d1663c35f15..1c14b5639feb 100644
--- a/widget/gonk/nsAppShell.cpp
+++ b/widget/gonk/nsAppShell.cpp
@@ -65,12 +65,15 @@
 using namespace android;
 using namespace mozilla;
 using namespace mozilla::dom;
+using namespace mozilla::services;
 
 bool gDrawRequest = false;
 static nsAppShell *gAppShell = NULL;
 static int epollfd = 0;
 static int signalfds[2] = {0};
 
+NS_IMPL_ISUPPORTS_INHERITED1(nsAppShell, nsBaseAppShell, nsIObserver)
+
 namespace mozilla {
 
 bool ProcessNextEvent()
@@ -586,6 +589,7 @@ GeckoInputDispatcher::unregisterInputChannel(const sp& inputChanne
 nsAppShell::nsAppShell()
     : mNativeCallbackRequest(false)
     , mHandlers()
+    , mEnableDraw(false)
 {
     gAppShell = this;
 }
@@ -620,16 +624,39 @@ nsAppShell::Init()
 
     InitGonkMemoryPressureMonitoring();
 
+    nsCOMPtr obsServ = GetObserverService();
+    if (obsServ) {
+        obsServ->AddObserver(this, "browser-ui-startup-complete", false);
+    }
+
     // Delay initializing input devices until the screen has been
     // initialized (and we know the resolution).
     return rv;
 }
 
+NS_IMETHODIMP
+nsAppShell::Observe(nsISupports* aSubject,
+                    const char* aTopic,
+                    const PRUnichar* aData)
+{
+    if (strcmp(aTopic, "browser-ui-startup-complete")) {
+        return nsBaseAppShell::Observe(aSubject, aTopic, aData);
+    }
+
+    mEnableDraw = true;
+    NotifyEvent();
+    return NS_OK;
+}
+
 NS_IMETHODIMP
 nsAppShell::Exit()
 {
-  OrientationObserver::ShutDown();
-  return nsBaseAppShell::Exit();
+    OrientationObserver::ShutDown();
+    nsCOMPtr obsServ = GetObserverService();
+    if (obsServ) {
+        obsServ->RemoveObserver(this, "browser-ui-startup-complete");
+    }
+    return nsBaseAppShell::Exit();
 }
 
 void
@@ -701,7 +728,7 @@ nsAppShell::ProcessNextNativeEvent(bool mayWait)
         NativeEventCallback();
     }
 
-    if (gDrawRequest) {
+    if (gDrawRequest && mEnableDraw) {
         gDrawRequest = false;
         nsWindow::DoDraw();
     }
diff --git a/widget/gonk/nsAppShell.h b/widget/gonk/nsAppShell.h
index f65c5b834889..ef63c4639b72 100644
--- a/widget/gonk/nsAppShell.h
+++ b/widget/gonk/nsAppShell.h
@@ -64,6 +64,9 @@ class nsAppShell : public nsBaseAppShell {
 public:
     nsAppShell();
 
+    NS_DECL_ISUPPORTS_INHERITED
+    NS_DECL_NSIOBSERVER
+
     nsresult Init();
 
     NS_IMETHOD Exit() MOZ_OVERRIDE;
@@ -87,6 +90,11 @@ private:
 
     // This is somewhat racy but is perfectly safe given how the callback works
     bool mNativeCallbackRequest;
+
+    // This gets flipped when we observe a browser-ui-startup-complete.
+    // browser-ui-startup-complete means that we're really ready to draw
+    // and can stop the boot animation
+    bool mEnableDraw;
     nsTArray mHandlers;
 
     android::sp               mEventHub;
diff --git a/widget/gonk/nsWindow.cpp b/widget/gonk/nsWindow.cpp
index b6c8b8ae7b57..535b538581b8 100644
--- a/widget/gonk/nsWindow.cpp
+++ b/widget/gonk/nsWindow.cpp
@@ -24,6 +24,7 @@
 #include "mozilla/Hal.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/FileUtils.h"
+#include "BootAnimation.h"
 #include "Framebuffer.h"
 #include "gfxContext.h"
 #include "gfxPlatform.h"
@@ -64,7 +65,6 @@ static nsRefPtr sGLContext;
 static nsTArray sTopWindows;
 static nsWindow *gWindowToRedraw = nullptr;
 static nsWindow *gFocusedWindow = nullptr;
-static android::FramebufferNativeWindow *gNativeWindow = nullptr;
 static bool sFramebufferOpen;
 static bool sUsingOMTC;
 static bool sUsingHwc;
@@ -74,37 +74,6 @@ static pthread_t sFramebufferWatchThread;
 
 namespace {
 
-static int
-CancelBufferNoop(ANativeWindow* aWindow, android_native_buffer_t* aBuffer)
-{
-    return 0;
-}
-
-android::FramebufferNativeWindow*
-NativeWindow()
-{
-    if (!gNativeWindow) {
-        // Some gralloc HALs need this in order to open the
-        // framebuffer device after we restart with the screen off.
-        //
-        // NB: this *must* run BEFORE allocating the
-        // FramebufferNativeWindow.  Do not separate these two C++
-        // statements.
-        hal::SetScreenEnabled(true);
-
-        // We (apparently) don't have a way to tell if allocating the
-        // fbs succeeded or failed.
-        gNativeWindow = new android::FramebufferNativeWindow();
-
-        // Bug 776742: FrambufferNativeWindow doesn't set the cancelBuffer
-        // function pointer, causing EGL to segfault when the window surface
-        // is destroyed (i.e. on process exit). This workaround stops us
-        // from hard crashing in that situation.
-        gNativeWindow->cancelBuffer = CancelBufferNoop;
-    }
-    return gNativeWindow;
-}
-
 static uint32_t
 EffectiveScreenRotation()
 {
@@ -243,6 +212,8 @@ nsWindow::DoDraw(void)
         return;
     }
 
+    StopBootAnimation();
+
     nsIntRegion region = gWindowToRedraw->mDirtyRegion;
     gWindowToRedraw->mDirtyRegion.SetEmpty();
 

From fe1ca13ca38917215e63c8fff3ed75d65879bf28 Mon Sep 17 00:00:00 2001
From: Michael Wu 
Date: Mon, 19 Nov 2012 19:54:33 -0600
Subject: [PATCH 33/57] Backed out changeset d12d63253125 (bug 809665) for red

---
 b2g/app/BootAnimation.cpp   | 657 ------------------------------------
 b2g/app/BootAnimation.h     |  17 -
 b2g/app/Makefile.in         |   7 -
 b2g/app/nsBrowserApp.cpp    |  10 -
 b2g/chrome/content/shell.js |   2 -
 widget/gonk/Makefile.in     |   1 -
 widget/gonk/nsAppShell.cpp  |  33 +-
 widget/gonk/nsAppShell.h    |   8 -
 widget/gonk/nsWindow.cpp    |  35 +-
 9 files changed, 35 insertions(+), 735 deletions(-)
 delete mode 100644 b2g/app/BootAnimation.cpp
 delete mode 100644 b2g/app/BootAnimation.h

diff --git a/b2g/app/BootAnimation.cpp b/b2g/app/BootAnimation.cpp
deleted file mode 100644
index 5aa2ac5a85c6..000000000000
--- a/b2g/app/BootAnimation.cpp
+++ /dev/null
@@ -1,657 +0,0 @@
-/* Copyright 2012 Mozilla Foundation and Mozilla contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include 
-#include 
-#include 
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include "mozilla/Util.h"
-#include "mozilla/NullPtr.h"
-#include "png.h"
-
-#include "android/log.h"
-#include "ui/FramebufferNativeWindow.h"
-#include "hardware_legacy/power.h"
-
-#define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "Gonk" , ## args)
-#define LOGW(args...) __android_log_print(ANDROID_LOG_WARN, "Gonk", ## args)
-#define LOGE(args...) __android_log_print(ANDROID_LOG_ERROR, "Gonk", ## args)
-
-using namespace android;
-using namespace mozilla;
-using namespace std;
-
-static sp gNativeWindow;
-static pthread_t sAnimationThread;
-static bool sRunAnimation;
-
-/* See http://www.pkware.com/documents/casestudies/APPNOTE.TXT */
-struct local_file_header {
-    uint32_t signature;
-    uint16_t min_version;
-    uint16_t general_flag;
-    uint16_t compression;
-    uint16_t lastmod_time;
-    uint16_t lastmod_date;
-    uint32_t crc32;
-    uint32_t compressed_size;
-    uint32_t uncompressed_size;
-    uint16_t filename_size;
-    uint16_t extra_field_size;
-    char     data[0];
-
-    uint32_t GetDataSize() const
-    {
-        return letoh32(uncompressed_size);
-    }
-
-    uint32_t GetSize() const
-    {
-        /* XXX account for data descriptor */
-        return sizeof(local_file_header) + letoh16(filename_size) +
-               letoh16(extra_field_size) + GetDataSize();
-    }
-
-    const char * GetData() const
-    {
-        return data + letoh16(filename_size) + letoh16(extra_field_size);
-    }
-} __attribute__((__packed__));
-
-struct data_descriptor {
-    uint32_t crc32;
-    uint32_t compressed_size;
-    uint32_t uncompressed_size;
-} __attribute__((__packed__));
-
-struct cdir_entry {
-    uint32_t signature;
-    uint16_t creator_version;
-    uint16_t min_version;
-    uint16_t general_flag;
-    uint16_t compression;
-    uint16_t lastmod_time;
-    uint16_t lastmod_date;
-    uint32_t crc32;
-    uint32_t compressed_size;
-    uint32_t uncompressed_size;
-    uint16_t filename_size;
-    uint16_t extra_field_size;
-    uint16_t file_comment_size;
-    uint16_t disk_num;
-    uint16_t internal_attr;
-    uint32_t external_attr;
-    uint32_t offset;
-    char     data[0];
-
-    uint32_t GetDataSize() const
-    {
-        return letoh32(compressed_size);
-    }
-
-    uint32_t GetSize() const
-    {
-        return sizeof(cdir_entry) + letoh16(filename_size) +
-               letoh16(extra_field_size) + letoh16(file_comment_size);
-    }
-
-    bool Valid() const
-    {
-        return signature == htole32(0x02014b50);
-    }
-} __attribute__((__packed__));
-
-struct cdir_end {
-    uint32_t signature;
-    uint16_t disk_num;
-    uint16_t cdir_disk;
-    uint16_t disk_entries;
-    uint16_t cdir_entries;
-    uint32_t cdir_size;
-    uint32_t cdir_offset;
-    uint16_t comment_size;
-    char     comment[0];
-
-    bool Valid() const
-    {
-        return signature == htole32(0x06054b50);
-    }
-} __attribute__((__packed__));
-
-/* We don't have access to libjar and the zip reader in android
- * doesn't quite fit what we want to do. */
-class ZipReader {
-    const char *mBuf;
-    const cdir_end *mEnd;
-    const char *mCdir_limit;
-    uint32_t mBuflen;
-
-public:
-    ZipReader() : mBuf(nullptr) {}
-    ~ZipReader() {
-        if (mBuf)
-            munmap((void *)mBuf, mBuflen);
-    }
-
-    bool OpenArchive(const char *path)
-    {
-        int fd;
-        do {
-            fd = open(path, O_RDONLY);
-        } while (fd == -1 && errno == EINTR);
-        if (fd == -1)
-            return false;
-
-        struct stat sb;
-        if (fstat(fd, &sb) == -1 || sb.st_size < sizeof(cdir_end)) {
-            close(fd);
-            return false;
-        }
-
-        mBuflen = sb.st_size;
-        mBuf = (char *)mmap(nullptr, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
-        close(fd);
-
-        if (!mBuf) {
-            return false;
-        }
-
-        madvise(mBuf, sb.st_size, MADV_SEQUENTIAL);
-
-        mEnd = (cdir_end *)(mBuf + mBuflen - sizeof(cdir_end));
-        while (!mEnd->Valid() &&
-               (char *)mEnd > mBuf) {
-            mEnd = (cdir_end *)((char *)mEnd - 1);
-        }
-
-        mCdir_limit = mBuf + letoh32(mEnd->cdir_offset) + letoh32(mEnd->cdir_size);
-
-        if (!mEnd->Valid() || mCdir_limit > (char *)mEnd) {
-            munmap((void *)mBuf, mBuflen);
-            mBuf = nullptr;
-            return false;
-        }
-
-        return true;
-    }
-
-    /* Pass null to get the first cdir entry */
-    const cdir_entry * GetNextEntry(const cdir_entry *prev)
-    {
-        const cdir_entry *entry;
-        if (prev)
-            entry = (cdir_entry *)((char *)prev + prev->GetSize());
-        else
-            entry = (cdir_entry *)(mBuf + letoh32(mEnd->cdir_offset));
-
-        if (((char *)entry + entry->GetSize()) > mCdir_limit ||
-            !entry->Valid())
-            return nullptr;
-        return entry;
-    }
-
-    string GetEntryName(const cdir_entry *entry)
-    {
-        uint16_t len = letoh16(entry->filename_size);
-
-        string name;
-        name.append(entry->data, len);
-        return name;
-    }
-
-    const local_file_header * GetLocalEntry(const cdir_entry *entry)
-    {
-        const local_file_header * data =
-            (local_file_header *)(mBuf + letoh32(entry->offset));
-        if (((char *)data + data->GetSize()) > (char *)mEnd)
-            return nullptr;
-        return data;
-    }
-};
-
-struct AnimationFrame {
-    char path[256];
-    char *buf;
-    uint16_t width;
-    uint16_t height;
-    const local_file_header *file;
-
-    AnimationFrame() : buf(nullptr) {}
-    AnimationFrame(const AnimationFrame &frame) : buf(nullptr) {
-        strncpy(path, frame.path, sizeof(path));
-        file = frame.file;
-    }
-    ~AnimationFrame()
-    {
-        if (buf)
-            free(buf);
-    }
-
-    bool operator<(const AnimationFrame &other) const
-    {
-        return strcmp(path, other.path) < 0;
-    }
-
-    void ReadPngFrame();
-};
-
-struct AnimationPart {
-    int32_t count;
-    int32_t pause;
-    char path[256];
-    vector frames;
-};
-
-using namespace android;
-
-struct RawReadState {
-    const char *start;
-    uint32_t offset;
-    uint32_t length;
-};
-
-static void
-RawReader(png_structp png_ptr, png_bytep data, png_size_t length)
-{
-    RawReadState *state = (RawReadState *)png_get_io_ptr(png_ptr);
-    if (length > (state->length - state->offset))
-        png_error(png_ptr, "Read too long");
-
-    memcpy(data, state->start + state->offset, length);
-    state->offset += length;
-}
-
-void
-AnimationFrame::ReadPngFrame()
-{
-    png_structp pngread = png_create_read_struct(PNG_LIBPNG_VER_STRING,
-                                                 nullptr, nullptr, nullptr);
-
-    png_infop pnginfo = png_create_info_struct(pngread);
-
-    RawReadState state;
-    state.start = file->GetData();
-    state.length = file->GetDataSize();
-    state.offset = 0;
-
-    png_set_read_fn(pngread, &state, RawReader);
-
-    setjmp(png_jmpbuf(pngread));
-
-    png_read_info(pngread, pnginfo);
-
-    width = png_get_image_width(pngread, pnginfo);
-    height = png_get_image_height(pngread, pnginfo);
-    buf = (char *)malloc(width * height * 3);
-
-    vector rows(height + 1);
-    uint32_t stride = width * 3;
-    for (int i = 0; i < height; i++) {
-        rows[i] = buf + (stride * i);
-    }
-    rows[height] = nullptr;
-    png_set_palette_to_rgb(pngread);
-    png_read_image(pngread, (png_bytepp)&rows.front());
-    png_destroy_read_struct(&pngread, &pnginfo, nullptr);
-}
-
-static const EGLint kEGLConfigAttribs[] = {
-    EGL_SURFACE_TYPE,    EGL_WINDOW_BIT,
-    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-    EGL_NONE
-};
-
-static bool
-CreateConfig(EGLConfig* aConfig, EGLDisplay display, int format)
-{
-    EGLConfig configs[64];
-    EGLint ncfg = ArrayLength(configs);
-
-    if (!eglChooseConfig(display, kEGLConfigAttribs,
-                         configs, ncfg, &ncfg) ||
-        ncfg < 1) {
-        return false;
-    }
-
-    for (int j = 0; j < ncfg; ++j) {
-        EGLConfig config = configs[j];
-        EGLint id;
-
-        if (eglGetConfigAttrib(display, config,
-                               EGL_NATIVE_VISUAL_ID, &id) &&
-            id > 0 && id == format)
-        {
-            *aConfig = config;
-            return true;
-        }
-    }
-    return false;
-}
-
-static void *
-AnimationThread(void *)
-{
-    ZipReader reader;
-    if (!reader.OpenArchive("/system/media/bootanimation.zip")) {
-        LOGW("Could not open boot animation");
-        return nullptr;
-    }
-
-    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-    eglInitialize(display, nullptr, nullptr);
-
-    int format;
-    ANativeWindow const * const window = gNativeWindow.get();
-    window->query(window, NATIVE_WINDOW_FORMAT, &format);
-
-    EGLConfig config = NULL;
-    CreateConfig(&config, display, format);
-    if (!config) {
-        LOGW("Could not find config for pixel format");
-        return nullptr;
-    }
-
-    EGLSurface surface = eglCreateWindowSurface(display, config, gNativeWindow.get(), nullptr);
-
-    const cdir_entry *entry = nullptr;
-    const local_file_header *file = nullptr;
-    while ((entry = reader.GetNextEntry(entry))) {
-        string name = reader.GetEntryName(entry);
-        if (!name.compare("desc.txt")) {
-            file = reader.GetLocalEntry(entry);
-            break;
-        }
-    }
-
-    if (!file) {
-        LOGW("Could not find desc.txt in boot animation");
-        return nullptr;
-    }
-
-    string descCopy;
-    descCopy.append(file->GetData(), entry->GetDataSize());
-    int32_t width, height, fps;
-    const char *line = descCopy.c_str();
-    const char *end;
-    bool headerRead = true;
-    vector parts;
-
-    /*
-     * bootanimation.zip
-     *
-     * This is the boot animation file format that Android uses.
-     * It's a zip file with a directories containing png frames
-     * and a desc.txt that describes how they should be played.
-     *
-     * desc.txt contains two types of lines
-     * 1. [width] [height] [fps]
-     *    There is one of these lines per bootanimation.
-     *    If the width and height are smaller than the screen,
-     *    the frames are centered on a black background.
-     *    XXX: Currently we stretch instead of centering the frame.
-     * 2. p [count] [pause] [path]
-     *    This describes one animation part.
-     *    Each animation part is played in sequence.
-     *    An animation part contains all the files/frames in the
-     *    directory specified in [path]
-     *    [count] indicates the number of times this part repeats.
-     *    [pause] indicates the number of frames that this part
-     *    should pause for after playing the full sequence but
-     *    before repeating.
-     */
-
-    do {
-        end = strstr(line, "\n");
-
-        AnimationPart part;
-        if (headerRead &&
-            sscanf(line, "%d %d %d", &width, &height, &fps) == 3) {
-            headerRead = false;
-        } else if (sscanf(line, "p %d %d %s",
-                          &part.count, &part.pause, part.path)) {
-            parts.push_back(part);
-        }
-    } while (end && *(line = end + 1));
-
-    for (uint32_t i = 0; i < parts.size(); i++) {
-        AnimationPart &part = parts[i];
-        entry = nullptr;
-        char search[256];
-        snprintf(search, sizeof(search), "%s/", part.path);
-        while ((entry = reader.GetNextEntry(entry))) {
-            string name = reader.GetEntryName(entry);
-            if (name.find(search) ||
-                !entry->GetDataSize() ||
-                name.length() >= 256)
-                continue;
-
-            part.frames.push_back();
-            AnimationFrame &frame = part.frames.back();
-            strcpy(frame.path, name.c_str());
-            frame.file = reader.GetLocalEntry(entry);
-        }
-
-        sort(part.frames.begin(), part.frames.end());
-    }
-
-    static EGLint gContextAttribs[] = {
-        EGL_CONTEXT_CLIENT_VERSION, 2,
-        EGL_NONE, 0
-    };
-    EGLContext context = eglCreateContext(display, config, EGL_NO_CONTEXT, gContextAttribs);
-
-    eglMakeCurrent(display, surface, surface, context);
-    glEnable(GL_TEXTURE_2D);
-
-    const char *vsString =
-        "attribute vec2 aPosition; "
-        "attribute vec2 aTexCoord; "
-        "varying vec2 vTexCoord; "
-        "void main() { "
-        "  gl_Position = vec4(aPosition, 0.0, 1.0); "
-        "  vTexCoord = aTexCoord; "
-        "}";
-
-    const char *fsString =
-        "precision mediump float; "
-        "varying vec2 vTexCoord; "
-        "uniform sampler2D sTexture; "
-        "void main() { "
-        "  gl_FragColor = vec4(texture2D(sTexture, vTexCoord).rgb, 1.0); "
-        "}";
-
-    GLint status;
-    GLuint vsh = glCreateShader(GL_VERTEX_SHADER);
-    glShaderSource(vsh, 1, &vsString, nullptr);
-    glCompileShader(vsh);
-    glGetShaderiv(vsh, GL_COMPILE_STATUS, &status);
-    if (!status) {
-        LOGE("Failed to compile vertex shader");
-        return nullptr;
-    }
-
-    GLuint fsh = glCreateShader(GL_FRAGMENT_SHADER);
-    glShaderSource(fsh, 1, &fsString, nullptr);
-    glCompileShader(fsh);
-    glGetShaderiv(fsh, GL_COMPILE_STATUS, &status);
-    if (!status) {
-        LOGE("Failed to compile fragment shader");
-        return nullptr;
-    }
-
-    GLuint programId = glCreateProgram();
-    glAttachShader(programId, vsh);
-    glAttachShader(programId, fsh);
-
-    glLinkProgram(programId);
-    glGetProgramiv(programId, GL_LINK_STATUS, &status);
-    if (!status) {
-        LOG("Failed to link program");
-        return nullptr;
-    }
-
-    GLint positionLoc = glGetAttribLocation(programId, "aPosition");
-    GLint texCoordLoc = glGetAttribLocation(programId, "aTexCoord");
-    GLint textureLoc = glGetUniformLocation(programId, "sTexture");
-
-    glUseProgram(programId);
-
-    GLfloat texCoords[] = { 0.0f, 1.0f,
-                            0.0f, 0.0f,
-                            1.0f, 1.0f,
-                            1.0f, 0.0f };
-
-    GLfloat vCoords[] = { -1.0f, -1.0f,
-                          -1.0f,  1.0f,
-                           1.0f, -1.0f,
-                           1.0f,  1.0f };
-
-    GLuint rectBuf, texBuf;
-    glGenBuffers(1, &rectBuf);
-    glGenBuffers(1, &texBuf);
-
-    GLuint tex;
-    glGenTextures(1, &tex);
-    glActiveTexture(GL_TEXTURE0);
-    glBindTexture(GL_TEXTURE_2D, tex);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
-    glEnableVertexAttribArray(positionLoc);
-    glBindBuffer(GL_ARRAY_BUFFER, rectBuf);
-    glBufferData(GL_ARRAY_BUFFER, sizeof(vCoords), vCoords, GL_STATIC_DRAW);
-    glVertexAttribPointer(positionLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
-
-    glEnableVertexAttribArray(texCoordLoc);
-    glBindBuffer(GL_ARRAY_BUFFER, texBuf);
-    glBufferData(GL_ARRAY_BUFFER, sizeof(texCoords), texCoords, GL_STATIC_DRAW);
-    glVertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
-    glBindBuffer(GL_ARRAY_BUFFER, 0);
-
-    glUniform1i(textureLoc, 0);
-
-    uint32_t frameDelayUs = 1000000 / fps;
-
-    for (uint32_t i = 0; i < parts.size(); i++) {
-        AnimationPart &part = parts[i];
-
-        uint32_t j = 0;
-        while (sRunAnimation && (!part.count || j++ < part.count)) {
-            for (uint32_t k = 0; k < part.frames.size(); k++) {
-                struct timeval tv1, tv2;
-                gettimeofday(&tv1, nullptr);
-                AnimationFrame &frame = part.frames[k];
-                if (!frame.buf) {
-                    frame.ReadPngFrame();
-                }
-
-                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
-                             frame.width, frame.height, 0,
-                             GL_RGB, GL_UNSIGNED_BYTE, frame.buf);
-                glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
-                gettimeofday(&tv2, nullptr);
-
-                timersub(&tv2, &tv1, &tv2);
-
-                if (tv2.tv_usec < frameDelayUs) {
-                    usleep(frameDelayUs - tv2.tv_usec);
-                } else {
-                    LOGW("Frame delay is %d us but decoding took %d us", frameDelayUs, tv2.tv_usec);
-                }
-
-                eglSwapBuffers(display, surface);
-
-                if (part.count && j >= part.count) {
-                    free(frame.buf);
-                    frame.buf = nullptr;
-                }
-            }
-            usleep(frameDelayUs * part.pause);
-        }
-    }
-    glBindTexture(GL_TEXTURE_2D, 0);
-    glUseProgram(0);
-    glDeleteTextures(1, &tex);
-    glDeleteBuffers(1, &texBuf);
-    glDeleteBuffers(1, &rectBuf);
-    glDeleteProgram(programId);
-    glDeleteShader(fsh);
-    glDeleteShader(vsh);
-
-    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-
-    eglDestroyContext(display, context);
-    eglDestroySurface(display, surface);
-    return nullptr;
-}
-
-static int
-CancelBufferNoop(ANativeWindow* aWindow, android_native_buffer_t* aBuffer)
-{
-    return 0;
-}
-
-__attribute__ ((visibility ("default")))
-FramebufferNativeWindow*
-NativeWindow()
-{
-    if (gNativeWindow.get()) {
-        return gNativeWindow.get();
-    }
-
-    // Some gralloc HALs need this in order to open the
-    // framebuffer device after we restart with the screen off.
-    //
-    // NB: this *must* run BEFORE allocating the
-    // FramebufferNativeWindow.  Do not separate these two C++
-    // statements.
-    set_screen_state(1);
-
-    // We (apparently) don't have a way to tell if allocating the
-    // fbs succeeded or failed.
-    gNativeWindow = new FramebufferNativeWindow();
-
-    // Bug 776742: FrambufferNativeWindow doesn't set the cancelBuffer
-    // function pointer, causing EGL to segfault when the window surface
-    // is destroyed (i.e. on process exit). This workaround stops us
-    // from hard crashing in that situation.
-    gNativeWindow->cancelBuffer = CancelBufferNoop;
-
-    sRunAnimation = true;
-    pthread_create(&sAnimationThread, nullptr, AnimationThread, nullptr);
-
-    return gNativeWindow.get();
-}
-
-
-__attribute__ ((visibility ("default")))
-void
-StopBootAnimation()
-{
-    if (sRunAnimation) {
-        sRunAnimation = false;
-        pthread_join(sAnimationThread, nullptr);
-    }
-}
diff --git a/b2g/app/BootAnimation.h b/b2g/app/BootAnimation.h
deleted file mode 100644
index 4fa9c530b5ea..000000000000
--- a/b2g/app/BootAnimation.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef BOOTANIMATION_H
-#define BOOTANIMATION_H
-
-namespace android {
-class FramebufferNativeWindow;
-}
-
-/* This returns a FramebufferNativeWindow if one exists.
- * If not, one is created and the boot animation is started. */
-__attribute__ ((weak))
-android::FramebufferNativeWindow* NativeWindow();
-
-/* This stops the boot animation if it's still running. */
-__attribute__ ((weak))
-void StopBootAnimation();
-
-#endif /* BOOTANIMATION_H */
diff --git a/b2g/app/Makefile.in b/b2g/app/Makefile.in
index 7bbbcff49604..e08be0185beb 100644
--- a/b2g/app/Makefile.in
+++ b/b2g/app/Makefile.in
@@ -24,13 +24,6 @@ endif
 
 CPPSRCS = nsBrowserApp.cpp
 
-ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
-CPPSRCS += BootAnimation.cpp
-LIBS += -lpng -lGLESv2 -lEGL -lui -lhardware_legacy -lhardware -lcutils
-LOCAL_INCLUDES += -I$(ANDROID_SOURCE)/external/libpng
-OS_LDFLAGS += -Wl,--export-dynamic
-endif
-
 LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
 LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/base
 LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/build
diff --git a/b2g/app/nsBrowserApp.cpp b/b2g/app/nsBrowserApp.cpp
index 1d5440f01547..d7f9d6910621 100644
--- a/b2g/app/nsBrowserApp.cpp
+++ b/b2g/app/nsBrowserApp.cpp
@@ -28,11 +28,6 @@
 #define snprintf _snprintf
 #define strcasecmp _stricmp
 #endif
-
-#ifdef MOZ_WIDGET_GONK
-#include "BootAnimation.h"
-#endif
-
 #include "BinaryPath.h"
 
 #include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL
@@ -144,11 +139,6 @@ static int do_main(int argc, char* argv[])
     argc -= 2;
   }
 
-#ifdef MOZ_WIDGET_GONK
-  /* Called to start the boot animation */
-  (void) NativeWindow();
-#endif
-
   if (appini) {
     nsXREAppData *appData;
     rv = XRE_CreateAppData(appini, &appData);
diff --git a/b2g/chrome/content/shell.js b/b2g/chrome/content/shell.js
index e8c76308ec41..c19a6a4d5ee3 100644
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -396,8 +396,6 @@ var shell = {
           content.removeEventListener('load', shell_homeLoaded);
           shell.isHomeLoaded = true;
 
-          Services.obs.notifyObservers(null, "browser-ui-startup-complete", "");
-
           if ('pendingChromeEvents' in shell) {
             shell.pendingChromeEvents.forEach((shell.sendChromeEvent).bind(shell));
           }
diff --git a/widget/gonk/Makefile.in b/widget/gonk/Makefile.in
index 2edb42995bad..21a2358147b5 100644
--- a/widget/gonk/Makefile.in
+++ b/widget/gonk/Makefile.in
@@ -73,7 +73,6 @@ include $(topsrcdir)/config/rules.mk
 DEFINES += -D_IMPL_NS_WIDGET -DHAVE_OFF64_T -DSK_BUILD_FOR_ANDROID_NDK
 
 LOCAL_INCLUDES += \
-	-I$(topsrcdir)/b2g/app \
 	-I$(topsrcdir)/widget/xpwidgets \
 	-I$(topsrcdir)/widget/shared \
 	-I$(topsrcdir)/dom/system/android \
diff --git a/widget/gonk/nsAppShell.cpp b/widget/gonk/nsAppShell.cpp
index 1c14b5639feb..2d1663c35f15 100644
--- a/widget/gonk/nsAppShell.cpp
+++ b/widget/gonk/nsAppShell.cpp
@@ -65,15 +65,12 @@
 using namespace android;
 using namespace mozilla;
 using namespace mozilla::dom;
-using namespace mozilla::services;
 
 bool gDrawRequest = false;
 static nsAppShell *gAppShell = NULL;
 static int epollfd = 0;
 static int signalfds[2] = {0};
 
-NS_IMPL_ISUPPORTS_INHERITED1(nsAppShell, nsBaseAppShell, nsIObserver)
-
 namespace mozilla {
 
 bool ProcessNextEvent()
@@ -589,7 +586,6 @@ GeckoInputDispatcher::unregisterInputChannel(const sp& inputChanne
 nsAppShell::nsAppShell()
     : mNativeCallbackRequest(false)
     , mHandlers()
-    , mEnableDraw(false)
 {
     gAppShell = this;
 }
@@ -624,39 +620,16 @@ nsAppShell::Init()
 
     InitGonkMemoryPressureMonitoring();
 
-    nsCOMPtr obsServ = GetObserverService();
-    if (obsServ) {
-        obsServ->AddObserver(this, "browser-ui-startup-complete", false);
-    }
-
     // Delay initializing input devices until the screen has been
     // initialized (and we know the resolution).
     return rv;
 }
 
-NS_IMETHODIMP
-nsAppShell::Observe(nsISupports* aSubject,
-                    const char* aTopic,
-                    const PRUnichar* aData)
-{
-    if (strcmp(aTopic, "browser-ui-startup-complete")) {
-        return nsBaseAppShell::Observe(aSubject, aTopic, aData);
-    }
-
-    mEnableDraw = true;
-    NotifyEvent();
-    return NS_OK;
-}
-
 NS_IMETHODIMP
 nsAppShell::Exit()
 {
-    OrientationObserver::ShutDown();
-    nsCOMPtr obsServ = GetObserverService();
-    if (obsServ) {
-        obsServ->RemoveObserver(this, "browser-ui-startup-complete");
-    }
-    return nsBaseAppShell::Exit();
+  OrientationObserver::ShutDown();
+  return nsBaseAppShell::Exit();
 }
 
 void
@@ -728,7 +701,7 @@ nsAppShell::ProcessNextNativeEvent(bool mayWait)
         NativeEventCallback();
     }
 
-    if (gDrawRequest && mEnableDraw) {
+    if (gDrawRequest) {
         gDrawRequest = false;
         nsWindow::DoDraw();
     }
diff --git a/widget/gonk/nsAppShell.h b/widget/gonk/nsAppShell.h
index ef63c4639b72..f65c5b834889 100644
--- a/widget/gonk/nsAppShell.h
+++ b/widget/gonk/nsAppShell.h
@@ -64,9 +64,6 @@ class nsAppShell : public nsBaseAppShell {
 public:
     nsAppShell();
 
-    NS_DECL_ISUPPORTS_INHERITED
-    NS_DECL_NSIOBSERVER
-
     nsresult Init();
 
     NS_IMETHOD Exit() MOZ_OVERRIDE;
@@ -90,11 +87,6 @@ private:
 
     // This is somewhat racy but is perfectly safe given how the callback works
     bool mNativeCallbackRequest;
-
-    // This gets flipped when we observe a browser-ui-startup-complete.
-    // browser-ui-startup-complete means that we're really ready to draw
-    // and can stop the boot animation
-    bool mEnableDraw;
     nsTArray mHandlers;
 
     android::sp               mEventHub;
diff --git a/widget/gonk/nsWindow.cpp b/widget/gonk/nsWindow.cpp
index 535b538581b8..b6c8b8ae7b57 100644
--- a/widget/gonk/nsWindow.cpp
+++ b/widget/gonk/nsWindow.cpp
@@ -24,7 +24,6 @@
 #include "mozilla/Hal.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/FileUtils.h"
-#include "BootAnimation.h"
 #include "Framebuffer.h"
 #include "gfxContext.h"
 #include "gfxPlatform.h"
@@ -65,6 +64,7 @@ static nsRefPtr sGLContext;
 static nsTArray sTopWindows;
 static nsWindow *gWindowToRedraw = nullptr;
 static nsWindow *gFocusedWindow = nullptr;
+static android::FramebufferNativeWindow *gNativeWindow = nullptr;
 static bool sFramebufferOpen;
 static bool sUsingOMTC;
 static bool sUsingHwc;
@@ -74,6 +74,37 @@ static pthread_t sFramebufferWatchThread;
 
 namespace {
 
+static int
+CancelBufferNoop(ANativeWindow* aWindow, android_native_buffer_t* aBuffer)
+{
+    return 0;
+}
+
+android::FramebufferNativeWindow*
+NativeWindow()
+{
+    if (!gNativeWindow) {
+        // Some gralloc HALs need this in order to open the
+        // framebuffer device after we restart with the screen off.
+        //
+        // NB: this *must* run BEFORE allocating the
+        // FramebufferNativeWindow.  Do not separate these two C++
+        // statements.
+        hal::SetScreenEnabled(true);
+
+        // We (apparently) don't have a way to tell if allocating the
+        // fbs succeeded or failed.
+        gNativeWindow = new android::FramebufferNativeWindow();
+
+        // Bug 776742: FrambufferNativeWindow doesn't set the cancelBuffer
+        // function pointer, causing EGL to segfault when the window surface
+        // is destroyed (i.e. on process exit). This workaround stops us
+        // from hard crashing in that situation.
+        gNativeWindow->cancelBuffer = CancelBufferNoop;
+    }
+    return gNativeWindow;
+}
+
 static uint32_t
 EffectiveScreenRotation()
 {
@@ -212,8 +243,6 @@ nsWindow::DoDraw(void)
         return;
     }
 
-    StopBootAnimation();
-
     nsIntRegion region = gWindowToRedraw->mDirtyRegion;
     gWindowToRedraw->mDirtyRegion.SetEmpty();
 

From c4107853a9e9e2df6dbdb224617f72733d9c76d2 Mon Sep 17 00:00:00 2001
From: Mark Hammond 
Date: Tue, 20 Nov 2012 12:54:50 +1100
Subject: [PATCH 34/57] Bug 808235 - give chatbox focus when restored.  r=jaws

--HG--
extra : rebase_source : 6c224570314d77c83405b3345ee9b858f0df2fac
---
 browser/base/content/browser-social.js        |  5 +-
 browser/base/content/socialchat.xml           | 50 ++++++++++++++++---
 .../content/test/browser_social_chatwindow.js |  4 +-
 3 files changed, 46 insertions(+), 13 deletions(-)

diff --git a/browser/base/content/browser-social.js b/browser/base/content/browser-social.js
index c36ac22f755e..c1f3bb6d7664 100644
--- a/browser/base/content/browser-social.js
+++ b/browser/base/content/browser-social.js
@@ -254,10 +254,7 @@ let SocialChatBar = {
     }
   },
   focus: function SocialChatBar_focus() {
-    if (!this.chatbar.selectedChat)
-      return;
-    let commandDispatcher = gBrowser.ownerDocument.commandDispatcher;
-    commandDispatcher.advanceFocusIntoSubtree(this.chatbar.selectedChat);
+    this.chatbar.focus();
   }
 }
 
diff --git a/browser/base/content/socialchat.xml b/browser/base/content/socialchat.xml
index 29b64706eaee..501ae3dc4c99 100644
--- a/browser/base/content/socialchat.xml
+++ b/browser/base/content/socialchat.xml
@@ -27,13 +27,20 @@
         
           return this.getAttribute("minimized") == "true";
         
-        
+        
+            // this chat gets selected.
+            parent.selectedChat = this;
+          }
+        ]]>
       
 
       
@@ -123,6 +130,15 @@
         document.getAnonymousElementByAttribute(this, "anonid", "nub");
       
 
+      
+        
+      
+
       
         
       
 
+      
+        
+      
+
       
         
         
         
         
Date: Mon, 19 Nov 2012 17:54:12 -0800
Subject: [PATCH 35/57] Bug 813383 - Use
 firstElementChild/nextElementSibling/lastElementChild instead of
 firstChild/nextSibling/lastChild when possible. r=felipe

---
 browser/base/content/socialchat.xml | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/browser/base/content/socialchat.xml b/browser/base/content/socialchat.xml
index 501ae3dc4c99..64cdb7fdd997 100644
--- a/browser/base/content/socialchat.xml
+++ b/browser/base/content/socialchat.xml
@@ -179,11 +179,11 @@
         
       
@@ -191,11 +191,11 @@
       
         
       
@@ -359,8 +359,8 @@
       
         
Date: Mon, 19 Nov 2012 17:52:35 -0800
Subject: [PATCH 36/57] Bug 810062 - Toggle JSOPTIONs before the compartment
 creation. r=bhackett

---
 js/xpconnect/idl/xpccomponents.idl |  2 +-
 js/xpconnect/shell/xpcshell.cpp    | 58 +++++++++++++++++++++++-------
 2 files changed, 46 insertions(+), 14 deletions(-)

diff --git a/js/xpconnect/idl/xpccomponents.idl b/js/xpconnect/idl/xpccomponents.idl
index b6997c992088..e8036f760d0f 100644
--- a/js/xpconnect/idl/xpccomponents.idl
+++ b/js/xpconnect/idl/xpccomponents.idl
@@ -377,7 +377,7 @@ interface nsIXPCComponents_Utils : nsISupports
 
     [implicit_jscontext]
     attribute boolean strict_mode;
-    
+
     [implicit_jscontext]
     attribute boolean ion;
 
diff --git a/js/xpconnect/shell/xpcshell.cpp b/js/xpconnect/shell/xpcshell.cpp
index f76826058ebb..f4ce36132b39 100644
--- a/js/xpconnect/shell/xpcshell.cpp
+++ b/js/xpconnect/shell/xpcshell.cpp
@@ -1124,12 +1124,48 @@ static int
 usage(void)
 {
     fprintf(gErrFile, "%s\n", JS_GetImplementationVersion());
-    fprintf(gErrFile, "usage: xpcshell [-g gredir] [-a appdir] [-r manifest]... [-PsSwWxCij] [-v version] [-f scriptfile] [-e script] [scriptfile] [scriptarg...]\n");
+    fprintf(gErrFile, "usage: xpcshell [-g gredir] [-a appdir] [-r manifest]... [-PsSwWxCijmIn] [-v version] [-f scriptfile] [-e script] [scriptfile] [scriptarg...]\n");
     return 2;
 }
 
 extern JSClass global_class;
 
+static void
+ProcessArgsForCompartment(JSContext *cx, char **argv, int argc)
+{
+    for (int i = 0; i < argc; i++) {
+        if (argv[i][0] != '-' || argv[i][1] == '\0')
+            break;
+
+        switch (argv[i][1]) {
+          case 'v':
+          case 'f':
+          case 'e':
+            if (++i == argc)
+                return;
+            break;
+        case 'S':
+            JS_ToggleOptions(cx, JSOPTION_WERROR);
+        case 's':
+            JS_ToggleOptions(cx, JSOPTION_STRICT);
+            break;
+        case 'x':
+            JS_ToggleOptions(cx, JSOPTION_MOAR_XML);
+            break;
+        case 'm':
+            JS_ToggleOptions(cx, JSOPTION_METHODJIT);
+            break;
+        case 'I':
+            JS_ToggleOptions(cx, JSOPTION_COMPILE_N_GO);
+            JS_ToggleOptions(cx, JSOPTION_ION);
+            break;
+        case 'n':
+            JS_ToggleOptions(cx, JSOPTION_TYPE_INFERENCE);
+            break;
+        }
+    }
+}
+
 static int
 ProcessArgs(JSContext *cx, JSObject *obj, char **argv, int argc)
 {
@@ -1210,13 +1246,7 @@ ProcessArgs(JSContext *cx, JSObject *obj, char **argv, int argc)
         case 'w':
             reportWarnings = true;
             break;
-        case 'S':
-            JS_ToggleOptions(cx, JSOPTION_WERROR);
-        case 's':
-            JS_ToggleOptions(cx, JSOPTION_STRICT);
-            break;
         case 'x':
-            JS_ToggleOptions(cx, JSOPTION_MOAR_XML);
             break;
         case 'd':
             xpc_ActivateDebugMode();
@@ -1254,11 +1284,12 @@ ProcessArgs(JSContext *cx, JSObject *obj, char **argv, int argc)
             compileOnly = true;
             isInteractive = false;
             break;
+        case 'S':
+        case 's':
         case 'm':
-            JS_ToggleOptions(cx, JSOPTION_METHODJIT);
-            break;
+        case 'I':
         case 'n':
-            JS_ToggleOptions(cx, JSOPTION_TYPE_INFERENCE);
+            // These options are processed in ProcessArgsForCompartment.
             break;
         default:
             return usage();
@@ -1775,6 +1806,10 @@ main(int argc, char **argv, char **envp)
             return 1;
         }
 
+        argc--;
+        argv++;
+        ProcessArgsForCompartment(cx, argv, argc);
+
         JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_ALLOW_XML);
         xpc_LocalizeContext(cx);
 
@@ -1887,9 +1922,6 @@ main(int argc, char **argv, char **envp)
             JS_DefineProperty(cx, glob, "__LOCATION__", JSVAL_VOID,
                               GetLocationProperty, NULL, 0);
 
-            argc--;
-            argv++;
-
             result = ProcessArgs(cx, glob, argv, argc);
 
 

From 57a17a2534d0baf09f638c9e54718e52cec0f57c Mon Sep 17 00:00:00 2001
From: Matthew Gregan 
Date: Mon, 19 Nov 2012 13:54:29 +1300
Subject: [PATCH 37/57] Bug 812937 - Remove unused audio remoting code. 
 r=cjones

---
 content/media/AudioStream.cpp | 370 ++--------------------------------
 content/media/AudioStream.h   |   2 +-
 dom/ipc/AudioChild.cpp        | 116 -----------
 dom/ipc/AudioChild.h          |  52 -----
 dom/ipc/AudioParent.cpp       | 341 -------------------------------
 dom/ipc/AudioParent.h         |  68 -------
 dom/ipc/ContentChild.cpp      |  29 ---
 dom/ipc/ContentChild.h        |   4 -
 dom/ipc/ContentParent.cpp     |  27 ---
 dom/ipc/ContentParent.h       |   4 -
 dom/ipc/Makefile.in           |  11 -
 dom/ipc/PAudio.ipdl           |  40 ----
 dom/ipc/PContent.ipdl         |   4 -
 dom/ipc/ipdl.mk               |   1 -
 14 files changed, 13 insertions(+), 1056 deletions(-)
 delete mode 100644 dom/ipc/AudioChild.cpp
 delete mode 100644 dom/ipc/AudioChild.h
 delete mode 100644 dom/ipc/AudioParent.cpp
 delete mode 100644 dom/ipc/AudioParent.h
 delete mode 100644 dom/ipc/PAudio.ipdl

diff --git a/content/media/AudioStream.cpp b/content/media/AudioStream.cpp
index 40da163b6704..71b55daa88a2 100644
--- a/content/media/AudioStream.cpp
+++ b/content/media/AudioStream.cpp
@@ -3,13 +3,6 @@
 /* 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 "mozilla/dom/ContentChild.h"
-#include "mozilla/dom/PAudioChild.h"
-#include "mozilla/dom/AudioChild.h"
-#include "nsXULAppAPI.h"
-using namespace mozilla::dom;
-
 #include 
 #include 
 #include "prlog.h"
@@ -19,6 +12,7 @@ using namespace mozilla::dom;
 #include "AudioStream.h"
 #include "nsAlgorithm.h"
 #include "VideoUtils.h"
+#include "mozilla/Monitor.h"
 #include "mozilla/Mutex.h"
 extern "C" {
 #include "sydneyaudio/sydney_audio.h"
@@ -45,12 +39,6 @@ namespace mozilla {
 #define SA_PER_STREAM_VOLUME 1
 #endif
 
-// Android's audio backend is not available in content processes, so
-// audio must be remoted to the parent chrome process.
-#if defined(MOZ_WIDGET_ANDROID)
-#define REMOTE_AUDIO 1
-#endif
-
 #ifdef PR_LOGGING
 PRLogModuleInfo* gAudioStreamLog = nullptr;
 #endif
@@ -69,7 +57,7 @@ class nsNativeAudioStream : public AudioStream
   nsNativeAudioStream();
 
   nsresult Init(int32_t aNumChannels, int32_t aRate,
-                const AudioChannelType aAudioChannelType);
+                const dom::AudioChannelType aAudioChannelType);
   void Shutdown();
   nsresult Write(const AudioDataValue* aBuf, uint32_t aFrames);
   uint32_t Available();
@@ -95,198 +83,6 @@ class nsNativeAudioStream : public AudioStream
 
 };
 
-#if defined(REMOTE_AUDIO)
-class nsRemotedAudioStream : public AudioStream
-{
- public:
-  NS_DECL_ISUPPORTS
-
-  nsRemotedAudioStream();
-  ~nsRemotedAudioStream();
-
-  nsresult Init(int32_t aNumChannels, int32_t aRate,
-                const AudioChannelType aAudioChannelType);
-  void Shutdown();
-  nsresult Write(const AudioDataValue* aBuf, uint32_t aFrames);
-  uint32_t Available();
-  void SetVolume(double aVolume);
-  void Drain();
-  void Pause();
-  void Resume();
-  int64_t GetPosition();
-  int64_t GetPositionInFrames();
-  bool IsPaused();
-  int32_t GetMinWriteSize();
-
-private:
-  nsRefPtr mAudioChild;
-
-  int32_t mBytesPerFrame;
-
-  // True if this audio stream is paused.
-  bool mPaused;
-
-  friend class AudioInitEvent;
-};
-
-class AudioInitEvent : public nsRunnable
-{
- public:
-  AudioInitEvent(nsRemotedAudioStream* owner)
-  {
-    mOwner = owner;
-  }
-
-  NS_IMETHOD Run()
-  {
-    ContentChild * cpc = ContentChild::GetSingleton();
-    NS_ASSERTION(cpc, "Content Protocol is NULL!");
-    mOwner->mAudioChild =  static_cast(cpc->SendPAudioConstructor(mOwner->mChannels,
-                                                                               mOwner->mRate));
-    return NS_OK;
-  }
-
-  nsRefPtr mOwner;
-};
-
-class AudioWriteEvent : public nsRunnable
-{
- public:
-  AudioWriteEvent(AudioChild* aChild,
-                  const AudioDataValue* aBuf,
-                  uint32_t aNumberOfFrames,
-                  uint32_t aBytesPerFrame)
-  {
-    mAudioChild = aChild;
-    mBytesPerFrame = aBytesPerFrame;
-    mBuffer.Assign(reinterpret_cast(aBuf),
-                   aNumberOfFrames * aBytesPerFrame);
-  }
-
-  NS_IMETHOD Run()
-  {
-    if (!mAudioChild->IsIPCOpen())
-      return NS_OK;
-
-    mAudioChild->SendWrite(mBuffer, mBuffer.Length() / mBytesPerFrame);
-    return NS_OK;
-  }
-
-  nsRefPtr mAudioChild;
-  nsCString mBuffer;
-  uint32_t mBytesPerFrame;
-};
-
-class AudioSetVolumeEvent : public nsRunnable
-{
- public:
-  AudioSetVolumeEvent(AudioChild* aChild, double aVolume)
-  {
-    mAudioChild = aChild;
-    mVolume = aVolume;
-  }
-
-  NS_IMETHOD Run()
-  {
-    if (!mAudioChild->IsIPCOpen())
-      return NS_OK;
-
-    mAudioChild->SendSetVolume(mVolume);
-    return NS_OK;
-  }
-
-  nsRefPtr mAudioChild;
-  double mVolume;
-};
-
-
-class AudioMinWriteSizeEvent : public nsRunnable
-{
- public:
-  AudioMinWriteSizeEvent(AudioChild* aChild)
-  {
-    mAudioChild = aChild;
-  }
-
-  NS_IMETHOD Run()
-  {
-    if (!mAudioChild->IsIPCOpen())
-      return NS_OK;
-
-    mAudioChild->SendMinWriteSize();
-    return NS_OK;
-  }
-
-  nsRefPtr mAudioChild;
-};
-
-class AudioDrainEvent : public nsRunnable
-{
- public:
-  AudioDrainEvent(AudioChild* aChild)
-  {
-    mAudioChild = aChild;
-  }
-
-  NS_IMETHOD Run()
-  {
-    if (!mAudioChild->IsIPCOpen())
-      return NS_OK;
-
-    mAudioChild->SendDrain();
-    return NS_OK;
-  }
-
-  nsRefPtr mAudioChild;
-};
-
-
-class AudioPauseEvent : public nsRunnable
-{
- public:
-  AudioPauseEvent(AudioChild* aChild, bool pause)
-  {
-    mAudioChild = aChild;
-    mPause = pause;
-  }
-
-  NS_IMETHOD Run()
-  {
-    if (!mAudioChild->IsIPCOpen())
-      return NS_OK;
-
-    if (mPause)
-      mAudioChild->SendPause();
-    else
-      mAudioChild->SendResume();
-
-    return NS_OK;
-  }
-
-  nsRefPtr mAudioChild;
-  bool mPause;
-};
-
-
-class AudioShutdownEvent : public nsRunnable
-{
- public:
-  AudioShutdownEvent(AudioChild* aChild)
-  {
-    mAudioChild = aChild;
-  }
-
-  NS_IMETHOD Run()
-  {
-    if (mAudioChild->IsIPCOpen())
-      mAudioChild->SendShutdown();
-    return NS_OK;
-  }
-
-  nsRefPtr mAudioChild;
-};
-#endif
-
 #define PREF_VOLUME_SCALE "media.volume_scale"
 #define PREF_USE_CUBEB "media.use_cubeb"
 #define PREF_CUBEB_LATENCY "media.cubeb_latency_ms"
@@ -359,20 +155,20 @@ static uint32_t GetCubebLatency()
 }
 #endif
 
-static sa_stream_type_t ConvertChannelToSAType(AudioChannelType aType)
+static sa_stream_type_t ConvertChannelToSAType(dom::AudioChannelType aType)
 {
   switch(aType) {
-    case AUDIO_CHANNEL_NORMAL:
+    case dom::AUDIO_CHANNEL_NORMAL:
       return SA_STREAM_TYPE_SYSTEM;
-    case AUDIO_CHANNEL_CONTENT:
+    case dom::AUDIO_CHANNEL_CONTENT:
       return SA_STREAM_TYPE_MUSIC;
-    case AUDIO_CHANNEL_NOTIFICATION:
+    case dom::AUDIO_CHANNEL_NOTIFICATION:
       return SA_STREAM_TYPE_NOTIFICATION;
-    case AUDIO_CHANNEL_ALARM:
+    case dom::AUDIO_CHANNEL_ALARM:
       return SA_STREAM_TYPE_ALARM;
-    case AUDIO_CHANNEL_TELEPHONY:
+    case dom::AUDIO_CHANNEL_TELEPHONY:
       return SA_STREAM_TYPE_VOICE_CALL;
-    case AUDIO_CHANNEL_PUBLICNOTIFICATION:
+    case dom::AUDIO_CHANNEL_PUBLICNOTIFICATION:
       return SA_STREAM_TYPE_ENFORCED_AUDIBLE;
     default:
       NS_ERROR("The value of AudioChannelType is invalid");
@@ -458,7 +254,7 @@ nsNativeAudioStream::~nsNativeAudioStream()
 NS_IMPL_THREADSAFE_ISUPPORTS0(nsNativeAudioStream)
 
 nsresult nsNativeAudioStream::Init(int32_t aNumChannels, int32_t aRate,
-                                   const AudioChannelType aAudioChannelType)
+                                   const dom::AudioChannelType aAudioChannelType)
 {
   mRate = aRate;
   mChannels = aNumChannels;
@@ -633,143 +429,6 @@ int32_t nsNativeAudioStream::GetMinWriteSize()
   return static_cast(size / mChannels / sizeof(short));
 }
 
-#if defined(REMOTE_AUDIO)
-nsRemotedAudioStream::nsRemotedAudioStream()
- : mAudioChild(nullptr),
-   mBytesPerFrame(0),
-   mPaused(false)
-{}
-
-nsRemotedAudioStream::~nsRemotedAudioStream()
-{
-  Shutdown();
-}
-
-NS_IMPL_THREADSAFE_ISUPPORTS0(nsRemotedAudioStream)
-
-nsresult
-nsRemotedAudioStream::Init(int32_t aNumChannels,
-                           int32_t aRate, AudioChannelType aAudioChannelType)
-{
-  mRate = aRate;
-  mChannels = aNumChannels;
-  mBytesPerFrame = sizeof(AudioDataValue) * mChannels;
-
-  nsCOMPtr event = new AudioInitEvent(this);
-  NS_DispatchToMainThread(event, NS_DISPATCH_SYNC);
-  return NS_OK;
-}
-
-void
-nsRemotedAudioStream::Shutdown()
-{
-  if (!mAudioChild)
-    return;
-  nsCOMPtr event = new AudioShutdownEvent(mAudioChild);
-  NS_DispatchToMainThread(event);
-  mAudioChild = nullptr;
-}
-
-nsresult
-nsRemotedAudioStream::Write(const AudioDataValue* aBuf, uint32_t aFrames)
-{
-  if (!mAudioChild)
-    return NS_ERROR_FAILURE;
-  nsCOMPtr event = new AudioWriteEvent(mAudioChild,
-                                                    aBuf,
-                                                    aFrames,
-                                                    mBytesPerFrame);
-  NS_DispatchToMainThread(event);
-  mAudioChild->WaitForWrite();
-  return NS_OK;
-}
-
-uint32_t
-nsRemotedAudioStream::Available()
-{
-  return FAKE_BUFFER_SIZE;
-}
-
-int32_t nsRemotedAudioStream::GetMinWriteSize()
-{
-  if (!mAudioChild)
-    return -1;
-  nsCOMPtr event = new AudioMinWriteSizeEvent(mAudioChild);
-  NS_DispatchToMainThread(event);
-  return mAudioChild->WaitForMinWriteSize();
-}
-
-void
-nsRemotedAudioStream::SetVolume(double aVolume)
-{
-  if (!mAudioChild)
-    return;
-  nsCOMPtr event = new AudioSetVolumeEvent(mAudioChild, aVolume);
-  NS_DispatchToMainThread(event);
-}
-
-void
-nsRemotedAudioStream::Drain()
-{
-  if (!mAudioChild)
-    return;
-  nsCOMPtr event = new AudioDrainEvent(mAudioChild);
-  NS_DispatchToMainThread(event);
-  mAudioChild->WaitForDrain();
-}
-
-void
-nsRemotedAudioStream::Pause()
-{
-  mPaused = true;
-  if (!mAudioChild)
-    return;
-  nsCOMPtr event = new AudioPauseEvent(mAudioChild, true);
-  NS_DispatchToMainThread(event);
-}
-
-void
-nsRemotedAudioStream::Resume()
-{
-  mPaused = false;
-  if (!mAudioChild)
-    return;
-  nsCOMPtr event = new AudioPauseEvent(mAudioChild, false);
-  NS_DispatchToMainThread(event);
-}
-
-int64_t nsRemotedAudioStream::GetPosition()
-{
-  int64_t position = GetPositionInFrames();
-  if (position >= 0) {
-    return ((USECS_PER_S * position) / mRate);
-  }
-  return 0;
-}
-
-int64_t
-nsRemotedAudioStream::GetPositionInFrames()
-{
-  if(!mAudioChild)
-    return 0;
-
-  int64_t position = mAudioChild->GetLastKnownPosition();
-  if (position == -1)
-    return 0;
-
-  int64_t time = mAudioChild->GetLastKnownPositionTimestamp();
-  int64_t dt = PR_IntervalToMilliseconds(PR_IntervalNow() - time);
-
-  return position + (mRate * dt / MS_PER_S);
-}
-
-bool
-nsRemotedAudioStream::IsPaused()
-{
-  return mPaused;
-}
-#endif
-
 #if defined(MOZ_CUBEB)
 class nsCircularByteBuffer
 {
@@ -845,7 +504,7 @@ class nsBufferedAudioStream : public AudioStream
   ~nsBufferedAudioStream();
 
   nsresult Init(int32_t aNumChannels, int32_t aRate,
-                const AudioChannelType aAudioChannelType);
+                const dom::AudioChannelType aAudioChannelType);
   void Shutdown();
   nsresult Write(const AudioDataValue* aBuf, uint32_t aFrames);
   uint32_t Available();
@@ -919,11 +578,6 @@ private:
 
 AudioStream* AudioStream::AllocateStream()
 {
-#if defined(REMOTE_AUDIO)
-  if (XRE_GetProcessType() == GeckoProcessType_Content) {
-    return new nsRemotedAudioStream();
-  }
-#endif
 #if defined(MOZ_CUBEB)
   if (GetUseCubeb()) {
     return new nsBufferedAudioStream();
@@ -948,7 +602,7 @@ NS_IMPL_THREADSAFE_ISUPPORTS0(nsBufferedAudioStream)
 
 nsresult
 nsBufferedAudioStream::Init(int32_t aNumChannels, int32_t aRate,
-                            const AudioChannelType aAudioChannelType)
+                            const dom::AudioChannelType aAudioChannelType)
 {
   cubeb* cubebContext = GetCubebContext();
 
diff --git a/content/media/AudioStream.h b/content/media/AudioStream.h
index 6308245493d2..59d5d9495786 100644
--- a/content/media/AudioStream.h
+++ b/content/media/AudioStream.h
@@ -52,7 +52,7 @@ public:
   // Unsafe to call with a monitor held due to synchronous event execution
   // on the main thread, which may attempt to acquire any held monitor.
   virtual nsresult Init(int32_t aNumChannels, int32_t aRate,
-                        const mozilla::dom::AudioChannelType aAudioStreamType) = 0;
+                        const dom::AudioChannelType aAudioStreamType) = 0;
 
   // Closes the stream. All future use of the stream is an error.
   // Unsafe to call with a monitor held due to synchronous event execution
diff --git a/dom/ipc/AudioChild.cpp b/dom/ipc/AudioChild.cpp
deleted file mode 100644
index 872f7a7e406a..000000000000
--- a/dom/ipc/AudioChild.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set sw=2 ts=2 et tw=80 : */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mozilla/dom/AudioChild.h"
-
-namespace mozilla {
-namespace dom {
-NS_IMPL_THREADSAFE_ADDREF(AudioChild);
-NS_IMPL_THREADSAFE_RELEASE(AudioChild);
-
-AudioChild::AudioChild()
-  : mLastPosition(-1),
-    mLastPositionTimestamp(0),
-    mWriteCounter(0),
-    mMinWriteSize(-2),// Initial value, -2, error on -1
-    mAudioReentrantMonitor("AudioChild.mReentrantMonitor"),
-    mIPCOpen(true),
-    mDrained(false)
-{
-  MOZ_COUNT_CTOR(AudioChild);
-}
-
-AudioChild::~AudioChild()
-{
-  MOZ_COUNT_DTOR(AudioChild);
-}
-
-void
-AudioChild::ActorDestroy(ActorDestroyReason aWhy)
-{
-  mIPCOpen = false;
-}
-
-bool
-AudioChild::RecvPositionInFramesUpdate(const int64_t& position,
-                                       const int64_t& time)
-{
-  mLastPosition = position;
-  mLastPositionTimestamp = time;
-  return true;
-}
-
-bool
-AudioChild::RecvDrainDone()
-{
-  ReentrantMonitorAutoEnter mon(mAudioReentrantMonitor);
-  mDrained = true;
-  mAudioReentrantMonitor.NotifyAll();
-  return true;
-}
-
-int32_t
-AudioChild::WaitForMinWriteSize()
-{
-  ReentrantMonitorAutoEnter mon(mAudioReentrantMonitor);
-  // -2 : initial value
-  while (mMinWriteSize == -2 && mIPCOpen) {
-    mAudioReentrantMonitor.Wait();
-  }
-  return mMinWriteSize;
-}
-
-bool
-AudioChild::RecvMinWriteSizeDone(const int32_t& minFrames)
-{
-  ReentrantMonitorAutoEnter mon(mAudioReentrantMonitor);
-  mMinWriteSize = minFrames;
-  mAudioReentrantMonitor.NotifyAll();
-  return true;
-}
-
-void
-AudioChild::WaitForDrain()
-{
-  ReentrantMonitorAutoEnter mon(mAudioReentrantMonitor);
-  while (!mDrained && mIPCOpen) {
-    mAudioReentrantMonitor.Wait();
-  }
-}
-
-bool
-AudioChild::RecvWriteDone()
-{
-  ReentrantMonitorAutoEnter mon(mAudioReentrantMonitor);
-  mWriteCounter += 1;
-  mAudioReentrantMonitor.NotifyAll();
-  return true;
-}
-
-void
-AudioChild::WaitForWrite()
-{
-  ReentrantMonitorAutoEnter mon(mAudioReentrantMonitor);
-  uint64_t writeCounter = mWriteCounter;
-  while (mWriteCounter == writeCounter && mIPCOpen) {
-    mAudioReentrantMonitor.Wait();
-  }
-}
-
-int64_t
-AudioChild::GetLastKnownPosition()
-{
-  return mLastPosition;
-}
-
-int64_t
-AudioChild::GetLastKnownPositionTimestamp()
-{
-  return mLastPositionTimestamp;
-}
-
-} // namespace dom
-} // namespace mozilla
diff --git a/dom/ipc/AudioChild.h b/dom/ipc/AudioChild.h
deleted file mode 100644
index 07a024e6cea0..000000000000
--- a/dom/ipc/AudioChild.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* vim: set sw=4 ts=8 et tw=80 : */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_AudioChild_h
-#define mozilla_dom_AudioChild_h
-
-#include "mozilla/dom/PAudioChild.h"
-#include "mozilla/ReentrantMonitor.h"
-
-namespace mozilla {
-namespace dom {
-
-class AudioChild : public PAudioChild
-{
- public:
-    NS_IMETHOD_(nsrefcnt) AddRef();
-    NS_IMETHOD_(nsrefcnt) Release();
-
-    AudioChild();
-    virtual ~AudioChild();
-    virtual bool RecvPositionInFramesUpdate(const int64_t&, const int64_t&);
-    virtual bool RecvDrainDone();
-    virtual int32_t WaitForMinWriteSize();
-    virtual bool RecvMinWriteSizeDone(const int32_t& frameCount);
-    virtual void WaitForDrain();
-    virtual bool RecvWriteDone();
-    virtual void WaitForWrite();
-    virtual void ActorDestroy(ActorDestroyReason);
-
-    int64_t GetLastKnownPosition();
-    int64_t GetLastKnownPositionTimestamp();
-
-    bool IsIPCOpen() { return mIPCOpen; };
- private:
-    nsAutoRefCnt mRefCnt;
-    NS_DECL_OWNINGTHREAD
-    int64_t mLastPosition;
-    int64_t mLastPositionTimestamp;
-    uint64_t mWriteCounter;
-    int32_t mMinWriteSize;
-    mozilla::ReentrantMonitor mAudioReentrantMonitor;
-    bool mIPCOpen;
-    bool mDrained;
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif
diff --git a/dom/ipc/AudioParent.cpp b/dom/ipc/AudioParent.cpp
deleted file mode 100644
index 986a4a909aa4..000000000000
--- a/dom/ipc/AudioParent.cpp
+++ /dev/null
@@ -1,341 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set sw=2 ts=8 et tw=80 : */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mozilla/dom/AudioParent.h"
-#include "mozilla/unused.h"
-#include "nsThreadUtils.h"
-#include "AudioChannelCommon.h"
-
-// C++ file contents
-namespace mozilla {
-namespace dom {
-
-class AudioWriteDoneEvent : public nsRunnable
-{
- public:
-  AudioWriteDoneEvent(AudioParent* owner)
-  {
-    mOwner = owner;
-  }
-
-  NS_IMETHOD Run()
-  {
-    mOwner->SendWriteDone();
-    return NS_OK;
-  }
-
- private:
-    nsRefPtr mOwner;
-};
-
-class AudioWriteEvent : public nsRunnable
-{
- public:
-  AudioWriteEvent(AudioParent* parent, AudioStream* owner, nsCString data, uint32_t frames)
-  {
-    mParent = parent;
-    mOwner = owner;
-    mData  = data;
-    mFrames = frames;
-  }
-
-  NS_IMETHOD Run()
-  {
-    mOwner->Write(reinterpret_cast(mData.get()), mFrames);
-    nsCOMPtr event = new AudioWriteDoneEvent(mParent);
-    NS_DispatchToMainThread(event);
-    return NS_OK;
-  }
-
- private:
-    nsRefPtr mParent;
-    nsRefPtr mOwner;
-    nsCString mData;
-    uint32_t  mFrames;
-};
-
-class AudioPauseEvent : public nsRunnable
-{
- public:
-  AudioPauseEvent(AudioStream* owner, bool aPause)
-  {
-    mOwner = owner;
-    mPause = aPause;
-  }
-
-  NS_IMETHOD Run()
-  {
-    if (mPause)
-        mOwner->Pause();
-    else
-        mOwner->Resume();
-    return NS_OK;
-  }
-
- private:
-    nsRefPtr mOwner;
-    bool mPause;
-};
-
-class AudioStreamShutdownEvent : public nsRunnable
-{
- public:
-  AudioStreamShutdownEvent(AudioStream* owner)
-  {
-    mOwner = owner;
-  }
-
-  NS_IMETHOD Run()
-  {
-    mOwner->Shutdown();
-    return NS_OK;
-  }
-
- private:
-    nsRefPtr mOwner;
-};
-
-
-class AudioMinWriteSizeDone : public nsRunnable
-{
- public:
-  AudioMinWriteSizeDone(AudioParent* owner, int32_t minFrames)
-  {
-    mOwner = owner;
-    mMinFrames = minFrames;
-  }
-
-  NS_IMETHOD Run()
-  {
-    mOwner->SendMinWriteSizeDone(mMinFrames);
-    return NS_OK;
-  }
-
- private:
-    nsRefPtr mOwner;
-    int32_t mMinFrames;
-};
-
-class AudioMinWriteSizeEvent : public nsRunnable
-{
- public:
-  AudioMinWriteSizeEvent(AudioParent* parent, AudioStream* owner)
-  {
-    mParent = parent;
-    mOwner = owner;
-  }
-
-  NS_IMETHOD Run()
-  {
-    int32_t minFrames = mOwner->GetMinWriteSize();
-    nsCOMPtr event = new AudioMinWriteSizeDone(mParent, minFrames);
-    NS_DispatchToMainThread(event);
-    return NS_OK;
-  }
-
- private:
-    nsRefPtr mOwner;
-    nsRefPtr mParent;
-};
-
-class AudioDrainDoneEvent : public nsRunnable
-{
- public:
-  AudioDrainDoneEvent(AudioParent* owner)
-  {
-    mOwner = owner;
-  }
-
-  NS_IMETHOD Run()
-  {
-    mOwner->SendDrainDone();
-    return NS_OK;
-  }
-
- private:
-    nsRefPtr mOwner;
-};
-
-class AudioDrainEvent : public nsRunnable
-{
- public:
-  AudioDrainEvent(AudioParent* parent, AudioStream* owner)
-  {
-    mParent = parent;
-    mOwner = owner;
-  }
-
-  NS_IMETHOD Run()
-  {
-    mOwner->Drain();
-    nsCOMPtr event = new AudioDrainDoneEvent(mParent);
-    NS_DispatchToMainThread(event);
-    return NS_OK;
-  }
-
- private:
-    nsRefPtr mOwner;
-    nsRefPtr mParent;
-};
-
-NS_IMPL_THREADSAFE_ISUPPORTS1(AudioParent, nsITimerCallback)
-
-nsresult
-AudioParent::Notify(nsITimer* timer)
-{
-  if (!mIPCOpen) {
-    timer->Cancel();
-    return NS_ERROR_FAILURE;
-  }
-
-  NS_ASSERTION(mStream, "AudioStream not initialized.");
-  int64_t position = mStream->GetPositionInFrames();
-  unused << SendPositionInFramesUpdate(position, PR_IntervalNow());
-  return NS_OK;
-}
-
-bool
-AudioParent::RecvWrite(const nsCString& data, const uint32_t& frames)
-{
-  if (!mStream)
-    return false;
-  nsCOMPtr event = new AudioWriteEvent(this, mStream, data, frames);
-  nsCOMPtr thread = mStream->GetThread();
-  thread->Dispatch(event, nsIEventTarget::DISPATCH_NORMAL);
-  return true;
-}
-
-bool
-AudioParent::RecvSetVolume(const float& aVolume)
-{
-  if (!mStream)
-      return false;
-  mStream->SetVolume(aVolume);
-  return true;
-}
-
-bool
-AudioParent::RecvMinWriteSize()
-{
-  if (!mStream)
-    return false;
-  nsCOMPtr event = new AudioMinWriteSizeEvent(this, mStream);
-  nsCOMPtr thread = mStream->GetThread();
-  thread->Dispatch(event, nsIEventTarget::DISPATCH_NORMAL);
-  return true;
-}
-
-bool
-AudioParent::RecvDrain()
-{
-  if (!mStream)
-    return false;
-  nsCOMPtr event = new AudioDrainEvent(this, mStream);
-  nsCOMPtr thread = mStream->GetThread();
-  thread->Dispatch(event, nsIEventTarget::DISPATCH_NORMAL);
-  return true;
-}
-
-bool
-AudioParent::RecvPause()
-{
-  if (!mStream)
-    return false;
-  nsCOMPtr event = new AudioPauseEvent(mStream, true);
-  nsCOMPtr thread = mStream->GetThread();
-  thread->Dispatch(event, nsIEventTarget::DISPATCH_NORMAL);
-  return true;
-}
-
-bool
-AudioParent::RecvResume()
-{
-  if (!mStream)
-    return false;
-  nsCOMPtr event = new AudioPauseEvent(mStream, false);
-  nsCOMPtr thread = mStream->GetThread();
-  thread->Dispatch(event, nsIEventTarget::DISPATCH_NORMAL);
-  return true;
-}
-
-bool
-AudioParent::RecvShutdown()
-{
-  Shutdown();
-  unused << PAudioParent::Send__delete__(this);
-  return true;
-}
-
-bool
-AudioParent::SendMinWriteSizeDone(int32_t minFrames)
-{
-  if (mIPCOpen)
-    return PAudioParent::SendMinWriteSizeDone(minFrames);
-  return true;
-}
-
-bool
-AudioParent::SendDrainDone()
-{
-  if (mIPCOpen)
-    return PAudioParent::SendDrainDone();
-  return true;
-}
-
-bool
-AudioParent::SendWriteDone()
-{
-  if (mIPCOpen)
-    return PAudioParent::SendWriteDone();
-  return true;
-}
-
-AudioParent::AudioParent(int32_t aNumChannels, int32_t aRate)
-  : mIPCOpen(true)
-{
-  mStream = AudioStream::AllocateStream();
-  NS_ASSERTION(mStream, "AudioStream allocation failed.");
-
-  if (NS_FAILED(mStream->Init(aNumChannels, aRate, AUDIO_CHANNEL_NORMAL))) {
-      NS_WARNING("AudioStream initialization failed.");
-      mStream = nullptr;
-      return;
-  }
-
-  mTimer = do_CreateInstance("@mozilla.org/timer;1");
-  mTimer->InitWithCallback(this, 1000, nsITimer::TYPE_REPEATING_SLACK);
-}
-
-AudioParent::~AudioParent()
-{
-}
-
-void
-AudioParent::ActorDestroy(ActorDestroyReason aWhy)
-{
-  mIPCOpen = false;
-
-  Shutdown();
-}
-
-void
-AudioParent::Shutdown()
-{
-  if (mTimer) {
-    mTimer->Cancel();
-    mTimer = nullptr;
-  }
-
-  if (mStream) {
-      nsCOMPtr event = new AudioStreamShutdownEvent(mStream);
-      nsCOMPtr thread = mStream->GetThread();
-      thread->Dispatch(event, nsIEventTarget::DISPATCH_NORMAL);
-      mStream = nullptr;
-  }
-}
-
-} // namespace dom
-} // namespace mozilla
diff --git a/dom/ipc/AudioParent.h b/dom/ipc/AudioParent.h
deleted file mode 100644
index 5c8230d46c26..000000000000
--- a/dom/ipc/AudioParent.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* vim: set sw=4 ts=8 et tw=80 : */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_AudioParent_h
-#define mozilla_dom_AudioParent_h
-
-#include "mozilla/dom/PAudioParent.h"
-#include "AudioStream.h"
-#include "nsITimer.h"
-
-namespace mozilla {
-namespace dom {
-class AudioParent : public PAudioParent, public nsITimerCallback
-{
- public:
-
-    NS_DECL_ISUPPORTS
-    NS_DECL_NSITIMERCALLBACK
-
-    virtual bool
-    RecvWrite(const nsCString& data, const uint32_t& count);
-
-    virtual bool
-    RecvSetVolume(const float& aVolume);
-
-    virtual bool
-    RecvMinWriteSize();
-
-    virtual bool
-    RecvDrain();
-
-    virtual bool
-    RecvPause();
-
-    virtual bool
-    RecvResume();
-
-    virtual bool
-    RecvShutdown();
-
-    virtual bool
-    SendMinWriteSizeDone(int32_t minFrames);
-
-    virtual bool
-    SendDrainDone();
-
-    virtual bool
-    SendWriteDone();
-
-    AudioParent(int32_t aNumChannels, int32_t aRate);
-    virtual ~AudioParent();
-    virtual void ActorDestroy(ActorDestroyReason);
-
-    nsRefPtr mStream;
-    nsCOMPtr mTimer;
-
-private:
-    void Shutdown();
-
-    bool mIPCOpen;
-};
-} // namespace dom
-} // namespace mozilla
-
-#endif
diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp
index bb24336b806a..cd7ac782462c 100644
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -15,9 +15,6 @@
 #include "ContentChild.h"
 #include "CrashReporterChild.h"
 #include "TabChild.h"
-#if defined(MOZ_SYDNEYAUDIO)
-#include "AudioChild.h"
-#endif
 
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/ExternalHelperAppChild.h"
@@ -34,9 +31,6 @@
 #include "mozilla/net/NeckoChild.h"
 #include "mozilla/Preferences.h"
 
-#if defined(MOZ_SYDNEYAUDIO)
-#include "AudioStream.h"
-#endif
 #include "nsIMemoryReporter.h"
 #include "nsIMemoryInfoDumper.h"
 #include "nsIObserverService.h"
@@ -662,29 +656,6 @@ ContentChild::RecvPTestShellConstructor(PTestShellChild* actor)
     return true;
 }
 
-PAudioChild*
-ContentChild::AllocPAudio(const int32_t& numChannels,
-                          const int32_t& rate)
-{
-#if defined(MOZ_SYDNEYAUDIO)
-    AudioChild *child = new AudioChild();
-    NS_ADDREF(child);
-    return child;
-#else
-    return nullptr;
-#endif
-}
-
-bool
-ContentChild::DeallocPAudio(PAudioChild* doomed)
-{
-#if defined(MOZ_SYDNEYAUDIO)
-    AudioChild *child = static_cast(doomed);
-    NS_RELEASE(child);
-#endif
-    return true;
-}
-
 PDeviceStorageRequestChild*
 ContentChild::AllocPDeviceStorageRequest(const DeviceStorageParams& aParams)
 {
diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h
index 257d095bb2e6..5eaadda8b609 100644
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -123,10 +123,6 @@ public:
     virtual bool DeallocPTestShell(PTestShellChild*);
     virtual bool RecvPTestShellConstructor(PTestShellChild*);
 
-    virtual PAudioChild* AllocPAudio(const int32_t&,
-                                     const int32_t&);
-    virtual bool DeallocPAudio(PAudioChild*);
-
     virtual PNeckoChild* AllocPNecko();
     virtual bool DeallocPNecko(PNeckoChild*);
 
diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp
index d417769d44ee..8dc7f8ad2fd9 100644
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -92,10 +92,6 @@
 # include "nsPermissionManager.h"
 #endif
 
-#ifdef MOZ_SYDNEYAUDIO
-# include "AudioParent.h"
-#endif
-
 #ifdef MOZ_WIDGET_ANDROID
 # include "AndroidBridge.h"
 #endif
@@ -1442,29 +1438,6 @@ ContentParent::DeallocPTestShell(PTestShellParent* shell)
   return true;
 }
  
-PAudioParent*
-ContentParent::AllocPAudio(const int32_t& numChannels,
-                           const int32_t& rate)
-{
-#if defined(MOZ_SYDNEYAUDIO)
-    AudioParent *parent = new AudioParent(numChannels, rate);
-    NS_ADDREF(parent);
-    return parent;
-#else
-    return nullptr;
-#endif
-}
-
-bool
-ContentParent::DeallocPAudio(PAudioParent* doomed)
-{
-#if defined(MOZ_SYDNEYAUDIO)
-    AudioParent *parent = static_cast(doomed);
-    NS_RELEASE(parent);
-#endif
-    return true;
-}
-
 PNeckoParent* 
 ContentParent::AllocPNecko()
 {
diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h
index 77b4e1efe25a..f4b173ed6df3 100644
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -217,10 +217,6 @@ private:
     virtual PTestShellParent* AllocPTestShell();
     virtual bool DeallocPTestShell(PTestShellParent* shell);
 
-    virtual PAudioParent* AllocPAudio(const int32_t&,
-                                     const int32_t&);
-    virtual bool DeallocPAudio(PAudioParent*);
-
     virtual PNeckoParent* AllocPNecko();
     virtual bool DeallocPNecko(PNeckoParent* necko);
 
diff --git a/dom/ipc/Makefile.in b/dom/ipc/Makefile.in
index 5a65074e407d..ce6575c1c093 100644
--- a/dom/ipc/Makefile.in
+++ b/dom/ipc/Makefile.in
@@ -69,17 +69,6 @@ CPPSRCS = \
   TabMessageUtils.cpp \
   $(NULL)
 
-ifdef MOZ_SYDNEYAUDIO
-EXPORTS_mozilla/dom += \
-  AudioChild.h \
-  AudioParent.h \
-  $(NULL)
-CPPSRCS += \
-  AudioChild.cpp \
-  AudioParent.cpp \
-  $(NULL)
-endif
-
 include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 include $(topsrcdir)/config/rules.mk
diff --git a/dom/ipc/PAudio.ipdl b/dom/ipc/PAudio.ipdl
deleted file mode 100644
index 0ea1d45f7f1b..000000000000
--- a/dom/ipc/PAudio.ipdl
+++ /dev/null
@@ -1,40 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* vim: set sw=4 ts=8 et tw=80 : */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-include protocol PContent;
-
-namespace mozilla {
-namespace dom {
-
-protocol PAudio
-{
-  manager PContent;
-
-parent:
-
-  Write(nsCString data, uint32_t frames);
-
-  SetVolume(float aVolume);
-
-  MinWriteSize();
-  Drain();
-
-  Pause();
-  Resume();
-  Shutdown();
-
- child:
-
-  __delete__();
-
-  PositionInFramesUpdate(int64_t position, int64_t time);
-  MinWriteSizeDone(int32_t frameCount);
-  DrainDone();
-  WriteDone();
-};
-
-} // namespace dom
-} // namespace mozilla
diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl
index 2b8d846f2032..b093d8caeb27 100644
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -4,7 +4,6 @@
  * 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 protocol PAudio;
 include protocol PBlob;
 include protocol PBluetooth;
 include protocol PBrowser;
@@ -213,7 +212,6 @@ rpc protocol PContent
     parent opens PCompositor;
     parent opens PImageBridge;
 
-    manages PAudio;
     manages PBlob;
     manages PBluetooth;
     manages PBrowser;
@@ -335,8 +333,6 @@ parent:
     sync GetXPCOMProcessAttributes()
         returns (bool isOffline);
 
-    PAudio(int32_t aNumChannels, int32_t aRate);
-
     PDeviceStorageRequest(DeviceStorageParams params);
 
     sync PCrashReporter(NativeThreadId tid, uint32_t processType);
diff --git a/dom/ipc/ipdl.mk b/dom/ipc/ipdl.mk
index f0282cd7b456..3fd6124139ee 100644
--- a/dom/ipc/ipdl.mk
+++ b/dom/ipc/ipdl.mk
@@ -4,7 +4,6 @@
 
 IPDLSRCS = \
   DOMTypes.ipdlh \
-  PAudio.ipdl \
   PBlob.ipdl \
   PBlobStream.ipdl \
   PBrowser.ipdl \

From 5c550b9fd6a064baf0ac44a5f488caa063dfe530 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote 
Date: Mon, 19 Nov 2012 22:00:19 -0500
Subject: [PATCH 38/57] Bug 812957 - Add memory reporter for Freetype.
 r=karlt,jlebar

---
 gfx/thebes/gfxAndroidPlatform.cpp | 66 ++++++++++++++++++++++++++++++-
 1 file changed, 64 insertions(+), 2 deletions(-)

diff --git a/gfx/thebes/gfxAndroidPlatform.cpp b/gfx/thebes/gfxAndroidPlatform.cpp
index e1e9e1d1c58b..648b8f6761cc 100644
--- a/gfx/thebes/gfxAndroidPlatform.cpp
+++ b/gfx/thebes/gfxAndroidPlatform.cpp
@@ -19,6 +19,8 @@
 
 #include "ft2build.h"
 #include FT_FREETYPE_H
+#include FT_MODULE_H
+
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::gfx;
@@ -27,9 +29,69 @@ static FT_Library gPlatformFTLibrary = NULL;
 
 #define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "GeckoFonts" , ## args)
 
+static int64_t sFreetypeMemoryUsed;
+static FT_MemoryRec_ sFreetypeMemoryRecord;
+
+static int64_t
+GetFreetypeSize()
+{
+    return sFreetypeMemoryUsed;
+}
+
+NS_MEMORY_REPORTER_IMPLEMENT(Freetype,
+    "explicit/freetype",
+    KIND_HEAP,
+    UNITS_BYTES,
+    GetFreetypeSize,
+    "Memory used by Freetype."
+)
+
+NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(FreetypeMallocSizeOfForCounterInc, "freetype")
+NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN_UN(FreetypeMallocSizeOfForCounterDec)
+
+static void
+*CountingAlloc(FT_Memory memory, long size)
+{
+    void *p = malloc(size);
+    sFreetypeMemoryUsed += FreetypeMallocSizeOfForCounterInc(p);
+    return p;
+}
+
+static void
+CountingFree(FT_Memory memory, void* p)
+{
+    sFreetypeMemoryUsed -= FreetypeMallocSizeOfForCounterDec(p);
+    free(p);
+}
+
+static void
+*CountingRealloc(FT_Memory memory, long cur_size, long new_size, void* p)
+{
+    sFreetypeMemoryUsed -= FreetypeMallocSizeOfForCounterDec(p);
+    void *pnew = realloc(p, new_size);
+    if (pnew) {
+        sFreetypeMemoryUsed += FreetypeMallocSizeOfForCounterInc(pnew);
+    } else {
+        // realloc failed;  undo the decrement from above
+        sFreetypeMemoryUsed += FreetypeMallocSizeOfForCounterInc(p);
+    }
+    return pnew;
+}
+
 gfxAndroidPlatform::gfxAndroidPlatform()
 {
-    FT_Init_FreeType(&gPlatformFTLibrary);
+    // A custom allocator.  It counts allocations, enabling memory reporting.
+    sFreetypeMemoryRecord.user    = nullptr;
+    sFreetypeMemoryRecord.alloc   = CountingAlloc;
+    sFreetypeMemoryRecord.free    = CountingFree;
+    sFreetypeMemoryRecord.realloc = CountingRealloc;
+
+    // These two calls are equivalent to FT_Init_FreeType(), but allow us to
+    // provide a custom memory allocator.
+    FT_New_Library(&sFreetypeMemoryRecord, &gPlatformFTLibrary);
+    FT_Add_Default_Modules(gPlatformFTLibrary);
+
+    NS_RegisterMemoryReporter(new NS_MEMORY_REPORTER_NAME(Freetype));
 
     nsCOMPtr screenMgr = do_GetService("@mozilla.org/gfx/screenmanager;1");
     nsCOMPtr screen;
@@ -46,7 +108,7 @@ gfxAndroidPlatform::~gfxAndroidPlatform()
 {
     cairo_debug_reset_static_data();
 
-    FT_Done_FreeType(gPlatformFTLibrary);
+    FT_Done_Library(gPlatformFTLibrary);
     gPlatformFTLibrary = NULL;
 }
 

From 499c9100c75d2381fc361e2d503f3b0e917cd25d Mon Sep 17 00:00:00 2001
From: Phil Ringnalda 
Date: Mon, 19 Nov 2012 19:54:41 -0800
Subject: [PATCH 39/57] Back out 39890b75361f (bug 779520) for Windows leaks

---
 .../src/atk/ApplicationAccessibleWrap.cpp     |  88 +++++++-------
 .../src/atk/ApplicationAccessibleWrap.h       |   3 +
 accessible/src/base/nsAccDocManager.cpp       |   3 +-
 .../src/base/nsAccessibilityService.cpp       |   1 +
 accessible/src/generic/Accessible.cpp         |   5 +
 accessible/src/generic/Accessible.h           |   5 +
 .../src/generic/ApplicationAccessible.cpp     |   7 +-
 .../src/generic/ApplicationAccessible.h       |   1 +
 accessible/src/generic/DocAccessible.cpp      | 110 +++++++++++-------
 accessible/src/generic/DocAccessible.h        |   2 +
 accessible/src/generic/RootAccessible.cpp     | 107 +++++++++--------
 accessible/src/generic/RootAccessible.h       |   3 +-
 accessible/src/xul/XULTreeAccessible.cpp      |   8 +-
 accessible/src/xul/XULTreeAccessible.h        |   1 +
 accessible/src/xul/XULTreeGridAccessible.cpp  |  27 +++--
 accessible/src/xul/XULTreeGridAccessible.h    |   3 +
 16 files changed, 226 insertions(+), 148 deletions(-)

diff --git a/accessible/src/atk/ApplicationAccessibleWrap.cpp b/accessible/src/atk/ApplicationAccessibleWrap.cpp
index f4c272057e30..51503156a2bf 100644
--- a/accessible/src/atk/ApplicationAccessibleWrap.cpp
+++ b/accessible/src/atk/ApplicationAccessibleWrap.cpp
@@ -511,54 +511,12 @@ add_listener (GSignalEmissionHook listener,
 
 static nsresult LoadGtkModule(GnomeAccessibilityModule& aModule);
 
-static gboolean toplevel_event_watcher(GSignalInvocationHint*, guint,
-                                       const GValue*, gpointer);
-
 // ApplicationAccessibleWrap
 
 ApplicationAccessibleWrap::ApplicationAccessibleWrap():
   ApplicationAccessible()
 {
   MAI_LOG_DEBUG(("======Create AppRootAcc=%p\n", (void*)this));
-
-  if (ShouldA11yBeEnabled()) {
-      // Load and initialize gail library.
-      nsresult rv = LoadGtkModule(sGail);
-      if (NS_SUCCEEDED(rv)) {
-          (*sGail.init)();
-      } else {
-          MAI_LOG_DEBUG(("Fail to load lib: %s\n", sGail.libName));
-      }
-
-      MAI_LOG_DEBUG(("Mozilla Atk Implementation initializing\n"));
-
-      // Initialize the MAI Utility class, it will overwrite gail_util.
-      g_type_class_unref(g_type_class_ref(MAI_TYPE_UTIL));
-
-      // Init atk-bridge now
-      PR_SetEnv("NO_AT_BRIDGE=0");
-
-      // load and initialize atk-bridge library
-      rv = LoadGtkModule(sAtkBridge);
-      if (NS_SUCCEEDED(rv)) {
-          (*sAtkBridge.init)();
-      } else {
-          MAI_LOG_DEBUG(("Fail to load lib: %s\n", sAtkBridge.libName));
-      }
-
-      if (!sToplevel_event_hook_added) {
-        sToplevel_event_hook_added = true;
-        sToplevel_show_hook =
-          g_signal_add_emission_hook(g_signal_lookup("show", GTK_TYPE_WINDOW),
-            0, toplevel_event_watcher,
-            reinterpret_cast(nsIAccessibleEvent::EVENT_SHOW), NULL);
-        sToplevel_hide_hook =
-          g_signal_add_emission_hook(g_signal_lookup("hide", GTK_TYPE_WINDOW),
-            0, toplevel_event_watcher,
-            reinterpret_cast(nsIAccessibleEvent::EVENT_HIDE), NULL);
-      }
-  }
-
 }
 
 ApplicationAccessibleWrap::~ApplicationAccessibleWrap()
@@ -615,6 +573,52 @@ toplevel_event_watcher(GSignalInvocationHint* ihint,
   return TRUE;
 }
 
+void
+ApplicationAccessibleWrap::Init()
+{
+    if (ShouldA11yBeEnabled()) {
+        // load and initialize gail library
+        nsresult rv = LoadGtkModule(sGail);
+        if (NS_SUCCEEDED(rv)) {
+            (*sGail.init)();
+        }
+        else {
+            MAI_LOG_DEBUG(("Fail to load lib: %s\n", sGail.libName));
+        }
+
+        MAI_LOG_DEBUG(("Mozilla Atk Implementation initializing\n"));
+        // Initialize the MAI Utility class
+        // it will overwrite gail_util
+        g_type_class_unref(g_type_class_ref(MAI_TYPE_UTIL));
+
+        // Init atk-bridge now
+        PR_SetEnv("NO_AT_BRIDGE=0");
+
+        // load and initialize atk-bridge library
+        rv = LoadGtkModule(sAtkBridge);
+        if (NS_SUCCEEDED(rv)) {
+            // init atk-bridge
+            (*sAtkBridge.init)();
+        } else {
+            MAI_LOG_DEBUG(("Fail to load lib: %s\n", sAtkBridge.libName));
+        }
+
+        if (!sToplevel_event_hook_added) {
+          sToplevel_event_hook_added = true;
+          sToplevel_show_hook =
+            g_signal_add_emission_hook(g_signal_lookup("show", GTK_TYPE_WINDOW),
+              0, toplevel_event_watcher,
+              reinterpret_cast(nsIAccessibleEvent::EVENT_SHOW), NULL);
+          sToplevel_hide_hook =
+            g_signal_add_emission_hook(g_signal_lookup("hide", GTK_TYPE_WINDOW),
+              0, toplevel_event_watcher,
+              reinterpret_cast(nsIAccessibleEvent::EVENT_HIDE), NULL);
+        }
+    }
+
+    ApplicationAccessible::Init();
+}
+
 void
 ApplicationAccessibleWrap::Unload()
 {
diff --git a/accessible/src/atk/ApplicationAccessibleWrap.h b/accessible/src/atk/ApplicationAccessibleWrap.h
index b4354306dcff..51b15b1cfa46 100644
--- a/accessible/src/atk/ApplicationAccessibleWrap.h
+++ b/accessible/src/atk/ApplicationAccessibleWrap.h
@@ -22,6 +22,9 @@ public:
   ApplicationAccessibleWrap();
   virtual ~ApplicationAccessibleWrap();
 
+  // nsAccessNode
+  virtual void Init();
+
   // Accessible
   virtual mozilla::a11y::ENameValueFlag Name(nsString& aName);
   virtual bool AppendChild(Accessible* aChild);
diff --git a/accessible/src/base/nsAccDocManager.cpp b/accessible/src/base/nsAccDocManager.cpp
index aa5e98ab711b..cbbbc18200b7 100644
--- a/accessible/src/base/nsAccDocManager.cpp
+++ b/accessible/src/base/nsAccDocManager.cpp
@@ -383,7 +383,8 @@ nsAccDocManager::CreateDocOrRootAccessible(nsIDocument* aDocument)
   // Cache the document accessible into document cache.
   mDocAccessibleCache.Put(aDocument, docAcc);
 
-  // Set role map entry of document accessible.
+  // Initialize the document accessible.
+  docAcc->Init();
   docAcc->SetRoleMapEntry(aria::GetRoleMap(aDocument));
 
   // Bind the document to the tree.
diff --git a/accessible/src/base/nsAccessibilityService.cpp b/accessible/src/base/nsAccessibilityService.cpp
index cbbee0b66fd6..5a562217a34f 100644
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -997,6 +997,7 @@ nsAccessibilityService::Init()
   ApplicationAccessibleWrap::PreCreate();
   gApplicationAccessible = new ApplicationAccessibleWrap();
   NS_ADDREF(gApplicationAccessible); // will release in Shutdown()
+  gApplicationAccessible->Init();
 
   // Initialize accessibility.
   nsAccessNodeWrap::InitAccessibility();
diff --git a/accessible/src/generic/Accessible.cpp b/accessible/src/generic/Accessible.cpp
index 27eba376376f..bf6519284b6a 100644
--- a/accessible/src/generic/Accessible.cpp
+++ b/accessible/src/generic/Accessible.cpp
@@ -190,6 +190,11 @@ Accessible::~Accessible()
 {
 }
 
+void
+Accessible::Init()
+{
+}
+
 NS_IMETHODIMP
 Accessible::GetDocument(nsIAccessibleDocument** aDocument)
 {
diff --git a/accessible/src/generic/Accessible.h b/accessible/src/generic/Accessible.h
index 61e3bd4297c8..d1a286302239 100644
--- a/accessible/src/generic/Accessible.h
+++ b/accessible/src/generic/Accessible.h
@@ -126,6 +126,11 @@ public:
   //////////////////////////////////////////////////////////////////////////////
   // Public methods
 
+  /**
+   * Initialize the accessible.
+   */
+  virtual void Init();
+
   /**
    * Get the description of this accessible.
    */
diff --git a/accessible/src/generic/ApplicationAccessible.cpp b/accessible/src/generic/ApplicationAccessible.cpp
index f122f2fe87b3..fac2183fe7e0 100644
--- a/accessible/src/generic/ApplicationAccessible.cpp
+++ b/accessible/src/generic/ApplicationAccessible.cpp
@@ -27,7 +27,6 @@ ApplicationAccessible::ApplicationAccessible() :
   AccessibleWrap(nullptr, nullptr)
 {
   mFlags |= eApplicationAccessible;
-  mAppInfo = do_GetService("@mozilla.org/xre/app-info;1");
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -267,6 +266,12 @@ ApplicationAccessible::GetPlatformVersion(nsAString& aVersion)
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessNode public methods
 
+void
+ApplicationAccessible::Init()
+{
+  mAppInfo = do_GetService("@mozilla.org/xre/app-info;1");
+}
+
 void
 ApplicationAccessible::Shutdown()
 {
diff --git a/accessible/src/generic/ApplicationAccessible.h b/accessible/src/generic/ApplicationAccessible.h
index 033df8ed8a81..25f42737a701 100644
--- a/accessible/src/generic/ApplicationAccessible.h
+++ b/accessible/src/generic/ApplicationAccessible.h
@@ -58,6 +58,7 @@ public:
   NS_DECL_NSIACCESSIBLEAPPLICATION
 
   // nsAccessNode
+  virtual void Init();
   virtual void Shutdown();
 
   // Accessible
diff --git a/accessible/src/generic/DocAccessible.cpp b/accessible/src/generic/DocAccessible.cpp
index 5fe06a706998..d3d15bcd7b8a 100644
--- a/accessible/src/generic/DocAccessible.cpp
+++ b/accessible/src/generic/DocAccessible.cpp
@@ -107,49 +107,6 @@ DocAccessible::
   // We provide a virtual cursor if this is a root doc or if it's a tab doc.
   mIsCursorable = (!(mDocument->GetParentDocument()) ||
                    nsCoreUtils::IsTabDocument(mDocument));
-#ifdef A11Y_LOG
-  if (logging::IsEnabled(logging::eDocCreate))
-    logging::DocCreate("document initialize", mDocument, this);
-#endif
-
-  // Initialize notification controller.
-  mNotificationController = new NotificationController(this, mPresShell);
-
-  // Mark the document accessible as loaded if its DOM document was loaded at
-  // this point (this can happen because a11y is started late or DOM document
-  // having no container was loaded.
-  if (mDocument->GetReadyStateEnum() == nsIDocument::READYSTATE_COMPLETE)
-    mLoadState |= eDOMLoaded;
-
-  nsCOMPtr container = mDocument->GetContainer();
-  nsCOMPtr docShellTreeItem(do_QueryInterface(container));
-
-  // We only want to be a command observer for content docshells with an
-  // editor.
-  int32_t itemType;
-  docShellTreeItem->GetItemType(&itemType);
-
-  bool isContent = (itemType == nsIDocShellTreeItem::typeContent);
-  if (isContent) {
-    nsCOMPtr commandManager = do_GetInterface(docShellTreeItem);
-    if (commandManager)
-      commandManager->AddCommandObserver(this, "obs_documentCreated");
-  }
-
-  a11y::RootAccessible* rootAccessible = RootAccessible();
-
-  // XXX we might be the root accessible in which case eRootAccessible hasn't
-  // been added to mFlags yet, so the downcast failed, and RootAccessible()
-  // returned NULL.  Bug 678477 should
-  // remove this hack.
-  if (rootAccessible) {
-    nsRefPtr caretAccessible = rootAccessible->GetCaretAccessible();
-    if (caretAccessible)
-      caretAccessible->AddDocSelectionListener(mPresShell);
-  }
-
-  // Add document observer.
-  mDocument->AddObserver(this);
 }
 
 DocAccessible::~DocAccessible()
@@ -625,6 +582,26 @@ DocAccessible::GetAccessible(nsINode* aNode) const
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessNode
 
+void
+DocAccessible::Init()
+{
+#ifdef A11Y_LOG
+  if (logging::IsEnabled(logging::eDocCreate))
+    logging::DocCreate("document initialize", mDocument, this);
+#endif
+
+  // Initialize notification controller.
+  mNotificationController = new NotificationController(this, mPresShell);
+
+  // Mark the document accessible as loaded if its DOM document was loaded at
+  // this point (this can happen because a11y is started late or DOM document
+  // having no container was loaded.
+  if (mDocument->GetReadyStateEnum() == nsIDocument::READYSTATE_COMPLETE)
+    mLoadState |= eDOMLoaded;
+
+  AddEventListeners();
+}
+
 void
 DocAccessible::Shutdown()
 {
@@ -736,6 +713,50 @@ DocAccessible::GetBoundsRect(nsRect& aBounds, nsIFrame** aRelativeFrame)
   }
 }
 
+// DocAccessible protected member
+nsresult
+DocAccessible::AddEventListeners()
+{
+  // 1) Set up scroll position listener
+  // 2) Check for editor and listen for changes to editor
+
+  NS_ENSURE_TRUE(mPresShell, NS_ERROR_FAILURE);
+
+  nsCOMPtr container = mDocument->GetContainer();
+  nsCOMPtr docShellTreeItem(do_QueryInterface(container));
+  NS_ENSURE_TRUE(docShellTreeItem, NS_ERROR_FAILURE);
+
+  // Make sure we're a content docshell
+  // We don't want to listen to chrome progress
+  int32_t itemType;
+  docShellTreeItem->GetItemType(&itemType);
+
+  bool isContent = (itemType == nsIDocShellTreeItem::typeContent);
+
+  if (isContent) {
+    // We're not an editor yet, but we might become one
+    nsCOMPtr commandManager = do_GetInterface(docShellTreeItem);
+    if (commandManager) {
+      commandManager->AddCommandObserver(this, "obs_documentCreated");
+    }
+  }
+
+  nsCOMPtr rootTreeItem;
+  docShellTreeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem));
+  if (rootTreeItem) {
+    a11y::RootAccessible* rootAccessible = RootAccessible();
+    NS_ENSURE_TRUE(rootAccessible, NS_ERROR_FAILURE);
+    nsRefPtr caretAccessible = rootAccessible->GetCaretAccessible();
+    if (caretAccessible) {
+      caretAccessible->AddDocSelectionListener(mPresShell);
+    }
+  }
+
+  // add document observer
+  mDocument->AddObserver(this);
+  return NS_OK;
+}
+
 // DocAccessible protected member
 nsresult
 DocAccessible::RemoveEventListeners()
@@ -1367,6 +1388,9 @@ DocAccessible::BindToDocument(Accessible* aAccessible,
   // Put into unique ID cache.
   mAccessibleCache.Put(aAccessible->UniqueID(), aAccessible);
 
+  // Initialize the accessible.
+  aAccessible->Init();
+
   aAccessible->SetRoleMapEntry(aRoleMapEntry);
   if (aAccessible->IsElement())
     AddDependentIDsFor(aAccessible);
diff --git a/accessible/src/generic/DocAccessible.h b/accessible/src/generic/DocAccessible.h
index e043fe9b17e0..ee222d03a433 100644
--- a/accessible/src/generic/DocAccessible.h
+++ b/accessible/src/generic/DocAccessible.h
@@ -76,6 +76,7 @@ public:
   NS_DECL_NSIDOCUMENTOBSERVER
 
   // nsAccessNode
+  virtual void Init();
   virtual void Shutdown();
   virtual nsIFrame* GetFrame() const;
   virtual nsINode* GetNode() const { return mDocument; }
@@ -321,6 +322,7 @@ protected:
   virtual void CacheChildren();
 
   // DocAccessible
+  virtual nsresult AddEventListeners();
   virtual nsresult RemoveEventListeners();
 
   /**
diff --git a/accessible/src/generic/RootAccessible.cpp b/accessible/src/generic/RootAccessible.cpp
index 332d5d2b6778..6a69285d1cc8 100644
--- a/accessible/src/generic/RootAccessible.cpp
+++ b/accessible/src/generic/RootAccessible.cpp
@@ -48,35 +48,6 @@
 using namespace mozilla;
 using namespace mozilla::a11y;
 
-const char* const kEventTypes[] = {
-#ifdef DEBUG_DRAGDROPSTART
-  // Capture mouse over events and fire fake DRAGDROPSTART event to simplify
-  // debugging a11y objects with event viewers.
-  "mouseover",
-#endif
-  // Fired whenever list or tree control selection is changed.
-  "select",
-  // Fired whenever value changes, immediately after, whether focus moves or
-  // not.
-  "ValueChange",
-  "AlertActive",
-  "TreeRowCountChanged",
-  "TreeInvalidated",
-  // add ourself as a OpenStateChange listener (custom event fired in tree.xml)
-  "OpenStateChange",
-  // add ourself as a CheckboxStateChange listener (custom event fired in nsHTMLInputElement.cpp)
-  "CheckboxStateChange",
-  // add ourself as a RadioStateChange Listener ( custom event fired in in nsHTMLInputElement.cpp  & radio.xml)
-  "RadioStateChange",
-  "popupshown",
-  "popuphiding",
-  "DOMMenuInactive",
-  "DOMMenuItemActive",
-  "DOMMenuItemInactive",
-  "DOMMenuBarActive",
-  "DOMMenuBarInactive"
-};
-
 ////////////////////////////////////////////////////////////////////////////////
 // nsISupports
 
@@ -91,25 +62,6 @@ RootAccessible::
   DocAccessibleWrap(aDocument, aRootContent, aPresShell)
 {
   mFlags |= eRootAccessible;
-
-  // nsIDOMEventTarget interface allows to register event listeners to
-  // receive untrusted events (synthetic events generated by untrusted code).
-  // For example, XBL bindings implementations for elements that are hosted in
-  // non chrome document fire untrusted events.
-  nsCOMPtr nstarget(do_QueryInterface(mDocument));
-  if (nstarget) {
-    for (const char* const* e = kEventTypes,
-                   * const* e_end = ArrayEnd(kEventTypes);
-         e < e_end; ++e) {
-      nstarget->AddEventListener(NS_ConvertASCIItoUTF16(*e),
-                                 this, true, true, 2);
-    }
-  }
-
-  // XXX DocAccessible constructor can't tell if its creating a RootAccessible
-  // so we need to construct the caret accessible here.
-  mCaretAccessible = new nsCaretAccessible(this);
-  mCaretAccessible->AddDocSelectionListener(aPresShell);
 }
 
 RootAccessible::~RootAccessible()
@@ -199,13 +151,68 @@ RootAccessible::NativeState()
   return state;
 }
 
+const char* const docEvents[] = {
+#ifdef DEBUG_DRAGDROPSTART
+  // Capture mouse over events and fire fake DRAGDROPSTART event to simplify
+  // debugging a11y objects with event viewers
+  "mouseover",
+#endif
+  // capture Form change events 
+  "select",
+  // capture ValueChange events (fired whenever value changes, immediately after, whether focus moves or not)
+  "ValueChange",
+  // capture AlertActive events (fired whenever alert pops up)
+  "AlertActive",
+  "TreeRowCountChanged",
+  "TreeInvalidated",
+  // add ourself as a OpenStateChange listener (custom event fired in tree.xml)
+  "OpenStateChange",
+  // add ourself as a CheckboxStateChange listener (custom event fired in nsHTMLInputElement.cpp)
+  "CheckboxStateChange",
+  // add ourself as a RadioStateChange Listener ( custom event fired in in nsHTMLInputElement.cpp  & radio.xml)
+  "RadioStateChange",
+  "popupshown",
+  "popuphiding",
+  "DOMMenuInactive",
+  "DOMMenuItemActive",
+  "DOMMenuItemInactive",
+  "DOMMenuBarActive",
+  "DOMMenuBarInactive"
+};
+
+nsresult
+RootAccessible::AddEventListeners()
+{
+  // nsIDOMEventTarget interface allows to register event listeners to
+  // receive untrusted events (synthetic events generated by untrusted code).
+  // For example, XBL bindings implementations for elements that are hosted in
+  // non chrome document fire untrusted events.
+  nsCOMPtr nstarget(do_QueryInterface(mDocument));
+
+  if (nstarget) {
+    for (const char* const* e = docEvents,
+                   * const* e_end = ArrayEnd(docEvents);
+         e < e_end; ++e) {
+      nsresult rv = nstarget->AddEventListener(NS_ConvertASCIItoUTF16(*e),
+                                               this, true, true, 2);
+      NS_ENSURE_SUCCESS(rv, rv);
+    }
+  }
+
+  if (!mCaretAccessible) {
+    mCaretAccessible = new nsCaretAccessible(this);
+  }
+
+  return DocAccessible::AddEventListeners();
+}
+
 nsresult
 RootAccessible::RemoveEventListeners()
 {
   nsCOMPtr target(do_QueryInterface(mDocument));
   if (target) { 
-    for (const char* const* e = kEventTypes,
-                   * const* e_end = ArrayEnd(kEventTypes);
+    for (const char* const* e = docEvents,
+                   * const* e_end = ArrayEnd(docEvents);
          e < e_end; ++e) {
       nsresult rv = target->RemoveEventListener(NS_ConvertASCIItoUTF16(*e), this, true);
       NS_ENSURE_SUCCESS(rv, rv);
diff --git a/accessible/src/generic/RootAccessible.h b/accessible/src/generic/RootAccessible.h
index c0900fc552af..e9b1a6f57072 100644
--- a/accessible/src/generic/RootAccessible.h
+++ b/accessible/src/generic/RootAccessible.h
@@ -50,8 +50,9 @@ public:
 protected:
 
   /**
-   * Remove DOM event listeners.
+   * Add/remove DOM event listeners.
    */
+  virtual nsresult AddEventListeners();
   virtual nsresult RemoveEventListeners();
 
   /**
diff --git a/accessible/src/xul/XULTreeAccessible.cpp b/accessible/src/xul/XULTreeAccessible.cpp
index d46897f9c275..c1a353d67a55 100644
--- a/accessible/src/xul/XULTreeAccessible.cpp
+++ b/accessible/src/xul/XULTreeAccessible.cpp
@@ -1099,7 +1099,6 @@ XULTreeItemAccessible::
   XULTreeItemAccessibleBase(aContent, aDoc, aParent, aTree, aTreeView, aRow)
 {
   mColumn = nsCoreUtils::GetFirstSensibleColumn(mTree);
-  GetCellName(mColumn, mCachedName);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1137,6 +1136,13 @@ XULTreeItemAccessible::Name(nsString& aName)
 ////////////////////////////////////////////////////////////////////////////////
 // XULTreeItemAccessible: nsAccessNode implementation
 
+void
+XULTreeItemAccessible::Init()
+{
+  XULTreeItemAccessibleBase::Init();
+  Name(mCachedName);
+}
+
 void
 XULTreeItemAccessible::Shutdown()
 {
diff --git a/accessible/src/xul/XULTreeAccessible.h b/accessible/src/xul/XULTreeAccessible.h
index 5dfd8b1bacfd..79fd3ce7b123 100644
--- a/accessible/src/xul/XULTreeAccessible.h
+++ b/accessible/src/xul/XULTreeAccessible.h
@@ -233,6 +233,7 @@ public:
                                            XULTreeItemAccessibleBase)
 
   // nsAccessNode
+  virtual void Init();
   virtual void Shutdown();
 
   // Accessible
diff --git a/accessible/src/xul/XULTreeGridAccessible.cpp b/accessible/src/xul/XULTreeGridAccessible.cpp
index f22edfb79096..ce0ab56d1d6d 100644
--- a/accessible/src/xul/XULTreeGridAccessible.cpp
+++ b/accessible/src/xul/XULTreeGridAccessible.cpp
@@ -469,15 +469,6 @@ XULTreeGridCellAccessible::
 {
   mParent = aRowAcc;
   mFlags |= eSharedNode;
-
-  NS_ASSERTION(mTreeView, "mTreeView is null");
-
-  int16_t type = -1;
-  mColumn->GetType(&type);
-  if (type == nsITreeColumn::TYPE_CHECKBOX)
-    mTreeView->GetCellValue(mRow, mColumn, mCachedTextEquiv);
-  else
-    mTreeView->GetCellText(mRow, mColumn, mCachedTextEquiv);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -714,6 +705,24 @@ XULTreeGridCellAccessible::Selected()
   return selected;
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// XULTreeGridCellAccessible: nsAccessNode implementation
+
+void
+XULTreeGridCellAccessible::Init()
+{
+  LeafAccessible::Init();
+
+  NS_ASSERTION(mTreeView, "mTreeView is null");
+
+  int16_t type;
+  mColumn->GetType(&type);
+  if (type == nsITreeColumn::TYPE_CHECKBOX)
+    mTreeView->GetCellValue(mRow, mColumn, mCachedTextEquiv);
+  else
+    mTreeView->GetCellText(mRow, mColumn, mCachedTextEquiv);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // XULTreeGridCellAccessible: Accessible public implementation
 
diff --git a/accessible/src/xul/XULTreeGridAccessible.h b/accessible/src/xul/XULTreeGridAccessible.h
index 0ae8d97a4a1c..e0fbe9696e64 100644
--- a/accessible/src/xul/XULTreeGridAccessible.h
+++ b/accessible/src/xul/XULTreeGridAccessible.h
@@ -150,6 +150,9 @@ public:
   // nsIAccessibleTableCell
   NS_FORWARD_NSIACCESSIBLETABLECELL(xpcAccessibleTableCell::)
 
+  // nsAccessNode
+  virtual void Init();
+
   // Accessible
   virtual TableCellAccessible* AsTableCell() { return this; }
   virtual void Shutdown();

From 211ec8576f0b6681524a39aaf25068dd5272b5c0 Mon Sep 17 00:00:00 2001
From: Brian Smith 
Date: Fri, 13 Jul 2012 15:44:24 -0700
Subject: [PATCH 40/57] Bug 804663: Add a CryptoTask class for asynchronous
 crypto operations and add more utilities to ScopedNSSTypes.h

--HG--
extra : source : cc195997c6e526ce4b64d28cfb065d671b90bdba
---
 security/manager/ssl/src/CryptoTask.cpp     |  71 +++++++
 security/manager/ssl/src/CryptoTask.h       |  87 +++++++++
 security/manager/ssl/src/Makefile.in        |   2 +
 security/manager/ssl/src/ScopedNSSTypes.h   | 202 +++++++++++++++++++-
 security/manager/ssl/src/nsNSSComponent.cpp |   5 +-
 toolkit/identity/IdentityCryptoService.cpp  |  29 +--
 6 files changed, 361 insertions(+), 35 deletions(-)
 create mode 100644 security/manager/ssl/src/CryptoTask.cpp
 create mode 100644 security/manager/ssl/src/CryptoTask.h

diff --git a/security/manager/ssl/src/CryptoTask.cpp b/security/manager/ssl/src/CryptoTask.cpp
new file mode 100644
index 000000000000..02000f0fffba
--- /dev/null
+++ b/security/manager/ssl/src/CryptoTask.cpp
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "CryptoTask.h"
+
+namespace mozilla {
+
+CryptoTask::~CryptoTask()
+{
+  MOZ_ASSERT(mReleasedNSSResources);
+
+  nsNSSShutDownPreventionLock lock;
+  if (!isAlreadyShutDown()) {
+    shutdown(calledFromObject);
+  }
+}
+
+nsresult
+CryptoTask::Dispatch(const nsACString & taskThreadName)
+{
+  nsCOMPtr thread;
+  nsresult rv = NS_NewThread(getter_AddRefs(thread), this);
+  if (thread) {
+    NS_SetThreadName(thread, taskThreadName);
+  }
+  return rv;
+}
+
+NS_IMETHODIMP
+CryptoTask::Run()
+{
+  if (!NS_IsMainThread()) {
+    nsNSSShutDownPreventionLock locker;
+    if (isAlreadyShutDown()) {
+      mRv = NS_ERROR_NOT_AVAILABLE;
+    } else {
+      mRv = CalculateResult();
+    }
+    NS_DispatchToMainThread(this);
+  } else {
+    // back on the main thread
+
+    // call ReleaseNSSResources now, before calling CallCallback, so that
+    // CryptoTasks have consistent behavior regardless of whether NSS is shut
+    // down between CalculateResult being called and CallCallback being called.
+    if (!mReleasedNSSResources) {
+      mReleasedNSSResources = true;
+      ReleaseNSSResources();
+    }
+
+    CallCallback(mRv);
+  }
+
+  return NS_OK;
+}
+
+void
+CryptoTask::virtualDestroyNSSReference()
+{
+  NS_ABORT_IF_FALSE(NS_IsMainThread(),
+                    "virtualDestroyNSSReference called off the main thread");
+  if (!mReleasedNSSResources) {
+    mReleasedNSSResources = true;
+    ReleaseNSSResources();
+  }
+}
+
+} // namespace mozilla
diff --git a/security/manager/ssl/src/CryptoTask.h b/security/manager/ssl/src/CryptoTask.h
new file mode 100644
index 000000000000..465b88f7cdd1
--- /dev/null
+++ b/security/manager/ssl/src/CryptoTask.h
@@ -0,0 +1,87 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla__CryptoTask_h
+#define mozilla__CryptoTask_h
+
+#include "mozilla/Attributes.h"
+#include "nsThreadUtils.h"
+#include "nsNSSShutDown.h"
+
+namespace mozilla {
+
+/**
+ * Frequently we need to run a task on a background thread without blocking
+ * the main thread, and then call a callback on the main thread with the
+ * result. This class provides the framework for that. Subclasses must:
+ *
+ *   (1) Override CalculateResult for the off-the-main-thread computation.
+ *       NSS functionality may only be accessed within CalculateResult.
+ *   (2) Override ReleaseNSSResources to release references to all NSS
+ *       resources (that do implement nsNSSShutDownObject themselves).
+ *   (3) Override CallCallback() for the on-the-main-thread call of the
+ *       callback.
+ *
+ * CalculateResult, ReleaseNSSResources, and CallCallback are called in order,
+ * except CalculateResult might be skipped if NSS is shut down before it can
+ * be called; in that case ReleaseNSSResources will be called and then
+ * CallCallback will be called with an error code.
+ */
+class CryptoTask : public nsRunnable,
+                   public nsNSSShutDownObject
+{
+public:
+  template 
+  nsresult Dispatch(const char (&taskThreadName)[LEN])
+  {
+    MOZ_STATIC_ASSERT(LEN <= 15,
+                      "Thread name must be no more than 15 characters");
+    return Dispatch(nsDependentCString(taskThreadName));
+  }
+
+protected:
+  CryptoTask()
+    : mRv(NS_ERROR_NOT_INITIALIZED),
+      mReleasedNSSResources(false)
+  {
+  }
+
+  virtual ~CryptoTask();
+
+  /**
+   * Called on a background thread (never the main thread). If CalculateResult
+   * is called, then its result will be passed to CallCallback on the main
+   * thread.
+   */
+  virtual nsresult CalculateResult() = 0;
+
+  /**
+   * Called on the main thread during NSS shutdown or just before CallCallback
+   * has been called. All NSS resources must be released. Usually, this just
+   * means assigning nullptr to the ScopedNSSType-based memory variables.
+   */
+  virtual void ReleaseNSSResources() = 0;
+
+  /**
+   * Called on the main thread with the result from CalculateResult() or
+   * with an error code if NSS was shut down before CalculateResult could
+   * be called.
+   */
+  virtual void CallCallback(nsresult rv) = 0;
+
+private:
+  NS_IMETHOD Run() MOZ_OVERRIDE MOZ_FINAL;
+  virtual void virtualDestroyNSSReference() MOZ_OVERRIDE MOZ_FINAL;
+
+  nsresult Dispatch(const nsACString & taskThreadName);
+
+  nsresult mRv;
+  bool mReleasedNSSResources;
+};
+
+} // namespace mozilla
+
+#endif // mozilla__CryptoTask_h
diff --git a/security/manager/ssl/src/Makefile.in b/security/manager/ssl/src/Makefile.in
index 99e9acf381bb..8bc4a34c17fa 100644
--- a/security/manager/ssl/src/Makefile.in
+++ b/security/manager/ssl/src/Makefile.in
@@ -20,6 +20,7 @@ GRE_MODULE	= 1
 LIBXUL_LIBRARY	= 1
 
 CPPSRCS = 				\
+	CryptoTask.cpp \
 	nsCERTValInParamWrapper.cpp     \
 	nsNSSCleaner.cpp                \
 	nsCertOverrideService.cpp   \
@@ -90,6 +91,7 @@ DEFINES += \
   $(NULL)
 
 EXPORTS += \
+  CryptoTask.h \
   nsNSSShutDown.h \
   ScopedNSSTypes.h \
   $(NULL)
diff --git a/security/manager/ssl/src/ScopedNSSTypes.h b/security/manager/ssl/src/ScopedNSSTypes.h
index 8de8555fdc52..4a560f0e4a48 100644
--- a/security/manager/ssl/src/ScopedNSSTypes.h
+++ b/security/manager/ssl/src/ScopedNSSTypes.h
@@ -7,6 +7,8 @@
 #ifndef mozilla_ScopedNSSTypes_h
 #define mozilla_ScopedNSSTypes_h
 
+#include "mozilla/Likely.h"
+#include "mozilla/mozalloc_oom.h"
 #include "mozilla/Scoped.h"
 
 #include "prio.h"
@@ -15,6 +17,61 @@
 #include "keyhi.h"
 #include "pk11pub.h"
 #include "sechash.h"
+#include "secpkcs7.h"
+#include "prerror.h"
+
+namespace mozilla {
+
+// It is very common to cast between char* and uint8_t* when doing crypto stuff.
+// Here, we provide more type-safe wrappers around reinterpret_cast so you don't
+// shoot yourself in the foot by reinterpret_casting completely unrelated types.
+
+inline char *
+char_ptr_cast(uint8_t * p) { return reinterpret_cast(p); }
+
+inline const char *
+char_ptr_cast(const uint8_t * p) { return reinterpret_cast(p); }
+
+inline uint8_t *
+uint8_t_ptr_cast(char * p) { return reinterpret_cast(p); }
+
+inline const uint8_t *
+uint8_t_ptr_cast(const char * p) { return reinterpret_cast(p); }
+
+// NSPR APIs use PRStatus/PR_GetError and NSS APIs use SECStatus/PR_GetError to
+// report success/failure. These funtions make it more convenient and *safer*
+// to translate NSPR/NSS results to nsresult. They are safer because they
+// refuse to traslate any bad PRStatus/SECStatus into an NS_OK, even when the
+// NSPR/NSS function forgot to call PR_SetError.
+
+// IMPORTANT: This must be called immediately after the function that set the
+// error code. Prefer using MapSECStatus to this.
+inline nsresult
+PRErrorCode_to_nsresult(PRErrorCode error)
+{
+  if (!error) {
+    MOZ_NOT_REACHED("Function failed without calling PR_GetError");
+    return NS_ERROR_UNEXPECTED;
+  }
+
+  // From NSSErrorsService::GetXPCOMFromNSSError
+  // XXX Don't make up nsresults, it's supposed to be an enum (bug 778113)
+  return (nsresult)NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_SECURITY,
+                                             -1 * error);
+}
+
+// IMPORTANT: This must be called immediately after the function returning the
+// SECStatus result. The recommended usage is:
+//    nsresult rv = MapSECStatus(f(x, y, z));
+inline nsresult
+MapSECStatus(SECStatus rv)
+{
+  if (rv == SECSuccess)
+    return NS_OK;
+
+  PRErrorCode error = PR_GetError();
+  return PRErrorCode_to_nsresult(error);
+}
 
 // Alphabetical order by NSS type
 MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPRFileDesc,
@@ -45,10 +102,6 @@ MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedCERTValidity,
                                           CERTValidity,
                                           CERT_DestroyValidity)
 
-MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedHASHContext,
-                                          HASHContext,
-                                          HASH_Destroy)
-
 MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedNSSCMSMessage,
                                           NSSCMSMessage,
                                           NSS_CMSMessage_Destroy)
@@ -56,6 +109,93 @@ MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedNSSCMSSignedData,
                                           NSSCMSSignedData,
                                           NSS_CMSSignedData_Destroy)
 
+namespace psm {
+
+inline void
+PK11_DestroyContext_true(PK11Context * ctx) {
+  PK11_DestroyContext(ctx, true);
+}
+
+} // namespace mozilla::psm
+
+MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPK11Context,
+                                          PK11Context,
+                                          mozilla::psm::PK11_DestroyContext_true)
+
+/** A more convenient way of dealing with digests calculated into
+ *  stack-allocated buffers.
+ *
+ * Typical usage, for digesting a buffer in memory:
+ *
+ *   Digest digest;
+ *   nsresult rv = digest.DigestBuf(SEC_OID_SHA256, mybuffer, myBufferLen);
+ *   NS_ENSURE_SUCCESS(rv, rv);
+ *   rv = MapSECStatus(SomeNSSFunction(..., digest.get(), ...));
+ *
+ * Less typical usage, for digesting while doing streaming I/O and similar:
+ *
+ *   Digest digest;
+ *   ScopedPK11Context digestContext(PK11_CreateDigestContext(SEC_OID_SHA1));
+ *   NS_ENSURE_TRUE(digestContext, NS_ERROR_OUT_OF_MEMORY);
+ *   rv = MapSECStatus(PK11_DigestBegin(digestContext));
+ *   NS_ENSURE_SUCCESS(rv, rv);
+ *   for (...) {
+ *      rv = MapSECStatus(PK11_DigestOp(digestContext, ...));
+ *      NS_ENSURE_SUCCESS(rv, rv);
+ *   }
+ *   rv = digestContext.End(SEC_OID_SHA1, digestContext);
+ *   NS_ENSURE_SUCCESS(rv, rv)
+ */
+class Digest
+{
+public:
+  Digest()
+  {
+    item.type = siBuffer;
+    item.data = buf;
+    item.len = 0;
+  }
+
+  nsresult DigestBuf(SECOidTag hashAlg, const uint8_t * buf, uint32_t len)
+  {
+    nsresult rv = SetLength(hashAlg);
+    NS_ENSURE_SUCCESS(rv, rv);
+    return MapSECStatus(PK11_HashBuf(hashAlg, item.data, buf, len));
+  }
+
+  nsresult End(SECOidTag hashAlg, ScopedPK11Context & context)
+  {
+    nsresult rv = SetLength(hashAlg);
+    NS_ENSURE_SUCCESS(rv, rv);
+    uint32_t len;
+    rv = MapSECStatus(PK11_DigestFinal(context, item.data, &len, item.len));
+    NS_ENSURE_SUCCESS(rv, rv);
+    context = nullptr;
+    NS_ENSURE_TRUE(len == item.len, NS_ERROR_UNEXPECTED);
+    return NS_OK;
+  }
+
+  const SECItem & get() const { return item; }
+
+private:
+  nsresult SetLength(SECOidTag hashType)
+  {
+    switch (hashType)
+    {
+      case SEC_OID_SHA1:   item.len = SHA1_LENGTH;   break;
+      case SEC_OID_SHA256: item.len = SHA256_LENGTH; break;
+      case SEC_OID_SHA384: item.len = SHA384_LENGTH; break;
+      case SEC_OID_SHA512: item.len = SHA512_LENGTH; break;
+      default:
+        return NS_ERROR_INVALID_ARG;
+    }
+
+    return NS_OK;
+  }
+
+  uint8_t buf[HASH_LENGTH_MAX];
+  SECItem item;
+};
 
 MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPK11SlotInfo,
                                           PK11SlotInfo,
@@ -67,6 +207,59 @@ MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPK11SymKey,
                                           PK11SymKey,
                                           PK11_FreeSymKey)
 
+MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedSEC_PKCS7ContentInfo,
+                                          SEC_PKCS7ContentInfo,
+                                          SEC_PKCS7DestroyContentInfo)
+
+// Wrapper around NSS's SECItem_AllocItem that handles OOM the same way as
+// other allocators.
+inline void
+SECITEM_AllocItem(SECItem & item, uint32_t len)
+{
+  if (MOZ_UNLIKELY(!SECITEM_AllocItem(nullptr, &item, len))) {
+    mozalloc_handle_oom(len);
+    if (MOZ_UNLIKELY(!SECITEM_AllocItem(nullptr, &item, len))) {
+      MOZ_CRASH();
+    }
+  }
+}
+
+class ScopedAutoSECItem MOZ_FINAL : public SECItem
+{
+public:
+  ScopedAutoSECItem(uint32_t initialAllocatedLen = 0)
+  {
+    data = NULL;
+    len = 0;
+    if (initialAllocatedLen > 0) {
+      SECITEM_AllocItem(*this, initialAllocatedLen);
+    }
+  }
+
+  void reset()
+  {
+    SECITEM_FreeItem(this, false);
+  }
+
+  ~ScopedAutoSECItem()
+  {
+    reset();
+  }
+};
+
+namespace psm {
+
+inline void SECITEM_FreeItem_true(SECItem * s)
+{
+  return SECITEM_FreeItem(s, true);
+}
+
+} // namespace impl
+
+MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedSECItem,
+                                          ::SECItem,
+                                          ::mozilla::psm::SECITEM_FreeItem_true)
+
 MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedSECKEYPrivateKey,
                                           SECKEYPrivateKey,
                                           SECKEY_DestroyPrivateKey)
@@ -74,5 +267,6 @@ MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedSECKEYPublicKey,
                                           SECKEYPublicKey,
                                           SECKEY_DestroyPublicKey)
 
+} // namespace mozilla
 
 #endif // mozilla_ScopedNSSTypes_h
diff --git a/security/manager/ssl/src/nsNSSComponent.cpp b/security/manager/ssl/src/nsNSSComponent.cpp
index a9d703f95ee2..3a93e8c482a6 100644
--- a/security/manager/ssl/src/nsNSSComponent.cpp
+++ b/security/manager/ssl/src/nsNSSComponent.cpp
@@ -55,6 +55,7 @@
 #include "nsNSSShutDown.h"
 #include "nsSmartCardEvent.h"
 #include "nsIKeyModule.h"
+#include "ScopedNSSTypes.h"
 
 #include "nss.h"
 #include "pk11func.h"
@@ -2028,7 +2029,7 @@ nsNSSComponent::VerifySignature(const char* aRSABuf, uint32_t aRSABufLen,
   *aPrincipal = nullptr;
 
   nsNSSShutDownPreventionLock locker;
-  SEC_PKCS7ContentInfo * p7_info = nullptr; 
+  ScopedSEC_PKCS7ContentInfo p7_info; 
   unsigned char hash[SHA1_LENGTH]; 
 
   SECItem item;
@@ -2127,8 +2128,6 @@ nsNSSComponent::VerifySignature(const char* aRSABuf, uint32_t aRSABufLen,
     } while (0);
   }
 
-  SEC_PKCS7DestroyContentInfo(p7_info);
-
   return rv2;
 }
 
diff --git a/toolkit/identity/IdentityCryptoService.cpp b/toolkit/identity/IdentityCryptoService.cpp
index 707636ced19d..d476103ce658 100644
--- a/toolkit/identity/IdentityCryptoService.cpp
+++ b/toolkit/identity/IdentityCryptoService.cpp
@@ -13,6 +13,7 @@
 #include "nsCOMPtr.h"
 #include "nsStringGlue.h"
 #include "mozilla/Base64.h"
+#include "ScopedNSSTypes.h"
 
 #include "nss.h"
 #include "pk11pub.h"
@@ -60,34 +61,6 @@ Base64UrlEncodeImpl(const nsACString & utf8Input, nsACString & result)
   return NS_OK;
 }
 
-
-nsresult
-PRErrorCode_to_nsresult(PRErrorCode error)
-{
-  if (!error) {
-    MOZ_NOT_REACHED("Function failed without calling PR_GetError");
-    return NS_ERROR_UNEXPECTED;
-  }
-
-  // From NSSErrorsService::GetXPCOMFromNSSError
-  // XXX Don't make up nsresults, it's supposed to be an enum (bug 778113)
-  return (nsresult)NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_SECURITY,
-                                             -1 * error);
-}
-
-// IMPORTANT: This must be called immediately after the function returning the
-// SECStatus result. The recommended usage is:
-//    nsresult rv = MapSECStatus(f(x, y, z));
-nsresult
-MapSECStatus(SECStatus rv)
-{
-  if (rv == SECSuccess)
-    return NS_OK;
-
-  PRErrorCode error = PR_GetError();
-  return PRErrorCode_to_nsresult(error);
-}
-
 #define DSA_KEY_TYPE_STRING (NS_LITERAL_CSTRING("DS160"))
 #define RSA_KEY_TYPE_STRING (NS_LITERAL_CSTRING("RS256"))
 

From e09dffecb5a2b7c5fe0ab5df64931ca09b025fea Mon Sep 17 00:00:00 2001
From: Justin Lebar 
Date: Mon, 19 Nov 2012 23:14:14 -0500
Subject: [PATCH 41/57] Bug 812957 - Follow-up: Replace void\n* with void*\n.
 r=oops DONTBUILD

---
 gfx/thebes/gfxAndroidPlatform.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/gfx/thebes/gfxAndroidPlatform.cpp b/gfx/thebes/gfxAndroidPlatform.cpp
index 648b8f6761cc..9edbcfe267e2 100644
--- a/gfx/thebes/gfxAndroidPlatform.cpp
+++ b/gfx/thebes/gfxAndroidPlatform.cpp
@@ -49,8 +49,8 @@ NS_MEMORY_REPORTER_IMPLEMENT(Freetype,
 NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(FreetypeMallocSizeOfForCounterInc, "freetype")
 NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN_UN(FreetypeMallocSizeOfForCounterDec)
 
-static void
-*CountingAlloc(FT_Memory memory, long size)
+static void*
+CountingAlloc(FT_Memory memory, long size)
 {
     void *p = malloc(size);
     sFreetypeMemoryUsed += FreetypeMallocSizeOfForCounterInc(p);
@@ -64,8 +64,8 @@ CountingFree(FT_Memory memory, void* p)
     free(p);
 }
 
-static void
-*CountingRealloc(FT_Memory memory, long cur_size, long new_size, void* p)
+static void*
+CountingRealloc(FT_Memory memory, long cur_size, long new_size, void* p)
 {
     sFreetypeMemoryUsed -= FreetypeMallocSizeOfForCounterDec(p);
     void *pnew = realloc(p, new_size);

From 2980f5b3c0a2ce96cde46a51267ef3e4ea935a85 Mon Sep 17 00:00:00 2001
From: Brian Smith 
Date: Mon, 19 Nov 2012 20:24:47 -0800
Subject: [PATCH 42/57] Backed out changeset ef6db4ced917 (bug 804663) due to
 build bustage, a=bustage

--HG--
extra : rebase_source : 20d434a5f205052e836e059bcee57a0bf84725c4
---
 security/manager/ssl/src/CryptoTask.cpp     |  71 -------
 security/manager/ssl/src/CryptoTask.h       |  87 ---------
 security/manager/ssl/src/Makefile.in        |   2 -
 security/manager/ssl/src/ScopedNSSTypes.h   | 202 +-------------------
 security/manager/ssl/src/nsNSSComponent.cpp |   5 +-
 toolkit/identity/IdentityCryptoService.cpp  |  29 ++-
 6 files changed, 35 insertions(+), 361 deletions(-)
 delete mode 100644 security/manager/ssl/src/CryptoTask.cpp
 delete mode 100644 security/manager/ssl/src/CryptoTask.h

diff --git a/security/manager/ssl/src/CryptoTask.cpp b/security/manager/ssl/src/CryptoTask.cpp
deleted file mode 100644
index 02000f0fffba..000000000000
--- a/security/manager/ssl/src/CryptoTask.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "CryptoTask.h"
-
-namespace mozilla {
-
-CryptoTask::~CryptoTask()
-{
-  MOZ_ASSERT(mReleasedNSSResources);
-
-  nsNSSShutDownPreventionLock lock;
-  if (!isAlreadyShutDown()) {
-    shutdown(calledFromObject);
-  }
-}
-
-nsresult
-CryptoTask::Dispatch(const nsACString & taskThreadName)
-{
-  nsCOMPtr thread;
-  nsresult rv = NS_NewThread(getter_AddRefs(thread), this);
-  if (thread) {
-    NS_SetThreadName(thread, taskThreadName);
-  }
-  return rv;
-}
-
-NS_IMETHODIMP
-CryptoTask::Run()
-{
-  if (!NS_IsMainThread()) {
-    nsNSSShutDownPreventionLock locker;
-    if (isAlreadyShutDown()) {
-      mRv = NS_ERROR_NOT_AVAILABLE;
-    } else {
-      mRv = CalculateResult();
-    }
-    NS_DispatchToMainThread(this);
-  } else {
-    // back on the main thread
-
-    // call ReleaseNSSResources now, before calling CallCallback, so that
-    // CryptoTasks have consistent behavior regardless of whether NSS is shut
-    // down between CalculateResult being called and CallCallback being called.
-    if (!mReleasedNSSResources) {
-      mReleasedNSSResources = true;
-      ReleaseNSSResources();
-    }
-
-    CallCallback(mRv);
-  }
-
-  return NS_OK;
-}
-
-void
-CryptoTask::virtualDestroyNSSReference()
-{
-  NS_ABORT_IF_FALSE(NS_IsMainThread(),
-                    "virtualDestroyNSSReference called off the main thread");
-  if (!mReleasedNSSResources) {
-    mReleasedNSSResources = true;
-    ReleaseNSSResources();
-  }
-}
-
-} // namespace mozilla
diff --git a/security/manager/ssl/src/CryptoTask.h b/security/manager/ssl/src/CryptoTask.h
deleted file mode 100644
index 465b88f7cdd1..000000000000
--- a/security/manager/ssl/src/CryptoTask.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla__CryptoTask_h
-#define mozilla__CryptoTask_h
-
-#include "mozilla/Attributes.h"
-#include "nsThreadUtils.h"
-#include "nsNSSShutDown.h"
-
-namespace mozilla {
-
-/**
- * Frequently we need to run a task on a background thread without blocking
- * the main thread, and then call a callback on the main thread with the
- * result. This class provides the framework for that. Subclasses must:
- *
- *   (1) Override CalculateResult for the off-the-main-thread computation.
- *       NSS functionality may only be accessed within CalculateResult.
- *   (2) Override ReleaseNSSResources to release references to all NSS
- *       resources (that do implement nsNSSShutDownObject themselves).
- *   (3) Override CallCallback() for the on-the-main-thread call of the
- *       callback.
- *
- * CalculateResult, ReleaseNSSResources, and CallCallback are called in order,
- * except CalculateResult might be skipped if NSS is shut down before it can
- * be called; in that case ReleaseNSSResources will be called and then
- * CallCallback will be called with an error code.
- */
-class CryptoTask : public nsRunnable,
-                   public nsNSSShutDownObject
-{
-public:
-  template 
-  nsresult Dispatch(const char (&taskThreadName)[LEN])
-  {
-    MOZ_STATIC_ASSERT(LEN <= 15,
-                      "Thread name must be no more than 15 characters");
-    return Dispatch(nsDependentCString(taskThreadName));
-  }
-
-protected:
-  CryptoTask()
-    : mRv(NS_ERROR_NOT_INITIALIZED),
-      mReleasedNSSResources(false)
-  {
-  }
-
-  virtual ~CryptoTask();
-
-  /**
-   * Called on a background thread (never the main thread). If CalculateResult
-   * is called, then its result will be passed to CallCallback on the main
-   * thread.
-   */
-  virtual nsresult CalculateResult() = 0;
-
-  /**
-   * Called on the main thread during NSS shutdown or just before CallCallback
-   * has been called. All NSS resources must be released. Usually, this just
-   * means assigning nullptr to the ScopedNSSType-based memory variables.
-   */
-  virtual void ReleaseNSSResources() = 0;
-
-  /**
-   * Called on the main thread with the result from CalculateResult() or
-   * with an error code if NSS was shut down before CalculateResult could
-   * be called.
-   */
-  virtual void CallCallback(nsresult rv) = 0;
-
-private:
-  NS_IMETHOD Run() MOZ_OVERRIDE MOZ_FINAL;
-  virtual void virtualDestroyNSSReference() MOZ_OVERRIDE MOZ_FINAL;
-
-  nsresult Dispatch(const nsACString & taskThreadName);
-
-  nsresult mRv;
-  bool mReleasedNSSResources;
-};
-
-} // namespace mozilla
-
-#endif // mozilla__CryptoTask_h
diff --git a/security/manager/ssl/src/Makefile.in b/security/manager/ssl/src/Makefile.in
index 8bc4a34c17fa..99e9acf381bb 100644
--- a/security/manager/ssl/src/Makefile.in
+++ b/security/manager/ssl/src/Makefile.in
@@ -20,7 +20,6 @@ GRE_MODULE	= 1
 LIBXUL_LIBRARY	= 1
 
 CPPSRCS = 				\
-	CryptoTask.cpp \
 	nsCERTValInParamWrapper.cpp     \
 	nsNSSCleaner.cpp                \
 	nsCertOverrideService.cpp   \
@@ -91,7 +90,6 @@ DEFINES += \
   $(NULL)
 
 EXPORTS += \
-  CryptoTask.h \
   nsNSSShutDown.h \
   ScopedNSSTypes.h \
   $(NULL)
diff --git a/security/manager/ssl/src/ScopedNSSTypes.h b/security/manager/ssl/src/ScopedNSSTypes.h
index 4a560f0e4a48..8de8555fdc52 100644
--- a/security/manager/ssl/src/ScopedNSSTypes.h
+++ b/security/manager/ssl/src/ScopedNSSTypes.h
@@ -7,8 +7,6 @@
 #ifndef mozilla_ScopedNSSTypes_h
 #define mozilla_ScopedNSSTypes_h
 
-#include "mozilla/Likely.h"
-#include "mozilla/mozalloc_oom.h"
 #include "mozilla/Scoped.h"
 
 #include "prio.h"
@@ -17,61 +15,6 @@
 #include "keyhi.h"
 #include "pk11pub.h"
 #include "sechash.h"
-#include "secpkcs7.h"
-#include "prerror.h"
-
-namespace mozilla {
-
-// It is very common to cast between char* and uint8_t* when doing crypto stuff.
-// Here, we provide more type-safe wrappers around reinterpret_cast so you don't
-// shoot yourself in the foot by reinterpret_casting completely unrelated types.
-
-inline char *
-char_ptr_cast(uint8_t * p) { return reinterpret_cast(p); }
-
-inline const char *
-char_ptr_cast(const uint8_t * p) { return reinterpret_cast(p); }
-
-inline uint8_t *
-uint8_t_ptr_cast(char * p) { return reinterpret_cast(p); }
-
-inline const uint8_t *
-uint8_t_ptr_cast(const char * p) { return reinterpret_cast(p); }
-
-// NSPR APIs use PRStatus/PR_GetError and NSS APIs use SECStatus/PR_GetError to
-// report success/failure. These funtions make it more convenient and *safer*
-// to translate NSPR/NSS results to nsresult. They are safer because they
-// refuse to traslate any bad PRStatus/SECStatus into an NS_OK, even when the
-// NSPR/NSS function forgot to call PR_SetError.
-
-// IMPORTANT: This must be called immediately after the function that set the
-// error code. Prefer using MapSECStatus to this.
-inline nsresult
-PRErrorCode_to_nsresult(PRErrorCode error)
-{
-  if (!error) {
-    MOZ_NOT_REACHED("Function failed without calling PR_GetError");
-    return NS_ERROR_UNEXPECTED;
-  }
-
-  // From NSSErrorsService::GetXPCOMFromNSSError
-  // XXX Don't make up nsresults, it's supposed to be an enum (bug 778113)
-  return (nsresult)NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_SECURITY,
-                                             -1 * error);
-}
-
-// IMPORTANT: This must be called immediately after the function returning the
-// SECStatus result. The recommended usage is:
-//    nsresult rv = MapSECStatus(f(x, y, z));
-inline nsresult
-MapSECStatus(SECStatus rv)
-{
-  if (rv == SECSuccess)
-    return NS_OK;
-
-  PRErrorCode error = PR_GetError();
-  return PRErrorCode_to_nsresult(error);
-}
 
 // Alphabetical order by NSS type
 MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPRFileDesc,
@@ -102,6 +45,10 @@ MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedCERTValidity,
                                           CERTValidity,
                                           CERT_DestroyValidity)
 
+MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedHASHContext,
+                                          HASHContext,
+                                          HASH_Destroy)
+
 MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedNSSCMSMessage,
                                           NSSCMSMessage,
                                           NSS_CMSMessage_Destroy)
@@ -109,93 +56,6 @@ MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedNSSCMSSignedData,
                                           NSSCMSSignedData,
                                           NSS_CMSSignedData_Destroy)
 
-namespace psm {
-
-inline void
-PK11_DestroyContext_true(PK11Context * ctx) {
-  PK11_DestroyContext(ctx, true);
-}
-
-} // namespace mozilla::psm
-
-MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPK11Context,
-                                          PK11Context,
-                                          mozilla::psm::PK11_DestroyContext_true)
-
-/** A more convenient way of dealing with digests calculated into
- *  stack-allocated buffers.
- *
- * Typical usage, for digesting a buffer in memory:
- *
- *   Digest digest;
- *   nsresult rv = digest.DigestBuf(SEC_OID_SHA256, mybuffer, myBufferLen);
- *   NS_ENSURE_SUCCESS(rv, rv);
- *   rv = MapSECStatus(SomeNSSFunction(..., digest.get(), ...));
- *
- * Less typical usage, for digesting while doing streaming I/O and similar:
- *
- *   Digest digest;
- *   ScopedPK11Context digestContext(PK11_CreateDigestContext(SEC_OID_SHA1));
- *   NS_ENSURE_TRUE(digestContext, NS_ERROR_OUT_OF_MEMORY);
- *   rv = MapSECStatus(PK11_DigestBegin(digestContext));
- *   NS_ENSURE_SUCCESS(rv, rv);
- *   for (...) {
- *      rv = MapSECStatus(PK11_DigestOp(digestContext, ...));
- *      NS_ENSURE_SUCCESS(rv, rv);
- *   }
- *   rv = digestContext.End(SEC_OID_SHA1, digestContext);
- *   NS_ENSURE_SUCCESS(rv, rv)
- */
-class Digest
-{
-public:
-  Digest()
-  {
-    item.type = siBuffer;
-    item.data = buf;
-    item.len = 0;
-  }
-
-  nsresult DigestBuf(SECOidTag hashAlg, const uint8_t * buf, uint32_t len)
-  {
-    nsresult rv = SetLength(hashAlg);
-    NS_ENSURE_SUCCESS(rv, rv);
-    return MapSECStatus(PK11_HashBuf(hashAlg, item.data, buf, len));
-  }
-
-  nsresult End(SECOidTag hashAlg, ScopedPK11Context & context)
-  {
-    nsresult rv = SetLength(hashAlg);
-    NS_ENSURE_SUCCESS(rv, rv);
-    uint32_t len;
-    rv = MapSECStatus(PK11_DigestFinal(context, item.data, &len, item.len));
-    NS_ENSURE_SUCCESS(rv, rv);
-    context = nullptr;
-    NS_ENSURE_TRUE(len == item.len, NS_ERROR_UNEXPECTED);
-    return NS_OK;
-  }
-
-  const SECItem & get() const { return item; }
-
-private:
-  nsresult SetLength(SECOidTag hashType)
-  {
-    switch (hashType)
-    {
-      case SEC_OID_SHA1:   item.len = SHA1_LENGTH;   break;
-      case SEC_OID_SHA256: item.len = SHA256_LENGTH; break;
-      case SEC_OID_SHA384: item.len = SHA384_LENGTH; break;
-      case SEC_OID_SHA512: item.len = SHA512_LENGTH; break;
-      default:
-        return NS_ERROR_INVALID_ARG;
-    }
-
-    return NS_OK;
-  }
-
-  uint8_t buf[HASH_LENGTH_MAX];
-  SECItem item;
-};
 
 MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPK11SlotInfo,
                                           PK11SlotInfo,
@@ -207,59 +67,6 @@ MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPK11SymKey,
                                           PK11SymKey,
                                           PK11_FreeSymKey)
 
-MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedSEC_PKCS7ContentInfo,
-                                          SEC_PKCS7ContentInfo,
-                                          SEC_PKCS7DestroyContentInfo)
-
-// Wrapper around NSS's SECItem_AllocItem that handles OOM the same way as
-// other allocators.
-inline void
-SECITEM_AllocItem(SECItem & item, uint32_t len)
-{
-  if (MOZ_UNLIKELY(!SECITEM_AllocItem(nullptr, &item, len))) {
-    mozalloc_handle_oom(len);
-    if (MOZ_UNLIKELY(!SECITEM_AllocItem(nullptr, &item, len))) {
-      MOZ_CRASH();
-    }
-  }
-}
-
-class ScopedAutoSECItem MOZ_FINAL : public SECItem
-{
-public:
-  ScopedAutoSECItem(uint32_t initialAllocatedLen = 0)
-  {
-    data = NULL;
-    len = 0;
-    if (initialAllocatedLen > 0) {
-      SECITEM_AllocItem(*this, initialAllocatedLen);
-    }
-  }
-
-  void reset()
-  {
-    SECITEM_FreeItem(this, false);
-  }
-
-  ~ScopedAutoSECItem()
-  {
-    reset();
-  }
-};
-
-namespace psm {
-
-inline void SECITEM_FreeItem_true(SECItem * s)
-{
-  return SECITEM_FreeItem(s, true);
-}
-
-} // namespace impl
-
-MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedSECItem,
-                                          ::SECItem,
-                                          ::mozilla::psm::SECITEM_FreeItem_true)
-
 MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedSECKEYPrivateKey,
                                           SECKEYPrivateKey,
                                           SECKEY_DestroyPrivateKey)
@@ -267,6 +74,5 @@ MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedSECKEYPublicKey,
                                           SECKEYPublicKey,
                                           SECKEY_DestroyPublicKey)
 
-} // namespace mozilla
 
 #endif // mozilla_ScopedNSSTypes_h
diff --git a/security/manager/ssl/src/nsNSSComponent.cpp b/security/manager/ssl/src/nsNSSComponent.cpp
index 3a93e8c482a6..a9d703f95ee2 100644
--- a/security/manager/ssl/src/nsNSSComponent.cpp
+++ b/security/manager/ssl/src/nsNSSComponent.cpp
@@ -55,7 +55,6 @@
 #include "nsNSSShutDown.h"
 #include "nsSmartCardEvent.h"
 #include "nsIKeyModule.h"
-#include "ScopedNSSTypes.h"
 
 #include "nss.h"
 #include "pk11func.h"
@@ -2029,7 +2028,7 @@ nsNSSComponent::VerifySignature(const char* aRSABuf, uint32_t aRSABufLen,
   *aPrincipal = nullptr;
 
   nsNSSShutDownPreventionLock locker;
-  ScopedSEC_PKCS7ContentInfo p7_info; 
+  SEC_PKCS7ContentInfo * p7_info = nullptr; 
   unsigned char hash[SHA1_LENGTH]; 
 
   SECItem item;
@@ -2128,6 +2127,8 @@ nsNSSComponent::VerifySignature(const char* aRSABuf, uint32_t aRSABufLen,
     } while (0);
   }
 
+  SEC_PKCS7DestroyContentInfo(p7_info);
+
   return rv2;
 }
 
diff --git a/toolkit/identity/IdentityCryptoService.cpp b/toolkit/identity/IdentityCryptoService.cpp
index d476103ce658..707636ced19d 100644
--- a/toolkit/identity/IdentityCryptoService.cpp
+++ b/toolkit/identity/IdentityCryptoService.cpp
@@ -13,7 +13,6 @@
 #include "nsCOMPtr.h"
 #include "nsStringGlue.h"
 #include "mozilla/Base64.h"
-#include "ScopedNSSTypes.h"
 
 #include "nss.h"
 #include "pk11pub.h"
@@ -61,6 +60,34 @@ Base64UrlEncodeImpl(const nsACString & utf8Input, nsACString & result)
   return NS_OK;
 }
 
+
+nsresult
+PRErrorCode_to_nsresult(PRErrorCode error)
+{
+  if (!error) {
+    MOZ_NOT_REACHED("Function failed without calling PR_GetError");
+    return NS_ERROR_UNEXPECTED;
+  }
+
+  // From NSSErrorsService::GetXPCOMFromNSSError
+  // XXX Don't make up nsresults, it's supposed to be an enum (bug 778113)
+  return (nsresult)NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_SECURITY,
+                                             -1 * error);
+}
+
+// IMPORTANT: This must be called immediately after the function returning the
+// SECStatus result. The recommended usage is:
+//    nsresult rv = MapSECStatus(f(x, y, z));
+nsresult
+MapSECStatus(SECStatus rv)
+{
+  if (rv == SECSuccess)
+    return NS_OK;
+
+  PRErrorCode error = PR_GetError();
+  return PRErrorCode_to_nsresult(error);
+}
+
 #define DSA_KEY_TYPE_STRING (NS_LITERAL_CSTRING("DS160"))
 #define RSA_KEY_TYPE_STRING (NS_LITERAL_CSTRING("RS256"))
 

From 4e419ab728cd80ffcc036cb6cb9d7496520fbc89 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote 
Date: Mon, 19 Nov 2012 16:18:41 -0800
Subject: [PATCH 43/57] Bug 811203 (part 1) - Inline
 XPTMethodDescriptor::result.  r=khuey.

--HG--
extra : rebase_source : 1c2a89684f5b60a3e24ce995ed7e062e88e18610
---
 xpcom/reflect/xptinfo/public/xptinfo.h  |  2 +-
 xpcom/typelib/xpt/public/xpt_struct.h   |  2 +-
 xpcom/typelib/xpt/src/xpt_struct.c      | 17 +++--------------
 xpcom/typelib/xpt/tests/SimpleTypeLib.c |  8 ++++----
 4 files changed, 9 insertions(+), 20 deletions(-)

diff --git a/xpcom/reflect/xptinfo/public/xptinfo.h b/xpcom/reflect/xptinfo/public/xptinfo.h
index 010c86e37226..40eb0dfb77b7 100644
--- a/xpcom/reflect/xptinfo/public/xptinfo.h
+++ b/xpcom/reflect/xptinfo/public/xptinfo.h
@@ -172,7 +172,7 @@ public:
             return params[idx];
         }
     const nsXPTParamInfo GetResult() const
-        {return *result;}
+        {return result;}
 private:
     nsXPTMethodInfo();  // no implementation
 // NO DATA - this a flyweight wrapper
diff --git a/xpcom/typelib/xpt/public/xpt_struct.h b/xpcom/typelib/xpt/public/xpt_struct.h
index 3f76a5f8dbdf..e4eaaa6af720 100644
--- a/xpcom/typelib/xpt/public/xpt_struct.h
+++ b/xpcom/typelib/xpt/public/xpt_struct.h
@@ -449,7 +449,7 @@ XPT_FillParamDescriptor(XPTArena *arena,
 struct XPTMethodDescriptor {
     char                *name;
     XPTParamDescriptor  *params;
-    XPTParamDescriptor  *result;
+    XPTParamDescriptor  result;
     uint8_t             flags;
     uint8_t             num_args;
 };
diff --git a/xpcom/typelib/xpt/src/xpt_struct.c b/xpcom/typelib/xpt/src/xpt_struct.c
index c42e375eb3c0..185b4d9a7081 100644
--- a/xpcom/typelib/xpt/src/xpt_struct.c
+++ b/xpcom/typelib/xpt/src/xpt_struct.c
@@ -392,7 +392,6 @@ XPT_FreeInterfaceDescriptor(XPTArena *arena, XPTInterfaceDescriptor* id)
         for (; md < mdend; md++) {
             XPT_FREEIF(arena, md->name);
             XPT_FREEIF(arena, md->params);
-            XPT_FREEIF(arena, md->result);
         }
         XPT_FREEIF(arena, id->method_descriptors);
 
@@ -514,10 +513,10 @@ SizeOfMethodDescriptor(XPTMethodDescriptor *md, XPTInterfaceDescriptor *id)
 {
     uint32_t i, size =  1 /* flags */ + 4 /* name */ + 1 /* num_args */;
 
-    for (i = 0; i < md->num_args; i++) 
+    for (i = 0; i < md->num_args; i++)
         size += 1 + SizeOfTypeDescriptor(&md->params[i].type, id);
 
-    size += 1 + SizeOfTypeDescriptor(&md->result->type, id);
+    size += 1 + SizeOfTypeDescriptor(&md->result.type, id);
     return size;
 }
 
@@ -711,9 +710,6 @@ XPT_FillMethodDescriptor(XPTArena *arena, XPTMethodDescriptor *meth,
     } else {
         meth->params = NULL;
     }
-    meth->result = XPT_NEWZAP(arena, XPTParamDescriptor);
-    if (!meth->result)
-        goto free_params;
     return PR_TRUE;
 
  free_params:
@@ -746,14 +742,7 @@ DoMethodDescriptor(XPTArena *arena, XPTCursor *cursor, XPTMethodDescriptor *md,
             goto error;
     }
     
-    if (mode == XPT_DECODE) {
-        md->result = XPT_NEWZAP(arena, XPTParamDescriptor);
-        if (!md->result)
-            return PR_FALSE;
-    }
-
-    if (!md->result ||
-        !DoParamDescriptor(arena, cursor, md->result, id))
+    if (!DoParamDescriptor(arena, cursor, &md->result, id))
         goto error;
     
     return PR_TRUE;
diff --git a/xpcom/typelib/xpt/tests/SimpleTypeLib.c b/xpcom/typelib/xpt/tests/SimpleTypeLib.c
index 6d78dc4034b3..4ce8e75e8359 100644
--- a/xpcom/typelib/xpt/tests/SimpleTypeLib.c
+++ b/xpcom/typelib/xpt/tests/SimpleTypeLib.c
@@ -88,16 +88,16 @@ main(int argc, char **argv)
     meth = &id->method_descriptors[0];
     ok = XPT_FillMethodDescriptor(arena, meth, 0, "method1", 0);
     TRY("FillMethodDescriptor", ok);
-    meth->result->flags = 0;
-    meth->result->type.prefix.flags = TD_VOID;
+    meth->result.flags = 0;
+    meth->result.type.prefix.flags = TD_VOID;
 
     /* wstring method2(in uint32_t, in bool) */
     meth = &id->method_descriptors[1];
     ok = XPT_FillMethodDescriptor(arena, meth, 0, "method2", 2);
     TRY("FillMethodDescriptor", ok);
 
-    meth->result->flags = 0;
-    meth->result->type.prefix.flags = TD_PSTRING | XPT_TDP_POINTER;
+    meth->result.flags = 0;
+    meth->result.type.prefix.flags = TD_PSTRING | XPT_TDP_POINTER;
     meth->params[0].type.prefix.flags = TD_UINT32;
     meth->params[0].flags = XPT_PD_IN;
     meth->params[1].type.prefix.flags = TD_BOOL;

From 69b10075fc1e69523266670c3bbb51a68addebe5 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote 
Date: Mon, 19 Nov 2012 16:19:17 -0800
Subject: [PATCH 44/57] Bug 811203 (part 2) - Pack the fields in
 XPTInterfaceDescriptor better.  r=khuey.

--HG--
extra : rebase_source : e5afee2bf6ba8cc2a1ee344f176a819367bc9d32
---
 xpcom/typelib/xpt/public/xpt_struct.h | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/xpcom/typelib/xpt/public/xpt_struct.h b/xpcom/typelib/xpt/public/xpt_struct.h
index e4eaaa6af720..f71e90e6c86b 100644
--- a/xpcom/typelib/xpt/public/xpt_struct.h
+++ b/xpcom/typelib/xpt/public/xpt_struct.h
@@ -206,11 +206,16 @@ XPT_DestroyInterfaceDirectoryEntry(XPTArena *arena,
  * single XPCOM interface, including all of its methods. 
  */
 struct XPTInterfaceDescriptor {
+    /* This field ordering minimizes the size of this struct.
+    *  The fields are serialized on disk in a different order.
+    *  See DoInterfaceDescriptor().
+    */
+    XPTMethodDescriptor     *method_descriptors;
+    XPTConstDescriptor      *const_descriptors;
+    XPTTypeDescriptor       *additional_types;
     uint16_t                parent_interface;
     uint16_t                num_methods;
-    XPTMethodDescriptor     *method_descriptors;
     uint16_t                num_constants;
-    XPTConstDescriptor      *const_descriptors;
     uint8_t                 flags;
 
     /* additional_types are used for arrays where we may need multiple
@@ -229,7 +234,6 @@ struct XPTInterfaceDescriptor {
     *  for that.
     */
 
-    XPTTypeDescriptor       *additional_types;
     uint16_t                num_additional_types;
 };
 

From d810cdfa1b83e3bf138ae423e7f67badd6efee4a Mon Sep 17 00:00:00 2001
From: Geoff Brown 
Date: Mon, 19 Nov 2012 21:33:01 -0700
Subject: [PATCH 45/57] Bug 812791 - Correct typo in ctm-singular-sanity
 reftest; r=cjones

---
 layout/reftests/canvas/ctm-singular-sanity.html | 2 +-
 layout/reftests/canvas/reftest.list             | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/layout/reftests/canvas/ctm-singular-sanity.html b/layout/reftests/canvas/ctm-singular-sanity.html
index 8e6af1c99ada..7080ce7c3f68 100644
--- a/layout/reftests/canvas/ctm-singular-sanity.html
+++ b/layout/reftests/canvas/ctm-singular-sanity.html
@@ -36,7 +36,7 @@ window.onload = function() {
         var m = [ 1, 2, 3, 4, 5, 6 ];
         ctx.mozCurrentTransform = m;
         ctx.mozCurrentTransformInverse = singular;
-        assert(isSameTM(m, ctx.mozCurrentTransform,
+        assert(isSameTM(m, ctx.mozCurrentTransform),
                         "Setting currentTransformInverse to a singular matrix is a no-op");
         ctx.mozCurrentTransform = IM;
     } catch (e) {
diff --git a/layout/reftests/canvas/reftest.list b/layout/reftests/canvas/reftest.list
index b7c10427ac89..43cd6dda63c8 100644
--- a/layout/reftests/canvas/reftest.list
+++ b/layout/reftests/canvas/reftest.list
@@ -73,7 +73,7 @@ fails-if(OSX==10.6||(azureQuartz&&(OSX==10.7||OSX==10.8))) == linear-gradient-1b
 fuzzy-if(azureSkia,9,470) random-if(Android) == dash-1.html dash-1-ref.svg  # Bug 668412 (really is android-specific, not IPC-specific)
 
 == ctm-sanity.html data:text/html,Pass
-fails == ctm-singular-sanity.html data:text/html,Pass  # Bug 612033
+== ctm-singular-sanity.html data:text/html,Pass
 == ctm-1.html ctm-1-ref.html
 
 fails-if(OSX==10.6) == 672646-alpha-radial-gradient.html 672646-alpha-radial-gradient-ref.html # Bug 673333

From 8cc35a7931e04a7d17f944c21024d058bde4e5f9 Mon Sep 17 00:00:00 2001
From: Phil Ringnalda 
Date: Mon, 19 Nov 2012 20:34:52 -0800
Subject: [PATCH 46/57] Back out 1b6d5e373bcc (bug 812845) for timeouts in
 accessible/events/test_textattrchange.html

--HG--
extra : rebase_source : a4e733ee7db79b26176ad0eb703e06beb79f4719
---
 .../mochitest/events/test_textattrchange.html | 45 +++----------------
 1 file changed, 7 insertions(+), 38 deletions(-)

diff --git a/accessible/tests/mochitest/events/test_textattrchange.html b/accessible/tests/mochitest/events/test_textattrchange.html
index e990f3f9d1d8..a69a8df15e08 100644
--- a/accessible/tests/mochitest/events/test_textattrchange.html
+++ b/accessible/tests/mochitest/events/test_textattrchange.html
@@ -29,7 +29,7 @@
 
     Components.utils.import("resource://gre/modules/InlineSpellChecker.jsm");
 
-    function spelledTextInvoker(aID, aText, aTests)
+    function spelledTextInvoker(aID)
     {
       this.DOMNode = getNode(aID);
 
@@ -46,7 +46,7 @@
         //var spellchecker = editor.getInlineSpellChecker(true);
         //spellchecker.enableRealTimeSpell = true;
 
-        this.DOMNode.value = aText;
+        this.DOMNode.value = "valid text inalid tixt";
       }
 
       this.finalCheck = function spelledTextInvoker_finalCheck()
@@ -61,11 +61,10 @@
           "invalid": "spelling"
         };
 
-        for (var i = 0; i < aTests.length; i++) {
-          testTextAttrs(aID, aTests[i].start,
-                        aTests[i].misspelled ? misspelledAttrs : attrs,
-                        defAttrs, aTests[i].start, aTests[i].end);
-        }
+        testTextAttrs(aID, 0, attrs, defAttrs, 0, 11);
+        testTextAttrs(aID, 11, misspelledAttrs, defAttrs, 11, 17);
+        testTextAttrs(aID, 17, attrs, defAttrs, 17, 18);
+        testTextAttrs(aID, 18, misspelledAttrs, defAttrs, 18, 22);
       }
 
       this.getID = function spelledTextInvoker_getID()
@@ -88,32 +87,7 @@
 
       gQueue = new eventQueue();
       gQueue.push(new synthFocus("input"));
-
-      var tests = [
-        { misspelled: false, start: 0, end: 11},
-        { misspelled: true, start: 11, end: 17},
-        { misspelled: false, start: 17, end: 18},
-        { misspelled: true, start: 18, end: 22}
-      ];
-      gQueue.push(new spelledTextInvoker("input", "valid text inalid tixt",
-                                         tests));
-
-      tests = [
-        { misspelled: false, start: 0, end: 4}
-      ];
-      gQueue.push(new spelledTextInvoker("input", "that", tests));
-
-      tests = [
-        { misspelled: true, start: 0, end: 4}
-      ];
-      gQueue.push(new spelledTextInvoker("input", "taht", tests));
-
-      tests = [
-        { misspelled: true, start: 0, end: 4},
-        { misspelled: false, start: 4, end: 8}
-      ];
-      gQueue.push(new spelledTextInvoker("input", "taht cat", tests));
-
+      gQueue.push(new spelledTextInvoker("input"));
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
@@ -129,11 +103,6 @@
      title="Implement text attributes">
     Mozilla Bug 345759
   
-  
   


From 334ae7f03271d4b1d576525cbade438d2aa46030 Mon Sep 17 00:00:00 2001
From: Alexander Surkov 
Date: Tue, 20 Nov 2012 13:53:38 +0900
Subject: [PATCH 47/57] Bug 678454 - coalesce events by accessible tree,
 r=tbsaunde

---
 accessible/src/base/AccEvent.cpp              | 130 +---------
 accessible/src/base/AccEvent.h                |  50 ++--
 accessible/src/base/FocusManager.cpp          |   2 +-
 accessible/src/base/Logging.cpp               |   9 +-
 .../src/base/NotificationController.cpp       |   9 +-
 accessible/src/base/NotificationController.h  |   2 +-
 accessible/src/base/TextUpdater.cpp           |   6 +-
 accessible/src/base/nsAccDocManager.cpp       |   5 +-
 accessible/src/base/nsCaretAccessible.cpp     |  20 +-
 accessible/src/base/nsEventShell.cpp          |   2 +-
 accessible/src/generic/DocAccessible-inl.h    |  34 ++-
 accessible/src/generic/DocAccessible.cpp      | 227 +++++++-----------
 accessible/src/generic/DocAccessible.h        |  51 ++--
 accessible/src/generic/RootAccessible.cpp     |  13 +-
 .../src/html/HTMLImageMapAccessible.cpp       |   8 +-
 accessible/src/xpcom/nsAccEvent.cpp           |   2 +-
 accessible/src/xul/XULTreeAccessible.cpp      |   3 +-
 .../tests/mochitest/events/test_attrs.html    |   2 +-
 18 files changed, 201 insertions(+), 374 deletions(-)

diff --git a/accessible/src/base/AccEvent.cpp b/accessible/src/base/AccEvent.cpp
index 9b299c727906..66cad558fa24 100644
--- a/accessible/src/base/AccEvent.cpp
+++ b/accessible/src/base/AccEvent.cpp
@@ -35,47 +35,9 @@ AccEvent::AccEvent(uint32_t aEventType, Accessible* aAccessible,
   CaptureIsFromUserInput(aIsFromUserInput);
 }
 
-AccEvent::AccEvent(uint32_t aEventType, nsINode* aNode,
-                   EIsFromUserInput aIsFromUserInput, EEventRule aEventRule) :
-  mEventType(aEventType), mEventRule(aEventRule), mNode(aNode)
-{
-  CaptureIsFromUserInput(aIsFromUserInput);
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // AccEvent public methods
 
-Accessible* 
-AccEvent::GetAccessible()
-{
-  if (!mAccessible)
-    mAccessible = GetAccessibleForNode();
-
-  return mAccessible;
-}
-
-nsINode*
-AccEvent::GetNode()
-{
-  if (!mNode && mAccessible)
-    mNode = mAccessible->GetNode();
-
-  return mNode;
-}
-
-DocAccessible*
-AccEvent::GetDocAccessible()
-{
-  if (mAccessible)
-    return mAccessible->Document();
-
-  nsINode* node = GetNode();
-  if (node)
-    return GetAccService()->GetDocAccessible(node->OwnerDoc());
-
-  return nullptr;
-}
-
 already_AddRefed
 AccEvent::CreateXPCOMObject()
 {
@@ -104,56 +66,23 @@ NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(AccEvent, Release)
 ////////////////////////////////////////////////////////////////////////////////
 // AccEvent protected methods
 
-Accessible*
-AccEvent::GetAccessibleForNode() const
-{
-  if (mNode) {
-    DocAccessible* document =
-      GetAccService()->GetDocAccessible(mNode->OwnerDoc());
-    if (document)
-      return document->GetAccessible(mNode);
-  }
-
-  return nullptr;
-}
-
 void
 AccEvent::CaptureIsFromUserInput(EIsFromUserInput aIsFromUserInput)
 {
-  nsINode *targetNode = GetNode();
-
-#ifdef DEBUG
-  if (!targetNode) {
-    // XXX: remove this hack during reorganization of 506907. Meanwhile we
-    // want to get rid an assertion for application accessible events which
-    // don't have DOM node (see bug 506206).
-
-    if (mAccessible != static_cast(ApplicationAcc()))
-      NS_ASSERTION(targetNode, "There should always be a DOM node for an event");
-  }
-#endif
-
   if (aIsFromUserInput != eAutoDetect) {
     mIsFromUserInput = aIsFromUserInput == eFromUserInput ? true : false;
     return;
   }
 
-  if (!targetNode)
-    return;
-
-  nsIPresShell *presShell = nsCoreUtils::GetPresShellFor(targetNode);
-  if (!presShell) {
-    NS_NOTREACHED("Threre should always be an pres shell for an event");
+  DocAccessible* document = mAccessible->Document();
+  if (!document) {
+    NS_ASSERTION(mAccessible == ApplicationAcc(),
+                 "Accessible other than application should always have a doc!");
     return;
   }
 
-  nsEventStateManager *esm = presShell->GetPresContext()->EventStateManager();
-  if (!esm) {
-    NS_NOTREACHED("There should always be an ESM for an event");
-    return;
-  }
-
-  mIsFromUserInput = esm->IsHandlingUserInputExternal();
+  mIsFromUserInput =
+    document->PresContext()->EventStateManager()->IsHandlingUserInputExternal();
 }
 
 
@@ -161,39 +90,6 @@ AccEvent::CaptureIsFromUserInput(EIsFromUserInput aIsFromUserInput)
 // AccStateChangeEvent
 ////////////////////////////////////////////////////////////////////////////////
 
-// Note: we pass in eAllowDupes to the base class because we don't currently
-// support correct state change coalescence (XXX Bug 569356). Also we need to
-// decide how to coalesce events created via accessible (instead of node).
-AccStateChangeEvent::
-  AccStateChangeEvent(Accessible* aAccessible, uint64_t aState,
-                      bool aIsEnabled, EIsFromUserInput aIsFromUserInput):
-  AccEvent(nsIAccessibleEvent::EVENT_STATE_CHANGE, aAccessible,
-           aIsFromUserInput, eAllowDupes),
-  mState(aState), mIsEnabled(aIsEnabled)
-{
-}
-
-AccStateChangeEvent::
-  AccStateChangeEvent(nsINode* aNode, uint64_t aState, bool aIsEnabled):
-  AccEvent(::nsIAccessibleEvent::EVENT_STATE_CHANGE, aNode,
-           eAutoDetect, eAllowDupes),
-  mState(aState), mIsEnabled(aIsEnabled)
-{
-}
-
-AccStateChangeEvent::
-  AccStateChangeEvent(nsINode* aNode, uint64_t aState) :
-  AccEvent(::nsIAccessibleEvent::EVENT_STATE_CHANGE, aNode,
-           eAutoDetect, eAllowDupes),
-  mState(aState)
-{
-  // Use GetAccessibleForNode() because we do not want to store an accessible
-  // since it leads to problems with delayed events in the case when
-  // an accessible gets reorder event before delayed event is processed.
-  Accessible* accessible = GetAccessibleForNode();
-  mIsEnabled = accessible && ((accessible->State() & mState) != 0);
-}
-
 already_AddRefed
 AccStateChangeEvent::CreateXPCOMObject()
 {
@@ -296,20 +192,6 @@ AccShowEvent::
 // AccCaretMoveEvent
 ////////////////////////////////////////////////////////////////////////////////
 
-AccCaretMoveEvent::
-  AccCaretMoveEvent(Accessible* aAccessible, int32_t aCaretOffset) :
-  AccEvent(::nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED, aAccessible),
-  mCaretOffset(aCaretOffset)
-{
-}
-
-AccCaretMoveEvent::
-  AccCaretMoveEvent(nsINode* aNode) :
-  AccEvent(::nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED, aNode),
-  mCaretOffset(-1)
-{
-}
-
 already_AddRefed
 AccCaretMoveEvent::CreateXPCOMObject()
 {
diff --git a/accessible/src/base/AccEvent.h b/accessible/src/base/AccEvent.h
index 2d1d4f12020e..ddce278fc32d 100644
--- a/accessible/src/base/AccEvent.h
+++ b/accessible/src/base/AccEvent.h
@@ -38,17 +38,18 @@ public:
   // Rule for accessible events.
   // The rule will be applied when flushing pending events.
   enum EEventRule {
-     // eAllowDupes : More than one event of the same type is allowed.
-     //    This event will always be emitted.
-     eAllowDupes,
+    // eAllowDupes : More than one event of the same type is allowed.
+    //    This event will always be emitted. This flag is used for events that
+    //    don't support coalescence.
+    eAllowDupes,
 
      // eCoalesceReorder : For reorder events from the same subtree or the same
      //    node, only the umbrella event on the ancestor will be emitted.
-     eCoalesceReorder,
+    eCoalesceReorder,
 
      // eCoalesceMutationTextChange : coalesce text change events caused by
      // tree mutations of the same tree level.
-     eCoalesceMutationTextChange,
+    eCoalesceMutationTextChange,
 
     // eCoalesceOfSameType : For events of the same type, only the newest event
     // will be processed.
@@ -59,20 +60,16 @@ public:
 
      // eRemoveDupes : For repeat events, only the newest event in queue
      //    will be emitted.
-     eRemoveDupes,
+    eRemoveDupes,
 
      // eDoNotEmit : This event is confirmed as a duplicate, do not emit it.
-     eDoNotEmit
+    eDoNotEmit
   };
 
   // Initialize with an nsIAccessible
   AccEvent(uint32_t aEventType, Accessible* aAccessible,
            EIsFromUserInput aIsFromUserInput = eAutoDetect,
            EEventRule aEventRule = eRemoveDupes);
-  // Initialize with an nsINode
-  AccEvent(uint32_t aEventType, nsINode* aNode,
-           EIsFromUserInput aIsFromUserInput = eAutoDetect,
-           EEventRule aEventRule = eRemoveDupes);
   virtual ~AccEvent() {}
 
   // AccEvent
@@ -80,9 +77,8 @@ public:
   EEventRule GetEventRule() const { return mEventRule; }
   bool IsFromUserInput() const { return mIsFromUserInput; }
 
-  Accessible* GetAccessible();
-  DocAccessible* GetDocAccessible();
-  nsINode* GetNode();
+  Accessible* GetAccessible() const { return mAccessible; }
+  DocAccessible* GetDocAccessible() const { return mAccessible->Document(); }
 
   /**
    * Create and return an XPCOM object for accessible event object.
@@ -119,10 +115,6 @@ public:
   NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(AccEvent)
 
 protected:
-  /**
-   * Get an accessible from event target node.
-   */
-  Accessible* GetAccessibleForNode() const;
 
   /**
    * Determine whether the event is from user input by event state manager if
@@ -134,7 +126,6 @@ protected:
   uint32_t mEventType;
   EEventRule mEventRule;
   nsRefPtr mAccessible;
-  nsCOMPtr mNode;
 
   friend class NotificationController;
   friend class AccReorderEvent;
@@ -149,11 +140,15 @@ class AccStateChangeEvent: public AccEvent
 public:
   AccStateChangeEvent(Accessible* aAccessible, uint64_t aState,
                       bool aIsEnabled,
-                      EIsFromUserInput aIsFromUserInput = eAutoDetect);
+                      EIsFromUserInput aIsFromUserInput = eAutoDetect) :
+    AccEvent(nsIAccessibleEvent::EVENT_STATE_CHANGE, aAccessible,
+             aIsFromUserInput, eAllowDupes),
+             mState(aState), mIsEnabled(aIsEnabled) { }
 
-  AccStateChangeEvent(nsINode* aNode, uint64_t aState, bool aIsEnabled);
-
-  AccStateChangeEvent(nsINode* aNode, uint64_t aState);
+  AccStateChangeEvent(Accessible* aAccessible, uint64_t aState) :
+    AccEvent(::nsIAccessibleEvent::EVENT_STATE_CHANGE, aAccessible,
+             eAutoDetect, eAllowDupes), mState(aState)
+    { mIsEnabled = (mAccessible->State() & mState) != 0; }
 
   // AccEvent
   virtual already_AddRefed CreateXPCOMObject();
@@ -239,6 +234,7 @@ public:
   bool IsHide() const { return mEventType == nsIAccessibleEvent::EVENT_HIDE; }
 
 protected:
+  nsCOMPtr mNode;
   nsRefPtr mParent;
   nsRefPtr mTextChangeEvent;
 
@@ -350,8 +346,10 @@ protected:
 class AccCaretMoveEvent: public AccEvent
 {
 public:
-  AccCaretMoveEvent(Accessible* aAccessible, int32_t aCaretOffset);
-  AccCaretMoveEvent(nsINode* aNode);
+  AccCaretMoveEvent(Accessible* aAccessible) :
+    AccEvent(::nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED, aAccessible),
+    mCaretOffset(-1) { }
+  virtual ~AccCaretMoveEvent() { }
 
   // AccEvent
   virtual already_AddRefed CreateXPCOMObject();
@@ -367,6 +365,8 @@ public:
 
 private:
   int32_t mCaretOffset;
+
+  friend class NotificationController;
 };
 
 
diff --git a/accessible/src/base/FocusManager.cpp b/accessible/src/base/FocusManager.cpp
index 72d561390848..c3dd87dcf2bc 100644
--- a/accessible/src/base/FocusManager.cpp
+++ b/accessible/src/base/FocusManager.cpp
@@ -219,7 +219,7 @@ FocusManager::DispatchFocusEvent(DocAccessible* aDocument,
     nsRefPtr event =
       new AccEvent(nsIAccessibleEvent::EVENT_FOCUS, aTarget,
                    eAutoDetect, AccEvent::eCoalesceOfSameType);
-    aDocument->FireDelayedAccessibleEvent(event);
+    aDocument->FireDelayedEvent(event);
 
 #ifdef A11Y_LOG
     if (logging::IsEnabled(logging::eFocus))
diff --git a/accessible/src/base/Logging.cpp b/accessible/src/base/Logging.cpp
index 2f1ba9a7b6bd..dbecdf7aea13 100644
--- a/accessible/src/base/Logging.cpp
+++ b/accessible/src/base/Logging.cpp
@@ -471,12 +471,9 @@ logging::DocLoadEventHandled(AccEvent* aEvent)
 
   MsgBegin(sDocEventTitle, "handled '%s' event", strEventType.get());
 
-  nsINode* node = aEvent->GetNode();
-  if (node->IsNodeOfType(nsINode::eDOCUMENT)) {
-    nsIDocument* documentNode = static_cast(node);
-    DocAccessible* document = aEvent->GetDocAccessible();
-    LogDocInfo(documentNode, document);
-  }
+  DocAccessible* document = aEvent->GetAccessible()->AsDoc();
+  if (document)
+    LogDocInfo(document->DocumentNode(), document);
 
   MsgEnd();
 }
diff --git a/accessible/src/base/NotificationController.cpp b/accessible/src/base/NotificationController.cpp
index b4057533be8a..899e2ba3e86d 100644
--- a/accessible/src/base/NotificationController.cpp
+++ b/accessible/src/base/NotificationController.cpp
@@ -385,7 +385,7 @@ NotificationController::CoalesceEvents()
         AccEvent* accEvent = mEvents[index];
         if (accEvent->mEventType == tailEvent->mEventType &&
             accEvent->mEventRule == tailEvent->mEventRule &&
-            accEvent->mNode == tailEvent->mNode) {
+            accEvent->mAccessible == tailEvent->mAccessible) {
           tailEvent->mEventRule = AccEvent::eDoNotEmit;
           return;
         }
@@ -705,12 +705,11 @@ NotificationController::ProcessEventQueue()
 
       // Dispatch caret moved and text selection change events.
       if (event->mEventType == nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED) {
+        AccCaretMoveEvent* caretMoveEvent = downcast_accEvent(event);
         HyperTextAccessible* hyperText = target->AsHyperText();
-        int32_t caretOffset = -1;
         if (hyperText &&
-          NS_SUCCEEDED(hyperText->GetCaretOffset(&caretOffset))) {
-          nsRefPtr caretMoveEvent =
-            new AccCaretMoveEvent(hyperText, caretOffset);
+            NS_SUCCEEDED(hyperText->GetCaretOffset(&caretMoveEvent->mCaretOffset))) {
+
           nsEventShell::FireEvent(caretMoveEvent);
 
           // There's a selection so fire selection change as well.
diff --git a/accessible/src/base/NotificationController.h b/accessible/src/base/NotificationController.h
index 757b682758a7..d9e253084dbe 100644
--- a/accessible/src/base/NotificationController.h
+++ b/accessible/src/base/NotificationController.h
@@ -78,7 +78,7 @@ private:
 
   Class* mInstance;
   Callback mCallback;
-  nsCOMPtr mArg;
+  nsRefPtr mArg;
 };
 
 /**
diff --git a/accessible/src/base/TextUpdater.cpp b/accessible/src/base/TextUpdater.cpp
index e503aeeb514f..866d7a502680 100644
--- a/accessible/src/base/TextUpdater.cpp
+++ b/accessible/src/base/TextUpdater.cpp
@@ -82,14 +82,14 @@ TextUpdater::DoUpdate(const nsAString& aNewText, const nsAString& aOldText,
       // Fire text change event for removal.
       nsRefPtr textRemoveEvent =
         new AccTextChangeEvent(mHyperText, mTextOffset, str1, false);
-      mDocument->FireDelayedAccessibleEvent(textRemoveEvent);
+      mDocument->FireDelayedEvent(textRemoveEvent);
     }
 
     if (strLen2 > 0) {
       // Fire text change event for insertion.
       nsRefPtr textInsertEvent =
         new AccTextChangeEvent(mHyperText, mTextOffset, str2, true);
-      mDocument->FireDelayedAccessibleEvent(textInsertEvent);
+      mDocument->FireDelayedEvent(textInsertEvent);
     }
 
     mDocument->MaybeNotifyOfValueChange(mHyperText);
@@ -135,7 +135,7 @@ TextUpdater::DoUpdate(const nsAString& aNewText, const nsAString& aOldText,
 
   // Fire events.
   for (int32_t idx = events.Length() - 1; idx >= 0; idx--)
-    mDocument->FireDelayedAccessibleEvent(events[idx]);
+    mDocument->FireDelayedEvent(events[idx]);
 
   mDocument->MaybeNotifyOfValueChange(mHyperText);
 
diff --git a/accessible/src/base/nsAccDocManager.cpp b/accessible/src/base/nsAccDocManager.cpp
index cbbbc18200b7..0317bfdbe0fc 100644
--- a/accessible/src/base/nsAccDocManager.cpp
+++ b/accessible/src/base/nsAccDocManager.cpp
@@ -400,9 +400,8 @@ nsAccDocManager::CreateDocOrRootAccessible(nsIDocument* aDocument)
     // the same document.
     // Note: don't use AccReorderEvent to avoid coalsecense and special reorder
     // events processing.
-    nsRefPtr reorderEvent =
-      new AccEvent(nsIAccessibleEvent::EVENT_REORDER, ApplicationAcc());
-    docAcc->FireDelayedAccessibleEvent(reorderEvent);
+    docAcc->FireDelayedEvent(nsIAccessibleEvent::EVENT_REORDER,
+                             ApplicationAcc());
 
   } else {
     parentDocAcc->BindChildDocument(docAcc);
diff --git a/accessible/src/base/nsCaretAccessible.cpp b/accessible/src/base/nsCaretAccessible.cpp
index f52479590c8f..a1a7b26ea268 100644
--- a/accessible/src/base/nsCaretAccessible.cpp
+++ b/accessible/src/base/nsCaretAccessible.cpp
@@ -243,10 +243,8 @@ nsCaretAccessible::NormalSelectionChanged(nsISelection* aSelection)
   mLastCaretOffset = caretOffset;
   mLastTextAccessible = textAcc;
 
-  nsRefPtr event =
-    new AccCaretMoveEvent(mLastTextAccessible->GetNode());
-  if (event)
-    mLastTextAccessible->Document()->FireDelayedAccessibleEvent(event);
+  nsRefPtr event = new AccCaretMoveEvent(mLastTextAccessible);
+  mLastTextAccessible->Document()->FireDelayedEvent(event);
 }
 
 void
@@ -258,15 +256,13 @@ nsCaretAccessible::SpellcheckSelectionChanged(nsISelection* aSelection)
   // misspelled word). If spellchecking is disabled (for example,
   // @spellcheck="false" on html:body) then we won't fire any event.
 
-  HyperTextAccessible* textAcc =
+  HyperTextAccessible* hyperText =
     nsAccUtils::GetTextAccessibleFromSelection(aSelection);
-  if (!textAcc)
-    return;
-
-  nsRefPtr event =
-    new AccEvent(nsIAccessibleEvent::EVENT_TEXT_ATTRIBUTE_CHANGED, textAcc);
-  if (event)
-    textAcc->Document()->FireDelayedAccessibleEvent(event);
+  if (hyperText) {
+    hyperText->Document()->
+      FireDelayedEvent(nsIAccessibleEvent::EVENT_TEXT_ATTRIBUTE_CHANGED,
+                       hyperText);
+  }
 }
 
 nsIntRect
diff --git a/accessible/src/base/nsEventShell.cpp b/accessible/src/base/nsEventShell.cpp
index 6a589fb1645f..06a7084b3f72 100644
--- a/accessible/src/base/nsEventShell.cpp
+++ b/accessible/src/base/nsEventShell.cpp
@@ -22,7 +22,7 @@ nsEventShell::FireEvent(AccEvent* aEvent)
   Accessible* accessible = aEvent->GetAccessible();
   NS_ENSURE_TRUE_VOID(accessible);
 
-  nsINode* node = aEvent->GetNode();
+  nsINode* node = accessible->GetNode();
   if (node) {
     sEventTargetNode = node;
     sEventFromUserInput = aEvent->IsFromUserInput();
diff --git a/accessible/src/generic/DocAccessible-inl.h b/accessible/src/generic/DocAccessible-inl.h
index 5236f81fbcb5..6ae0a371ac03 100644
--- a/accessible/src/generic/DocAccessible-inl.h
+++ b/accessible/src/generic/DocAccessible-inl.h
@@ -12,9 +12,31 @@
 #include "NotificationController.h"
 #include "States.h"
 
+#ifdef A11Y_LOG
+#include "Logging.h"
+#endif
+
 namespace mozilla {
 namespace a11y {
 
+inline void
+DocAccessible::FireDelayedEvent(AccEvent* aEvent)
+{
+#ifdef A11Y_LOG
+  if (logging::IsEnabled(logging::eDocLoad))
+    logging::DocLoadEventFired(aEvent);
+#endif
+
+  mNotificationController->QueueEvent(aEvent);
+}
+
+inline void
+DocAccessible::FireDelayedEvent(uint32_t aEventType, Accessible* aTarget)
+{
+  nsRefPtr event = new AccEvent(aEventType, aTarget);
+  FireDelayedEvent(event);
+}
+
 inline void
 DocAccessible::BindChildDocument(DocAccessible* aDocument)
 {
@@ -54,20 +76,16 @@ DocAccessible::NotifyOfLoad(uint32_t aLoadEventType)
   if (HasLoadState(eCompletelyLoaded) && IsLoadEventTarget()) {
     nsRefPtr stateEvent =
       new AccStateChangeEvent(this, states::BUSY, false);
-    FireDelayedAccessibleEvent(stateEvent);
+    FireDelayedEvent(stateEvent);
   }
 }
 
 inline void
 DocAccessible::MaybeNotifyOfValueChange(Accessible* aAccessible)
 {
-  mozilla::a11y::role role = aAccessible->Role();
-  if (role == roles::ENTRY || role == roles::COMBOBOX) {
-    nsRefPtr valueChangeEvent =
-      new AccEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, aAccessible,
-                   eAutoDetect, AccEvent::eRemoveDupes);
-    FireDelayedAccessibleEvent(valueChangeEvent);
-  }
+  a11y::role role = aAccessible->Role();
+  if (role == roles::ENTRY || role == roles::COMBOBOX)
+    FireDelayedEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, aAccessible);
 }
 
 } // namespace a11y
diff --git a/accessible/src/generic/DocAccessible.cpp b/accessible/src/generic/DocAccessible.cpp
index d3d15bcd7b8a..4b4b4c1dc782 100644
--- a/accessible/src/generic/DocAccessible.cpp
+++ b/accessible/src/generic/DocAccessible.cpp
@@ -44,10 +44,6 @@
 #include "mozilla/Assertions.h"
 #include "mozilla/dom/Element.h"
 
-#ifdef A11Y_LOG
-#include "Logging.h"
-#endif
-
 #ifdef MOZ_XUL
 #include "nsIXULDocument.h"
 #endif
@@ -892,7 +888,7 @@ DocAccessible::Observe(nsISupports* aSubject, const char* aTopic,
     // about this exceptional case.
     nsRefPtr event =
       new AccStateChangeEvent(this, states::EDITABLE, true);
-    FireDelayedAccessibleEvent(event);
+    FireDelayedEvent(event);
   }
 
   return NS_OK;
@@ -987,7 +983,7 @@ DocAccessible::AttributeChanged(nsIDocument* aDocument,
 
   // Fire accessible events iff there's an accessible, otherwise we consider
   // the accessible state wasn't changed, i.e. its state is initial state.
-  AttributeChangedImpl(aElement, aNameSpaceID, aAttribute);
+  AttributeChangedImpl(accessible, aNameSpaceID, aAttribute);
 
   // Update dependent IDs cache. Take care of accessible elements because no
   // accessible element means either the element is not accessible at all or
@@ -1002,7 +998,8 @@ DocAccessible::AttributeChanged(nsIDocument* aDocument,
 
 // DocAccessible protected member
 void
-DocAccessible::AttributeChangedImpl(nsIContent* aContent, int32_t aNameSpaceID, nsIAtom* aAttribute)
+DocAccessible::AttributeChangedImpl(Accessible* aAccessible,
+                                    int32_t aNameSpaceID, nsIAtom* aAttribute)
 {
   // Fire accessible event after short timer, because we need to wait for
   // DOM attribute & resulting layout to actually change. Otherwise,
@@ -1033,14 +1030,12 @@ DocAccessible::AttributeChangedImpl(nsIContent* aContent, int32_t aNameSpaceID,
     // ARIA's aria-disabled does not affect the disabled state bit.
 
     nsRefPtr enabledChangeEvent =
-      new AccStateChangeEvent(aContent, states::ENABLED);
-
-    FireDelayedAccessibleEvent(enabledChangeEvent);
+      new AccStateChangeEvent(aAccessible, states::ENABLED);
+    FireDelayedEvent(enabledChangeEvent);
 
     nsRefPtr sensitiveChangeEvent =
-      new AccStateChangeEvent(aContent, states::SENSITIVE);
-
-    FireDelayedAccessibleEvent(sensitiveChangeEvent);
+      new AccStateChangeEvent(aAccessible, states::SENSITIVE);
+    FireDelayedEvent(sensitiveChangeEvent);
     return;
   }
 
@@ -1049,7 +1044,7 @@ DocAccessible::AttributeChangedImpl(nsIContent* aContent, int32_t aNameSpaceID,
     // Check for hyphenated aria-foo property?
     if (StringBeginsWith(nsDependentAtomString(aAttribute),
                          NS_LITERAL_STRING("aria-"))) {
-      ARIAAttributeChanged(aContent, aAttribute);
+      ARIAAttributeChanged(aAccessible, aAttribute);
     }
   }
 
@@ -1057,75 +1052,69 @@ DocAccessible::AttributeChangedImpl(nsIContent* aContent, int32_t aNameSpaceID,
       aAttribute == nsGkAtoms::title ||
       aAttribute == nsGkAtoms::aria_label ||
       aAttribute == nsGkAtoms::aria_labelledby) {
-    FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE,
-                               aContent);
+    FireDelayedEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE, aAccessible);
     return;
   }
 
   if (aAttribute == nsGkAtoms::aria_busy) {
-    bool isOn = aContent->AttrValueIs(aNameSpaceID, aAttribute,
-                                      nsGkAtoms::_true, eCaseMatters);
-    nsRefPtr event = new AccStateChangeEvent(aContent, states::BUSY, isOn);
-    FireDelayedAccessibleEvent(event);
+    bool isOn = aAccessible->GetContent()->
+      AttrValueIs(aNameSpaceID, aAttribute, nsGkAtoms::_true, eCaseMatters);
+    nsRefPtr event =
+      new AccStateChangeEvent(aAccessible, states::BUSY, isOn);
+    FireDelayedEvent(event);
     return;
   }
 
   // ARIA or XUL selection
-  if ((aContent->IsXUL() && aAttribute == nsGkAtoms::selected) ||
+  if ((aAccessible->GetContent()->IsXUL() && aAttribute == nsGkAtoms::selected) ||
       aAttribute == nsGkAtoms::aria_selected) {
-    Accessible* item = GetAccessible(aContent);
-    if (!item)
-      return;
-
     Accessible* widget =
-      nsAccUtils::GetSelectableContainer(item, item->State());
+      nsAccUtils::GetSelectableContainer(aAccessible, aAccessible->State());
     if (widget) {
+      nsIContent* elm = aAccessible->GetContent();
       AccSelChangeEvent::SelChangeType selChangeType =
-        aContent->AttrValueIs(aNameSpaceID, aAttribute,
-                              nsGkAtoms::_true, eCaseMatters) ?
+        elm->AttrValueIs(aNameSpaceID, aAttribute, nsGkAtoms::_true, eCaseMatters) ?
           AccSelChangeEvent::eSelectionAdd : AccSelChangeEvent::eSelectionRemove;
 
       nsRefPtr event =
-        new AccSelChangeEvent(widget, item, selChangeType);
-      FireDelayedAccessibleEvent(event);
+        new AccSelChangeEvent(widget, aAccessible, selChangeType);
+      FireDelayedEvent(event);
     }
+
     return;
   }
 
   if (aAttribute == nsGkAtoms::contenteditable) {
     nsRefPtr editableChangeEvent =
-      new AccStateChangeEvent(aContent, states::EDITABLE);
-    FireDelayedAccessibleEvent(editableChangeEvent);
+      new AccStateChangeEvent(aAccessible, states::EDITABLE);
+    FireDelayedEvent(editableChangeEvent);
     return;
   }
 
   if (aAttribute == nsGkAtoms::value) {
-    Accessible* accessible = GetAccessible(aContent);
-    if(accessible && accessible->IsProgress()) {
-      FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE,
-                                 aContent);
-    }
+    if (aAccessible->IsProgress())
+      FireDelayedEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, aAccessible);
   }
 }
 
 // DocAccessible protected member
 void
-DocAccessible::ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute)
+DocAccessible::ARIAAttributeChanged(Accessible* aAccessible, nsIAtom* aAttribute)
 {
   // Note: For universal/global ARIA states and properties we don't care if
   // there is an ARIA role present or not.
 
   if (aAttribute == nsGkAtoms::aria_required) {
     nsRefPtr event =
-      new AccStateChangeEvent(aContent, states::REQUIRED);
-    FireDelayedAccessibleEvent(event);
+      new AccStateChangeEvent(aAccessible, states::REQUIRED);
+    FireDelayedEvent(event);
     return;
   }
 
   if (aAttribute == nsGkAtoms::aria_invalid) {
     nsRefPtr event =
-      new AccStateChangeEvent(aContent, states::INVALID);
-    FireDelayedAccessibleEvent(event);
+      new AccStateChangeEvent(aAccessible, states::INVALID);
+    FireDelayedEvent(event);
     return;
   }
 
@@ -1133,8 +1122,8 @@ DocAccessible::ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute)
   // to the element with the id that activedescendant points to. Make sure
   // the tree up to date before processing.
   if (aAttribute == nsGkAtoms::aria_activedescendant) {
-    mNotificationController->HandleNotification
-      (this, &DocAccessible::ARIAActiveDescendantChanged, aContent);
+    mNotificationController->HandleNotification
+      (this, &DocAccessible::ARIAActiveDescendantChanged, aAccessible);
 
     return;
   }
@@ -1142,8 +1131,8 @@ DocAccessible::ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute)
   // We treat aria-expanded as a global ARIA state for historical reasons
   if (aAttribute == nsGkAtoms::aria_expanded) {
     nsRefPtr event =
-      new AccStateChangeEvent(aContent, states::EXPANDED);
-    FireDelayedAccessibleEvent(event);
+      new AccStateChangeEvent(aAccessible, states::EXPANDED);
+    FireDelayedEvent(event);
     return;
   }
 
@@ -1151,10 +1140,11 @@ DocAccessible::ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute)
   // change event; at least until native API comes up with a more meaningful event.
   uint8_t attrFlags = nsAccUtils::GetAttributeCharacteristics(aAttribute);
   if (!(attrFlags & ATTR_BYPASSOBJ))
-    FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_OBJECT_ATTRIBUTE_CHANGED,
-                               aContent);
+    FireDelayedEvent(nsIAccessibleEvent::EVENT_OBJECT_ATTRIBUTE_CHANGED,
+                     aAccessible);
 
-  if (!aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::role)) {
+  nsIContent* elm = aAccessible->GetContent();
+  if (!elm->HasAttr(kNameSpaceID_None, nsGkAtoms::role)) {
     // We don't care about these other ARIA attribute changes unless there is
     // an ARIA role set for the element
     // XXX: we should check the role map to see if the changed property is
@@ -1165,29 +1155,26 @@ DocAccessible::ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute)
   // The following ARIA attributes only take affect when dynamic content role is present
   if (aAttribute == nsGkAtoms::aria_checked ||
       aAttribute == nsGkAtoms::aria_pressed) {
-    const uint32_t kState = (aAttribute == nsGkAtoms::aria_checked) ?
+    const uint64_t kState = (aAttribute == nsGkAtoms::aria_checked) ?
                             states::CHECKED : states::PRESSED;
-    nsRefPtr event = new AccStateChangeEvent(aContent, kState);
-    FireDelayedAccessibleEvent(event);
+    nsRefPtr event = new AccStateChangeEvent(aAccessible, kState);
+    FireDelayedEvent(event);
 
-    Accessible* accessible = event->GetAccessible();
-    if (accessible) {
-      bool wasMixed = (mARIAAttrOldValue == nsGkAtoms::mixed);
-      bool isMixed = aContent->AttrValueIs(kNameSpaceID_None, aAttribute,
-                                           nsGkAtoms::mixed, eCaseMatters);
-      if (isMixed != wasMixed) {
-        nsRefPtr event =
-          new AccStateChangeEvent(aContent, states::MIXED, isMixed);
-        FireDelayedAccessibleEvent(event);
-      }
+    bool wasMixed = (mARIAAttrOldValue == nsGkAtoms::mixed);
+    bool isMixed = elm->AttrValueIs(kNameSpaceID_None, aAttribute,
+                                    nsGkAtoms::mixed, eCaseMatters);
+    if (isMixed != wasMixed) {
+      nsRefPtr event =
+        new AccStateChangeEvent(aAccessible, states::MIXED, isMixed);
+      FireDelayedEvent(event);
     }
     return;
   }
 
   if (aAttribute == nsGkAtoms::aria_readonly) {
     nsRefPtr event =
-      new AccStateChangeEvent(aContent, states::READONLY);
-    FireDelayedAccessibleEvent(event);
+      new AccStateChangeEvent(aAccessible, states::READONLY);
+    FireDelayedEvent(event);
     return;
   }
 
@@ -1195,23 +1182,22 @@ DocAccessible::ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute)
   // when aria-valuenow is changed and aria-valuetext is empty
   if (aAttribute == nsGkAtoms::aria_valuetext ||
       (aAttribute == nsGkAtoms::aria_valuenow &&
-       (!aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_valuetext) ||
-        aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::aria_valuetext,
-                              nsGkAtoms::_empty, eCaseMatters)))) {
-    FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE,
-                               aContent);
+       (!elm->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_valuetext) ||
+        elm->AttrValueIs(kNameSpaceID_None, nsGkAtoms::aria_valuetext,
+                         nsGkAtoms::_empty, eCaseMatters)))) {
+    FireDelayedEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, aAccessible);
     return;
   }
 }
 
 void
-DocAccessible::ARIAActiveDescendantChanged(nsIContent* aElm)
+DocAccessible::ARIAActiveDescendantChanged(Accessible* aAccessible)
 {
-  Accessible* widget = GetAccessible(aElm);
-  if (widget && widget->IsActiveWidget()) {
+  nsIContent* elm = aAccessible->GetContent();
+  if (elm && aAccessible->IsActiveWidget()) {
     nsAutoString id;
-    if (aElm->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_activedescendant, id)) {
-      dom::Element* activeDescendantElm = aElm->OwnerDoc()->GetElementById(id);
+    if (elm->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_activedescendant, id)) {
+      dom::Element* activeDescendantElm = elm->OwnerDoc()->GetElementById(id);
       if (activeDescendantElm) {
         Accessible* activeDescendant = GetAccessible(activeDescendantElm);
         if (activeDescendant) {
@@ -1240,31 +1226,32 @@ DocAccessible::ContentStateChanged(nsIDocument* aDocument,
                                    nsIContent* aContent,
                                    nsEventStates aStateMask)
 {
+  Accessible* accessible = GetAccessible(aContent);
+  if (!accessible)
+    return;
+
   if (aStateMask.HasState(NS_EVENT_STATE_CHECKED)) {
-    Accessible* item = GetAccessible(aContent);
-    if (item) {
-      Accessible* widget = item->ContainerWidget();
-      if (widget && widget->IsSelect()) {
-        AccSelChangeEvent::SelChangeType selChangeType =
-          aContent->AsElement()->State().HasState(NS_EVENT_STATE_CHECKED) ?
-            AccSelChangeEvent::eSelectionAdd : AccSelChangeEvent::eSelectionRemove;
-        nsRefPtr event = new AccSelChangeEvent(widget, item,
-                                                         selChangeType);
-        FireDelayedAccessibleEvent(event);
-      }
+    Accessible* widget = accessible->ContainerWidget();
+    if (widget && widget->IsSelect()) {
+      AccSelChangeEvent::SelChangeType selChangeType =
+        aContent->AsElement()->State().HasState(NS_EVENT_STATE_CHECKED) ?
+          AccSelChangeEvent::eSelectionAdd : AccSelChangeEvent::eSelectionRemove;
+      nsRefPtr event =
+        new AccSelChangeEvent(widget, accessible, selChangeType);
+      FireDelayedEvent(event);
     }
   }
 
   if (aStateMask.HasState(NS_EVENT_STATE_INVALID)) {
     nsRefPtr event =
-      new AccStateChangeEvent(aContent, states::INVALID, true);
-    FireDelayedAccessibleEvent(event);
+      new AccStateChangeEvent(accessible, states::INVALID, true);
+    FireDelayedEvent(event);
   }
 
   if (aStateMask.HasState(NS_EVENT_STATE_VISITED)) {
     nsRefPtr event =
-      new AccStateChangeEvent(aContent, states::TRAVERSED, true);
-    FireDelayedAccessibleEvent(event);
+      new AccStateChangeEvent(accessible, states::TRAVERSED, true);
+    FireDelayedEvent(event);
   }
 }
 
@@ -1542,8 +1529,8 @@ DocAccessible::NotifyOfLoading(bool aIsReloading)
   // Fire state busy change event. Use delayed event since we don't care
   // actually if event isn't delivered when the document goes away like a shot.
   nsRefPtr stateEvent =
-    new AccStateChangeEvent(mDocument, states::BUSY, true);
-  FireDelayedAccessibleEvent(stateEvent);
+    new AccStateChangeEvent(this, states::BUSY, true);
+  FireDelayedEvent(stateEvent);
 }
 
 void
@@ -1567,7 +1554,7 @@ DocAccessible::DoInitialUpdate()
   // a problem then consider to keep event processing per tab document.
   if (!IsRoot()) {
     nsRefPtr reorderEvent = new AccReorderEvent(Parent());
-    ParentDocument()->FireDelayedAccessibleEvent(reorderEvent);
+    ParentDocument()->FireDelayedEvent(reorderEvent);
   }
 }
 
@@ -1747,36 +1734,6 @@ DocAccessible::UpdateAccessibleOnAttrChange(dom::Element* aElement,
   return false;
 }
 
-// DocAccessible public member
-nsresult
-DocAccessible::FireDelayedAccessibleEvent(uint32_t aEventType, nsINode* aNode,
-                                          AccEvent::EEventRule aAllowDupes,
-                                          EIsFromUserInput aIsFromUserInput)
-{
-  nsRefPtr event =
-    new AccEvent(aEventType, aNode, aIsFromUserInput, aAllowDupes);
-  NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
-
-  return FireDelayedAccessibleEvent(event);
-}
-
-// DocAccessible public member
-nsresult
-DocAccessible::FireDelayedAccessibleEvent(AccEvent* aEvent)
-{
-  NS_ENSURE_ARG(aEvent);
-
-#ifdef A11Y_LOG
-  if (logging::IsEnabled(logging::eDocLoad))
-    logging::DocLoadEventFired(aEvent);
-#endif
-
-  if (mNotificationController)
-    mNotificationController->QueueEvent(aEvent);
-
-  return NS_OK;
-}
-
 void
 DocAccessible::ProcessContentInserted(Accessible* aContainer,
                                       const nsTArray >* aInsertedContent)
@@ -1874,9 +1831,7 @@ DocAccessible::UpdateTree(Accessible* aContainer, nsIContent* aChildNode,
     Accessible* ancestor = aContainer;
     while (ancestor) {
       if (ancestor->ARIARole() == roles::ALERT) {
-        nsRefPtr alertEvent =
-          new AccEvent(nsIAccessibleEvent::EVENT_ALERT, ancestor);
-        FireDelayedAccessibleEvent(alertEvent);
+        FireDelayedEvent(nsIAccessibleEvent::EVENT_ALERT, ancestor);
         break;
       }
 
@@ -1892,7 +1847,7 @@ DocAccessible::UpdateTree(Accessible* aContainer, nsIContent* aChildNode,
 
   // Fire reorder event so the MSAA clients know the children have changed. Also
   // the event is used internally by MSAA layer.
-  FireDelayedAccessibleEvent(reorderEvent);
+  FireDelayedEvent(reorderEvent);
 }
 
 uint32_t
@@ -1916,11 +1871,8 @@ DocAccessible::UpdateTreeInternal(Accessible* aChild, bool aIsInsert,
     // the changes before our processing and we may miss some menupopup
     // events. Now we just want to be consistent in content insertion/removal
     // handling.
-    if (aChild->ARIARole() == roles::MENUPOPUP) {
-      nsRefPtr event =
-        new AccEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_END, aChild);
-      FireDelayedAccessibleEvent(event);
-    }
+    if (aChild->ARIARole() == roles::MENUPOPUP)
+      FireDelayedEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_END, aChild);
   }
 
   // Fire show/hide event.
@@ -1930,23 +1882,19 @@ DocAccessible::UpdateTreeInternal(Accessible* aChild, bool aIsInsert,
   else
     event = new AccHideEvent(aChild, node);
 
-  FireDelayedAccessibleEvent(event);
+  FireDelayedEvent(event);
   aReorderEvent->AddSubMutationEvent(event);
 
   if (aIsInsert) {
     roles::Role ariaRole = aChild->ARIARole();
     if (ariaRole == roles::MENUPOPUP) {
       // Fire EVENT_MENUPOPUP_START if ARIA menu appears.
-      nsRefPtr event =
-        new AccEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_START, aChild);
-      FireDelayedAccessibleEvent(event);
+      FireDelayedEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_START, aChild);
 
     } else if (ariaRole == roles::ALERT) {
       // Fire EVENT_ALERT if ARIA alert appears.
       updateFlags = eAlertAccessible;
-      nsRefPtr event =
-        new AccEvent(nsIAccessibleEvent::EVENT_ALERT, aChild);
-      FireDelayedAccessibleEvent(event);
+      FireDelayedEvent(nsIAccessibleEvent::EVENT_ALERT, aChild);
     }
 
     // If focused node has been shown then it means its frame was recreated
@@ -1996,8 +1944,7 @@ DocAccessible::CacheChildrenInSubtree(Accessible* aRoot)
   if (aRoot->HasARIARole() && !aRoot->IsDoc()) {
     a11y::role role = aRoot->ARIARole();
     if (role == roles::DIALOG || role == roles::DOCUMENT)
-      FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE,
-                                 aRoot->GetContent());
+      FireDelayedEvent(nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE, aRoot);
   }
 }
 
diff --git a/accessible/src/generic/DocAccessible.h b/accessible/src/generic/DocAccessible.h
index ee222d03a433..8b8fbf9dd85f 100644
--- a/accessible/src/generic/DocAccessible.h
+++ b/accessible/src/generic/DocAccessible.h
@@ -173,22 +173,10 @@ public:
     { return mChildDocuments.SafeElementAt(aIndex, nullptr); }
 
   /**
-   * Non-virtual method to fire a delayed event after a 0 length timeout.
-   *
-   * @param aEventType   [in] the nsIAccessibleEvent event type
-   * @param aDOMNode     [in] DOM node the accesible event should be fired for
-   * @param aAllowDupes  [in] rule to process an event (see EEventRule constants)
+   * Fire accessible event asynchronously.
    */
-  nsresult FireDelayedAccessibleEvent(uint32_t aEventType, nsINode *aNode,
-                                      AccEvent::EEventRule aAllowDupes = AccEvent::eRemoveDupes,
-                                      EIsFromUserInput aIsFromUserInput = eAutoDetect);
-
-  /**
-   * Fire accessible event after timeout.
-   *
-   * @param aEvent  [in] the event to fire
-   */
-  nsresult FireDelayedAccessibleEvent(AccEvent* aEvent);
+  void FireDelayedEvent(AccEvent* aEvent);
+  void FireDelayedEvent(uint32_t aEventType, Accessible* aTarget);
 
   /**
    * Fire value change event on the given accessible if applicable.
@@ -398,27 +386,28 @@ protected:
   bool UpdateAccessibleOnAttrChange(mozilla::dom::Element* aElement,
                                     nsIAtom* aAttribute);
 
-    /**
-     * Fires accessible events when attribute is changed.
-     *
-     * @param aContent - node that attribute is changed for
-     * @param aNameSpaceID - namespace of changed attribute
-     * @param aAttribute - changed attribute
-     */
-    void AttributeChangedImpl(nsIContent* aContent, int32_t aNameSpaceID, nsIAtom* aAttribute);
+  /**
+   * Fire accessible events when attribute is changed.
+   *
+   * @param aAccessible   [in] accessible the DOM attribute is changed for
+   * @param aNameSpaceID  [in] namespace of changed attribute
+   * @param aAttribute    [in] changed attribute
+   */
+  void AttributeChangedImpl(Accessible* aAccessible,
+                            int32_t aNameSpaceID, nsIAtom* aAttribute);
 
-    /**
-     * Fires accessible events when ARIA attribute is changed.
-     *
-     * @param aContent - node that attribute is changed for
-     * @param aAttribute - changed attribute
-     */
-    void ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute);
+  /**
+   * Fire accessible events when ARIA attribute is changed.
+   *
+   * @param aAccessible  [in] accesislbe the DOM attribute is changed for
+   * @param aAttribute   [in] changed attribute
+   */
+  void ARIAAttributeChanged(Accessible* aAccessible, nsIAtom* aAttribute);
 
   /**
    * Process ARIA active-descendant attribute change.
    */
-  void ARIAActiveDescendantChanged(nsIContent* aElm);
+  void ARIAActiveDescendantChanged(Accessible* aAccessible);
 
   /**
    * Update the accessible tree for inserted content.
diff --git a/accessible/src/generic/RootAccessible.cpp b/accessible/src/generic/RootAccessible.cpp
index 6a69285d1cc8..af1c1aaa98b7 100644
--- a/accessible/src/generic/RootAccessible.cpp
+++ b/accessible/src/generic/RootAccessible.cpp
@@ -311,8 +311,6 @@ RootAccessible::ProcessDOMEvent(nsIDOMEvent* aDOMEvent)
   if (!accessible)
     return;
 
-  nsINode* targetNode = accessible->GetNode();
-
 #ifdef MOZ_XUL
   XULTreeAccessible* treeAcc = accessible->AsXULTree();
   if (treeAcc) {
@@ -383,6 +381,7 @@ RootAccessible::ProcessDOMEvent(nsIDOMEvent* aDOMEvent)
     return;
   }
 
+  nsINode* targetNode = accessible->GetNode();
   if (treeItemAcc && eventType.EqualsLiteral("select")) {
     // XXX: We shouldn't be based on DOM select event which doesn't provide us
     // any context info. We should integrate into nsTreeSelection instead.
@@ -478,10 +477,10 @@ RootAccessible::ProcessDOMEvent(nsIDOMEvent* aDOMEvent)
 
     //We don't process 'ValueChange' events for progress meters since we listen
     //@value attribute change for them.
-    if (!accessible->IsProgress())
-      targetDocument->
-        FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE,
-                                   targetNode);
+    if (!accessible->IsProgress()) {
+      targetDocument->FireDelayedEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE,
+                                       accessible);
+    }
   }
 #ifdef DEBUG_DRAGDROPSTART
   else if (eventType.EqualsLiteral("mouseover")) {
@@ -677,7 +676,7 @@ RootAccessible::HandlePopupHidingEvent(nsINode* aPopupNode)
   if (notifyOf & kNotifyOfState) {
     nsRefPtr event =
       new AccStateChangeEvent(widget, states::EXPANDED, false);
-    document->FireDelayedAccessibleEvent(event);
+    document->FireDelayedEvent(event);
   }
 }
 
diff --git a/accessible/src/html/HTMLImageMapAccessible.cpp b/accessible/src/html/HTMLImageMapAccessible.cpp
index 55789b1502e2..925bd2dd5eef 100644
--- a/accessible/src/html/HTMLImageMapAccessible.cpp
+++ b/accessible/src/html/HTMLImageMapAccessible.cpp
@@ -7,7 +7,7 @@
 
 #include "nsAccUtils.h"
 #include "nsARIAMap.h"
-#include "DocAccessible.h"
+#include "DocAccessible-inl.h"
 #include "Role.h"
 
 #include "nsIDOMHTMLCollection.h"
@@ -95,7 +95,7 @@ HTMLImageMapAccessible::UpdateChildAreas(bool aDoFireEvents)
 
     if (aDoFireEvents) {
       nsRefPtr event = new AccHideEvent(area, area->GetContent());
-      mDoc->FireDelayedAccessibleEvent(event);
+      mDoc->FireDelayedEvent(event);
       reorderEvent->AddSubMutationEvent(event);
       doReorderEvent = true;
     }
@@ -121,7 +121,7 @@ HTMLImageMapAccessible::UpdateChildAreas(bool aDoFireEvents)
 
       if (aDoFireEvents) {
         nsRefPtr event = new AccShowEvent(area, areaContent);
-        mDoc->FireDelayedAccessibleEvent(event);
+        mDoc->FireDelayedEvent(event);
         reorderEvent->AddSubMutationEvent(event);
         doReorderEvent = true;
       }
@@ -130,7 +130,7 @@ HTMLImageMapAccessible::UpdateChildAreas(bool aDoFireEvents)
 
   // Fire reorder event if needed.
   if (doReorderEvent)
-    mDoc->FireDelayedAccessibleEvent(reorderEvent);
+    mDoc->FireDelayedEvent(reorderEvent);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/accessible/src/xpcom/nsAccEvent.cpp b/accessible/src/xpcom/nsAccEvent.cpp
index a181b1342e8c..0cb5f4682fff 100644
--- a/accessible/src/xpcom/nsAccEvent.cpp
+++ b/accessible/src/xpcom/nsAccEvent.cpp
@@ -45,7 +45,7 @@ nsAccEvent::GetDOMNode(nsIDOMNode** aDOMNode)
   NS_ENSURE_ARG_POINTER(aDOMNode);
   *aDOMNode = nullptr;
 
-  nsINode* node = mEvent->GetNode();
+  nsINode* node = mEvent->GetAccessible()->GetNode();
   if (node)
     CallQueryInterface(node, aDOMNode);
 
diff --git a/accessible/src/xul/XULTreeAccessible.cpp b/accessible/src/xul/XULTreeAccessible.cpp
index c1a353d67a55..8e0f285118c5 100644
--- a/accessible/src/xul/XULTreeAccessible.cpp
+++ b/accessible/src/xul/XULTreeAccessible.cpp
@@ -6,6 +6,7 @@
 
 #include "XULTreeAccessible.h"
 
+#include "DocAccessible-inl.h"
 #include "nsAccCache.h"
 #include "nsAccUtils.h"
 #include "nsCoreUtils.h"
@@ -663,7 +664,7 @@ XULTreeAccessible::TreeViewChanged(nsITreeView* aView)
   // show/hide events on tree items because it can be expensive to fire them for
   // each tree item.
   nsRefPtr reorderEvent = new AccReorderEvent(this);
-  Document()->FireDelayedAccessibleEvent(reorderEvent);
+  Document()->FireDelayedEvent(reorderEvent);
 
   // Clear cache.
   ClearCache(mAccessibleCache);
diff --git a/accessible/tests/mochitest/events/test_attrs.html b/accessible/tests/mochitest/events/test_attrs.html
index 7a515ebd1771..1d5577572ee9 100644
--- a/accessible/tests/mochitest/events/test_attrs.html
+++ b/accessible/tests/mochitest/events/test_attrs.html
@@ -58,7 +58,7 @@
 
       if (!MAC) { // Mac failure is bug 541093
         var checker =
-          new eventFromInputChecker(EVENT_TEXT_CARET_MOVED, id, "false", noTargetId);
+          new eventFromInputChecker(EVENT_TEXT_CARET_MOVED, id, "true", noTargetId);
         gQueue.push(new synthHomeKey(id, checker));
       }
 

From e55fd9da0aee92ff7e8d9644e48b4b7e725752f8 Mon Sep 17 00:00:00 2001
From: Ehsan Akhgari 
Date: Tue, 20 Nov 2012 00:01:30 -0500
Subject: [PATCH 48/57] Bug 813433 - Make nsMediaSniffer accept null request
 arguments; r=bzbarsky

This patch will make the content sniffer useful to sniff the mimetype of
in-memory media buffers.
---
 .../mediasniffer/nsMediaSniffer.cpp           | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/toolkit/components/mediasniffer/nsMediaSniffer.cpp b/toolkit/components/mediasniffer/nsMediaSniffer.cpp
index 5e1e09a6cfaf..679b2287ffac 100644
--- a/toolkit/components/mediasniffer/nsMediaSniffer.cpp
+++ b/toolkit/components/mediasniffer/nsMediaSniffer.cpp
@@ -75,16 +75,15 @@ nsMediaSniffer::GetMIMETypeFromContent(nsIRequest* aRequest,
   // For media, we want to sniff only if the Content-Type is unknown, or if it
   // is application/octet-stream.
   nsCOMPtr channel = do_QueryInterface(aRequest);
-  if (!channel) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-  nsAutoCString contentType;
-  nsresult rv = channel->GetContentType(contentType);
-  NS_ENSURE_SUCCESS(rv, rv);
-  if (!contentType.IsEmpty() &&
-      !contentType.EqualsLiteral(APPLICATION_OCTET_STREAM) &&
-      !contentType.EqualsLiteral(UNKNOWN_CONTENT_TYPE)) {
-    return NS_ERROR_NOT_AVAILABLE;
+  if (channel) {
+    nsAutoCString contentType;
+    nsresult rv = channel->GetContentType(contentType);
+    NS_ENSURE_SUCCESS(rv, rv);
+    if (!contentType.IsEmpty() &&
+        !contentType.EqualsLiteral(APPLICATION_OCTET_STREAM) &&
+        !contentType.EqualsLiteral(UNKNOWN_CONTENT_TYPE)) {
+      return NS_ERROR_NOT_AVAILABLE;
+    }
   }
 
   const uint32_t clampedLength = NS_MIN(aLength, MAX_BYTES_SNIFFED);

From e5dfdef2b0d0929786f48141eb4a5e97a6c50208 Mon Sep 17 00:00:00 2001
From: Masayuki Nakano 
Date: Tue, 20 Nov 2012 15:05:56 +0900
Subject: [PATCH 49/57] Bug 812427 part.1 Remove unused event struct type r=roc

---
 widget/nsGUIEvent.h | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/widget/nsGUIEvent.h b/widget/nsGUIEvent.h
index 24d8b9c39b9a..878abcccbd98 100644
--- a/widget/nsGUIEvent.h
+++ b/widget/nsGUIEvent.h
@@ -50,10 +50,6 @@ class nsHashKey;
  */
 #define NS_EVENT                           1
 #define NS_GUI_EVENT                       2
-#define NS_SIZE_EVENT                      3
-#define NS_SIZEMODE_EVENT                  4
-#define NS_ZLEVEL_EVENT                    5
-#define NS_PAINT_EVENT                     6
 #define NS_SCROLLBAR_EVENT                 7
 #define NS_INPUT_EVENT                     8
 #define NS_KEY_EVENT                       9
@@ -80,7 +76,6 @@ class nsHashKey;
 #define NS_QUERY_CONTENT_EVENT            33
 
 #define NS_DRAG_EVENT                     35
-#define NS_NOTIFYPAINT_EVENT              36
 #define NS_SIMPLE_GESTURE_EVENT           37
 #define NS_SELECTION_EVENT                38
 #define NS_CONTENT_COMMAND_EVENT          39

From 8aa5135506027a12606b069405dfbccc5becd470 Mon Sep 17 00:00:00 2001
From: Masayuki Nakano 
Date: Tue, 20 Nov 2012 15:05:56 +0900
Subject: [PATCH 50/57] Bug 812427 part.2 Make event struct type named
 enumeration r=roc+smaug

---
 content/events/src/nsDOMEvent.cpp          |  2 +
 content/events/src/nsEventDispatcher.cpp   |  6 +-
 dom/plugins/base/nsPluginInstanceOwner.cpp |  4 +
 layout/base/PositionedEventTargeting.cpp   |  4 +-
 layout/base/PositionedEventTargeting.h     |  4 +-
 widget/nsGUIEvent.h                        | 98 +++++++++++++---------
 widget/nsGUIEventIPC.h                     | 15 ++--
 widget/windows/KeyboardLayout.cpp          |  2 +
 widget/xpwidgets/PuppetWidget.cpp          |  2 +
 9 files changed, 86 insertions(+), 51 deletions(-)

diff --git a/content/events/src/nsDOMEvent.cpp b/content/events/src/nsDOMEvent.cpp
index 457154dba832..1681c264da5d 100644
--- a/content/events/src/nsDOMEvent.cpp
+++ b/content/events/src/nsDOMEvent.cpp
@@ -1020,6 +1020,8 @@ nsDOMEvent::GetEventPopupControlState(nsEvent *aEvent)
       }
     }
     break;
+  default:
+    break;
   }
 
   return abuse;
diff --git a/content/events/src/nsEventDispatcher.cpp b/content/events/src/nsEventDispatcher.cpp
index 7ebaa8872cbe..b922d709395f 100644
--- a/content/events/src/nsEventDispatcher.cpp
+++ b/content/events/src/nsEventDispatcher.cpp
@@ -763,10 +763,10 @@ nsEventDispatcher::CreateEvent(nsPresContext* aPresContext,
     case NS_ANIMATION_EVENT:
       return NS_NewDOMAnimationEvent(aDOMEvent, aPresContext,
                                      static_cast(aEvent));
+    default:
+      // For all other types of events, create a vanilla event object.
+      return NS_NewDOMEvent(aDOMEvent, aPresContext, aEvent);
     }
-
-    // For all other types of events, create a vanilla event object.
-    return NS_NewDOMEvent(aDOMEvent, aPresContext, aEvent);
   }
 
   // And if we didn't get an event, check the type argument.
diff --git a/dom/plugins/base/nsPluginInstanceOwner.cpp b/dom/plugins/base/nsPluginInstanceOwner.cpp
index cfdfad627c01..bf2d859833ca 100644
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -2569,6 +2569,10 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const nsGUIEvent& anEvent)
          mInstance->HandleEvent(pluginEvent, nullptr);
        }
      }
+     break;
+
+    default:
+      break;
     }
     rv = nsEventStatus_eConsumeNoDefault;
 #endif
diff --git a/layout/base/PositionedEventTargeting.cpp b/layout/base/PositionedEventTargeting.cpp
index 1cf661e2a95f..5b7f05ae85f8 100644
--- a/layout/base/PositionedEventTargeting.cpp
+++ b/layout/base/PositionedEventTargeting.cpp
@@ -68,7 +68,7 @@ static EventRadiusPrefs sMouseEventRadiusPrefs;
 static EventRadiusPrefs sTouchEventRadiusPrefs;
 
 static const EventRadiusPrefs*
-GetPrefsFor(uint8_t aEventStructType)
+GetPrefsFor(nsEventStructType aEventStructType)
 {
   EventRadiusPrefs* prefs = nullptr;
   const char* prefBranch = nullptr;
@@ -235,7 +235,7 @@ GetClosest(nsIFrame* aRoot, const nsPoint& aPointRelativeToRootFrame,
 }
 
 nsIFrame*
-FindFrameTargetedByInputEvent(uint8_t aEventStructType,
+FindFrameTargetedByInputEvent(nsEventStructType aEventStructType,
                               nsIFrame* aRootFrame,
                               const nsPoint& aPointRelativeToRootFrame,
                               uint32_t aFlags)
diff --git a/layout/base/PositionedEventTargeting.h b/layout/base/PositionedEventTargeting.h
index 68acbdb92d33..3edefdeafdf0 100644
--- a/layout/base/PositionedEventTargeting.h
+++ b/layout/base/PositionedEventTargeting.h
@@ -6,8 +6,8 @@
 #define mozilla_PositionedEventTargeting_h
 
 #include "nsPoint.h"
+#include "nsGUIEvent.h"
 
-class nsGUIEvent;
 class nsIFrame;
 
 namespace mozilla {
@@ -21,7 +21,7 @@ enum {
  * that are suitable targets, to account for inaccurate pointing devices.
  */
 nsIFrame*
-FindFrameTargetedByInputEvent(uint8_t aEventStructType,
+FindFrameTargetedByInputEvent(nsEventStructType aEventStructType,
                               nsIFrame* aRootFrame,
                               const nsPoint& aPointRelativeToRootFrame,
                               uint32_t aFlags = 0);
diff --git a/widget/nsGUIEvent.h b/widget/nsGUIEvent.h
index 878abcccbd98..dfb3c869ddb0 100644
--- a/widget/nsGUIEvent.h
+++ b/widget/nsGUIEvent.h
@@ -48,41 +48,61 @@ class nsHashKey;
 /**
  * Event Struct Types
  */
-#define NS_EVENT                           1
-#define NS_GUI_EVENT                       2
-#define NS_SCROLLBAR_EVENT                 7
-#define NS_INPUT_EVENT                     8
-#define NS_KEY_EVENT                       9
-#define NS_MOUSE_EVENT                    10
-#define NS_SCRIPT_ERROR_EVENT             12
-#define NS_TEXT_EVENT                     13
-#define NS_COMPOSITION_EVENT              14
-#define NS_MOUSE_SCROLL_EVENT             16
-#define NS_SCROLLPORT_EVENT               18
-#define NS_MUTATION_EVENT                 19 // |nsMutationEvent| in content
-#define NS_FORM_EVENT                     21
-#define NS_FOCUS_EVENT                    22
-#define NS_POPUP_EVENT                    23
-#define NS_COMMAND_EVENT                  24
-#define NS_SCROLLAREA_EVENT               25
-#define NS_TRANSITION_EVENT               26
-#define NS_ANIMATION_EVENT                27
+enum nsEventStructType {
+  // Generic events
+  NS_EVENT,                          // nsEvent
+  NS_GUI_EVENT,                      // nsGUIEvent
+  NS_INPUT_EVENT,                    // nsInputEvent
 
-#define NS_UI_EVENT                       28
-#define NS_SVG_EVENT                      30
-#define NS_SVGZOOM_EVENT                  31
-#define NS_SMIL_TIME_EVENT                32
+  // Mouse related events
+  NS_MOUSE_EVENT,                    // nsMouseEvent
+  NS_POPUP_EVENT,                    // nsMouseEvent
+  NS_MOUSE_SCROLL_EVENT,             // nsMouseScrollEvent
+  NS_DRAG_EVENT,                     // nsDragEvent
+  NS_WHEEL_EVENT,                    // widget::WheelEvent
 
-#define NS_QUERY_CONTENT_EVENT            33
+  // Touchpad related events
+  NS_GESTURENOTIFY_EVENT,            // nsGestureNotifyEvent
+  NS_SIMPLE_GESTURE_EVENT,           // nsSimpleGestureEvent
+  NS_TOUCH_EVENT,                    // nsTouchEvent
 
-#define NS_DRAG_EVENT                     35
-#define NS_SIMPLE_GESTURE_EVENT           37
-#define NS_SELECTION_EVENT                38
-#define NS_CONTENT_COMMAND_EVENT          39
-#define NS_GESTURENOTIFY_EVENT            40
-#define NS_PLUGIN_EVENT                   43
-#define NS_TOUCH_EVENT                    44
-#define NS_WHEEL_EVENT                    45
+  // Key or IME events
+  NS_KEY_EVENT,                      // nsKeyEvent
+  NS_COMPOSITION_EVENT,              // nsCompositionEvent
+  NS_TEXT_EVENT,                     // nsTextEvent
+
+  // IME related events
+  NS_QUERY_CONTENT_EVENT,            // nsQueryContentEvent
+  NS_SELECTION_EVENT,                // nsSelectionEvent
+
+  // Scroll related events
+  NS_SCROLLBAR_EVENT,                // nsScrollbarEvent
+  NS_SCROLLPORT_EVENT,               // nsScrollPortEvent
+  NS_SCROLLAREA_EVENT,               // nsScrollAreaEvent
+
+  // DOM events
+  NS_UI_EVENT,                       // nsUIEvent
+  NS_SCRIPT_ERROR_EVENT,             // nsScriptErrorEvent
+  NS_MUTATION_EVENT,                 // nsMutationEvent
+  NS_FORM_EVENT,                     // nsFormEvent
+  NS_FOCUS_EVENT,                    // nsFocusEvent
+
+  // SVG events
+  NS_SVG_EVENT,                      // nsEvent or nsGUIEvent
+  NS_SVGZOOM_EVENT,                  // nsGUIEvent
+  NS_SMIL_TIME_EVENT,                // nsUIEvent
+
+  // CSS events
+  NS_TRANSITION_EVENT,               // nsTransitionEvent
+  NS_ANIMATION_EVENT,                // nsAnimationEvent
+
+  // Command events
+  NS_COMMAND_EVENT,                  // nsCommandEvent
+  NS_CONTENT_COMMAND_EVENT,          // nsContentCommandEvent
+
+  // Plugin event
+  NS_PLUGIN_EVENT                    // nsPluginEvent
+};
 
 // These flags are sort of a mess. They're sort of shared between event
 // listener flags and event flags, but only some of them. You've been
@@ -496,7 +516,7 @@ enum nsWindowZ {
 class nsEvent
 {
 protected:
-  nsEvent(bool isTrusted, uint32_t msg, uint8_t structType)
+  nsEvent(bool isTrusted, uint32_t msg, nsEventStructType structType)
     : eventStructType(structType),
       message(msg),
       refPoint(0, 0),
@@ -538,7 +558,7 @@ public:
   }
 
   // See event struct types
-  uint8_t     eventStructType;
+  nsEventStructType eventStructType;
   // See GUI MESSAGES,
   uint32_t    message;
   // Relative to the widget of the event, or if there is no widget then it is
@@ -567,7 +587,8 @@ public:
 class nsGUIEvent : public nsEvent
 {
 protected:
-  nsGUIEvent(bool isTrusted, uint32_t msg, nsIWidget *w, uint8_t structType)
+  nsGUIEvent(bool isTrusted, uint32_t msg, nsIWidget *w,
+             nsEventStructType structType)
     : nsEvent(isTrusted, msg, structType),
       widget(w), pluginEvent(nullptr)
   {
@@ -660,7 +681,7 @@ class nsInputEvent : public nsGUIEvent
 {
 protected:
   nsInputEvent(bool isTrusted, uint32_t msg, nsIWidget *w,
-               uint8_t structType)
+               nsEventStructType structType)
     : nsGUIEvent(isTrusted, msg, w, structType),
       modifiers(0)
   {
@@ -777,7 +798,8 @@ public:
   {
   }
 
-  nsMouseEvent_base(bool isTrusted, uint32_t msg, nsIWidget *w, uint8_t type)
+  nsMouseEvent_base(bool isTrusted, uint32_t msg, nsIWidget *w,
+                    nsEventStructType type)
     : nsInputEvent(isTrusted, msg, w, type), button(0), buttons(0),
       pressure(0), inputSource(nsIDOMMouseEvent::MOZ_SOURCE_MOUSE) {}
 
@@ -822,7 +844,7 @@ public:
 
 protected:
   nsMouseEvent(bool isTrusted, uint32_t msg, nsIWidget *w,
-               uint8_t structType, reasonType aReason)
+               nsEventStructType structType, reasonType aReason)
     : nsMouseEvent_base(isTrusted, msg, w, structType),
       acceptActivation(false), ignoreRootScrollFrame(false),
       reason(aReason), context(eNormal), exit(eChild), clickCount(0)
diff --git a/widget/nsGUIEventIPC.h b/widget/nsGUIEventIPC.h
index 3ed1125c412b..b0087bda6935 100644
--- a/widget/nsGUIEventIPC.h
+++ b/widget/nsGUIEventIPC.h
@@ -20,7 +20,7 @@ struct ParamTraits
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
-    WriteParam(aMsg, aParam.eventStructType);
+    WriteParam(aMsg, (uint8_t) aParam.eventStructType);
     WriteParam(aMsg, aParam.message);
     WriteParam(aMsg, aParam.refPoint);
     WriteParam(aMsg, aParam.time);
@@ -29,11 +29,14 @@ struct ParamTraits
 
   static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
   {
-    return ReadParam(aMsg, aIter, &aResult->eventStructType) &&
-           ReadParam(aMsg, aIter, &aResult->message) &&
-           ReadParam(aMsg, aIter, &aResult->refPoint) &&
-           ReadParam(aMsg, aIter, &aResult->time) &&
-           ReadParam(aMsg, aIter, &aResult->flags);
+    uint8_t eventStructType = 0;
+    bool ret = ReadParam(aMsg, aIter, &eventStructType) &&
+               ReadParam(aMsg, aIter, &aResult->message) &&
+               ReadParam(aMsg, aIter, &aResult->refPoint) &&
+               ReadParam(aMsg, aIter, &aResult->time) &&
+               ReadParam(aMsg, aIter, &aResult->flags);
+    aResult->eventStructType = static_cast(eventStructType);
+    return ret;
   }
 };
 
diff --git a/widget/windows/KeyboardLayout.cpp b/widget/windows/KeyboardLayout.cpp
index d98b73106290..53c13e39583d 100644
--- a/widget/windows/KeyboardLayout.cpp
+++ b/widget/windows/KeyboardLayout.cpp
@@ -120,6 +120,8 @@ ModifierKeyState::InitInputEvent(nsInputEvent& aInputEvent) const
     case NS_SIMPLE_GESTURE_EVENT:
       InitMouseEvent(aInputEvent);
       break;
+    default:
+      break;
   }
 }
 
diff --git a/widget/xpwidgets/PuppetWidget.cpp b/widget/xpwidgets/PuppetWidget.cpp
index 8eed5a45698c..6713d5cfcccd 100644
--- a/widget/xpwidgets/PuppetWidget.cpp
+++ b/widget/xpwidgets/PuppetWidget.cpp
@@ -284,6 +284,8 @@ PuppetWidget::DispatchEvent(nsGUIEvent* event, nsEventStatus& aStatus)
     if (mIMELastReceivedSeqno < mIMELastBlurSeqno)
       return NS_OK;
     break;
+  default:
+    break;
   }
 
   aStatus = mAttachedWidgetListener->HandleEvent(event, mUseAttachedEvents);

From 4144d695aea6165f8c42bcac78e3bfe851f107f8 Mon Sep 17 00:00:00 2001
From: Masayuki Nakano 
Date: Tue, 20 Nov 2012 15:05:56 +0900
Subject: [PATCH 51/57] Bug 812427 part.3 Remove NS_POPUP_EVENT r=roc+smaug

---
 content/events/src/nsDOMEvent.cpp        | 11 -----------
 content/events/src/nsDOMUIEvent.cpp      |  2 --
 content/events/src/nsDOMUIEvent.h        |  2 --
 content/events/src/nsEventDispatcher.cpp |  1 -
 widget/nsGUIEvent.h                      |  1 -
 5 files changed, 17 deletions(-)

diff --git a/content/events/src/nsDOMEvent.cpp b/content/events/src/nsDOMEvent.cpp
index 1681c264da5d..4652bd3aee65 100644
--- a/content/events/src/nsDOMEvent.cpp
+++ b/content/events/src/nsDOMEvent.cpp
@@ -704,15 +704,6 @@ nsDOMEvent::DuplicatePrivateData()
       newEvent = newFocusEvent;
       break;
     }
-
-    case NS_POPUP_EVENT:
-    {
-      newEvent = new nsInputEvent(false, msg, nullptr);
-      NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
-      isInputEvent = true;
-      newEvent->eventStructType = NS_POPUP_EVENT;
-      break;
-    }
     case NS_COMMAND_EVENT:
     {
       newEvent = new nsCommandEvent(false, mEvent->userType,
@@ -1062,7 +1053,6 @@ nsDOMEvent::GetScreenCoords(nsPresContext* aPresContext,
 
   if (!aEvent || 
        (aEvent->eventStructType != NS_MOUSE_EVENT &&
-        aEvent->eventStructType != NS_POPUP_EVENT &&
         aEvent->eventStructType != NS_MOUSE_SCROLL_EVENT &&
         aEvent->eventStructType != NS_WHEEL_EVENT &&
         aEvent->eventStructType != NS_TOUCH_EVENT &&
@@ -1121,7 +1111,6 @@ nsDOMEvent::GetClientCoords(nsPresContext* aPresContext,
 
   if (!aEvent ||
       (aEvent->eventStructType != NS_MOUSE_EVENT &&
-       aEvent->eventStructType != NS_POPUP_EVENT &&
        aEvent->eventStructType != NS_MOUSE_SCROLL_EVENT &&
        aEvent->eventStructType != NS_WHEEL_EVENT &&
        aEvent->eventStructType != NS_TOUCH_EVENT &&
diff --git a/content/events/src/nsDOMUIEvent.cpp b/content/events/src/nsDOMUIEvent.cpp
index a94851023b1b..02189970c43a 100644
--- a/content/events/src/nsDOMUIEvent.cpp
+++ b/content/events/src/nsDOMUIEvent.cpp
@@ -111,7 +111,6 @@ nsDOMUIEvent::GetMovementPoint()
 
   if (!mEvent ||
       (mEvent->eventStructType != NS_MOUSE_EVENT &&
-       mEvent->eventStructType != NS_POPUP_EVENT &&
        mEvent->eventStructType != NS_MOUSE_SCROLL_EVENT &&
        mEvent->eventStructType != NS_WHEEL_EVENT &&
        mEvent->eventStructType != NS_DRAG_EVENT &&
@@ -314,7 +313,6 @@ nsDOMUIEvent::GetLayerPoint()
 {
   if (!mEvent ||
       (mEvent->eventStructType != NS_MOUSE_EVENT &&
-       mEvent->eventStructType != NS_POPUP_EVENT &&
        mEvent->eventStructType != NS_MOUSE_SCROLL_EVENT &&
        mEvent->eventStructType != NS_WHEEL_EVENT &&
        mEvent->eventStructType != NS_TOUCH_EVENT &&
diff --git a/content/events/src/nsDOMUIEvent.h b/content/events/src/nsDOMUIEvent.h
index a7360fabd092..ef807fce8d04 100644
--- a/content/events/src/nsDOMUIEvent.h
+++ b/content/events/src/nsDOMUIEvent.h
@@ -37,7 +37,6 @@ public:
   {
     if (!aEvent ||
         (aEvent->eventStructType != NS_MOUSE_EVENT &&
-         aEvent->eventStructType != NS_POPUP_EVENT &&
          aEvent->eventStructType != NS_MOUSE_SCROLL_EVENT &&
          aEvent->eventStructType != NS_WHEEL_EVENT &&
          aEvent->eventStructType != NS_DRAG_EVENT &&
@@ -62,7 +61,6 @@ public:
   {
     if (!aEvent ||
         (aEvent->eventStructType != NS_MOUSE_EVENT &&
-         aEvent->eventStructType != NS_POPUP_EVENT &&
          aEvent->eventStructType != NS_MOUSE_SCROLL_EVENT &&
          aEvent->eventStructType != NS_WHEEL_EVENT &&
          aEvent->eventStructType != NS_DRAG_EVENT &&
diff --git a/content/events/src/nsEventDispatcher.cpp b/content/events/src/nsEventDispatcher.cpp
index b922d709395f..a8f00a3f2c06 100644
--- a/content/events/src/nsEventDispatcher.cpp
+++ b/content/events/src/nsEventDispatcher.cpp
@@ -724,7 +724,6 @@ nsEventDispatcher::CreateEvent(nsPresContext* aPresContext,
       return NS_NewDOMCompositionEvent(
         aDOMEvent, aPresContext, static_cast(aEvent));
     case NS_MOUSE_EVENT:
-    case NS_POPUP_EVENT:
       return NS_NewDOMMouseEvent(aDOMEvent, aPresContext,
                                  static_cast(aEvent));
     case NS_MOUSE_SCROLL_EVENT:
diff --git a/widget/nsGUIEvent.h b/widget/nsGUIEvent.h
index dfb3c869ddb0..4254d2ec1e65 100644
--- a/widget/nsGUIEvent.h
+++ b/widget/nsGUIEvent.h
@@ -56,7 +56,6 @@ enum nsEventStructType {
 
   // Mouse related events
   NS_MOUSE_EVENT,                    // nsMouseEvent
-  NS_POPUP_EVENT,                    // nsMouseEvent
   NS_MOUSE_SCROLL_EVENT,             // nsMouseScrollEvent
   NS_DRAG_EVENT,                     // nsDragEvent
   NS_WHEEL_EVENT,                    // widget::WheelEvent

From 7ff5ce90654dfb361af3c5f890a4f98a6903f146 Mon Sep 17 00:00:00 2001
From: Chris Jones 
Date: Thu, 11 Oct 2012 16:55:42 -0700
Subject: [PATCH 52/57] Bug 799768: Only bother computing an invalid rect if it
 affects composition and enable omtc for X11 b2g builds. r=mattwoodrow

---
 b2g/app/nsBrowserApp.cpp      | 4 ++++
 layout/base/nsDisplayList.cpp | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/b2g/app/nsBrowserApp.cpp b/b2g/app/nsBrowserApp.cpp
index d7f9d6910621..38a604aec947 100644
--- a/b2g/app/nsBrowserApp.cpp
+++ b/b2g/app/nsBrowserApp.cpp
@@ -158,6 +158,10 @@ int main(int argc, char* argv[])
 {
   char exePath[MAXPATHLEN];
 
+#if defined(MOZ_X11)
+  putenv("MOZ_USE_OMTC=1");
+#endif
+
   nsresult rv = mozilla::BinaryPath::Get(argv[0], exePath);
   if (NS_FAILED(rv)) {
     Output("Couldn't calculate the application directory.\n");
diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp
index b2200dde8eee..10f4019e5a44 100644
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -1061,7 +1061,7 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
   NotifySubDocInvalidationFunc computeInvalidFunc =
     presContext->MayHavePaintEventListenerInSubDocument() ? nsPresContext::NotifySubDocInvalidation : 0;
   bool computeInvalidRect = (computeInvalidFunc ||
-                             (layerManager->GetBackendType() == LAYERS_BASIC)) &&
+                             !layerManager->IsCompositingCheap()) &&
                             widgetTransaction;
 
   nsAutoPtr props(computeInvalidRect ? 

From 93ac2a58903ce27b76d18d1be44566da75333ff7 Mon Sep 17 00:00:00 2001
From: Paul Adenot 
Date: Fri, 16 Nov 2012 16:47:01 -0800
Subject: [PATCH 53/57] Bug 812667 - Make soundtouch compile properly if
 cpuid.h is not present. r=khuey

---
 media/libsoundtouch/moz-libsoundtouch.patch | 2 +-
 media/libsoundtouch/src/cpu_detect_x86.cpp  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/media/libsoundtouch/moz-libsoundtouch.patch b/media/libsoundtouch/moz-libsoundtouch.patch
index 8eb21f016fd8..6523f7c66d80 100644
--- a/media/libsoundtouch/moz-libsoundtouch.patch
+++ b/media/libsoundtouch/moz-libsoundtouch.patch
@@ -475,7 +475,7 @@ unchanged:
 -
 -    #if defined(__GNUC__) && defined(__i386__)
 -        // gcc
-+    #if defined(__GNUC__)
++    #if defined(__GNUC__) && defined (HAVE_CPUID_H)
 +        // gcc and clang
          #include "cpuid.h"
      #elif defined(_M_IX86)
diff --git a/media/libsoundtouch/src/cpu_detect_x86.cpp b/media/libsoundtouch/src/cpu_detect_x86.cpp
index b3af0e9786e0..a42008e096b8 100644
--- a/media/libsoundtouch/src/cpu_detect_x86.cpp
+++ b/media/libsoundtouch/src/cpu_detect_x86.cpp
@@ -43,7 +43,7 @@
 #include "STTypes.h"
 
 #if defined(SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS)
-    #if defined(__GNUC__)
+    #if defined(__GNUC__) && defined (HAVE_CPUID_H)
         // gcc and clang
         #include "cpuid.h"
     #elif defined(_M_IX86)

From 1cfc9de8d01d33eeae5b06272b3f27e830a35acd Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote 
Date: Mon, 19 Nov 2012 20:52:44 -0800
Subject: [PATCH 54/57] Bug 811596 - Shrink the IPC message buffer after each
 message is processed.  r=cjones.

---
 .../src/chrome/common/ipc_channel_posix.cc         | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/ipc/chromium/src/chrome/common/ipc_channel_posix.cc b/ipc/chromium/src/chrome/common/ipc_channel_posix.cc
index 7edbb5413eba..a00212ad68e8 100644
--- a/ipc/chromium/src/chrome/common/ipc_channel_posix.cc
+++ b/ipc/chromium/src/chrome/common/ipc_channel_posix.cc
@@ -363,6 +363,16 @@ bool Channel::ChannelImpl::EnqueueHelloMessage() {
   return true;
 }
 
+static void
+ClearAndShrink(std::string& s, size_t capacity)
+{
+  // This swap trick is the closest thing C++ has to a guaranteed way to
+  // shrink the capacity of a string.
+  std::string tmp;
+  tmp.reserve(capacity);
+  s.swap(tmp);
+}
+
 bool Channel::ChannelImpl::Connect() {
   if (mode_ == MODE_SERVER && uses_fifo_) {
     if (server_listen_pipe_ == -1) {
@@ -489,7 +499,7 @@ bool Channel::ChannelImpl::ProcessIncomingMessages() {
     } else {
       if (input_overflow_buf_.size() >
          static_cast(kMaximumMessageSize - bytes_read)) {
-        input_overflow_buf_.clear();
+        ClearAndShrink(input_overflow_buf_, Channel::kReadBufferSize);
         LOG(ERROR) << "IPC message is too big";
         return false;
       }
@@ -573,7 +583,7 @@ bool Channel::ChannelImpl::ProcessIncomingMessages() {
       }
     }
     if (end == p) {
-      input_overflow_buf_.clear();
+      ClearAndShrink(input_overflow_buf_, Channel::kReadBufferSize);
     } else if (!overflowp) {
       // p is from input_buf_
       input_overflow_buf_.assign(p, end - p);

From f8c8439640e2357f54b6c715d1d51f784a450ba3 Mon Sep 17 00:00:00 2001
From: Jeff Gilbert 
Date: Tue, 20 Nov 2012 01:39:26 -0800
Subject: [PATCH 55/57] Bug 813278 - Overload JSAutoCompartment for
 TimeZoneSettingObserver - r=luke

---
 dom/system/gonk/TimeZoneSettingObserver.cpp | 2 +-
 js/src/jsapi.cpp                            | 8 ++++++++
 js/src/jsapi.h                              | 1 +
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/dom/system/gonk/TimeZoneSettingObserver.cpp b/dom/system/gonk/TimeZoneSettingObserver.cpp
index 79158383816a..c742f844b43d 100644
--- a/dom/system/gonk/TimeZoneSettingObserver.cpp
+++ b/dom/system/gonk/TimeZoneSettingObserver.cpp
@@ -82,7 +82,7 @@ public:
     // Set the system timezone based on the current settings.
     if (aResult.isString()) {
       JSAutoRequest ar(cx);
-      JSAutoCompartment ac(cx, JSVAL_TO_OBJECT(aResult));
+      JSAutoCompartment ac(cx, aResult.toString());
       return TimeZoneSettingObserver::SetTimeZone(aResult, cx);
     }
 
diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp
index 6eb395e63c0b..6c77b904fdde 100644
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -1488,6 +1488,14 @@ JSAutoCompartment::JSAutoCompartment(JSContext *cx, JSStackFrame *target)
     cx_->enterCompartment(Valueify(target)->global().compartment());
 }
 
+JSAutoCompartment::JSAutoCompartment(JSContext *cx, JSString *target)
+  : cx_(cx),
+    oldCompartment_(cx->compartment)
+{
+    AssertHeapIsIdleOrIterating(cx_);
+    cx_->enterCompartment(target->compartment());
+}
+
 JSAutoCompartment::~JSAutoCompartment()
 {
     cx_->leaveCompartment(oldCompartment_);
diff --git a/js/src/jsapi.h b/js/src/jsapi.h
index 0635f2ff49ca..ba4ed5550f40 100644
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -3156,6 +3156,7 @@ class JS_PUBLIC_API(JSAutoCompartment)
     JSAutoCompartment(JSContext *cx, JSRawObject target);
     JSAutoCompartment(JSContext *cx, JSScript *target);
     JSAutoCompartment(JSContext *cx, JSStackFrame *target);
+    JSAutoCompartment(JSContext *cx, JSString *target);
     ~JSAutoCompartment();
 };
 

From 71692e401b5baba603689addd6bbd3011e3808bc Mon Sep 17 00:00:00 2001
From: Jon Coppeard 
Date: Tue, 20 Nov 2012 10:03:09 +0000
Subject: [PATCH 56/57] Bug 813007 - Remove ExecutableAllocatorSymbian.cpp
 r=billm

---
 .../jit/ExecutableAllocatorSymbian.cpp        | 73 -------------------
 1 file changed, 73 deletions(-)
 delete mode 100644 js/src/assembler/jit/ExecutableAllocatorSymbian.cpp

diff --git a/js/src/assembler/jit/ExecutableAllocatorSymbian.cpp b/js/src/assembler/jit/ExecutableAllocatorSymbian.cpp
deleted file mode 100644
index f51c0d507877..000000000000
--- a/js/src/assembler/jit/ExecutableAllocatorSymbian.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, 
- *  Boston, MA  02110-1301  USA
- *
- */
-
-#include "config.h"
-
-#include "ExecutableAllocator.h"
-
-#if ENABLE_ASSEMBLER && WTF_OS_SYMBIAN
-
-#include 
-#include 
-
-// Set the page size to 256 Kb to compensate for moving memory model limitation
-const size_t MOVING_MEM_PAGE_SIZE = 256 * 1024; 
-
-namespace JSC {
-
-size_t ExecutableAllocator::determinePageSize()
-{
-#if WTF_CPU_ARMV5_OR_LOWER
-    // The moving memory model (as used in ARMv5 and earlier platforms)
-    // on Symbian OS limits the number of chunks for each process to 16. 
-    // To mitigate this limitation increase the pagesize to 
-    // allocate less of larger chunks.
-    return MOVING_MEM_PAGE_SIZE;
-#else
-    TInt page_size;
-    UserHal::PageSizeInBytes(page_size);
-    return page_size;
-#endif
-}
-
-ExecutablePool::Allocation ExecutableAllocator::systemAlloc(size_t n)
-{
-    RChunk* codeChunk = new RChunk();
-
-    TInt errorCode = codeChunk->CreateLocalCode(n, n);
-
-    char* allocation = reinterpret_cast(codeChunk->Base());
-    ExecutablePool::Allocation alloc = { allocation, n, codeChunk };
-    return alloc;
-}
-
-void ExecutableAllocator::systemRelease(const ExecutablePool::Allocation& alloc)
-{ 
-    alloc.chunk->Close();
-    delete alloc.chunk;
-}
-
-#if ENABLE_ASSEMBLER_WX_EXCLUSIVE
-#error "ASSEMBLER_WX_EXCLUSIVE not yet suported on this platform."
-#endif
-
-}
-
-#endif // HAVE(ASSEMBLER)

From 3c41cdb199b167855a8b9d4e84172e07486714b2 Mon Sep 17 00:00:00 2001
From: Ed Morley 
Date: Tue, 20 Nov 2012 10:57:43 +0000
Subject: [PATCH 57/57] Backout 9f8721399b14 (bug 812218) for Win PGO bustage

---
 config/config.mk        | 4 ++--
 js/src/config/config.mk | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/config/config.mk b/config/config.mk
index e3beadd0b60b..9b897d5087ce 100644
--- a/config/config.mk
+++ b/config/config.mk
@@ -498,8 +498,8 @@ OS_COMPILE_CMMFLAGS += -fobjc-abi-version=2 -fobjc-legacy-dispatch
 endif
 endif
 
-COMPILE_CFLAGS	= $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_CPPFLAGS) $(OS_COMPILE_CFLAGS) $(CFLAGS)
-COMPILE_CXXFLAGS = $(STL_FLAGS) $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_CPPFLAGS) $(OS_COMPILE_CXXFLAGS) $(CXXFLAGS)
+COMPILE_CFLAGS	= $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(CFLAGS) $(RTL_FLAGS) $(OS_CPPFLAGS) $(OS_COMPILE_CFLAGS)
+COMPILE_CXXFLAGS = $(STL_FLAGS) $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(CXXFLAGS) $(RTL_FLAGS) $(OS_CPPFLAGS) $(OS_COMPILE_CXXFLAGS)
 COMPILE_CMFLAGS = $(OS_COMPILE_CMFLAGS)
 COMPILE_CMMFLAGS = $(OS_COMPILE_CMMFLAGS)
 
diff --git a/js/src/config/config.mk b/js/src/config/config.mk
index e3beadd0b60b..9b897d5087ce 100644
--- a/js/src/config/config.mk
+++ b/js/src/config/config.mk
@@ -498,8 +498,8 @@ OS_COMPILE_CMMFLAGS += -fobjc-abi-version=2 -fobjc-legacy-dispatch
 endif
 endif
 
-COMPILE_CFLAGS	= $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_CPPFLAGS) $(OS_COMPILE_CFLAGS) $(CFLAGS)
-COMPILE_CXXFLAGS = $(STL_FLAGS) $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_CPPFLAGS) $(OS_COMPILE_CXXFLAGS) $(CXXFLAGS)
+COMPILE_CFLAGS	= $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(CFLAGS) $(RTL_FLAGS) $(OS_CPPFLAGS) $(OS_COMPILE_CFLAGS)
+COMPILE_CXXFLAGS = $(STL_FLAGS) $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(CXXFLAGS) $(RTL_FLAGS) $(OS_CPPFLAGS) $(OS_COMPILE_CXXFLAGS)
 COMPILE_CMFLAGS = $(OS_COMPILE_CMFLAGS)
 COMPILE_CMMFLAGS = $(OS_COMPILE_CMMFLAGS)