Only sync parent directory once after a leveldb file rename.
[chromium-blink-merge.git] / win8 / metro_driver / toast_notification_handler.cc
blob9448e12b74de07da09cc562519e24a9353b72872
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/utf_string_conversions.h"
14 // TODO(ananta)
15 // Refactor the chrome_util and shell_util code from chrome into a common lib
16 #include "win8/delegate_execute/chrome_util.h"
17 #include "win8/metro_driver/winrt_utils.h"
19 typedef winfoundtn::ITypedEventHandler<
20 winui::Notifications::ToastNotification*, IInspectable*>
21 ToastActivationHandler;
23 typedef winfoundtn::ITypedEventHandler<
24 winui::Notifications::ToastNotification*,
25 winui::Notifications::ToastDismissedEventArgs*> ToastDismissedHandler;
27 namespace {
29 // Helper function to return the text node root identified by the index passed
30 // in.
31 HRESULT GetTextNodeRoot(
32 unsigned int index,
33 winxml::Dom::IXmlDocument* xml_doc,
34 winxml::Dom::IXmlNode** node) {
35 DCHECK(xml_doc);
36 DCHECK(node);
38 mswr::ComPtr<winxml::Dom::IXmlElement> document_element;
39 HRESULT hr = xml_doc->get_DocumentElement(&document_element);
40 CheckHR(hr);
42 mswr::ComPtr<winxml::Dom::IXmlNodeList> elements;
43 mswrw::HString tag_name;
44 tag_name.Attach(MakeHString(L"text"));
45 hr = document_element->GetElementsByTagName(tag_name.Get(),
46 &elements);
47 CheckHR(hr);
49 unsigned int count = 0;
50 elements->get_Length(&count);
52 if (index > count) {
53 DVLOG(1) << "Invalid text node index passed in : " << index;
54 return E_FAIL;
56 hr = elements->Item(index, node);
57 CheckHR(hr);
58 return hr;
61 // Helper function to append a text element to the text section in the
62 // XML document passed in.
63 // The index parameter identifies which text node we append to.
64 HRESULT CreateTextNode(winxml::Dom::IXmlDocument* xml_doc,
65 int index,
66 const string16& text_string) {
67 DCHECK(xml_doc);
69 mswr::ComPtr<winxml::Dom::IXmlElement> document_element;
70 HRESULT hr = xml_doc->get_DocumentElement(&document_element);
71 CheckHR(hr);
73 mswr::ComPtr<winxml::Dom::IXmlText> xml_text_node;
74 mswrw::HString data_hstring;
75 data_hstring.Attach(MakeHString(text_string.c_str()));
76 hr = xml_doc->CreateTextNode(data_hstring.Get(), &xml_text_node);
77 CheckHR(hr);
79 mswr::ComPtr<winxml::Dom::IXmlNode> created_node;
80 hr = xml_text_node.CopyTo(
81 winxml::Dom::IID_IXmlNode,
82 reinterpret_cast<void**>(created_node.GetAddressOf()));
83 CheckHR(hr);
85 mswr::ComPtr<winxml::Dom::IXmlNode> text_node_root;
86 hr = GetTextNodeRoot(index, xml_doc, &text_node_root);
87 CheckHR(hr);
89 mswr::ComPtr<winxml::Dom::IXmlNode> appended_node;
90 hr = text_node_root->AppendChild(created_node.Get(), &appended_node);
91 CheckHR(hr);
92 return hr;
95 } // namespace
97 ToastNotificationHandler::DesktopNotification::DesktopNotification(
98 const char* notification_origin,
99 const char* notification_icon,
100 const wchar_t* notification_title,
101 const wchar_t* notification_body,
102 const wchar_t* notification_display_source,
103 const char* notification_id,
104 base::win::MetroNotificationClickedHandler handler,
105 const wchar_t* handler_context)
106 : origin_url(notification_origin),
107 icon_url(notification_icon),
108 title(notification_title),
109 body(notification_body),
110 display_source(notification_display_source),
111 id(notification_id),
112 notification_handler(handler) {
113 if (handler_context)
114 notification_context = handler_context;
117 ToastNotificationHandler::DesktopNotification::DesktopNotification()
118 : notification_handler(NULL) {
121 ToastNotificationHandler::ToastNotificationHandler() {
122 DVLOG(1) << __FUNCTION__;
125 ToastNotificationHandler::~ToastNotificationHandler() {
126 DVLOG(1) << __FUNCTION__;
128 if (notifier_ && notification_)
129 CancelNotification();
132 void ToastNotificationHandler::DisplayNotification(
133 const DesktopNotification& notification) {
134 DVLOG(1) << __FUNCTION__;
136 DCHECK(notifier_.Get() == NULL);
137 DCHECK(notification_.Get() == NULL);
139 notification_info_ = notification;
141 mswr::ComPtr<winui::Notifications::IToastNotificationManagerStatics>
142 toast_manager;
144 HRESULT hr = winrt_utils::CreateActivationFactory(
145 RuntimeClass_Windows_UI_Notifications_ToastNotificationManager,
146 toast_manager.GetAddressOf());
147 CheckHR(hr);
149 mswr::ComPtr<winxml::Dom::IXmlDocument> toast_xml;
150 hr = toast_manager->GetTemplateContent(
151 winui::Notifications::ToastTemplateType_ToastText02,
152 &toast_xml);
153 CheckHR(hr);
155 if (!toast_xml)
156 return;
158 mswr::ComPtr<winxml::Dom::IXmlElement> document_element;
159 hr = toast_xml->get_DocumentElement(&document_element);
160 CheckHR(hr);
162 if (!document_element)
163 return;
165 hr = CreateTextNode(toast_xml.Get(), 0, notification.title);
166 CheckHR(hr);
168 hr = CreateTextNode(toast_xml.Get(), 1, notification.body);
169 CheckHR(hr);
171 mswrw::HString duration_attribute_name;
172 duration_attribute_name.Attach(MakeHString(L"duration"));
173 mswrw::HString duration_attribute_value;
174 duration_attribute_value.Attach(MakeHString(L"long"));
176 hr = document_element->SetAttribute(duration_attribute_name.Get(),
177 duration_attribute_value.Get());
178 CheckHR(hr);
180 // TODO(ananta)
181 // We should set the image and launch params attribute in the notification
182 // XNL as described here: http://msdn.microsoft.com/en-us/library/hh465448
183 // To set the image we may have to extract the image and specify it in the
184 // following url form. ms-appx:///images/foo.png
185 // The launch params as described don't get passed back to us via the
186 // winapp::Activation::ILaunchActivatedEventArgs argument. Needs to be
187 // investigated.
188 mswr::ComPtr<winui::Notifications::IToastNotificationFactory>
189 toast_notification_factory;
190 hr = winrt_utils::CreateActivationFactory(
191 RuntimeClass_Windows_UI_Notifications_ToastNotification,
192 toast_notification_factory.GetAddressOf());
193 CheckHR(hr);
195 hr = toast_notification_factory->CreateToastNotification(
196 toast_xml.Get(), &notification_);
197 CheckHR(hr);
199 base::FilePath chrome_path;
200 if (!PathService::Get(base::FILE_EXE, &chrome_path)) {
201 NOTREACHED() << "Failed to get chrome exe path";
202 return;
204 string16 appid = delegate_execute::GetAppId(chrome_path);
205 DVLOG(1) << "Chrome Appid is " << appid.c_str();
207 // TODO(ananta)
208 // We should probably use BrowserDistribution here to get the product name.
209 mswrw::HString app_user_model_id;
210 app_user_model_id.Attach(MakeHString(appid));
212 hr = toast_manager->CreateToastNotifierWithId(app_user_model_id.Get(),
213 &notifier_);
214 CheckHR(hr);
216 hr = notification_->add_Activated(
217 mswr::Callback<ToastActivationHandler>(
218 this, &ToastNotificationHandler::OnActivate).Get(),
219 &activated_token_);
220 CheckHR(hr);
222 hr = notifier_->Show(notification_.Get());
223 CheckHR(hr);
226 void ToastNotificationHandler::CancelNotification() {
227 DVLOG(1) << __FUNCTION__;
229 DCHECK(notifier_);
230 DCHECK(notification_);
232 notifier_->Hide(notification_.Get());
235 HRESULT ToastNotificationHandler::OnActivate(
236 winui::Notifications::IToastNotification* notification,
237 IInspectable* inspectable) {
238 // TODO(ananta)
239 // We should pass back information from the notification like the source url
240 // etc to ChromeAppView which would enable it to ensure that the
241 // correct tab in chrome is activated.
242 DVLOG(1) << __FUNCTION__;
244 if (notification_info_.notification_handler) {
245 notification_info_.notification_handler(
246 notification_info_.notification_context.c_str());
248 return S_OK;