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