Merge the last PGO-green inbound changeset to m-c.
authorRyan VanderMeulen <ryanvm@gmail.com>
Thu, 05 Jul 2012 20:26:55 -0400
changeset 98471 4b1249ae1906544429f9cf7ba4b77da31f78a89b
parent 98470 41cbcc06d6b3ea5a79cc9872823cdfae1f6515da (current diff)
parent 98449 654181827f06cb9f4c5090d44b3ca10499377cfb (diff)
child 98472 421a53b025972781f2780f58d7585b392795063d
child 98529 874900dd7b775c666b4d333b1e544f262d92da6d
push id11498
push userryanvm@gmail.com
push dateFri, 06 Jul 2012 01:07:53 +0000
treeherdermozilla-inbound@d64dfd57d873 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone16.0a1
first release with
nightly linux32
4b1249ae1906 / 16.0a1 / 20120706030535 / files
nightly linux64
4b1249ae1906 / 16.0a1 / 20120706030535 / files
nightly mac
4b1249ae1906 / 16.0a1 / 20120706030535 / files
nightly win32
4b1249ae1906 / 16.0a1 / 20120706030535 / files
nightly win64
4b1249ae1906 / 16.0a1 / 20120706030535 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge the last PGO-green inbound changeset to m-c.
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -43,17 +43,17 @@ XPCOMUtils.defineLazyGetter(this, 'Debug
 });
 
 // FIXME Bug 707625
 // until we have a proper security model, add some rights to
 // the pre-installed web applications
 // XXX never grant 'content-camera' to non-gaia apps
 function addPermissions(urls) {
   let permissions = [
-    'indexedDB', 'indexedDB-unlimited', 'webapps-manage', 'offline-app', 'pin-app',
+    'indexedDB-unlimited', 'webapps-manage', 'offline-app', 'pin-app',
     'websettings-read', 'websettings-readwrite',
     'content-camera', 'webcontacts-manage', 'wifi-manage', 'desktop-notification',
     'geolocation', 'device-storage'
   ];
   urls.forEach(function(url) {
     url = url.trim();
     let uri = Services.io.newURI(url, null, null);
     let allow = Ci.nsIPermissionManager.ALLOW_ACTION;
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1177,8 +1177,11 @@ pref("pdfjs.firstRun", true);
 // became the default.
 pref("pdfjs.previousHandler.preferredAction", 0);
 pref("pdfjs.previousHandler.alwaysAskBeforeHandling", false);
 
 // The maximum amount of decoded image data we'll willingly keep around (we
 // might keep around more than this, but we'll try to get down to this value).
 // (This is intentionally on the high side; see bug 746055.)
 pref("image.mem.max_decoded_image_kb", 256000);
+
+// Example social provider
+pref("social.manifest.motown", "{\"origin\":\"https://motown-dev.mozillalabs.com\",\"name\":\"MoTown\",\"workerURL\":\"https://motown-dev.mozillalabs.com/social/worker.js\"}");
--- a/browser/base/content/abouthome/aboutHome.css
+++ b/browser/base/content/abouthome/aboutHome.css
@@ -38,16 +38,17 @@ a {
 }
 
 #topSection {
   text-align: center;
 }
 
 #brandLogo {
   height: 154px;
+  width: 154px;
   margin: 22px 0 31px;
 }
 
 #searchForm,
 #snippets {
   width: 470px;
 }
 
@@ -59,16 +60,18 @@ a {
   display: -moz-box;
   -moz-box-align: center;
   padding-top: 2px;
   -moz-padding-end: 8px;
 }
 
 #searchEngineLogo {
   display: inline-block;
+  height: 28px;
+  width: 70px;
 }
 
 #searchText {
   -moz-box-flex: 1;
   padding: 6px 8px;
   background: hsla(0,0%,100%,.9) padding-box;
   border: 1px solid;
   border-color: hsla(210,54%,20%,.15) hsla(210,54%,20%,.17) hsla(210,54%,20%,.2);
@@ -77,17 +80,18 @@ a {
               0 1px 0 hsla(0,0%,100%,.2);
   border-radius: 2.5px 0 0 2.5px;
 }
 
 body[dir=rtl] #searchText {
   border-radius: 0 2.5px 2.5px 0;
 }
 
-#searchText:focus {
+#searchText:focus,
+#searchText[autofocus] {
   border-color: hsla(206,100%,60%,.6) hsla(206,76%,52%,.6) hsla(204,100%,40%,.6);
 }
 
 #searchSubmit {
   -moz-margin-start: -1px;
   background: -moz-linear-gradient(hsla(0,0%,100%,.8), hsla(0,0%,100%,.1)) padding-box;
   padding: 0 9px;
   border: 1px solid;
@@ -101,22 +105,24 @@ body[dir=rtl] #searchText {
   -moz-transition-duration: 150ms;
 }
 
 body[dir=rtl] #searchSubmit {
   border-radius: 2.5px 0 0 2.5px;
 }
 
 #searchText:focus + #searchSubmit,
-#searchText + #searchSubmit:hover {
+#searchText + #searchSubmit:hover,
+#searchText[autofocus] + #searchSubmit {
   border-color: #59b5fc #45a3e7 #3294d5;
   color: white;
 }
 
-#searchText:focus + #searchSubmit {
+#searchText:focus + #searchSubmit,
+#searchText[autofocus] + #searchSubmit {
   background-image: -moz-linear-gradient(#4cb1ff, #1793e5);
   box-shadow: 0 1px 0 hsla(0,0%,100%,.2) inset,
               0 0 0 1px hsla(0,0%,100%,.1) inset,
               0 1px 0 hsla(210,54%,20%,.03);
 }
 
 #searchText + #searchSubmit:hover {
   background-image: -moz-linear-gradient(#66bdff, #0d9eff);
@@ -155,16 +161,22 @@ body[dir=rtl] #defaultSnippet2 {
 }
 
 #snippets {
   display: inline-block;
   text-align: start;
   margin: 12px 0;
   color: #3c3c3c;
   font-size: 75%;
+  /* 17px is approx. the default line-height as measured on Windows 7 Segoe UI.
+     12px is 75% of approx. the default font-size as measured on Windows 7 Segoe UI.
+     The 17/12 is here to convert em from units of font-size to units of
+     line-height. The goal here is to initialize at the height of a
+     three-line snippet to reduce visual moving/flickering. */
+  min-height: -moz-calc(17/12 * 3em);
 }
 
 #launcher {
   display: -moz-box;
   -moz-box-align: center;
   -moz-box-pack: center;
   width: 100%;
   background-color: hsla(0,0%,0%,.03);
@@ -251,18 +263,19 @@ body[narrow] #restorePreviousSessionSepa
 }
 
 body[narrow] #restorePreviousSession {
   font-size: 80%;
 }
 
 .launchButton::before {
   display: block;
+  width: 32px;
   height: 32px;
-  margin-bottom: 6px;
+  margin: 0 auto 6px;
   line-height: 0; /* remove extra vertical space due to non-zero font-size */
 }
 
 #downloads::before {
   content: url("chrome://browser/content/abouthome/downloads.png");
 }
 
 #bookmarks::before {
--- a/browser/base/content/abouthome/aboutHome.js
+++ b/browser/base/content/abouthome/aboutHome.js
@@ -160,16 +160,25 @@ function setupSearchEngine()
 
   // Add search engine logo.
   if (gSearchEngine.image) {
     let logoElt = document.getElementById("searchEngineLogo");
     logoElt.src = gSearchEngine.image;
     logoElt.alt = gSearchEngine.name;
   }
 
+  // The "autofocus" attribute doesn't focus the form element
+  // immediately when the element is first drawn, so the
+  // attribute is also used for styling when the page first loads.
+  let searchText = document.getElementById("searchText");
+  searchText.addEventListener("blur", function searchText_onBlur(e) {
+    searchText.removeEventListener("blur", searchText_onBlur);
+    e.target.removeAttribute("autofocus");
+  });
+
 }
 
 function loadSnippets()
 {
   // Check last snippets update.
   let lastUpdate = localStorage["snippets-last-update"];
   let updateURL = localStorage["snippets-update-url"];
   if (updateURL && (!lastUpdate ||
--- a/browser/base/content/abouthome/aboutHome.xhtml
+++ b/browser/base/content/abouthome/aboutHome.xhtml
@@ -20,19 +20,16 @@
 <html xmlns="http://www.w3.org/1999/xhtml">
   <head>
     <title>&abouthome.pageTitle;</title>
 
     <link rel="icon" type="image/png" id="favicon"
           href="chrome://branding/content/icon16.png"/>
     <link rel="stylesheet" type="text/css" media="all"
           href="chrome://browser/content/abouthome/aboutHome.css"/>
-
-    <script type="text/javascript;version=1.8"
-            src="chrome://browser/content/abouthome/aboutHome.js"/>
   </head>
 
   <body dir="&locale.dir;">
     <div class="spacer"/>
     <div id="topSection">
       <img id="brandLogo" src="chrome://branding/content/about-logo.png" alt=""/>
 
       <div id="searchContainer">
@@ -62,10 +59,13 @@
       <button class="launchButton" id="addons">&abouthome.addonsButton.label;</button>
       <button class="launchButton" id="sync">&abouthome.syncButton.label;</button>
       <button class="launchButton" id="settings">&abouthome.settingsButton.label;</button>
       <div id="restorePreviousSessionSeparator"/>
       <button class="launchButton" id="restorePreviousSession">&historyRestoreLastSession.label;</button>
     </div>
 
     <a id="aboutMozilla" href="http://www.mozilla.org/about/"/>
+
+    <script type="text/javascript;version=1.8"
+            src="chrome://browser/content/abouthome/aboutHome.js"/>
   </body>
 </html>
--- a/browser/base/content/pageinfo/pageInfo.xul
+++ b/browser/base/content/pageinfo/pageInfo.xul
@@ -349,27 +349,32 @@
               <radio id="geo#2" command="cmd_geoToggle" label="&permBlock;"/>
             </radiogroup>
           </hbox>
         </vbox>
         <vbox class="permission">
           <label class="permissionLabel" id="permIndexedDBLabel"
                  value="&permIndexedDB;" control="indexedDBRadioGroup"/>
           <hbox role="group" aria-labelledby="permIndexedDBLabel">
-            <checkbox id="indexedDBDef" command="cmd_indexedDBDef" label="&permAskAlways;"/>
+            <checkbox id="indexedDBDef" command="cmd_indexedDBDef" label="&permUseDefault;"/>
+            <spacer flex="1"/>
+            <radiogroup id="indexedDBRadioGroup" orient="horizontal">
+              <!-- Ask and Allow are purposefully reversed here! -->
+              <radio id="indexedDB#1" command="cmd_indexedDBToggle" label="&permAskAlways;"/>
+              <radio id="indexedDB#0" command="cmd_indexedDBToggle" label="&permAllow;"/>
+              <radio id="indexedDB#2" command="cmd_indexedDBToggle" label="&permBlock;"/>
+            </radiogroup>
+          </hbox>
+          <hbox>
             <spacer flex="1"/>
             <vbox pack="center">
-              <label id="indexedDBStatus" control="indexedDBClear"/>
+              <label id="indexedDBStatus" control="indexedDBClear" hidden="true"/>
             </vbox>
-            <button id="indexedDBClear" label="&permClearStorage;"
+            <button id="indexedDBClear" label="&permClearStorage;" hidden="true"
                     accesskey="&permClearStorage.accesskey;" onclick="onIndexedDBClear();"/>
-            <radiogroup id="indexedDBRadioGroup" orient="horizontal">
-              <radio id="indexedDB#1" command="cmd_indexedDBToggle" label="&permAllow;"/>
-              <radio id="indexedDB#2" command="cmd_indexedDBToggle" label="&permBlock;"/>
-            </radiogroup>
           </hbox>
         </vbox>
         <vbox class="permission" id="permPluginsRow">
           <label class="permissionLabel" id="permPluginsLabel"
                  value="&permPlugins;" control="pluginsRadioGroup"/>
           <hbox role="group" aria-labelledby="permPluginsLabel">
             <checkbox id="pluginsDef" command="cmd_pluginsDef" label="&permAskAlways;"/>
             <spacer flex="1"/>
--- a/browser/base/content/pageinfo/permissions.js
+++ b/browser/base/content/pageinfo/permissions.js
@@ -46,17 +46,17 @@ var gPermObj = {
     return BLOCK;
   },
   geo: function getGeoDefaultPermissions()
   {
     return BLOCK;
   },
   indexedDB: function getIndexedDBDefaultPermissions()
   {
-    return BLOCK;
+    return UNKNOWN;
   },
   plugins: function getPluginsDefaultPermissions()
   {
     if (gPrefs.getBoolPref("plugins.click_to_play"))
       return BLOCK;
     return ALLOW;
   },
   fullscreen: function getFullscreenDefaultPermissions()
@@ -144,19 +144,16 @@ function onCheckboxClick(aPartId)
 {
   var permissionManager = Components.classes[PERMISSION_CONTRACTID]
                                     .getService(nsIPermissionManager);
 
   var command  = document.getElementById("cmd_" + aPartId + "Toggle");
   var checkbox = document.getElementById(aPartId + "Def");
   if (checkbox.checked) {
     permissionManager.remove(gPermURI.host, aPartId);
-    if (aPartId == "indexedDB") {
-      permissionManager.remove(gPermURI.host, "indexedDB-unlimited");
-    }
     command.setAttribute("disabled", "true");
     var perm = gPermObj[aPartId]();
     setRadioState(aPartId, perm);
   }
   else {
     onRadioClick(aPartId);
     command.removeAttribute("disabled");
   }
@@ -166,17 +163,18 @@ function onRadioClick(aPartId)
 {
   var permissionManager = Components.classes[PERMISSION_CONTRACTID]
                                     .getService(nsIPermissionManager);
 
   var radioGroup = document.getElementById(aPartId + "RadioGroup");
   var id = radioGroup.selectedItem.id;
   var permission = id.split('#')[1];
   permissionManager.add(gPermURI, aPartId, permission);
-  if (aPartId == "indexedDB" && permission == BLOCK) {
+  if (aPartId == "indexedDB" &&
+      (permission == ALLOW || permission == BLOCK)) {
     permissionManager.remove(gPermURI.host, "indexedDB-unlimited");
   }
   if (aPartId == "fullscreen" && permission == UNKNOWN) {
     permissionManager.remove(gPermURI.host, "fullscreen");
   }  
 }
 
 function setRadioState(aPartId, aValue)
@@ -202,17 +200,16 @@ function initIndexedDBRow()
 function onIndexedDBClear()
 {
   Components.classes["@mozilla.org/dom/indexeddb/manager;1"]
             .getService(nsIIndexedDatabaseManager)
             .clearDatabasesForURI(gPermURI);
 
   var permissionManager = Components.classes[PERMISSION_CONTRACTID]
                                     .getService(nsIPermissionManager);
-  permissionManager.remove(gPermURI.host, "indexedDB");
   permissionManager.remove(gPermURI.host, "indexedDB-unlimited");
   initIndexedDBRow();
 }
 
 function onIndexedDBUsageCallback(uri, usage, fileUsage)
 {
   if (!uri.equals(gPermURI)) {
     throw new Error("Callback received for bad URI: " + uri);
--- a/browser/components/dirprovider/DirectoryProvider.h
+++ b/browser/components/dirprovider/DirectoryProvider.h
@@ -4,32 +4,33 @@
 
 #ifndef DirectoryProvider_h__
 #define DirectoryProvider_h__
 
 #include "nsIDirectoryService.h"
 #include "nsComponentManagerUtils.h"
 #include "nsISimpleEnumerator.h"
 #include "nsIFile.h"
+#include "mozilla/Attributes.h"
 
 #define NS_BROWSERDIRECTORYPROVIDER_CONTRACTID \
   "@mozilla.org/browser/directory-provider;1"
 
 namespace mozilla {
 namespace browser {
 
-class DirectoryProvider : public nsIDirectoryServiceProvider2
+class DirectoryProvider MOZ_FINAL : public nsIDirectoryServiceProvider2
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDIRECTORYSERVICEPROVIDER
   NS_DECL_NSIDIRECTORYSERVICEPROVIDER2
 
 private:
-  class AppendingEnumerator : public nsISimpleEnumerator
+  class AppendingEnumerator MOZ_FINAL : public nsISimpleEnumerator
   {
   public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSISIMPLEENUMERATOR
 
     AppendingEnumerator(nsISimpleEnumerator* aBase,
                         char const *const *aAppendList);
 
--- a/browser/components/feeds/src/nsFeedSniffer.h
+++ b/browser/components/feeds/src/nsFeedSniffer.h
@@ -2,18 +2,20 @@
 /* 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 "nsIContentSniffer.h"
 #include "nsIStreamListener.h"
 #include "nsStringAPI.h"
+#include "mozilla/Attributes.h"
 
-class nsFeedSniffer : public nsIContentSniffer, nsIStreamListener
+class nsFeedSniffer MOZ_FINAL : public nsIContentSniffer,
+                                       nsIStreamListener
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSICONTENTSNIFFER
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSISTREAMLISTENER
 
   static NS_METHOD AppendSegmentToString(nsIInputStream* inputStream,
--- a/browser/components/privatebrowsing/src/nsPrivateBrowsingServiceWrapper.h
+++ b/browser/components/privatebrowsing/src/nsPrivateBrowsingServiceWrapper.h
@@ -1,20 +1,21 @@
 /* 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 "nsCOMPtr.h"
 #include "nsIPrivateBrowsingService.h"
 #include "nsIObserver.h"
+#include "mozilla/Attributes.h"
 
 class nsIJSContextStack;
 
-class nsPrivateBrowsingServiceWrapper : public nsIPrivateBrowsingService,
-                                        public nsIObserver
+class nsPrivateBrowsingServiceWrapper MOZ_FINAL : public nsIPrivateBrowsingService,
+                                                  public nsIObserver
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIPRIVATEBROWSINGSERVICE
   NS_DECL_NSIOBSERVER
 
   nsresult Init();
 
--- a/dom/file/test/helpers.js
+++ b/dom/file/test/helpers.js
@@ -12,27 +12,25 @@ var fileStorages = [
 ];
 
 var utils = SpecialPowers.getDOMWindowUtils(window);
 
 var testGenerator = testSteps();
 
 function runTest()
 {
-  allowIndexedDB();
   allowUnlimitedQuota();
 
   SimpleTest.waitForExplicitFinish();
   testGenerator.next();
 }
 
 function finishTest()
 {
   resetUnlimitedQuota();
-  resetIndexedDB();
 
   SimpleTest.executeSoon(function() {
     testGenerator.close();
     SimpleTest.finish();
   });
 }
 
 function grabEventAndContinueHandler(event)
@@ -85,26 +83,16 @@ function addPermission(type, allow, url)
 function removePermission(type, url)
 {
   if (!url) {
     url = window.document;
   }
   SpecialPowers.removePermission(type, url);
 }
 
-function allowIndexedDB(url)
-{
-  addPermission("indexedDB", true, url);
-}
-
-function resetIndexedDB(url)
-{
-  removePermission("indexedDB", url);
-}
-
 function allowUnlimitedQuota(url)
 {
   addPermission("indexedDB-unlimited", true, url);
 }
 
 function resetUnlimitedQuota(url)
 {
   removePermission("indexedDB-unlimited", url);
--- a/dom/indexedDB/CheckPermissionsHelper.cpp
+++ b/dom/indexedDB/CheckPermissionsHelper.cpp
@@ -24,64 +24,73 @@
 
 #include "IndexedDatabaseManager.h"
 
 #define PERMISSION_INDEXEDDB "indexedDB"
 #define PREF_INDEXEDDB_ENABLED "dom.indexedDB.enabled"
 #define TOPIC_PERMISSIONS_PROMPT "indexedDB-permissions-prompt"
 #define TOPIC_PERMISSIONS_RESPONSE "indexedDB-permissions-response"
 
+// This is a little confusing, but our default behavior (UNKNOWN_ACTION) is to
+// allow access without a prompt. If the "indexedDB" permission is set to
+// ALLOW_ACTION then we will issue a prompt before allowing access. Otherwise
+// (DENY_ACTION) we deny access.
+#define PERMISSION_ALLOWED nsIPermissionManager::UNKNOWN_ACTION
+#define PERMISSION_DENIED nsIPermissionManager::DENY_ACTION
+#define PERMISSION_PROMPT nsIPermissionManager::ALLOW_ACTION
+
 using namespace mozilla;
 USING_INDEXEDDB_NAMESPACE
 using namespace mozilla::services;
 
 namespace {
 
 inline
 PRUint32
 GetIndexedDBPermissions(const nsACString& aASCIIOrigin,
                         nsIDOMWindow* aWindow)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   if (!Preferences::GetBool(PREF_INDEXEDDB_ENABLED)) {
-    return nsIPermissionManager::DENY_ACTION;
+    return PERMISSION_DENIED;
   }
 
-  // No window here means chrome access
+  // No window here means chrome access.
   if (!aWindow) {
-    return nsIPermissionManager::ALLOW_ACTION;
+    return PERMISSION_ALLOWED;
   }
 
   nsCOMPtr<nsIScriptObjectPrincipal> sop(do_QueryInterface(aWindow));
   NS_ENSURE_TRUE(sop, nsIPermissionManager::DENY_ACTION);
 
   if (nsContentUtils::IsSystemPrincipal(sop->GetPrincipal())) {
-    return nsIPermissionManager::ALLOW_ACTION;
+    return PERMISSION_ALLOWED;
   }
 
   nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(aWindow);
   nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(webNav);
   if (loadContext && loadContext->UsePrivateBrowsing()) {
     // TODO Support private browsing indexedDB?
-    return nsIPermissionManager::DENY_ACTION;
+    NS_WARNING("IndexedDB may not be used while in private browsing mode!");
+    return PERMISSION_DENIED;
   }
 
   nsCOMPtr<nsIURI> uri;
   nsresult rv = NS_NewURI(getter_AddRefs(uri), aASCIIOrigin);
-  NS_ENSURE_SUCCESS(rv, nsIPermissionManager::DENY_ACTION);
+  NS_ENSURE_SUCCESS(rv, PERMISSION_DENIED);
 
   nsCOMPtr<nsIPermissionManager> permissionManager =
     do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
-  NS_ENSURE_TRUE(permissionManager, nsIPermissionManager::DENY_ACTION);
+  NS_ENSURE_TRUE(permissionManager, PERMISSION_DENIED);
 
   PRUint32 permission;
   rv = permissionManager->TestPermission(uri, PERMISSION_INDEXEDDB,
                                          &permission);
-  NS_ENSURE_SUCCESS(rv, nsIPermissionManager::DENY_ACTION);
+  NS_ENSURE_SUCCESS(rv, PERMISSION_DENIED);
 
   return permission;
 }
 
 } // anonymous namespace
 
 NS_IMPL_THREADSAFE_ISUPPORTS3(CheckPermissionsHelper, nsIRunnable,
                                                       nsIInterfaceRequestor,
@@ -97,56 +106,55 @@ CheckPermissionsHelper::Run()
                         GetIndexedDBPermissions(mASCIIOrigin, mWindow);
 
   nsresult rv;
   if (mHasPrompted) {
     // Add permissions to the database, but only if we are in the parent
     // process (if we are in the child process, we have already
     // set the permission when the prompt was shown in the parent, as
     // we cannot set the permission from the child).
-    if (permission != nsIPermissionManager::UNKNOWN_ACTION &&
-        XRE_GetProcessType() == GeckoProcessType_Default) {
+    if (permission != PERMISSION_PROMPT &&
+        IndexedDatabaseManager::IsMainProcess()) {
       nsCOMPtr<nsIURI> uri;
       rv = NS_NewURI(getter_AddRefs(uri), mASCIIOrigin);
       NS_ENSURE_SUCCESS(rv, rv);
-  
+
       nsCOMPtr<nsIPermissionManager> permissionManager =
         do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
       NS_ENSURE_STATE(permissionManager);
-  
+
       rv = permissionManager->Add(uri, PERMISSION_INDEXEDDB, permission,
                                   nsIPermissionManager::EXPIRE_NEVER, 0);
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
-  else if (permission == nsIPermissionManager::UNKNOWN_ACTION &&
-           mPromptAllowed) {
+  else if (permission == PERMISSION_PROMPT && mPromptAllowed) {
     nsCOMPtr<nsIObserverService> obs = GetObserverService();
     rv = obs->NotifyObservers(static_cast<nsIRunnable*>(this),
                               TOPIC_PERMISSIONS_PROMPT, nsnull);
     NS_ENSURE_SUCCESS(rv, rv);
 
     return NS_OK;
   }
 
   nsRefPtr<OpenDatabaseHelper> helper;
   helper.swap(mHelper);
 
   nsCOMPtr<nsIDOMWindow> window;
   window.swap(mWindow);
 
-  if (permission == nsIPermissionManager::ALLOW_ACTION) {
+  if (permission == PERMISSION_ALLOWED) {
     IndexedDatabaseManager* mgr = IndexedDatabaseManager::Get();
     NS_ASSERTION(mgr, "This should never be null!");
 
     return helper->Dispatch(mgr->IOThread());
   }
 
-  NS_ASSERTION(permission == nsIPermissionManager::UNKNOWN_ACTION ||
-               permission == nsIPermissionManager::DENY_ACTION,
+  NS_ASSERTION(permission == PERMISSION_PROMPT ||
+               permission == PERMISSION_DENIED,
                "Unknown permission!");
 
   helper->SetError(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
 
   return helper->RunImmediately();
 }
 
 NS_IMETHODIMP
@@ -173,16 +181,34 @@ CheckPermissionsHelper::Observe(nsISuppo
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(!strcmp(aTopic, TOPIC_PERMISSIONS_RESPONSE), "Bad topic!");
   NS_ASSERTION(mPromptAllowed, "How did we get here?");
 
   mHasPrompted = true;
 
   nsresult rv;
-  mPromptResult = nsDependentString(aData).ToInteger(&rv);
+  PRUint32 promptResult = nsDependentString(aData).ToInteger(&rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  // Have to convert the permission we got from the user to our weird reversed
+  // permission type.
+  switch (promptResult) {
+    case nsIPermissionManager::ALLOW_ACTION:
+      mPromptResult = PERMISSION_ALLOWED;
+      break;
+    case nsIPermissionManager::DENY_ACTION:
+      mPromptResult = PERMISSION_DENIED;
+      break;
+    case nsIPermissionManager::UNKNOWN_ACTION:
+      mPromptResult = PERMISSION_PROMPT;
+      break;
+
+    default:
+      NS_NOTREACHED("Unknown permission type!");
+      mPromptResult = PERMISSION_DENIED;
+  }
+
   rv = NS_DispatchToCurrentThread(this);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
--- a/dom/indexedDB/test/browser_forgetThisSite.js
+++ b/dom/indexedDB/test/browser_forgetThisSite.js
@@ -15,18 +15,18 @@ const testPageURL1 = "http://" + domains
 const testPageURL2 = "http://" + domains[1] + addPath;
 const testPageURL3 = "http://" + domains[0] + getPath;
 const testPageURL4 = "http://" + domains[1] + getPath;
 
 function test()
 {
   waitForExplicitFinish();
   // Avoids the prompt
-  setPermission(testPageURL1, "indexedDB");
-  setPermission(testPageURL2, "indexedDB");
+  setPermission(testPageURL1, "indexedDB", "unknown");
+  setPermission(testPageURL2, "indexedDB", "unknown");
   executeSoon(test1);
 }
 
 function test1()
 {
   // Set database version for domain 1
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.selectedBrowser.addEventListener("load", function () {
@@ -62,17 +62,17 @@ function test2()
 }
 
 function test3()
 {
   // Remove database from domain 2
   Components.classes["@mozilla.org/privatebrowsing;1"]
             .getService(Components.interfaces.nsIPrivateBrowsingService)
             .removeDataFromDomain(domains[1]);
-  setPermission(testPageURL4, "indexedDB");
+  setPermission(testPageURL4, "indexedDB", "unknown");
   executeSoon(test4);
 }
 
 function test4()
 {
   // Get database version for domain 1
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.selectedBrowser.addEventListener("load", function () {
--- a/dom/indexedDB/test/browser_permissionsPromptAllow.js
+++ b/dom/indexedDB/test/browser_permissionsPromptAllow.js
@@ -5,34 +5,35 @@
 
 const testPageURL = "http://mochi.test:8888/browser/" +
   "dom/indexedDB/test/browser_permissionsPrompt.html";
 const notificationID = "indexedDB-permissions-prompt";
 
 function test()
 {
   waitForExplicitFinish();
-  removePermission(testPageURL, "indexedDB");
+  // We want a prompt.
+  setPermission(testPageURL, "indexedDB", "allow");
   executeSoon(test1);
 }
 
 function test1()
 {
   info("creating tab");
   gBrowser.selectedTab = gBrowser.addTab();
 
   gBrowser.selectedBrowser.addEventListener("load", function () {
     gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
 
     setFinishedCallback(function(result, exception) {
       ok(result instanceof Components.interfaces.nsIIDBDatabase,
          "First database creation was successful");
       ok(!exception, "No exception");
       is(getPermission(testPageURL, "indexedDB"),
-         Components.interfaces.nsIPermissionManager.ALLOW_ACTION,
+         Components.interfaces.nsIPermissionManager.UNKNOWN_ACTION,
          "Correct permission set");
       gBrowser.removeCurrentTab();
       executeSoon(test2);
     });
 
     registerPopupEventHandler("popupshowing", function () {
       ok(true, "prompt showing");
     });
@@ -58,17 +59,17 @@ function test2()
   gBrowser.selectedBrowser.addEventListener("load", function () {
     gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
 
     setFinishedCallback(function(result, exception) {
       ok(result instanceof Components.interfaces.nsIIDBDatabase,
          "First database creation was successful");
       ok(!exception, "No exception");
       is(getPermission(testPageURL, "indexedDB"),
-         Components.interfaces.nsIPermissionManager.ALLOW_ACTION,
+         Components.interfaces.nsIPermissionManager.UNKNOWN_ACTION,
          "Correct permission set");
       gBrowser.removeCurrentTab();
       unregisterAllPopupEventHandlers();
       removePermission(testPageURL, "indexedDB");
       executeSoon(finish);
     });
 
     registerPopupEventHandler("popupshowing", function () {
--- a/dom/indexedDB/test/browser_permissionsPromptDeny.js
+++ b/dom/indexedDB/test/browser_permissionsPromptDeny.js
@@ -5,17 +5,18 @@
 
 const testPageURL = "http://mochi.test:8888/browser/" +
   "dom/indexedDB/test/browser_permissionsPrompt.html";
 const notificationID = "indexedDB-permissions-prompt";
 
 function test()
 {
   waitForExplicitFinish();
-  removePermission(testPageURL, "indexedDB");
+  // We want the prompt.
+  setPermission(testPageURL, "indexedDB", "allow");
   executeSoon(test1);
 }
 
 function test1()
 {
   info("creating tab");
   gBrowser.selectedTab = gBrowser.addTab();
 
--- a/dom/indexedDB/test/browser_privateBrowsing.js
+++ b/dom/indexedDB/test/browser_privateBrowsing.js
@@ -5,18 +5,16 @@
 
 const testPageURL = "http://mochi.test:8888/browser/" +
   "dom/indexedDB/test/browser_permissionsPrompt.html";
 const notificationID = "indexedDB-permissions-prompt";
 
 function test()
 {
   waitForExplicitFinish();
-  // Avoids the actual prompt
-  setPermission(testPageURL, "indexedDB");
   executeSoon(test1);
 }
 
 function test1()
 {
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.selectedBrowser.addEventListener("load", function () {
     gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
--- a/dom/indexedDB/test/browser_quotaPromptAllow.js
+++ b/dom/indexedDB/test/browser_quotaPromptAllow.js
@@ -7,17 +7,16 @@
 const testPageURL = "http://bug704464-1.example.com/browser/" +
   "dom/indexedDB/test/browser_quotaPrompt.html";
 const notificationID = "indexedDB-quota-prompt";
 
 function test()
 {
   waitForExplicitFinish();
   requestLongerTimeout(10);
-  setPermission(testPageURL, "indexedDB");
   removePermission(testPageURL, "indexedDB-unlimited");
   Services.prefs.setIntPref("dom.indexedDB.warningQuota", 2);
   executeSoon(test1);
 }
 
 let addMoreTest1Count = 0;
 
 function test1()
@@ -38,17 +37,17 @@ function test1()
         if (addMoreTest1Count > seenPopupCount + 5) {
           setFinishedCallback(function(result) {
             is(result, "finished", "Got 'finished' result");
             is(getPermission(testPageURL, "indexedDB-unlimited"),
                Components.interfaces.nsIPermissionManager.ALLOW_ACTION,
                "Correct permission set");
             gBrowser.removeCurrentTab();
             unregisterAllPopupEventHandlers();
-            executeSoon(test2);
+            executeSoon(finish);
           });
           executeSoon(function() { dispatchEvent("indexedDB-done"); });
         }
         else {
           ++addMoreTest1Count;
           executeSoon(function() { dispatchEvent("indexedDB-addMore"); });
         }
       });
--- a/dom/indexedDB/test/browser_quotaPromptDatabases.js
+++ b/dom/indexedDB/test/browser_quotaPromptDatabases.js
@@ -7,17 +7,16 @@
 const testPageURL = "http://bug704464-3.example.com/browser/" +
   "dom/indexedDB/test/browser_quotaPromptDatabases.html";
 const notificationID = "indexedDB-quota-prompt";
 
 function test()
 {
   waitForExplicitFinish();
   requestLongerTimeout(10);
-  setPermission(testPageURL, "indexedDB");
   removePermission(testPageURL, "indexedDB-unlimited");
   Services.prefs.setIntPref("dom.indexedDB.warningQuota", 2);
   executeSoon(test1);
 }
 
 let addMoreTest1Count = 0;
 
 function test1()
--- a/dom/indexedDB/test/browser_quotaPromptDelete.js
+++ b/dom/indexedDB/test/browser_quotaPromptDelete.js
@@ -7,17 +7,16 @@
 const testPageURL = "http://bug702292.example.com/browser/" +
   "dom/indexedDB/test/browser_quotaPromptDelete.html";
 const notificationID = "indexedDB-quota-prompt";
 
 function test()
 {
   waitForExplicitFinish();
   requestLongerTimeout(10);
-  setPermission(testPageURL, "indexedDB");
   removePermission(testPageURL, "indexedDB-unlimited");
   Services.prefs.setIntPref("dom.indexedDB.warningQuota", 2);
   executeSoon(test1);
 }
 
 let addMoreTest1Count = 0;
 let haveReset = false;
 let secondTimeCount = 0;
--- a/dom/indexedDB/test/browser_quotaPromptDeny.js
+++ b/dom/indexedDB/test/browser_quotaPromptDeny.js
@@ -7,17 +7,16 @@
 const testPageURL = "http://bug704464-2.example.com/browser/" +
   "dom/indexedDB/test/browser_quotaPrompt.html";
 const notificationID = "indexedDB-quota-prompt";
 
 function test()
 {
   waitForExplicitFinish();
   requestLongerTimeout(10);
-  setPermission(testPageURL, "indexedDB");
   removePermission(testPageURL, "indexedDB-unlimited");
   Services.prefs.setIntPref("dom.indexedDB.warningQuota", 2);
   executeSoon(test1);
 }
 
 let addMoreTest1Count = 0;
 
 function test1()
--- a/dom/indexedDB/test/error_events_abort_transactions_iframe.html
+++ b/dom/indexedDB/test/error_events_abort_transactions_iframe.html
@@ -44,18 +44,16 @@
       }, 0);
     }
 
     window.onerror = function(message, filename, lineno) {
       is(message, "ConstraintError", "Expect a constraint error");
     };
 
     function testSteps() {
-      window.parent.SpecialPowers.addPermission("indexedDB", true, document);
-
       let request = indexedDB.open(window.location.pathname, 1);
       request.onsuccess = unexpectedSuccessHandler;
       request.onerror = grabEventAndContinueHandler;
       request.onupgradeneeded = grabEventAndContinueHandler;
       let event = yield;
 
       let db = event.target.result;
 
--- a/dom/indexedDB/test/event_propagation_iframe.html
+++ b/dom/indexedDB/test/event_propagation_iframe.html
@@ -82,18 +82,16 @@
         captureCount = bubbleCount = atTargetCount = 0;
         if (windowErrorCount) {
           finishTest();
         }
       }
     }
 
     function testSteps() {
-      window.parent.SpecialPowers.addPermission("indexedDB", true, document);
-
       let request = indexedDB.open(window.location.pathname, 1);
       request.onerror = errorHandler;
       request.onupgradeneeded = grabEventAndContinueHandler;
       let event = yield;
 
       let db = event.target.result;
       db.onerror = errorEventCounter;
       db.addEventListener("error", errorEventCounter, true);
--- a/dom/indexedDB/test/exceptions_in_events_iframe.html
+++ b/dom/indexedDB/test/exceptions_in_events_iframe.html
@@ -46,18 +46,16 @@
       }, 0);
     }
 
     window.onerror = function() {
       return false;
     };
 
     function testSteps() {
-      window.parent.SpecialPowers.addPermission("indexedDB", true, document);
-
       // Test 1: Throwing an exception in an upgradeneeded handler should
       // abort the versionchange transaction and fire an error at the request.
       let request = indexedDB.open(window.location.pathname, 1);
       request.onerror = errorHandler;
       request.onsuccess = unexpectedSuccessHandler;
       request.onupgradeneeded = function () {
         let transaction = request.transaction;
         transaction.oncomplete = unexpectedSuccessHandler;
--- a/dom/indexedDB/test/head.js
+++ b/dom/indexedDB/test/head.js
@@ -97,25 +97,40 @@ function setFinishedCallback(callback)
 function dispatchEvent(eventName)
 {
   info("dispatching event: " + eventName);
   let event = document.createEvent("Events");
   event.initEvent(eventName, false, false);
   gBrowser.selectedBrowser.contentWindow.dispatchEvent(event);
 }
 
-function setPermission(url, permission)
+function setPermission(url, permission, value)
 {
+  const nsIPermissionManager = Components.interfaces.nsIPermissionManager;
+
+  switch (value) {
+    case "allow":
+      value = nsIPermissionManager.ALLOW_ACTION;
+      break;
+    case "deny":
+      value = nsIPermissionManager.DENY_ACTION;
+      break;
+    case "unknown":
+      value = nsIPermissionManager.UNKNOWN_ACTION;
+      break;
+    default:
+      throw new Error("No idea what to set here!");
+  }
+
   let uri = Components.classes["@mozilla.org/network/io-service;1"]
                       .getService(Components.interfaces.nsIIOService)
                       .newURI(url, null, null);
   Components.classes["@mozilla.org/permissionmanager;1"]
             .getService(Components.interfaces.nsIPermissionManager)
-            .add(uri, permission,
-                 Components.interfaces.nsIPermissionManager.ALLOW_ACTION);
+            .add(uri, permission, value);
 }
 
 function removePermission(url, permission)
 {
   let uri = Components.classes["@mozilla.org/network/io-service;1"]
                       .getService(Components.interfaces.nsIIOService)
                       .newURI(url, null, null);
   Components.classes["@mozilla.org/permissionmanager;1"]
--- a/dom/indexedDB/test/helpers.js
+++ b/dom/indexedDB/test/helpers.js
@@ -48,32 +48,30 @@ function clearAllDatabases(callback) {
   });
 }
 
 if (!window.runTest) {
   window.runTest = function(limitedQuota)
   {
     SimpleTest.waitForExplicitFinish();
 
-    allowIndexedDB();
     if (limitedQuota) {
       denyUnlimitedQuota();
     }
     else {
       allowUnlimitedQuota();
     }
 
     clearAllDatabases(function () { testGenerator.next(); });
   }
 }
 
 function finishTest()
 {
   resetUnlimitedQuota();
-  resetIndexedDB();
 
   SimpleTest.executeSoon(function() {
     testGenerator.close();
     //clearAllDatabases(function() { SimpleTest.finish(); });
     SimpleTest.finish();
   });
 }
 
@@ -185,26 +183,16 @@ function removePermission(type, url)
   SpecialPowers.removePermission(type, url);
 }
 
 function setQuota(quota)
 {
   SpecialPowers.setIntPref("dom.indexedDB.warningQuota", quota);
 }
 
-function allowIndexedDB(url)
-{
-  addPermission("indexedDB", true, url);
-}
-
-function resetIndexedDB(url)
-{
-  removePermission("indexedDB", url);
-}
-
 function allowUnlimitedQuota(url)
 {
   addPermission("indexedDB-unlimited", true, url);
 }
 
 function denyUnlimitedQuota(url)
 {
   addPermission("indexedDB-unlimited", false, url);
--- a/dom/indexedDB/test/test_third_party.html
+++ b/dom/indexedDB/test/test_third_party.html
@@ -57,19 +57,16 @@
         return;
       }
 
       SimpleTest.finish();
     }
 
     function runTest() {
       SimpleTest.waitForExplicitFinish();
-
-      SpecialPowers.addPermission("indexedDB", true, document);
-
       window.addEventListener("message", messageListener, false);
       setiframe();
     }
   </script>
 
 </head>
 
 <body onload="runTest();">
--- a/dom/system/gonk/AutoMounterSetting.cpp
+++ b/dom/system/gonk/AutoMounterSetting.cpp
@@ -11,28 +11,29 @@
 #include "nsCOMPtr.h"
 #include "nsDebug.h"
 #include "nsIObserverService.h"
 #include "nsIJSContextStack.h"
 #include "nsISettingsService.h"
 #include "nsServiceManagerUtils.h"
 #include "nsString.h"
 #include "xpcpublic.h"
+#include "mozilla/Attributes.h"
 
 #undef LOG
 #define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "AutoMounterSetting" , ## args)
 #define ERR(args...)  __android_log_print(ANDROID_LOG_ERROR, "AutoMounterSetting" , ## args)
 
 #define UMS_MODE                "ums.mode"
 #define MOZSETTINGS_CHANGED     "mozsettings-changed"
 
 namespace mozilla {
 namespace system {
 
-class SettingsServiceCallback : public nsISettingsServiceCallback
+class SettingsServiceCallback MOZ_FINAL : public nsISettingsServiceCallback
 {
 public:
   NS_DECL_ISUPPORTS
 
   SettingsServiceCallback() {}
 
   NS_IMETHOD Handle(const nsAString &aName, const JS::Value &aResult, JSContext *aContext) {
     if (JSVAL_IS_INT(aResult)) {
--- a/dom/tests/mochitest/webapps/test_bug_765063.xul
+++ b/dom/tests/mochitest/webapps/test_bug_765063.xul
@@ -16,16 +16,17 @@
   <script type="application/javascript" src="jshelper.js"/>
 
 <script> 
 SimpleTest.waitForExplicitFinish();
 
 // Observe app installation and confirm that the install origin didn't change.
 var observer = {
   observe: function observe(subject, topic, data) {
+    Services.obs.removeObserver(observer, "webapps-sync-install");
     ok(JSON.parse(data).installOrigin == "http://www.example.com",
        "the install origin didn't change");
     tearDown();
     SimpleTest.finish();
   }
 };
 
 Components.utils.import("resource://gre/modules/Services.jsm");
--- a/editor/libeditor/html/nsHTMLEditorStyle.cpp
+++ b/editor/libeditor/html/nsHTMLEditorStyle.cpp
@@ -1749,29 +1749,25 @@ nsHTMLEditor::RelativeFontChangeHelper(P
   if (aSizeChange != 1 && aSizeChange != -1) {
     return NS_ERROR_ILLEGAL_VALUE;
   }
 
   // If this is a font node with size, put big/small inside it.
   if (aNode->IsElement() && aNode->AsElement()->IsHTML(nsGkAtoms::font) &&
       aNode->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::size)) {
     // Cycle through children and adjust relative font size.
-    for (nsIContent* child = aNode->GetLastChild();
-         child;
-         child = child->GetPreviousSibling()) {
-      nsresult rv = RelativeFontChangeOnNode(aSizeChange, child);
+    for (PRUint32 i = aNode->GetChildCount(); i--; ) {
+      nsresult rv = RelativeFontChangeOnNode(aSizeChange, aNode->GetChildAt(i));
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
 
   // Now cycle through the children.
-  for (nsIContent* child = aNode->GetLastChild();
-       child;
-       child = child->GetPreviousSibling()) {
-    nsresult rv = RelativeFontChangeHelper(aSizeChange, child);
+  for (PRUint32 i = aNode->GetChildCount(); i--; ) {
+    nsresult rv = RelativeFontChangeHelper(aSizeChange, aNode->GetChildAt(i));
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return NS_OK;
 }
 
 
 nsresult
@@ -1827,20 +1823,18 @@ nsHTMLEditor::RelativeFontChangeOnNode(P
     return InsertContainerAbove(aNode->AsDOMNode(), address_of(tmp),
                                 nsAtomString(atom));
   }
 
   // none of the above?  then cycle through the children.
   // MOOSE: we should group the children together if possible
   // into a single "big" or "small".  For the moment they are
   // each getting their own.  
-  for (nsIContent* child = aNode->GetLastChild();
-       child;
-       child = child->GetPreviousSibling()) {
-    nsresult rv = RelativeFontChangeOnNode(aSizeChange, child);
+  for (PRUint32 i = aNode->GetChildCount(); i--; ) {
+    nsresult rv = RelativeFontChangeOnNode(aSizeChange, aNode->GetChildAt(i));
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP 
 nsHTMLEditor::GetFontFaceState(bool *aMixed, nsAString &outFace)
--- a/editor/libeditor/html/tests/Makefile.in
+++ b/editor/libeditor/html/tests/Makefile.in
@@ -74,16 +74,17 @@ include $(topsrcdir)/config/rules.mk
 		test_dom_input_event_on_htmleditor.html \
 		test_htmleditor_keyevent_handling.html \
 		test_keypress_untrusted_event.html \
 		test_select_all_without_body.html \
 		file_select_all_without_body.html \
 		test_root_element_replacement.html \
 		test_bug738366.html \
 		test_bug757371.html \
+		test_bug767684.html \
 		$(NULL)
 
 ifneq (mobile,$(MOZ_BUILD_APP))
 _TEST_FILES +=  test_spellcheck_pref.html \
 		$(NULL)
 endif
 
 _DATA_FILES = \
new file mode 100644
--- /dev/null
+++ b/editor/libeditor/html/tests/test_bug767684.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=767684
+-->
+<title>Test for Bug 767684</title>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" href="/tests/SimpleTest/test.css">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=767684">Mozilla Bug 767684</a>
+<div contenteditable>foo<b>bar</b>baz</div>
+<script>
+getSelection().selectAllChildren(document.querySelector("div"));
+document.execCommand("increaseFontSize");
+is(document.querySelector("div").innerHTML, "<big>foo<b>bar</b>baz</big>",
+   "All selected text must be embiggened");
+</script>
--- a/extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
+++ b/extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
@@ -13,23 +13,24 @@
 #include "nsIJSRuntimeService.h"
 #include "nsCOMPtr.h"
 #include "nsIServiceManager.h"
 #include "nsIComponentManager.h"
 #include "nsString.h"
 #include "nsIPrefService.h"
 #include "nsIJSContextStack.h"
 #include "nspr.h"
+#include "mozilla/Attributes.h"
 
 extern PRLogModuleInfo *MCD;
 
 // Security Manager for new XPCONNECT enabled JS Context
 // Right now it allows all access
 
-class AutoConfigSecMan : public nsIXPCSecurityManager
+class AutoConfigSecMan MOZ_FINAL : public nsIXPCSecurityManager
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIXPCSECURITYMANAGER
     AutoConfigSecMan();
 };
 
 NS_IMPL_ISUPPORTS1(AutoConfigSecMan, nsIXPCSecurityManager)
--- a/gfx/layers/opengl/LayerManagerOGLShaders.h
+++ b/gfx/layers/opengl/LayerManagerOGLShaders.h
@@ -1,746 +1,746 @@
-/* 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/. */
+/* AUTOMATICALLY GENERATED from LayerManagerOGLShaders.txt */
+/* DO NOT EDIT! */
+
+static const char sLayerVS[] = "/* sLayerVS */\n\
+/* Vertex Shader */\n\
+uniform mat4 uMatrixProj;\n\
+uniform mat4 uLayerQuadTransform;\n\
+uniform mat4 uLayerTransform;\n\
+uniform vec4 uRenderTargetOffset;\n\
+attribute vec4 aVertexCoord;\n\
+attribute vec2 aTexCoord;\n\
+#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
+varying mediump vec2 vTexCoord;\n\
+#else\n\
+varying vec2 vTexCoord;\n\
+#endif\n\
+\n\
+void main()\n\
+{\n\
+vec4 finalPosition = aVertexCoord;\n\
+finalPosition = uLayerQuadTransform * finalPosition;\n\
+finalPosition = uLayerTransform * finalPosition;\n\
+finalPosition.xyz /= finalPosition.w;\n\
+\n\
+\n\
+finalPosition = finalPosition - uRenderTargetOffset;\n\
+finalPosition.xyz *= finalPosition.w;\n\
+finalPosition = uMatrixProj * finalPosition;\n\
+vTexCoord = aTexCoord;\n\
+gl_Position = finalPosition;\n\
+}\n\
+";
+
+static const char sLayerMaskVS[] = "/* sLayerMaskVS */\n\
+/* Vertex Shader */\n\
+uniform mat4 uMatrixProj;\n\
+uniform mat4 uLayerQuadTransform;\n\
+uniform mat4 uLayerTransform;\n\
+uniform vec4 uRenderTargetOffset;\n\
+attribute vec4 aVertexCoord;\n\
+attribute vec2 aTexCoord;\n\
+#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
+varying mediump vec2 vTexCoord;\n\
+#else\n\
+varying vec2 vTexCoord;\n\
+#endif\n\
+\n\
+uniform mat4 uMaskQuadTransform;\n\
+varying vec2 vMaskCoord;\n\
+\n\
+void main()\n\
+{\n\
+vec4 finalPosition = aVertexCoord;\n\
+finalPosition = uLayerQuadTransform * finalPosition;\n\
+finalPosition = uLayerTransform * finalPosition;\n\
+finalPosition.xyz /= finalPosition.w;\n\
+vMaskCoord = (uMaskQuadTransform * finalPosition).xy;\n\
+\n\
+finalPosition = finalPosition - uRenderTargetOffset;\n\
+finalPosition.xyz *= finalPosition.w;\n\
+finalPosition = uMatrixProj * finalPosition;\n\
+vTexCoord = aTexCoord;\n\
+gl_Position = finalPosition;\n\
+}\n\
+";
+
+static const char sLayerMask3DVS[] = "/* sLayerMask3DVS */\n\
+/* Vertex Shader */\n\
+uniform mat4 uMatrixProj;\n\
+uniform mat4 uLayerQuadTransform;\n\
+uniform mat4 uLayerTransform;\n\
+uniform vec4 uRenderTargetOffset;\n\
+attribute vec4 aVertexCoord;\n\
+attribute vec2 aTexCoord;\n\
+#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
+varying mediump vec2 vTexCoord;\n\
+#else\n\
+varying vec2 vTexCoord;\n\
+#endif\n\
+\n\
+uniform mat4 uMaskQuadTransform;\n\
+varying vec3 vMaskCoord;\n\
+\n\
+void main()\n\
+{\n\
+vec4 finalPosition = aVertexCoord;\n\
+finalPosition = uLayerQuadTransform * finalPosition;\n\
+finalPosition = uLayerTransform * finalPosition;\n\
+finalPosition.xyz /= finalPosition.w;\n\
+vMaskCoord.xy = (uMaskQuadTransform * vec4(finalPosition.xyz, 1.0)).xy;\n\
+// correct for perspective correct interpolation, see comment in D3D10 shader\n\
+vMaskCoord.z = 1.0;\n\
+vMaskCoord *= finalPosition.w;\n\
+\n\
+finalPosition = finalPosition - uRenderTargetOffset;\n\
+finalPosition.xyz *= finalPosition.w;\n\
+finalPosition = uMatrixProj * finalPosition;\n\
+vTexCoord = aTexCoord;\n\
+gl_Position = finalPosition;\n\
+}\n\
+";
+
+static const char sSolidColorLayerFS[] = "/* sSolidColorLayerFS */\n\
+#define NO_LAYER_OPACITY 1\n\
+/* Fragment Shader */\n\
+#ifdef GL_ES\n\
+precision lowp float;\n\
+#endif\n\
+\n\
+#ifndef NO_LAYER_OPACITY\n\
+uniform float uLayerOpacity;\n\
+#endif\n\
+#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
+varying mediump vec2 vTexCoord;\n\
+#else\n\
+varying vec2 vTexCoord;\n\
+#endif\n\
+\n\
+uniform vec4 uRenderColor;\n\
+void main()\n\
+{\n\
+float mask = 1.0;\n\
+\n\
+gl_FragColor = mask * uRenderColor;\n\
+}\n\
+";
+
+static const char sSolidColorLayerMaskFS[] = "/* sSolidColorLayerMaskFS */\n\
+#define NO_LAYER_OPACITY 1\n\
+/* Fragment Shader */\n\
+#ifdef GL_ES\n\
+precision lowp float;\n\
+#endif\n\
+\n\
+#ifndef NO_LAYER_OPACITY\n\
+uniform float uLayerOpacity;\n\
+#endif\n\
+#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
+varying mediump vec2 vTexCoord;\n\
+#else\n\
+varying vec2 vTexCoord;\n\
+#endif\n\
+\n\
+varying vec2 vMaskCoord;\n\
+uniform sampler2D uMaskTexture;\n\
+\n\
+uniform vec4 uRenderColor;\n\
+void main()\n\
+{\n\
+float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
+\n\
+gl_FragColor = mask * uRenderColor;\n\
+}\n\
+";
+
+static const char sRGBATextureLayerFS[] = "/* sRGBATextureLayerFS */\n\
+/* Fragment Shader */\n\
+#ifdef GL_ES\n\
+precision lowp float;\n\
+#endif\n\
+\n\
+#ifndef NO_LAYER_OPACITY\n\
+uniform float uLayerOpacity;\n\
+#endif\n\
+#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
+varying mediump vec2 vTexCoord;\n\
+#else\n\
+varying vec2 vTexCoord;\n\
+#endif\n\
+\n\
+uniform sampler2D uTexture;\n\
+void main()\n\
+{\n\
+float mask = 1.0;\n\
+\n\
+gl_FragColor = texture2D(uTexture, vTexCoord) * uLayerOpacity * mask;\n\
+}\n\
+";
+
+static const char sRGBATextureLayerMaskFS[] = "/* sRGBATextureLayerMaskFS */\n\
+/* Fragment Shader */\n\
+#ifdef GL_ES\n\
+precision lowp float;\n\
+#endif\n\
+\n\
+#ifndef NO_LAYER_OPACITY\n\
+uniform float uLayerOpacity;\n\
+#endif\n\
+#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
+varying mediump vec2 vTexCoord;\n\
+#else\n\
+varying vec2 vTexCoord;\n\
+#endif\n\
+\n\
+varying vec2 vMaskCoord;\n\
+uniform sampler2D uMaskTexture;\n\
+\n\
+uniform sampler2D uTexture;\n\
+void main()\n\
+{\n\
+float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
+\n\
+gl_FragColor = texture2D(uTexture, vTexCoord) * uLayerOpacity * mask;\n\
+}\n\
+";
+
+static const char sRGBATextureLayerMask3DFS[] = "/* sRGBATextureLayerMask3DFS */\n\
+/* Fragment Shader */\n\
+#ifdef GL_ES\n\
+precision lowp float;\n\
+#endif\n\
+\n\
+#ifndef NO_LAYER_OPACITY\n\
+uniform float uLayerOpacity;\n\
+#endif\n\
+#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
+varying mediump vec2 vTexCoord;\n\
+#else\n\
+varying vec2 vTexCoord;\n\
+#endif\n\
+\n\
+varying vec3 vMaskCoord;\n\
+uniform sampler2D uMaskTexture;\n\
+\n\
+uniform sampler2D uTexture;\n\
+void main()\n\
+{\n\
+vec2 maskCoords = vMaskCoord.xy / vMaskCoord.z;\n\
+float mask = texture2D(uMaskTexture, maskCoords).r;\n\
+\n\
+gl_FragColor = texture2D(uTexture, vTexCoord) * uLayerOpacity * mask;\n\
+}\n\
+";
+
+static const char sRGBARectTextureLayerFS[] = "/* sRGBARectTextureLayerFS */\n\
+#extension GL_ARB_texture_rectangle : enable\n\
+/* Fragment Shader */\n\
+#ifdef GL_ES\n\
+precision lowp float;\n\
+#endif\n\
+\n\
+#ifndef NO_LAYER_OPACITY\n\
+uniform float uLayerOpacity;\n\
+#endif\n\
+#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
+varying mediump vec2 vTexCoord;\n\
+#else\n\
+varying vec2 vTexCoord;\n\
+#endif\n\
+\n\
+/* This should not be used on GL ES */\n\
+#ifndef GL_ES\n\
+uniform sampler2DRect uTexture;\n\
+uniform vec2 uTexCoordMultiplier;\n\
+void main()\n\
+{\n\
+float mask = 1.0;\n\
+\n\
+gl_FragColor = texture2DRect(uTexture, vec2(vTexCoord * uTexCoordMultiplier)) * uLayerOpacity * mask;\n\
+}\n\
+#else\n\
+void main()\n\
+{\n\
+gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n\
+}\n\
+#endif\n\
+";
+
+static const char sRGBARectTextureLayerMaskFS[] = "/* sRGBARectTextureLayerMaskFS */\n\
+#extension GL_ARB_texture_rectangle : enable\n\
+/* Fragment Shader */\n\
+#ifdef GL_ES\n\
+precision lowp float;\n\
+#endif\n\
+\n\
+#ifndef NO_LAYER_OPACITY\n\
+uniform float uLayerOpacity;\n\
+#endif\n\
+#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
+varying mediump vec2 vTexCoord;\n\
+#else\n\
+varying vec2 vTexCoord;\n\
+#endif\n\
+\n\
+varying vec2 vMaskCoord;\n\
+uniform sampler2D uMaskTexture;\n\
+\n\
+/* This should not be used on GL ES */\n\
+#ifndef GL_ES\n\
+uniform sampler2DRect uTexture;\n\
+uniform vec2 uTexCoordMultiplier;\n\
+void main()\n\
+{\n\
+float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
+\n\
+gl_FragColor = texture2DRect(uTexture, vec2(vTexCoord * uTexCoordMultiplier)) * uLayerOpacity * mask;\n\
+}\n\
+#else\n\
+void main()\n\
+{\n\
+gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n\
+}\n\
+#endif\n\
+";
+
+static const char sRGBARectTextureLayerMask3DFS[] = "/* sRGBARectTextureLayerMask3DFS */\n\
+#extension GL_ARB_texture_rectangle : enable\n\
+/* Fragment Shader */\n\
+#ifdef GL_ES\n\
+precision lowp float;\n\
+#endif\n\
+\n\
+#ifndef NO_LAYER_OPACITY\n\
+uniform float uLayerOpacity;\n\
+#endif\n\
+#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
+varying mediump vec2 vTexCoord;\n\
+#else\n\
+varying vec2 vTexCoord;\n\
+#endif\n\
+\n\
+varying vec3 vMaskCoord;\n\
+uniform sampler2D uMaskTexture;\n\
+\n\
+/* This should not be used on GL ES */\n\
+#ifndef GL_ES\n\
+uniform sampler2DRect uTexture;\n\
+uniform vec2 uTexCoordMultiplier;\n\
+void main()\n\
+{\n\
+vec2 maskCoords = vMaskCoord.xy / vMaskCoord.z;\n\
+float mask = texture2D(uMaskTexture, maskCoords).r;\n\
+\n\
+gl_FragColor = texture2DRect(uTexture, vec2(vTexCoord * uTexCoordMultiplier)) * uLayerOpacity * mask;\n\
+}\n\
+#else\n\
+void main()\n\
+{\n\
+gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n\
+}\n\
+#endif\n\
+";
+
+static const char sBGRATextureLayerFS[] = "/* sBGRATextureLayerFS */\n\
+/* Fragment Shader */\n\
+#ifdef GL_ES\n\
+precision lowp float;\n\
+#endif\n\
+\n\
+#ifndef NO_LAYER_OPACITY\n\
+uniform float uLayerOpacity;\n\
+#endif\n\
+#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
+varying mediump vec2 vTexCoord;\n\
+#else\n\
+varying vec2 vTexCoord;\n\
+#endif\n\
+\n\
+uniform sampler2D uTexture;\n\
+void main()\n\
+{\n\
+float mask = 1.0;\n\
+\n\
+gl_FragColor = texture2D(uTexture, vTexCoord).bgra * uLayerOpacity * mask;\n\
+}\n\
+";
 
-/* AUTOMATICALLY GENERATED from LayerManagerOGLShaders.txt */
-/* DO NOT EDIT! */
-
-static const char sLayerVS[] = "/* sLayerVS */\n\
-/* Vertex Shader */\n\
-uniform mat4 uMatrixProj;\n\
-uniform mat4 uLayerQuadTransform;\n\
-uniform mat4 uLayerTransform;\n\
-uniform vec4 uRenderTargetOffset;\n\
-attribute vec4 aVertexCoord;\n\
-attribute vec2 aTexCoord;\n\
-#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
-varying mediump vec2 vTexCoord;\n\
-#else\n\
-varying vec2 vTexCoord;\n\
-#endif\n\
-\n\
-void main()\n\
-{\n\
-vec4 finalPosition = aVertexCoord;\n\
-finalPosition = uLayerQuadTransform * finalPosition;\n\
-finalPosition = uLayerTransform * finalPosition;\n\
-finalPosition.xyz /= finalPosition.w;\n\
-\n\
-\n\
-finalPosition = finalPosition - uRenderTargetOffset;\n\
-finalPosition.xyz *= finalPosition.w;\n\
-finalPosition = uMatrixProj * finalPosition;\n\
-vTexCoord = aTexCoord;\n\
-gl_Position = finalPosition;\n\
-}\n\
-";
-
-static const char sLayerMaskVS[] = "/* sLayerMaskVS */\n\
-/* Vertex Shader */\n\
-uniform mat4 uMatrixProj;\n\
-uniform mat4 uLayerQuadTransform;\n\
-uniform mat4 uLayerTransform;\n\
-uniform vec4 uRenderTargetOffset;\n\
-attribute vec4 aVertexCoord;\n\
-attribute vec2 aTexCoord;\n\
-#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
-varying mediump vec2 vTexCoord;\n\
-#else\n\
-varying vec2 vTexCoord;\n\
-#endif\n\
-\n\
-uniform mat4 uMaskQuadTransform;\n\
-varying vec2 vMaskCoord;\n\
-\n\
-void main()\n\
-{\n\
-vec4 finalPosition = aVertexCoord;\n\
-finalPosition = uLayerQuadTransform * finalPosition;\n\
-finalPosition = uLayerTransform * finalPosition;\n\
-finalPosition.xyz /= finalPosition.w;\n\
-vMaskCoord = (uMaskQuadTransform * finalPosition).xy;\n\
-\n\
-finalPosition = finalPosition - uRenderTargetOffset;\n\
-finalPosition.xyz *= finalPosition.w;\n\
-finalPosition = uMatrixProj * finalPosition;\n\
-vTexCoord = aTexCoord;\n\
-gl_Position = finalPosition;\n\
-}\n\
-";
-
-static const char sLayerMask3DVS[] = "/* sLayerMask3DVS */\n\
-/* Vertex Shader */\n\
-uniform mat4 uMatrixProj;\n\
-uniform mat4 uLayerQuadTransform;\n\
-uniform mat4 uLayerTransform;\n\
-uniform vec4 uRenderTargetOffset;\n\
-attribute vec4 aVertexCoord;\n\
-attribute vec2 aTexCoord;\n\
-#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
-varying mediump vec2 vTexCoord;\n\
-#else\n\
-varying vec2 vTexCoord;\n\
-#endif\n\
-\n\
-uniform mat4 uMaskQuadTransform;\n\
-varying vec3 vMaskCoord;\n\
-\n\
-void main()\n\
-{\n\
-vec4 finalPosition = aVertexCoord;\n\
-finalPosition = uLayerQuadTransform * finalPosition;\n\
-finalPosition = uLayerTransform * finalPosition;\n\
-finalPosition.xyz /= finalPosition.w;\n\
-vMaskCoord.xy = (uMaskQuadTransform * vec4(finalPosition.xyz, 1.0)).xy;\n\
-// correct for perspective correct interpolation, see comment in D3D10 shader\n\
-vMaskCoord.z = 1.0;\n\
-vMaskCoord *= finalPosition.w;\n\
-\n\
-finalPosition = finalPosition - uRenderTargetOffset;\n\
-finalPosition.xyz *= finalPosition.w;\n\
-finalPosition = uMatrixProj * finalPosition;\n\
-vTexCoord = aTexCoord;\n\
-gl_Position = finalPosition;\n\
-}\n\
-";
-
-static const char sSolidColorLayerFS[] = "/* sSolidColorLayerFS */\n\
-#define NO_LAYER_OPACITY 1\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision lowp float;\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform float uLayerOpacity;\n\
-#endif\n\
-#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
-varying mediump vec2 vTexCoord;\n\
-#else\n\
-varying vec2 vTexCoord;\n\
-#endif\n\
-\n\
-uniform vec4 uRenderColor;\n\
-void main()\n\
-{\n\
-float mask = 1.0;\n\
-\n\
-gl_FragColor = mask * uRenderColor;\n\
-}\n\
-";
-
-static const char sSolidColorLayerMaskFS[] = "/* sSolidColorLayerMaskFS */\n\
-#define NO_LAYER_OPACITY 1\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision lowp float;\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform float uLayerOpacity;\n\
-#endif\n\
-#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
-varying mediump vec2 vTexCoord;\n\
-#else\n\
-varying vec2 vTexCoord;\n\
-#endif\n\
-\n\
-varying vec2 vMaskCoord;\n\
-uniform sampler2D uMaskTexture;\n\
-\n\
-uniform vec4 uRenderColor;\n\
-void main()\n\
-{\n\
-float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
-\n\
-gl_FragColor = mask * uRenderColor;\n\
-}\n\
-";
-
-static const char sRGBATextureLayerFS[] = "/* sRGBATextureLayerFS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision lowp float;\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform float uLayerOpacity;\n\
-#endif\n\
-#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
-varying mediump vec2 vTexCoord;\n\
-#else\n\
-varying vec2 vTexCoord;\n\
-#endif\n\
-\n\
-uniform sampler2D uTexture;\n\
-void main()\n\
-{\n\
-float mask = 1.0;\n\
-\n\
-gl_FragColor = texture2D(uTexture, vTexCoord) * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sRGBATextureLayerMaskFS[] = "/* sRGBATextureLayerMaskFS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision lowp float;\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform float uLayerOpacity;\n\
-#endif\n\
-#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
-varying mediump vec2 vTexCoord;\n\
-#else\n\
-varying vec2 vTexCoord;\n\
-#endif\n\
-\n\
-varying vec2 vMaskCoord;\n\
-uniform sampler2D uMaskTexture;\n\
-\n\
-uniform sampler2D uTexture;\n\
-void main()\n\
-{\n\
-float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
-\n\
-gl_FragColor = texture2D(uTexture, vTexCoord) * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sRGBATextureLayerMask3DFS[] = "/* sRGBATextureLayerMask3DFS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision lowp float;\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform float uLayerOpacity;\n\
-#endif\n\
-#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
-varying mediump vec2 vTexCoord;\n\
-#else\n\
-varying vec2 vTexCoord;\n\
-#endif\n\
-\n\
-varying vec3 vMaskCoord;\n\
-uniform sampler2D uMaskTexture;\n\
-\n\
-uniform sampler2D uTexture;\n\
-void main()\n\
-{\n\
-vec2 maskCoords = vMaskCoord.xy / vMaskCoord.z;\n\
-float mask = texture2D(uMaskTexture, maskCoords).r;\n\
-\n\
-gl_FragColor = texture2D(uTexture, vTexCoord) * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sRGBARectTextureLayerFS[] = "/* sRGBARectTextureLayerFS */\n\
-#extension GL_ARB_texture_rectangle : enable\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision lowp float;\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform float uLayerOpacity;\n\
-#endif\n\
-#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
-varying mediump vec2 vTexCoord;\n\
-#else\n\
-varying vec2 vTexCoord;\n\
-#endif\n\
-\n\
-/* This should not be used on GL ES */\n\
-#ifndef GL_ES\n\
-uniform sampler2DRect uTexture;\n\
-uniform vec2 uTexCoordMultiplier;\n\
-void main()\n\
-{\n\
-float mask = 1.0;\n\
-\n\
-gl_FragColor = texture2DRect(uTexture, vec2(vTexCoord * uTexCoordMultiplier)) * uLayerOpacity * mask;\n\
-}\n\
-#else\n\
-void main()\n\
-{\n\
-gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n\
-}\n\
-#endif\n\
-";
-
-static const char sRGBARectTextureLayerMaskFS[] = "/* sRGBARectTextureLayerMaskFS */\n\
-#extension GL_ARB_texture_rectangle : enable\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision lowp float;\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform float uLayerOpacity;\n\
-#endif\n\
-#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
-varying mediump vec2 vTexCoord;\n\
-#else\n\
-varying vec2 vTexCoord;\n\
-#endif\n\
-\n\
-varying vec2 vMaskCoord;\n\
-uniform sampler2D uMaskTexture;\n\
-\n\
-/* This should not be used on GL ES */\n\
-#ifndef GL_ES\n\
-uniform sampler2DRect uTexture;\n\
-uniform vec2 uTexCoordMultiplier;\n\
-void main()\n\
-{\n\
-float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
-\n\
-gl_FragColor = texture2DRect(uTexture, vec2(vTexCoord * uTexCoordMultiplier)) * uLayerOpacity * mask;\n\
-}\n\
-#else\n\
-void main()\n\
-{\n\
-gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n\
-}\n\
-#endif\n\
-";
-
-static const char sRGBARectTextureLayerMask3DFS[] = "/* sRGBARectTextureLayerMask3DFS */\n\
-#extension GL_ARB_texture_rectangle : enable\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision lowp float;\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform float uLayerOpacity;\n\
-#endif\n\
-#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
-varying mediump vec2 vTexCoord;\n\
-#else\n\
-varying vec2 vTexCoord;\n\
-#endif\n\
-\n\
-varying vec3 vMaskCoord;\n\
-uniform sampler2D uMaskTexture;\n\
-\n\
-/* This should not be used on GL ES */\n\
-#ifndef GL_ES\n\
-uniform sampler2DRect uTexture;\n\
-uniform vec2 uTexCoordMultiplier;\n\
-void main()\n\
-{\n\
-vec2 maskCoords = vMaskCoord.xy / vMaskCoord.z;\n\
-float mask = texture2D(uMaskTexture, maskCoords).r;\n\
-\n\
-gl_FragColor = texture2DRect(uTexture, vec2(vTexCoord * uTexCoordMultiplier)) * uLayerOpacity * mask;\n\
-}\n\
-#else\n\
-void main()\n\
-{\n\
-gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n\
-}\n\
-#endif\n\
-";
-
-static const char sBGRATextureLayerFS[] = "/* sBGRATextureLayerFS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision lowp float;\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform float uLayerOpacity;\n\
-#endif\n\
-#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
-varying mediump vec2 vTexCoord;\n\
-#else\n\
-varying vec2 vTexCoord;\n\
-#endif\n\
-\n\
-uniform sampler2D uTexture;\n\
-void main()\n\
-{\n\
-float mask = 1.0;\n\
-\n\
-gl_FragColor = texture2D(uTexture, vTexCoord).bgra * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sBGRATextureLayerMaskFS[] = "/* sBGRATextureLayerMaskFS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision lowp float;\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform float uLayerOpacity;\n\
-#endif\n\
-#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
-varying mediump vec2 vTexCoord;\n\
-#else\n\
-varying vec2 vTexCoord;\n\
-#endif\n\
-\n\
-varying vec2 vMaskCoord;\n\
-uniform sampler2D uMaskTexture;\n\
-\n\
-uniform sampler2D uTexture;\n\
-void main()\n\
-{\n\
-float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
-\n\
-gl_FragColor = texture2D(uTexture, vTexCoord).bgra * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sRGBXTextureLayerFS[] = "/* sRGBXTextureLayerFS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision lowp float;\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform float uLayerOpacity;\n\
-#endif\n\
-#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
-varying mediump vec2 vTexCoord;\n\
-#else\n\
-varying vec2 vTexCoord;\n\
-#endif\n\
-\n\
-uniform sampler2D uTexture;\n\
-void main()\n\
-{\n\
-float mask = 1.0;\n\
-\n\
-gl_FragColor = vec4(texture2D(uTexture, vTexCoord).rgb, 1.0) * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sRGBXTextureLayerMaskFS[] = "/* sRGBXTextureLayerMaskFS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision lowp float;\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform float uLayerOpacity;\n\
-#endif\n\
-#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
-varying mediump vec2 vTexCoord;\n\
-#else\n\
-varying vec2 vTexCoord;\n\
-#endif\n\
-\n\
-varying vec2 vMaskCoord;\n\
-uniform sampler2D uMaskTexture;\n\
-\n\
-uniform sampler2D uTexture;\n\
-void main()\n\
-{\n\
-float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
-\n\
-gl_FragColor = vec4(texture2D(uTexture, vTexCoord).rgb, 1.0) * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sBGRXTextureLayerFS[] = "/* sBGRXTextureLayerFS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision lowp float;\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform float uLayerOpacity;\n\
-#endif\n\
-#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
-varying mediump vec2 vTexCoord;\n\
-#else\n\
-varying vec2 vTexCoord;\n\
-#endif\n\
-\n\
-uniform sampler2D uTexture;\n\
-void main()\n\
-{\n\
-float mask = 1.0;\n\
-\n\
-gl_FragColor = vec4(texture2D(uTexture, vTexCoord).bgr, 1.0) * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sBGRXTextureLayerMaskFS[] = "/* sBGRXTextureLayerMaskFS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision lowp float;\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform float uLayerOpacity;\n\
-#endif\n\
-#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
-varying mediump vec2 vTexCoord;\n\
-#else\n\
-varying vec2 vTexCoord;\n\
-#endif\n\
-\n\
-varying vec2 vMaskCoord;\n\
-uniform sampler2D uMaskTexture;\n\
-\n\
-uniform sampler2D uTexture;\n\
-void main()\n\
-{\n\
-float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
-\n\
-gl_FragColor = vec4(texture2D(uTexture, vTexCoord).bgr, 1.0) * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sYCbCrTextureLayerFS[] = "/* sYCbCrTextureLayerFS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision lowp float;\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform float uLayerOpacity;\n\
-#endif\n\
-#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
-varying mediump vec2 vTexCoord;\n\
-#else\n\
-varying vec2 vTexCoord;\n\
-#endif\n\
-\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#endif\n\
-uniform sampler2D uYTexture;\n\
-uniform sampler2D uCbTexture;\n\
-uniform sampler2D uCrTexture;\n\
-void main()\n\
-{\n\
-vec4 yuv;\n\
-vec4 color;\n\
-yuv.r = texture2D(uCrTexture, vTexCoord).r - 0.5;\n\
-yuv.g = texture2D(uYTexture, vTexCoord).r - 0.0625;\n\
-yuv.b = texture2D(uCbTexture, vTexCoord).r - 0.5;\n\
-color.r = yuv.g * 1.164 + yuv.r * 1.596;\n\
-color.g = yuv.g * 1.164 - 0.813 * yuv.r - 0.391 * yuv.b;\n\
-color.b = yuv.g * 1.164 + yuv.b * 2.018;\n\
-color.a = 1.0;\n\
-float mask = 1.0;\n\
-\n\
-gl_FragColor = color * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sYCbCrTextureLayerMaskFS[] = "/* sYCbCrTextureLayerMaskFS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision lowp float;\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform float uLayerOpacity;\n\
-#endif\n\
-#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
-varying mediump vec2 vTexCoord;\n\
-#else\n\
-varying vec2 vTexCoord;\n\
-#endif\n\
-\n\
-varying vec2 vMaskCoord;\n\
-uniform sampler2D uMaskTexture;\n\
-\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#endif\n\
-uniform sampler2D uYTexture;\n\
-uniform sampler2D uCbTexture;\n\
-uniform sampler2D uCrTexture;\n\
-void main()\n\
-{\n\
-vec4 yuv;\n\
-vec4 color;\n\
-yuv.r = texture2D(uCrTexture, vTexCoord).r - 0.5;\n\
-yuv.g = texture2D(uYTexture, vTexCoord).r - 0.0625;\n\
-yuv.b = texture2D(uCbTexture, vTexCoord).r - 0.5;\n\
-color.r = yuv.g * 1.164 + yuv.r * 1.596;\n\
-color.g = yuv.g * 1.164 - 0.813 * yuv.r - 0.391 * yuv.b;\n\
-color.b = yuv.g * 1.164 + yuv.b * 2.018;\n\
-color.a = 1.0;\n\
-float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
-\n\
-gl_FragColor = color * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sComponentPass1FS[] = "/* sComponentPass1FS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision lowp float;\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform float uLayerOpacity;\n\
-#endif\n\
-#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
-varying mediump vec2 vTexCoord;\n\
-#else\n\
-varying vec2 vTexCoord;\n\
-#endif\n\
-\n\
-uniform sampler2D uBlackTexture;\n\
-uniform sampler2D uWhiteTexture;\n\
-void main()\n\
-{\n\
-vec3 onBlack = texture2D(uBlackTexture, vTexCoord).bgr;\n\
-vec3 onWhite = texture2D(uWhiteTexture, vTexCoord).bgr;\n\
-vec4 alphas = (1.0 - onWhite + onBlack).rgbg;\n\
-float mask = 1.0;\n\
-\n\
-gl_FragColor = alphas * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sComponentPassMask1FS[] = "/* sComponentPassMask1FS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision lowp float;\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform float uLayerOpacity;\n\
-#endif\n\
-#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
-varying mediump vec2 vTexCoord;\n\
-#else\n\
-varying vec2 vTexCoord;\n\
-#endif\n\
-\n\
-varying vec2 vMaskCoord;\n\
-uniform sampler2D uMaskTexture;\n\
-\n\
-uniform sampler2D uBlackTexture;\n\
-uniform sampler2D uWhiteTexture;\n\
-void main()\n\
-{\n\
-vec3 onBlack = texture2D(uBlackTexture, vTexCoord).bgr;\n\
-vec3 onWhite = texture2D(uWhiteTexture, vTexCoord).bgr;\n\
-vec4 alphas = (1.0 - onWhite + onBlack).rgbg;\n\
-float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
-\n\
-gl_FragColor = alphas * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sComponentPass2FS[] = "/* sComponentPass2FS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision lowp float;\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform float uLayerOpacity;\n\
-#endif\n\
-#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
-varying mediump vec2 vTexCoord;\n\
-#else\n\
-varying vec2 vTexCoord;\n\
-#endif\n\
-\n\
-uniform sampler2D uBlackTexture;\n\
-uniform sampler2D uWhiteTexture;\n\
-void main()\n\
-{\n\
-vec3 onBlack = texture2D(uBlackTexture, vTexCoord).bgr;\n\
-vec3 onWhite = texture2D(uWhiteTexture, vTexCoord).bgr;\n\
-vec4 alphas = (1.0 - onWhite + onBlack).rgbg;\n\
-float mask = 1.0;\n\
-\n\
-gl_FragColor = vec4(onBlack, alphas.a) * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sComponentPassMask2FS[] = "/* sComponentPassMask2FS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision lowp float;\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform float uLayerOpacity;\n\
-#endif\n\
-#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
-varying mediump vec2 vTexCoord;\n\
-#else\n\
-varying vec2 vTexCoord;\n\
-#endif\n\
-\n\
-varying vec2 vMaskCoord;\n\
-uniform sampler2D uMaskTexture;\n\
-\n\
-uniform sampler2D uBlackTexture;\n\
-uniform sampler2D uWhiteTexture;\n\
-void main()\n\
-{\n\
-vec3 onBlack = texture2D(uBlackTexture, vTexCoord).bgr;\n\
-vec3 onWhite = texture2D(uWhiteTexture, vTexCoord).bgr;\n\
-vec4 alphas = (1.0 - onWhite + onBlack).rgbg;\n\
-float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
-\n\
-gl_FragColor = vec4(onBlack, alphas.a) * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sCopyVS[] = "/* sCopyVS */\n\
-/* Vertex Shader */\n\
-attribute vec4 aVertexCoord;\n\
-attribute vec2 aTexCoord;\n\
-varying vec2 vTexCoord;\n\
-void main()\n\
-{\n\
-gl_Position = aVertexCoord;\n\
-vTexCoord = aTexCoord;\n\
-}\n\
-";
-
-static const char sCopy2DFS[] = "/* sCopy2DFS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision lowp float;\n\
-#endif\n\
-\n\
-varying vec2 vTexCoord;\n\
-uniform sampler2D uTexture;\n\
-void main()\n\
-{\n\
-gl_FragColor = texture2D(uTexture, vTexCoord);\n\
-}\n\
-";
-
-static const char sCopy2DRectFS[] = "/* sCopy2DRectFS */\n\
-#extension GL_ARB_texture_rectangle : enable\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision lowp float;\n\
-#endif\n\
-\n\
-varying vec2 vTexCoord;\n\
-uniform vec2 uTexCoordMultiplier;\n\
-#ifndef GL_ES\n\
-uniform sampler2DRect uTexture;\n\
-void main()\n\
-{\n\
-gl_FragColor = texture2DRect(uTexture, vTexCoord * uTexCoordMultiplier);\n\
-}\n\
-#else\n\
-void main()\n\
-{\n\
-gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n\
-}\n\
-#endif\n\
-";
-
+static const char sBGRATextureLayerMaskFS[] = "/* sBGRATextureLayerMaskFS */\n\
+/* Fragment Shader */\n\
+#ifdef GL_ES\n\
+precision lowp float;\n\
+#endif\n\
+\n\
+#ifndef NO_LAYER_OPACITY\n\
+uniform float uLayerOpacity;\n\
+#endif\n\
+#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
+varying mediump vec2 vTexCoord;\n\
+#else\n\
+varying vec2 vTexCoord;\n\
+#endif\n\
+\n\
+varying vec2 vMaskCoord;\n\
+uniform sampler2D uMaskTexture;\n\
+\n\
+uniform sampler2D uTexture;\n\
+void main()\n\
+{\n\
+float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
+\n\
+gl_FragColor = texture2D(uTexture, vTexCoord).bgra * uLayerOpacity * mask;\n\
+}\n\
+";
+
+static const char sRGBXTextureLayerFS[] = "/* sRGBXTextureLayerFS */\n\
+/* Fragment Shader */\n\
+#ifdef GL_ES\n\
+precision lowp float;\n\
+#endif\n\
+\n\
+#ifndef NO_LAYER_OPACITY\n\
+uniform float uLayerOpacity;\n\
+#endif\n\
+#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
+varying mediump vec2 vTexCoord;\n\
+#else\n\
+varying vec2 vTexCoord;\n\
+#endif\n\
+\n\
+uniform sampler2D uTexture;\n\
+void main()\n\
+{\n\
+float mask = 1.0;\n\
+\n\
+gl_FragColor = vec4(texture2D(uTexture, vTexCoord).rgb, 1.0) * uLayerOpacity * mask;\n\
+}\n\
+";
+
+static const char sRGBXTextureLayerMaskFS[] = "/* sRGBXTextureLayerMaskFS */\n\
+/* Fragment Shader */\n\
+#ifdef GL_ES\n\
+precision lowp float;\n\
+#endif\n\
+\n\
+#ifndef NO_LAYER_OPACITY\n\
+uniform float uLayerOpacity;\n\
+#endif\n\
+#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
+varying mediump vec2 vTexCoord;\n\
+#else\n\
+varying vec2 vTexCoord;\n\
+#endif\n\
+\n\
+varying vec2 vMaskCoord;\n\
+uniform sampler2D uMaskTexture;\n\
+\n\
+uniform sampler2D uTexture;\n\
+void main()\n\
+{\n\
+float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
+\n\
+gl_FragColor = vec4(texture2D(uTexture, vTexCoord).rgb, 1.0) * uLayerOpacity * mask;\n\
+}\n\
+";
+
+static const char sBGRXTextureLayerFS[] = "/* sBGRXTextureLayerFS */\n\
+/* Fragment Shader */\n\
+#ifdef GL_ES\n\
+precision lowp float;\n\
+#endif\n\
+\n\
+#ifndef NO_LAYER_OPACITY\n\
+uniform float uLayerOpacity;\n\
+#endif\n\
+#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
+varying mediump vec2 vTexCoord;\n\
+#else\n\
+varying vec2 vTexCoord;\n\
+#endif\n\
+\n\
+uniform sampler2D uTexture;\n\
+void main()\n\
+{\n\
+float mask = 1.0;\n\
+\n\
+gl_FragColor = vec4(texture2D(uTexture, vTexCoord).bgr, 1.0) * uLayerOpacity * mask;\n\
+}\n\
+";
+
+static const char sBGRXTextureLayerMaskFS[] = "/* sBGRXTextureLayerMaskFS */\n\
+/* Fragment Shader */\n\
+#ifdef GL_ES\n\
+precision lowp float;\n\
+#endif\n\
+\n\
+#ifndef NO_LAYER_OPACITY\n\
+uniform float uLayerOpacity;\n\
+#endif\n\
+#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
+varying mediump vec2 vTexCoord;\n\
+#else\n\
+varying vec2 vTexCoord;\n\
+#endif\n\
+\n\
+varying vec2 vMaskCoord;\n\
+uniform sampler2D uMaskTexture;\n\
+\n\
+uniform sampler2D uTexture;\n\
+void main()\n\
+{\n\
+float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
+\n\
+gl_FragColor = vec4(texture2D(uTexture, vTexCoord).bgr, 1.0) * uLayerOpacity * mask;\n\
+}\n\
+";
+
+static const char sYCbCrTextureLayerFS[] = "/* sYCbCrTextureLayerFS */\n\
+/* Fragment Shader */\n\
+#ifdef GL_ES\n\
+precision lowp float;\n\
+#endif\n\
+\n\
+#ifndef NO_LAYER_OPACITY\n\
+uniform float uLayerOpacity;\n\
+#endif\n\
+#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
+varying mediump vec2 vTexCoord;\n\
+#else\n\
+varying vec2 vTexCoord;\n\
+#endif\n\
+\n\
+#ifdef GL_ES\n\
+precision mediump float;\n\
+#endif\n\
+uniform sampler2D uYTexture;\n\
+uniform sampler2D uCbTexture;\n\
+uniform sampler2D uCrTexture;\n\
+void main()\n\
+{\n\
+vec4 color;\n\
+float y = texture2D(uYTexture, vTexCoord).r;\n\
+float cb = texture2D(uCbTexture, vTexCoord).r;\n\
+float cr = texture2D(uCrTexture, vTexCoord).r;\n\
+y = (y - 0.0625) * 1.164;\n\
+cb = cb - 0.5;\n\
+cr = cr - 0.5;\n\
+color.r = y + cr * 1.596;\n\
+color.g = y - 0.813 * cr - 0.391 * cb;\n\
+color.b = y + cb * 2.018;\n\
+color.a = 1.0;\n\
+float mask = 1.0;\n\
+\n\
+gl_FragColor = color * uLayerOpacity * mask;\n\
+}\n\
+";
+
+static const char sYCbCrTextureLayerMaskFS[] = "/* sYCbCrTextureLayerMaskFS */\n\
+/* Fragment Shader */\n\
+#ifdef GL_ES\n\
+precision lowp float;\n\
+#endif\n\
+\n\
+#ifndef NO_LAYER_OPACITY\n\
+uniform float uLayerOpacity;\n\
+#endif\n\
+#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
+varying mediump vec2 vTexCoord;\n\
+#else\n\
+varying vec2 vTexCoord;\n\
+#endif\n\
+\n\
+varying vec2 vMaskCoord;\n\
+uniform sampler2D uMaskTexture;\n\
+\n\
+#ifdef GL_ES\n\
+precision mediump float;\n\
+#endif\n\
+uniform sampler2D uYTexture;\n\
+uniform sampler2D uCbTexture;\n\
+uniform sampler2D uCrTexture;\n\
+void main()\n\
+{\n\
+vec4 color;\n\
+float y = texture2D(uYTexture, vTexCoord).r;\n\
+float cb = texture2D(uCbTexture, vTexCoord).r;\n\
+float cr = texture2D(uCrTexture, vTexCoord).r;\n\
+y = (y - 0.0625) * 1.164;\n\
+cb = cb - 0.5;\n\
+cr = cr - 0.5;\n\
+color.r = y + cr * 1.596;\n\
+color.g = y - 0.813 * cr - 0.391 * cb;\n\
+color.b = y + cb * 2.018;\n\
+color.a = 1.0;\n\
+float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
+\n\
+gl_FragColor = color * uLayerOpacity * mask;\n\
+}\n\
+";
+
+static const char sComponentPass1FS[] = "/* sComponentPass1FS */\n\
+/* Fragment Shader */\n\
+#ifdef GL_ES\n\
+precision lowp float;\n\
+#endif\n\
+\n\
+#ifndef NO_LAYER_OPACITY\n\
+uniform float uLayerOpacity;\n\
+#endif\n\
+#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
+varying mediump vec2 vTexCoord;\n\
+#else\n\
+varying vec2 vTexCoord;\n\
+#endif\n\
+\n\
+uniform sampler2D uBlackTexture;\n\
+uniform sampler2D uWhiteTexture;\n\
+void main()\n\
+{\n\
+vec3 onBlack = texture2D(uBlackTexture, vTexCoord).bgr;\n\
+vec3 onWhite = texture2D(uWhiteTexture, vTexCoord).bgr;\n\
+vec4 alphas = (1.0 - onWhite + onBlack).rgbg;\n\
+float mask = 1.0;\n\
+\n\
+gl_FragColor = alphas * uLayerOpacity * mask;\n\
+}\n\
+";
+
+static const char sComponentPassMask1FS[] = "/* sComponentPassMask1FS */\n\
+/* Fragment Shader */\n\
+#ifdef GL_ES\n\
+precision lowp float;\n\
+#endif\n\
+\n\
+#ifndef NO_LAYER_OPACITY\n\
+uniform float uLayerOpacity;\n\
+#endif\n\
+#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
+varying mediump vec2 vTexCoord;\n\
+#else\n\
+varying vec2 vTexCoord;\n\
+#endif\n\
+\n\
+varying vec2 vMaskCoord;\n\
+uniform sampler2D uMaskTexture;\n\
+\n\
+uniform sampler2D uBlackTexture;\n\
+uniform sampler2D uWhiteTexture;\n\
+void main()\n\
+{\n\
+vec3 onBlack = texture2D(uBlackTexture, vTexCoord).bgr;\n\
+vec3 onWhite = texture2D(uWhiteTexture, vTexCoord).bgr;\n\
+vec4 alphas = (1.0 - onWhite + onBlack).rgbg;\n\
+float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
+\n\
+gl_FragColor = alphas * uLayerOpacity * mask;\n\
+}\n\
+";
+
+static const char sComponentPass2FS[] = "/* sComponentPass2FS */\n\
+/* Fragment Shader */\n\
+#ifdef GL_ES\n\
+precision lowp float;\n\
+#endif\n\
+\n\
+#ifndef NO_LAYER_OPACITY\n\
+uniform float uLayerOpacity;\n\
+#endif\n\
+#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
+varying mediump vec2 vTexCoord;\n\
+#else\n\
+varying vec2 vTexCoord;\n\
+#endif\n\
+\n\
+uniform sampler2D uBlackTexture;\n\
+uniform sampler2D uWhiteTexture;\n\
+void main()\n\
+{\n\
+vec3 onBlack = texture2D(uBlackTexture, vTexCoord).bgr;\n\
+vec3 onWhite = texture2D(uWhiteTexture, vTexCoord).bgr;\n\
+vec4 alphas = (1.0 - onWhite + onBlack).rgbg;\n\
+float mask = 1.0;\n\
+\n\
+gl_FragColor = vec4(onBlack, alphas.a) * uLayerOpacity * mask;\n\
+}\n\
+";
+
+static const char sComponentPassMask2FS[] = "/* sComponentPassMask2FS */\n\
+/* Fragment Shader */\n\
+#ifdef GL_ES\n\
+precision lowp float;\n\
+#endif\n\
+\n\
+#ifndef NO_LAYER_OPACITY\n\
+uniform float uLayerOpacity;\n\
+#endif\n\
+#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
+varying mediump vec2 vTexCoord;\n\
+#else\n\
+varying vec2 vTexCoord;\n\
+#endif\n\
+\n\
+varying vec2 vMaskCoord;\n\
+uniform sampler2D uMaskTexture;\n\
+\n\
+uniform sampler2D uBlackTexture;\n\
+uniform sampler2D uWhiteTexture;\n\
+void main()\n\
+{\n\
+vec3 onBlack = texture2D(uBlackTexture, vTexCoord).bgr;\n\
+vec3 onWhite = texture2D(uWhiteTexture, vTexCoord).bgr;\n\
+vec4 alphas = (1.0 - onWhite + onBlack).rgbg;\n\
+float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
+\n\
+gl_FragColor = vec4(onBlack, alphas.a) * uLayerOpacity * mask;\n\
+}\n\
+";
+
+static const char sCopyVS[] = "/* sCopyVS */\n\
+/* Vertex Shader */\n\
+attribute vec4 aVertexCoord;\n\
+attribute vec2 aTexCoord;\n\
+varying vec2 vTexCoord;\n\
+void main()\n\
+{\n\
+gl_Position = aVertexCoord;\n\
+vTexCoord = aTexCoord;\n\
+}\n\
+";
+
+static const char sCopy2DFS[] = "/* sCopy2DFS */\n\
+/* Fragment Shader */\n\
+#ifdef GL_ES\n\
+precision lowp float;\n\
+#endif\n\
+\n\
+varying vec2 vTexCoord;\n\
+uniform sampler2D uTexture;\n\
+void main()\n\
+{\n\
+gl_FragColor = texture2D(uTexture, vTexCoord);\n\
+}\n\
+";
+
+static const char sCopy2DRectFS[] = "/* sCopy2DRectFS */\n\
+#extension GL_ARB_texture_rectangle : enable\n\
+/* Fragment Shader */\n\
+#ifdef GL_ES\n\
+precision lowp float;\n\
+#endif\n\
+\n\
+varying vec2 vTexCoord;\n\
+uniform vec2 uTexCoordMultiplier;\n\
+#ifndef GL_ES\n\
+uniform sampler2DRect uTexture;\n\
+void main()\n\
+{\n\
+gl_FragColor = texture2DRect(uTexture, vTexCoord * uTexCoordMultiplier);\n\
+}\n\
+#else\n\
+void main()\n\
+{\n\
+gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n\
+}\n\
+#endif\n\
+";
+
--- a/gfx/layers/opengl/LayerManagerOGLShaders.txt
+++ b/gfx/layers/opengl/LayerManagerOGLShaders.txt
@@ -267,36 +267,49 @@ uniform sampler2D uTexture;
 
 void main()
 {
 $FRAGMENT_CALC_MASK<mask>$
   gl_FragColor = vec4(texture2D(uTexture, vTexCoord).bgr, 1.0) * uLayerOpacity * mask;
 }
 @end
 
-// Three textures, representing YCbCr planes of a video image
+// Three textures, representing YCbCr planes of a video image.
+//
+// Some older versions of the Tegra 2 android driver have a bug
+// where arithmetic ops on a texture read are just ignored.  So,
+// if the below was |cb = texture2D(...).r - 0.5|, the "- 0.5" was
+// just being ignored/skipped.  This, of course, lead to crappy
+// rendering -- see bug 765150.  Doing them separately like below
+// makes it all OK.  We don't know if this is special to constants,
+// special to 0.5, special to addition/subtraction, etc.
 @shader sYCbCrTextureLayer<mask:,Mask>FS
 $LAYER_FRAGMENT<mask>$
 #ifdef GL_ES
 precision mediump float;
 #endif
 uniform sampler2D uYTexture;
 uniform sampler2D uCbTexture;
 uniform sampler2D uCrTexture;
 
 void main()
 {
-  vec4 yuv;
   vec4 color;
-  yuv.r = texture2D(uCrTexture, vTexCoord).r - 0.5;
-  yuv.g = texture2D(uYTexture, vTexCoord).r - 0.0625;
-  yuv.b = texture2D(uCbTexture, vTexCoord).r - 0.5;
-  color.r = yuv.g * 1.164 + yuv.r * 1.596;
-  color.g = yuv.g * 1.164 - 0.813 * yuv.r - 0.391 * yuv.b;
-  color.b = yuv.g * 1.164 + yuv.b * 2.018;
+
+  float y = texture2D(uYTexture, vTexCoord).r;
+  float cb = texture2D(uCbTexture, vTexCoord).r;
+  float cr = texture2D(uCrTexture, vTexCoord).r;
+
+  y = (y - 0.0625) * 1.164;
+  cb = cb - 0.5;
+  cr = cr - 0.5;
+
+  color.r = y + cr * 1.596;
+  color.g = y - 0.813 * cr - 0.391 * cb;
+  color.b = y + cb * 2.018;
   color.a = 1.0;
 $FRAGMENT_CALC_MASK<mask>$
   gl_FragColor = color * uLayerOpacity * mask;
 }
 @end
 
 // Two textures and two passes for component alpha rendering
 @shader sComponentPass<mask:,Mask>1FS
--- a/startupcache/StartupCache.h
+++ b/startupcache/StartupCache.h
@@ -16,16 +16,17 @@
 #include "nsZipArchive.h"
 #include "nsIStartupCache.h"
 #include "nsIStorageStream.h"
 #include "nsITimer.h"
 #include "nsIObserverService.h"
 #include "nsIObserver.h"
 #include "nsIOutputStream.h"
 #include "nsIFile.h"
+#include "mozilla/Attributes.h"
 
 /**
  * The StartupCache is a persistent cache of simple key-value pairs,
  * where the keys are null-terminated c-strings and the values are 
  * arbitrary data, passed as a (char*, size) tuple. 
  *
  * Clients should use the GetSingleton() static method to access the cache. It 
  * will be available from the end of XPCOM init (NS_InitXPCOM3 in nsXPComInit.cpp), 
@@ -83,17 +84,17 @@ struct CacheEntry
 
   size_t SizeOfExcludingThis(nsMallocSizeOfFun mallocSizeOf) {
     return mallocSizeOf(data);
   }
 };
 
 // We don't want to refcount StartupCache, and ObserverService wants to
 // refcount its listeners, so we'll let it refcount this instead.
-class StartupCacheListener : public nsIObserver
+class StartupCacheListener MOZ_FINAL : public nsIObserver
 {
   NS_DECL_ISUPPORTS
   NS_DECL_NSIOBSERVER
 };
 
 class StartupCache
 {
 
@@ -174,17 +175,17 @@ private:
   nsIMemoryReporter* mMappingMemoryReporter;
   nsIMemoryReporter* mDataMemoryReporter;
 };
 
 // This debug outputstream attempts to detect if clients are writing multiple
 // references to the same object. We only support that if that object
 // is a singleton.
 #ifdef DEBUG
-class StartupCacheDebugOutputStream
+class StartupCacheDebugOutputStream MOZ_FINAL
   : public nsIObjectOutputStream
 {  
   NS_DECL_ISUPPORTS
   NS_DECL_NSIOBJECTOUTPUTSTREAM
 
   StartupCacheDebugOutputStream (nsIObjectOutputStream* binaryStream,
                                    nsTHashtable<nsISupportsHashKey>* objectMap)
   : mBinaryStream(binaryStream), mObjectMap(objectMap) { }
@@ -200,17 +201,17 @@ class StartupCacheDebugOutputStream
 #endif // DEBUG
 
 // XPCOM wrapper interface provided for tests only.
 #define NS_STARTUPCACHE_CID \
       {0xae4505a9, 0x87ab, 0x477c, \
       {0xb5, 0x77, 0xf9, 0x23, 0x57, 0xed, 0xa8, 0x84}}
 // contract id: "@mozilla.org/startupcache/cache;1"
 
-class StartupCacheWrapper 
+class StartupCacheWrapper MOZ_FINAL
   : public nsIStartupCache
 {
   NS_DECL_ISUPPORTS
   NS_DECL_NSISTARTUPCACHE
 
   static StartupCacheWrapper* GetSingleton();
   static StartupCacheWrapper *gStartupCacheWrapper;
 };
--- a/toolkit/components/alerts/mac/nsAlertsImageLoadListener.h
+++ b/toolkit/components/alerts/mac/nsAlertsImageLoadListener.h
@@ -4,18 +4,19 @@
 
 #ifndef nsAlertsImageLoadListener_h_
 #define nsAlertsImageLoadListener_h_
 
 #import "mozGrowlDelegate.h"
 
 #include "nsIStreamLoader.h"
 #include "nsStringAPI.h"
+#include "mozilla/Attributes.h"
 
-class nsAlertsImageLoadListener : public nsIStreamLoaderObserver
+class nsAlertsImageLoadListener MOZ_FINAL : public nsIStreamLoaderObserver
 {
 public:
   nsAlertsImageLoadListener(const nsAString &aName,
                             const nsAString& aAlertTitle,
                             const nsAString& aAlertText,
                             const nsAString& aAlertCookie,
                             PRUint32 aAlertListenerKey);
 
--- a/toolkit/components/places/tests/cpp/places_test_harness.h
+++ b/toolkit/components/places/tests/cpp/places_test_harness.h
@@ -14,16 +14,17 @@
 #include "nsINavHistoryService.h"
 #include "nsIObserverService.h"
 #include "mozilla/IHistory.h"
 #include "mozIStorageConnection.h"
 #include "mozIStorageStatement.h"
 #include "nsPIPlacesDatabase.h"
 #include "nsIObserver.h"
 #include "prinrval.h"
+#include "mozilla/Attributes.h"
 
 #define TOPIC_FRECENCY_UPDATED "places-frecency-updated"
 #define WAITFORTOPIC_TIMEOUT_SECONDS 5
 
 using namespace mozilla;
 
 static size_t gTotalTests = 0;
 static size_t gPassedTests = 0;
@@ -90,17 +91,17 @@ void run_next_test();
  * To be used around asynchronous work.
  */
 void do_test_pending();
 void do_test_finished();
 
 /**
  * Spins current thread until a topic is received.
  */
-class WaitForTopicSpinner : public nsIObserver
+class WaitForTopicSpinner MOZ_FINAL : public nsIObserver
 {
 public:
   NS_DECL_ISUPPORTS
 
   WaitForTopicSpinner(const char* const aTopic)
   : mTopicReceived(false)
   , mStartTime(PR_IntervalNow())
   {
@@ -294,17 +295,17 @@ do_get_lastVisit(PRInt64 placeId, VisitR
   do_check_success(rv);
   rv = stmt->GetInt32(2, &result.transitionType);
   do_check_success(rv);
 }
 
 static const char TOPIC_PROFILE_CHANGE[] = "profile-before-change";
 static const char TOPIC_PLACES_CONNECTION_CLOSED[] = "places-connection-closed";
 
-class WaitForConnectionClosed : public nsIObserver
+class WaitForConnectionClosed MOZ_FINAL : public nsIObserver
 {
   nsRefPtr<WaitForTopicSpinner> mSpinner;
 public:
   NS_DECL_ISUPPORTS
 
   WaitForConnectionClosed()
   {
     nsCOMPtr<nsIObserverService> os =
--- a/toolkit/components/places/tests/cpp/test_IHistory.cpp
+++ b/toolkit/components/places/tests/cpp/test_IHistory.cpp
@@ -3,16 +3,17 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "places_test_harness.h"
 #include "nsIBrowserHistory.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
+#include "mozilla/Attributes.h"
 
 #include "mock_Link.h"
 using namespace mozilla::dom;
 
 /**
  * This file tests the IHistory interface.
  */
 
@@ -41,17 +42,17 @@ new_test_uri()
 
   // Create the URI for the spec.
   nsCOMPtr<nsIURI> testURI;
   nsresult rv = NS_NewURI(getter_AddRefs(testURI), spec);
   do_check_success(rv);
   return testURI.forget();
 }
 
-class VisitURIObserver : public nsIObserver
+class VisitURIObserver MOZ_FINAL : public nsIObserver
 {
 public:
   NS_DECL_ISUPPORTS
 
   VisitURIObserver(int aExpectedVisits = 1) :
     mVisits(0),
     mExpectedVisits(aExpectedVisits)
   {
@@ -277,17 +278,17 @@ test_RegisterVisitedCallback_returns_bef
 
   run_next_test();
 }
 
 namespace test_observer_topic_dispatched_helpers {
   #define URI_VISITED "visited"
   #define URI_NOT_VISITED "not visited"
   #define URI_VISITED_RESOLUTION_TOPIC "visited-status-resolution"
-  class statusObserver : public nsIObserver
+  class statusObserver MOZ_FINAL : public nsIObserver
   {
   public:
     NS_DECL_ISUPPORTS
 
     statusObserver(nsIURI* aURI,
                    const bool aExpectVisit,
                    bool& _notified)
     : mURI(aURI)
--- a/toolkit/components/social/Makefile.in
+++ b/toolkit/components/social/Makefile.in
@@ -7,15 +7,16 @@ topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 EXTRA_JS_MODULES = \
   FrameWorker.jsm \
   SocialService.jsm \
+  SocialProvider.jsm \
   $(NULL)
 
 TEST_DIRS += \
   test \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/toolkit/components/social/SocialProvider.jsm
@@ -0,0 +1,55 @@
+/* -*- Mode: JavaScript; tab-width: 2; 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/. */
+
+const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/FrameWorker.jsm");
+
+const EXPORTED_SYMBOLS = ["SocialProvider"];
+
+/**
+ * The SocialProvider object represents a social provider, and allows
+ * controlling its FrameWorker.
+ *
+ * @constructor
+ * @param {jsobj} object representing the manifest file describing this provider
+ */
+function SocialProvider(input) {
+  if (!input.name)
+    throw new Error("SocialProvider must be passed a name");
+  if (!input.workerURL)
+    throw new Error("SocialProvider must be passed a workerURL");
+  if (!input.origin)
+    throw new Error("SocialProvider must be passed an origin");
+
+  this.name = input.name;
+  this.workerURL = input.workerURL;
+  this.origin = input.origin;
+}
+
+SocialProvider.prototype = {
+  /**
+   * Terminate's the provider's FrameWorker, closing all of its ports.
+   */
+  terminate: function shutdown() {
+    try {
+      getFrameWorkerHandle(this.workerURL, null).terminate();
+    } catch (e) {
+      Cu.reportError("SocialProvider termination failed: " + e);
+    }
+  },
+
+  /**
+   * Instantiates a FrameWorker for the provider if one doesn't exist, and
+   * returns a reference to a port to that FrameWorker.
+   *
+   * @param {DOMWindow} window (optional)
+   */
+  getWorkerPort: function getWorkerPort(window) {
+    return getFrameWorkerHandle(this.workerURL, window).port;
+  }
+}
--- a/toolkit/components/social/SocialService.jsm
+++ b/toolkit/components/social/SocialService.jsm
@@ -1,39 +1,54 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 const EXPORTED_SYMBOLS = ["SocialService"];
 
 const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+
 Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/SocialProvider.jsm");
 
 const MANIFEST_PREFS = Services.prefs.getBranch("social.manifest.");
 
-const SocialService = {
+let SocialServiceInternal = {};
 
-  _init: function _init() {
-    let origins = MANIFEST_PREFS.getChildList("", {});
-    this._providers = origins.reduce(function (memo, origin) {
-      try {
-        var manifest = JSON.parse(MANIFEST_PREFS.getCharPref(origin));
+XPCOMUtils.defineLazyGetter(SocialServiceInternal, "providers", function () {
+  let providers = {};
+  let prefs = MANIFEST_PREFS.getChildList("", {});
+  prefs.forEach(function (pref) {
+    try {
+      var manifest = JSON.parse(MANIFEST_PREFS.getCharPref(pref));
+      if (manifest && typeof(manifest) == "object") {
+        let provider = new SocialProvider(manifest);
+        providers[provider.origin] = provider;
       }
-      catch (err) {}
-      if (manifest && typeof(manifest) == "object") {
-        memo[manifest.origin] = Object.create(manifest);
-      }
-      return memo;
-    }, {}, this);
+    } catch (err) {
+      Cu.reportError("SocialService: failed to load provider: " + pref +
+                     ", exception: " + err);
+    }
+  }, this);
+
+  return providers;
+});
+
+const SocialService = {
+  getProvider: function getProvider(origin, onDone) {
+    schedule((function () {
+      onDone(SocialServiceInternal.providers[origin] || null);
+    }).bind(this));
   },
 
-  getProvider: function getProvider(origin, onDone) {
+  // Returns an array of installed provider origins.
+  getProviderList: function getProviderList(onDone) {
+    let providers = [p for each (p in SocialServiceInternal.providers)];
     schedule((function () {
-      onDone(this._providers[origin] || null);
+      onDone(providers);
     }).bind(this));
-  },
+  }
 };
 
-SocialService._init();
-
 function schedule(callback) {
   Services.tm.mainThread.dispatch(callback, Ci.nsIThread.DISPATCH_NORMAL);
 }
--- a/toolkit/components/social/test/xpcshell/test_getProvider.js
+++ b/toolkit/components/social/test/xpcshell/test_getProvider.js
@@ -1,17 +1,18 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 function run_test() {
   let manifests = [0, 1, 2].map(function (i) {
     return {
-      origin: "http://example" + i + ".com",
       name: "provider " + i,
+      workerURL: "http://example" + i + ".com/worker.js",
+      origin: "http://example" + i + ".com"
     };
   });
   manifests.forEach(function (manifest) {
     MANIFEST_PREFS.setCharPref(manifest.origin, JSON.stringify(manifest));
   });
   do_register_cleanup(function () MANIFEST_PREFS.deleteBranch(""));
 
   Cu.import("resource://gre/modules/SocialService.jsm");
@@ -21,13 +22,14 @@ function run_test() {
   runner.next();
 }
 
 function test(manifests, next) {
   for (let i = 0; i < manifests.length; i++) {
     let manifest = manifests[i];
     let provider = yield SocialService.getProvider(manifest.origin, next);
     do_check_neq(provider, null);
+    do_check_eq(provider.name, manifest.name);
+    do_check_eq(provider.workerURL, manifest.workerURL);
     do_check_eq(provider.origin, manifest.origin);
-    do_check_eq(provider.name, manifest.name);
   }
   do_check_eq((yield SocialService.getProvider("bogus", next)), null);
 }
copy from toolkit/components/social/test/xpcshell/test_getProvider.js
copy to toolkit/components/social/test/xpcshell/test_getProviderList.js
--- a/toolkit/components/social/test/xpcshell/test_getProvider.js
+++ b/toolkit/components/social/test/xpcshell/test_getProviderList.js
@@ -1,33 +1,33 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 function run_test() {
   let manifests = [0, 1, 2].map(function (i) {
     return {
-      origin: "http://example" + i + ".com",
       name: "provider " + i,
+      workerURL: "http://example" + i + ".com/worker.js",
+      origin: "http://example" + i + ".com"
     };
   });
   manifests.forEach(function (manifest) {
     MANIFEST_PREFS.setCharPref(manifest.origin, JSON.stringify(manifest));
   });
   do_register_cleanup(function () MANIFEST_PREFS.deleteBranch(""));
 
   Cu.import("resource://gre/modules/SocialService.jsm");
 
   let runner = new AsyncRunner();
   runner.appendIterator(test(manifests, runner.next.bind(runner)));
   runner.next();
 }
 
 function test(manifests, next) {
+  let providers = yield SocialService.getProviderList(next);
+  do_check_true(providers.length >= 3);
   for (let i = 0; i < manifests.length; i++) {
-    let manifest = manifests[i];
-    let provider = yield SocialService.getProvider(manifest.origin, next);
-    do_check_neq(provider, null);
-    do_check_eq(provider.origin, manifest.origin);
-    do_check_eq(provider.name, manifest.name);
+    do_check_neq(providers.map(function (p) p.origin).indexOf(manifests[i].origin), -1);
+    do_check_neq(providers.map(function (p) p.workerURL).indexOf(manifests[i].workerURL), -1);
+    do_check_neq(providers.map(function (p) p.name).indexOf(manifests[i].name), -1);
   }
-  do_check_eq((yield SocialService.getProvider("bogus", next)), null);
 }
--- a/toolkit/components/social/test/xpcshell/xpcshell.ini
+++ b/toolkit/components/social/test/xpcshell/xpcshell.ini
@@ -1,5 +1,6 @@
 [DEFAULT]
 head = head.js
 tail =
 
 [test_getProvider.js]
+[test_getProviderList.js]
--- a/toolkit/profile/nsToolkitProfileService.cpp
+++ b/toolkit/profile/nsToolkitProfileService.cpp
@@ -32,20 +32,21 @@
 #include "nsXULAppAPI.h"
 
 #include "nsINIParser.h"
 #include "nsXREDirProvider.h"
 #include "nsAppRunner.h"
 #include "nsString.h"
 #include "nsReadableUtils.h"
 #include "nsNativeCharsetUtils.h"
+#include "mozilla/Attributes.h"
 
 using namespace mozilla;
 
-class nsToolkitProfile : public nsIToolkitProfile
+class nsToolkitProfile MOZ_FINAL : public nsIToolkitProfile
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSITOOLKITPROFILE
 
     friend class nsToolkitProfileService;
     nsCOMPtr<nsToolkitProfile> mNext;
     nsToolkitProfile          *mPrev;
@@ -63,17 +64,17 @@ private:
 
     nsCString                  mName;
     nsCOMPtr<nsIFile>          mRootDir;
     nsCOMPtr<nsIFile>          mLocalDir;
     nsIProfileLock*            mLock;
     bool                       mForExternalApp;
 };
 
-class nsToolkitProfileLock : public nsIProfileLock
+class nsToolkitProfileLock MOZ_FINAL : public nsIProfileLock
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIPROFILELOCK
 
     nsresult Init(nsToolkitProfile* aProfile, nsIProfileUnlocker* *aUnlocker);
     nsresult Init(nsIFile* aDirectory, nsIFile* aLocalDirectory,
                   nsIProfileUnlocker* *aUnlocker);
@@ -84,24 +85,24 @@ public:
 private:
     nsCOMPtr<nsToolkitProfile> mProfile;
     nsCOMPtr<nsIFile> mDirectory;
     nsCOMPtr<nsIFile> mLocalDirectory;
 
     nsProfileLock mLock;
 };
 
-class nsToolkitProfileFactory : public nsIFactory
+class nsToolkitProfileFactory MOZ_FINAL : public nsIFactory
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIFACTORY
 };
 
-class nsToolkitProfileService : public nsIToolkitProfileService
+class nsToolkitProfileService MOZ_FINAL : public nsIToolkitProfileService
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSITOOLKITPROFILESERVICE
 
 private:
     friend class nsToolkitProfile;
     friend class nsToolkitProfileFactory;
@@ -137,17 +138,17 @@ private:
     nsCOMPtr<nsIFile>           mTempData;
     nsCOMPtr<nsIFile>           mListFile;
     bool mDirty;
     bool mStartWithLast;
     bool mStartOffline;
 
     static nsToolkitProfileService *gService;
 
-    class ProfileEnumerator : public nsISimpleEnumerator
+    class ProfileEnumerator MOZ_FINAL : public nsISimpleEnumerator
     {
     public:
         NS_DECL_ISUPPORTS
         NS_DECL_NSISIMPLEENUMERATOR
 
         ProfileEnumerator(nsToolkitProfile *first)
           { mCurrent = first; }
     private:
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -19,16 +19,17 @@
 #include <QInputContext>
 #endif
 #endif // MOZ_WIDGET_QT
 
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/ContentChild.h"
 
 #include "mozilla/Util.h"
+#include "mozilla/Attributes.h"
 
 #include "nsAppRunner.h"
 #include "mozilla/AppData.h"
 #include "nsUpdateDriver.h"
 #include "ProfileReset.h"
 
 #ifdef MOZ_INSTRUMENT_EVENT_LOOP
 #include "EventTracer.h"
@@ -1175,17 +1176,17 @@ ScopedXPCOMStartup::Initialize()
 
   return rv;
 }
 
 /**
  * This is a little factory class that serves as a singleton-service-factory
  * for the nativeappsupport object.
  */
-class nsSingletonFactory : public nsIFactory
+class nsSingletonFactory MOZ_FINAL : public nsIFactory
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIFACTORY
 
   nsSingletonFactory(nsISupports* aSingleton);
   ~nsSingletonFactory() { }
 
--- a/toolkit/xre/nsUpdateDriver.h
+++ b/toolkit/xre/nsUpdateDriver.h
@@ -8,16 +8,17 @@
 #define nsUpdateDriver_h__
 
 #include "nscore.h"
 #ifdef MOZ_UPDATER
 #include "nsIUpdateService.h"
 #include "nsIThread.h"
 #include "nsCOMPtr.h"
 #include "nsString.h"
+#include "mozilla/Attributes.h"
 #endif
 
 class nsIFile;
 
 #if defined(XP_WIN)
 #include <windows.h>
   typedef HANDLE     ProcessType;
 #elif defined(XP_MACOSX)
@@ -54,17 +55,17 @@ NS_HIDDEN_(nsresult) ProcessUpdates(nsIF
                                     bool restart = true,
                                     ProcessType *pid = nsnull);
 
 #ifdef MOZ_UPDATER
 // The implementation of the update processor handles the task of loading the
 // updater application in the background for applying an update.
 // XXX ehsan this is living in this file in order to make use of the existing
 // stuff here, we might want to move it elsewhere in the future.
-class nsUpdateProcessor : public nsIUpdateProcessor
+class nsUpdateProcessor MOZ_FINAL : public nsIUpdateProcessor
 {
 public:
   nsUpdateProcessor();
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIUPDATEPROCESSOR
 
 private:
--- a/toolkit/xre/nsXREDirProvider.cpp
+++ b/toolkit/xre/nsXREDirProvider.cpp
@@ -787,17 +787,17 @@ nsXREDirProvider::DoStartup()
     }
     mozilla::Telemetry::Accumulate(mozilla::Telemetry::SAFE_MODE_USAGE, mode);
 
     obsSvc->NotifyObservers(nsnull, "profile-initial-state", nsnull);
   }
   return NS_OK;
 }
 
-class ProfileChangeStatusImpl : public nsIProfileChangeStatus
+class ProfileChangeStatusImpl MOZ_FINAL : public nsIProfileChangeStatus
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIPROFILECHANGESTATUS
   ProfileChangeStatusImpl() { }
 private:
   ~ProfileChangeStatusImpl() { }
 };
--- a/toolkit/xre/nsXREDirProvider.h
+++ b/toolkit/xre/nsXREDirProvider.h
@@ -7,19 +7,20 @@
 #define _nsXREDirProvider_h__
 
 #include "nsIDirectoryService.h"
 #include "nsIProfileMigrator.h"
 #include "nsIFile.h"
 
 #include "nsCOMPtr.h"
 #include "nsCOMArray.h"
+#include "mozilla/Attributes.h"
 
-class nsXREDirProvider : public nsIDirectoryServiceProvider2,
-                         public nsIProfileStartup
+class nsXREDirProvider MOZ_FINAL : public nsIDirectoryServiceProvider2,
+                                   public nsIProfileStartup
 {
 public:
   // we use a custom isupports implementation (no refcount)
   NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
   NS_IMETHOD_(nsrefcnt) AddRef(void);
   NS_IMETHOD_(nsrefcnt) Release(void);
 
   NS_DECL_NSIDIRECTORYSERVICEPROVIDER
--- a/tools/profiler/TableTicker.cpp
+++ b/tools/profiler/TableTicker.cpp
@@ -300,16 +300,23 @@ public:
           break;
         case 'r':
           {
             if (sample) {
               b.DefineProperty(sample, "responsiveness", entry.mTagFloat);
             }
           }
           break;
+        case 't':
+          {
+            if (sample) {
+              b.DefineProperty(sample, "time", entry.mTagFloat);
+            }
+          }
+          break;
         case 'c':
         case 'l':
           {
             if (sample) {
               JSObject *frame = b.CreateObject();
               if (entry.mTagName == 'l') {
                 // Bug 753041
                 // We need a double cast here to tell GCC that we don't want to sign
@@ -357,16 +364,17 @@ hasFeature(const char** aFeatures, uint3
 }
 
 class TableTicker: public Sampler {
  public:
   TableTicker(int aInterval, int aEntrySize, ProfileStack *aStack,
               const char** aFeatures, uint32_t aFeatureCount)
     : Sampler(aInterval, true)
     , mPrimaryThreadProfile(aEntrySize, aStack)
+    , mStartTime(TimeStamp::Now())
     , mSaveRequested(false)
   {
     mUseStackWalk = hasFeature(aFeatures, aFeatureCount, "stackwalk");
 
     //XXX: It's probably worth splitting the jank profiler out from the regular profiler at some point
     mJankOnly = hasFeature(aFeatures, aFeatureCount, "jank");
     mPrimaryThreadProfile.addTag(ProfileEntry('m', "Start"));
   }
@@ -396,16 +404,17 @@ class TableTicker: public Sampler {
 
 private:
   // Not implemented on platforms which do not support backtracing
   void doBacktrace(ThreadProfile &aProfile, TickSample* aSample);
 
 private:
   // This represent the application's main thread (SAMPLER_INIT)
   ThreadProfile mPrimaryThreadProfile;
+  TimeStamp mStartTime;
   bool mSaveRequested;
   bool mUseStackWalk;
   bool mJankOnly;
 };
 
 std::string GetSharedLibraryInfoString();
 
 /**
@@ -760,20 +769,25 @@ void TableTicker::Tick(TickSample* sampl
   }
 #else
   doSampleStackTrace(stack, mPrimaryThreadProfile, sample);
 #endif
 
   if (recordSample)
     mPrimaryThreadProfile.flush();
 
-  if (!mJankOnly && !sLastTracerEvent.IsNull() && sample) {
+  if (!sLastTracerEvent.IsNull() && sample) {
     TimeDuration delta = sample->timestamp - sLastTracerEvent;
     mPrimaryThreadProfile.addTag(ProfileEntry('r', delta.ToMilliseconds()));
   }
+
+  if (sample) {
+    TimeDuration delta = sample->timestamp - mStartTime;
+    mPrimaryThreadProfile.addTag(ProfileEntry('t', delta.ToMilliseconds()));
+  }
 }
 
 std::ostream& operator<<(std::ostream& stream, const ThreadProfile& profile)
 {
   int readPos = profile.mReadPos;
   while (readPos != profile.mLastFlushPos) {
     stream << profile.mEntries[readPos];
     readPos = (readPos + 1) % profile.mEntrySize;
--- a/tools/profiler/sampler.h
+++ b/tools/profiler/sampler.h
@@ -37,16 +37,17 @@
  *         'l-<library name>@<hex address>' and will expect an external tool to translate
  *         the tag into something readable through a symbolication processing step.
  * 'm' - Timeline marker. Zero or more may appear before a 's' tag.
  * 'l' - Information about the program counter library and address. Post processing
  *         can include function and source line. If built with leaf data enabled
  *         this tag will describe the last 'c' tag.
  * 'r' - Responsiveness tag following an 's' tag. Gives an indication on how well the
  *          application is responding to the event loop. Lower is better.
+ * 't' - Elapse time since recording started.
  *
  * NOTE: File format is planned to be extended to include a dictionary to reduce size.
  */
 
 #ifndef SAMPLER_H
 #define SAMPLER_H
 
 // Redefine the macros for platforms where SPS is supported.
--- a/xpcom/glue/nsCOMPtr.cpp
+++ b/xpcom/glue/nsCOMPtr.cpp
@@ -36,23 +36,16 @@ nsQueryInterfaceWithError::operator()( c
 		else
 			status = NS_ERROR_NULL_POINTER;
 		
 		if ( mErrorPtr )
 			*mErrorPtr = status;
 		return status;
 	}
 
-nsCOMPtr_base::~nsCOMPtr_base()
-	{
-	  NSCAP_LOG_RELEASE(this, mRawPtr);
-		if ( mRawPtr )
-			NSCAP_RELEASE(this, mRawPtr);
-	}
-
 void
 nsCOMPtr_base::assign_with_AddRef( nsISupports* rawPtr )
 	{
     if ( rawPtr )
     	NSCAP_ADDREF(this, rawPtr);
     assign_assuming_AddRef(rawPtr);
 	}
 
--- a/xpcom/glue/nsCOMPtr.h
+++ b/xpcom/glue/nsCOMPtr.h
@@ -396,17 +396,22 @@ nsCOMPtr_base
     public:
 
       nsCOMPtr_base( nsISupports* rawPtr = 0 )
           : mRawPtr(rawPtr)
         {
           // nothing else to do here
         }
 
-      NS_COM_GLUE NS_CONSTRUCTOR_FASTCALL ~nsCOMPtr_base();
+      NS_COM_GLUE ~nsCOMPtr_base()
+        {
+          NSCAP_LOG_RELEASE(this, mRawPtr);
+            if ( mRawPtr )
+              NSCAP_RELEASE(this, mRawPtr);
+        }
 
       NS_COM_GLUE void NS_FASTCALL   assign_with_AddRef( nsISupports* );
       NS_COM_GLUE void NS_FASTCALL   assign_from_qi( const nsQueryInterface, const nsIID& );
       NS_COM_GLUE void NS_FASTCALL   assign_from_qi_with_error( const nsQueryInterfaceWithError&, const nsIID& );
       NS_COM_GLUE void NS_FASTCALL   assign_from_gs_cid( const nsGetServiceByCID, const nsIID& );
       NS_COM_GLUE void NS_FASTCALL   assign_from_gs_cid_with_error( const nsGetServiceByCIDWithError&, const nsIID& );
       NS_COM_GLUE void NS_FASTCALL   assign_from_gs_contractid( const nsGetServiceByContractID, const nsIID& );
       NS_COM_GLUE void NS_FASTCALL   assign_from_gs_contractid_with_error( const nsGetServiceByContractIDWithError&, const nsIID& );
--- a/xpcom/sample/nsSample.h
+++ b/xpcom/sample/nsSample.h
@@ -5,16 +5,17 @@
 
 /**
  * A sample of XPConnect. This file is the header of an implementation
  * nsSample of the nsISample interface.
  *
  */
 
 #include "nsISample.h"
+#include "mozilla/Attributes.h"
 
 /**
  * SampleImpl is an implementation of the nsISample interface.  In XPCOM,
  * there can be more than one implementation of an given interface.  Class
  * IDs (CIDs) uniquely identify a particular implementation of an interface.
  * Interface IDs (IIDs) uniquely identify an interface.
  *
  * The CID is also a unique number that looks just like an IID
@@ -23,17 +24,17 @@
  */
 
 #define NS_SAMPLE_CID \
 { 0x7cb5b7a0, 0x7d7, 0x11d3, { 0xbd, 0xe2, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }
 
 #define NS_SAMPLE_CONTRACTID "@mozilla.org/sample;1"
 
 
-class nsSampleImpl : public nsISample
+class nsSampleImpl MOZ_FINAL : public nsISample
 {
 public:
     nsSampleImpl();
 
     /**
      * This macro expands into a declaration of the nsISupports interface.
      * Every XPCOM component needs to implement nsISupports, as it acts
      * as the gateway to other interfaces this component implements.  You
--- a/xpcom/tests/TestAutoPtr.cpp
+++ b/xpcom/tests/TestAutoPtr.cpp
@@ -2,16 +2,17 @@
 // vim:cindent:ts=4:et:sw=4:
 /* 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 "nsAutoPtr.h"
 #include <stdio.h>
 #include "nscore.h"
+#include "mozilla/Attributes.h"
 
 class TestObjectBaseA {
     public:
         // Virtual dtor for deleting through base class pointer
         virtual ~TestObjectBaseA() { };
         int fooA;
 };
 
@@ -48,17 +49,17 @@ class TestRefObjectBaseA {
 
 class TestRefObjectBaseB {
     public:
         int fooB;
         virtual nsrefcnt AddRef() = 0;
         virtual nsrefcnt Release() = 0;
 };
 
-class TestRefObject : public TestRefObjectBaseA, public TestRefObjectBaseB {
+class TestRefObject MOZ_FINAL : public TestRefObjectBaseA, public TestRefObjectBaseB {
     public:
         TestRefObject()
             : mRefCount(0)
         {
             printf("  Creating TestRefObject %p.\n",
                    static_cast<void*>(this));
         }
 
--- a/xpcom/tests/TestCOMArray.cpp
+++ b/xpcom/tests/TestCOMArray.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 // vim:cindent:ts=4:et:sw=4:
 /* 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 "TestHarness.h"
 #include "nsCOMArray.h"
+#include "mozilla/Attributes.h"
 
 // {9e70a320-be02-11d1-8031-006008159b5a}
 #define NS_IFOO_IID \
   {0x9e70a320, 0xbe02, 0x11d1,    \
     {0x80, 0x31, 0x00, 0x60, 0x08, 0x15, 0x9b, 0x5a}}
 
 class IFoo : public nsISupports {
 public:
@@ -18,17 +19,17 @@ public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IFOO_IID)
 
   NS_IMETHOD_(nsrefcnt) RefCnt() = 0;
   NS_IMETHOD_(PRInt32) ID() = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(IFoo, NS_IFOO_IID)
 
-class Foo : public IFoo {
+class Foo MOZ_FINAL : public IFoo {
 public:
 
   Foo(PRInt32 aID);
   ~Foo();
 
   // nsISupports implementation
   NS_DECL_ISUPPORTS
 
@@ -68,17 +69,17 @@ typedef nsCOMArray<IFoo> Array;
 class IBar : public nsISupports {
 public:
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IBAR_IID)
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(IBar, NS_IBAR_IID)
 
-class Bar : public IBar {
+class Bar MOZ_FINAL : public IBar {
 public:
 
   explicit Bar(nsCOMArray<IBar>& aArray);
   ~Bar();
 
   // nsISupports implementation
   NS_DECL_ISUPPORTS
 
--- a/xpcom/tests/TestCallTemplates.cpp
+++ b/xpcom/tests/TestCallTemplates.cpp
@@ -15,29 +15,31 @@
 #include "nsIComponentManager.h"
 #include "nsIServiceManager.h"
 #include "nsWeakReference.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsComponentManagerUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "nsAutoPtr.h"
+#include "mozilla/Attributes.h"
 
 #define NS_ITESTSERVICE_IID \
   {0x127b5253, 0x37b1, 0x43c7, \
     { 0x96, 0x2b, 0xab, 0xf1, 0x2d, 0x22, 0x56, 0xae }}
 
 class NS_NO_VTABLE nsITestService : public nsISupports {
   public: 
     NS_DECLARE_STATIC_IID_ACCESSOR(NS_ITESTSERVICE_IID)
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsITestService, NS_ITESTSERVICE_IID)
 
-class nsTestService : public nsITestService, public nsSupportsWeakReference
+class nsTestService MOZ_FINAL : public nsITestService,
+                                public nsSupportsWeakReference
 {
   public:
     NS_DECL_ISUPPORTS
 };
 
 NS_IMPL_ISUPPORTS2(nsTestService, nsITestService, nsISupportsWeakReference)
 
 #define NS_TEST_SERVICE_CONTRACTID "@mozilla.org/test/testservice;1"
--- a/xpcom/tests/TestHashtables.cpp
+++ b/xpcom/tests/TestHashtables.cpp
@@ -7,16 +7,17 @@
 #include "nsBaseHashtable.h"
 #include "nsDataHashtable.h"
 #include "nsInterfaceHashtable.h"
 #include "nsClassHashtable.h"
 
 #include "nsCOMPtr.h"
 #include "nsISupports.h"
 #include "nsCOMArray.h"
+#include "mozilla/Attributes.h"
 
 #include <stdio.h>
 
 namespace TestHashtables {
 
 class TestUniChar // for nsClassHashtable
 {
 public:
@@ -186,17 +187,17 @@ nsCEnum(const nsACString& aKey, nsAutoPt
 //
 // all this nsIFoo stuff was copied wholesale from TestCOMPtr.cpp
 //
 
 #define NS_IFOO_IID \
 { 0x6f7652e0,  0xee43, 0x11d1, \
  { 0x9c, 0xc3, 0x00, 0x60, 0x08, 0x8c, 0xa6, 0xb3 } }
 
-class IFoo : public nsISupports
+class IFoo MOZ_FINAL : public nsISupports
   {
     public:
       NS_DECLARE_STATIC_IID_ACCESSOR(NS_IFOO_IID)
 
       IFoo();
 
       NS_IMETHOD_(nsrefcnt) AddRef();
       NS_IMETHOD_(nsrefcnt) Release();
--- a/xpcom/tests/TestObserverService.cpp
+++ b/xpcom/tests/TestObserverService.cpp
@@ -6,16 +6,17 @@
 #include "nsISupports.h"
 #include "nsIComponentManager.h"
 #include "nsIObserverService.h"
 #include "nsIObserver.h"
 #include "nsIEnumerator.h"
 #include "nsStringGlue.h"
 #include "nsWeakReference.h"
 #include "nsComponentManagerUtils.h"
+#include "mozilla/Attributes.h"
 
 #include <stdio.h>
 
 static nsIObserverService *anObserverService = NULL;
 
 static void testResult( nsresult rv ) {
     if ( NS_SUCCEEDED( rv ) ) {
         printf("...ok\n");
@@ -24,17 +25,19 @@ static void testResult( nsresult rv ) {
     }
     return;
 }
 
 void printString(nsString &str) {
     printf("%s", NS_ConvertUTF16toUTF8(str).get());
 }
 
-class TestObserver : public nsIObserver, public nsSupportsWeakReference {
+class TestObserver MOZ_FINAL : public nsIObserver,
+                               public nsSupportsWeakReference
+{
 public:
     TestObserver( const nsAString &name )
         : mName( name ) {
     }
     NS_DECL_ISUPPORTS
     NS_DECL_NSIOBSERVER
 
     nsString mName;
--- a/xpcom/tests/TestPipe.cpp
+++ b/xpcom/tests/TestPipe.cpp
@@ -2,16 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "TestHarness.h"
 
 #include "nsIPipe.h"
 #include "nsIMemory.h"
+#include "mozilla/Attributes.h"
 
 /** NS_NewPipe2 reimplemented, because it's not exported by XPCOM */
 nsresult TP_NewPipe2(nsIAsyncInputStream** input,
                      nsIAsyncOutputStream** output,
                      bool nonBlockingInput,
                      bool nonBlockingOutput,
                      PRUint32 segmentSize,
                      PRUint32 segmentCount,
@@ -36,17 +37,17 @@ nsresult TP_NewPipe2(nsIAsyncInputStream
 }
 
 /**
  * Allocator can allocate exactly count * size bytes, stored at mMemory;
  * immediately after the end of this is a byte-map of 0/1 values indicating
  * which <size>-byte locations in mMemory are empty and which are filled.
  * Pretty stupid, but enough to test bug 394692.
  */
-class BackwardsAllocator : public nsIMemory
+class BackwardsAllocator MOZ_FINAL : public nsIMemory
 {
   public:
     BackwardsAllocator()
       : mMemory(0),
         mIndex(0xFFFFFFFF),
         mCount(0xFFFFFFFF),
         mSize(0)
     { }
--- a/xpcom/tests/TestRacingServiceManager.cpp
+++ b/xpcom/tests/TestRacingServiceManager.cpp
@@ -10,16 +10,17 @@
 #include "nsXULAppAPI.h"
 #include "nsIThread.h"
 #include "nsIComponentRegistrar.h"
 
 #include "nsAutoPtr.h"
 #include "nsThreadUtils.h"
 #include "nsXPCOMCIDInternal.h"
 #include "prmon.h"
+#include "mozilla/Attributes.h"
 
 #include "mozilla/ReentrantMonitor.h"
 using namespace mozilla;
 
 #ifdef DEBUG
 #define TEST_ASSERTION(_test, _msg) \
     NS_ASSERTION(_test, _msg);
 #else
@@ -78,17 +79,17 @@ public:
       *mReentrantMonitorPtr = nsnull;
     }
   }
 
 private:
   ReentrantMonitor** mReentrantMonitorPtr;
 };
 
-class Factory : public nsIFactory
+class Factory MOZ_FINAL : public nsIFactory
 {
 public:
   NS_DECL_ISUPPORTS
 
   Factory() : mFirstComponentCreated(false) { }
 
   NS_IMETHOD CreateInstance(nsISupports* aDelegate,
                             const nsIID& aIID,
@@ -98,17 +99,17 @@ public:
     return NS_OK;
   }
 
   bool mFirstComponentCreated;
 };
 
 NS_IMPL_THREADSAFE_ISUPPORTS1(Factory, nsIFactory)
 
-class Component1 : public nsISupports
+class Component1 MOZ_FINAL : public nsISupports
 {
 public:
   NS_DECL_ISUPPORTS
 
   Component1() {
     // This is the real test - make sure that only one instance is ever created.
     PRInt32 count = PR_AtomicIncrement(&gComponent1Count);
     TEST_ASSERTION(count == 1, "Too many components created!");
@@ -118,17 +119,17 @@ public:
 NS_IMPL_THREADSAFE_ADDREF(Component1)
 NS_IMPL_THREADSAFE_RELEASE(Component1)
 
 NS_INTERFACE_MAP_BEGIN(Component1)
   NS_INTERFACE_MAP_ENTRY(Component1)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
-class Component2 : public nsISupports
+class Component2 MOZ_FINAL : public nsISupports
 {
 public:
   NS_DECL_ISUPPORTS
 
   Component2() {
     // This is the real test - make sure that only one instance is ever created.
     PRInt32 count = PR_AtomicIncrement(&gComponent2Count);
     TEST_ASSERTION(count == 1, "Too many components created!");
--- a/xpcom/tests/TestThreadPoolListener.cpp
+++ b/xpcom/tests/TestThreadPoolListener.cpp
@@ -9,16 +9,17 @@
 #include "nsIThreadPool.h"
 
 #include "nsThreadUtils.h"
 #include "nsXPCOMCIDInternal.h"
 #include "pratom.h"
 #include "prinrval.h"
 #include "prmon.h"
 #include "prthread.h"
+#include "mozilla/Attributes.h"
 
 #include "mozilla/ReentrantMonitor.h"
 using namespace mozilla;
 
 #define NUMBER_OF_THREADS 4
 
 // One hour... because test boxes can be slow!
 #define IDLE_THREAD_TIMEOUT 3600000
@@ -39,17 +40,17 @@ static bool gAllThreadsShutDown = false;
 #define TEST_ASSERTION(_test, _msg) \
   PR_BEGIN_MACRO \
     if (!(_test)) { \
       NS_DebugBreak(NS_DEBUG_ABORT, _msg, #_test, __FILE__, __LINE__); \
     } \
   PR_END_MACRO
 #endif
 
-class Listener : public nsIThreadPoolListener
+class Listener MOZ_FINAL : public nsIThreadPoolListener
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSITHREADPOOLLISTENER
 };
 
 NS_IMPL_THREADSAFE_ISUPPORTS1(Listener, nsIThreadPoolListener)
 
--- a/xpcom/tests/TestTimers.cpp
+++ b/xpcom/tests/TestTimers.cpp
@@ -9,16 +9,17 @@
 #include "nsITimer.h"
 
 #include "nsCOMPtr.h"
 #include "nsComponentManagerUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 #include "prinrval.h"
 #include "prmon.h"
+#include "mozilla/Attributes.h"
 
 #include "mozilla/ReentrantMonitor.h"
 using namespace mozilla;
 
 typedef nsresult(*TestFuncPtr)();
 
 class AutoTestThread
 {
@@ -63,17 +64,17 @@ public:
   operator ReentrantMonitor* () {
     return mReentrantMonitor;
   }
 
 private:
   ReentrantMonitor* mReentrantMonitor;
 };
 
-class TimerCallback : public nsITimerCallback
+class TimerCallback MOZ_FINAL : public nsITimerCallback
 {
 public:
   NS_DECL_ISUPPORTS
 
   TimerCallback(nsIThread** aThreadPtr, ReentrantMonitor* aReentrantMonitor)
   : mThreadPtr(aThreadPtr), mReentrantMonitor(aReentrantMonitor) { }
 
   NS_IMETHOD Notify(nsITimer* aTimer) {