Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1185)

Side by Side Diff: google_apis/gcm/gcm_client_impl.cc

Issue 215363007: [GCM] Adding basic G-services handling (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressing the feedback Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/gcm_client_impl.h" 5 #include "google_apis/gcm/gcm_client_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/files/file_path.h" 8 #include "base/files/file_path.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop/message_loop.h" 11 #include "base/message_loop/message_loop.h"
12 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
13 #include "base/sequenced_task_runner.h" 13 #include "base/sequenced_task_runner.h"
14 #include "base/strings/string_number_conversions.h"
14 #include "base/time/default_clock.h" 15 #include "base/time/default_clock.h"
15 #include "google_apis/gcm/base/mcs_message.h" 16 #include "google_apis/gcm/base/mcs_message.h"
16 #include "google_apis/gcm/base/mcs_util.h" 17 #include "google_apis/gcm/base/mcs_util.h"
17 #include "google_apis/gcm/engine/checkin_request.h" 18 #include "google_apis/gcm/engine/checkin_request.h"
18 #include "google_apis/gcm/engine/connection_factory_impl.h" 19 #include "google_apis/gcm/engine/connection_factory_impl.h"
19 #include "google_apis/gcm/engine/gcm_store_impl.h" 20 #include "google_apis/gcm/engine/gcm_store_impl.h"
20 #include "google_apis/gcm/engine/mcs_client.h" 21 #include "google_apis/gcm/engine/mcs_client.h"
21 #include "google_apis/gcm/protocol/mcs.pb.h" 22 #include "google_apis/gcm/protocol/mcs.pb.h"
22 #include "net/http/http_network_session.h" 23 #include "net/http/http_network_session.h"
23 #include "net/url_request/url_request_context.h" 24 #include "net/url_request/url_request_context.h"
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 SEND_ERROR, // Error sending a message. 68 SEND_ERROR, // Error sending a message.
68 }; 69 };
69 70
70 // MCS endpoints. SSL Key pinning is done automatically due to the *.google.com 71 // MCS endpoints. SSL Key pinning is done automatically due to the *.google.com
71 // pinning rule. 72 // pinning rule.
72 // Note: modifying the endpoints will affect the ability to compare the 73 // Note: modifying the endpoints will affect the ability to compare the
73 // GCM.CurrentEnpoint histogram across versions. 74 // GCM.CurrentEnpoint histogram across versions.
74 const char kMCSEndpointMain[] = "https://mtalk.google.com:5228"; 75 const char kMCSEndpointMain[] = "https://mtalk.google.com:5228";
75 const char kMCSEndpointFallback[] = "https://mtalk.google.com:443"; 76 const char kMCSEndpointFallback[] = "https://mtalk.google.com:443";
76 77
78 const char kCheckinIntervalKey[] = "checkin_interval";
79 const int64 kDefaultCheckinInterval = 172800LL; // seconds = 2 days.
80 const char kDeleteSettingPrefix[] = "delete_";
77 const int kMaxRegistrationRetries = 5; 81 const int kMaxRegistrationRetries = 5;
78 const char kMessageTypeDataMessage[] = "gcm"; 82 const char kMessageTypeDataMessage[] = "gcm";
79 const char kMessageTypeDeletedMessagesKey[] = "deleted_messages"; 83 const char kMessageTypeDeletedMessagesKey[] = "deleted_messages";
80 const char kMessageTypeKey[] = "message_type"; 84 const char kMessageTypeKey[] = "message_type";
81 const char kMessageTypeSendErrorKey[] = "send_error"; 85 const char kMessageTypeSendErrorKey[] = "send_error";
82 const char kSendErrorMessageIdKey[] = "google.message_id"; 86 const char kSendErrorMessageIdKey[] = "google.message_id";
83 const char kSendMessageFromValue[] = "gcm@chrome.com"; 87 const char kSendMessageFromValue[] = "gcm@chrome.com";
84 const int64 kDefaultUserSerialNumber = 0LL; 88 const int64 kDefaultUserSerialNumber = 0LL;
85 89
86 GCMClient::Result ToGCMClientResult(MCSClient::MessageSendStatus status) { 90 GCMClient::Result ToGCMClientResult(MCSClient::MessageSendStatus status) {
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 209
206 if (!result->success) { 210 if (!result->success) {
207 ResetState(); 211 ResetState();
208 return; 212 return;
209 } 213 }
210 214
211 registrations_ = result->registrations; 215 registrations_ = result->registrations;
212 216
213 device_checkin_info_.android_id = result->device_android_id; 217 device_checkin_info_.android_id = result->device_android_id;
214 device_checkin_info_.secret = result->device_security_token; 218 device_checkin_info_.secret = result->device_security_token;
219 g_services_settings_ = result->g_services_settings;
215 InitializeMCSClient(result.Pass()); 220 InitializeMCSClient(result.Pass());
216 if (!device_checkin_info_.IsValid()) { 221 if (!device_checkin_info_.IsValid()) {
217 device_checkin_info_.Reset(); 222 device_checkin_info_.Reset();
218 state_ = INITIAL_DEVICE_CHECKIN; 223 state_ = INITIAL_DEVICE_CHECKIN;
219 StartCheckin(device_checkin_info_); 224 StartCheckin(device_checkin_info_);
220 return; 225 return;
226 } else {
227 SchedulePeriodicCheckin(result->last_checkin_time, device_checkin_info_);
221 } 228 }
222 229
223 OnReady(); 230 OnReady();
224 } 231 }
225 232
226 void GCMClientImpl::InitializeMCSClient( 233 void GCMClientImpl::InitializeMCSClient(
227 scoped_ptr<GCMStore::LoadResult> result) { 234 scoped_ptr<GCMStore::LoadResult> result) {
228 std::vector<GURL> endpoints; 235 std::vector<GURL> endpoints;
229 endpoints.push_back(GURL(kMCSEndpointMain)); 236 endpoints.push_back(GURL(kMCSEndpointMain));
230 endpoints.push_back(GURL(kMCSEndpointFallback)); 237 endpoints.push_back(GURL(kMCSEndpointFallback));
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 weak_ptr_factory_.GetWeakPtr()), 294 weak_ptr_factory_.GetWeakPtr()),
288 kDefaultBackoffPolicy, 295 kDefaultBackoffPolicy,
289 chrome_build_proto_, 296 chrome_build_proto_,
290 checkin_info.android_id, 297 checkin_info.android_id,
291 checkin_info.secret, 298 checkin_info.secret,
292 account_ids_, 299 account_ids_,
293 url_request_context_getter_)); 300 url_request_context_getter_));
294 checkin_request_->Start(); 301 checkin_request_->Start();
295 } 302 }
296 303
297 void GCMClientImpl::OnCheckinCompleted(uint64 android_id, 304 void GCMClientImpl::SchedulePeriodicCheckin(
298 uint64 security_token) { 305 const base::Time& last_checkin_time,
306 const CheckinInfo& checkin_info) {
Nicolas Zea 2014/03/28 22:56:53 why pass CheckinInfo in as a param? Aren't we alwa
fgorski 2014/03/29 01:09:33 Done.
307 GServicesSettingsMap::const_iterator iter =
308 g_services_settings_.find(kCheckinIntervalKey);
309 int64 checkin_interval_sec = kDefaultCheckinInterval;
310 if (iter != g_services_settings_.end())
311 base::StringToInt64(iter->second, &checkin_interval_sec);
312 base::TimeDelta checkin_interval =
313 base::TimeDelta::FromSeconds(checkin_interval_sec);
314 base::TimeDelta time_to_next_checkin =
315 last_checkin_time + checkin_interval - clock_->Now();
316 base::MessageLoop::current()->PostDelayedTask(
Nicolas Zea 2014/03/28 22:56:53 What about if time_to_next_checkin is negative (I
fgorski 2014/03/29 01:09:33 Done.
317 FROM_HERE,
318 base::Bind(&GCMClientImpl::StartCheckin,
319 weak_ptr_factory_.GetWeakPtr(),
320 checkin_info),
321 time_to_next_checkin);
322 }
323
324 void GCMClientImpl::OnCheckinCompleted(
325 const checkin_proto::AndroidCheckinResponse& checkin_response) {
299 checkin_request_.reset(); 326 checkin_request_.reset();
300 327
301 CheckinInfo checkin_info; 328 if (!checkin_response.has_android_id() ||
302 checkin_info.android_id = android_id; 329 !checkin_response.has_security_token()) {
303 checkin_info.secret = security_token;
304
305 if (!checkin_info.IsValid()) {
306 // TODO(fgorski): I don't think a retry here will help, we should probalby 330 // TODO(fgorski): I don't think a retry here will help, we should probalby
Nicolas Zea 2014/03/28 22:56:53 nit: probalby -> probably
fgorski 2014/03/29 01:09:33 Done.
307 // start over. By checking in with (0, 0). 331 // start over. By checking in with (0, 0).
308 return; 332 return;
309 } 333 }
310 334
335 CheckinInfo checkin_info;
336 checkin_info.android_id = checkin_response.android_id();
337 checkin_info.secret = checkin_response.security_token();
338
311 if (state_ == INITIAL_DEVICE_CHECKIN) { 339 if (state_ == INITIAL_DEVICE_CHECKIN) {
312 OnFirstTimeDeviceCheckinCompleted(checkin_info); 340 OnFirstTimeDeviceCheckinCompleted(checkin_info);
313 } else { 341 } else {
314 DCHECK_EQ(READY, state_); 342 DCHECK_EQ(READY, state_);
315 if (device_checkin_info_.android_id != checkin_info.android_id || 343 if (device_checkin_info_.android_id != checkin_info.android_id ||
316 device_checkin_info_.secret != checkin_info.secret) { 344 device_checkin_info_.secret != checkin_info.secret) {
317 ResetState(); 345 ResetState();
318 } else {
319 // TODO(fgorski): Reset the checkin timer.
320 } 346 }
321 } 347 }
348
349 if (device_checkin_info_.IsValid()) {
350 UpdateGServicesSettings(checkin_response);
351 SchedulePeriodicCheckin(clock_->Now(), device_checkin_info_);
352 }
322 } 353 }
323 354
324 void GCMClientImpl::SetDeviceCredentialsCallback(bool success) { 355 void GCMClientImpl::SetDeviceCredentialsCallback(bool success) {
325 // TODO(fgorski): This is one of the signals that store needs a rebuild. 356 // TODO(fgorski): This is one of the signals that store needs a rebuild.
326 DCHECK(success); 357 DCHECK(success);
327 } 358 }
328 359
329 void GCMClientImpl::UpdateRegistrationCallback(bool success) { 360 void GCMClientImpl::UpdateRegistrationCallback(bool success) {
330 // TODO(fgorski): This is one of the signals that store needs a rebuild. 361 // TODO(fgorski): This is one of the signals that store needs a rebuild.
331 DCHECK(success); 362 DCHECK(success);
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 send_error_details.additional_data.find(kSendErrorMessageIdKey); 688 send_error_details.additional_data.find(kSendErrorMessageIdKey);
658 if (iter != send_error_details.additional_data.end()) { 689 if (iter != send_error_details.additional_data.end()) {
659 send_error_details.message_id = iter->second; 690 send_error_details.message_id = iter->second;
660 send_error_details.additional_data.erase(iter); 691 send_error_details.additional_data.erase(iter);
661 } 692 }
662 693
663 delegate_->OnMessageSendError(data_message_stanza.category(), 694 delegate_->OnMessageSendError(data_message_stanza.category(),
664 send_error_details); 695 send_error_details);
665 } 696 }
666 697
698 void GCMClientImpl::UpdateGServicesSettings(
699 const checkin_proto::AndroidCheckinResponse& checkin_response) {
700 std::vector<std::string> settings_to_remove;
701 std::map<std::string, std::string> settings_to_add;
702
703 // Check if we are only dealing with a diff of settings or full update.
704 bool settings_diff = false;
705 if (checkin_response.has_settings_diff() &&
706 !checkin_response.settings_diff()) {
707 for (GServicesSettingsMap::const_iterator it = g_services_settings_.begin();
708 it != g_services_settings_.end(); ++it) {
709 settings_to_remove.push_back(it->first);
710 }
711 g_services_settings_.clear();
712 settings_diff = true;
713 }
714
715 for (int i = 0; i < checkin_response.setting_size(); ++i) {
716 std::string name = checkin_response.setting(i).name();
717 // When the settings_diff is set to true in the protobuf, the entries that
718 // start from "delete_" are meant to be removing the settings.
719 if (settings_diff && name.find(kDeleteSettingPrefix) == 0) {
720 name = name.substr(arraysize(kDeleteSettingPrefix) - 1);
721 GServicesSettingsMap::iterator iter = g_services_settings_.find(name);
722 if (iter != g_services_settings_.end()) {
723 settings_to_remove.push_back(name);
724 g_services_settings_.erase(iter);
725 }
726 } else {
727 std::string value = checkin_response.setting(i).value();
728 g_services_settings_[name] = value;
729 settings_to_add[name] = value;
730 }
731 }
732
733 gcm_store_->UpdateGServicesSettings(
734 settings_to_remove,
735 settings_to_add,
736 clock_->Now(),
737 base::Bind(&GCMClientImpl::UpdateGServicesSettingsCallback,
738 weak_ptr_factory_.GetWeakPtr()));
739 }
740
741 void GCMClientImpl::UpdateGServicesSettingsCallback(bool success) {
742 DCHECK(success);
743 }
744
667 } // namespace gcm 745 } // namespace gcm
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698