Bug 950241 - Delay desktop restart for updating until the metro browser has shutdown. r=bbondy, a=lsblakk
authorJim Mathies <jmathies@mozilla.com>
Thu, 30 Jan 2014 13:32:49 -0600
changeset 176263 5d2ffbeb04f7d73db1db35e0274b96f14d62087b
parent 176262 25dd5a9531d3734c12390d03eb857000f19d3fa6
child 176264 138ec444b4e3b18eb3036cbb61c1cb0c034dc690
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbondy, lsblakk
bugs950241
milestone28.0
Bug 950241 - Delay desktop restart for updating until the metro browser has shutdown. r=bbondy, a=lsblakk
browser/metro/shell/commandexecutehandler/CommandExecuteHandler.cpp
--- a/browser/metro/shell/commandexecutehandler/CommandExecuteHandler.cpp
+++ b/browser/metro/shell/commandexecutehandler/CommandExecuteHandler.cpp
@@ -92,22 +92,24 @@ public:
     mRef(1),
     mShellItemArray(nullptr),
     mUnkSite(nullptr),
     mTargetIsFileSystemLink(false),
     mTargetIsDefaultBrowser(false),
     mTargetIsBrowser(false),
     mRequestType(DEFAULT_LAUNCH),
     mRequestMet(false),
+    mRelaunchDesktopDelayedRequested(false),
     mVerb(L"open")
   {
   }
 
   bool RequestMet() { return mRequestMet; }
   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),
@@ -410,16 +412,17 @@ private:
   CStringW mVerb;
   CStringW mTarget;
   CStringW mParameters;
   bool mTargetIsFileSystemLink;
   bool mTargetIsDefaultBrowser;
   bool mTargetIsBrowser;
   DWORD mKeyState;
   bool mRequestMet;
+  bool mRelaunchDesktopDelayedRequested;
 };
 
 /*
  * Retrieve the current default browser's path.
  *
  * @aPathBuffer Buffer to fill
  */
 static bool GetDefaultBrowserPath(CStringW& aPathBuffer)
@@ -639,16 +642,28 @@ CExecuteCommandVerb::LaunchDesktopBrowse
   if (!GetDesktopBrowserPath(browserPath)) {
     return;
   }
 
   LaunchDesktopBrowserWithParams(browserPath, mVerb, mTarget, mParameters,
                                  mTargetIsDefaultBrowser, mTargetIsBrowser);
 }
 
+void
+CExecuteCommandVerb::HeartBeat()
+{
+  if (mRequestType == METRO_UPDATE &&
+      mRelaunchDesktopDelayedRequested &&
+      !IsMetroProcessRunning()) {
+    mRelaunchDesktopDelayedRequested = false;
+    LaunchDesktopBrowser();
+    mRequestMet = true;
+  }
+}
+
 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 false;
@@ -715,34 +730,38 @@ IFACEMETHODIMP CExecuteCommandVerb::Exec
   Log(L"Execute()");
 
   if (!mTarget.GetLength()) {
     // We shut down when this flips to true
     mRequestMet = true;
     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;
+    mRelaunchDesktopDelayedRequested = true;
+    return S_OK;
+  }
+
   // We shut down when this flips to true
   AutoSetRequestMet asrm(&mRequestMet);
 
   // Launch on the desktop
   if (mRequestType == DESKTOP_RESTART ||
       (mRequestType == DEFAULT_LAUNCH && DefaultLaunchIsDesktop())) {
     LaunchDesktopBrowser();
     return S_OK;
   }
 
-  // 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) {
-    mParameters = kMetroUpdateCmdLine;
-    LaunchDesktopBrowser();
-    return S_OK;
-  }
-
   LaunchMetroBrowser();
   return S_OK;
 }
 
 class ClassFactory : public IClassFactory 
 {
 public:
   ClassFactory(IUnknown *punkObject);
@@ -853,16 +872,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);
       }