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   DVLOG(1) << "Push notifications: Subscription stanza: "
     47           << XmlElementToString(*iq_stanza.get());
     48 
     49   if (SendStanza(iq_stanza.get()) != buzz::XMPP_RETURN_OK) {
     50     if (delegate_)
     51       delegate_->OnSubscriptionError();
     52     return STATE_ERROR;
     53   }
     54   return STATE_RESPONSE;
     55 }
     56 
     57 int PushNotificationsSubscribeTask::ProcessResponse() {
     58   DVLOG(1) << "Push notifications: Subscription response received.";
     59   const buzz::XmlElement* stanza = NextStanza();
     60   if (stanza == NULL) {
     61     return STATE_BLOCKED;
     62   }
     63   DVLOG(1) << "Push notifications: Subscription response: "
     64            << XmlElementToString(*stanza);
     65   // We've received a response to our subscription request.
     66   if (stanza->HasAttr(buzz::QN_TYPE) &&
     67     stanza->Attr(buzz::QN_TYPE) == buzz::STR_RESULT) {
     68     if (delegate_)
     69       delegate_->OnSubscribed();
     70     return STATE_DONE;
     71   }
     72   // An error response was received.
     73   if (delegate_)
     74     delegate_->OnSubscriptionError();
     75   return STATE_ERROR;
     76 }
     77 
     78 buzz::XmlElement* PushNotificationsSubscribeTask::MakeSubscriptionMessage(
     79     const SubscriptionList& subscriptions,
     80     const buzz::Jid& jid, const std::string& task_id) {
     81   DCHECK(jid.IsFull());
     82   const buzz::QName kQnSubscribe(
     83       kPushNotificationsNamespace, "subscribe");
     84 
     85   // Create the subscription stanza using the notifications protocol.
     86   // <iq from={full_jid} to={bare_jid} type="set" id={id}>
     87   //  <subscribe xmlns="google:push">
     88   //    <item channel={channel_name} from={domain_name or bare_jid}/>
     89   //    <item channel={channel_name2} from={domain_name or bare_jid}/>
     90   //    <item channel={channel_name3} from={domain_name or bare_jid}/>
     91   //  </subscribe>
     92   // </iq>
     93   buzz::XmlElement* iq = MakeIq(buzz::STR_SET, jid.BareJid(), task_id);
     94   buzz::XmlElement* subscribe = new buzz::XmlElement(kQnSubscribe, true);
     95   iq->AddElement(subscribe);
     96 
     97   for (SubscriptionList::const_iterator iter =
     98            subscriptions.begin(); iter != subscriptions.end(); ++iter) {
     99     buzz::XmlElement* item = new buzz::XmlElement(
    100         buzz::QName(kPushNotificationsNamespace, "item"));
    101     item->AddAttr(buzz::QName(buzz::STR_EMPTY, "channel"),
    102                   iter->channel.c_str());
    103     item->AddAttr(buzz::QN_FROM, iter->from.c_str());
    104     subscribe->AddElement(item);
    105   }
    106   return iq;
    107 }
    108 
    109 }  // namespace notifier
    110