diff options
Diffstat (limited to 'sync/notifier/push_client_channel.cc')
-rw-r--r-- | sync/notifier/push_client_channel.cc | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/sync/notifier/push_client_channel.cc b/sync/notifier/push_client_channel.cc new file mode 100644 index 0000000..cfd3129 --- /dev/null +++ b/sync/notifier/push_client_channel.cc @@ -0,0 +1,151 @@ +// 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 "sync/notifier/push_client_channel.h" + +#include "base/stl_util.h" +#include "google/cacheinvalidation/v2/client_gateway.pb.h" +#include "jingle/notifier/listener/push_client.h" + +namespace sync_notifier { + +namespace { + +const char kBotJid[] = "tango@bot.talk.google.com"; +const char kChannelName[] = "tango_raw"; + +} // namespace + +PushClientChannel::PushClientChannel( + scoped_ptr<notifier::PushClient> push_client) + : push_client_(push_client.Pass()), + notifications_enabled_(false), + scheduling_hash_(0) { + push_client_->AddObserver(this); + notifier::Subscription subscription; + subscription.channel = kChannelName; + subscription.from = ""; + notifier::SubscriptionList subscriptions; + subscriptions.push_back(subscription); + push_client_->UpdateSubscriptions(subscriptions); +} + +PushClientChannel::~PushClientChannel() { + push_client_->RemoveObserver(this); + STLDeleteElements(&network_status_receivers_); +} + +void PushClientChannel::UpdateCredentials( + const std::string& email, const std::string& token) { + push_client_->UpdateCredentials(email, token); +} + +void PushClientChannel::SendMessage(const std::string& outgoing_message) { + push_client_->SendNotification( + EncodeMessage(outgoing_message, service_context_, scheduling_hash_)); +} + +void PushClientChannel::SetMessageReceiver( + invalidation::MessageCallback* incoming_receiver) { + incoming_receiver_.reset(incoming_receiver); +} + +void PushClientChannel::AddNetworkStatusReceiver( + invalidation::NetworkStatusCallback* network_status_receiver) { + network_status_receiver->Run(notifications_enabled_); + network_status_receivers_.push_back(network_status_receiver); +} + +void PushClientChannel::SetSystemResources( + invalidation::SystemResources* resources) { + // Do nothing. +} + +void PushClientChannel::OnNotificationStateChange( + bool notifications_enabled) { + for (NetworkStatusReceiverList::const_iterator it = + network_status_receivers_.begin(); + it != network_status_receivers_.end(); ++it) { + (*it)->Run(notifications_enabled); + } +} + +void PushClientChannel::OnIncomingNotification( + const notifier::Notification& notification) { + if (!incoming_receiver_.get()) { + DLOG(ERROR) << "No receiver for incoming notification"; + return; + } + std::string message; + if (!DecodeMessage(notification, + &message, &service_context_, &scheduling_hash_)) { + DLOG(ERROR) << "Could not parse ClientGatewayMessage from: " + << notification.ToString(); + } + incoming_receiver_->Run(message); +} + +const std::string& PushClientChannel::GetServiceContextForTest() const { + return service_context_; +} + +int64 PushClientChannel::GetSchedulingHashForTest() const { + return scheduling_hash_; +} + +notifier::Notification PushClientChannel::EncodeMessageForTest( + const std::string& message, const std::string& service_context, + int64 scheduling_hash) { + return EncodeMessage(message, service_context, scheduling_hash); +} + +bool PushClientChannel::DecodeMessageForTest( + const notifier::Notification& notification, + std::string* message, + std::string* service_context, + int64* scheduling_hash) { + return DecodeMessage( + notification, message, service_context, scheduling_hash); +} + +notifier::Notification PushClientChannel::EncodeMessage( + const std::string& message, const std::string& service_context, + int64 scheduling_hash) { + ipc::invalidation::ClientGatewayMessage envelope; + envelope.set_is_client_to_server(true); + if (!service_context.empty()) { + envelope.set_service_context(service_context); + envelope.set_rpc_scheduling_hash(scheduling_hash); + } + envelope.set_network_message(message); + + notifier::Recipient recipient; + recipient.to = kBotJid; + notifier::Notification notification; + notification.channel = kChannelName; + notification.recipients.push_back(recipient); + envelope.SerializeToString(¬ification.data); + return notification; +} + +bool PushClientChannel::DecodeMessage( + const notifier::Notification& notification, + std::string* message, + std::string* service_context, + int64* scheduling_hash) { + ipc::invalidation::ClientGatewayMessage envelope; + if (!envelope.ParseFromString(notification.data)) { + return false; + } + *message = envelope.network_message(); + if (envelope.has_service_context()) { + *service_context = envelope.service_context(); + } + if (envelope.has_rpc_scheduling_hash()) { + *scheduling_hash = envelope.rpc_scheduling_hash(); + } + return true; +} + +} // namespace sync_notifier |