Bug 951120 - Detach ICoreWindow related events prior to shutdown, plus some misc. code cleanup. r=bbondy, a=metro-only
authorJim Mathies <jmathies@mozilla.com>
Mon, 27 Jan 2014 09:09:33 -0600
changeset 175120 5b9c5ed94b04258f1be088609c144abb5e5826ba
parent 175119 7e64908ef411c6385b03e27dbd8dcb24ff80ca46
child 175121 41a58e12473fa62fc0346c4784460142bf451e7f
push id3224
push userlsblakk@mozilla.com
push dateTue, 04 Feb 2014 01:06:49 +0000
treeherdermozilla-beta@60c04d0987f1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbondy, metro-only
bugs951120
milestone28.0a2
Bug 951120 - Detach ICoreWindow related events prior to shutdown, plus some misc. code cleanup. r=bbondy, a=metro-only
widget/windows/winrt/FrameworkView.cpp
widget/windows/winrt/FrameworkView.h
widget/windows/winrt/MetroApp.cpp
widget/windows/winrt/MetroApp.h
widget/windows/winrt/MetroAppShell.cpp
--- a/widget/windows/winrt/FrameworkView.cpp
+++ b/widget/windows/winrt/FrameworkView.cpp
@@ -46,16 +46,29 @@ FrameworkView::FrameworkView(MetroApp* a
   mWidget(nullptr),
   mShuttingDown(false),
   mMetroApp(aMetroApp),
   mWindow(nullptr),
   mMetroInput(nullptr),
   mWinVisible(false),
   mWinActiveState(false)
 {
+  mActivated.value = 0;
+  mWindowActivated.value = 0;
+  mWindowVisibilityChanged.value = 0;
+  mWindowSizeChanged.value = 0;
+  mSoftKeyboardHidden.value = 0;
+  mSoftKeyboardShown.value = 0;
+  mDisplayPropertiesChanged.value = 0;
+  mAutomationProviderRequested.value = 0;
+  mDataTransferRequested.value = 0;
+  mSearchQuerySubmitted.value = 0;
+  mPlayToRequested.value = 0;
+  mSettingsPane.value = 0;
+  mPrintManager.value = 0;
   memset(&sKeyboardRect, 0, sizeof(Rect));
   sSettingsArray = new nsTArray<nsString>();
   LogFunction();
 }
 
 ////////////////////////////////////////////////////
 // IFrameworkView impl.
 
@@ -146,18 +159,16 @@ FrameworkView::AddEventHandlers() {
 
   mMetroInput = Make<MetroInput>(mWidget.Get(),
                                  mWindow.Get());
 
   mWindow->add_VisibilityChanged(Callback<__FITypedEventHandler_2_Windows__CUI__CCore__CCoreWindow_Windows__CUI__CCore__CVisibilityChangedEventArgs>(
     this, &FrameworkView::OnWindowVisibilityChanged).Get(), &mWindowVisibilityChanged);
   mWindow->add_Activated(Callback<__FITypedEventHandler_2_Windows__CUI__CCore__CCoreWindow_Windows__CUI__CCore__CWindowActivatedEventArgs_t>(
     this, &FrameworkView::OnWindowActivated).Get(), &mWindowActivated);
-  mWindow->add_Closed(Callback<__FITypedEventHandler_2_Windows__CUI__CCore__CCoreWindow_Windows__CUI__CCore__CCoreWindowEventArgs_t>(
-    this, &FrameworkView::OnWindowClosed).Get(), &mWindowClosed);
   mWindow->add_SizeChanged(Callback<__FITypedEventHandler_2_Windows__CUI__CCore__CCoreWindow_Windows__CUI__CCore__CWindowSizeChangedEventArgs_t>(
     this, &FrameworkView::OnWindowSizeChanged).Get(), &mWindowSizeChanged);
 
   mWindow->add_AutomationProviderRequested(Callback<__FITypedEventHandler_2_Windows__CUI__CCore__CCoreWindow_Windows__CUI__CCore__CAutomationProviderRequestedEventArgs_t>(
     this, &FrameworkView::OnAutomationProviderRequested).Get(), &mAutomationProviderRequested);
 
   HRESULT hr;
   ComPtr<ABI::Windows::Graphics::Display::IDisplayPropertiesStatics> dispProps;
@@ -176,21 +187,45 @@ FrameworkView::AddEventHandlers() {
       inputPane->add_Showing(Callback<__FITypedEventHandler_2_Windows__CUI__CViewManagement__CInputPane_Windows__CUI__CViewManagement__CInputPaneVisibilityEventArgs_t>(
         this, &FrameworkView::OnSoftkeyboardShown).Get(), &mSoftKeyboardShown);
     }
   }
 }
 
 // Called by MetroApp
 void
-FrameworkView::ShutdownXPCOM()
+FrameworkView::Shutdown()
 {
   LogFunction();
   mShuttingDown = true;
 
+  if (mWindow && mWindowVisibilityChanged.value) {
+    mWindow->remove_VisibilityChanged(mWindowVisibilityChanged);
+    mWindow->remove_Activated(mWindowActivated);
+    mWindow->remove_Closed(mWindowClosed);
+    mWindow->remove_SizeChanged(mWindowSizeChanged);
+    mWindow->remove_AutomationProviderRequested(mAutomationProviderRequested);
+  }
+
+  ComPtr<ABI::Windows::Graphics::Display::IDisplayPropertiesStatics> dispProps;
+  if (mDisplayPropertiesChanged.value &&
+      SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), dispProps.GetAddressOf()))) {
+    dispProps->remove_LogicalDpiChanged(mDisplayPropertiesChanged);
+  }
+
+  ComPtr<ABI::Windows::UI::ViewManagement::IInputPaneStatics> inputStatic;
+  if (mSoftKeyboardHidden.value &&
+      SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_ViewManagement_InputPane).Get(), inputStatic.GetAddressOf()))) {
+    ComPtr<ABI::Windows::UI::ViewManagement::IInputPane> inputPane;
+    if (SUCCEEDED(inputStatic->GetForCurrentView(inputPane.GetAddressOf()))) {
+      inputPane->remove_Hiding(mSoftKeyboardHidden);
+      inputPane->remove_Showing(mSoftKeyboardShown);
+    }
+  }
+
   if (mAutomationProvider) {
     ComPtr<IUIABridge> provider;
     mAutomationProvider.As(&provider);
     if (provider) {
       provider->Disconnect();
     }
   }
   mAutomationProvider = nullptr;
@@ -347,16 +382,20 @@ FrameworkView::OnWindowVisibilityChanged
 }
 
 HRESULT
 FrameworkView::OnActivated(ICoreApplicationView* aApplicationView,
                            IActivatedEventArgs* aArgs)
 {
   LogFunction();
 
+  if (mShuttingDown) {
+    return S_OK;
+  }
+
   aArgs->get_PreviousExecutionState(&mPreviousExecutionState);
   bool startup = mPreviousExecutionState == ApplicationExecutionState::ApplicationExecutionState_Terminated ||
                  mPreviousExecutionState == ApplicationExecutionState::ApplicationExecutionState_ClosedByUser ||
                  mPreviousExecutionState == ApplicationExecutionState::ApplicationExecutionState_NotRunning;
   ProcessActivationArgs(aArgs, startup);
   return S_OK;
 }
 
@@ -366,65 +405,50 @@ FrameworkView::GetPreviousExecutionState
   return mPreviousExecutionState;
 }
 
 HRESULT
 FrameworkView::OnSoftkeyboardHidden(IInputPane* aSender,
                                     IInputPaneVisibilityEventArgs* aArgs)
 {
   LogFunction();
-  if (mShuttingDown)
-    return S_OK;
   sKeyboardIsVisible = false;
   memset(&sKeyboardRect, 0, sizeof(Rect));
   MetroUtils::FireObserver("metro_softkeyboard_hidden");
   aArgs->put_EnsuredFocusedElementInView(true);
   return S_OK;
 }
 
 HRESULT
 FrameworkView::OnSoftkeyboardShown(IInputPane* aSender,
                                    IInputPaneVisibilityEventArgs* aArgs)
 {
   LogFunction();
-  if (mShuttingDown)
-    return S_OK;
   sKeyboardIsVisible = true;
   aSender->get_OccludedRect(&sKeyboardRect);
   MetroUtils::FireObserver("metro_softkeyboard_shown");
   aArgs->put_EnsuredFocusedElementInView(true);
   return S_OK;
 }
 
 HRESULT
-FrameworkView::OnWindowClosed(ICoreWindow* aSender, ICoreWindowEventArgs* aArgs)
-{
-  // this doesn't seem very reliable
-  return S_OK;
-}
-
-HRESULT
 FrameworkView::OnWindowSizeChanged(ICoreWindow* aSender, IWindowSizeChangedEventArgs* aArgs)
 {
   LogFunction();
-
-  if (mShuttingDown) {
-    return S_OK;
-  }
-
   UpdateWidgetSizeAndPosition();
   return S_OK;
 }
 
 HRESULT
 FrameworkView::OnWindowActivated(ICoreWindow* aSender, IWindowActivatedEventArgs* aArgs)
 {
   LogFunction();
-  if (mShuttingDown || !mWidget)
+  if (!mWidget) {
     return S_OK;
+  }
   CoreWindowActivationState state;
   aArgs->get_WindowActivationState(&state);
   mWinActiveState = !(state == CoreWindowActivationState::CoreWindowActivationState_Deactivated);
   SendActivationEvent();
   return S_OK;
 }
 
 HRESULT
--- a/widget/windows/winrt/FrameworkView.h
+++ b/widget/windows/winrt/FrameworkView.h
@@ -77,17 +77,16 @@ public:
   STDMETHODIMP Load(HSTRING aEntryPoint);
   STDMETHODIMP Run();
   STDMETHODIMP Uninitialize();
 
   HRESULT ActivateView();
 
   // Public apis for MetroWidget
   int GetPreviousExecutionState();
-  void ShutdownXPCOM();
   float GetDPI() { return mDPI; }
   ICoreWindow* GetCoreWindow() { return mWindow.Get(); }
   void SetWidget(MetroWidget* aWidget);
   MetroWidget* GetWidget() { return mWidget.Get(); }
   void GetBounds(nsIntRect &aRect);
   void GetActivationURI(nsAString &aActivationURI) { aActivationURI = mActivationURI; }
   void SetCursor(ABI::Windows::UI::Core::CoreCursorType aCursorType, DWORD aCustomId = 0);
   void ClearCursor();
@@ -95,31 +94,30 @@ public:
   bool IsVisible() const;
 
   // Soft keyboard info for nsIWinMetroUtils
   static bool IsKeyboardVisible() { return sKeyboardIsVisible; }
   static ABI::Windows::Foundation::Rect KeyboardVisibleRect() { return sKeyboardRect; }
 
   // MetroApp apis
   void SetupContracts();
+  void Shutdown();
 
   // MetroContracts settings panel enumerator entry
   void AddSetting(ISettingsPaneCommandsRequestedEventArgs* aArgs, uint32_t aId,
                   Microsoft::WRL::Wrappers::HString& aSettingName);
 protected:
   // Event Handlers
   HRESULT OnActivated(ICoreApplicationView* aApplicationView,
                       IActivatedEventArgs* aArgs);
   HRESULT OnWindowVisibilityChanged(ICoreWindow* aCoreWindow,
                                     IVisibilityChangedEventArgs* aArgs);
 
   HRESULT OnWindowSizeChanged(ICoreWindow* aSender,
                               IWindowSizeChangedEventArgs* aArgs);
-  HRESULT OnWindowClosed(ICoreWindow* aSender,
-                         ICoreWindowEventArgs* aArgs);
   HRESULT OnWindowActivated(ICoreWindow* aSender,
                             IWindowActivatedEventArgs* aArgs);
   HRESULT OnLogicalDpiChanged(IInspectable* aSender);
 
   HRESULT OnAutomationProviderRequested(ICoreWindow* aSender,
                                         IAutomationProviderRequestedEventArgs* aArgs);
 
   HRESULT OnSoftkeyboardHidden(IInputPane* aSender,
--- a/widget/windows/winrt/MetroApp.cpp
+++ b/widget/windows/winrt/MetroApp.cpp
@@ -92,27 +92,27 @@ MetroApp::Run()
     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.
 void
-MetroApp::ShutdownXPCOM()
+MetroApp::Shutdown()
 {
   LogThread();
 
   if (sCoreApp) {
     sCoreApp->remove_Suspending(mSuspendEvent);
     sCoreApp->remove_Resuming(mResumeEvent);
   }
 
   if (sFrameworkView) {
-    sFrameworkView->ShutdownXPCOM();
+    sFrameworkView->Shutdown();
   }
 
   MetroApp::sGeckoShuttingDown = true;
 
   // Shut down xpcom
   XRE_metroShutdown();
 
   // Unhook this thread from the profiler
--- a/widget/windows/winrt/MetroApp.h
+++ b/widget/windows/winrt/MetroApp.h
@@ -39,18 +39,18 @@ public:
   HRESULT OnSuspending(IInspectable* aSender, ISuspendingEventArgs* aArgs);
   HRESULT OnResuming(IInspectable* aSender, IInspectable* aArgs);
 
   // nsIWinMetroUtils tile related async callbacks
   HRESULT OnAsyncTileCreated(ABI::Windows::Foundation::IAsyncOperation<bool>* aOperation, AsyncStatus aStatus);
 
   void Run();
   void CoreExit();
+  void Shutdown();
 
-  void ShutdownXPCOM();
   // Set when gecko enters xpcom shutdown.
   static bool sGeckoShuttingDown;
 
   // Shared pointers between framework and widget
   static void SetBaseWidget(MetroWidget* aPtr);
   static void PostSuspendResumeProcessNotification(bool aIsSuspend);
   static void PostSleepWakeNotification(bool aIsSuspend);
 
--- a/widget/windows/winrt/MetroAppShell.cpp
+++ b/widget/windows/winrt/MetroAppShell.cpp
@@ -257,17 +257,17 @@ MetroAppShell::Run(void)
 
       if (appStartup && NS_SUCCEEDED(appStartup->GetRestartingTouchEnvironment(&restartingInMetro)) &&
           restartingInMetro) {
         restartingInDesktop = false;
       }
 
       // This calls XRE_metroShutdown() in xre. Shuts down gecko, including
       // releasing the profile, and destroys MessagePump.
-      sMetroApp->ShutdownXPCOM();
+      sMetroApp->Shutdown();
 
       // Handle update restart or browser switch requests
       if (restartingInDesktop) {
         WinUtils::Log("Relaunching desktop browser");
         SHELLEXECUTEINFOW sinfo;
         memset(&sinfo, 0, sizeof(SHELLEXECUTEINFOW));
         sinfo.cbSize       = sizeof(SHELLEXECUTEINFOW);
         // Per the Metro style enabled desktop browser, for some reason,