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. 4 5 #include "jingle/notifier/listener/push_notifications_send_update_task.h" 6 7 #include <string> 8 9 #include "base/base64.h" 10 #include "base/logging.h" 11 #include "base/memory/scoped_ptr.h" 12 #include "jingle/notifier/listener/notification_constants.h" 13 #include "jingle/notifier/listener/xml_element_util.h" 14 #include "talk/xmllite/qname.h" 15 #include "talk/xmllite/xmlelement.h" 16 #include "talk/xmpp/constants.h" 17 #include "talk/xmpp/jid.h" 18 #include "talk/xmpp/xmppclient.h" 19 20 namespace notifier { 21 22 PushNotificationsSendUpdateTask::PushNotificationsSendUpdateTask( 23 buzz::XmppTaskParentInterface* parent, const Notification& notification) 24 : XmppTask(parent), notification_(notification) {} 25 26 PushNotificationsSendUpdateTask::~PushNotificationsSendUpdateTask() {} 27 28 int PushNotificationsSendUpdateTask::ProcessStart() { 29 scoped_ptr<buzz::XmlElement> stanza( 30 MakeUpdateMessage(notification_, 31 GetClient()->jid().BareJid())); 32 DVLOG(1) << "Sending notification " << notification_.ToString() 33 << " as stanza " << XmlElementToString(*stanza); 34 if (SendStanza(stanza.get()) != buzz::XMPP_RETURN_OK) { 35 DLOG(WARNING) << "Could not send stanza " << XmlElementToString(*stanza); 36 } 37 return STATE_DONE; 38 } 39 40 buzz::XmlElement* PushNotificationsSendUpdateTask::MakeUpdateMessage( 41 const Notification& notification, 42 const buzz::Jid& to_jid_bare) { 43 DCHECK(to_jid_bare.IsBare()); 44 const buzz::QName kQnPush(kPushNotificationsNamespace, "push"); 45 const buzz::QName kQnChannel(buzz::STR_EMPTY, "channel"); 46 const buzz::QName kQnData(kPushNotificationsNamespace, "data"); 47 const buzz::QName kQnRecipient(kPushNotificationsNamespace, "recipient"); 48 49 // Create our update stanza. The message is constructed as: 50 // <message from='{full jid}' to='{bare jid}' type='headline'> 51 // <push xmlns='google:push' channel='{channel}'> 52 // [<recipient to='{bare jid}'>{base-64 encoded data}</data>]* 53 // <data>{base-64 encoded data}</data> 54 // </push> 55 // </message> 56 57 buzz::XmlElement* message = new buzz::XmlElement(buzz::QN_MESSAGE); 58 message->AddAttr(buzz::QN_TO, to_jid_bare.Str()); 59 message->AddAttr(buzz::QN_TYPE, "headline"); 60 61 buzz::XmlElement* push = new buzz::XmlElement(kQnPush, true); 62 push->AddAttr(kQnChannel, notification.channel); 63 message->AddElement(push); 64 65 const RecipientList& recipients = notification.recipients; 66 for (size_t i = 0; i < recipients.size(); ++i) { 67 const Recipient& recipient = recipients[i]; 68 buzz::XmlElement* recipient_element = 69 new buzz::XmlElement(kQnRecipient, true); 70 push->AddElement(recipient_element); 71 recipient_element->AddAttr(buzz::QN_TO, recipient.to); 72 if (!recipient.user_specific_data.empty()) { 73 std::string base64_data; 74 if (!base::Base64Encode(recipient.user_specific_data, &base64_data)) { 75 DLOG(WARNING) << "Could not encode data " 76 << recipient.user_specific_data; 77 } else { 78 recipient_element->SetBodyText(base64_data); 79 } 80 } 81 } 82 83 buzz::XmlElement* data = new buzz::XmlElement(kQnData, true); 84 std::string base64_data; 85 if (!base::Base64Encode(notification.data, &base64_data)) { 86 DLOG(WARNING) << "Could not encode data " << notification.data; 87 } 88 data->SetBodyText(base64_data); 89 push->AddElement(data); 90 91 return message; 92 } 93 94 } // namespace notifier 95