Merge mozilla-central into mozilla-inbound, but DONTBUILD since this all NPOTB stuff
authorEhsan Akhgari <ehsan@mozilla.com>
Wed, 05 Dec 2012 15:01:59 -0500
changeset 115109 77d88ac7bb306d2e47bb014f71e36c0d561736c5
parent 115108 e1cdd4d430ca8554ae606206219eccfe9dbabf7e (current diff)
parent 115049 277998cf11cd918674390a85395eaa09278cf978 (diff)
child 115110 af1833fbace89fa7d52c1c719ffad7e29551d4a8
push id23973
push useremorley@mozilla.com
push dateThu, 06 Dec 2012 10:04:18 +0000
treeherdermozilla-central@ddda5400c826 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone20.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-central into mozilla-inbound, but DONTBUILD since this all NPOTB stuff
browser/themes/gnomestripe/browser.css
browser/themes/winstripe/browser.css
new file mode 120000
--- /dev/null
+++ b/b2g/config/panda-gaia-central/README
@@ -0,0 +1,1 @@
+../panda/README
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/b2g/config/panda-gaia-central/config.json
@@ -0,0 +1,24 @@
+{
+    "config_version": 1,
+    "tooltool_manifest": "releng-pandaboard.tt",
+    "mock_target": "mozilla-centos6-i386",
+    "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel"],
+    "mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
+    "build_targets": ["boottarball", "systemtarball", "userdatatarball"],
+    "upload_files": [
+        "{workdir}/out/target/product/panda/*.tar.bz2",
+        "{objdir}/dist/b2g-update/*.mar",
+        "{objdir}/dist/b2g-*.tar.gz",
+        "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
+        "{srcdir}/b2g/config/panda/README",
+        "{workdir}/sources.xml"
+    ],
+    "gaia": {
+        "vcs": "hgtool",
+        "repo": "http://hg.mozilla.org/integration/gaia-central",
+        "l10n": {
+            "vcs": "hgtool",
+            "root": "http://hg.mozilla.org/gaia-l10n"
+        }
+    }
+}
new file mode 120000
--- /dev/null
+++ b/b2g/config/panda-gaia-central/releng-pandaboard.tt
@@ -0,0 +1,1 @@
+../panda/releng-pandaboard.tt
\ No newline at end of file
new file mode 120000
--- /dev/null
+++ b/b2g/config/panda-gaia-central/sources.xml
@@ -0,0 +1,1 @@
+../panda/sources.xml
\ No newline at end of file
--- a/browser/base/content/browser-appmenu.inc
+++ b/browser/base/content/browser-appmenu.inc
@@ -22,30 +22,30 @@
             <menuitem id="appmenu_newTab_popup"
                       label="&tabCmd.label;"
                       command="cmd_newNavigatorTab"
                       key="key_newNavigatorTab"/>
             <menuitem id="appmenu_newNavigator"
                       label="&newNavigatorCmd.label;"
                       command="cmd_newNavigator"
                       key="key_newNavigator"/>
-#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
-            <menuitem id="appmenu_newPrivateWindow"
-                      label="&newPrivateWindow.label;"
-                      command="Tools:PrivateBrowsing"
-                      key="key_privatebrowsing"/>
-#endif
             <menuseparator/>
             <menuitem id="appmenu_openFile"
                       label="&openFileCmd.label;"
                       command="Browser:OpenFile"
                       key="openFileKb"/>
           </menupopup>
       </splitmenu>
-#ifndef MOZ_PER_WINDOW_PRIVATE_BROWSING
+#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
+      <menuitem id="appmenu_newPrivateWindow"
+                class="menuitem-iconic menuitem-iconic-tooltip"
+                label="&newPrivateWindow.label;"
+                command="Tools:PrivateBrowsing"
+                key="key_privatebrowsing"/>
+#else
       <menuitem id="appmenu_privateBrowsing"
                 class="menuitem-iconic menuitem-iconic-tooltip"
                 label="&privateBrowsingCmd.start.label;"
                 startlabel="&privateBrowsingCmd.start.label;"
                 stoplabel="&privateBrowsingCmd.stop.label;"
                 command="Tools:PrivateBrowsing"
                 key="key_privatebrowsing"/>
 #endif
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -246,17 +246,16 @@ endif
                  plugin_clickToPlayDeny.html \
                  plugin_bug749455.html \
                  plugin_bug797677.html \
                  plugin_hidden_to_visible.html \
                  plugin_two_types.html \
                  alltabslistener.html \
                  zoom_test.html \
                  dummy_page.html \
-                 browser_tabMatchesInAwesomebar.js \
                  file_bug550565_popup.html \
                  file_bug550565_favicon.ico \
                  browser_aboutHome.js \
                  app_bug575561.html \
                  app_subframe_bug575561.html \
                  browser_contentAreaClick.js \
                  browser_addon_bar_close_button.js \
                  browser_addon_bar_shortcut.js \
@@ -313,22 +312,24 @@ endif
 ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
 _BROWSER_FILES += \
                 browser_bug763468_perwindowpb.js \
                 browser_bug767836_perwindowpb.js \
                 browser_bug816527.js \
                 browser_private_browsing_window.js \
                 browser_save_link-perwindowpb.js \
                 browser_save_private_link_perwindowpb.js \
+                browser_tabMatchesInAwesomebar_perwindowpb.js \
                 $(NULL)
 else
 _BROWSER_FILES += \
                 browser_bug763468.js \
                 browser_bug767836.js \
                 browser_save_link.js \
                 browser_save_private_link.js \
+                browser_tabMatchesInAwesomebar.js \
                 $(NULL)
 endif
 
 include $(topsrcdir)/config/rules.mk
 
 libs::	$(_BROWSER_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
--- a/browser/base/content/test/browser_bug816527.js
+++ b/browser/base/content/test/browser_bug816527.js
@@ -13,43 +13,43 @@ function test() {
       // web pages on the test. If calling executeSoon() is not necesary, then
       // call whenNewWindowLoaded() instead of testOnWindow() on your test.
       executeSoon(function() aCallback(aWin));
     });
   };
 
   testOnWindow({}, function(aNormalWindow) {
     testOnWindow({private: true}, function(aPrivateWindow) {
-      runTest(aNormalWindow, aPrivateWindow, function() {
+      runTest(aNormalWindow, aPrivateWindow, false, function() {
         aNormalWindow.close();
         aPrivateWindow.close();
         testOnWindow({}, function(aNormalWindow) {
           testOnWindow({private: true}, function(aPrivateWindow) {
-            runTest(aPrivateWindow, aNormalWindow, function() {
+            runTest(aPrivateWindow, aNormalWindow, false, function() {
               aNormalWindow.close();
               aPrivateWindow.close();
               testOnWindow({private: true}, function(aPrivateWindow) {
-                runTest(aPrivateWindow, aPrivateWindow, function() {
+                runTest(aPrivateWindow, aPrivateWindow, false, function() {
                   aPrivateWindow.close();
                   testOnWindow({}, function(aNormalWindow) {
-                    runTest(aNormalWindow, aNormalWindow, function() {
+                    runTest(aNormalWindow, aNormalWindow, true, function() {
                       aNormalWindow.close();
                       finish();
                     });
                   });
                 });
               });
             });
           });
         });
       });
     });
   });
 
-  function runTest(aSourceWindow, aDestWindow, aCallback) {
+  function runTest(aSourceWindow, aDestWindow, aExpectSuccess, aCallback) {
     // Open the base tab
     let baseTab = aSourceWindow.gBrowser.addTab(testURL);
     baseTab.linkedBrowser.addEventListener("load", function() {
       // Wait for the tab to be fully loaded so matching happens correctly
       if (baseTab.linkedBrowser.currentURI.spec == "about:blank")
         return;
       baseTab.linkedBrowser.removeEventListener("load", arguments.callee, true);
 
@@ -86,31 +86,35 @@ function test() {
         // The reason that we can't avoid the timeout here is because we are
         // trying to test something which should not happen, so we just need
         // to wait for a while and then check whether any bad things have
         // happened.
 
         function onTabClose(aEvent) {
           aDestWindow.gBrowser.tabContainer.removeEventListener("TabClose", onTabClose, false);
           aDestWindow.gBrowser.removeEventListener("load", onLoad, false);
+          clearTimeout(timeout);
           // Should only happen when we expect success
-          ok(false, "Tab closed as expected");
+          ok(aExpectSuccess, "Tab closed as expected");
           aCallback();
         }
         function onLoad(aEvent) {
           aDestWindow.gBrowser.tabContainer.removeEventListener("TabClose", onTabClose, false);
           aDestWindow.gBrowser.removeEventListener("load", onLoad, false);
+          clearTimeout(timeout);
           // Should only happen when we expect success
-          ok(false, "Tab loaded as expected");
+          ok(aExpectSuccess, "Tab loaded as expected");
           aCallback();
         }
 
         aDestWindow.gBrowser.tabContainer.addEventListener("TabClose", onTabClose, false);
         aDestWindow.gBrowser.addEventListener("load", onLoad, false);
-        setTimeout(function() {
+        let timeout = setTimeout(function() {
+          aDestWindow.gBrowser.tabContainer.removeEventListener("TabClose", onTabClose, false);
+          aDestWindow.gBrowser.removeEventListener("load", onLoad, false);
           aCallback();
         }, 500);
 
         // Press enter!
         EventUtils.synthesizeKey("VK_RETURN", {});
       }, aDestWindow);
     }, true);
   }
copy from browser/base/content/test/browser_tabMatchesInAwesomebar.js
copy to browser/base/content/test/browser_tabMatchesInAwesomebar_perwindowpb.js
--- a/browser/base/content/test/browser_tabMatchesInAwesomebar.js
+++ b/browser/base/content/test/browser_tabMatchesInAwesomebar_perwindowpb.js
@@ -4,18 +4,16 @@
  * 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 TEST_URL_BASES = [
   "http://example.org/browser/browser/base/content/test/dummy_page.html#tabmatch",
   "http://example.org/browser/browser/base/content/test/moz.png#tabmatch"
 ];
 
-var gPrivateBrowsing = Cc["@mozilla.org/privatebrowsing;1"].
-                         getService(Ci.nsIPrivateBrowsingService);
 var gController = Cc["@mozilla.org/autocomplete/controller;1"].
                   getService(Ci.nsIAutoCompleteController);
 
 var gTabWaitCount = 0;
 var gTabCounter = 0;
 
 var gTestSteps = [
   function() {
@@ -35,126 +33,53 @@ var gTestSteps = [
       loadTab(gBrowser.tabs[i], TEST_URL_BASES[1] + (++gTabCounter));
   },
   function() {
     info("Running step 3");
     for (let i = 1; i < gBrowser.tabs.length; i++)
       loadTab(gBrowser.tabs[i], TEST_URL_BASES[0] + gTabCounter);
   },
   function() {
-    info("Running step 4");
-    let ps = Services.prefs;
-    ps.setBoolPref("browser.privatebrowsing.keep_current_session", true);
-    ps.setBoolPref("browser.tabs.warnOnClose", false);
-
-    // Make sure that all restored tabs are loaded without waiting for the user
-    // to bring them to the foreground. We ensure this by resetting the
-    // related preference (see the "firefox.js" defaults file for details).
-    ps.setBoolPref("browser.sessionstore.restore_on_demand", false);
-
-    gPrivateBrowsing.privateBrowsingEnabled = true;
-
-    executeSoon(function() {
-      ensure_opentabs_match_db(nextStep);
-    });
-  },
-  function() {
-    info("Running step 5");
-    gPrivateBrowsing.privateBrowsingEnabled = false;
-
-    executeSoon(function() {
-      let ps = Services.prefs;
-      ps.clearUserPref("browser.privatebrowsing.keep_current_session");
-      ps.clearUserPref("browser.tabs.warnOnClose");
-
-      ensure_opentabs_match_db(nextStep);
-    });
-  },
-  function() {
-    info("Running step 6 - ensure we don't register subframes as open pages");
+    info("Running step 4 - ensure we don't register subframes as open pages");
     let tab = gBrowser.addTab();
     tab.linkedBrowser.addEventListener("load", function () {
       tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
       // Start the sub-document load.
       executeSoon(function () {
         tab.linkedBrowser.addEventListener("load", function (e) {
           tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
             ensure_opentabs_match_db(nextStep);
         }, true);
         tab.linkedBrowser.contentDocument.querySelector("iframe").src = "http://test2.example.org/";
       });
     }, true);
     tab.linkedBrowser.loadURI('data:text/html,<body><iframe src=""></iframe></body>');
   },
   function() {
-    info("Running step 7 - remove tab immediately");
+    info("Running step 5 - remove tab immediately");
     let tab = gBrowser.addTab("about:logo");
     gBrowser.removeTab(tab);
     ensure_opentabs_match_db(nextStep);
   },
   function() {
-    info("Running step 8 - check swapBrowsersAndCloseOther preserves registered switch-to-tab result");
+    info("Running step 6 - check swapBrowsersAndCloseOther preserves registered switch-to-tab result");
     let tabToKeep = gBrowser.addTab();
     let tab = gBrowser.addTab();
     tab.linkedBrowser.addEventListener("load", function () {
       tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
       gBrowser.swapBrowsersAndCloseOther(tabToKeep, tab);
       ensure_opentabs_match_db(function () {
         gBrowser.removeTab(tabToKeep);
         ensure_opentabs_match_db(nextStep);
       });
     }, true);
     tab.linkedBrowser.loadURI("about:mozilla");
   },
   function() {
-    info("Running step 9 - enter private browsing mode, without keeping session");
-    let ps = Services.prefs;
-    ps.setBoolPref("browser.privatebrowsing.keep_current_session", false);
-    ps.setBoolPref("browser.tabs.warnOnClose", false);
-
-    Services.obs.addObserver(function(aSubject, aTopic, aData) {
-      Services.obs.removeObserver(arguments.callee, "private-browsing-transition-complete");
-
-      for (let i = 0; i < gBrowser.tabs.length; i++)
-        waitForRestoredTab(gBrowser.tabs[i]);
-    }, "private-browsing-transition-complete", false);
-
-    gPrivateBrowsing.privateBrowsingEnabled = true;
-  },
-  function() {
-    info("Running step 10 - open tabs in private browsing mode");
-    for (let i = 0; i < 3; i++) {
-      let tab = gBrowser.addTab();
-      loadTab(tab, TEST_URL_BASES[0] + (++gTabCounter));
-    }
-  },
-  function() {
-    info("Running step 11 - close tabs in private browsing mode");
-    gBrowser.removeCurrentTab();
-    ensure_opentabs_match_db(nextStep);
-  },
-  function() {
-    info("Running step 12 - leave private browsing mode");
-
-    Services.obs.addObserver(function(aSubject, aTopic, aData) {
-      Services.obs.removeObserver(arguments.callee, "private-browsing-transition-complete");
-
-      let ps = Services.prefs;
-      ps.clearUserPref("browser.privatebrowsing.keep_current_session");
-      ps.clearUserPref("browser.tabs.warnOnClose");
-
-      for (let i = 1; i < gBrowser.tabs.length; i++)
-        waitForRestoredTab(gBrowser.tabs[i]);
-
-    }, "private-browsing-transition-complete", false);
-
-    gPrivateBrowsing.privateBrowsingEnabled = false;
-  },
-  function() {
-    info("Running step 13 - close all tabs");
+    info("Running step 7 - close all tabs");
 
     Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand");
 
     gBrowser.addTab("about:blank", {skipAnimation: true});
     while (gBrowser.tabs.length > 1) {
       info("Removing tab: " + gBrowser.tabs[0].linkedBrowser.currentURI.spec);
       gBrowser.selectTabAtIndex(0);
       gBrowser.removeCurrentTab();
@@ -167,17 +92,17 @@ var gTestSteps = [
 
 function test() {
   waitForExplicitFinish();
   nextStep();
 }
 
 function loadTab(tab, url) {
   // Because adding visits is async, we will not be notified immediately.
-  let visited = gPrivateBrowsing.privateBrowsingEnabled;
+  let visited = false;
   let loaded = false;
 
   function maybeCheckResults() {
     if (visited && loaded && --gTabWaitCount == 0) {
       ensure_opentabs_match_db(nextStep);
     }
   }
 
--- a/browser/components/privatebrowsing/content/aboutPrivateBrowsing.xhtml
+++ b/browser/components/privatebrowsing/content/aboutPrivateBrowsing.xhtml
@@ -8,37 +8,51 @@
   <!ENTITY % htmlDTD PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
   %htmlDTD;
   <!ENTITY % netErrorDTD SYSTEM "chrome://global/locale/netError.dtd">
   %netErrorDTD;
   <!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
   %globalDTD;
   <!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd">
   %browserDTD;
+#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
+#ifdef XP_MACOSX
+  <!ENTITY basePBMenu.label   "&fileMenu.label;">
+#else
+  <!ENTITY basePBMenu.label   "<span class='appMenuButton'>&brandShortName;</span><span class='fileMenu'>&fileMenu.label;</span>">
+#endif
+#else
 #ifdef XP_MACOSX
   <!ENTITY basePBMenu.label   "&toolsMenu.label;">
 #else
   <!ENTITY basePBMenu.label   "<span class='appMenuButton'>&brandShortName;</span><span class='toolsMenu'>&toolsMenu.label;</span>">
 #endif
+#endif
   <!ENTITY % privatebrowsingpageDTD SYSTEM "chrome://browser/locale/aboutPrivateBrowsing.dtd">
   %privatebrowsingpageDTD;
 ]>
 
 <html xmlns="http://www.w3.org/1999/xhtml">
   <head>
     <link rel="stylesheet" href="chrome://global/skin/netError.css" type="text/css" media="all"/>
     <link rel="stylesheet" href="chrome://browser/skin/aboutPrivateBrowsing.css" type="text/css" media="all"/>
     <style type="text/css"><![CDATA[
       body.normal .showPrivate,
       body.private .showNormal {
         display: none;
       }
+#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
+      body.appMenuButtonVisible .fileMenu {
+        display: none;
+      }
+#else
       body.appMenuButtonVisible .toolsMenu {
         display: none;
       }
+#endif
       body.appMenuButtonInvisible .appMenuButton {
         display: none;
       }
     ]]></style>
     <script type="application/javascript;version=1.7"><![CDATA[
       const Cc = Components.classes;
       const Ci = Components.interfaces;
 
@@ -88,20 +102,26 @@
 
         // Show the correct menu structure based on whether the App Menu button is
         // shown or not.
         var menuBar = mainWindow.document.getElementById("toolbar-menubar");
         var appMenuButtonIsVisible = menuBar.getAttribute("autohide") == "true";
         document.body.classList.add(appMenuButtonIsVisible ? "appMenuButtonVisible" :
                                                              "appMenuButtonInvisible");
       }, false);
-      
+
+#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
+      function openPrivateWindow() {
+        mainWindow.OpenBrowserWindow({private: true});
+      }
+#else
       function togglePrivateBrowsing() {
         mainWindow.gPrivateBrowsingUI.toggleMode();
       }
+#endif
     ]]></script>
   </head>
 
   <body dir="&locale.dir;"
         class="private">
 
     <!-- PAGE CONTAINER (for styling purposes only) -->
     <div id="errorPageContainer">
@@ -112,37 +132,58 @@
         <h1 id="errorTitleTextNormal" class="showNormal">&privatebrowsingpage.title.normal;</h1>
       </div>
 
       <!-- LONG CONTENT (the section most likely to require scrolling) -->
       <div id="errorLongContent">
 
         <!-- Short Description -->
         <div id="errorShortDesc">
+#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
+          <p id="errorShortDescText" class="showPrivate">&privatebrowsingpage.perwindow.issueDesc;</p>
+          <p id="errorShortDescTextNormal" class="showNormal">&privatebrowsingpage.perwindow.issueDesc.normal;</p>
+#else
           <p id="errorShortDescText" class="showPrivate">&privatebrowsingpage.issueDesc;</p>
           <p id="errorShortDescTextNormal" class="showNormal">&privatebrowsingpage.issueDesc.normal;</p>
+#endif
         </div>
 
         <!-- Long Description -->
         <div id="errorLongDesc">
+#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
+          <p id="errorLongDescText">&privatebrowsingpage.perwindow.description;</p>
+#else
           <p id="errorLongDescText">&privatebrowsingpage.description;</p>
+#endif
         </div>
 
         <!-- Start Private Browsing -->
         <div id="startPrivateBrowsingDesc" class="showNormal">
+#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
+          <button xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+                  id="startPrivateBrowsing" label="&privatebrowsingpage.openPrivateWindow.label;"
+                  accesskey="&privatebrowsingpage.openPrivateWindow.accesskey;"
+                  oncommand="openPrivateWindow();"/>
+#else
           <button xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
                   id="startPrivateBrowsing" label="&privatebrowsingpage.startPrivateBrowsing.label;"
                   accesskey="&privatebrowsingpage.startPrivateBrowsing.accesskey;"
                   oncommand="togglePrivateBrowsing();"/>
+#endif
         </div>
 
         <!-- Footer -->
         <div id="footerDesc">
+#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
+          <p id="footerText" class="showPrivate">&privatebrowsingpage.howToStop3;</p>
+          <p id="footerTextNormal" class="showNormal">&privatebrowsingpage.howToStart3;</p>
+#else
           <p id="footerText" class="showPrivate">&privatebrowsingpage.howToStop2;</p>
           <p id="footerTextNormal" class="showNormal">&privatebrowsingpage.howToStart2;</p>
+#endif
         </div>
 
         <!-- More Info -->
         <div id="moreInfo" class="showPrivate">
           <p id="moreInfoText">
             &privatebrowsingpage.moreInfo;
           </p>
           <p id="moreInfoLinkContainer">
--- a/browser/components/tabview/test/Makefile.in
+++ b/browser/components/tabview/test/Makefile.in
@@ -64,17 +64,16 @@ include $(topsrcdir)/config/rules.mk
                  browser_tabview_bug616729.js \
                  browser_tabview_bug616967.js \
                  browser_tabview_bug618816.js \
                  browser_tabview_bug618828.js \
                  browser_tabview_bug619937.js \
                  browser_tabview_bug622835.js \
                  browser_tabview_bug623768.js \
                  browser_tabview_bug624692.js \
-                 browser_tabview_bug624727.js \
                  browser_tabview_bug624847.js \
                  browser_tabview_bug624931.js \
                  browser_tabview_bug624953.js \
                  browser_tabview_bug625195.js \
                  browser_tabview_bug625269.js \
                  browser_tabview_bug625424.js \
                  browser_tabview_bug625955.js \
                  browser_tabview_bug626368.js \
@@ -102,17 +101,16 @@ include $(topsrcdir)/config/rules.mk
                  browser_tabview_bug641802.js \
                  browser_tabview_bug642793.js \
                  browser_tabview_bug643392.js \
                  browser_tabview_bug644097.js \
                  browser_tabview_bug648882.js \
                  browser_tabview_bug649006.js \
                  browser_tabview_bug649307.js \
                  browser_tabview_bug649319.js \
-                 browser_tabview_bug650280.js \
                  browser_tabview_bug650573.js \
                  browser_tabview_bug651311.js \
                  browser_tabview_bug654295.js \
                  browser_tabview_bug654721.js \
                  browser_tabview_bug654941.js \
                  browser_tabview_bug655269.js \
                  browser_tabview_bug656778.js \
                  browser_tabview_bug656913.js \
@@ -163,21 +161,25 @@ include $(topsrcdir)/config/rules.mk
                  test_bug600645.html \
                  test_bug644097.html \
                  test_bug678374.html \
                  test_bug678374_icon16.png \
                  $(NULL)
 
 ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
 _BROWSER_FILES += \
-                browser_tabview_bug624265_perwindowpb.js \
-                $(NULL)
+                 browser_tabview_bug624265_perwindowpb.js \
+                 browser_tabview_bug624727_perwindowpb.js \
+                 browser_tabview_bug650280_perwindowpb.js \
+                 $(NULL)
 else
 _BROWSER_FILES += \
-                browser_tabview_bug624265.js \
-                $(NULL)
+                 browser_tabview_bug624265.js \
+                 browser_tabview_bug624727.js \
+                 browser_tabview_bug650280.js \
+                 $(NULL)
 endif
 
 
 # browser_tabview_bug597980.js is disabled for leaking, see bug 711907
 
 libs::	$(_BROWSER_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
copy from browser/components/tabview/test/browser_tabview_bug624727.js
copy to browser/components/tabview/test/browser_tabview_bug624727_perwindowpb.js
--- a/browser/components/tabview/test/browser_tabview_bug624727.js
+++ b/browser/components/tabview/test/browser_tabview_bug624727_perwindowpb.js
@@ -1,130 +1,143 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-let pb = Cc['@mozilla.org/privatebrowsing;1'].
-         getService(Ci.nsIPrivateBrowsingService);
-
 function test() {
-  let cw;
-
-  let createGroupItem = function () {
+  let createGroupItem = function (aWindow) {
+    let cw = aWindow.TabView.getContentWindow();
     let bounds = new cw.Rect(20, 20, 400, 200);
     let groupItem = new cw.GroupItem([], {bounds: bounds, immediately: true});
     cw.UI.setActive(groupItem);
 
     let groupItemId = groupItem.id;
     registerCleanupFunction(function() {
       let groupItem = cw.GroupItems.groupItem(groupItemId);
       if (groupItem)
         groupItem.close();
     });
 
     for (let i=0; i<3; i++)
-      gBrowser.addTab('about:blank');
+      aWindow.gBrowser.addTab('about:blank');
   }
 
-  let assertTabViewIsHidden = function (prefix) {
-    ok(!TabView.isVisible(), prefix + ': tabview is hidden');
+  let assertTabViewIsHidden = function (aWindow, prefix) {
+    ok(!aWindow.TabView.isVisible(), prefix + ': tabview is hidden');
   }
 
-  let assertNumberOfTabs = function (prefix, num) {
-    is(gBrowser.tabs.length, num, prefix + ': there are ' + num + ' tabs');
+  let assertNumberOfTabs = function (aWindow, prefix, num) {
+    is(aWindow.gBrowser.tabs.length, num, prefix + ': there are ' + num + ' tabs');
   }
 
-  let assertNumberOfPinnedTabs = function (prefix, num) {
-    is(gBrowser._numPinnedTabs, num, prefix + ': there are ' + num + ' pinned tabs');
+  let assertNumberOfPinnedTabs = function (aWindow, prefix, num) {
+    is(aWindow.gBrowser._numPinnedTabs, num, prefix + ': there are ' + num + ' pinned tabs');
   }
 
-  let assertNumberOfGroups = function (prefix, num) {
-    is(cw.GroupItems.groupItems.length, num, prefix + ': there are ' + num + ' groups');
+  let assertNumberOfGroups = function (aCW, prefix, num) {
+    is(aCW.GroupItems.groupItems.length, num, prefix + ': there are ' + num + ' groups');
   }
 
   let assertOneTabInGroup = function (prefix, groupItem) {
     is(groupItem.getChildren().length, 1, prefix + ': group contains one tab');
   }
 
-  let assertValidPrerequisites = function (prefix) {
-    assertNumberOfTabs(prefix, 1);
-    assertNumberOfPinnedTabs(prefix, 0);
-    assertTabViewIsHidden(prefix);
+  let assertValidPrerequisites = function (aWindow, prefix) {
+    assertNumberOfTabs(aWindow, prefix, 1);
+    assertNumberOfPinnedTabs(aWindow, prefix, 0);
+    assertTabViewIsHidden(aWindow, prefix);
   }
 
-  let assertValidSetup = function (prefix) {
-    assertNumberOfGroups(prefix, 2);
-    assertNumberOfTabs(prefix, 4);
-    assertNumberOfPinnedTabs(prefix, 2);
+  let assertValidSetup = function (aWindow, prefix) {
+    let cw = aWindow.TabView.getContentWindow();
+    assertNumberOfGroups(cw, prefix, 2);
+    assertNumberOfTabs(aWindow, prefix, 4);
+    assertNumberOfPinnedTabs(aWindow, prefix, 2);
 
     let [group1, group2] = cw.GroupItems.groupItems;
     assertOneTabInGroup(prefix, group1);
     assertOneTabInGroup(prefix, group2);
   }
 
-  let testStateAfterEnteringPB = function () {
-    let prefix = 'enter';
-    ok(!pb.privateBrowsingEnabled, prefix + ': private browsing is disabled');
-    registerCleanupFunction(function () {
-      pb.privateBrowsingEnabled = false;
-    });
+  let testStateAfterEnteringPB = function (aWindow, aCallback) {
+    let prefix = 'window is private';
+    ok(PrivateBrowsingUtils.isWindowPrivate(aWindow), prefix);
+
+    assertTabViewIsHidden(aWindow, prefix);
 
-    togglePrivateBrowsing(function () {
-      assertTabViewIsHidden(prefix);
+    showTabView(function () {
+      let cw = aWindow.TabView.getContentWindow();
 
-      showTabView(function () {
-        assertNumberOfGroups(prefix, 1);
-        assertNumberOfTabs(prefix, 1);
-        assertOneTabInGroup(prefix, cw.GroupItems.groupItems[0]);
-        hideTabView(testStateAfterLeavingPB);
-      });
-    });
+      assertNumberOfGroups(cw, prefix, 1);
+      assertNumberOfTabs(aWindow, prefix, 1);
+      assertOneTabInGroup(prefix, cw.GroupItems.groupItems[0]);
+      aCallback();
+    }, aWindow);
   }
 
-  let testStateAfterLeavingPB = function () {
-    let prefix = 'leave';
-    ok(pb.privateBrowsingEnabled, prefix + ': private browsing is enabled');
+  let testStateAfterLeavingPB = function (aWindow) {
+    let prefix = 'window is not private';
+    ok(!PrivateBrowsingUtils.isWindowPrivate(aWindow), prefix);
 
-    togglePrivateBrowsing(function () {
-      assertTabViewIsHidden(prefix);
+    assertTabViewIsHidden(aWindow, prefix);
 
-      showTabView(function () {
-        assertValidSetup(prefix);
-        finishTest();
-      });
-    });
+    showTabView(function () {
+      assertValidSetup(aWindow, prefix);
+      finishTest(aWindow);
+    }, aWindow);
   }
 
-  let finishTest = function () {
-    // remove pinned tabs
-    gBrowser.removeTab(gBrowser.tabs[0]);
-    gBrowser.removeTab(gBrowser.tabs[0]);
+  let finishTest = function (aWindow) {
+    let cw = aWindow.TabView.getContentWindow();
+
+    // Remove pinned tabs
+    aWindow.gBrowser.removeTab(aWindow.gBrowser.tabs[0]);
+    aWindow.gBrowser.removeTab(aWindow.gBrowser.tabs[0]);
 
     cw.GroupItems.groupItems[1].closeAll();
 
     hideTabView(function () {
-      assertValidPrerequisites('exit');
-      assertNumberOfGroups('exit', 1);
+      assertValidPrerequisites(aWindow, 'exit');
+      assertNumberOfGroups(cw, 'exit', 1);
+      aWindow.close();
       finish();
-    });
+    }, aWindow);
+  }
+
+  let testOnWindow = function(aIsPrivate, aCallback) {
+    let win = OpenBrowserWindow({private: aIsPrivate});
+    win.addEventListener("load", function onLoad() {
+      win.removeEventListener("load", onLoad, false);
+      executeSoon(function() { aCallback(win) });
+    }, false);
   }
 
   waitForExplicitFinish();
-  registerCleanupFunction(function () TabView.hide());
-  assertValidPrerequisites('start');
+  testOnWindow(false, function(publicWindow) {
+    registerCleanupFunction(function () publicWindow.TabView.hide());
+    assertValidPrerequisites(publicWindow, 'start');
 
-  showTabView(function () {
-    cw = TabView.getContentWindow();
-    assertNumberOfGroups('start', 1);
-
-    createGroupItem();
+    showTabView(function () {
+      let cw = publicWindow.TabView.getContentWindow();
+      assertNumberOfGroups(cw, 'start', 1);
+      createGroupItem(publicWindow);
 
-    afterAllTabsLoaded(function () {
-      // setup
-      let groupItems = cw.GroupItems.groupItems;
-      let [tabItem1, tabItem2, ] = groupItems[1].getChildren();
-      gBrowser.pinTab(tabItem1.tab);
-      gBrowser.pinTab(tabItem2.tab);
+      afterAllTabsLoaded(function () {
+        // Setup
+        let groupItems = cw.GroupItems.groupItems;
+        let [tabItem1, tabItem2, ] = groupItems[1].getChildren();
+        publicWindow.gBrowser.pinTab(tabItem1.tab);
+        publicWindow.gBrowser.pinTab(tabItem2.tab);
 
-      assertValidSetup('setup');
-      hideTabView(testStateAfterEnteringPB);
-    });
+        assertValidSetup(publicWindow, 'setup');
+        hideTabView(function() {
+          testOnWindow(true, function(privateWindow) {
+            testStateAfterEnteringPB(privateWindow, function() {
+              privateWindow.close();
+              hideTabView(function() {
+                testStateAfterLeavingPB(publicWindow);
+              }, publicWindow);
+            });
+          });
+        }, publicWindow);
+      });
+    }, publicWindow);
   });
 }
copy from browser/components/tabview/test/browser_tabview_bug650280.js
copy to browser/components/tabview/test/browser_tabview_bug650280_perwindowpb.js
--- a/browser/components/tabview/test/browser_tabview_bug650280.js
+++ b/browser/components/tabview/test/browser_tabview_bug650280_perwindowpb.js
@@ -1,67 +1,75 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-let pb = Cc["@mozilla.org/privatebrowsing;1"].
-         getService(Ci.nsIPrivateBrowsingService);
-
 function test() {
-  let cw;
-
-  registerCleanupFunction(function() {
-    if (cw)
-      cw.Search.hide();
-
-    TabView.hide();
-    pb.privateBrowsingEnabled = false;
-  });
-
-  let enableSearch = function (callback) {
-    if (cw.Search.isEnabled()) {
-      callback();
+  let enableSearch = function (aCW, aCallback) {
+    if (aCW.Search.isEnabled()) {
+       aCallback();
       return;
     }
 
-    cw.addEventListener("tabviewsearchenabled", function onSearchEnabled() {
-      cw.removeEventListener("tabviewsearchenabled", onSearchEnabled, false);
-      executeSoon(callback);
+    aCW.addEventListener("tabviewsearchenabled", function onSearchEnabled() {
+      aCW.removeEventListener("tabviewsearchenabled", onSearchEnabled, false);
+      executeSoon(aCallback);
     }, false);
 
-    cw.Search.ensureShown();
-  };
-
-  let getSearchboxValue = function () {
-    return cw.iQ("#searchbox").val();
+    aCW.Search.ensureShown();
   };
 
-  let prepareSearchbox = function (callback) {
-    ok(!cw.Search.isEnabled(), "search is disabled");
-
-    enableSearch(function () {
-      cw.iQ("#searchbox").val("moz");
-      callback();
-    });
+  let getSearchboxValue = function (aCW) {
+    return aCW.iQ("#searchbox").val();
   };
 
-  let searchAndSwitchPBMode = function (callback) {
-    prepareSearchbox(function () {
-      togglePrivateBrowsing(function () {
-        showTabView(function () {
-          ok(!cw.Search.isEnabled(), "search is disabled");
-          is(getSearchboxValue(), "", "search box is empty");
-          callback();
-        });
+  let prepareSearchbox = function (aCW, aCallback) {
+    ok(!aCW.Search.isEnabled(), "search is disabled");
+
+    executeSoon(function() {
+      enableSearch(aCW, function() {
+        aCW.iQ("#searchbox").val("moz");
+        aCallback();
       });
     });
   };
 
+  let searchAndSwitchPBMode = function (aWindow, aCallback) {
+    showTabView(function() {
+      let cw = aWindow.TabView.getContentWindow();
+
+      prepareSearchbox(cw, function() {
+        testOnWindow(!PrivateBrowsingUtils.isWindowPrivate(aWindow), function(win) {
+          showTabView(function() {
+            let contentWindow = win.TabView.getContentWindow();
+            ok(!contentWindow.Search.isEnabled(), "search is disabled");
+            is(getSearchboxValue(contentWindow), "", "search box is empty");
+            aWindow.TabView.hide();
+            win.close();
+            hideTabView(function() {
+              aWindow.close();
+              aCallback();
+            }, aWindow);
+          }, win);
+        });
+      });
+    }, aWindow);
+  };
+
+  let testOnWindow = function(aIsPrivate, aCallback) {
+    let win = OpenBrowserWindow({private: aIsPrivate});
+    win.addEventListener("load", function onLoad() {
+      win.removeEventListener("load", onLoad, false);
+      executeSoon(function() { aCallback(win) });
+    }, false);
+  }
+
   waitForExplicitFinish();
 
-  showTabView(function () {
-    cw = TabView.getContentWindow();
-    searchAndSwitchPBMode(function () {
-      searchAndSwitchPBMode(function () {
-        hideTabView(finish);
+  testOnWindow(false, function(win) {
+    searchAndSwitchPBMode(win, function() {
+      testOnWindow(true, function(win) {
+        searchAndSwitchPBMode(win, function() {
+          finish();
+        });
       });
     });
   });
 }
--- a/browser/locales/en-US/chrome/browser/aboutPrivateBrowsing.dtd
+++ b/browser/locales/en-US/chrome/browser/aboutPrivateBrowsing.dtd
@@ -3,21 +3,32 @@
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
 <!ENTITY privatebrowsingpage.title                 "Private Browsing">
 <!ENTITY privatebrowsingpage.title.normal          "Would you like to start Private Browsing?">
 
 <!ENTITY privatebrowsingpage.issueDesc                 "&brandShortName; won't remember any history for this session.">
 <!ENTITY privatebrowsingpage.issueDesc.normal          "&brandShortName; is not currently in Private Browsing mode.">
 
+<!ENTITY privatebrowsingpage.perwindow.issueDesc        "&brandShortName; won't remember any history for this window.">
+<!ENTITY privatebrowsingpage.perwindow.issueDesc.normal "You are not currently in a private window.">
+
 <!ENTITY privatebrowsingpage.description               "In a Private Browsing session, &brandShortName; won't keep any browser history, search history, download history, web form history, cookies, or temporary internet files.  However, files you download and bookmarks you make will be kept.">
 
+<!ENTITY privatebrowsingpage.perwindow.description     "In a Private Browsing window, &brandShortName; won't keep any browser history, search history, download history, web form history, cookies, or temporary internet files.  However, files you download and bookmarks you make will be kept.">
 
 <!ENTITY privatebrowsingpage.startPrivateBrowsing.label "Start Private Browsing">
 <!ENTITY privatebrowsingpage.startPrivateBrowsing.accesskey "P">
 
+<!ENTITY privatebrowsingpage.openPrivateWindow.label "Open a Private Window">
+<!ENTITY privatebrowsingpage.openPrivateWindow.accesskey "P">
+
 <!-- LOCALIZATION NOTE (privatebrowsingpage.howToStop2): please leave &basePBMenu.label; intact in the translation -->
 <!-- LOCALIZATION NOTE (privatebrowsingpage.howToStart2): please leave &basePBMenu.label; intact in the translation -->
 <!ENTITY privatebrowsingpage.howToStop2                "To stop Private Browsing, select &basePBMenu.label; &gt; &privateBrowsingCmd.stop.label;, or close &brandShortName;.">
 <!ENTITY privatebrowsingpage.howToStart2               "To start Private Browsing, you can also select &basePBMenu.label; &gt; &privateBrowsingCmd.start.label;.">
 
+<!-- LOCALIZATION NOTE (privatebrowsingpage.howToStart3): please leave &basePBMenu.label; intact in the translation -->
+<!ENTITY privatebrowsingpage.howToStart3               "To start Private Browsing, you can also select &basePBMenu.label; &gt; &newPrivateWindow.label;.">
+<!ENTITY privatebrowsingpage.howToStop3                "To stop Private Browsing, you can close this window.">
+
 <!ENTITY privatebrowsingpage.moreInfo                  "While this computer won't have a record of your browsing history, your internet service provider or employer can still track the pages you visit.">
 <!ENTITY privatebrowsingpage.learnMore                 "Learn More">
--- a/browser/themes/gnomestripe/browser.css
+++ b/browser/themes/gnomestripe/browser.css
@@ -496,16 +496,17 @@ menuitem:not([type]):not(.menuitem-toolt
 
 #menu_pageInfo,
 #context-viewinfo,
 #context-viewframeinfo {
   list-style-image: url("moz-icon://stock/gtk-info?size=menu");
 }
 
 #appmenu_privateBrowsing,
+#appmenu_newPrivateWindow,
 #privateBrowsingItem {
   list-style-image: url("chrome://browser/skin/Privacy-16.png");
 }
 
 #placesContext_show\:info {
   list-style-image: url("moz-icon://stock/gtk-properties?size=menu");
 }
 
--- a/browser/themes/winstripe/browser.css
+++ b/browser/themes/winstripe/browser.css
@@ -411,17 +411,18 @@
   font-style: italic;
 }
 
 #appmenu_bookmarks {
   list-style-image: url("chrome://browser/skin/places/bookmark.png");
   -moz-image-region: rect(0px 48px 16px 32px);
 }
 
-#appmenu_privateBrowsing {
+#appmenu_privateBrowsing,
+#appmenu_newPrivateWindow {
   list-style-image: url("chrome://browser/skin/Privacy-16.png");
 }
 
 #appmenu_addons {
   list-style-image: url("chrome://mozapps/skin/extensions/extensionGeneric-16.png");
 }
 
 #BMB_bookmarkThisPage,
--- a/media/libspeex_resampler/src/Makefile.in
+++ b/media/libspeex_resampler/src/Makefile.in
@@ -29,12 +29,14 @@ else
 DEFINES += -DFLOATING_POINT
 endif
 
 CSRCS = \
     resample.c \
     $(NULL)
 
 EXPORTS_speex = \
+    speex_config_types.h \
     speex_resampler.h \
+    speex_types.h \
     $(NULL)
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/media/libspeex_resampler/src/speex_config_types.h
@@ -0,0 +1,11 @@
+#ifndef __SPEEX_TYPES_H__
+#define __SPEEX_TYPES_H__
+
+/* these are filled in by configure */
+typedef uint16_t spx_int16_t;
+typedef unsigned uint16_t spx_uint16_t;
+typedef uint32_t spx_int32_t;
+typedef unsigned uint32_t spx_uint32_t;
+
+#endif
+
new file mode 100644
--- /dev/null
+++ b/media/libspeex_resampler/src/speex_types.h
@@ -0,0 +1,130 @@
+/* speex_types.h taken from libogg */
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: #ifdef jail to whip a few platforms into the UNIX ideal.
+ last mod: $Id: os_types.h 7524 2004-08-11 04:20:36Z conrad $
+
+ ********************************************************************/
+/**
+   @file speex_types.h
+   @brief Speex types
+*/
+#ifndef _SPEEX_TYPES_H
+#define _SPEEX_TYPES_H
+
+#if defined(_WIN32) 
+
+#  if defined(__CYGWIN__)
+#    include <_G_config.h>
+     typedef _G_int32_t spx_int32_t;
+     typedef _G_uint32_t spx_uint32_t;
+     typedef _G_int16_t spx_int16_t;
+     typedef _G_uint16_t spx_uint16_t;
+#  elif defined(__MINGW32__)
+     typedef short spx_int16_t;
+     typedef unsigned short spx_uint16_t;
+     typedef int spx_int32_t;
+     typedef unsigned int spx_uint32_t;
+#  elif defined(__MWERKS__)
+     typedef int spx_int32_t;
+     typedef unsigned int spx_uint32_t;
+     typedef short spx_int16_t;
+     typedef unsigned short spx_uint16_t;
+#  else
+     /* MSVC/Borland */
+     typedef __int32 spx_int32_t;
+     typedef unsigned __int32 spx_uint32_t;
+     typedef __int16 spx_int16_t;
+     typedef unsigned __int16 spx_uint16_t;
+#  endif
+
+#elif defined(__MACOS__)
+
+#  include <sys/types.h>
+   typedef SInt16 spx_int16_t;
+   typedef UInt16 spx_uint16_t;
+   typedef SInt32 spx_int32_t;
+   typedef UInt32 spx_uint32_t;
+
+#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */
+
+#  include <sys/types.h>
+   typedef int16_t spx_int16_t;
+   typedef u_int16_t spx_uint16_t;
+   typedef int32_t spx_int32_t;
+   typedef u_int32_t spx_uint32_t;
+
+#elif defined(__BEOS__)
+
+   /* Be */
+#  include <inttypes.h>
+   typedef int16_t spx_int16_t;
+   typedef u_int16_t spx_uint16_t;
+   typedef int32_t spx_int32_t;
+   typedef u_int32_t spx_uint32_t;
+
+#elif defined (__EMX__)
+
+   /* OS/2 GCC */
+   typedef short spx_int16_t;
+   typedef unsigned short spx_uint16_t;
+   typedef int spx_int32_t;
+   typedef unsigned int spx_uint32_t;
+
+#elif defined (DJGPP)
+
+   /* DJGPP */
+   typedef short spx_int16_t;
+   typedef int spx_int32_t;
+   typedef unsigned int spx_uint32_t;
+
+#elif defined(R5900)
+
+   /* PS2 EE */
+   typedef int spx_int32_t;
+   typedef unsigned spx_uint32_t;
+   typedef short spx_int16_t;
+
+#elif defined(__SYMBIAN32__)
+
+   /* Symbian GCC */
+   typedef signed short spx_int16_t;
+   typedef unsigned short spx_uint16_t;
+   typedef signed int spx_int32_t;
+   typedef unsigned int spx_uint32_t;
+
+#elif defined(CONFIG_TI_C54X) || defined (CONFIG_TI_C55X)
+
+   typedef short spx_int16_t;
+   typedef unsigned short spx_uint16_t;
+   typedef long spx_int32_t;
+   typedef unsigned long spx_uint32_t;
+
+#elif defined(CONFIG_TI_C6X)
+
+   typedef short spx_int16_t;
+   typedef unsigned short spx_uint16_t;
+   typedef int spx_int32_t;
+   typedef unsigned int spx_uint32_t;
+
+#else
+
+# ifdef _BUILD_SPEEX
+#  include "include/speex/speex_config_types.h"
+#else
+#  include <speex/speex_config_types.h>
+#endif
+
+#endif
+
+#endif  /* _SPEEX_TYPES_H */
--- a/media/libspeex_resampler/update.sh
+++ b/media/libspeex_resampler/update.sh
@@ -6,10 +6,12 @@
 #
 # Copies the needed files from a directory containing the original
 # libspeex sources that we need for HTML5 media playback rate change.
 cp $1/libspeex/resample.c src
 cp $1/libspeex/arch.h src
 cp $1/libspeex/stack_alloc.h src
 cp $1/libspeex/fixed_generic.h src
 cp $1/include/speex/speex_resampler.h src
+cp $1/include/speex/speex_types.h src
+sed -e 's/@SIZE16@/uint16_t/g' -e 's/@SIZE32@/uint32_t/g' < $1/include/speex/speex_config_types.h.in > src/speex_config_types.h
 cp $1/AUTHORS .
 cp $1/COPYING .
--- a/python/mozbuild/mozbuild/mozconfig.py
+++ b/python/mozbuild/mozbuild/mozconfig.py
@@ -165,17 +165,18 @@ class MozconfigLoader(ProcessExecutionMi
         path = path.replace(os.sep, '/')
 
         result['configure_args'] = []
         result['make_extra'] = []
         result['make_flags'] = []
 
         env = dict(os.environ)
 
-        args = self._normalize_command([self._loader_script, path], True)
+        args = self._normalize_command([self._loader_script, self.topsrcdir,
+            path], True)
 
         output = subprocess.check_output(args, stderr=subprocess.PIPE,
             cwd=self.topsrcdir, env=env)
 
         parsed = self._parse_loader_output(output)
 
         all_variables = set(parsed['vars_before'].keys())
         all_variables |= set(parsed['vars_after'].keys())
@@ -293,48 +294,48 @@ class MozconfigLoader(ProcessExecutionMi
                 # $ foo="a='b'
                 # c='d'"
                 # $ set
                 # foo='a='"'"'b'"'"'
                 # c='"'"'d'"'"
 
                 name = in_variable
                 value = None
-
                 if in_variable:
                     # Reached the end of a multi-line variable.
                     if line.endswith("'") and not line.endswith("\\'"):
                         current.append(line[:-1])
                         value = '\n'.join(current)
                         in_variable = None
                     else:
                         current.append(line)
                         continue
                 else:
                     equal_pos = line.find('=')
 
                     if equal_pos < 1:
-                        # TODO log warning
+                        # TODO log warning?
                         continue
 
                     name = line[0:equal_pos]
-                    has_quote = line[equal_pos + 1] == "'"
+                    value = line[equal_pos + 1:]
 
-                    if has_quote:
-                        value = line[equal_pos + 2:]
-                    else:
-                        value = line[equal_pos + 1:]
+                    if len(value):
+                        has_quote = value[0] == "'"
+
+                        if has_quote:
+                            value = value[1:]
 
-                    # Lines with a quote not ending in a quote are multi-line.
-                    if has_quote and not value.endswith("'"):
-                        in_variable = name
-                        current.append(value)
-                        continue
-                    else:
-                        value = value[:-1] if has_quote else value
+                        # Lines with a quote not ending in a quote are multi-line.
+                        if has_quote and not value.endswith("'"):
+                            in_variable = name
+                            current.append(value)
+                            continue
+                        else:
+                            value = value[:-1] if has_quote else value
 
                 assert name is not None
 
                 if current_type == 'BEFORE_SOURCE':
                     before_source[name] = value
                 else:
                     after_source[name] = value
 
--- a/python/mozbuild/mozbuild/mozconfig_loader
+++ b/python/mozbuild/mozbuild/mozconfig_loader
@@ -31,14 +31,18 @@ mk_add_options() {
     echo "------END_MK_OPTION"
   done
 }
 
 echo "------BEGIN_BEFORE_SOURCE"
 set
 echo "------END_BEFORE_SOURCE"
 
-. $1
+topsrcdir=$1
+
+. $2
+
+unset topsrcdir
 
 echo "------BEGIN_AFTER_SOURCE"
 set
 echo "------END_AFTER_SOURCE"
 
--- a/python/mozbuild/mozbuild/test/test_mozconfig.py
+++ b/python/mozbuild/mozbuild/test/test_mozconfig.py
@@ -269,8 +269,30 @@ class TestMozconfigLoader(unittest.TestC
 
             result = self.get_loader().read_mozconfig(mozconfig.name)
 
             self.assertEqual(result['env']['added'], {
                 'multi': 'foo\nbar',
                 'single': '1'
             })
 
+    def test_read_topsrcdir_defined(self):
+        """Ensure $topsrcdir references work as expected."""
+        with NamedTemporaryFile(mode='w') as mozconfig:
+            mozconfig.write('TEST=$topsrcdir')
+            mozconfig.flush()
+
+            loader = self.get_loader()
+            result = loader.read_mozconfig(mozconfig.name)
+
+            self.assertEqual(result['env']['added']['TEST'], loader.topsrcdir)
+
+    def test_read_empty_variable_value(self):
+        """Ensure empty variable values are parsed properly."""
+        with NamedTemporaryFile(mode='w') as mozconfig:
+            mozconfig.write('EMPTY=\n')
+            mozconfig.flush()
+
+            result = self.get_loader().read_mozconfig(mozconfig.name)
+
+            self.assertIn('EMPTY', result['env']['added'])
+            self.assertEqual(result['env']['added']['EMPTY'], '')
+
--- a/testing/xpcshell/remotexpcshelltests.py
+++ b/testing/xpcshell/remotexpcshelltests.py
@@ -3,18 +3,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/.
 
 import sys, os
 import subprocess
 import runxpcshelltests as xpcshell
 import tempfile
-from automationutils import *
-from mozdevice import devicemanagerADB, devicemanagerSUT
+from automationutils import replaceBackSlashes
+from mozdevice import devicemanagerADB, devicemanagerSUT, DMError
 
 here = os.path.dirname(os.path.abspath(__file__))
 
 # A specialization of XPCShellTests that runs tests on an Android device
 # via devicemanager.
 class XPCShellRemote(xpcshell.XPCShellTests, object):
 
     def __init__(self, devmgr, options, args):
--- a/testing/xpcshell/runtestsb2g.py
+++ b/testing/xpcshell/runtestsb2g.py
@@ -5,18 +5,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 import sys
 import os
 sys.path.insert(0, os.path.abspath(os.path.realpath(os.path.dirname(sys.argv[0]))))
 
 import traceback
 from remotexpcshelltests import XPCShellRemote, RemoteXPCShellOptions
-from automationutils import *
-from mozdevice import devicemanagerADB
+from mozdevice import devicemanagerADB, DMError
 
 DEVICE_TEST_ROOT = '/data/local/tests'
 
 
 from marionette import Marionette
 
 class B2GXPCShellRemote(XPCShellRemote):