blob: 4083e23d417c8080de2204fe32e93176af3e1b8e [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "jingle/notifier/listener/xmpp_push_client.h"
#include "base/logging.h"
#include "jingle/notifier/base/notifier_options_util.h"
#include "jingle/notifier/listener/push_client_observer.h"
#include "jingle/notifier/listener/send_ping_task.h"
#include "jingle/notifier/listener/push_notifications_send_update_task.h"
namespace notifier {
XmppPushClient::XmppPushClient(const NotifierOptions& notifier_options)
: notifier_options_(notifier_options) {
DCHECK(notifier_options_.request_context_getter->
GetNetworkTaskRunner()->BelongsToCurrentThread());
}
XmppPushClient::~XmppPushClient() {
DCHECK(thread_checker_.CalledOnValidThread());
}
void XmppPushClient::OnConnect(
base::WeakPtr<buzz::XmppTaskParentInterface> base_task) {
DCHECK(thread_checker_.CalledOnValidThread());
base_task_ = base_task;
if (!base_task_.get()) {
NOTREACHED();
return;
}
// Listen for notifications.
{
// Owned by |base_task_|.
PushNotificationsListenTask* listener =
new PushNotificationsListenTask(base_task_.get(), this);
listener->Start();
}
// Send subscriptions.
{
// Owned by |base_task_|.
PushNotificationsSubscribeTask* subscribe_task =
new PushNotificationsSubscribeTask(
base_task_.get(), subscriptions_, this);
subscribe_task->Start();
}
std::vector<Notification> notifications_to_send;
notifications_to_send.swap(pending_notifications_to_send_);
for (std::vector<Notification>::const_iterator it =
notifications_to_send.begin();
it != notifications_to_send.end(); ++it) {
DVLOG(1) << "Push: Sending pending notification " << it->ToString();
SendNotification(*it);
}
}
void XmppPushClient::OnTransientDisconnection() {
DCHECK(thread_checker_.CalledOnValidThread());
DVLOG(1) << "Push: Transient disconnection";
base_task_.reset();
FOR_EACH_OBSERVER(PushClientObserver, observers_,
OnNotificationsDisabled(TRANSIENT_NOTIFICATION_ERROR));
}
void XmppPushClient::OnCredentialsRejected() {
DCHECK(thread_checker_.CalledOnValidThread());
DVLOG(1) << "Push: Credentials rejected";
base_task_.reset();
FOR_EACH_OBSERVER(
PushClientObserver, observers_,
OnNotificationsDisabled(NOTIFICATION_CREDENTIALS_REJECTED));
}
void XmppPushClient::OnNotificationReceived(
const Notification& notification) {
DCHECK(thread_checker_.CalledOnValidThread());
FOR_EACH_OBSERVER(PushClientObserver, observers_,
OnIncomingNotification(notification));
}
void XmppPushClient::OnPingResponseReceived() {
DCHECK(thread_checker_.CalledOnValidThread());
FOR_EACH_OBSERVER(PushClientObserver, observers_, OnPingResponse());
}
void XmppPushClient::OnSubscribed() {
DCHECK(thread_checker_.CalledOnValidThread());
FOR_EACH_OBSERVER(PushClientObserver, observers_,
OnNotificationsEnabled());
}
void XmppPushClient::OnSubscriptionError() {
DCHECK(thread_checker_.CalledOnValidThread());
FOR_EACH_OBSERVER(PushClientObserver, observers_,
OnNotificationsDisabled(TRANSIENT_NOTIFICATION_ERROR));
}
void XmppPushClient::AddObserver(PushClientObserver* observer) {
DCHECK(thread_checker_.CalledOnValidThread());
observers_.AddObserver(observer);
}
void XmppPushClient::RemoveObserver(PushClientObserver* observer) {
DCHECK(thread_checker_.CalledOnValidThread());
observers_.RemoveObserver(observer);
}
void XmppPushClient::UpdateSubscriptions(
const SubscriptionList& subscriptions) {
DCHECK(thread_checker_.CalledOnValidThread());
subscriptions_ = subscriptions;
}
void XmppPushClient::UpdateCredentials(
const std::string& email, const std::string& token) {
DCHECK(thread_checker_.CalledOnValidThread());
DVLOG(1) << "Push: Updating credentials for " << email;
xmpp_settings_ = MakeXmppClientSettings(notifier_options_, email, token);
if (login_.get()) {
login_->UpdateXmppSettings(xmpp_settings_);
} else {
DVLOG(1) << "Push: Starting XMPP connection";
base_task_.reset();
login_.reset(new notifier::Login(this,
xmpp_settings_,
notifier_options_.request_context_getter,
GetServerList(notifier_options_),
notifier_options_.try_ssltcp_first,
notifier_options_.auth_mechanism));
login_->StartConnection();
}
}
void XmppPushClient::SendNotification(const Notification& notification) {
DCHECK(thread_checker_.CalledOnValidThread());
if (!base_task_.get()) {
// TODO(akalin): Figure out whether we really need to do this.
DVLOG(1) << "Push: Cannot send notification "
<< notification.ToString() << "; sending later";
pending_notifications_to_send_.push_back(notification);
return;
}
// Owned by |base_task_|.
PushNotificationsSendUpdateTask* task =
new PushNotificationsSendUpdateTask(base_task_.get(), notification);
task->Start();
}
void XmppPushClient::SendPing() {
DCHECK(thread_checker_.CalledOnValidThread());
if (!base_task_.get()) {
DVLOG(1) << "Push: Cannot send ping";
return;
}
// Owned by |base_task_|.
SendPingTask* task = new SendPingTask(base_task_.get(), this);
task->Start();
}
} // namespace notifier