TouchView always maximize mode: Suppressing invalid state changes, adding new windows...
[chromium-blink-merge.git] / win8 / metro_driver / toast_notification_handler.cc
blobfb44b11dc2cc3a2a09e29ca942468502e59d715d
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include <string>
7 #include "win8/metro_driver/stdafx.h"
8 #include "win8/metro_driver/toast_notification_handler.h"
10 #include "base/files/file_path.h"
11 #include "base/logging.h"
12 #include "base/path_service.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/installer/util/browser_distribution.h"
15 #include "chrome/installer/util/install_util.h"
16 #include "chrome/installer/util/shell_util.h"
18 #include "win8/metro_driver/winrt_utils.h"
20 typedef winfoundtn::ITypedEventHandler<
21 winui::Notifications::ToastNotification*, IInspectable*>
22 ToastActivationHandler;
24 typedef winfoundtn::ITypedEventHandler<
25 winui::Notifications::ToastNotification*,
26 winui::Notifications::ToastDismissedEventArgs*> ToastDismissedHandler;
28 namespace {
30 // Helper function to return the text node root identified by the index passed
31 // in.
32 HRESULT GetTextNodeRoot(
33 unsigned int index,
34 winxml::Dom::IXmlDocument* xml_doc,
35 winxml::Dom::IXmlNode** node) {
36 DCHECK(xml_doc);
37 DCHECK(node);
39 mswr::ComPtr<winxml::Dom::IXmlElement> document_element;
40 HRESULT hr = xml_doc->get_DocumentElement(&document_element);
41 CheckHR(hr);
43 mswr::ComPtr<winxml::Dom::IXmlNodeList> elements;
44 mswrw::HString tag_name;
45 tag_name.Attach(MakeHString(L"text"));
46 hr = document_element->GetElementsByTagName(tag_name.Get(),
47 &elements);
48 CheckHR(hr);
50 unsigned int count = 0;
51 elements->get_Length(&count);
53 if (index > count) {
54 DVLOG(1) << "Invalid text node index passed in : " << index;
55 return E_FAIL;
57 hr = elements->Item(index, node);
58 CheckHR(hr);
59 return hr;
62 // Helper function to append a text element to the text section in the
63 // XML document passed in.
64 // The index parameter identifies which text node we append to.
65 HRESULT CreateTextNode(winxml::Dom::IXmlDocument* xml_doc,
66 int index,
67 const base::string16& text_string) {
68 DCHECK(xml_doc);
70 mswr::ComPtr<winxml::Dom::IXmlElement> document_element;
71 HRESULT hr = xml_doc->get_DocumentElement(&document_element);
72 CheckHR(hr);
74 mswr::ComPtr<winxml::Dom::IXmlText> xml_text_node;
75 mswrw::HString data_hstring;
76 data_hstring.Attach(MakeHString(text_string.c_str()));
77 hr = xml_doc->CreateTextNode(data_hstring.Get(), &xml_text_node);
78 CheckHR(hr);
80 mswr::ComPtr<winxml::Dom::IXmlNode> created_node;
81 hr = xml_text_node.CopyTo(
82 winxml::Dom::IID_IXmlNode,
83 reinterpret_cast<void**>(created_node.GetAddressOf()));
84 CheckHR(hr);
86 mswr::ComPtr<winxml::Dom::IXmlNode> text_node_root;
87 hr = GetTextNodeRoot(index, xml_doc, &text_node_root);
88 CheckHR(hr);
90 mswr::ComPtr<winxml::Dom::IXmlNode> appended_node;
91 hr = text_node_root->AppendChild(created_node.Get(), &appended_node);
92 CheckHR(hr);
93 return hr;
96 } // namespace
98 ToastNotificationHandler::DesktopNotification::DesktopNotification(
99 const char* notification_origin,
100 const char* notification_icon,
101 const wchar_t* notification_title,
102 const wchar_t* notification_body,
103 const wchar_t* notification_display_source,
104 const char* notification_id,
105 base::win::MetroNotificationClickedHandler handler,
106 const wchar_t* handler_context)
107 : origin_url(notification_origin),
108 icon_url(notification_icon),
109 title(notification_title),
110 body(notification_body),
111 display_source(notification_display_source),
112 id(notification_id),
113 notification_handler(handler) {
114 if (handler_context)
115 notification_context = handler_context;
118 ToastNotificationHandler::DesktopNotification::DesktopNotification()
119 : notification_handler(NULL) {
122 ToastNotificationHandler::ToastNotificationHandler() {
123 DVLOG(1) << __FUNCTION__;
126 ToastNotificationHandler::~ToastNotificationHandler() {
127 DVLOG(1) << __FUNCTION__;
129 if (notifier_ && notification_)
130 CancelNotification();
133 void ToastNotificationHandler::DisplayNotification(
134 const DesktopNotification& notification) {
135 DVLOG(1) << __FUNCTION__;
137 DCHECK(notifier_.Get() == NULL);
138 DCHECK(notification_.Get() == NULL);
140 notification_info_ = notification;
142 mswr::ComPtr<winui::Notifications::IToastNotificationManagerStatics>
143 toast_manager;
145 HRESULT hr = winrt_utils::CreateActivationFactory(
146 RuntimeClass_Windows_UI_Notifications_ToastNotificationManager,
147 toast_manager.GetAddressOf());
148 CheckHR(hr);
150 mswr::ComPtr<winxml::Dom::IXmlDocument> toast_xml;
151 hr = toast_manager->GetTemplateContent(
152 winui::Notifications::ToastTemplateType_ToastText02,
153 &toast_xml);
154 CheckHR(hr);
156 if (!toast_xml)
157 return;
159 mswr::ComPtr<winxml::Dom::IXmlElement> document_element;
160 hr = toast_xml->get_DocumentElement(&document_element);
161 CheckHR(hr);
163 if (!document_element)
164 return;
166 hr = CreateTextNode(toast_xml.Get(), 0, notification.title);
167 CheckHR(hr);
169 hr = CreateTextNode(toast_xml.Get(), 1, notification.body);
170 CheckHR(hr);
172 mswrw::HString duration_attribute_name;
173 duration_attribute_name.Attach(MakeHString(L"duration"));
174 mswrw::HString duration_attribute_value;
175 duration_attribute_value.Attach(MakeHString(L"long"));
177 hr = document_element->SetAttribute(duration_attribute_name.Get(),
178 duration_attribute_value.Get());
179 CheckHR(hr);
181 // TODO(ananta)
182 // We should set the image and launch params attribute in the notification
183 // XNL as described here: http://msdn.microsoft.com/en-us/library/hh465448
184 // To set the image we may have to extract the image and specify it in the
185 // following url form. ms-appx:///images/foo.png
186 // The launch params as described don't get passed back to us via the
187 // winapp::Activation::ILaunchActivatedEventArgs argument. Needs to be
188 // investigated.
189 mswr::ComPtr<winui::Notifications::IToastNotificationFactory>
190 toast_notification_factory;
191 hr = winrt_utils::CreateActivationFactory(
192 RuntimeClass_Windows_UI_Notifications_ToastNotification,
193 toast_notification_factory.GetAddressOf());
194 CheckHR(hr);
196 hr = toast_notification_factory->CreateToastNotification(
197 toast_xml.Get(), &notification_);
198 CheckHR(hr);
200 base::FilePath chrome_path;
201 if (!PathService::Get(base::FILE_EXE, &chrome_path)) {
202 NOTREACHED() << "Failed to get chrome exe path";
203 return;
206 BrowserDistribution* dist = BrowserDistribution::GetDistribution();
207 bool is_per_user_install = InstallUtil::IsPerUserInstall(
208 chrome_path.value().c_str());
209 base::string16 appid =
210 ShellUtil::GetBrowserModelId(dist, is_per_user_install);
211 DVLOG(1) << "Chrome Appid is " << appid.c_str();
213 mswrw::HString app_user_model_id;
214 app_user_model_id.Attach(MakeHString(appid));
216 hr = toast_manager->CreateToastNotifierWithId(app_user_model_id.Get(),
217 &notifier_);
218 CheckHR(hr);
220 hr = notification_->add_Activated(
221 mswr::Callback<ToastActivationHandler>(
222 this, &ToastNotificationHandler::OnActivate).Get(),
223 &activated_token_);
224 CheckHR(hr);
226 hr = notifier_->Show(notification_.Get());
227 CheckHR(hr);
230 void ToastNotificationHandler::CancelNotification() {
231 DVLOG(1) << __FUNCTION__;
233 DCHECK(notifier_);
234 DCHECK(notification_);
236 notifier_->Hide(notification_.Get());
239 HRESULT ToastNotificationHandler::OnActivate(
240 winui::Notifications::IToastNotification* notification,
241 IInspectable* inspectable) {
242 // TODO(ananta)
243 // We should pass back information from the notification like the source url
244 // etc to ChromeAppView which would enable it to ensure that the
245 // correct tab in chrome is activated.
246 DVLOG(1) << __FUNCTION__;
248 if (notification_info_.notification_handler) {
249 notification_info_.notification_handler(
250 notification_info_.notification_context.c_str());
252 return S_OK;