Bug 807593 - Land metro specific nsAppRunner bits on mc. r=bbondy
authorJim Mathies <jmathies@mozilla.com>
Mon, 05 Nov 2012 05:26:12 -0600
changeset 112296 31784b0d633427abbe92b8d8a8c79e6393d35eec
parent 112295 cc7db2e7e54cdc1e1225c5b2693cb9ea2f1dd38a
child 112297 b91b1e93e3d406c587fe5af6bebea343780734d3
push id23809
push useremorley@mozilla.com
push dateMon, 05 Nov 2012 15:24:12 +0000
treeherdermozilla-central@358c9830d166 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbondy
bugs807593
milestone19.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
Bug 807593 - Land metro specific nsAppRunner bits on mc. r=bbondy
toolkit/xre/nsAppRunner.cpp
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -98,16 +98,19 @@
 using namespace mozilla;
 using mozilla::unused;
 using mozilla::scache::StartupCache;
 
 #ifdef XP_WIN
 #include "nsIWinAppHelper.h"
 #include <windows.h>
 #include "cairo/cairo-features.h"
+#ifdef MOZ_METRO
+#include <roapi.h>
+#endif
 
 #ifndef PROCESS_DEP_ENABLE
 #define PROCESS_DEP_ENABLE 0x1
 #endif
 #endif
 
 #include "nsCRT.h"
 #include "nsCOMPtr.h"
@@ -3953,23 +3956,159 @@ XREMain::XRE_main(int argc, char* argv[]
       CrashReporter::UnsetExceptionHandler();
 #endif
 
   XRE_DeinitCommandLine();
 
   return NS_FAILED(rv) ? 1 : 0;
 }
 
+#if defined(MOZ_METRO) && defined(XP_WIN)
+extern bool XRE_MetroCoreApplicationRun();
+static XREMain* xreMainPtr;
+
+// must be called by the thread we want as the main thread
+nsresult
+XRE_metroStartup()
+{
+  nsresult rv;
+
+  bool exit = false;
+  if (xreMainPtr->XRE_mainStartup(&exit) != 0 || exit)
+    return NS_ERROR_FAILURE;
+
+  // Start the real application
+  xreMainPtr->mScopedXPCom = new ScopedXPCOMStartup();
+  if (!xreMainPtr->mScopedXPCom)
+    return NS_ERROR_FAILURE;
+
+  rv = xreMainPtr->mScopedXPCom->Initialize();
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = xreMainPtr->XRE_mainRun();
+  NS_ENSURE_SUCCESS(rv, rv);
+  return NS_OK;
+}
+
+void
+XRE_metroShutdown()
+{
+  delete xreMainPtr->mScopedXPCom;
+  xreMainPtr->mScopedXPCom = nullptr;
+
+#ifdef MOZ_INSTRUMENT_EVENT_LOOP
+  mozilla::ShutdownEventTracing();
+#endif
+
+  // unlock the profile after ScopedXPCOMStartup object (xpcom) 
+  // has gone out of scope.  see bug #386739 for more details
+  xreMainPtr->mProfileLock->Unlock();
+  gProfileLock = nullptr;
+
+#ifdef MOZ_CRASHREPORTER
+  if (xreMainPtr->mAppData->flags & NS_XRE_ENABLE_CRASH_REPORTER)
+      CrashReporter::UnsetExceptionHandler();
+#endif
+
+  XRE_DeinitCommandLine();
+}
+
+class WinRTInitWrapper
+{
+public:
+  WinRTInitWrapper() {
+    mResult = ::RoInitialize(RO_INIT_MULTITHREADED);
+  }
+  ~WinRTInitWrapper() {
+    if (SUCCEEDED(mResult)) {
+      ::RoUninitialize();
+    }
+  }
+  HRESULT mResult;
+};
+
+int
+XRE_mainMetro(int argc, char* argv[], const nsXREAppData* aAppData)
+{
+  SAMPLER_INIT();
+  SAMPLE_LABEL("Startup", "XRE_Main");
+
+  nsresult rv = NS_OK;
+
+  xreMainPtr = new XREMain();
+  if (!xreMainPtr) {
+    return 1;
+  }
+
+  // Inits Winrt and COM underneath it.
+  WinRTInitWrapper wrap;
+
+  gArgc = argc;
+  gArgv = argv;
+
+  NS_ENSURE_TRUE(aAppData, 2);
+
+  xreMainPtr->mAppData = new ScopedAppData(aAppData);
+  if (!xreMainPtr->mAppData)
+    return 1;
+  // used throughout this file
+  gAppData = xreMainPtr->mAppData;
+
+  ScopedLogging log;
+
+  // init
+  bool exit = false;
+  if (xreMainPtr->XRE_mainInit(aAppData, &exit) != 0 || exit)
+    return 1;
+
+  // Located in widget, will call back into XRE_metroStartup and
+  // XRE_metroShutdown above.
+  if (!XRE_MetroCoreApplicationRun()) {
+    return 1;
+  }
+
+  // XRE_metroShutdown should have already been called on the worker
+  // thread that called XRE_metroStartup.
+  NS_ASSERTION(!xreMainPtr->mScopedXPCom,
+               "XPCOM Shutdown hasn't occured, and we are exiting.");
+  return 0;
+}
+
+void SetWindowsEnvironment(WindowsEnvironmentType aEnvID);
+#endif // MOZ_METRO || !defined(XP_WIN)
+
 int
 XRE_main(int argc, char* argv[], const nsXREAppData* aAppData, uint32_t aFlags)
 {
+#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);
+  }
+
+  // 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");
+
+  int result = XRE_mainMetro(argc, argv, aAppData);
+  mozilla::RecordShutdownEndTimeStamp();
+  return result;
+#endif // MOZ_METRO || !defined(XP_WIN)
 }
 
 nsresult
 XRE_InitCommandLine(int aArgc, char* aArgv[])
 {
   nsresult rv = NS_OK;
 
 #if defined(OS_WIN)