15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "jingle/notifier/listener/push_notifications_subscribe_task.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "jingle/notifier/listener/notification_constants.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "jingle/notifier/listener/xml_element_util.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "talk/xmpp/constants.h"
145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "talk/xmpp/xmppclient.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "talk/xmpp/xmppengine.h"
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "third_party/webrtc/libjingle/xmllite/qname.h"
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "third_party/webrtc/libjingle/xmllite/xmlelement.h"
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "webrtc/base/task.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace notifier {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PushNotificationsSubscribeTask::PushNotificationsSubscribeTask(
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buzz::XmppTaskParentInterface* parent,
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SubscriptionList& subscriptions,
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Delegate* delegate)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : XmppTask(parent, buzz::XmppEngine::HL_SINGLE),
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      subscriptions_(subscriptions), delegate_(delegate) {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PushNotificationsSubscribeTask::~PushNotificationsSubscribeTask() {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PushNotificationsSubscribeTask::HandleStanza(
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const buzz::XmlElement* stanza) {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!MatchResponseIq(stanza, GetClient()->jid().BareJid(), task_id()))
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueueStanza(stanza);
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int PushNotificationsSubscribeTask::ProcessStart() {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "Push notifications: Subscription task started.";
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<buzz::XmlElement> iq_stanza(
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MakeSubscriptionMessage(subscriptions_, GetClient()->jid(),
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              task_id()));
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "Push notifications: Subscription stanza: "
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          << XmlElementToString(*iq_stanza.get());
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (SendStanza(iq_stanza.get()) != buzz::XMPP_RETURN_OK) {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (delegate_)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_->OnSubscriptionError();
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return STATE_ERROR;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return STATE_RESPONSE;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int PushNotificationsSubscribeTask::ProcessResponse() {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "Push notifications: Subscription response received.";
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const buzz::XmlElement* stanza = NextStanza();
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (stanza == NULL) {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return STATE_BLOCKED;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "Push notifications: Subscription response: "
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           << XmlElementToString(*stanza);
653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // We've received a response to our subscription request.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (stanza->HasAttr(buzz::QN_TYPE) &&
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    stanza->Attr(buzz::QN_TYPE) == buzz::STR_RESULT) {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (delegate_)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_->OnSubscribed();
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return STATE_DONE;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // An error response was received.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnSubscriptionError();
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return STATE_ERROR;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)buzz::XmlElement* PushNotificationsSubscribeTask::MakeSubscriptionMessage(
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SubscriptionList& subscriptions,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const buzz::Jid& jid, const std::string& task_id) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(jid.IsFull());
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const buzz::QName kQnSubscribe(
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kPushNotificationsNamespace, "subscribe");
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create the subscription stanza using the notifications protocol.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // <iq from={full_jid} to={bare_jid} type="set" id={id}>
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  <subscribe xmlns="google:push">
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    <item channel={channel_name} from={domain_name or bare_jid}/>
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    <item channel={channel_name2} from={domain_name or bare_jid}/>
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    <item channel={channel_name3} from={domain_name or bare_jid}/>
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  </subscribe>
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // </iq>
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  buzz::XmlElement* iq = MakeIq(buzz::STR_SET, jid.BareJid(), task_id);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  buzz::XmlElement* subscribe = new buzz::XmlElement(kQnSubscribe, true);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iq->AddElement(subscribe);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (SubscriptionList::const_iterator iter =
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           subscriptions.begin(); iter != subscriptions.end(); ++iter) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buzz::XmlElement* item = new buzz::XmlElement(
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        buzz::QName(kPushNotificationsNamespace, "item"));
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    item->AddAttr(buzz::QName(buzz::STR_EMPTY, "channel"),
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  iter->channel.c_str());
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    item->AddAttr(buzz::QN_FROM, iter->from.c_str());
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    subscribe->AddElement(item);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return iq;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace notifier
110