146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "components/invalidation/push_client_channel.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "components/invalidation/notifier_reason_util.h" 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "google/cacheinvalidation/client_gateway.pb.h" 10010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "google/cacheinvalidation/types.pb.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "jingle/notifier/listener/push_client.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace syncer { 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kBotJid[] = "tango@bot.talk.google.com"; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kChannelName[] = "tango_raw"; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PushClientChannel::PushClientChannel( 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<notifier::PushClient> push_client) 2423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) : push_client_(push_client.Pass()), 2523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scheduling_hash_(0), 2623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) sent_messages_count_(0) { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) push_client_->AddObserver(this); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notifier::Subscription subscription; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) subscription.channel = kChannelName; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) subscription.from = ""; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notifier::SubscriptionList subscriptions; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) subscriptions.push_back(subscription); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) push_client_->UpdateSubscriptions(subscriptions); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PushClientChannel::~PushClientChannel() { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) push_client_->RemoveObserver(this); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PushClientChannel::UpdateCredentials( 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& email, const std::string& token) { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) push_client_->UpdateCredentials(email, token); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)int PushClientChannel::GetInvalidationClientType() { 46010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#if defined(OS_IOS) 47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return ipc::invalidation::ClientType::CHROME_SYNC_IOS; 48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#else 49010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return ipc::invalidation::ClientType::CHROME_SYNC; 50010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#endif 51010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 52010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 5323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void PushClientChannel::RequestDetailedStatus( 5423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Callback<void(const base::DictionaryValue&)> callback) { 5523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) callback.Run(*CollectDebugData()); 5623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 5723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void PushClientChannel::SendMessage(const std::string& message) { 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string encoded_message; 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EncodeMessage(&encoded_message, message, service_context_, scheduling_hash_); 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) notifier::Recipient recipient; 63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) recipient.to = kBotJid; 64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) notifier::Notification notification; 65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) notification.channel = kChannelName; 66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) notification.recipients.push_back(recipient); 67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) notification.data = encoded_message; 68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) push_client_->SendNotification(notification); 6923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) sent_messages_count_++; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PushClientChannel::OnNotificationsEnabled() { 736d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) NotifyNetworkStatusChange(true); 746d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) NotifyChannelStateChange(INVALIDATIONS_ENABLED); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PushClientChannel::OnNotificationsDisabled( 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notifier::NotificationsDisabledReason reason) { 796d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) NotifyNetworkStatusChange(false); 806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) NotifyChannelStateChange(FromNotifierReason(reason)); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PushClientChannel::OnIncomingNotification( 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const notifier::Notification& notification) { 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string message; 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string service_context; 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int64 scheduling_hash; 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!DecodeMessage( 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) notification.data, &message, &service_context, &scheduling_hash)) { 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DLOG(ERROR) << "Could not parse ClientGatewayMessage"; 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (DeliverIncomingMessage(message)) { 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) service_context_ = service_context; 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scheduling_hash_ = scheduling_hash; 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const std::string& PushClientChannel::GetServiceContextForTest() const { 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return service_context_; 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)int64 PushClientChannel::GetSchedulingHashForTest() const { 104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return scheduling_hash_; 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)std::string PushClientChannel::EncodeMessageForTest( 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& message, 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& service_context, 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int64 scheduling_hash) { 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string encoded_message; 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EncodeMessage(&encoded_message, message, service_context, scheduling_hash); 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return encoded_message; 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool PushClientChannel::DecodeMessageForTest(const std::string& data, 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string* message, 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string* service_context, 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int64* scheduling_hash) { 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return DecodeMessage(data, message, service_context, scheduling_hash); 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void PushClientChannel::EncodeMessage(std::string* encoded_message, 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& message, 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& service_context, 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int64 scheduling_hash) { 127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ipc::invalidation::ClientGatewayMessage envelope; 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) envelope.set_is_client_to_server(true); 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!service_context.empty()) { 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) envelope.set_service_context(service_context); 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) envelope.set_rpc_scheduling_hash(scheduling_hash); 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) envelope.set_network_message(message); 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) envelope.SerializeToString(encoded_message); 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool PushClientChannel::DecodeMessage(const std::string& data, 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string* message, 139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string* service_context, 140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int64* scheduling_hash) { 141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ipc::invalidation::ClientGatewayMessage envelope; 142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!envelope.ParseFromString(data)) { 143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *message = envelope.network_message(); 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (envelope.has_service_context()) { 147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *service_context = envelope.service_context(); 148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (envelope.has_rpc_scheduling_hash()) { 150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *scheduling_hash = envelope.rpc_scheduling_hash(); 151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)scoped_ptr<base::DictionaryValue> PushClientChannel::CollectDebugData() const { 15623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_ptr<base::DictionaryValue> status(new base::DictionaryValue); 15723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) status->SetString("PushClientChannel.NetworkChannel", "Push Client"); 15823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) status->SetInteger("PushClientChannel.SentMessages", sent_messages_count_); 15923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) status->SetInteger("PushClientChannel.ReceivedMessages", 16023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) SyncNetworkChannel::GetReceivedMessagesCount()); 16123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return status.Pass(); 16223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 16323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace syncer 165