Bug 973489 - Part 2. Fix memory leak. r=jimm
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Thu, 20 Feb 2014 11:29:16 +0900
changeset 169986 392946fdbf684f7f7568587f5da79d5ede0575a6
parent 169985 2b844df6ce123ed596ca4b10341841ab2a49277e
child 169987 36335b77688ed8517f88196bbf8d49f72f4fae5f
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewersjimm
bugs973489
milestone30.0a1
Bug 973489 - Part 2. Fix memory leak. r=jimm
widget/windows/winrt/ToastNotificationHandler.cpp
widget/windows/winrt/ToastNotificationHandler.h
widget/windows/winrt/nsWinMetroUtils.cpp
--- a/widget/windows/winrt/ToastNotificationHandler.cpp
+++ b/widget/windows/winrt/ToastNotificationHandler.cpp
@@ -13,17 +13,17 @@ using namespace ABI::Windows::Data::Xml:
 using namespace Microsoft::WRL;
 using namespace Microsoft::WRL::Wrappers;
 using namespace mozilla;
 using namespace ABI::Windows::UI::Notifications;
 
 typedef __FITypedEventHandler_2_Windows__CUI__CNotifications__CToastNotification_IInspectable_t ToastActivationHandler;
 typedef __FITypedEventHandler_2_Windows__CUI__CNotifications__CToastNotification_Windows__CUI__CNotifications__CToastDismissedEventArgs ToastDismissHandler;
 
-void
+bool
 ToastNotificationHandler::DisplayNotification(HSTRING title,
                                               HSTRING msg,
                                               HSTRING imagePath,
                                               const nsAString& aCookie,
                                               const nsAString& aAppId)
 {
   mCookie = aCookie;
 
@@ -34,98 +34,101 @@ ToastNotificationHandler::DisplayNotific
   HSTRING textNodeStr, imageNodeStr, srcNodeStr;
   HSTRING_HEADER textHeader, imageHeader, srcHeader;
   WindowsCreateStringReference(L"text", 4, &textHeader, &textNodeStr);
   WindowsCreateStringReference(L"image", 5, &imageHeader, &imageNodeStr);
   WindowsCreateStringReference(L"src", 3, &srcHeader, &srcNodeStr);
   toastXml->GetElementsByTagName(textNodeStr, &toastTextElements);
   toastXml->GetElementsByTagName(imageNodeStr, &toastImageElements);
 
-  AssertHRESULT(toastTextElements->Item(0, &titleTextNodeRoot));
-  AssertHRESULT(toastTextElements->Item(1, &msgTextNodeRoot));
-  AssertHRESULT(toastImageElements->Item(0, &imageNodeRoot));
+  AssertRetHRESULT(toastTextElements->Item(0, &titleTextNodeRoot), false);
+  AssertRetHRESULT(toastTextElements->Item(1, &msgTextNodeRoot), false);
+  AssertRetHRESULT(toastImageElements->Item(0, &imageNodeRoot), false);
 
   ComPtr<IXmlNamedNodeMap> attributes;
-  AssertHRESULT(imageNodeRoot->get_Attributes(&attributes));
-  AssertHRESULT(attributes->GetNamedItem(srcNodeStr, &srcAttribute));
+  AssertRetHRESULT(imageNodeRoot->get_Attributes(&attributes), false);
+  AssertRetHRESULT(attributes->GetNamedItem(srcNodeStr, &srcAttribute), false);
 
   SetNodeValueString(title, titleTextNodeRoot.Get(), toastXml.Get());
   SetNodeValueString(msg, msgTextNodeRoot.Get(), toastXml.Get());
   SetNodeValueString(imagePath, srcAttribute.Get(), toastXml.Get());
 
-  CreateWindowsNotificationFromXml(toastXml.Get(), aAppId);
+  return CreateWindowsNotificationFromXml(toastXml.Get(), aAppId);
 }
 
-void
+bool
 ToastNotificationHandler::DisplayTextNotification(HSTRING title,
                                                   HSTRING msg,
                                                   const nsAString& aCookie,
                                                   const nsAString& aAppId)
 {
   mCookie = aCookie;
 
   ComPtr<IXmlDocument> toastXml = InitializeXmlForTemplate(ToastTemplateType::ToastTemplateType_ToastText03);
   ComPtr<IXmlNodeList> toastTextElements;
   ComPtr<IXmlNode> titleTextNodeRoot, msgTextNodeRoot;
 
   HSTRING textNodeStr;
   HSTRING_HEADER textHeader;
   WindowsCreateStringReference(L"text", 4, &textHeader, &textNodeStr);
   toastXml->GetElementsByTagName(textNodeStr, &toastTextElements);
 
-  AssertHRESULT(toastTextElements->Item(0, &titleTextNodeRoot));
-  AssertHRESULT(toastTextElements->Item(1, &msgTextNodeRoot));
+  AssertRetHRESULT(toastTextElements->Item(0, &titleTextNodeRoot), false);
+  AssertRetHRESULT(toastTextElements->Item(1, &msgTextNodeRoot), false);
 
   SetNodeValueString(title, titleTextNodeRoot.Get(), toastXml.Get());
   SetNodeValueString(msg, msgTextNodeRoot.Get(), toastXml.Get());
 
-  CreateWindowsNotificationFromXml(toastXml.Get(), aAppId);
+  return CreateWindowsNotificationFromXml(toastXml.Get(), aAppId);
 }
 
 ComPtr<IXmlDocument>
 ToastNotificationHandler::InitializeXmlForTemplate(ToastTemplateType templateType) {
   ComPtr<IXmlDocument> toastXml;
 
   AssertRetHRESULT(GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_Notifications_ToastNotificationManager).Get(),
     mToastNotificationManagerStatics.GetAddressOf()), nullptr);
 
   mToastNotificationManagerStatics->GetTemplateContent(templateType, &toastXml);
 
   return toastXml;
 }
 
-void
+bool
 ToastNotificationHandler::CreateWindowsNotificationFromXml(IXmlDocument *toastXml,
                                                            const nsAString& aAppId)
 {
   ComPtr<IToastNotification> notification;
   ComPtr<IToastNotificationFactory> factory;
-  AssertHRESULT(GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_Notifications_ToastNotification).Get(),
-    factory.GetAddressOf()));
-  AssertHRESULT(factory->CreateToastNotification(toastXml, &notification));
+  AssertRetHRESULT(GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_Notifications_ToastNotification).Get(),
+    factory.GetAddressOf()), false);
+  AssertRetHRESULT(factory->CreateToastNotification(toastXml, &notification),
+                   false);
 
   EventRegistrationToken activatedToken;
-  AssertHRESULT(notification->add_Activated(Callback<ToastActivationHandler>(this,
-    &ToastNotificationHandler::OnActivate).Get(), &activatedToken));
+  AssertRetHRESULT(notification->add_Activated(Callback<ToastActivationHandler>(this,
+    &ToastNotificationHandler::OnActivate).Get(), &activatedToken), false);
   EventRegistrationToken dismissedToken;
-  AssertHRESULT(notification->add_Dismissed(Callback<ToastDismissHandler>(this,
-    &ToastNotificationHandler::OnDismiss).Get(), &dismissedToken));
+  AssertRetHRESULT(notification->add_Dismissed(Callback<ToastDismissHandler>(this,
+    &ToastNotificationHandler::OnDismiss).Get(), &dismissedToken), false);
 
   ComPtr<IToastNotifier> notifier;
   if (aAppId.IsEmpty()) {
-    AssertHRESULT(mToastNotificationManagerStatics->CreateToastNotifier(
-                    &notifier));
+    AssertRetHRESULT(mToastNotificationManagerStatics->CreateToastNotifier(
+                       &notifier), false);
   } else {
-    AssertHRESULT(mToastNotificationManagerStatics->CreateToastNotifierWithId(
+    AssertRetHRESULT(mToastNotificationManagerStatics->CreateToastNotifierWithId(
                     HStringReference(PromiseFlatString(aAppId).get()).Get(),
-                    &notifier));
+                    &notifier), false);
   }
-  notifier->Show(notification.Get());
+  AssertRetHRESULT(notifier->Show(notification.Get()), false);
 
   MetroUtils::FireObserver("metro_native_toast_shown", mCookie.get());
+
+  return true;
 }
 
 void ToastNotificationHandler::SetNodeValueString(HSTRING inputString, ComPtr<IXmlNode> node, ComPtr<IXmlDocument> xml) {
   ComPtr<IXmlText> inputText;
   ComPtr<IXmlNode> inputTextNode, pAppendedChild;
 
   AssertHRESULT(xml->CreateTextNode(inputString, &inputText));
   AssertHRESULT(inputText.As(&inputTextNode));
@@ -137,10 +140,11 @@ HRESULT ToastNotificationHandler::OnActi
   return S_OK;
 }
 
 HRESULT
 ToastNotificationHandler::OnDismiss(IToastNotification *notification,
                                     IToastDismissedEventArgs* aArgs)
 {
   MetroUtils::FireObserver("metro_native_toast_dismissed", mCookie.get());
+  delete this;
   return S_OK;
 }
--- a/widget/windows/winrt/ToastNotificationHandler.h
+++ b/widget/windows/winrt/ToastNotificationHandler.h
@@ -20,25 +20,25 @@ class ToastNotificationHandler {
     typedef ABI::Windows::Data::Xml::Dom::IXmlNode IXmlNode;
     typedef ABI::Windows::Data::Xml::Dom::IXmlDocument IXmlDocument;
 
     void SetNodeValueString(HSTRING inputString, ComPtr<IXmlNode> node, ComPtr<IXmlDocument> xml);
   public:
     ToastNotificationHandler() {};
     ~ToastNotificationHandler() {};
 
-    void DisplayNotification(HSTRING title, HSTRING msg, HSTRING imagePath,
+    bool DisplayNotification(HSTRING title, HSTRING msg, HSTRING imagePath,
                              const nsAString& aCookie, const nsAString& aAppId);
-    void DisplayTextNotification(HSTRING title, HSTRING msg,
+    bool DisplayTextNotification(HSTRING title, HSTRING msg,
                                  const nsAString& aCookie,
                                  const nsAString& aAppId);
     HRESULT OnActivate(IToastNotification *notification, IInspectable *inspectable);
     HRESULT OnDismiss(IToastNotification *notification,
                       IToastDismissedEventArgs* aArgs);
 
   private:
     nsString mCookie;
     ComPtr<IToastNotificationManagerStatics> mToastNotificationManagerStatics;
 
-    void CreateWindowsNotificationFromXml(IXmlDocument *toastXml,
+    bool CreateWindowsNotificationFromXml(IXmlDocument *toastXml,
                                           const nsAString& aAppId);
     ComPtr<IXmlDocument> InitializeXmlForTemplate(ToastTemplateType templateType);
 };
--- a/widget/windows/winrt/nsWinMetroUtils.cpp
+++ b/widget/windows/winrt/nsWinMetroUtils.cpp
@@ -203,22 +203,30 @@ nsWinMetroUtils::ShowNativeToast(const n
   const nsAString &aCookie, const nsAString& aAppId)
 {
   ToastNotificationHandler* notification_handler =
       new ToastNotificationHandler;
 
   HSTRING title = HStringReference(aTitle.BeginReading()).Get();
   HSTRING msg = HStringReference(aMessage.BeginReading()).Get();
 
+  bool ret;
   if (anImage.Length() > 0) {
     HSTRING imagePath = HStringReference(anImage.BeginReading()).Get();
-    notification_handler->DisplayNotification(title, msg, imagePath, aCookie,
-                                              aAppId);
+    ret = notification_handler->DisplayNotification(title, msg, imagePath,
+                                                    aCookie,
+                                                    aAppId);
   } else {
-    notification_handler->DisplayTextNotification(title, msg, aCookie, aAppId);
+    ret = notification_handler->DisplayTextNotification(title, msg, aCookie,
+                                                        aAppId);
+  }
+
+  if (!ret) {
+    delete notification_handler;
+    return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWinMetroUtils::ShowSettingsFlyout()
 {