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

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 Jian Li's CR comments. 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.
77 const int kMaxRegistrationRetries = 5; 80 const int kMaxRegistrationRetries = 5;
78 const char kMessageTypeDataMessage[] = "gcm"; 81 const char kMessageTypeDataMessage[] = "gcm";
79 const char kMessageTypeDeletedMessagesKey[] = "deleted_messages"; 82 const char kMessageTypeDeletedMessagesKey[] = "deleted_messages";
80 const char kMessageTypeKey[] = "message_type"; 83 const char kMessageTypeKey[] = "message_type";
81 const char kMessageTypeSendErrorKey[] = "send_error"; 84 const char kMessageTypeSendErrorKey[] = "send_error";
82 const char kSendErrorMessageIdKey[] = "google.message_id"; 85 const char kSendErrorMessageIdKey[] = "google.message_id";
83 const char kSendMessageFromValue[] = "gcm@chrome.com"; 86 const char kSendMessageFromValue[] = "gcm@chrome.com";
84 const int64 kDefaultUserSerialNumber = 0LL; 87 const int64 kDefaultUserSerialNumber = 0LL;
85 88
86 GCMClient::Result ToGCMClientResult(MCSClient::MessageSendStatus status) { 89 GCMClient::Result ToGCMClientResult(MCSClient::MessageSendStatus status) {
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 208
206 if (!result->success) { 209 if (!result->success) {
207 ResetState(); 210 ResetState();
208 return; 211 return;
209 } 212 }
210 213
211 registrations_ = result->registrations; 214 registrations_ = result->registrations;
212 215
213 device_checkin_info_.android_id = result->device_android_id; 216 device_checkin_info_.android_id = result->device_android_id;
214 device_checkin_info_.secret = result->device_security_token; 217 device_checkin_info_.secret = result->device_security_token;
218 gservices_settings_ = result->gservices_settings;
219 gservices_digest_ = result->gservices_digest;
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();
220 return; 225 return;
226 } else {
227 SchedulePeriodicCheckin(result->last_checkin_time);
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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 DCHECK(device_checkin_info_.IsValid()); 281 DCHECK(device_checkin_info_.IsValid());
275 mcs_client_->Login(device_checkin_info_.android_id, 282 mcs_client_->Login(device_checkin_info_.android_id,
276 device_checkin_info_.secret); 283 device_checkin_info_.secret);
277 } 284 }
278 285
279 void GCMClientImpl::ResetState() { 286 void GCMClientImpl::ResetState() {
280 state_ = UNINITIALIZED; 287 state_ = UNINITIALIZED;
281 // TODO(fgorski): reset all of the necessart objects and start over. 288 // TODO(fgorski): reset all of the necessart objects and start over.
282 } 289 }
283 290
284 void GCMClientImpl::StartCheckin(const CheckinInfo& checkin_info) { 291 void GCMClientImpl::StartCheckin() {
292 CheckinRequest::RequestInfo request_info(
293 device_checkin_info_.android_id,
294 device_checkin_info_.secret,
295 gservices_digest_,
296 account_ids_,
297 chrome_build_proto_);
285 checkin_request_.reset( 298 checkin_request_.reset(
286 new CheckinRequest(base::Bind(&GCMClientImpl::OnCheckinCompleted, 299 new CheckinRequest(request_info,
300 kDefaultBackoffPolicy,
301 base::Bind(&GCMClientImpl::OnCheckinCompleted,
287 weak_ptr_factory_.GetWeakPtr()), 302 weak_ptr_factory_.GetWeakPtr()),
288 kDefaultBackoffPolicy,
289 chrome_build_proto_,
290 checkin_info.android_id,
291 checkin_info.secret,
292 account_ids_,
293 url_request_context_getter_)); 303 url_request_context_getter_));
294 checkin_request_->Start(); 304 checkin_request_->Start();
295 } 305 }
296 306
297 void GCMClientImpl::OnCheckinCompleted(uint64 android_id, 307 void GCMClientImpl::SchedulePeriodicCheckin(
298 uint64 security_token) { 308 const base::Time& last_checkin_time) {
309 base::TimeDelta time_to_next_checkin =
310 last_checkin_time + GetCheckinInterval() - clock_->Now();
311 if (time_to_next_checkin < base::TimeDelta::FromSeconds(0LL))
312 time_to_next_checkin = base::TimeDelta::FromSeconds(0LL);
313 base::MessageLoop::current()->PostDelayedTask(
314 FROM_HERE,
315 base::Bind(&GCMClientImpl::StartCheckin,
Nicolas Zea 2014/04/01 21:42:14 Add a TODO to modify this once we can trigger chec
fgorski 2014/04/02 18:23:00 Done.
316 weak_ptr_factory_.GetWeakPtr()),
317 time_to_next_checkin);
318 }
319
320 base::TimeDelta GCMClientImpl::GetCheckinInterval() const {
321 GServicesSettingsMap::const_iterator iter =
322 gservices_settings_.find(kCheckinIntervalKey);
323 int64 checkin_interval_sec = kDefaultCheckinInterval;
324 if (iter != gservices_settings_.end())
325 base::StringToInt64(iter->second, &checkin_interval_sec);
326 return base::TimeDelta::FromSeconds(checkin_interval_sec);
327 }
328
329 void GCMClientImpl::OnCheckinCompleted(
330 const checkin_proto::AndroidCheckinResponse& checkin_response) {
299 checkin_request_.reset(); 331 checkin_request_.reset();
300 332
301 CheckinInfo checkin_info; 333 if (!checkin_response.has_android_id() ||
302 checkin_info.android_id = android_id; 334 !checkin_response.has_security_token()) {
303 checkin_info.secret = security_token; 335 // TODO(fgorski): I don't think a retry here will help, we should probably
304
305 if (!checkin_info.IsValid()) {
306 // TODO(fgorski): I don't think a retry here will help, we should probalby
307 // start over. By checking in with (0, 0). 336 // start over. By checking in with (0, 0).
308 return; 337 return;
309 } 338 }
310 339
340 CheckinInfo checkin_info;
341 checkin_info.android_id = checkin_response.android_id();
342 checkin_info.secret = checkin_response.security_token();
343
311 if (state_ == INITIAL_DEVICE_CHECKIN) { 344 if (state_ == INITIAL_DEVICE_CHECKIN) {
312 OnFirstTimeDeviceCheckinCompleted(checkin_info); 345 OnFirstTimeDeviceCheckinCompleted(checkin_info);
313 } else { 346 } else {
314 DCHECK_EQ(READY, state_); 347 DCHECK_EQ(READY, state_);
315 if (device_checkin_info_.android_id != checkin_info.android_id || 348 if (device_checkin_info_.android_id != checkin_info.android_id ||
316 device_checkin_info_.secret != checkin_info.secret) { 349 device_checkin_info_.secret != checkin_info.secret) {
317 ResetState(); 350 ResetState();
318 } else {
319 // TODO(fgorski): Reset the checkin timer.
320 } 351 }
321 } 352 }
353
354 if (device_checkin_info_.IsValid()) {
355 UpdateGServicesSettings(checkin_response);
356 SchedulePeriodicCheckin(clock_->Now());
357 }
322 } 358 }
323 359
324 void GCMClientImpl::SetDeviceCredentialsCallback(bool success) { 360 void GCMClientImpl::SetDeviceCredentialsCallback(bool success) {
325 // 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.
326 DCHECK(success); 362 DCHECK(success);
327 } 363 }
328 364
329 void GCMClientImpl::UpdateRegistrationCallback(bool success) { 365 void GCMClientImpl::UpdateRegistrationCallback(bool success) {
330 // TODO(fgorski): This is one of the signals that store needs a rebuild. 366 // TODO(fgorski): This is one of the signals that store needs a rebuild.
331 DCHECK(success); 367 DCHECK(success);
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 send_error_details.additional_data.find(kSendErrorMessageIdKey); 693 send_error_details.additional_data.find(kSendErrorMessageIdKey);
658 if (iter != send_error_details.additional_data.end()) { 694 if (iter != send_error_details.additional_data.end()) {
659 send_error_details.message_id = iter->second; 695 send_error_details.message_id = iter->second;
660 send_error_details.additional_data.erase(iter); 696 send_error_details.additional_data.erase(iter);
661 } 697 }
662 698
663 delegate_->OnMessageSendError(data_message_stanza.category(), 699 delegate_->OnMessageSendError(data_message_stanza.category(),
664 send_error_details); 700 send_error_details);
665 } 701 }
666 702
703 void GCMClientImpl::UpdateGServicesSettings(
704 const checkin_proto::AndroidCheckinResponse& checkin_response) {
705 if (!checkin_response.has_digest() ||
706 checkin_response.digest() == gservices_digest_) {
707 return;
708 }
709
710 gservices_digest_ = checkin_response.digest();
711 gservices_settings_.clear();
712
713 for (int i = 0; i < checkin_response.setting_size(); ++i) {
714 std::string name = checkin_response.setting(i).name();
715 std::string value = checkin_response.setting(i).value();
716 gservices_settings_[name] = value;
717 }
718
719 gcm_store_->SetGServicesSettings(
720 gservices_settings_,
721 gservices_digest_,
722 clock_->Now(),
723 base::Bind(&GCMClientImpl::UpdateGServicesSettingsCallback,
724 weak_ptr_factory_.GetWeakPtr()));
725 }
726
727 void GCMClientImpl::UpdateGServicesSettingsCallback(bool success) {
728 DCHECK(success);
729 }
730
667 } // namespace gcm 731 } // namespace gcm
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698