Home | History | Annotate | Download | only in listener
      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