Merge mozilla-beta to b2g28. a=merge
authorRyan VanderMeulen <ryanvm@gmail.com>
Mon, 10 Feb 2014 19:03:53 -0500
changeset 170540 873e98e750bfb40a87b6950984f79fbea6cd9122
parent 170517 4180028c15eea1d6f56d808bc40d0779e38f5f38 (current diff)
parent 170539 58908dc356c157181e741f7385c51f726113a16b (diff)
child 170541 62b074d6a3387cda2e82fd56e00c16eb221ed074
push id57
push userryanvm@gmail.com
push dateTue, 11 Feb 2014 00:03:55 +0000
reviewersmerge
milestone28.0
Merge mozilla-beta to b2g28. a=merge
docshell/base/nsDocShell.cpp
dom/ipc/TabChild.cpp
layout/reftests/mathml/menclose-1.html
uriloader/prefetch/nsOfflineCacheUpdate.cpp
--- a/addon-sdk/source/lib/sdk/tabs/tab-fennec.js
+++ b/addon-sdk/source/lib/sdk/tabs/tab-fennec.js
@@ -5,17 +5,17 @@
 
 const { Cc, Ci } = require('chrome');
 const { Class } = require('../core/heritage');
 const { tabNS, rawTabNS } = require('./namespace');
 const { EventTarget } = require('../event/target');
 const { activateTab, getTabTitle, setTabTitle, closeTab, getTabURL, getTabContentWindow,
         getTabForBrowser,
         setTabURL, getOwnerWindow, getTabContentType, getTabId } = require('./utils');
-const { emit } = require('../event/core');
+const { emit } = require('../view/core');
 const { getOwnerWindow: getPBOwnerWindow } = require('../private-browsing/window/utils');
 const { when: unload } = require('../system/unload');
 const { viewFor } = require('../event/core');
 const { EVENTS } = require('./events');
 
 const ERR_FENNEC_MSG = 'This method is not yet supported by Fennec';
 
 const Tab = Class({
--- a/browser/base/content/browser-appmenu.inc
+++ b/browser/base/content/browser-appmenu.inc
@@ -198,19 +198,25 @@
                 label="&syncSetup.label;"
                 observes="sync-setup-state"
                 oncommand="gSyncUI.openSetup()"/>
       <menuitem id="sync-syncnowitem-appmenu"
                 label="&syncSyncNowItem.label;"
                 observes="sync-syncnow-state"
                 oncommand="gSyncUI.doSync(event);"/>
 #endif
+#ifdef HAVE_SHELL_SERVICE
+#ifdef XP_WIN
+#ifdef MOZ_METRO
       <menuitem id="switch-to-metro"
                 label="&switchToMetroCmd2.label;"
                 oncommand="SwitchToMetro()"/>
+#endif
+#endif
+#endif
       <menuitem id="appmenu-quit"
                 class="menuitem-iconic"
 #ifdef XP_WIN
                 label="&quitApplicationCmdWin.label;"
 #else
                 label="&quitApplicationCmd.label;"
 #endif
                 command="cmd_quitApplication"/>
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -2559,19 +2559,25 @@ function isInWin8() {
   let osName = sysInfo.getProperty("name");
   let version = sysInfo.getProperty("version");
 
   // Windows 8 is version >= 6.2
   return osName == "Windows_NT" && version >= 6.2;
 }
 
 function updateSwitchToMetroVisibility() {
+#ifdef HAVE_SHELL_SERVICE
+#ifdef XP_WIN
+#ifdef MOZ_METRO
   if (PrivateBrowsingUtils.isWindowPrivate(window) || !isInWin8()) {
     document.getElementById("switch-to-metro").hidden = true;
   }
+#endif
+#endif
+#endif
 }
 
 function onFullScreen(event) {
   FullScreen.toggle(event);
 }
 
 function onMozEnteredDomFullscreen(event) {
   FullScreen.enterDomFullscreen(event);
--- a/browser/metro/base/content/flyoutpanels/AboutFlyoutPanel.js
+++ b/browser/metro/base/content/flyoutpanels/AboutFlyoutPanel.js
@@ -273,35 +273,38 @@ appUpdater.prototype =
                        getService(Components.interfaces.nsIAppStartup);
 
       // If already in safe mode restart in safe mode (bug 327119)
       if (Services.appinfo.inSafeMode) {
         appStartup.restartInSafeMode(Components.interfaces.nsIAppStartup.eAttemptQuit);
         return;
       }
 
+      Services.metro.updatePending = true;
       appStartup.quit(Components.interfaces.nsIAppStartup.eAttemptQuit |
                       Components.interfaces.nsIAppStartup.eRestartTouchEnvironment);
       return;
     }
 
-    const URI_UPDATE_PROMPT_DIALOG = "chrome://mozapps/content/update/updates.xul";
+    // XXX We can't create dialogs in metro, and we currently don't support addons, so
+    // commenting this out for now.
+    /* const URI_UPDATE_PROMPT_DIALOG = "chrome://mozapps/content/update/updates.xul";
     // Firefox no longer displays a license for updates and the licenseURL check
     // is just in case a distibution does.
     if (this.update && (this.update.billboardURL || this.update.licenseURL ||
         this.addons.length != 0)) {
       var ary = null;
       ary = Components.classes["@mozilla.org/supports-array;1"].
             createInstance(Components.interfaces.nsISupportsArray);
       ary.AppendElement(this.update);
       var openFeatures = "chrome,centerscreen,dialog=no,resizable=no,titlebar,toolbar=no";
       Services.ww.openWindow(null, URI_UPDATE_PROMPT_DIALOG, "", openFeatures, ary);
       window.close();
       return;
-    }
+    }*/
 
     this.selectPanel("checkingForUpdates");
     this.isChecking = true;
     this.checker.checkForUpdates(this.updateCheckListener, true);
   },
 
   /**
    * Implements nsIUpdateCheckListener. The methods implemented by
--- a/browser/metro/components/HelperAppDialog.js
+++ b/browser/metro/components/HelperAppDialog.js
@@ -104,29 +104,29 @@ HelperAppLauncherDialog.prototype = {
         callback: function() { aLauncher.cancel(Cr.NS_BINDING_ABORTED); }
       }
     ];
 
     let window = Services.wm.getMostRecentWindow("navigator:browser");
     let chromeWin = this._getChromeWindow(window).wrappedJSObject;
     let notificationBox = chromeWin.Browser.getNotificationBox();
     let document = notificationBox.ownerDocument;
-    downloadSize = this._getDownloadSize(aLauncher.contentLength);
+    let downloadSize = this._getDownloadSize(aLauncher.contentLength);
 
     let msg = browserBundle.GetStringFromName("alertDownloadSave2");
 
     let fragment =  ContentUtil.populateFragmentFromString(
                       document.createDocumentFragment(),
                       msg,
                       {
                         text: aLauncher.suggestedFileName,
                         className: "download-filename-text"
                       },
                       {
-                        text: aLauncher.downloadSize,
+                        text: downloadSize,
                         className: "download-size-text"
                       },
                       {
                         text: aLauncher.source.host,
                         className: "download-host-text"
                       }
                     );
     let newBar = notificationBox.appendNotification("",
--- a/browser/metro/shell/commandexecutehandler/CEHHelper.cpp
+++ b/browser/metro/shell/commandexecutehandler/CEHHelper.cpp
@@ -8,46 +8,49 @@
 
 #ifdef SHOW_CONSOLE
 #include <io.h> // _open_osfhandle
 #endif
 
 HANDLE sCon;
 LPCWSTR metroDX10Available = L"MetroD3DAvailable";
 LPCWSTR metroLastAHE = L"MetroLastAHE";
+LPCWSTR cehDumpDebugStrings = L"CEHDump";
+extern const WCHAR* kFirefoxExe;
 
 typedef HRESULT (WINAPI*D3D10CreateDevice1Func)
   (IDXGIAdapter *, D3D10_DRIVER_TYPE, HMODULE, UINT,
    D3D10_FEATURE_LEVEL1, UINT, ID3D10Device1 **);
 typedef HRESULT(WINAPI*CreateDXGIFactory1Func)(REFIID , void **);
 
 void
 Log(const wchar_t *fmt, ...)
 {
 #if !defined(SHOW_CONSOLE)
-  return;
+  DWORD dwRes = 0;
+  if (!GetDWORDRegKey(cehDumpDebugStrings, dwRes) || !dwRes) {
+    return;
+  }
 #endif
   va_list a = nullptr;
   wchar_t szDebugString[1024];
   if(!lstrlenW(fmt))
     return;
   va_start(a,fmt);
   vswprintf(szDebugString, 1024, fmt, a);
   va_end(a);
   if(!lstrlenW(szDebugString))
     return;
 
   DWORD len;
   WriteConsoleW(sCon, szDebugString, lstrlenW(szDebugString), &len, nullptr);
   WriteConsoleW(sCon, L"\n", 1, &len, nullptr);
 
-  if (IsDebuggerPresent()) {  
-    OutputDebugStringW(szDebugString);
-    OutputDebugStringW(L"\n");
-  }
+  OutputDebugStringW(szDebugString);
+  OutputDebugStringW(L"\n");
 }
 
 #if defined(SHOW_CONSOLE)
 void
 SetupConsole()
 {
   FILE *fp;
   AllocConsole();
@@ -103,16 +106,28 @@ IsProcessRunning(const wchar_t *processN
       }
     }
   }
 
   CloseHandle(snapshot);
   return exists;
 }
 
+bool
+IsMetroProcessRunning()
+{
+  return IsProcessRunning(kFirefoxExe, true);
+}
+
+bool
+IsDesktopProcessRunning()
+{
+  return IsProcessRunning(kFirefoxExe, false);
+}
+
 /*
  * Retrieve the last front end ui we launched so we can target it
  * again. This value is updated down in nsAppRunner when the browser
  * starts up.
  */
 AHE_TYPE
 GetLastAHE()
 {
--- a/browser/metro/shell/commandexecutehandler/CEHHelper.h
+++ b/browser/metro/shell/commandexecutehandler/CEHHelper.h
@@ -26,9 +26,10 @@ void SetupConsole();
 #endif
 
 AHE_TYPE GetLastAHE();
 bool SetLastAHE(AHE_TYPE ahe);
 bool IsDX10Available();
 bool GetDWORDRegKey(LPCWSTR name, DWORD &value);
 bool SetDWORDRegKey(LPCWSTR name, DWORD value);
 bool IsImmersiveProcessDynamic(HANDLE process);
-bool IsProcessRunning(const wchar_t *processName, bool bCheckIfMetro);
+bool IsMetroProcessRunning();
+bool IsDesktopProcessRunning();
--- a/browser/metro/shell/commandexecutehandler/CommandExecuteHandler.cpp
+++ b/browser/metro/shell/commandexecutehandler/CommandExecuteHandler.cpp
@@ -27,27 +27,20 @@
 
 // Heartbeat timer duration used while waiting for an incoming request.
 #define HEARTBEAT_MSEC 1000
 // Total number of heartbeats we wait before giving up and shutting down.
 #define REQUEST_WAIT_TIMEOUT 30
 // Pulled from desktop browser's shell
 #define APP_REG_NAME L"Firefox"
 
-// If we have a restart request, attempt to wait up to RESTART_WAIT_TIMEOUT
-// until the previous instance closes.  We don't want to wait too long
-// because the browser could appear to randomly start for the user. We want
-// it to also be long enough so the browser has time to close.
-#define RESTART_WAIT_PER_RETRY 50
-#define RESTART_WAIT_TIMEOUT 38000
-
-static const WCHAR* kFirefoxExe = L"firefox.exe";
-static const WCHAR* kMetroFirefoxExe = L"firefox.exe";
+const WCHAR* kFirefoxExe = L"firefox.exe";
 static const WCHAR* kDefaultMetroBrowserIDPathKey = L"FirefoxURL";
 static const WCHAR* kMetroRestartCmdLine = L"--metro-restart";
+static const WCHAR* kMetroUpdateCmdLine = L"--metro-update";
 static const WCHAR* kDesktopRestartCmdLine = L"--desktop-restart";
 
 static bool GetDefaultBrowserPath(CStringW& aPathBuffer);
 
 /*
  * Retrieve our module dir path.
  *
  * @aPathBuffer Buffer to fill
@@ -91,32 +84,33 @@ class __declspec(uuid("5100FEC1-212B-4BF
                         public IObjectWithSelection,
                         public IInitializeCommand,
                         public IObjectWithSite,
                         public IExecuteCommandApplicationHostEnvironment
 {
 public:
 
   CExecuteCommandVerb() :
-    mRef(1),
+    mRef(0),
     mShellItemArray(nullptr),
     mUnkSite(nullptr),
     mTargetIsFileSystemLink(false),
     mTargetIsDefaultBrowser(false),
     mTargetIsBrowser(false),
-    mIsDesktopRequest(true),
-    mIsRestartMetroRequest(false),
-    mIsRestartDesktopRequest(false),
+    mRequestType(DEFAULT_LAUNCH),
     mRequestMet(false),
+    mDelayedLaunchType(NONE),
     mVerb(L"open")
   {
   }
 
   bool RequestMet() { return mRequestMet; }
+  void SetRequestMet();
   long RefCount() { return mRef; }
+  void HeartBeat();
 
   // IUnknown
   IFACEMETHODIMP QueryInterface(REFIID aRefID, void **aInt)
   {
     static const QITAB qit[] = {
       QITABENT(CExecuteCommandVerb, IExecuteCommand),
       QITABENT(CExecuteCommandVerb, IObjectWithSelection),
       QITABENT(CExecuteCommandVerb, IInitializeCommand),
@@ -147,20 +141,22 @@ public:
     mKeyState = aKeyState;
     return S_OK;
   }
 
   IFACEMETHODIMP SetParameters(PCWSTR aParameters)
   {
     Log(L"SetParameters: '%s'", aParameters);
 
-    if (_wcsicmp(aParameters, kMetroRestartCmdLine) == 0) {
-      mIsRestartMetroRequest = true;
+    if (!_wcsicmp(aParameters, kMetroRestartCmdLine)) {
+      mRequestType = METRO_RESTART;
+    } else if (_wcsicmp(aParameters, kMetroUpdateCmdLine) == 0) {
+      mRequestType = METRO_UPDATE;
     } else if (_wcsicmp(aParameters, kDesktopRestartCmdLine) == 0) {
-      mIsRestartDesktopRequest = true;
+      mRequestType = DESKTOP_RESTART;
     } else {
       mParameters = aParameters;
     }
     return S_OK;
   }
 
   IFACEMETHODIMP SetPosition(POINT aPoint)
   { return S_OK; }
@@ -257,62 +253,67 @@ public:
     return mUnkSite ? mUnkSite->QueryInterface(aRefID, aInt) : E_FAIL;
   }
 
   // IExecuteCommandApplicationHostEnvironment
   IFACEMETHODIMP GetValue(AHE_TYPE *aLaunchType)
   {
     Log(L"IExecuteCommandApplicationHostEnvironment::GetValue()");
     *aLaunchType = GetLaunchType();
-    mIsDesktopRequest = (*aLaunchType == AHE_DESKTOP);
     return S_OK;
   }
 
   /**
    * Choose the appropriate launch type based on the user's previously chosen
    * host environment, along with system constraints.
    *
    * AHE_DESKTOP = 0, AHE_IMMERSIVE = 1
    */
-  AHE_TYPE GetLaunchType() {
+  AHE_TYPE GetLaunchType()
+  {
     AHE_TYPE ahe = GetLastAHE();
     Log(L"Previous AHE: %d", ahe);
 
-    if (!mIsRestartMetroRequest && IsProcessRunning(kFirefoxExe, false)) {
-      Log(L"Returning AHE_DESKTOP because desktop is already running");
-      return AHE_DESKTOP;
-    } else if (!mIsRestartDesktopRequest && IsProcessRunning(kMetroFirefoxExe, true)) {
-      Log(L"Returning AHE_IMMERSIVE because Metro is already running");
-      return AHE_IMMERSIVE;
-    }
-
-    if (mIsRestartDesktopRequest) {
+    // Default launch settings from GetLastAHE() can be overriden by
+    // custom parameter values we receive. 
+    if (mRequestType == DESKTOP_RESTART) {
       Log(L"Restarting in desktop host environment.");
       return AHE_DESKTOP;
-    }
-
-    if (mIsRestartMetroRequest) {
+    } else if (mRequestType == METRO_RESTART) {
       Log(L"Restarting in metro host environment.");
       ahe = AHE_IMMERSIVE;
+    } else if (mRequestType == METRO_UPDATE) {
+      // Shouldn't happen from GetValue above, but might from other calls.
+      ahe = AHE_IMMERSIVE;
     }
 
     if (ahe == AHE_IMMERSIVE) {
       if (!IsDefaultBrowser()) {
         Log(L"returning AHE_DESKTOP because we are not the default browser");
         return AHE_DESKTOP;
       }
 
       if (!IsDX10Available()) {
         Log(L"returning AHE_DESKTOP because DX10 is not available");
         return AHE_DESKTOP;
       }
     }
     return ahe;
   }
 
+  bool DefaultLaunchIsDesktop()
+  {
+    return GetLaunchType() == AHE_DESKTOP;
+  }
+
+  bool DefaultLaunchIsMetro()
+  {
+    return GetLaunchType() == AHE_IMMERSIVE;
+  }
+
   /*
    * Retrieve the target path if it is the default browser
    * or if not default, retreives the target path if it is a firefox browser
    * or if the target is not firefox, relies on a hack to get the
    * 'module dir path\firefox.exe'
    * The reason why it's not good to rely on the CEH path is because there is
    * no guarantee win8 will use the CEH at our expected path.  It has an in
    * memory cache even if the registry is updated for the CEH path.
@@ -381,36 +382,56 @@ public:
     CStringW browserPath;
     GetDefaultBrowserPath(browserPath);
 
     return !selfPath.CompareNoCase(browserPath);
   }
 private:
   ~CExecuteCommandVerb()
   {
-    SafeRelease(&mShellItemArray);
-    SafeRelease(&mUnkSite);
   }
 
   void LaunchDesktopBrowser();
+  bool LaunchMetroBrowser();
   bool SetTargetPath(IShellItem* aItem);
+  bool TestForUpdateLock();
+
+  /*
+   * Defines the type of startup request we receive.
+   */
+  enum RequestType {
+    DEFAULT_LAUNCH,
+    DESKTOP_RESTART,
+    METRO_RESTART,
+    METRO_UPDATE,
+  };
+
+  RequestType mRequestType;
+
+  /*
+   * Defines the type of delayed launch we might do.
+   */
+  enum DelayedLaunchType {
+    NONE,
+    DESKTOP,
+    METRO,
+  };
+
+  DelayedLaunchType mDelayedLaunchType;
 
   long mRef;
   IShellItemArray *mShellItemArray;
   IUnknown *mUnkSite;
   CStringW mVerb;
   CStringW mTarget;
   CStringW mParameters;
   bool mTargetIsFileSystemLink;
   bool mTargetIsDefaultBrowser;
   bool mTargetIsBrowser;
   DWORD mKeyState;
-  bool mIsDesktopRequest;
-  bool mIsRestartMetroRequest;
-  bool mIsRestartDesktopRequest;
   bool mRequestMet;
 };
 
 /*
  * Retrieve the current default browser's path.
  *
  * @aPathBuffer Buffer to fill
  */
@@ -583,17 +604,17 @@ void LaunchDesktopBrowserWithParams(CStr
   }
 
   // Tack on any extra parameters we received (for example -profilemanager)
   if (!aParameters.IsEmpty()) {
     params += " ";
     params += aParameters;
   }
 
-  Log(L"Desktop Launch: verb:%s exe:%s params:%s", aVerb, aBrowserPath, params);
+  Log(L"Desktop Launch: verb:'%s' exe:'%s' params:'%s'", aVerb, aBrowserPath, params);
 
   // Relaunch in Desktop mode uses a special URL to trick Windows into
   // switching environments. We shouldn't actually try to open this URL.
   if (!_wcsicmp(aTarget, L"http://-desktop/")) {
     // Ignore any params and just launch on desktop
     params.Empty();
   }
 
@@ -619,169 +640,165 @@ void LaunchDesktopBrowserWithParams(CStr
   if (!AllowSetForegroundWindow(procInfo.dwProcessId)) {
     Log(L"AllowSetForegroundWindow failed! (%d)", GetLastError());
   }
   CloseHandle(procInfo.hThread);
   CloseHandle(procInfo.hProcess);
   Log(L"Desktop browser process id: %d", procInfo.dwProcessId);
 }
 
-void CExecuteCommandVerb::LaunchDesktopBrowser()
+void
+CExecuteCommandVerb::LaunchDesktopBrowser()
 {
   CStringW browserPath;
   if (!GetDesktopBrowserPath(browserPath)) {
     return;
   }
 
   LaunchDesktopBrowserWithParams(browserPath, mVerb, mTarget, mParameters,
                                  mTargetIsDefaultBrowser, mTargetIsBrowser);
 }
 
-class AutoSetRequestMet
+void
+CExecuteCommandVerb::HeartBeat()
 {
-public:
-  explicit AutoSetRequestMet(bool* aFlag) :
-    mFlag(aFlag) {}
-  ~AutoSetRequestMet() { if (mFlag) *mFlag = true; }
-private:
-  bool* mFlag;
-};
+  if (mRequestType == METRO_UPDATE && mDelayedLaunchType == DESKTOP &&
+      !IsMetroProcessRunning()) {
+    mDelayedLaunchType = NONE;
+    LaunchDesktopBrowser();
+    SetRequestMet();
+  }
+  if (mDelayedLaunchType == METRO && !TestForUpdateLock()) {
+    mDelayedLaunchType = NONE;
+    LaunchMetroBrowser();
+    SetRequestMet();
+  }
+}
 
-static HRESULT
+static bool
 PrepareActivationManager(CComPtr<IApplicationActivationManager> &activateMgr)
 {
   HRESULT hr = activateMgr.CoCreateInstance(CLSID_ApplicationActivationManager,
                                             nullptr, CLSCTX_LOCAL_SERVER);
   if (FAILED(hr)) {
     Log(L"CoCreateInstance failed, launching on desktop.");
-    return E_FAIL;
+    return false;
   }
 
   // Hand off focus rights to the out-of-process activation server. Without
   // this the metro interface won't launch.
   hr = CoAllowSetForegroundWindow(activateMgr, nullptr);
   if (FAILED(hr)) {
     Log(L"CoAllowSetForegroundWindow result %X", hr);
-    return E_FAIL;
-  }
-
-  return S_OK;
-}
-
-DWORD WINAPI
-DelayedExecuteThread(LPVOID param)
-{
-  Log(L"Starting delayed execute thread...");
-  bool &bRequestMet(*(bool*)param);
-  AutoSetRequestMet asrm(&bRequestMet);
-
-  CoInitialize(nullptr);
-
-  CComPtr<IApplicationActivationManager> activateMgr;
-  if (FAILED(PrepareActivationManager(activateMgr))) {
-      Log(L"Warning: Could not prepare activation manager");
+    return false;
   }
 
-  size_t currentWaitTime = 0;
-  while(currentWaitTime < RESTART_WAIT_TIMEOUT) {
-    if (!IsProcessRunning(kMetroFirefoxExe, true))
-      break;
-    currentWaitTime += RESTART_WAIT_PER_RETRY;
-    Sleep(RESTART_WAIT_PER_RETRY);
-  }
-
-  Log(L"Done waiting, getting app ID");
-  // Activate the application as long as we can obtian the appModelID
-  WCHAR appModelID[256];
-  if (GetDefaultBrowserAppModelID(appModelID)) {
-    Log(L"Activating application");
-    DWORD processID;
-    HRESULT hr = activateMgr->ActivateApplication(appModelID, L"", AO_NOERRORUI, &processID);
-    if (SUCCEEDED(hr)) {
-      Log(L"Activate application succeeded");
-    } else {
-      Log(L"Activate application failed! (%x)", hr);
-    }
-  }
-
-  CoUninitialize();
-  return 0;
+  return true;
 }
 
-IFACEMETHODIMP CExecuteCommandVerb::Execute()
+bool
+CExecuteCommandVerb::TestForUpdateLock()
 {
-  Log(L"Execute()");
-
-  if (!mTarget.GetLength()) {
-    // We shut down when this flips to true
-    mRequestMet = true;
-    return E_FAIL;
+  CStringW browserPath;
+  if (!GetDefaultBrowserPath(browserPath)) {
+    return false;
   }
-
-  if (mIsRestartMetroRequest) {
-    HANDLE thread = CreateThread(nullptr, 0, DelayedExecuteThread,
-                                 &mRequestMet, 0, nullptr);
-    CloseHandle(thread);
-    return S_OK;
-  }
-
-  if (mIsRestartDesktopRequest) {
-    CStringW browserPath;
-    if (!GetDesktopBrowserPath(browserPath)) {
-      return E_FAIL;
-    }
+
+  HANDLE hFile = CreateFileW(browserPath,
+                             FILE_EXECUTE, FILE_SHARE_READ|FILE_SHARE_WRITE,
+                             nullptr, OPEN_EXISTING, 0, nullptr);
+  if (hFile != INVALID_HANDLE_VALUE) {
+    CloseHandle(hFile);
+    return false;
+  }
+  return true;
+}
 
-    LaunchDesktopBrowserWithParams(browserPath,
-                                   mVerb,
-                                   mTarget,
-                                   mParameters,
-                                   mTargetIsDefaultBrowser,
-                                   mTargetIsBrowser);
-    return S_OK;
-  }
-
-  // We shut down when this flips to true
-  AutoSetRequestMet asrm(&mRequestMet);
-
-  // Launch on the desktop
-  if (mIsDesktopRequest) {
-    LaunchDesktopBrowser();
-    return S_OK;
-  }
-
+bool
+CExecuteCommandVerb::LaunchMetroBrowser()
+{
+  // Launch in metro
   CComPtr<IApplicationActivationManager> activateMgr;
-  if (FAILED(PrepareActivationManager(activateMgr))) {
-      LaunchDesktopBrowser();
-      return S_OK;
+  if (!PrepareActivationManager(activateMgr)) {
+    return false;
   }
 
   HRESULT hr;
   WCHAR appModelID[256];
   if (!GetDefaultBrowserAppModelID(appModelID)) {
-    Log(L"GetDefaultBrowserAppModelID failed, launching on desktop.");
-    LaunchDesktopBrowser();
-    return S_OK;
+    Log(L"GetDefaultBrowserAppModelID failed.");
+    return false;
   }
 
-  Log(L"Metro Launch: verb:%s appid:%s params:%s", mVerb, appModelID, mTarget);
+  Log(L"Metro Launch: verb:'%s' appid:'%s' params:'%s'", mVerb, appModelID, mTarget);
 
   // shortcuts to the application
   DWORD processID;
   if (mTargetIsDefaultBrowser) {
     hr = activateMgr->ActivateApplication(appModelID, L"", AO_NONE, &processID);
     Log(L"ActivateApplication result %X", hr);
   // files
   } else if (mTargetIsFileSystemLink) {
     hr = activateMgr->ActivateForFile(appModelID, mShellItemArray, mVerb, &processID);
     Log(L"ActivateForFile result %X", hr);
   // protocols
   } else {
     hr = activateMgr->ActivateForProtocol(appModelID, mShellItemArray, &processID);
     Log(L"ActivateForProtocol result %X", hr);
   }
+  return true;
+}
+
+void CExecuteCommandVerb::SetRequestMet()
+{
+  SafeRelease(&mShellItemArray);
+  SafeRelease(&mUnkSite);
+  mRequestMet = true;
+  Log(L"Request met, exiting.");
+}
+
+IFACEMETHODIMP CExecuteCommandVerb::Execute()
+{
+  Log(L"Execute()");
+
+  if (!mTarget.GetLength()) {
+    // We shut down when this flips to true
+    SetRequestMet();
+    return E_FAIL;
+  }
+
+  // Deal with metro restart for an update - launch desktop with a command
+  // that tells it to run updater then launch the metro browser.
+  if (mRequestType == METRO_UPDATE) {
+    // We'll complete this in the heart beat callback from the main msg loop.
+    // We do this because the last browser instance makes this call to Execute
+    // sync. So we want to make sure it's completely shutdown before we do
+    // the update.
+    mParameters = kMetroUpdateCmdLine;
+    mDelayedLaunchType = DESKTOP;
+    return S_OK;
+  }
+
+  // Launch on the desktop
+  if (mRequestType == DESKTOP_RESTART ||
+      (mRequestType == DEFAULT_LAUNCH && DefaultLaunchIsDesktop())) {
+    LaunchDesktopBrowser();
+    SetRequestMet();
+    return S_OK;
+  }
+
+  // If we have an update in the works, don't try to activate yet,
+  // delay until the lock is removed.
+  if (TestForUpdateLock()) {
+    mDelayedLaunchType = METRO;
+    return S_OK;
+  }
+
+  LaunchMetroBrowser();
+  SetRequestMet();
   return S_OK;
 }
 
 class ClassFactory : public IClassFactory 
 {
 public:
   ClassFactory(IUnknown *punkObject);
   ~ClassFactory();
@@ -859,18 +876,16 @@ ClassFactory::LockServer(BOOL fLock)
   return S_OK;
 }
 
 int APIENTRY wWinMain(HINSTANCE, HINSTANCE, PWSTR pszCmdLine, int)
 {
 #if defined(SHOW_CONSOLE)
   SetupConsole();
 #endif
-  //Log(pszCmdLine);
-
   if (!wcslen(pszCmdLine) || StrStrI(pszCmdLine, L"-Embedding"))
   {
       CoInitialize(nullptr);
 
       CExecuteCommandVerb *pHandler = new CExecuteCommandVerb();
       if (!pHandler)
         return E_OUTOFMEMORY;
 
@@ -891,16 +906,17 @@ int APIENTRY wWinMain(HINSTANCE, HINSTAN
         Log(L"Failed to set timer, can't process request.");
         return -1;
       }
 
       MSG msg;
       long beatCount = 0;
       while (GetMessage(&msg, 0, 0, 0) > 0) {
         if (msg.message == WM_TIMER) {
+          pHandler->HeartBeat();
           if (++beatCount > REQUEST_WAIT_TIMEOUT ||
               (pHandler->RequestMet() && pHandler->RefCount() < 2)) {
             break;
           }
         }
         TranslateMessage(&msg);
         DispatchMessage(&msg);
       }
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -7012,17 +7012,17 @@ nsGlobalWindow::ClearInterval(int32_t aH
     ClearTimeoutOrInterval(aHandle, aError);
   }
 }
 
 NS_IMETHODIMP
 nsGlobalWindow::ClearInterval(int32_t aHandle)
 {
   ErrorResult rv;
-  ClearTimeoutOrInterval(aHandle, rv);
+  ClearInterval(aHandle, rv);
 
   return rv.ErrorCode();
 }
 
 NS_IMETHODIMP
 nsGlobalWindow::SetTimeout(int32_t *_retval)
 {
   return SetTimeoutOrInterval(false, _retval);
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -2092,17 +2092,17 @@ TabChild::AllocPOfflineCacheUpdateChild(
   NS_RUNTIMEABORT("unused");
   return nullptr;
 }
 
 bool
 TabChild::DeallocPOfflineCacheUpdateChild(POfflineCacheUpdateChild* actor)
 {
   OfflineCacheUpdateChild* offlineCacheUpdate = static_cast<OfflineCacheUpdateChild*>(actor);
-  delete offlineCacheUpdate;
+  NS_RELEASE(offlineCacheUpdate);
   return true;
 }
 
 bool
 TabChild::RecvLoadRemoteScript(const nsString& aURL)
 {
   if (!mGlobal && !InitTabChildGlobal())
     // This can happen if we're half-destroyed.  It's not a fatal
--- a/dom/system/OSFileConstants.cpp
+++ b/dom/system/OSFileConstants.cpp
@@ -23,16 +23,17 @@
 #endif // defined(XP_LINUX)
 
 #if defined(XP_MACOSX)
 #include "copyfile.h"
 #endif // defined(XP_MACOSX)
 
 #if defined(XP_WIN)
 #include <windows.h>
+#include <accctrl.h>
 #endif // defined(XP_WIN)
 
 #include "jsapi.h"
 #include "jsfriendapi.h"
 #include "BindingUtils.h"
 
 // Used to provide information on the OS
 
@@ -657,16 +658,21 @@ static const dom::ConstantSpec gWinPrope
 
   // MoveFile flags
   INT_CONSTANT(MOVEFILE_COPY_ALLOWED),
   INT_CONSTANT(MOVEFILE_REPLACE_EXISTING),
 
   // GetFileAttributes error constant
   INT_CONSTANT(INVALID_FILE_ATTRIBUTES),
 
+  // GetNamedSecurityInfo and SetNamedSecurityInfo constants
+  INT_CONSTANT(UNPROTECTED_DACL_SECURITY_INFORMATION),
+  INT_CONSTANT(SE_FILE_OBJECT),
+  INT_CONSTANT(DACL_SECURITY_INFORMATION),
+
   // Errors
   INT_CONSTANT(ERROR_ACCESS_DENIED),
   INT_CONSTANT(ERROR_DIR_NOT_EMPTY),
   INT_CONSTANT(ERROR_FILE_EXISTS),
   INT_CONSTANT(ERROR_ALREADY_EXISTS),
   INT_CONSTANT(ERROR_FILE_NOT_FOUND),
   INT_CONSTANT(ERROR_NO_MORE_FILES),
   INT_CONSTANT(ERROR_PATH_NOT_FOUND),
--- a/gfx/2d/FilterNodeSoftware.cpp
+++ b/gfx/2d/FilterNodeSoftware.cpp
@@ -230,17 +230,19 @@ CopyRect(DataSourceSurface* aSrc, DataSo
   }
 }
 
 TemporaryRef<DataSourceSurface>
 CloneAligned(DataSourceSurface* aSource)
 {
   RefPtr<DataSourceSurface> copy =
     Factory::CreateDataSourceSurface(aSource->GetSize(), aSource->GetFormat());
-  CopyRect(aSource, copy, IntRect(IntPoint(), aSource->GetSize()), IntPoint());
+  if (copy) {
+    CopyRect(aSource, copy, IntRect(IntPoint(), aSource->GetSize()), IntPoint());
+  }
   return copy;
 }
 
 static void
 FillRectWithPixel(DataSourceSurface *aSurface, const IntRect &aFillRect, IntPoint aPixelPos)
 {
   uint8_t* data = aSurface->GetData();
   uint8_t* sourcePixelData = data + DataOffset(aSurface, aPixelPos);
@@ -725,29 +727,30 @@ FilterNodeSoftware::GetInputDataSourceSu
     IntRect srcRect = aTransparencyPaddedSourceRect->Intersect(aRect);
     surface = GetDataSurfaceInRect(surface, surfaceRect, srcRect, EDGE_MODE_NONE);
     surfaceRect = srcRect;
   }
 
   RefPtr<DataSourceSurface> result =
     GetDataSurfaceInRect(surface, surfaceRect, aRect, aEdgeMode);
 
+  if (result &&
+      (result->Stride() != GetAlignedStride<16>(result->Stride()) ||
+      reinterpret_cast<uintptr_t>(result->GetData()) % 16 != 0)) {
+    // Align unaligned surface.
+    result = CloneAligned(result);
+  }
+
   if (!result) {
 #ifdef DEBUG_DUMP_SURFACES
     printf(" -- no input --</section>\n\n");
 #endif
     return nullptr;
   }
 
-  if (result->Stride() != GetAlignedStride<16>(result->Stride()) ||
-      reinterpret_cast<uintptr_t>(result->GetData()) % 16 != 0) {
-    // Align unaligned surface.
-    result = CloneAligned(result);
-  }
-
   SurfaceFormat currentFormat = result->GetFormat();
   if (DesiredFormat(currentFormat, aFormatHint) == FORMAT_B8G8R8A8 &&
       currentFormat != FORMAT_B8G8R8A8) {
     result = FilterProcessing::ConvertToB8G8R8A8(result);
   }
 
 #ifdef DEBUG_DUMP_SURFACES
   printf("<img src='"); DumpAsPNG(result); printf("'></section>");
--- a/layout/reftests/mathml/menclose-1-ref.html
+++ b/layout/reftests/mathml/menclose-1-ref.html
@@ -1,9 +1,21 @@
+<!-- -*- mode: HTML; tab-width: 2; indent-tabs-mode: nil; -*- -->
+<!-- vim: set tabstop=2 expandtab shiftwidth=2 textwidth=80:  -->
 <!DOCTYPE html>
 <html>
-  <head><title>Updiagonalarrow</title></head>
+  <head>
+    <title>Test menclose</title>
+    <!-- Copyright (c) 2011 Design Science, Inc.
+         License: Apache License 2.0 -->
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  </head>
+
   <body>
-
-    <p><math><menclose notation="updiagonalstrike"><mspace width="50px" height="50px"/></menclose></math></p>
+    <!-- menclose: test that attributes have an effect  -->
+    <math>
+      <menclose notation="">
+        <mspace width="100px" height="50px"></mspace>
+      </menclose>
+    </math>
 
   </body>
 </html>
deleted file mode 100644
--- a/layout/reftests/mathml/menclose-1.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <head><title>Updiagonalarrow</title></head>
-  <body>
-
-    <p><math><menclose><mspace width="50px" height="50px"/></menclose></math></p>
-
-  </body>
-</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/menclose-1a.html
@@ -0,0 +1,21 @@
+<!-- -*- mode: HTML; tab-width: 2; indent-tabs-mode: nil; -*- -->
+<!-- vim: set tabstop=2 expandtab shiftwidth=2 textwidth=80:  -->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Test menclose</title>
+    <!-- Copyright (c) 2011 Design Science, Inc.
+         License: Apache License 2.0 -->
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  </head>
+
+  <body>
+    <!-- menclose: test that attributes have an effect  -->
+    <math>
+      <menclose notation="longdiv">
+        <mspace width="100px" height="50px"></mspace>
+      </menclose>
+    </math>
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/menclose-1b.html
@@ -0,0 +1,21 @@
+<!-- -*- mode: HTML; tab-width: 2; indent-tabs-mode: nil; -*- -->
+<!-- vim: set tabstop=2 expandtab shiftwidth=2 textwidth=80:  -->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Test menclose</title>
+    <!-- Copyright (c) 2011 Design Science, Inc.
+         License: Apache License 2.0 -->
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  </head>
+
+  <body>
+    <!-- menclose: test that attributes have an effect  -->
+    <math>
+      <menclose notation="actuarial">
+        <mspace width="100px" height="50px"></mspace>
+      </menclose>
+    </math>
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/menclose-1c.html
@@ -0,0 +1,21 @@
+<!-- -*- mode: HTML; tab-width: 2; indent-tabs-mode: nil; -*- -->
+<!-- vim: set tabstop=2 expandtab shiftwidth=2 textwidth=80:  -->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Test menclose</title>
+    <!-- Copyright (c) 2011 Design Science, Inc.
+         License: Apache License 2.0 -->
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  </head>
+
+  <body>
+    <!-- menclose: test that attributes have an effect  -->
+    <math>
+      <menclose notation="radical">
+        <mspace width="100px" height="50px"></mspace>
+      </menclose>
+    </math>
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/menclose-1d.html
@@ -0,0 +1,21 @@
+<!-- -*- mode: HTML; tab-width: 2; indent-tabs-mode: nil; -*- -->
+<!-- vim: set tabstop=2 expandtab shiftwidth=2 textwidth=80:  -->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Test menclose</title>
+    <!-- Copyright (c) 2011 Design Science, Inc.
+         License: Apache License 2.0 -->
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  </head>
+
+  <body>
+    <!-- menclose: test that attributes have an effect  -->
+    <math>
+      <menclose notation="box">
+        <mspace width="100px" height="50px"></mspace>
+      </menclose>
+    </math>
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/menclose-1e.html
@@ -0,0 +1,21 @@
+<!-- -*- mode: HTML; tab-width: 2; indent-tabs-mode: nil; -*- -->
+<!-- vim: set tabstop=2 expandtab shiftwidth=2 textwidth=80:  -->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Test menclose</title>
+    <!-- Copyright (c) 2011 Design Science, Inc.
+         License: Apache License 2.0 -->
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  </head>
+
+  <body>
+    <!-- menclose: test that attributes have an effect  -->
+    <math>
+      <menclose notation="roundedbox">
+        <mspace width="100px" height="50px"></mspace>
+      </menclose>
+    </math>
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/menclose-1f.html
@@ -0,0 +1,21 @@
+<!-- -*- mode: HTML; tab-width: 2; indent-tabs-mode: nil; -*- -->
+<!-- vim: set tabstop=2 expandtab shiftwidth=2 textwidth=80:  -->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Test menclose</title>
+    <!-- Copyright (c) 2011 Design Science, Inc.
+         License: Apache License 2.0 -->
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  </head>
+
+  <body>
+    <!-- menclose: test that attributes have an effect  -->
+    <math>
+      <menclose notation="circle">
+        <mspace width="100px" height="50px"></mspace>
+      </menclose>
+    </math>
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/menclose-1g.html
@@ -0,0 +1,21 @@
+<!-- -*- mode: HTML; tab-width: 2; indent-tabs-mode: nil; -*- -->
+<!-- vim: set tabstop=2 expandtab shiftwidth=2 textwidth=80:  -->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Test menclose</title>
+    <!-- Copyright (c) 2011 Design Science, Inc.
+         License: Apache License 2.0 -->
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  </head>
+
+  <body>
+    <!-- menclose: test that attributes have an effect  -->
+    <math>
+      <menclose notation="left">
+        <mspace width="100px" height="50px"></mspace>
+      </menclose>
+    </math>
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/menclose-1h.html
@@ -0,0 +1,21 @@
+<!-- -*- mode: HTML; tab-width: 2; indent-tabs-mode: nil; -*- -->
+<!-- vim: set tabstop=2 expandtab shiftwidth=2 textwidth=80:  -->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Test menclose</title>
+    <!-- Copyright (c) 2011 Design Science, Inc.
+         License: Apache License 2.0 -->
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  </head>
+
+  <body>
+    <!-- menclose: test that attributes have an effect  -->
+    <math>
+      <menclose notation="right">
+        <mspace width="100px" height="50px"></mspace>
+      </menclose>
+    </math>
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/menclose-1i.html
@@ -0,0 +1,21 @@
+<!-- -*- mode: HTML; tab-width: 2; indent-tabs-mode: nil; -*- -->
+<!-- vim: set tabstop=2 expandtab shiftwidth=2 textwidth=80:  -->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Test menclose</title>
+    <!-- Copyright (c) 2011 Design Science, Inc.
+         License: Apache License 2.0 -->
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  </head>
+
+  <body>
+    <!-- menclose: test that attributes have an effect  -->
+    <math>
+      <menclose notation="top">
+        <mspace width="100px" height="50px"></mspace>
+      </menclose>
+    </math>
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/menclose-1j.html
@@ -0,0 +1,21 @@
+<!-- -*- mode: HTML; tab-width: 2; indent-tabs-mode: nil; -*- -->
+<!-- vim: set tabstop=2 expandtab shiftwidth=2 textwidth=80:  -->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Test menclose</title>
+    <!-- Copyright (c) 2011 Design Science, Inc.
+         License: Apache License 2.0 -->
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  </head>
+
+  <body>
+    <!-- menclose: test that attributes have an effect  -->
+    <math>
+      <menclose notation="bottom">
+        <mspace width="100px" height="50px"></mspace>
+      </menclose>
+    </math>
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/menclose-1k.html
@@ -0,0 +1,21 @@
+<!-- -*- mode: HTML; tab-width: 2; indent-tabs-mode: nil; -*- -->
+<!-- vim: set tabstop=2 expandtab shiftwidth=2 textwidth=80:  -->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Test menclose</title>
+    <!-- Copyright (c) 2011 Design Science, Inc.
+         License: Apache License 2.0 -->
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  </head>
+
+  <body>
+    <!-- menclose: test that attributes have an effect  -->
+    <math>
+      <menclose notation="updiagonalstrike">
+        <mspace width="100px" height="50px"></mspace>
+      </menclose>
+    </math>
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/menclose-1l.html
@@ -0,0 +1,21 @@
+<!-- -*- mode: HTML; tab-width: 2; indent-tabs-mode: nil; -*- -->
+<!-- vim: set tabstop=2 expandtab shiftwidth=2 textwidth=80:  -->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Test menclose</title>
+    <!-- Copyright (c) 2011 Design Science, Inc.
+         License: Apache License 2.0 -->
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  </head>
+
+  <body>
+    <!-- menclose: test that attributes have an effect  -->
+    <math>
+      <menclose notation="downdiagonalstrike">
+        <mspace width="100px" height="50px"></mspace>
+      </menclose>
+    </math>
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/menclose-1m.html
@@ -0,0 +1,21 @@
+<!-- -*- mode: HTML; tab-width: 2; indent-tabs-mode: nil; -*- -->
+<!-- vim: set tabstop=2 expandtab shiftwidth=2 textwidth=80:  -->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Test menclose</title>
+    <!-- Copyright (c) 2011 Design Science, Inc.
+         License: Apache License 2.0 -->
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  </head>
+
+  <body>
+    <!-- menclose: test that attributes have an effect  -->
+    <math>
+      <menclose notation="verticalstrike">
+        <mspace width="100px" height="50px"></mspace>
+      </menclose>
+    </math>
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/menclose-1n.html
@@ -0,0 +1,21 @@
+<!-- -*- mode: HTML; tab-width: 2; indent-tabs-mode: nil; -*- -->
+<!-- vim: set tabstop=2 expandtab shiftwidth=2 textwidth=80:  -->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Test menclose</title>
+    <!-- Copyright (c) 2011 Design Science, Inc.
+         License: Apache License 2.0 -->
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  </head>
+
+  <body>
+    <!-- menclose: test that attributes have an effect  -->
+    <math>
+      <menclose notation="horizontalstrike">
+        <mspace width="100px" height="50px"></mspace>
+      </menclose>
+    </math>
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/menclose-1o.html
@@ -0,0 +1,21 @@
+<!-- -*- mode: HTML; tab-width: 2; indent-tabs-mode: nil; -*- -->
+<!-- vim: set tabstop=2 expandtab shiftwidth=2 textwidth=80:  -->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Test menclose</title>
+    <!-- Copyright (c) 2011 Design Science, Inc.
+         License: Apache License 2.0 -->
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  </head>
+
+  <body>
+    <!-- menclose: test that attributes have an effect  -->
+    <math>
+      <menclose notation="madruwb">
+        <mspace width="100px" height="50px"></mspace>
+      </menclose>
+    </math>
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/menclose-1p.html
@@ -0,0 +1,21 @@
+<!-- -*- mode: HTML; tab-width: 2; indent-tabs-mode: nil; -*- -->
+<!-- vim: set tabstop=2 expandtab shiftwidth=2 textwidth=80:  -->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Test menclose</title>
+    <!-- Copyright (c) 2011 Design Science, Inc.
+         License: Apache License 2.0 -->
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  </head>
+
+  <body>
+    <!-- menclose: test that attributes have an effect  -->
+    <math>
+      <menclose notation="updiagonalarrow">
+        <mspace width="100px" height="50px"></mspace>
+      </menclose>
+    </math>
+
+  </body>
+</html>
--- a/layout/reftests/mathml/reftest.list
+++ b/layout/reftests/mathml/reftest.list
@@ -125,17 +125,32 @@ skip-if(B2G) == maction-dynamic-3.html m
 fails == whitespace-trim-4.html whitespace-trim-4-ref.html # Bug 787215
 == whitespace-trim-5.html whitespace-trim-5-ref.html
 == operator-1.xhtml operator-1-ref.xhtml
 == scriptshift-1.xhtml scriptshift-1-ref.xhtml
 == number-size-1.xhtml number-size-1-ref.xhtml
 == multiscripts-1.html multiscripts-1-ref.html
 == mathml-mmultiscript-base.html mathml-mmultiscript-base-ref.html
 == mathml-mmultiscript-mprescript.html mathml-mmultiscript-mprescript-ref.html
-!= menclose-1.html menclose-1-ref.html
+!= menclose-1a.html menclose-1-ref.html
+!= menclose-1b.html menclose-1-ref.html
+!= menclose-1c.html menclose-1-ref.html
+!= menclose-1d.html menclose-1-ref.html
+!= menclose-1e.html menclose-1-ref.html
+!= menclose-1f.html menclose-1-ref.html
+!= menclose-1g.html menclose-1-ref.html
+!= menclose-1h.html menclose-1-ref.html
+!= menclose-1i.html menclose-1-ref.html
+!= menclose-1j.html menclose-1-ref.html
+!= menclose-1k.html menclose-1-ref.html
+!= menclose-1l.html menclose-1-ref.html
+!= menclose-1m.html menclose-1-ref.html
+!= menclose-1n.html menclose-1-ref.html
+!= menclose-1o.html menclose-1-ref.html
+!= menclose-1p.html menclose-1-ref.html
 == mmultiscript-align.html mmultiscript-align-ref.html
 == mathvariant-1a.html mathvariant-1a-ref.html
 == mathvariant-1b.html mathvariant-1b-ref.html
 == mathvariant-1c.html mathvariant-1c-ref.html
 == mathvariant-1d.html mathvariant-1d-ref.html
 == mathvariant-2.html mathvariant-2-ref.html
 == mathvariant-3.html mathvariant-3-ref.html
 == mathvariant-4.html mathvariant-4-ref.html
--- a/mobile/android/base/gfx/PluginLayer.java
+++ b/mobile/android/base/gfx/PluginLayer.java
@@ -3,16 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.gfx;
 
 import org.mozilla.gecko.GeckoAppShell;
 import org.mozilla.gecko.util.FloatUtils;
 import org.mozilla.gecko.util.ThreadUtils;
 
+import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.view.SurfaceView;
 import android.view.View;
 import android.widget.AbsoluteLayout;
 
 public class PluginLayer extends TileLayer {
     private static final String LOGTAG = "PluginLayer";
@@ -102,17 +103,17 @@ public class PluginLayer extends TileLay
         if (mDestroyed)
             return;
 
         if (!RectUtils.fuzzyEquals(context.viewport, mLastViewport) ||
             !FloatUtils.fuzzyEquals(context.zoomFactor, mLastZoomFactor)) {
 
             mLastZoomFactor = context.zoomFactor;
             mLastViewport = context.viewport;
-            mLayoutParams.reposition(context.viewport, context.zoomFactor);
+            mLayoutParams.reposition(context.viewport, context.offset, context.zoomFactor);
 
             showView();
         }
     }
 
     @Override
     public void draw(RenderContext context) {
     }
@@ -143,19 +144,20 @@ public class PluginLayer extends TileLay
                 }
             }
         }
 
         public void reset(RectF rect) {
             mRect = rect;
         }
 
-        public void reposition(RectF viewport, float zoomFactor) {
+        public void reposition(RectF viewport, PointF offset, float zoomFactor) {
 
             RectF scaled = RectUtils.scale(mRect, zoomFactor);
+            scaled.offset(offset.x, offset.y);
 
             this.x = Math.round(scaled.left - viewport.left);
             this.y = Math.round(scaled.top - viewport.top);
 
             if (!FloatUtils.fuzzyEquals(mLastResolution, zoomFactor)) {
                 width = Math.round(mRect.width() * zoomFactor);
                 height = Math.round(mRect.height() * zoomFactor);
                 mLastResolution = zoomFactor;
--- a/toolkit/components/mediasniffer/nsMediaSniffer.cpp
+++ b/toolkit/components/mediasniffer/nsMediaSniffer.cpp
@@ -17,16 +17,20 @@
 
 #include "nsIClassInfoImpl.h"
 #include <algorithm>
 
 // The minimum number of bytes that are needed to attempt to sniff an mp4 file.
 static const unsigned MP4_MIN_BYTES_COUNT = 12;
 // The maximum number of bytes to consider when attempting to sniff a file.
 static const uint32_t MAX_BYTES_SNIFFED = 512;
+// The maximum number of bytes to consider when attempting to sniff for a mp3
+// bitstream.
+// This is 320kbps * 144 / 32kHz + 1 padding byte + 4 bytes of capture pattern.
+static const uint32_t MAX_BYTES_SNIFFED_MP3 = 320 * 144 / 32 + 1 + 4;
 
 NS_IMPL_ISUPPORTS1(nsMediaSniffer, nsIContentSniffer)
 
 nsMediaSniffer::nsMediaSnifferEntry nsMediaSniffer::sSnifferEntries[] = {
   // The string OggS, followed by the null byte.
   PATTERN_ENTRY("\xFF\xFF\xFF\xFF\xFF", "OggS", APPLICATION_OGG),
   // The string RIFF, followed by four bytes, followed by the string WAVE
   PATTERN_ENTRY("\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF", "RIFF\x00\x00\x00\x00WAVE", AUDIO_WAV),
@@ -137,17 +141,18 @@ nsMediaSniffer::GetMIMETypeFromContent(n
     return NS_OK;
   }
 
   if (MatchesWebM(aData, clampedLength)) {
     aSniffedType.AssignLiteral(VIDEO_WEBM);
     return NS_OK;
   }
 
-  if (MatchesMP3(aData, clampedLength)) {
+  // Bug 950023: 512 bytes are often not enough to sniff for mp3.
+  if (MatchesMP3(aData, std::min(aLength, MAX_BYTES_SNIFFED_MP3))) {
     aSniffedType.AssignLiteral(AUDIO_MP3);
     return NS_OK;
   }
 
   // Could not sniff the media type, we are required to set it to
   // application/octet-stream.
   aSniffedType.AssignLiteral(APPLICATION_OCTET_STREAM);
   return NS_ERROR_NOT_AVAILABLE;
--- a/toolkit/components/osfile/modules/osfile_win_back.jsm
+++ b/toolkit/components/osfile/modules/osfile_win_back.jsm
@@ -34,16 +34,17 @@
      if (exports.OS && exports.OS.Win && exports.OS.Win.File) {
        return; // Avoid double initialization
      }
 
      let SharedAll = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm");
      let SysAll = require("resource://gre/modules/osfile/osfile_win_allthreads.jsm");
      let LOG = SharedAll.LOG.bind(SharedAll, "Unix", "back");
      let libc = SysAll.libc;
+     let advapi32 = ctypes.open("advapi32.dll");
      let Const = SharedAll.Constants.Win;
 
      /**
       * Initialize the Windows module.
       *
       * @param {function=} declareFFI
       */
      // FIXME: Both |init| and |aDeclareFFI| are deprecated, we should remove them
@@ -116,19 +117,40 @@
 
        /**
         * A C integer holding 0 in case of error, any other value in
         * case of success.
         */
        Type.zero_or_nothing =
          Type.int.withName("zero_or_nothing");
 
+       /**
+        * A C integer holding flags related to NTFS security.
+        */
        Type.SECURITY_ATTRIBUTES =
          Type.void_t.withName("SECURITY_ATTRIBUTES");
 
+       /**
+        * A C integer holding pointers related to NTFS security.
+        */
+       Type.PSID =
+         Type.voidptr_t.withName("PSID");
+
+       Type.PACL =
+         Type.voidptr_t.withName("PACL");
+
+       Type.PSECURITY_DESCRIPTOR =
+         Type.voidptr_t.withName("PSECURITY_DESCRIPTOR");
+
+       /**
+        * A C integer holding Win32 local memory handle.
+        */
+       Type.HLOCAL =
+         Type.voidptr_t.withName("HLOCAL");
+
        Type.FILETIME =
          new SharedAll.Type("FILETIME",
                   ctypes.StructType("FILETIME", [
                   { lo: Type.DWORD.implementation },
                   { hi: Type.DWORD.implementation }]));
 
        Type.FindData =
          new SharedAll.Type("FIND_DATA",
@@ -351,16 +373,44 @@
                      /*return*/   Type.DWORD,
                      /*fileName*/ Type.path);
 
         declareLazyFFI(SysFile, "SetFileAttributes", libc,
           "SetFileAttributesW", ctypes.winapi_abi,
                      /*return*/         Type.zero_or_nothing,
                      /*fileName*/       Type.path,
                      /*fileAttributes*/ Type.DWORD);
+
+        declareLazyFFI(SysFile, "GetNamedSecurityInfo", advapi32,
+          "GetNamedSecurityInfoW", ctypes.winapi_abi,
+                     /*return*/       Type.DWORD,
+                     /*objectName*/   Type.path,
+                     /*objectType*/   Type.DWORD,
+                     /*securityInfo*/ Type.DWORD,
+                     /*sidOwner*/     Type.PSID.out_ptr,
+                     /*sidGroup*/     Type.PSID.out_ptr,
+                     /*dacl*/         Type.PACL.out_ptr,
+                     /*sacl*/         Type.PACL.out_ptr,
+                     /*securityDesc*/ Type.PSECURITY_DESCRIPTOR.out_ptr);
+
+        declareLazyFFI(SysFile, "SetNamedSecurityInfo", advapi32,
+          "SetNamedSecurityInfoW", ctypes.winapi_abi,
+                     /*return*/       Type.DWORD,
+                     /*objectName*/   Type.path,
+                     /*objectType*/   Type.DWORD,
+                     /*securityInfo*/ Type.DWORD,
+                     /*sidOwner*/     Type.PSID,
+                     /*sidGroup*/     Type.PSID,
+                     /*dacl*/         Type.PACL,
+                     /*sacl*/         Type.PACL);
+
+        declareLazyFFI(SysFile, "LocalFree", libc,
+          "LocalFree", ctypes.winapi_abi,
+                     /*return*/       Type.HLOCAL,
+                     /*mem*/          Type.HLOCAL);
      };
 
      exports.OS.Win = {
        File: {
            _init:  init
        }
      };
    })(this);
--- a/toolkit/components/osfile/modules/osfile_win_front.jsm
+++ b/toolkit/components/osfile/modules/osfile_win_front.jsm
@@ -511,16 +511,47 @@
          flags = Const.MOVEFILE_COPY_ALLOWED;
        }
        if (!options.noOverwrite) {
          flags = flags | Const.MOVEFILE_REPLACE_EXISTING;
        }
        throw_on_zero("move",
          WinFile.MoveFileEx(sourcePath, destPath, flags)
        );
+
+       // Inherit NTFS permissions from the destination directory
+       // if possible.
+       if (Path.dirname(sourcePath) === Path.dirname(destPath)) {
+         // Skip if the move operation was the simple rename,
+         return;
+       }
+       // The function may fail for various reasons (e.g. not all
+       // filesystems support NTFS permissions or the user may not
+       // have the enough rights to read/write permissions).
+       // However we can safely ignore errors. The file was already
+       // moved. Setting permissions is not mandatory.
+       let dacl = new ctypes.voidptr_t();
+       let sd = new ctypes.voidptr_t();
+       WinFile.GetNamedSecurityInfo(destPath, Const.SE_FILE_OBJECT,
+                                    Const.DACL_SECURITY_INFORMATION,
+                                    null /*sidOwner*/, null /*sidGroup*/,
+                                    dacl.address(), null /*sacl*/,
+                                    sd.address());
+       // dacl will be set only if the function succeeds.
+       if (!dacl.isNull()) {
+         WinFile.SetNamedSecurityInfo(destPath, Const.SE_FILE_OBJECT,
+                                      Const.DACL_SECURITY_INFORMATION |
+                                      Const.UNPROTECTED_DACL_SECURITY_INFORMATION,
+                                      null /*sidOwner*/, null /*sidGroup*/,
+                                      dacl, null /*sacl*/);
+       }
+       // sd will be set only if the function succeeds.
+       if (!sd.isNull()) {
+           WinFile.LocalFree(Type.HLOCAL.cast(sd));
+       }
      };
 
      /**
       * A global value used to receive data during time conversions.
       */
      let gSystemTime = new Type.SystemTime.implementation();
      let gSystemTimePtr = gSystemTime.address();
 
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -2790,16 +2790,48 @@ static DWORD InitDwriteBG(LPVOID lpdwThr
   return 0;
 }
 #endif
 
 #ifdef USE_GLX_TEST
 bool fire_glxtest_process();
 #endif
 
+#if defined(XP_WIN) && defined(MOZ_METRO)
+#ifndef AHE_TYPE
+enum AHE_TYPE {
+  AHE_DESKTOP = 0,
+  AHE_IMMERSIVE = 1
+};
+#endif
+
+/*
+ * The Windows launcher uses this value to decide what front end ui
+ * to launch. We always launch the same ui unless the user
+ * specifically asks to switch. Update the value on every startup
+ * based on the environment requested.
+ */
+void
+SetLastWinRunType(AHE_TYPE aType)
+{
+  HKEY key;
+  LONG result = RegOpenKeyExW(HKEY_CURRENT_USER,
+                              L"SOFTWARE\\Mozilla\\Firefox",
+                              0, KEY_WRITE, &key);
+  if (result != ERROR_SUCCESS) {
+    return;
+  }
+  DWORD value = (DWORD)aType;
+  result = RegSetValueEx(key, L"MetroLastAHE", 0, REG_DWORD,
+                         reinterpret_cast<LPBYTE>(&value),
+                         sizeof(DWORD));
+  RegCloseKey(key);
+}
+#endif // defined(XP_WIN) && defined(MOZ_METRO)
+
 #include "GeckoProfiler.h"
 
 // Encapsulates startup and shutdown state for XRE_main
 class XREMain
 {
 public:
   XREMain() :
     mScopedXPCom(nullptr)
@@ -2883,16 +2915,29 @@ XREMain::XRE_mainInit(bool* aExitFlag)
   // don't want the user to see its crashes. That's the whole reason for
   // doing this in a separate process.
   if (fire_glxtest_process()) {
     *aExitFlag = true;
     return 0;
   }
 #endif
 
+#if defined(XP_WIN) && defined(MOZ_METRO)
+  // Don't remove this arg, we want to pass it on to nsUpdateDriver 
+  if (CheckArg("metro-update", false, nullptr, false) == ARG_FOUND ||
+      XRE_GetWindowsEnvironment() == WindowsEnvironmentType_Metro) {
+    // If we're doing a restart update that was initiated from metro land,
+    // we'll be running desktop to handle the actual update. Request that
+    // after the restart we launch into metro.
+    SetLastWinRunType(AHE_IMMERSIVE);
+  } else {
+    SetLastWinRunType(AHE_DESKTOP);
+  }
+#endif
+
   SetupErrorHandling(gArgv[0]);
 
 #ifdef CAIRO_HAS_DWRITE_FONT
   {
     // Bug 602792 - when DWriteCreateFactory is called the dwrite client dll
     // starts the FntCache service if it isn't already running (it's set
     // to manual startup by default in Windows 7 RTM).  Subsequent DirectWrite
     // calls cause the IDWriteFactory object to communicate with the FntCache
@@ -3619,16 +3664,22 @@ XREMain::XRE_mainStartup(bool* aExitFlag
                  gRestartArgc,
                  gRestartArgv,
                  mAppData->version);
   if (EnvHasValue("MOZ_PROCESS_UPDATES")) {
     SaveToEnv("MOZ_PROCESS_UPDATES=");
     *aExitFlag = true;
     return 0;
   }
+#if defined(XP_WIN) && defined(MOZ_METRO)
+  if (CheckArg("metro-update", false) == ARG_FOUND) {
+    *aExitFlag = true;
+    return 0;
+  }
+#endif
 #endif
 
   rv = NS_NewToolkitProfileService(getter_AddRefs(mProfileSvc));
   if (rv == NS_ERROR_FILE_ACCESS_DENIED) {
     PR_fprintf(PR_STDERR, "Error: Access was denied while trying to open files in " \
                 "your profile directory.\n");
   }
   if (NS_FAILED(rv)) {
@@ -4217,46 +4268,16 @@ public:
   ~WinRTInitWrapper() {
     if (SUCCEEDED(mResult)) {
       ::RoUninitialize();
     }
   }
   HRESULT mResult;
 };
 
-#ifndef AHE_TYPE
-enum AHE_TYPE {
-  AHE_DESKTOP = 0,
-  AHE_IMMERSIVE = 1
-};
-#endif
-
-/*
- * The Windows launcher uses this value to decide what front end ui
- * to launch. We always launch the same ui unless the user
- * specifically asks to switch. Update the value on every startup
- * based on the environment requested.
- */
-void
-SetLastWinRunType(AHE_TYPE aType)
-{
-  HKEY key;
-  LONG result = RegOpenKeyExW(HKEY_CURRENT_USER,
-                              L"SOFTWARE\\Mozilla\\Firefox",
-                              0, KEY_WRITE, &key);
-  if (result != ERROR_SUCCESS) {
-    return;
-  }
-  DWORD value = (DWORD)aType;
-  result = RegSetValueEx(key, L"MetroLastAHE", 0, REG_DWORD,
-                         reinterpret_cast<LPBYTE>(&value),
-                         sizeof(DWORD));
-  RegCloseKey(key);
-}
-
 int
 XRE_mainMetro(int argc, char* argv[], const nsXREAppData* aAppData)
 {
   char aLocal;
   GeckoProfilerInitRAII profilerGuard(&aLocal);
   PROFILER_LABEL("Startup", "XRE_Main");
 
   nsresult rv = NS_OK;
@@ -4314,33 +4335,32 @@ XRE_main(int argc, char* argv[], const n
 #if !defined(MOZ_METRO) || !defined(XP_WIN)
   XREMain main;
   int result = main.XRE_main(argc, argv, aAppData);
   mozilla::RecordShutdownEndTimeStamp();
   return result;
 #else
   if (aFlags == XRE_MAIN_FLAG_USE_METRO) {
     SetWindowsEnvironment(WindowsEnvironmentType_Metro);
-    SetLastWinRunType(AHE_IMMERSIVE);
-  } else {
-    SetLastWinRunType(AHE_DESKTOP);
   }
 
   // Desktop
   if (XRE_GetWindowsEnvironment() == WindowsEnvironmentType_Desktop) {
     XREMain main;
     int result = main.XRE_main(argc, argv, aAppData);
     mozilla::RecordShutdownEndTimeStamp();
     return result;
   }
 
   // Metro
   NS_ASSERTION(XRE_GetWindowsEnvironment() == WindowsEnvironmentType_Metro,
                "Unknown Windows environment");
 
+  SetLastWinRunType(AHE_IMMERSIVE);
+
   int result = XRE_mainMetro(argc, argv, aAppData);
   mozilla::RecordShutdownEndTimeStamp();
   return result;
 #endif // MOZ_METRO || !defined(XP_WIN)
 }
 
 nsresult
 XRE_InitCommandLine(int aArgc, char* aArgv[])
--- a/toolkit/xre/nsUpdateDriver.cpp
+++ b/toolkit/xre/nsUpdateDriver.cpp
@@ -295,16 +295,29 @@ IsOlderVersion(nsIFile *versionFile, con
     return false;
 
   if (mozilla::Version(appVersion) > buf)
     return true;
 
   return false;
 }
 
+#if defined(XP_WIN) && defined(MOZ_METRO)
+static bool
+IsWindowsMetroUpdateRequest(int appArgc, char **appArgv)
+{
+  for (int index = 0; index < appArgc; index++) {
+    if (!strcmp(appArgv[index], "--metro-update")) {
+      return true;
+    }
+  }
+  return false;
+}
+#endif
+
 static bool
 CopyFileIntoUpdateDir(nsIFile *parentDir, const char *leafName, nsIFile *updateDir)
 {
   nsDependentCString leaf(leafName);
   nsCOMPtr<nsIFile> file;
 
   // Make sure there is not an existing file in the target location.
   nsresult rv = updateDir->Clone(getter_AddRefs(file));
@@ -530,18 +543,18 @@ SwitchToUpdatedApp(nsIFile *greDir, nsIF
   pid.AppendInt((int32_t) getpid());
 #endif
 
   // Append a special token to the PID in order to let the updater know that it
   // just needs to replace the update directory.
   pid.AppendLiteral("/replace");
 
   int immersiveArgc = 0;
-#ifdef XP_WIN
-  if (IsRunningInWindowsMetro()) {
+#if defined(XP_WIN) && defined(MOZ_METRO)
+  if (IsWindowsMetroUpdateRequest(appArgc, appArgv)) {
     immersiveArgc = 1;
   }
 #endif
   int argc = appArgc + 5 + immersiveArgc;
   char **argv = new char*[argc + 1];
   if (!argv)
     return;
   argv[0] = (char*) updaterPath.get();
@@ -817,18 +830,18 @@ ApplyUpdate(nsIFile *greDir, nsIFile *up
 #if defined(USE_EXECV)
     pid.AssignASCII("0");
 #else
     pid.AppendInt((int32_t) getpid());
 #endif
   }
 
   int immersiveArgc = 0;
-#ifdef XP_WIN
-  if (IsRunningInWindowsMetro()) {
+#if defined(XP_WIN) && defined(MOZ_METRO)
+  if (IsWindowsMetroUpdateRequest(appArgc, appArgv)) {
     immersiveArgc = 1;
   }
 #endif
   int argc = appArgc + 5 + immersiveArgc;
   char **argv = new char*[argc + 1 ];
   if (!argv)
     return;
   argv[0] = (char*) updaterPath.get();
--- a/uriloader/prefetch/OfflineCacheUpdateChild.cpp
+++ b/uriloader/prefetch/OfflineCacheUpdateChild.cpp
@@ -62,37 +62,25 @@ namespace docshell {
 //-----------------------------------------------------------------------------
 
 NS_INTERFACE_MAP_BEGIN(OfflineCacheUpdateChild)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_INTERFACE_MAP_ENTRY(nsIOfflineCacheUpdate)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_ADDREF(OfflineCacheUpdateChild)
-NS_IMPL_RELEASE_WITH_DESTROY(OfflineCacheUpdateChild, RefcountHitZero())
-
-void
-OfflineCacheUpdateChild::RefcountHitZero()
-{
-    if (mIPCActivated) {
-        // ContentChild::DeallocPOfflineCacheUpdate will delete this
-        OfflineCacheUpdateChild::Send__delete__(this);
-    } else {
-        delete this;    // we never opened IPDL channel
-    }
-}
+NS_IMPL_RELEASE(OfflineCacheUpdateChild)
 
 //-----------------------------------------------------------------------------
 // OfflineCacheUpdateChild <public>
 //-----------------------------------------------------------------------------
 
 OfflineCacheUpdateChild::OfflineCacheUpdateChild(nsIDOMWindow* aWindow)
     : mState(STATE_UNINITIALIZED)
     , mIsUpgrade(false)
-    , mIPCActivated(false)
     , mAppID(NECKO_NO_APP_ID)
     , mInBrowser(false)
     , mWindow(aWindow)
     , mByteProgress(0)
 {
 }
 
 OfflineCacheUpdateChild::~OfflineCacheUpdateChild()
@@ -443,18 +431,18 @@ OfflineCacheUpdateChild::Schedule()
     bool stickDocument = mDocument != nullptr; 
 
     // Need to addref ourself here, because the IPC stack doesn't hold
     // a reference to us. Will be released in RecvFinish() that identifies 
     // the work has been done.
     child->SendPOfflineCacheUpdateConstructor(this, manifestURI, documentURI,
                                               stickDocument);
 
-    mIPCActivated = true;
-    this->AddRef();
+    // TabChild::DeallocPOfflineCacheUpdate will release this.
+    NS_ADDREF_THIS();
 
     return NS_OK;
 }
 
 bool
 OfflineCacheUpdateChild::RecvAssociateDocuments(const nsCString &cacheGroupId,
                                                   const nsCString &cacheClientId)
 {
@@ -532,15 +520,16 @@ OfflineCacheUpdateChild::RecvFinish(cons
         observerService->NotifyObservers(static_cast<nsIOfflineCacheUpdate*>(this),
                                          "offline-cache-update-completed",
                                          nullptr);
         LOG(("Done offline-cache-update-completed"));
     }
 
     // This is by contract the last notification from the parent, release
     // us now. This is corresponding to AddRef in Schedule().
-    this->Release();
+    // TabChild::DeallocPOfflineCacheUpdate will call Release.
+    OfflineCacheUpdateChild::Send__delete__(this);
 
     return true;
 }
 
 }
 }
--- a/uriloader/prefetch/OfflineCacheUpdateChild.h
+++ b/uriloader/prefetch/OfflineCacheUpdateChild.h
@@ -48,30 +48,27 @@ public:
     void SetDocument(nsIDOMDocument *aDocument);
 
 private:
     nsresult AssociateDocument(nsIDOMDocument *aDocument,
                                nsIApplicationCache *aApplicationCache);
     void GatherObservers(nsCOMArray<nsIOfflineCacheUpdateObserver> &aObservers);
     nsresult Finish();
 
-    void RefcountHitZero();
-
     enum {
         STATE_UNINITIALIZED,
         STATE_INITIALIZED,
         STATE_CHECKING,
         STATE_DOWNLOADING,
         STATE_CANCELLED,
         STATE_FINISHED
     } mState;
 
     bool mIsUpgrade;
     bool mSucceeded;
-    bool mIPCActivated;
 
     nsCString mUpdateDomain;
     nsCOMPtr<nsIURI> mManifestURI;
     nsCOMPtr<nsIURI> mDocumentURI;
 
     nsCOMPtr<nsIObserverService> mObserverService;
 
     uint32_t mAppID;
--- a/uriloader/prefetch/nsOfflineCacheUpdate.cpp
+++ b/uriloader/prefetch/nsOfflineCacheUpdate.cpp
@@ -1204,17 +1204,16 @@ NS_IMPL_ISUPPORTS3(nsOfflineCacheUpdate,
                    nsIRunnable)
 
 //-----------------------------------------------------------------------------
 // nsOfflineCacheUpdate <public>
 //-----------------------------------------------------------------------------
 
 nsOfflineCacheUpdate::nsOfflineCacheUpdate()
     : mState(STATE_UNINITIALIZED)
-    , mOwner(nullptr)
     , mAddedItems(false)
     , mPartialUpdate(false)
     , mOnlyCheckUpdate(false)
     , mSucceeded(true)
     , mObsolete(false)
     , mAppID(NECKO_NO_APP_ID)
     , mInBrowser(false)
     , mItemsInProgress(0)
@@ -2033,17 +2032,17 @@ nsOfflineCacheUpdate::StickDocument(nsIU
 
     mDocumentURIs.AppendObject(aDocumentURI);
 }
 
 void
 nsOfflineCacheUpdate::SetOwner(nsOfflineCacheUpdateOwner *aOwner)
 {
     NS_ASSERTION(!mOwner, "Tried to set cache update owner twice.");
-    mOwner = aOwner;
+    mOwner = aOwner->asWeakPtr();
 }
 
 bool
 nsOfflineCacheUpdate::IsForGroupID(const nsCSubstring &groupID)
 {
     return mGroupID == groupID;
 }
 
@@ -2154,17 +2153,19 @@ nsOfflineCacheUpdate::FinishNoNotify()
             mApplicationCache->Discard();
         }
     }
 
     nsresult rv = NS_OK;
 
     if (mOwner) {
         rv = mOwner->UpdateFinished(this);
-        mOwner = nullptr;
+        // mozilla::WeakPtr is missing some key features, like setting it to
+        // null explicitly.
+        mOwner = mozilla::WeakPtr<nsOfflineCacheUpdateOwner>();
     }
 
     return rv;
 }
 
 nsresult
 nsOfflineCacheUpdate::Finish()
 {
--- a/uriloader/prefetch/nsOfflineCacheUpdate.h
+++ b/uriloader/prefetch/nsOfflineCacheUpdate.h
@@ -27,16 +27,17 @@
 #include "nsIURI.h"
 #include "nsIWebProgressListener.h"
 #include "nsClassHashtable.h"
 #include "nsString.h"
 #include "nsTArray.h"
 #include "nsWeakReference.h"
 #include "nsICryptoHash.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/WeakPtr.h"
 #include "nsTHashtable.h"
 #include "nsHashKeys.h"
 
 class nsOfflineCacheUpdate;
 
 class nsICacheEntryDescriptor;
 class nsIUTF8StringEnumerator;
 class nsILoadContext;
@@ -174,18 +175,20 @@ private:
     // manifest hash data
     nsCOMPtr<nsICryptoHash> mManifestHash;
     bool mManifestHashInitialized;
     nsCString mManifestHashValue;
     nsCString mOldManifestHashValue;
 };
 
 class nsOfflineCacheUpdateOwner
+  : public mozilla::SupportsWeakPtr<nsOfflineCacheUpdateOwner>
 {
 public:
+    virtual ~nsOfflineCacheUpdateOwner() {}
     virtual nsresult UpdateFinished(nsOfflineCacheUpdate *aUpdate) = 0;
 };
 
 class nsOfflineCacheUpdate MOZ_FINAL : public nsIOfflineCacheUpdate
                                      , public nsIOfflineCacheUpdateObserver
                                      , public nsIRunnable
                                      , public nsOfflineCacheUpdateOwner
 {
@@ -250,17 +253,17 @@ private:
         STATE_UNINITIALIZED,
         STATE_INITIALIZED,
         STATE_CHECKING,
         STATE_DOWNLOADING,
         STATE_CANCELLED,
         STATE_FINISHED
     } mState;
 
-    nsOfflineCacheUpdateOwner *mOwner;
+    mozilla::WeakPtr<nsOfflineCacheUpdateOwner> mOwner;
 
     bool mAddedItems;
     bool mPartialUpdate;
     bool mOnlyCheckUpdate;
     bool mSucceeded;
     bool mObsolete;
 
     nsCString mUpdateDomain;
--- a/widget/nsIWinMetroUtils.idl
+++ b/widget/nsIWinMetroUtils.idl
@@ -7,17 +7,17 @@
 
 /**
  * Integration with the "Metro"/"Modern" UI environment in Windows 8.
  *
  * Note: browser/metro/base/content/browser-scripts.js contains a stub
  * implementation of this interface for non-Windows systems, for testing and
  * development purposes only.
  */
-[scriptable, uuid(148f57d3-51df-4e5c-a40b-7ae5ee76188e)]
+[scriptable, uuid(b6cbef4a-eec1-470b-8e74-9f4120f678c6)]
 interface nsIWinMetroUtils : nsISupports
 {
   /**
    * Determine if the current browser is running in the metro immersive
    * environment.
    */
   readonly attribute boolean immersive;
 
@@ -28,16 +28,23 @@ interface nsIWinMetroUtils : nsISupports
 
   /**
    * Determine the previous execution state. The possible values of this
    * attribute are exactly those values in the
    * Windows::ApplicationModel::Activation enumeration.
    */
   readonly attribute long previousExecutionState;
 
+  /**
+   * Helper for our restart logic up in the about flyout. We set this
+   * right before we restart for an update so that MetroAppShell can
+   * communicate this to the ceh.
+   */
+  attribute boolean updatePending;
+
    /**
     * Show the settings flyout
     */
    void showSettingsFlyout();
 
   /**
    * Launches the specified application with the specified arguments and
    * switches to Desktop mode if in metro mode.
--- a/widget/windows/winrt/MetroApp.cpp
+++ b/widget/windows/winrt/MetroApp.cpp
@@ -80,19 +80,19 @@ MetroApp::Run()
   hr = sCoreApp->add_Suspending(Callback<__FIEventHandler_1_Windows__CApplicationModel__CSuspendingEventArgs_t>(
     this, &MetroApp::OnSuspending).Get(), &mSuspendEvent);
   AssertHRESULT(hr);
 
   hr = sCoreApp->add_Resuming(Callback<__FIEventHandler_1_IInspectable_t>(
     this, &MetroApp::OnResuming).Get(), &mResumeEvent);
   AssertHRESULT(hr);
 
-  WinUtils::Log("XPCOM startup initialization began");
+  WinUtils::Log("Calling XRE_metroStartup.");
   nsresult rv = XRE_metroStartup(true);
-  WinUtils::Log("XPCOM startup initialization complete");
+  WinUtils::Log("Exiting XRE_metroStartup.");
   if (NS_FAILED(rv)) {
     WinUtils::Log("XPCOM startup initialization failed, bailing. rv=%X", rv);
     CoreExit();
   }
 }
 
 // Free all xpcom related resources before calling the xre shutdown call.
 // Must be called on the metro main thread. Currently called from appshell.
--- a/widget/windows/winrt/MetroAppShell.cpp
+++ b/widget/windows/winrt/MetroAppShell.cpp
@@ -16,16 +16,17 @@
 #include "WinUtils.h"
 #include "nsIAppStartup.h"
 #include "nsToolkitCompsCID.h"
 #include <shellapi.h>
 #include "nsIDOMWakeLockListener.h"
 #include "nsIPowerManagerService.h"
 #include "mozilla/StaticPtr.h"
 #include <windows.system.display.h>
+#include "nsWinMetroUtils.h"
 
 using namespace mozilla;
 using namespace mozilla::widget;
 using namespace mozilla::widget::winrt;
 using namespace Microsoft::WRL;
 using namespace Microsoft::WRL::Wrappers;
 using namespace ABI::Windows::UI::Core;
 using namespace ABI::Windows::Foundation;
@@ -149,17 +150,17 @@ HRESULT SHCreateShellItemArrayFromShellI
 
   FreeLibrary(shell32DLL);
   return hr;
 }
 
 HRESULT
 WinLaunchDeferredMetroFirefox()
 {
-  // Create an instance of the Firefox Metro DEH which is used to launch the browser
+  // Create an instance of the Firefox Metro CEH which is used to launch the browser
   const CLSID CLSID_FirefoxMetroDEH = {0x5100FEC1,0x212B, 0x4BF5 ,{0x9B,0xF8, 0x3E,0x65, 0x0F,0xD7,0x94,0xA3}};
 
   nsRefPtr<IExecuteCommand> executeCommand;
   HRESULT hr = CoCreateInstance(CLSID_FirefoxMetroDEH,
                                 nullptr,
                                 CLSCTX_LOCAL_SERVER,
                                 IID_IExecuteCommand,
                                 getter_AddRefs(executeCommand));
@@ -193,21 +194,25 @@ WinLaunchDeferredMetroFirefox()
   nsRefPtr<IObjectWithSelection> selection;
   hr = executeCommand->QueryInterface(IID_IObjectWithSelection, getter_AddRefs(selection));
   if (FAILED(hr))
     return hr;
   hr = selection->SetSelection(shellItemArray);
   if (FAILED(hr))
     return hr;
 
-  hr = executeCommand->SetParameters(L"--metro-restart");
+  if (nsWinMetroUtils::sUpdatePending) {
+    hr = executeCommand->SetParameters(L"--metro-update");
+  } else {
+    hr = executeCommand->SetParameters(L"--metro-restart");
+  }
   if (FAILED(hr))
     return hr;
 
-  // Run the default browser through the DEH
+  // Run the default browser through the CEH
   return executeCommand->Execute();
 }
 
 // Called by appstartup->run in xre, which is initiated by a call to
 // XRE_metroStartup in MetroApp. This call is on the metro main thread.
 NS_IMETHODIMP
 MetroAppShell::Run(void)
 {
@@ -262,24 +267,27 @@ MetroAppShell::Run(void)
 
       // This calls XRE_metroShutdown() in xre. Shuts down gecko, including
       // releasing the profile, and destroys MessagePump.
       sMetroApp->Shutdown();
 
       // Handle update restart or browser switch requests
       if (restartingInDesktop) {
         WinUtils::Log("Relaunching desktop browser");
+        // We can't call into the ceh to do this. Microsoft prevents switching to
+        // desktop unless we go through shell execute.
         SHELLEXECUTEINFOW sinfo;
         memset(&sinfo, 0, sizeof(SHELLEXECUTEINFOW));
         sinfo.cbSize       = sizeof(SHELLEXECUTEINFOW);
-        // Per the Metro style enabled desktop browser, for some reason,
-        // SEE_MASK_FLAG_LOG_USAGE is needed to change from immersive mode
-        // to desktop.
+        // Per microsoft's metro style enabled desktop browser documentation
+        // SEE_MASK_FLAG_LOG_USAGE is needed if we want to change from immersive
+        // mode to desktop mode.
         sinfo.fMask        = SEE_MASK_FLAG_LOG_USAGE;
-        sinfo.lpFile       = L"http://-desktop";
+        // The ceh will filter out this fake target.
+        sinfo.lpFile       = L"http://-desktop/";
         sinfo.lpVerb       = L"open";
         sinfo.lpParameters = L"--desktop-restart";
         sinfo.nShow        = SW_SHOWNORMAL;
         ShellExecuteEx(&sinfo);
       } else if (restartingInMetro) {
         HRESULT hresult = WinLaunchDeferredMetroFirefox();
         WinUtils::Log("Relaunching metro browser (hr=%X)", hresult);
       }
--- a/widget/windows/winrt/nsWinMetroUtils.cpp
+++ b/widget/windows/winrt/nsWinMetroUtils.cpp
@@ -28,16 +28,18 @@ namespace winrt {
 extern ComPtr<MetroApp> sMetroApp;
 extern nsTArray<nsString>* sSettingsArray;
 extern ComPtr<FrameworkView> sFrameworkView;
 } } }
 
 namespace mozilla {
 namespace widget {
 
+bool nsWinMetroUtils::sUpdatePending = false;
+
 NS_IMPL_ISUPPORTS1(nsWinMetroUtils, nsIWinMetroUtils)
 
 nsWinMetroUtils::nsWinMetroUtils()
 {
 }
 
 nsWinMetroUtils::~nsWinMetroUtils()
 {
@@ -312,10 +314,24 @@ nsWinMetroUtils::AddSettingsPanelEntry(c
 
 NS_IMETHODIMP
 nsWinMetroUtils::SwapMouseButton(bool aValue, bool *aOriginalValue)
 {
   *aOriginalValue = ::SwapMouseButton(aValue);
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsWinMetroUtils::GetUpdatePending(bool *aUpdatePending)
+{
+  *aUpdatePending = sUpdatePending;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWinMetroUtils::SetUpdatePending(bool aUpdatePending)
+{
+  sUpdatePending = aUpdatePending;
+  return NS_OK;
+}
+
 } // widget
 } // mozilla
--- a/widget/windows/winrt/nsWinMetroUtils.h
+++ b/widget/windows/winrt/nsWinMetroUtils.h
@@ -14,12 +14,14 @@ namespace widget {
 class nsWinMetroUtils : public nsIWinMetroUtils
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIWINMETROUTILS
 
   nsWinMetroUtils();
   virtual ~nsWinMetroUtils();
+
+  static bool sUpdatePending;
 };
 
 } // widget
 } // mozilla