| // Copyright 2018 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/notifications/win/notification_util.h" |
| |
| #include <wrl/client.h> |
| |
| #include "base/logging.h" |
| #include "base/win/scoped_hstring.h" |
| #include "chrome/browser/notifications/win/notification_launch_id.h" |
| #include "chrome/browser/notifications/win/notification_metrics.h" |
| #include "chrome/browser/notifications/win/notification_template_builder.h" |
| |
| namespace mswr = Microsoft::WRL; |
| namespace winfoundtn = ABI::Windows::Foundation; |
| namespace winui = ABI::Windows::UI; |
| namespace winxml = ABI::Windows::Data::Xml; |
| |
| using notifications_uma::GetNotificationLaunchIdStatus; |
| using base::win::ScopedHString; |
| |
| NotificationLaunchId GetNotificationLaunchId( |
| winui::Notifications::IToastNotification* notification) { |
| mswr::ComPtr<winxml::Dom::IXmlDocument> document; |
| HRESULT hr = notification->get_Content(&document); |
| if (FAILED(hr)) { |
| LogGetNotificationLaunchIdStatus( |
| GetNotificationLaunchIdStatus::kNotificationGetContentFailed); |
| DLOG(ERROR) << "Failed to get XML document"; |
| return NotificationLaunchId(); |
| } |
| |
| ScopedHString tag = ScopedHString::Create(kNotificationToastElement); |
| mswr::ComPtr<winxml::Dom::IXmlNodeList> elements; |
| hr = document->GetElementsByTagName(tag.get(), &elements); |
| if (FAILED(hr)) { |
| LogGetNotificationLaunchIdStatus( |
| GetNotificationLaunchIdStatus::kGetElementsByTagFailed); |
| DLOG(ERROR) << "Failed to get <toast> elements from document"; |
| return NotificationLaunchId(); |
| } |
| |
| UINT32 length; |
| hr = elements->get_Length(&length); |
| if (FAILED(hr) || length == 0) { |
| LogGetNotificationLaunchIdStatus( |
| GetNotificationLaunchIdStatus::kMissingToastElementInDoc); |
| DLOG(ERROR) << "No <toast> elements in document."; |
| return NotificationLaunchId(); |
| } |
| |
| mswr::ComPtr<winxml::Dom::IXmlNode> node; |
| hr = elements->Item(0, &node); |
| if (FAILED(hr)) { |
| LogGetNotificationLaunchIdStatus( |
| GetNotificationLaunchIdStatus::kItemAtFailed); |
| DLOG(ERROR) << "Failed to get first <toast> element"; |
| return NotificationLaunchId(); |
| } |
| |
| mswr::ComPtr<winxml::Dom::IXmlNamedNodeMap> attributes; |
| hr = node->get_Attributes(&attributes); |
| if (FAILED(hr)) { |
| LogGetNotificationLaunchIdStatus( |
| GetNotificationLaunchIdStatus::kGetAttributesFailed); |
| DLOG(ERROR) << "Failed to get attributes of <toast>"; |
| return NotificationLaunchId(); |
| } |
| |
| mswr::ComPtr<winxml::Dom::IXmlNode> leaf; |
| ScopedHString id = ScopedHString::Create(kNotificationLaunchAttribute); |
| hr = attributes->GetNamedItem(id.get(), &leaf); |
| if (FAILED(hr)) { |
| LogGetNotificationLaunchIdStatus( |
| GetNotificationLaunchIdStatus::kGetNamedItemFailed); |
| DLOG(ERROR) << "Failed to get launch attribute of <toast>"; |
| return NotificationLaunchId(); |
| } |
| |
| if (!leaf) { |
| LogGetNotificationLaunchIdStatus( |
| GetNotificationLaunchIdStatus::kGetNamedItemNull); |
| DLOG(ERROR) << "GetNamedItem returned null querying for 'launch' attribute"; |
| return NotificationLaunchId(); |
| } |
| |
| mswr::ComPtr<winxml::Dom::IXmlNode> child; |
| hr = leaf->get_FirstChild(&child); |
| if (FAILED(hr)) { |
| LogGetNotificationLaunchIdStatus( |
| GetNotificationLaunchIdStatus::kGetFirstChildFailed); |
| DLOG(ERROR) << "Failed to get content of launch attribute"; |
| return NotificationLaunchId(); |
| } |
| |
| if (!child) { |
| LogGetNotificationLaunchIdStatus( |
| GetNotificationLaunchIdStatus::kGetFirstChildNull); |
| DLOG(ERROR) << "Launch attribute is a null node"; |
| return NotificationLaunchId(); |
| } |
| |
| mswr::ComPtr<IInspectable> inspectable; |
| hr = child->get_NodeValue(&inspectable); |
| if (FAILED(hr)) { |
| LogGetNotificationLaunchIdStatus( |
| GetNotificationLaunchIdStatus::kGetNodeValueFailed); |
| DLOG(ERROR) << "Failed to get node value of launch attribute"; |
| return NotificationLaunchId(); |
| } |
| |
| mswr::ComPtr<winfoundtn::IPropertyValue> property_value; |
| hr = inspectable.As<winfoundtn::IPropertyValue>(&property_value); |
| if (FAILED(hr)) { |
| LogGetNotificationLaunchIdStatus( |
| GetNotificationLaunchIdStatus::kConversionToPropValueFailed); |
| DLOG(ERROR) << "Failed to convert node value of launch attribute"; |
| return NotificationLaunchId(); |
| } |
| |
| HSTRING value_hstring; |
| hr = property_value->GetString(&value_hstring); |
| if (FAILED(hr)) { |
| LogGetNotificationLaunchIdStatus( |
| GetNotificationLaunchIdStatus::kGetStringFailed); |
| DLOG(ERROR) << "Failed to get string for launch attribute"; |
| return NotificationLaunchId(); |
| } |
| |
| LogGetNotificationLaunchIdStatus(GetNotificationLaunchIdStatus::kSuccess); |
| |
| ScopedHString value(value_hstring); |
| return NotificationLaunchId(value.GetAsUTF8()); |
| } |