• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "components/invalidation/push_client_channel.h"
6 
7 #include "base/stl_util.h"
8 #include "components/invalidation/notifier_reason_util.h"
9 #include "google/cacheinvalidation/client_gateway.pb.h"
10 #include "google/cacheinvalidation/types.pb.h"
11 #include "jingle/notifier/listener/push_client.h"
12 
13 namespace syncer {
14 
15 namespace {
16 
17 const char kBotJid[] = "tango@bot.talk.google.com";
18 const char kChannelName[] = "tango_raw";
19 
20 }  // namespace
21 
PushClientChannel(scoped_ptr<notifier::PushClient> push_client)22 PushClientChannel::PushClientChannel(
23     scoped_ptr<notifier::PushClient> push_client)
24     : push_client_(push_client.Pass()),
25       scheduling_hash_(0),
26       sent_messages_count_(0) {
27   push_client_->AddObserver(this);
28   notifier::Subscription subscription;
29   subscription.channel = kChannelName;
30   subscription.from = "";
31   notifier::SubscriptionList subscriptions;
32   subscriptions.push_back(subscription);
33   push_client_->UpdateSubscriptions(subscriptions);
34 }
35 
~PushClientChannel()36 PushClientChannel::~PushClientChannel() {
37   push_client_->RemoveObserver(this);
38 }
39 
UpdateCredentials(const std::string & email,const std::string & token)40 void PushClientChannel::UpdateCredentials(
41     const std::string& email, const std::string& token) {
42   push_client_->UpdateCredentials(email, token);
43 }
44 
GetInvalidationClientType()45 int PushClientChannel::GetInvalidationClientType() {
46 #if defined(OS_IOS)
47   return ipc::invalidation::ClientType::CHROME_SYNC_IOS;
48 #else
49   return ipc::invalidation::ClientType::CHROME_SYNC;
50 #endif
51 }
52 
RequestDetailedStatus(base::Callback<void (const base::DictionaryValue &)> callback)53 void PushClientChannel::RequestDetailedStatus(
54     base::Callback<void(const base::DictionaryValue&)> callback) {
55   callback.Run(*CollectDebugData());
56 }
57 
SendMessage(const std::string & message)58 void PushClientChannel::SendMessage(const std::string& message) {
59   std::string encoded_message;
60   EncodeMessage(&encoded_message, message, service_context_, scheduling_hash_);
61 
62   notifier::Recipient recipient;
63   recipient.to = kBotJid;
64   notifier::Notification notification;
65   notification.channel = kChannelName;
66   notification.recipients.push_back(recipient);
67   notification.data = encoded_message;
68   push_client_->SendNotification(notification);
69   sent_messages_count_++;
70 }
71 
OnNotificationsEnabled()72 void PushClientChannel::OnNotificationsEnabled() {
73   NotifyNetworkStatusChange(true);
74   NotifyChannelStateChange(INVALIDATIONS_ENABLED);
75 }
76 
OnNotificationsDisabled(notifier::NotificationsDisabledReason reason)77 void PushClientChannel::OnNotificationsDisabled(
78     notifier::NotificationsDisabledReason reason) {
79   NotifyNetworkStatusChange(false);
80   NotifyChannelStateChange(FromNotifierReason(reason));
81 }
82 
OnIncomingNotification(const notifier::Notification & notification)83 void PushClientChannel::OnIncomingNotification(
84     const notifier::Notification& notification) {
85   std::string message;
86   std::string service_context;
87   int64 scheduling_hash;
88   if (!DecodeMessage(
89            notification.data, &message, &service_context, &scheduling_hash)) {
90     DLOG(ERROR) << "Could not parse ClientGatewayMessage";
91     return;
92   }
93   if (DeliverIncomingMessage(message)) {
94     service_context_ = service_context;
95     scheduling_hash_ = scheduling_hash;
96   }
97 }
98 
GetServiceContextForTest() const99 const std::string& PushClientChannel::GetServiceContextForTest() const {
100   return service_context_;
101 }
102 
GetSchedulingHashForTest() const103 int64 PushClientChannel::GetSchedulingHashForTest() const {
104   return scheduling_hash_;
105 }
106 
EncodeMessageForTest(const std::string & message,const std::string & service_context,int64 scheduling_hash)107 std::string PushClientChannel::EncodeMessageForTest(
108     const std::string& message,
109     const std::string& service_context,
110     int64 scheduling_hash) {
111   std::string encoded_message;
112   EncodeMessage(&encoded_message, message, service_context, scheduling_hash);
113   return encoded_message;
114 }
115 
DecodeMessageForTest(const std::string & data,std::string * message,std::string * service_context,int64 * scheduling_hash)116 bool PushClientChannel::DecodeMessageForTest(const std::string& data,
117                                              std::string* message,
118                                              std::string* service_context,
119                                              int64* scheduling_hash) {
120   return DecodeMessage(data, message, service_context, scheduling_hash);
121 }
122 
EncodeMessage(std::string * encoded_message,const std::string & message,const std::string & service_context,int64 scheduling_hash)123 void PushClientChannel::EncodeMessage(std::string* encoded_message,
124                                       const std::string& message,
125                                       const std::string& service_context,
126                                       int64 scheduling_hash) {
127   ipc::invalidation::ClientGatewayMessage envelope;
128   envelope.set_is_client_to_server(true);
129   if (!service_context.empty()) {
130     envelope.set_service_context(service_context);
131     envelope.set_rpc_scheduling_hash(scheduling_hash);
132   }
133   envelope.set_network_message(message);
134   envelope.SerializeToString(encoded_message);
135 }
136 
DecodeMessage(const std::string & data,std::string * message,std::string * service_context,int64 * scheduling_hash)137 bool PushClientChannel::DecodeMessage(const std::string& data,
138                                       std::string* message,
139                                       std::string* service_context,
140                                       int64* scheduling_hash) {
141   ipc::invalidation::ClientGatewayMessage envelope;
142   if (!envelope.ParseFromString(data)) {
143     return false;
144   }
145   *message = envelope.network_message();
146   if (envelope.has_service_context()) {
147     *service_context = envelope.service_context();
148   }
149   if (envelope.has_rpc_scheduling_hash()) {
150     *scheduling_hash = envelope.rpc_scheduling_hash();
151   }
152   return true;
153 }
154 
CollectDebugData() const155 scoped_ptr<base::DictionaryValue> PushClientChannel::CollectDebugData() const {
156   scoped_ptr<base::DictionaryValue> status(new base::DictionaryValue);
157   status->SetString("PushClientChannel.NetworkChannel", "Push Client");
158   status->SetInteger("PushClientChannel.SentMessages", sent_messages_count_);
159   status->SetInteger("PushClientChannel.ReceivedMessages",
160                      SyncNetworkChannel::GetReceivedMessagesCount());
161   return status.Pass();
162 }
163 
164 }  // namespace syncer
165