| // 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 |