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_subscribe_task.h"
      6 
      7 #include <string>
      8 
      9 #include "base/logging.h"
     10 #include "base/memory/scoped_ptr.h"
     11 #include "jingle/notifier/listener/notification_constants.h"
     12 #include "jingle/notifier/listener/xml_element_util.h"
     13 #include "talk/base/task.h"
     14 #include "talk/xmllite/qname.h"
     15 #include "talk/xmllite/xmlelement.h"
     16 #include "talk/xmpp/xmppclient.h"
     17 #include "talk/xmpp/constants.h"
     18 #include "talk/xmpp/xmppengine.h"
     19 
     20 namespace notifier {
     21 
     22 PushNotificationsSubscribeTask::PushNotificationsSubscribeTask(
     23     buzz::XmppTaskParentInterface* parent,
     24     const SubscriptionList& subscriptions,
     25     Delegate* delegate)
     26     : XmppTask(parent, buzz::XmppEngine::HL_SINGLE),
     27       subscriptions_(subscriptions), delegate_(delegate) {
     28 }
     29 
     30 PushNotificationsSubscribeTask::~PushNotificationsSubscribeTask() {
     31 }
     32 
     33 bool PushNotificationsSubscribeTask::HandleStanza(
     34     const buzz::XmlElement* stanza) {
     35   if (!MatchResponseIq(stanza, GetClient()->jid().BareJid(), task_id()))
     36     return false;
     37   QueueStanza(stanza);
     38   return true;
     39 }
     40 
     41 int PushNotificationsSubscribeTask::ProcessStart() {
     42   DVLOG(1) << "Push notifications: Subscription task started.";
     43   scoped_ptr<buzz::XmlElement> iq_stanza(
     44       MakeSubscriptionMessage(subscriptions_, GetClient()->jid(),
     45                               task_id()));
     46   std::string stanza_str = XmlElementToString(*iq_stanza.get());
     47   DVLOG(1) << "Push notifications: Subscription stanza: "
     48           << XmlElementToString(*iq_stanza.get());
     49 
     50   if (SendStanza(iq_stanza.get()) != buzz::XMPP_RETURN_OK) {
     51     if (delegate_)
     52       delegate_->OnSubscriptionError();
     53     return STATE_ERROR;
     54   }
     55   return STATE_RESPONSE;
     56 }
     57 
     58 int PushNotificationsSubscribeTask::ProcessResponse() {
     59   DVLOG(1) << "Push notifications: Subscription response received.";
     60   const buzz::XmlElement* stanza = NextStanza();
     61   if (stanza == NULL) {
     62     return STATE_BLOCKED;
     63   }
     64   std::string stanza_str = XmlElementToString(*stanza);
     65   DVLOG(1) << "Push notifications: Subscription response: "
     66            << XmlElementToString(*stanza);
     67   // We've receieved a response to our subscription request.
     68   if (stanza->HasAttr(buzz::QN_TYPE) &&
     69     stanza->Attr(buzz::QN_TYPE) == buzz::STR_RESULT) {
     70     if (delegate_)
     71       delegate_->OnSubscribed();
     72     return STATE_DONE;
     73   }
     74   // An error response was received.
     75   if (delegate_)
     76     delegate_->OnSubscriptionError();
     77   return STATE_ERROR;
     78 }
     79 
     80 buzz::XmlElement* PushNotificationsSubscribeTask::MakeSubscriptionMessage(
     81     const SubscriptionList& subscriptions,
     82     const buzz::Jid& jid, const std::string& task_id) {
     83   DCHECK(jid.IsFull());
     84   const buzz::QName kQnSubscribe(
     85       kPushNotificationsNamespace, "subscribe");
     86 
     87   // Create the subscription stanza using the notifications protocol.
     88   // <iq from={full_jid} to={bare_jid} type="set" id={id}>
     89   //  <subscribe xmlns="google:push">
     90   //    <item channel={channel_name} from={domain_name or bare_jid}/>
     91   //    <item channel={channel_name2} from={domain_name or bare_jid}/>
     92   //    <item channel={channel_name3} from={domain_name or bare_jid}/>
     93   //  </subscribe>
     94   // </iq>
     95   buzz::XmlElement* iq = MakeIq(buzz::STR_SET, jid.BareJid(), task_id);
     96   buzz::XmlElement* subscribe = new buzz::XmlElement(kQnSubscribe, true);
     97   iq->AddElement(subscribe);
     98 
     99   for (SubscriptionList::const_iterator iter =
    100            subscriptions.begin(); iter != subscriptions.end(); ++iter) {
    101     buzz::XmlElement* item = new buzz::XmlElement(
    102         buzz::QName(kPushNotificationsNamespace, "item"));
    103     item->AddAttr(buzz::QName(buzz::STR_EMPTY, "channel"),
    104                   iter->channel.c_str());
    105     item->AddAttr(buzz::QN_FROM, iter->from.c_str());
    106     subscribe->AddElement(item);
    107   }
    108   return iq;
    109 }
    110 
    111 }  // namespace notifier
    112