| Index: win8/metro_driver/toast_notification_handler.cc
|
| diff --git a/win8/metro_driver/toast_notification_handler.cc b/win8/metro_driver/toast_notification_handler.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..36bddd5937d6b2ca6505d3fa063a835634461134
|
| --- /dev/null
|
| +++ b/win8/metro_driver/toast_notification_handler.cc
|
| @@ -0,0 +1,234 @@
|
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include <string>
|
| +
|
| +#include "win8/metro_driver/stdafx.h"
|
| +#include "win8/metro_driver/toast_notification_handler.h"
|
| +
|
| +#include "base/file_path.h"
|
| +#include "base/logging.h"
|
| +#include "base/path_service.h"
|
| +#include "base/utf_string_conversions.h"
|
| +// TODO(ananta)
|
| +// Refactor the chrome_util and shell_util code from chrome into a common lib
|
| +#include "win8/delegate_execute/chrome_util.h"
|
| +#include "win8/metro_driver/winrt_utils.h"
|
| +
|
| +typedef winfoundtn::ITypedEventHandler<
|
| + winui::Notifications::ToastNotification*, IInspectable*>
|
| + ToastActivationHandler;
|
| +
|
| +typedef winfoundtn::ITypedEventHandler<
|
| + winui::Notifications::ToastNotification*,
|
| + winui::Notifications::ToastDismissedEventArgs*> ToastDismissedHandler;
|
| +
|
| +namespace {
|
| +
|
| +// Helper function to return the text node root identified by the index passed
|
| +// in.
|
| +HRESULT GetTextNodeRoot(
|
| + unsigned int index,
|
| + winxml::Dom::IXmlDocument* xml_doc,
|
| + winxml::Dom::IXmlNode** node) {
|
| + DCHECK(xml_doc);
|
| + DCHECK(node);
|
| +
|
| + mswr::ComPtr<winxml::Dom::IXmlElement> document_element;
|
| + HRESULT hr = xml_doc->get_DocumentElement(&document_element);
|
| + CheckHR(hr);
|
| +
|
| + mswr::ComPtr<winxml::Dom::IXmlNodeList> elements;
|
| + mswrw::HString tag_name;
|
| + tag_name.Attach(MakeHString(L"text"));
|
| + hr = document_element->GetElementsByTagName(tag_name.Get(),
|
| + &elements);
|
| + CheckHR(hr);
|
| +
|
| + unsigned int count = 0;
|
| + elements->get_Length(&count);
|
| +
|
| + if (index > count) {
|
| + DVLOG(1) << "Invalid text node index passed in : " << index;
|
| + return E_FAIL;
|
| + }
|
| + hr = elements->Item(index, node);
|
| + CheckHR(hr);
|
| + return hr;
|
| +}
|
| +
|
| +// Helper function to append a text element to the text section in the
|
| +// XML document passed in.
|
| +// The index parameter identifies which text node we append to.
|
| +HRESULT CreateTextNode(winxml::Dom::IXmlDocument* xml_doc,
|
| + int index,
|
| + const string16& text_string) {
|
| + DCHECK(xml_doc);
|
| +
|
| + mswr::ComPtr<winxml::Dom::IXmlElement> document_element;
|
| + HRESULT hr = xml_doc->get_DocumentElement(&document_element);
|
| + CheckHR(hr);
|
| +
|
| + mswr::ComPtr<winxml::Dom::IXmlText> xml_text_node;
|
| + mswrw::HString data_hstring;
|
| + data_hstring.Attach(MakeHString(text_string.c_str()));
|
| + hr = xml_doc->CreateTextNode(data_hstring.Get(), &xml_text_node);
|
| + CheckHR(hr);
|
| +
|
| + mswr::ComPtr<winxml::Dom::IXmlNode> created_node;
|
| + hr = xml_text_node.CopyTo(
|
| + winxml::Dom::IID_IXmlNode,
|
| + reinterpret_cast<void**>(created_node.GetAddressOf()));
|
| + CheckHR(hr);
|
| +
|
| + mswr::ComPtr<winxml::Dom::IXmlNode> text_node_root;
|
| + hr = GetTextNodeRoot(index, xml_doc, &text_node_root);
|
| + CheckHR(hr);
|
| +
|
| + mswr::ComPtr<winxml::Dom::IXmlNode> appended_node;
|
| + hr = text_node_root->AppendChild(created_node.Get(), &appended_node);
|
| + CheckHR(hr);
|
| + return hr;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +ToastNotificationHandler::DesktopNotification::DesktopNotification(
|
| + const char* notification_origin,
|
| + const char* notification_icon,
|
| + const wchar_t* notification_title,
|
| + const wchar_t* notification_body,
|
| + const wchar_t* notification_display_source,
|
| + const char* notification_id)
|
| + : origin_url(notification_origin),
|
| + icon_url(notification_icon),
|
| + title(notification_title),
|
| + body(notification_body),
|
| + display_source(notification_display_source),
|
| + id(notification_id) {
|
| +}
|
| +
|
| +
|
| +ToastNotificationHandler::ToastNotificationHandler() {
|
| + DVLOG(1) << __FUNCTION__;
|
| +}
|
| +
|
| +ToastNotificationHandler::~ToastNotificationHandler() {
|
| + DVLOG(1) << __FUNCTION__;
|
| +
|
| + if (notifier_ && notification_)
|
| + CancelNotification();
|
| +}
|
| +
|
| +void ToastNotificationHandler::DisplayNotification(
|
| + const DesktopNotification& notification) {
|
| + DVLOG(1) << __FUNCTION__;
|
| +
|
| + DCHECK(notifier_.Get() == NULL);
|
| + DCHECK(notification_.Get() == NULL);
|
| +
|
| + mswr::ComPtr<winui::Notifications::IToastNotificationManagerStatics>
|
| + toast_manager;
|
| +
|
| + HRESULT hr = winrt_utils::CreateActivationFactory(
|
| + RuntimeClass_Windows_UI_Notifications_ToastNotificationManager,
|
| + toast_manager.GetAddressOf());
|
| + CheckHR(hr);
|
| +
|
| + mswr::ComPtr<winxml::Dom::IXmlDocument> toast_xml;
|
| + hr = toast_manager->GetTemplateContent(
|
| + winui::Notifications::ToastTemplateType_ToastText02,
|
| + &toast_xml);
|
| + CheckHR(hr);
|
| +
|
| + if (!toast_xml)
|
| + return;
|
| +
|
| + mswr::ComPtr<winxml::Dom::IXmlElement> document_element;
|
| + hr = toast_xml->get_DocumentElement(&document_element);
|
| + CheckHR(hr);
|
| +
|
| + if (!document_element)
|
| + return;
|
| +
|
| + hr = CreateTextNode(toast_xml.Get(), 0, notification.title);
|
| + CheckHR(hr);
|
| +
|
| + hr = CreateTextNode(toast_xml.Get(), 1, notification.body);
|
| + CheckHR(hr);
|
| +
|
| + mswrw::HString duration_attribute_name;
|
| + duration_attribute_name.Attach(MakeHString(L"duration"));
|
| + mswrw::HString duration_attribute_value;
|
| + duration_attribute_value.Attach(MakeHString(L"long"));
|
| +
|
| + hr = document_element->SetAttribute(duration_attribute_name.Get(),
|
| + duration_attribute_value.Get());
|
| + CheckHR(hr);
|
| +
|
| + // TODO(ananta)
|
| + // We should set the image and launch params attribute in the notification
|
| + // XNL as described here: http://msdn.microsoft.com/en-us/library/hh465448
|
| + // To set the image we may have to extract the image and specify it in the
|
| + // following url form. ms-appx:///images/foo.png
|
| + // The launch params as described don't get passed back to us via the
|
| + // winapp::Activation::ILaunchActivatedEventArgs argument. Needs to be
|
| + // investigated.
|
| + mswr::ComPtr<winui::Notifications::IToastNotificationFactory>
|
| + toast_notification_factory;
|
| + hr = winrt_utils::CreateActivationFactory(
|
| + RuntimeClass_Windows_UI_Notifications_ToastNotification,
|
| + toast_notification_factory.GetAddressOf());
|
| + CheckHR(hr);
|
| +
|
| + hr = toast_notification_factory->CreateToastNotification(
|
| + toast_xml.Get(), ¬ification_);
|
| + CheckHR(hr);
|
| +
|
| + FilePath chrome_path;
|
| + if (!PathService::Get(base::FILE_EXE, &chrome_path)) {
|
| + NOTREACHED() << "Failed to get chrome exe path";
|
| + return;
|
| + }
|
| + string16 appid = delegate_execute::GetAppId(chrome_path);
|
| + DVLOG(1) << "Chrome Appid is " << appid.c_str();
|
| +
|
| + // TODO(ananta)
|
| + // We should probably use BrowserDistribution here to get the product name.
|
| + mswrw::HString app_user_model_id;
|
| + app_user_model_id.Attach(MakeHString(appid));
|
| +
|
| + hr = toast_manager->CreateToastNotifierWithId(app_user_model_id.Get(),
|
| + ¬ifier_);
|
| + CheckHR(hr);
|
| +
|
| + hr = notification_->add_Activated(
|
| + mswr::Callback<ToastActivationHandler>(
|
| + this, &ToastNotificationHandler::OnActivate).Get(),
|
| + &activated_token_);
|
| + CheckHR(hr);
|
| +
|
| + hr = notifier_->Show(notification_.Get());
|
| + CheckHR(hr);
|
| +}
|
| +
|
| +void ToastNotificationHandler::CancelNotification() {
|
| + DVLOG(1) << __FUNCTION__;
|
| +
|
| + DCHECK(notifier_);
|
| + DCHECK(notification_);
|
| +
|
| + notifier_->Hide(notification_.Get());
|
| +}
|
| +
|
| +HRESULT ToastNotificationHandler::OnActivate(
|
| + winui::Notifications::IToastNotification* notification,
|
| + IInspectable* inspectable) {
|
| + // TODO(ananta)
|
| + // We should pass back information from the notification like the source url
|
| + // etc to ChromeAppView which would enable it to ensure that the
|
| + // correct tab in chrome is activated.
|
| + DVLOG(1) << __FUNCTION__;
|
| + return S_OK;
|
| +}
|
|
|