diff options
Diffstat (limited to 'sync/notifier/push_client_channel.cc')
-rw-r--r-- | sync/notifier/push_client_channel.cc | 161 |
1 files changed, 161 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..0bd07c9 --- /dev/null +++ b/sync/notifier/push_client_channel.cc @@ -0,0 +1,161 @@ +// Copyright 2014 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/client_gateway.pb.h" +#include "google/cacheinvalidation/types.pb.h" +#include "jingle/notifier/listener/push_client.h" + +namespace syncer { + +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()), + scheduling_hash_(0), + sent_messages_count_(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); +} + +void PushClientChannel::UpdateCredentials( + const std::string& email, const std::string& token) { + push_client_->UpdateCredentials(email, token); +} + +int PushClientChannel::GetInvalidationClientType() { +#if defined(OS_IOS) + return ipc::invalidation::ClientType::CHROME_SYNC_IOS; +#else + return ipc::invalidation::ClientType::CHROME_SYNC; +#endif +} + +void PushClientChannel::RequestDetailedStatus( + base::Callback<void(const base::DictionaryValue&)> callback) { + callback.Run(*CollectDebugData()); +} + +void PushClientChannel::SendMessage(const std::string& message) { + std::string encoded_message; + EncodeMessage(&encoded_message, message, service_context_, scheduling_hash_); + + notifier::Recipient recipient; + recipient.to = kBotJid; + notifier::Notification notification; + notification.channel = kChannelName; + notification.recipients.push_back(recipient); + notification.data = encoded_message; + push_client_->SendNotification(notification); + sent_messages_count_++; +} + +void PushClientChannel::OnNotificationsEnabled() { + NotifyStateChange(INVALIDATIONS_ENABLED); +} + +void PushClientChannel::OnNotificationsDisabled( + notifier::NotificationsDisabledReason reason) { + NotifyStateChange(FromNotifierReason(reason)); +} + +void PushClientChannel::OnIncomingNotification( + const notifier::Notification& notification) { + std::string message; + std::string service_context; + int64 scheduling_hash; + if (!DecodeMessage( + notification.data, &message, &service_context, &scheduling_hash)) { + DLOG(ERROR) << "Could not parse ClientGatewayMessage"; + return; + } + if (DeliverIncomingMessage(message)) { + service_context_ = service_context; + scheduling_hash_ = scheduling_hash; + } +} + +const std::string& PushClientChannel::GetServiceContextForTest() const { + return service_context_; +} + +int64 PushClientChannel::GetSchedulingHashForTest() const { + return scheduling_hash_; +} + +std::string PushClientChannel::EncodeMessageForTest( + const std::string& message, + const std::string& service_context, + int64 scheduling_hash) { + std::string encoded_message; + EncodeMessage(&encoded_message, message, service_context, scheduling_hash); + return encoded_message; +} + +bool PushClientChannel::DecodeMessageForTest(const std::string& data, + std::string* message, + std::string* service_context, + int64* scheduling_hash) { + return DecodeMessage(data, message, service_context, scheduling_hash); +} + +void PushClientChannel::EncodeMessage(std::string* encoded_message, + 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); + envelope.SerializeToString(encoded_message); +} + +bool PushClientChannel::DecodeMessage(const std::string& data, + std::string* message, + std::string* service_context, + int64* scheduling_hash) { + ipc::invalidation::ClientGatewayMessage envelope; + if (!envelope.ParseFromString(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; +} + +scoped_ptr<base::DictionaryValue> PushClientChannel::CollectDebugData() const { + scoped_ptr<base::DictionaryValue> status(new base::DictionaryValue); + status->SetString("PushClientChannel.NetworkChannel", "Push Client"); + status->SetInteger("PushClientChannel.SentMessages", sent_messages_count_); + status->SetInteger("PushClientChannel.ReceivedMessages", + SyncNetworkChannel::GetReceivedMessagesCount()); + return status.Pass(); +} + +} // namespace syncer |