michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "ToastNotificationHandler.h" michael@0: #include "MetroUtils.h" michael@0: #include "mozilla/Services.h" michael@0: #include "FrameworkView.h" michael@0: michael@0: using namespace ABI::Windows::Foundation; michael@0: using namespace ABI::Windows::Data::Xml::Dom; michael@0: using namespace Microsoft::WRL; michael@0: using namespace Microsoft::WRL::Wrappers; michael@0: using namespace mozilla; michael@0: using namespace ABI::Windows::UI::Notifications; michael@0: michael@0: typedef __FITypedEventHandler_2_Windows__CUI__CNotifications__CToastNotification_IInspectable_t ToastActivationHandler; michael@0: typedef __FITypedEventHandler_2_Windows__CUI__CNotifications__CToastNotification_Windows__CUI__CNotifications__CToastDismissedEventArgs ToastDismissHandler; michael@0: michael@0: bool michael@0: ToastNotificationHandler::DisplayNotification(HSTRING title, michael@0: HSTRING msg, michael@0: HSTRING imagePath, michael@0: const nsAString& aCookie, michael@0: const nsAString& aAppId) michael@0: { michael@0: mCookie = aCookie; michael@0: michael@0: Microsoft::WRL::ComPtr toastXml = michael@0: InitializeXmlForTemplate(ToastTemplateType::ToastTemplateType_ToastImageAndText03); michael@0: Microsoft::WRL::ComPtr toastTextElements, toastImageElements; michael@0: Microsoft::WRL::ComPtr titleTextNodeRoot, msgTextNodeRoot, imageNodeRoot, srcAttribute; michael@0: michael@0: HSTRING textNodeStr, imageNodeStr, srcNodeStr; michael@0: HSTRING_HEADER textHeader, imageHeader, srcHeader; michael@0: WindowsCreateStringReference(L"text", 4, &textHeader, &textNodeStr); michael@0: WindowsCreateStringReference(L"image", 5, &imageHeader, &imageNodeStr); michael@0: WindowsCreateStringReference(L"src", 3, &srcHeader, &srcNodeStr); michael@0: toastXml->GetElementsByTagName(textNodeStr, &toastTextElements); michael@0: toastXml->GetElementsByTagName(imageNodeStr, &toastImageElements); michael@0: michael@0: AssertRetHRESULT(toastTextElements->Item(0, &titleTextNodeRoot), false); michael@0: AssertRetHRESULT(toastTextElements->Item(1, &msgTextNodeRoot), false); michael@0: AssertRetHRESULT(toastImageElements->Item(0, &imageNodeRoot), false); michael@0: michael@0: Microsoft::WRL::ComPtr attributes; michael@0: AssertRetHRESULT(imageNodeRoot->get_Attributes(&attributes), false); michael@0: AssertRetHRESULT(attributes->GetNamedItem(srcNodeStr, &srcAttribute), false); michael@0: michael@0: SetNodeValueString(title, titleTextNodeRoot.Get(), toastXml.Get()); michael@0: SetNodeValueString(msg, msgTextNodeRoot.Get(), toastXml.Get()); michael@0: SetNodeValueString(imagePath, srcAttribute.Get(), toastXml.Get()); michael@0: michael@0: return CreateWindowsNotificationFromXml(toastXml.Get(), aAppId); michael@0: } michael@0: michael@0: bool michael@0: ToastNotificationHandler::DisplayTextNotification(HSTRING title, michael@0: HSTRING msg, michael@0: const nsAString& aCookie, michael@0: const nsAString& aAppId) michael@0: { michael@0: mCookie = aCookie; michael@0: michael@0: Microsoft::WRL::ComPtr toastXml = michael@0: InitializeXmlForTemplate(ToastTemplateType::ToastTemplateType_ToastText03); michael@0: Microsoft::WRL::ComPtr toastTextElements; michael@0: Microsoft::WRL::ComPtr titleTextNodeRoot, msgTextNodeRoot; michael@0: michael@0: HSTRING textNodeStr; michael@0: HSTRING_HEADER textHeader; michael@0: WindowsCreateStringReference(L"text", 4, &textHeader, &textNodeStr); michael@0: toastXml->GetElementsByTagName(textNodeStr, &toastTextElements); michael@0: michael@0: AssertRetHRESULT(toastTextElements->Item(0, &titleTextNodeRoot), false); michael@0: AssertRetHRESULT(toastTextElements->Item(1, &msgTextNodeRoot), false); michael@0: michael@0: SetNodeValueString(title, titleTextNodeRoot.Get(), toastXml.Get()); michael@0: SetNodeValueString(msg, msgTextNodeRoot.Get(), toastXml.Get()); michael@0: michael@0: return CreateWindowsNotificationFromXml(toastXml.Get(), aAppId); michael@0: } michael@0: michael@0: Microsoft::WRL::ComPtr michael@0: ToastNotificationHandler::InitializeXmlForTemplate(ToastTemplateType templateType) { michael@0: Microsoft::WRL::ComPtr toastXml; michael@0: michael@0: AssertRetHRESULT(GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_Notifications_ToastNotificationManager).Get(), michael@0: mToastNotificationManagerStatics.GetAddressOf()), nullptr); michael@0: michael@0: mToastNotificationManagerStatics->GetTemplateContent(templateType, &toastXml); michael@0: michael@0: return toastXml; michael@0: } michael@0: michael@0: bool michael@0: ToastNotificationHandler::CreateWindowsNotificationFromXml(IXmlDocument *toastXml, michael@0: const nsAString& aAppId) michael@0: { michael@0: Microsoft::WRL::ComPtr notification; michael@0: Microsoft::WRL::ComPtr factory; michael@0: AssertRetHRESULT(GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_Notifications_ToastNotification).Get(), michael@0: factory.GetAddressOf()), false); michael@0: AssertRetHRESULT(factory->CreateToastNotification(toastXml, ¬ification), michael@0: false); michael@0: michael@0: EventRegistrationToken activatedToken; michael@0: AssertRetHRESULT(notification->add_Activated(Callback(this, michael@0: &ToastNotificationHandler::OnActivate).Get(), &activatedToken), false); michael@0: EventRegistrationToken dismissedToken; michael@0: AssertRetHRESULT(notification->add_Dismissed(Callback(this, michael@0: &ToastNotificationHandler::OnDismiss).Get(), &dismissedToken), false); michael@0: michael@0: Microsoft::WRL::ComPtr notifier; michael@0: if (aAppId.IsEmpty()) { michael@0: AssertRetHRESULT(mToastNotificationManagerStatics->CreateToastNotifier( michael@0: ¬ifier), false); michael@0: } else { michael@0: AssertRetHRESULT(mToastNotificationManagerStatics->CreateToastNotifierWithId( michael@0: HStringReference(PromiseFlatString(aAppId).get()).Get(), michael@0: ¬ifier), false); michael@0: } michael@0: AssertRetHRESULT(notifier->Show(notification.Get()), false); michael@0: michael@0: MetroUtils::FireObserver("metro_native_toast_shown", mCookie.get()); michael@0: michael@0: return true; michael@0: } michael@0: michael@0: void ToastNotificationHandler::SetNodeValueString(HSTRING inputString, michael@0: Microsoft::WRL::ComPtr node, Microsoft::WRL::ComPtr xml) { michael@0: Microsoft::WRL::ComPtr inputText; michael@0: Microsoft::WRL::ComPtr inputTextNode, pAppendedChild; michael@0: michael@0: AssertHRESULT(xml->CreateTextNode(inputString, &inputText)); michael@0: AssertHRESULT(inputText.As(&inputTextNode)); michael@0: AssertHRESULT(node->AppendChild(inputTextNode.Get(), &pAppendedChild)); michael@0: } michael@0: michael@0: HRESULT ToastNotificationHandler::OnActivate(IToastNotification *notification, IInspectable *inspectable) { michael@0: MetroUtils::FireObserver("metro_native_toast_clicked", mCookie.get()); michael@0: return S_OK; michael@0: } michael@0: michael@0: HRESULT michael@0: ToastNotificationHandler::OnDismiss(IToastNotification *notification, michael@0: IToastDismissedEventArgs* aArgs) michael@0: { michael@0: MetroUtils::FireObserver("metro_native_toast_dismissed", mCookie.get()); michael@0: delete this; michael@0: return S_OK; michael@0: }