1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/widget/windows/winrt/ToastNotificationHandler.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,153 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "ToastNotificationHandler.h" 1.10 +#include "MetroUtils.h" 1.11 +#include "mozilla/Services.h" 1.12 +#include "FrameworkView.h" 1.13 + 1.14 +using namespace ABI::Windows::Foundation; 1.15 +using namespace ABI::Windows::Data::Xml::Dom; 1.16 +using namespace Microsoft::WRL; 1.17 +using namespace Microsoft::WRL::Wrappers; 1.18 +using namespace mozilla; 1.19 +using namespace ABI::Windows::UI::Notifications; 1.20 + 1.21 +typedef __FITypedEventHandler_2_Windows__CUI__CNotifications__CToastNotification_IInspectable_t ToastActivationHandler; 1.22 +typedef __FITypedEventHandler_2_Windows__CUI__CNotifications__CToastNotification_Windows__CUI__CNotifications__CToastDismissedEventArgs ToastDismissHandler; 1.23 + 1.24 +bool 1.25 +ToastNotificationHandler::DisplayNotification(HSTRING title, 1.26 + HSTRING msg, 1.27 + HSTRING imagePath, 1.28 + const nsAString& aCookie, 1.29 + const nsAString& aAppId) 1.30 +{ 1.31 + mCookie = aCookie; 1.32 + 1.33 + Microsoft::WRL::ComPtr<IXmlDocument> toastXml = 1.34 + InitializeXmlForTemplate(ToastTemplateType::ToastTemplateType_ToastImageAndText03); 1.35 + Microsoft::WRL::ComPtr<IXmlNodeList> toastTextElements, toastImageElements; 1.36 + Microsoft::WRL::ComPtr<IXmlNode> titleTextNodeRoot, msgTextNodeRoot, imageNodeRoot, srcAttribute; 1.37 + 1.38 + HSTRING textNodeStr, imageNodeStr, srcNodeStr; 1.39 + HSTRING_HEADER textHeader, imageHeader, srcHeader; 1.40 + WindowsCreateStringReference(L"text", 4, &textHeader, &textNodeStr); 1.41 + WindowsCreateStringReference(L"image", 5, &imageHeader, &imageNodeStr); 1.42 + WindowsCreateStringReference(L"src", 3, &srcHeader, &srcNodeStr); 1.43 + toastXml->GetElementsByTagName(textNodeStr, &toastTextElements); 1.44 + toastXml->GetElementsByTagName(imageNodeStr, &toastImageElements); 1.45 + 1.46 + AssertRetHRESULT(toastTextElements->Item(0, &titleTextNodeRoot), false); 1.47 + AssertRetHRESULT(toastTextElements->Item(1, &msgTextNodeRoot), false); 1.48 + AssertRetHRESULT(toastImageElements->Item(0, &imageNodeRoot), false); 1.49 + 1.50 + Microsoft::WRL::ComPtr<IXmlNamedNodeMap> attributes; 1.51 + AssertRetHRESULT(imageNodeRoot->get_Attributes(&attributes), false); 1.52 + AssertRetHRESULT(attributes->GetNamedItem(srcNodeStr, &srcAttribute), false); 1.53 + 1.54 + SetNodeValueString(title, titleTextNodeRoot.Get(), toastXml.Get()); 1.55 + SetNodeValueString(msg, msgTextNodeRoot.Get(), toastXml.Get()); 1.56 + SetNodeValueString(imagePath, srcAttribute.Get(), toastXml.Get()); 1.57 + 1.58 + return CreateWindowsNotificationFromXml(toastXml.Get(), aAppId); 1.59 +} 1.60 + 1.61 +bool 1.62 +ToastNotificationHandler::DisplayTextNotification(HSTRING title, 1.63 + HSTRING msg, 1.64 + const nsAString& aCookie, 1.65 + const nsAString& aAppId) 1.66 +{ 1.67 + mCookie = aCookie; 1.68 + 1.69 + Microsoft::WRL::ComPtr<IXmlDocument> toastXml = 1.70 + InitializeXmlForTemplate(ToastTemplateType::ToastTemplateType_ToastText03); 1.71 + Microsoft::WRL::ComPtr<IXmlNodeList> toastTextElements; 1.72 + Microsoft::WRL::ComPtr<IXmlNode> titleTextNodeRoot, msgTextNodeRoot; 1.73 + 1.74 + HSTRING textNodeStr; 1.75 + HSTRING_HEADER textHeader; 1.76 + WindowsCreateStringReference(L"text", 4, &textHeader, &textNodeStr); 1.77 + toastXml->GetElementsByTagName(textNodeStr, &toastTextElements); 1.78 + 1.79 + AssertRetHRESULT(toastTextElements->Item(0, &titleTextNodeRoot), false); 1.80 + AssertRetHRESULT(toastTextElements->Item(1, &msgTextNodeRoot), false); 1.81 + 1.82 + SetNodeValueString(title, titleTextNodeRoot.Get(), toastXml.Get()); 1.83 + SetNodeValueString(msg, msgTextNodeRoot.Get(), toastXml.Get()); 1.84 + 1.85 + return CreateWindowsNotificationFromXml(toastXml.Get(), aAppId); 1.86 +} 1.87 + 1.88 +Microsoft::WRL::ComPtr<IXmlDocument> 1.89 +ToastNotificationHandler::InitializeXmlForTemplate(ToastTemplateType templateType) { 1.90 + Microsoft::WRL::ComPtr<IXmlDocument> toastXml; 1.91 + 1.92 + AssertRetHRESULT(GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_Notifications_ToastNotificationManager).Get(), 1.93 + mToastNotificationManagerStatics.GetAddressOf()), nullptr); 1.94 + 1.95 + mToastNotificationManagerStatics->GetTemplateContent(templateType, &toastXml); 1.96 + 1.97 + return toastXml; 1.98 +} 1.99 + 1.100 +bool 1.101 +ToastNotificationHandler::CreateWindowsNotificationFromXml(IXmlDocument *toastXml, 1.102 + const nsAString& aAppId) 1.103 +{ 1.104 + Microsoft::WRL::ComPtr<IToastNotification> notification; 1.105 + Microsoft::WRL::ComPtr<IToastNotificationFactory> factory; 1.106 + AssertRetHRESULT(GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_Notifications_ToastNotification).Get(), 1.107 + factory.GetAddressOf()), false); 1.108 + AssertRetHRESULT(factory->CreateToastNotification(toastXml, ¬ification), 1.109 + false); 1.110 + 1.111 + EventRegistrationToken activatedToken; 1.112 + AssertRetHRESULT(notification->add_Activated(Callback<ToastActivationHandler>(this, 1.113 + &ToastNotificationHandler::OnActivate).Get(), &activatedToken), false); 1.114 + EventRegistrationToken dismissedToken; 1.115 + AssertRetHRESULT(notification->add_Dismissed(Callback<ToastDismissHandler>(this, 1.116 + &ToastNotificationHandler::OnDismiss).Get(), &dismissedToken), false); 1.117 + 1.118 + Microsoft::WRL::ComPtr<IToastNotifier> notifier; 1.119 + if (aAppId.IsEmpty()) { 1.120 + AssertRetHRESULT(mToastNotificationManagerStatics->CreateToastNotifier( 1.121 + ¬ifier), false); 1.122 + } else { 1.123 + AssertRetHRESULT(mToastNotificationManagerStatics->CreateToastNotifierWithId( 1.124 + HStringReference(PromiseFlatString(aAppId).get()).Get(), 1.125 + ¬ifier), false); 1.126 + } 1.127 + AssertRetHRESULT(notifier->Show(notification.Get()), false); 1.128 + 1.129 + MetroUtils::FireObserver("metro_native_toast_shown", mCookie.get()); 1.130 + 1.131 + return true; 1.132 +} 1.133 + 1.134 +void ToastNotificationHandler::SetNodeValueString(HSTRING inputString, 1.135 + Microsoft::WRL::ComPtr<IXmlNode> node, Microsoft::WRL::ComPtr<IXmlDocument> xml) { 1.136 + Microsoft::WRL::ComPtr<IXmlText> inputText; 1.137 + Microsoft::WRL::ComPtr<IXmlNode> inputTextNode, pAppendedChild; 1.138 + 1.139 + AssertHRESULT(xml->CreateTextNode(inputString, &inputText)); 1.140 + AssertHRESULT(inputText.As(&inputTextNode)); 1.141 + AssertHRESULT(node->AppendChild(inputTextNode.Get(), &pAppendedChild)); 1.142 +} 1.143 + 1.144 +HRESULT ToastNotificationHandler::OnActivate(IToastNotification *notification, IInspectable *inspectable) { 1.145 + MetroUtils::FireObserver("metro_native_toast_clicked", mCookie.get()); 1.146 + return S_OK; 1.147 +} 1.148 + 1.149 +HRESULT 1.150 +ToastNotificationHandler::OnDismiss(IToastNotification *notification, 1.151 + IToastDismissedEventArgs* aArgs) 1.152 +{ 1.153 + MetroUtils::FireObserver("metro_native_toast_dismissed", mCookie.get()); 1.154 + delete this; 1.155 + return S_OK; 1.156 +}