1 // Copyright (c) 2011 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.
5 #include "jingle/notifier/listener/push_notifications_listen_task.h"
7 #include "base/base64.h"
8 #include "base/logging.h"
9 #include "jingle/notifier/listener/notification_constants.h"
10 #include "jingle/notifier/listener/notification_defines.h"
11 #include "jingle/notifier/listener/xml_element_util.h"
12 #include "third_party/webrtc/libjingle/xmllite/qname.h"
13 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h"
14 #include "webrtc/base/task.h"
15 #include "webrtc/libjingle/xmpp/constants.h"
16 #include "webrtc/libjingle/xmpp/xmppclient.h"
17 #include "webrtc/libjingle/xmpp/xmppengine.h"
21 PushNotificationsListenTask::Delegate::~Delegate() {
24 PushNotificationsListenTask::PushNotificationsListenTask(
25 buzz::XmppTaskParentInterface* parent, Delegate* delegate)
26 : buzz::XmppTask(parent, buzz::XmppEngine::HL_TYPE),
31 PushNotificationsListenTask::~PushNotificationsListenTask() {
34 int PushNotificationsListenTask::ProcessStart() {
35 return STATE_RESPONSE;
38 int PushNotificationsListenTask::ProcessResponse() {
39 const buzz::XmlElement* stanza = NextStanza();
44 DVLOG(1) << "Received stanza " << XmlElementToString(*stanza);
46 // The push notifications service does not need us to acknowledge receipt of
47 // the notification to the buzz server.
49 // TODO(sanjeevr): Write unittests to cover this.
50 // Extract the service URL and service-specific data from the stanza.
51 // Note that we treat the channel name as service URL.
52 // The response stanza has the following format.
53 // <message from="{url or bare jid}" to={full jid}>
54 // <push xmlns="google:push" channel={channel name}>
55 // <recipient to={bare jid}>{base-64 encoded data}</recipient>
56 // <data>{base-64 encoded data}</data>
60 const buzz::QName kQnPush(kPushNotificationsNamespace, "push");
61 const buzz::QName kQnChannel(buzz::STR_EMPTY, "channel");
62 const buzz::QName kQnData(kPushNotificationsNamespace, "data");
64 const buzz::XmlElement* push_element = stanza->FirstNamed(kQnPush);
66 Notification notification;
67 notification.channel = push_element->Attr(kQnChannel);
68 const buzz::XmlElement* data_element = push_element->FirstNamed(kQnData);
70 const std::string& base64_encoded_data = data_element->BodyText();
71 if (!base::Base64Decode(base64_encoded_data, ¬ification.data)) {
72 LOG(WARNING) << "Could not base64-decode " << base64_encoded_data;
75 LOG(WARNING) << "No data element found in push element "
76 << XmlElementToString(*push_element);
78 DVLOG(1) << "Received notification " << notification.ToString();
79 delegate_->OnNotificationReceived(notification);
81 LOG(WARNING) << "No push element found in stanza "
82 << XmlElementToString(*stanza);
84 return STATE_RESPONSE;
87 bool PushNotificationsListenTask::HandleStanza(const buzz::XmlElement* stanza) {
88 if (IsValidNotification(stanza)) {
95 bool PushNotificationsListenTask::IsValidNotification(
96 const buzz::XmlElement* stanza) {
97 // We don't do much validation here, just check if the stanza is a message
99 return (stanza->Name() == buzz::QN_MESSAGE);
102 } // namespace notifier