OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "google_apis/gcm/engine/mcs_client.h" | 5 #include "google_apis/gcm/engine/mcs_client.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <set> | 8 #include <set> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/location.h" | 12 #include "base/location.h" |
13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
14 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
15 #include "base/thread_task_runner_handle.h" | 15 #include "base/thread_task_runner_handle.h" |
16 #include "base/time/clock.h" | 16 #include "base/time/clock.h" |
17 #include "base/time/time.h" | 17 #include "base/time/time.h" |
18 #include "base/timer/timer.h" | 18 #include "base/timer/timer.h" |
19 #include "google_apis/gcm/base/mcs_util.h" | 19 #include "google_apis/gcm/base/mcs_util.h" |
20 #include "google_apis/gcm/base/socket_stream.h" | 20 #include "google_apis/gcm/base/socket_stream.h" |
21 #include "google_apis/gcm/engine/connection_factory.h" | 21 #include "google_apis/gcm/engine/connection_factory.h" |
22 #include "google_apis/gcm/monitoring/gcm_stats_recorder.h" | 22 #include "google_apis/gcm/monitoring/gcm_stats_recorder.h" |
23 | 23 |
24 using namespace google::protobuf::io; | 24 using namespace google::protobuf::io; |
25 | 25 |
26 namespace gcm { | 26 namespace gcm { |
27 | 27 |
28 namespace { | 28 namespace { |
29 | 29 |
30 typedef scoped_ptr<google::protobuf::MessageLite> MCSProto; | 30 typedef std::unique_ptr<google::protobuf::MessageLite> MCSProto; |
31 | 31 |
32 // The category of messages intended for the GCM client itself from MCS. | 32 // The category of messages intended for the GCM client itself from MCS. |
33 const char kMCSCategory[] = "com.google.android.gsf.gtalkservice"; | 33 const char kMCSCategory[] = "com.google.android.gsf.gtalkservice"; |
34 | 34 |
35 // The from field for messages originating in the GCM client. | 35 // The from field for messages originating in the GCM client. |
36 const char kGCMFromField[] = "gcm@android.com"; | 36 const char kGCMFromField[] = "gcm@android.com"; |
37 | 37 |
38 // MCS status message types. | 38 // MCS status message types. |
39 // TODO(zea): handle these at the GCMClient layer. | 39 // TODO(zea): handle these at the GCMClient layer. |
40 const char kIdleNotification[] = "IdleNotification"; | 40 const char kIdleNotification[] = "IdleNotification"; |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 weak_ptr_factory_(this) { | 182 weak_ptr_factory_(this) { |
183 } | 183 } |
184 | 184 |
185 MCSClient::~MCSClient() { | 185 MCSClient::~MCSClient() { |
186 } | 186 } |
187 | 187 |
188 void MCSClient::Initialize( | 188 void MCSClient::Initialize( |
189 const ErrorCallback& error_callback, | 189 const ErrorCallback& error_callback, |
190 const OnMessageReceivedCallback& message_received_callback, | 190 const OnMessageReceivedCallback& message_received_callback, |
191 const OnMessageSentCallback& message_sent_callback, | 191 const OnMessageSentCallback& message_sent_callback, |
192 scoped_ptr<GCMStore::LoadResult> load_result) { | 192 std::unique_ptr<GCMStore::LoadResult> load_result) { |
193 DCHECK_EQ(state_, UNINITIALIZED); | 193 DCHECK_EQ(state_, UNINITIALIZED); |
194 | 194 |
195 state_ = LOADED; | 195 state_ = LOADED; |
196 mcs_error_callback_ = error_callback; | 196 mcs_error_callback_ = error_callback; |
197 message_received_callback_ = message_received_callback; | 197 message_received_callback_ = message_received_callback; |
198 message_sent_callback_ = message_sent_callback; | 198 message_sent_callback_ = message_sent_callback; |
199 | 199 |
200 connection_factory_->Initialize( | 200 connection_factory_->Initialize( |
201 base::Bind(&MCSClient::ResetStateAndBuildLoginRequest, | 201 base::Bind(&MCSClient::ResetStateAndBuildLoginRequest, |
202 weak_ptr_factory_.GetWeakPtr()), | 202 weak_ptr_factory_.GetWeakPtr()), |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 DCHECK_GE(ttl, 0); | 310 DCHECK_GE(ttl, 0); |
311 if (to_send_.size() > kMaxSendQueueSize) { | 311 if (to_send_.size() > kMaxSendQueueSize) { |
312 NotifyMessageSendStatus(message.GetProtobuf(), QUEUE_SIZE_LIMIT_REACHED); | 312 NotifyMessageSendStatus(message.GetProtobuf(), QUEUE_SIZE_LIMIT_REACHED); |
313 return; | 313 return; |
314 } | 314 } |
315 if (message.size() > kMaxMessageBytes) { | 315 if (message.size() > kMaxMessageBytes) { |
316 NotifyMessageSendStatus(message.GetProtobuf(), MESSAGE_TOO_LARGE); | 316 NotifyMessageSendStatus(message.GetProtobuf(), MESSAGE_TOO_LARGE); |
317 return; | 317 return; |
318 } | 318 } |
319 | 319 |
320 scoped_ptr<ReliablePacketInfo> packet_info(new ReliablePacketInfo()); | 320 std::unique_ptr<ReliablePacketInfo> packet_info(new ReliablePacketInfo()); |
321 packet_info->tag = message.tag(); | 321 packet_info->tag = message.tag(); |
322 packet_info->protobuf = message.CloneProtobuf(); | 322 packet_info->protobuf = message.CloneProtobuf(); |
323 | 323 |
324 if (ttl > 0) { | 324 if (ttl > 0) { |
325 DCHECK_EQ(message.tag(), kDataMessageStanzaTag); | 325 DCHECK_EQ(message.tag(), kDataMessageStanzaTag); |
326 | 326 |
327 // First check if this message should replace a pending message with the | 327 // First check if this message should replace a pending message with the |
328 // same collapse key. | 328 // same collapse key. |
329 mcs_proto::DataMessageStanza* data_message = | 329 mcs_proto::DataMessageStanza* data_message = |
330 reinterpret_cast<mcs_proto::DataMessageStanza*>( | 330 reinterpret_cast<mcs_proto::DataMessageStanza*>( |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
371 | 371 |
372 to_send_.push_back(make_linked_ptr(packet_info.release())); | 372 to_send_.push_back(make_linked_ptr(packet_info.release())); |
373 | 373 |
374 // Notify that the messages has been succsfully queued for sending. | 374 // Notify that the messages has been succsfully queued for sending. |
375 // TODO(jianli): We should report QUEUED after writing to GCM store succeeds. | 375 // TODO(jianli): We should report QUEUED after writing to GCM store succeeds. |
376 NotifyMessageSendStatus(message.GetProtobuf(), QUEUED); | 376 NotifyMessageSendStatus(message.GetProtobuf(), QUEUED); |
377 | 377 |
378 MaybeSendMessage(); | 378 MaybeSendMessage(); |
379 } | 379 } |
380 | 380 |
381 void MCSClient::UpdateHeartbeatTimer(scoped_ptr<base::Timer> timer) { | 381 void MCSClient::UpdateHeartbeatTimer(std::unique_ptr<base::Timer> timer) { |
382 heartbeat_manager_.UpdateHeartbeatTimer(std::move(timer)); | 382 heartbeat_manager_.UpdateHeartbeatTimer(std::move(timer)); |
383 } | 383 } |
384 | 384 |
385 void MCSClient::AddHeartbeatInterval(const std::string& scope, | 385 void MCSClient::AddHeartbeatInterval(const std::string& scope, |
386 int interval_ms) { | 386 int interval_ms) { |
387 if (!heartbeat_manager_.IsValidClientHeartbeatInterval(interval_ms)) | 387 if (!heartbeat_manager_.IsValidClientHeartbeatInterval(interval_ms)) |
388 return; | 388 return; |
389 | 389 |
390 custom_heartbeat_intervals_[scope] = interval_ms; | 390 custom_heartbeat_intervals_[scope] = interval_ms; |
391 gcm_store_->AddHeartbeatInterval(scope, interval_ms, | 391 gcm_store_->AddHeartbeatInterval(scope, interval_ms, |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
599 persistent_id_list.push_back(iter->second); | 599 persistent_id_list.push_back(iter->second); |
600 } | 600 } |
601 unacked_server_ids_.clear(); | 601 unacked_server_ids_.clear(); |
602 acked_server_ids_[stream_id_out_] = persistent_id_list; | 602 acked_server_ids_[stream_id_out_] = persistent_id_list; |
603 } | 603 } |
604 | 604 |
605 connection_handler_->SendMessage(*packet_info->protobuf); | 605 connection_handler_->SendMessage(*packet_info->protobuf); |
606 } | 606 } |
607 | 607 |
608 void MCSClient::HandleMCSDataMesssage( | 608 void MCSClient::HandleMCSDataMesssage( |
609 scoped_ptr<google::protobuf::MessageLite> protobuf) { | 609 std::unique_ptr<google::protobuf::MessageLite> protobuf) { |
610 mcs_proto::DataMessageStanza* data_message = | 610 mcs_proto::DataMessageStanza* data_message = |
611 reinterpret_cast<mcs_proto::DataMessageStanza*>(protobuf.get()); | 611 reinterpret_cast<mcs_proto::DataMessageStanza*>(protobuf.get()); |
612 // TODO(zea): implement a proper status manager rather than hardcoding these | 612 // TODO(zea): implement a proper status manager rather than hardcoding these |
613 // values. | 613 // values. |
614 scoped_ptr<mcs_proto::DataMessageStanza> response( | 614 std::unique_ptr<mcs_proto::DataMessageStanza> response( |
615 new mcs_proto::DataMessageStanza()); | 615 new mcs_proto::DataMessageStanza()); |
616 response->set_from(kGCMFromField); | 616 response->set_from(kGCMFromField); |
617 response->set_sent(clock_->Now().ToInternalValue() / | 617 response->set_sent(clock_->Now().ToInternalValue() / |
618 base::Time::kMicrosecondsPerSecond); | 618 base::Time::kMicrosecondsPerSecond); |
619 response->set_ttl(0); | 619 response->set_ttl(0); |
620 bool send = false; | 620 bool send = false; |
621 for (int i = 0; i < data_message->app_data_size(); ++i) { | 621 for (int i = 0; i < data_message->app_data_size(); ++i) { |
622 const mcs_proto::AppData& app_data = data_message->app_data(i); | 622 const mcs_proto::AppData& app_data = data_message->app_data(i); |
623 if (app_data.key() == kIdleNotification) { | 623 if (app_data.key() == kIdleNotification) { |
624 // Tell the MCS server the client is not idle. | 624 // Tell the MCS server the client is not idle. |
625 send = true; | 625 send = true; |
626 mcs_proto::AppData data; | 626 mcs_proto::AppData data; |
627 data.set_key(kIdleNotification); | 627 data.set_key(kIdleNotification); |
628 data.set_value("false"); | 628 data.set_value("false"); |
629 response->add_app_data()->CopyFrom(data); | 629 response->add_app_data()->CopyFrom(data); |
630 response->set_category(kMCSCategory); | 630 response->set_category(kMCSCategory); |
631 } | 631 } |
632 } | 632 } |
633 | 633 |
634 if (send) { | 634 if (send) { |
635 SendMessage(MCSMessage(kDataMessageStanzaTag, std::move(response))); | 635 SendMessage(MCSMessage(kDataMessageStanzaTag, std::move(response))); |
636 } | 636 } |
637 } | 637 } |
638 | 638 |
639 void MCSClient::HandlePacketFromWire( | 639 void MCSClient::HandlePacketFromWire( |
640 scoped_ptr<google::protobuf::MessageLite> protobuf) { | 640 std::unique_ptr<google::protobuf::MessageLite> protobuf) { |
641 if (!protobuf.get()) | 641 if (!protobuf.get()) |
642 return; | 642 return; |
643 uint8_t tag = GetMCSProtoTag(*protobuf); | 643 uint8_t tag = GetMCSProtoTag(*protobuf); |
644 PersistentId persistent_id = GetPersistentId(*protobuf); | 644 PersistentId persistent_id = GetPersistentId(*protobuf); |
645 StreamId last_stream_id_received = GetLastStreamIdReceived(*protobuf); | 645 StreamId last_stream_id_received = GetLastStreamIdReceived(*protobuf); |
646 | 646 |
647 if (last_stream_id_received != 0) { | 647 if (last_stream_id_received != 0) { |
648 last_device_to_server_stream_id_received_ = last_stream_id_received; | 648 last_device_to_server_stream_id_received_ = last_stream_id_received; |
649 | 649 |
650 // Process device to server messages that have now been acknowledged by the | 650 // Process device to server messages that have now been acknowledged by the |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
963 reinterpret_cast<mcs_proto::DataMessageStanza*>(packet->protobuf.get()); | 963 reinterpret_cast<mcs_proto::DataMessageStanza*>(packet->protobuf.get()); |
964 CollapseKey collapse_key(*data_message); | 964 CollapseKey collapse_key(*data_message); |
965 if (collapse_key.IsValid()) | 965 if (collapse_key.IsValid()) |
966 collapse_key_map_.erase(collapse_key); | 966 collapse_key_map_.erase(collapse_key); |
967 } | 967 } |
968 | 968 |
969 return packet; | 969 return packet; |
970 } | 970 } |
971 | 971 |
972 } // namespace gcm | 972 } // namespace gcm |
OLD | NEW |