Bug 919929 - AlertsService for Metro should send alertshow and alertfinished observer. r=jimm
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Wed, 09 Oct 2013 11:15:41 +0900
changeset 164255 80ceb04b7183a8bb5f5f589559d2b5831040cfb6
parent 164237 6fef99317f215e9b7b4830100f1d5989330a47b2
child 164256 266532efd5cb59da40ea3755ecc16fb2507991b1
push id3066
push userakeybl@mozilla.com
push dateMon, 09 Dec 2013 19:58:46 +0000
treeherdermozilla-beta@a31a0dce83aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm
bugs919929
milestone27.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 919929 - AlertsService for Metro should send alertshow and alertfinished observer. r=jimm
browser/metro/base/content/helperui/AlertsHelper.js
browser/metro/components/AlertsService.js
widget/nsIWinMetroUtils.idl
widget/windows/winrt/ToastNotificationHandler.cpp
widget/windows/winrt/ToastNotificationHandler.h
widget/windows/winrt/nsWinMetroUtils.cpp
--- a/browser/metro/base/content/helperui/AlertsHelper.js
+++ b/browser/metro/base/content/helperui/AlertsHelper.js
@@ -1,25 +1,41 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 var AlertsHelper = {
   _listener: null,
-  _cookie: "",
 
   showAlertNotification: function ah_show(aImageURL, aTitle, aText, aTextClickable, aCookie, aListener) {
-    Services.obs.addObserver(this, "metro_native_toast_clicked", false);
+    if (aListener) {
+      Services.obs.addObserver(this, "metro_native_toast_clicked", false);
+      Services.obs.addObserver(this, "metro_native_toast_dismissed", false);
+      Services.obs.addObserver(this, "metro_native_toast_shown", false);
+    }
     this._listener = aListener;
-    this._cookie = aCookie;
+
+    Services.metro.showNativeToast(aTitle, aText, aImageURL, aCookie);
+  },
 
-    Services.metro.showNativeToast(aTitle, aText, aImageURL);
+  closeAlert: function ah_close() {
+    if (this._listener) {
+      Services.obs.removeObserver(this, "metro_native_toast_shown");
+      Services.obs.removeObserver(this, "metro_native_toast_clicked");
+      Services.obs.removeObserver(this, "metro_native_toast_dismissed");
+      this._listener = null;
+    }
   },
 
   observe: function(aSubject, aTopic, aData) {
     switch (aTopic) {
       case "metro_native_toast_clicked":
-        Services.obs.removeObserver(this, "metro_native_toast_clicked");
-        this._listener.observe(null, "alertclickcallback", this._cookie);
+        this._listener.observe(null, "alertclickcallback", aData);
+        break;
+      case "metro_native_toast_shown":
+        this._listener.observe(null, "alertshow", aData);
+        break;
+      case "metro_native_toast_dismissed":
+        this._listener.observe(null, "alertfinished", aData);
         break;
     }
   }
 };
--- a/browser/metro/components/AlertsService.js
+++ b/browser/metro/components/AlertsService.js
@@ -13,31 +13,37 @@ Cu.import("resource://gre/modules/Servic
 // -----------------------------------------------------------------------
 
 function AlertsService() { }
 
 AlertsService.prototype = {
   classID: Components.ID("{fe33c107-82a4-41d6-8c64-5353267e04c9}"),
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIAlertsService]),
 
-  showAlertNotification: function(aImageUrl, aTitle, aText, aTextClickable, aCookie, aAlertListener, aName) {
+  showAlertNotification: function(aImageUrl, aTitle, aText, aTextClickable,
+                                  aCookie, aAlertListener, aName, aDir, aLang) {
     let browser = Services.wm.getMostRecentWindow("navigator:browser");
     try {
       browser.AlertsHelper.showAlertNotification(aImageUrl, aTitle, aText, aTextClickable, aCookie, aAlertListener);
     } catch (ex) {
       let chromeWin = this._getChromeWindow(browser).wrappedJSObject;
       let notificationBox = chromeWin.Browser.getNotificationBox();
       notificationBox.appendNotification(aTitle,
                                          aText,
                                          aImageUrl,
                                          notificationBox.PRIORITY_WARNING_MEDIUM,
                                          null);
     }
   },
 
+  closeAlert: function(aName) {
+    let browser = Services.wm.getMostRecentWindow("navigator:browser");
+    browser.AlertsHelper.closeAlert();
+  },
+
   _getChromeWindow: function (aWindow) {
       let chromeWin = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                             .getInterface(Ci.nsIWebNavigation)
                             .QueryInterface(Ci.nsIDocShellTreeItem)
                             .rootTreeItem
                             .QueryInterface(Ci.nsIInterfaceRequestor)
                             .getInterface(Ci.nsIDOMWindow)
                             .QueryInterface(Ci.nsIDOMChromeWindow);
--- 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(fa6750a2-f0fe-411c-af23-1cd6d2fdeceb)]
+[scriptable, uuid(25524bde-8b30-4b49-8d67-7070c790aada)]
 interface nsIWinMetroUtils : nsISupports
 {
   /* return constants for the handPreference property */
   const long handPreferenceLeft = 0;
   const long handPreferenceRight = 1;
 
   /**
    * Determine if the current browser is running in the metro immersive
@@ -44,17 +44,17 @@ interface nsIWinMetroUtils : nsISupports
    * Launches the specified application with the specified arguments and
    * switches to Desktop mode if in metro mode.
    */
    void launchInDesktop(in AString aPath, in AString aArguments); 
 
   /**
    * Displays a native Windows 8 toast.
    */
-   void showNativeToast(in AString aTitle, in AString aMessage, in AString anImage);
+   void showNativeToast(in AString aTitle, in AString aMessage, in AString anImage, in AString aCookie);
 
   /**
    * Secondary tiles are a Windows 8 specific feature for pinning new tiles
    * to the start screen.   Tiles can later be activated whether the browser is
    * already opened or not. 
    */
 
   /**
--- a/widget/windows/winrt/ToastNotificationHandler.cpp
+++ b/widget/windows/winrt/ToastNotificationHandler.cpp
@@ -11,18 +11,26 @@
 using namespace ABI::Windows::Foundation;
 using namespace ABI::Windows::Data::Xml::Dom;
 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 ToastNotificationHandler::DisplayNotification(HSTRING title, HSTRING msg, HSTRING imagePath) {
+void
+ToastNotificationHandler::DisplayNotification(HSTRING title,
+                                              HSTRING msg,
+                                              HSTRING imagePath,
+                                              const nsAString& aCookie)
+{
+  mCookie = aCookie;
+
   ComPtr<IToastNotificationManagerStatics> toastNotificationManagerStatics;
   AssertHRESULT(GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_Notifications_ToastNotificationManager).Get(),
                                     toastNotificationManagerStatics.GetAddressOf()));
 
   ComPtr<IXmlDocument> toastXml;
   toastNotificationManagerStatics->GetTemplateContent(ToastTemplateType::ToastTemplateType_ToastImageAndText03, &toastXml);
 
   ComPtr<IXmlNodeList> toastTextElements, toastImageElements;
@@ -52,27 +60,40 @@ void ToastNotificationHandler::DisplayNo
   ComPtr<IToastNotificationFactory> factory;
   AssertHRESULT(GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_Notifications_ToastNotification).Get(),
                 factory.GetAddressOf()));
   AssertHRESULT(factory->CreateToastNotification(toastXml.Get(), &notification));
 
   EventRegistrationToken activatedToken;
   AssertHRESULT(notification->add_Activated(Callback<ToastActivationHandler>(this,
       &ToastNotificationHandler::OnActivate).Get(), &activatedToken));
+  EventRegistrationToken dismissedToken;
+  AssertHRESULT(notification->add_Dismissed(Callback<ToastDismissHandler>(this,
+      &ToastNotificationHandler::OnDismiss).Get(), &dismissedToken));
 
   ComPtr<IToastNotifier> notifier;
   toastNotificationManagerStatics->CreateToastNotifier(&notifier);
   notifier->Show(notification.Get());
+
+  MetroUtils::FireObserver("metro_native_toast_shown", mCookie.get());
 }
 
 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));
   AssertHRESULT(node->AppendChild(inputTextNode.Get(), &pAppendedChild));
 }
 
 HRESULT ToastNotificationHandler::OnActivate(IToastNotification *notification, IInspectable *inspectable) {
-  MetroUtils::FireObserver("metro_native_toast_clicked");
+  MetroUtils::FireObserver("metro_native_toast_clicked", mCookie.get());
   return S_OK;
 }
+
+HRESULT
+ToastNotificationHandler::OnDismiss(IToastNotification *notification,
+                                    IToastDismissedEventArgs* aArgs)
+{
+  MetroUtils::FireObserver("metro_native_toast_dismissed", mCookie.get());
+  return S_OK;
+}
--- a/widget/windows/winrt/ToastNotificationHandler.h
+++ b/widget/windows/winrt/ToastNotificationHandler.h
@@ -3,24 +3,31 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #pragma once
 
 #include <windows.ui.notifications.h>
 #include <windows.data.xml.dom.h>
 #include "mozwrlbase.h"
+#include "nsString.h"
 
 using namespace Microsoft::WRL;
 
 class ToastNotificationHandler {
     typedef ABI::Windows::UI::Notifications::IToastNotification IToastNotification;
+    typedef ABI::Windows::UI::Notifications::IToastDismissedEventArgs IToastDismissedEventArgs;
     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);
+    void DisplayNotification(HSTRING title, HSTRING msg, HSTRING imagePath, const nsAString& aCookie);
     HRESULT OnActivate(IToastNotification *notification, IInspectable *inspectable);
+    HRESULT OnDismiss(IToastNotification *notification,
+                      IToastDismissedEventArgs* aArgs);
+
+  private:
+    nsString mCookie;
 };
--- a/widget/windows/winrt/nsWinMetroUtils.cpp
+++ b/widget/windows/winrt/nsWinMetroUtils.cpp
@@ -340,30 +340,31 @@ nsWinMetroUtils::LaunchInDesktop(const n
   if (!ShellExecuteEx(&sinfo)) {
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWinMetroUtils::ShowNativeToast(const nsAString &aTitle,
-  const nsAString &aMessage, const nsAString &anImage)
+  const nsAString &aMessage, const nsAString &anImage,
+  const nsAString &aCookie)
 {
   // Firefox is in the foreground, no need for a notification.
   if (::GetActiveWindow() == ::GetForegroundWindow()) {
     return NS_OK;
   }
 
   ToastNotificationHandler* notification_handler =
       new ToastNotificationHandler;
 
   HSTRING title = HStringReference(aTitle.BeginReading()).Get();
   HSTRING msg = HStringReference(aMessage.BeginReading()).Get();
   HSTRING imagePath = HStringReference(anImage.BeginReading()).Get();
-  notification_handler->DisplayNotification(title, msg, imagePath);
+  notification_handler->DisplayNotification(title, msg, imagePath, aCookie);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWinMetroUtils::ShowSettingsFlyout()
 {
   if (XRE_GetWindowsEnvironment() == WindowsEnvironmentType_Desktop) {