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.
5 #include "google_apis/gcm/engine/gservices_settings.h"
8 #include "base/strings/string_number_conversions.h"
11 // The expected time in seconds between periodic checkins.
12 const char kCheckinIntervalKey[] = "checkin_interval";
13 // The override URL to the checkin server.
14 const char kCheckinURLKey[] = "checkin_url";
15 // The MCS machine name to connect to.
16 const char kMCSHostnameKey[] = "gcm_hostname";
17 // The MCS port to connect to.
18 const char kMCSSecurePortKey[] = "gcm_secure_port";
19 // The URL to get MCS registration IDs.
20 const char kRegistrationURLKey[] = "gcm_registration_url";
22 const int64 kDefaultCheckinInterval = 2 * 24 * 60 * 60; // seconds = 2 days.
23 const int64 kMinimumCheckinInterval = 12 * 60 * 60; // seconds = 12 hours.
24 const char kDefaultCheckinURL[] = "https://android.clients.google.com/checkin";
25 const char kDefaultMCSHostname[] = "https://mtalk.google.com";
26 const int kDefaultMCSSecurePort = 5228;
27 const char kDefaultRegistrationURL[] =
28 "https://android.clients.google.com/c2dm/register3";
35 const base::TimeDelta GServicesSettings::MinimumCheckinInterval() {
36 return base::TimeDelta::FromSeconds(kMinimumCheckinInterval);
40 const GURL GServicesSettings::DefaultCheckinURL() {
41 return GURL(kDefaultCheckinURL);
44 GServicesSettings::GServicesSettings()
45 : checkin_interval_(base::TimeDelta::FromSeconds(kDefaultCheckinInterval)),
46 checkin_url_(kDefaultCheckinURL),
47 mcs_hostname_(kDefaultMCSHostname),
48 mcs_secure_port_(kDefaultMCSSecurePort),
49 registration_url_(kDefaultRegistrationURL),
50 weak_ptr_factory_(this) {
53 GServicesSettings::~GServicesSettings() {}
55 bool GServicesSettings::UpdateFromCheckinResponse(
56 const checkin_proto::AndroidCheckinResponse& checkin_response) {
57 if (!checkin_response.has_digest() ||
58 checkin_response.digest() == digest_) {
59 // There are no changes as digest is the same or no settings provided.
63 std::map<std::string, std::string> settings;
64 for (int i = 0; i < checkin_response.setting_size(); ++i) {
65 std::string name = checkin_response.setting(i).name();
66 std::string value = checkin_response.setting(i).value();
67 settings[name] = value;
70 // Only update the settings in store and digest, if the settings actually
71 // passed the verificaiton in update settings.
72 if (UpdateSettings(settings)) {
73 digest_ = checkin_response.digest();
80 void GServicesSettings::UpdateFromLoadResult(
81 const GCMStore::LoadResult& load_result) {
82 if (UpdateSettings(load_result.gservices_settings))
83 digest_ = load_result.gservices_digest;
86 std::map<std::string, std::string> GServicesSettings::GetSettingsMap() const {
87 std::map<std::string, std::string> settings;
88 settings[kCheckinIntervalKey] =
89 base::Int64ToString(checkin_interval_.InSeconds());
90 settings[kCheckinURLKey] = checkin_url_.spec();
91 settings[kMCSHostnameKey] = mcs_hostname_;
92 settings[kMCSSecurePortKey] = base::IntToString(mcs_secure_port_);
93 settings[kRegistrationURLKey] = registration_url_.spec();
97 bool GServicesSettings::UpdateSettings(
98 const std::map<std::string, std::string>& settings) {
99 int64 new_checkin_interval = kMinimumCheckinInterval;
100 std::map<std::string, std::string>::const_iterator iter =
101 settings.find(kCheckinIntervalKey);
102 if (iter == settings.end()) {
103 LOG(ERROR) << "Setting not found: " << kCheckinIntervalKey;
106 if (!base::StringToInt64(iter->second, &new_checkin_interval)) {
107 LOG(ERROR) << "Failed to parse checkin interval: " << iter->second;
110 if (new_checkin_interval < kMinimumCheckinInterval) {
111 LOG(ERROR) << "Checkin interval: " << new_checkin_interval
112 << " is less than allowed minimum: " << kMinimumCheckinInterval;
113 new_checkin_interval = kMinimumCheckinInterval;
115 if (new_checkin_interval == std::numeric_limits<int64>::max()) {
116 LOG(ERROR) << "Checkin interval is too big: " << new_checkin_interval;
120 std::string new_mcs_hostname;
121 iter = settings.find(kMCSHostnameKey);
122 if (iter == settings.end()) {
123 LOG(ERROR) << "Setting not found: " << kMCSHostnameKey;
126 new_mcs_hostname = iter->second;
127 if (new_mcs_hostname.empty()) {
128 LOG(ERROR) << "Empty MCS hostname provided.";
132 int new_mcs_secure_port = -1;
133 iter = settings.find(kMCSSecurePortKey);
134 if (iter == settings.end()) {
135 LOG(ERROR) << "Setting not found: " << kMCSSecurePortKey;
138 if (!base::StringToInt(iter->second, &new_mcs_secure_port)) {
139 LOG(ERROR) << "Failed to parse MCS secure port: " << iter->second;
142 if (new_mcs_secure_port < 0 || 65535 < new_mcs_secure_port) {
143 LOG(ERROR) << "Incorrect port value: " << new_mcs_secure_port;
147 GURL new_checkin_url;
148 iter = settings.find(kCheckinURLKey);
149 if (iter == settings.end()) {
150 LOG(ERROR) << "Setting not found: " << kCheckinURLKey;
153 new_checkin_url = GURL(iter->second);
154 if (!new_checkin_url.is_valid()) {
155 LOG(ERROR) << "Invalid checkin URL provided: "
156 << new_checkin_url.possibly_invalid_spec();
160 GURL new_registration_url;
161 iter = settings.find(kRegistrationURLKey);
162 if (iter == settings.end()) {
163 LOG(ERROR) << "Setting not found: " << kRegistrationURLKey;
166 new_registration_url = GURL(iter->second);
167 if (!new_registration_url.is_valid()) {
168 LOG(ERROR) << "Invalid registration URL provided: "
169 << new_registration_url.possibly_invalid_spec();
173 // We only update the settings once all of them are correct.
174 checkin_interval_ = base::TimeDelta::FromSeconds(new_checkin_interval);
175 mcs_hostname_ = new_mcs_hostname;
176 mcs_secure_port_ = new_mcs_secure_port;
177 checkin_url_ = new_checkin_url;
178 registration_url_ = new_registration_url;