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

Side by Side Diff: google_apis/gcm/engine/gcm_store_impl.cc

Issue 226893002: Revert of [GCM] Adding periodic checkin controlled by G-services settings (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 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 2014 The Chromium Authors. All rights reserved. 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 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/gcm_store_impl.h" 5 #include "google_apis/gcm/engine/gcm_store_impl.h"
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/callback.h" 9 #include "base/callback.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
11 #include "base/files/file_path.h" 11 #include "base/files/file_path.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/message_loop/message_loop_proxy.h" 13 #include "base/message_loop/message_loop_proxy.h"
14 #include "base/metrics/histogram.h" 14 #include "base/metrics/histogram.h"
15 #include "base/sequenced_task_runner.h" 15 #include "base/sequenced_task_runner.h"
16 #include "base/stl_util.h" 16 #include "base/stl_util.h"
17 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/string_piece.h" 18 #include "base/strings/string_piece.h"
19 #include "base/time/time.h"
20 #include "base/tracked_objects.h" 19 #include "base/tracked_objects.h"
21 #include "components/os_crypt/os_crypt.h" 20 #include "components/os_crypt/os_crypt.h"
22 #include "google_apis/gcm/base/mcs_message.h" 21 #include "google_apis/gcm/base/mcs_message.h"
23 #include "google_apis/gcm/base/mcs_util.h" 22 #include "google_apis/gcm/base/mcs_util.h"
24 #include "google_apis/gcm/protocol/mcs.pb.h" 23 #include "google_apis/gcm/protocol/mcs.pb.h"
25 #include "third_party/leveldatabase/src/include/leveldb/db.h" 24 #include "third_party/leveldatabase/src/include/leveldb/db.h"
26 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
27 25
28 namespace gcm { 26 namespace gcm {
29 27
30 namespace { 28 namespace {
31 29
32 // Limit to the number of outstanding messages per app. 30 // Limit to the number of outstanding messages per app.
33 const int kMessagesPerAppLimit = 20; 31 const int kMessagesPerAppLimit = 20;
34 32
35 // ---- LevelDB keys. ---- 33 // ---- LevelDB keys. ----
36 // Key for this device's android id. 34 // Key for this device's android id.
(...skipping 11 matching lines...) Expand all
48 const char kIncomingMsgKeyStart[] = "incoming1-"; 46 const char kIncomingMsgKeyStart[] = "incoming1-";
49 // Key guaranteed to be higher than all incoming message keys. 47 // Key guaranteed to be higher than all incoming message keys.
50 // Used for limiting iteration. 48 // Used for limiting iteration.
51 const char kIncomingMsgKeyEnd[] = "incoming2-"; 49 const char kIncomingMsgKeyEnd[] = "incoming2-";
52 // Lowest lexicographically ordered outgoing message key. 50 // Lowest lexicographically ordered outgoing message key.
53 // Used for prefixing outgoing messages. 51 // Used for prefixing outgoing messages.
54 const char kOutgoingMsgKeyStart[] = "outgoing1-"; 52 const char kOutgoingMsgKeyStart[] = "outgoing1-";
55 // Key guaranteed to be higher than all outgoing message keys. 53 // Key guaranteed to be higher than all outgoing message keys.
56 // Used for limiting iteration. 54 // Used for limiting iteration.
57 const char kOutgoingMsgKeyEnd[] = "outgoing2-"; 55 const char kOutgoingMsgKeyEnd[] = "outgoing2-";
58 // Lowest lexicographically ordered G-service settings key.
59 // Used for prefixing G-services settings.
60 const char kGServiceSettingKeyStart[] = "gservice1-";
61 // Key guaranteed to be higher than all G-services settings keys.
62 // Used for limiting iteration.
63 const char kGServiceSettingKeyEnd[] = "gservice2-";
64 // Key for digest of the last G-services settings update.
65 const char kGServiceSettingsDigestKey[] = "gservices_digest";
66 // Key used to timestamp last checkin (marked with G services settings update). 56 // Key used to timestamp last checkin (marked with G services settings update).
67 const char kLastCheckinTimeKey[] = "last_checkin_time"; 57 const char kLastCheckinTimeKey[] = "last_checkin_time";
68 58
69 std::string MakeRegistrationKey(const std::string& app_id) { 59 std::string MakeRegistrationKey(const std::string& app_id) {
70 return kRegistrationKeyStart + app_id; 60 return kRegistrationKeyStart + app_id;
71 } 61 }
72 62
73 std::string ParseRegistrationKey(const std::string& key) { 63 std::string ParseRegistrationKey(const std::string& key) {
74 return key.substr(arraysize(kRegistrationKeyStart) - 1); 64 return key.substr(arraysize(kRegistrationKeyStart) - 1);
75 } 65 }
76 66
77 std::string MakeIncomingKey(const std::string& persistent_id) { 67 std::string MakeIncomingKey(const std::string& persistent_id) {
78 return kIncomingMsgKeyStart + persistent_id; 68 return kIncomingMsgKeyStart + persistent_id;
79 } 69 }
80 70
81 std::string MakeOutgoingKey(const std::string& persistent_id) { 71 std::string MakeOutgoingKey(const std::string& persistent_id) {
82 return kOutgoingMsgKeyStart + persistent_id; 72 return kOutgoingMsgKeyStart + persistent_id;
83 } 73 }
84 74
85 std::string ParseOutgoingKey(const std::string& key) { 75 std::string ParseOutgoingKey(const std::string& key) {
86 return key.substr(arraysize(kOutgoingMsgKeyStart) - 1); 76 return key.substr(arraysize(kOutgoingMsgKeyStart) - 1);
87 } 77 }
88 78
89 std::string MakeGServiceSettingKey(const std::string& setting_name) {
90 return kGServiceSettingKeyStart + setting_name;
91 }
92
93 std::string ParseGServiceSettingKey(const std::string& key) {
94 return key.substr(arraysize(kGServiceSettingKeyStart) - 1);
95 }
96
97 // Note: leveldb::Slice keeps a pointer to the data in |s|, which must therefore 79 // Note: leveldb::Slice keeps a pointer to the data in |s|, which must therefore
98 // outlive the slice. 80 // outlive the slice.
99 // For example: MakeSlice(MakeOutgoingKey(x)) is invalid. 81 // For example: MakeSlice(MakeOutgoingKey(x)) is invalid.
100 leveldb::Slice MakeSlice(const base::StringPiece& s) { 82 leveldb::Slice MakeSlice(const base::StringPiece& s) {
101 return leveldb::Slice(s.begin(), s.size()); 83 return leveldb::Slice(s.begin(), s.size());
102 } 84 }
103 85
104 } // namespace 86 } // namespace
105 87
106 class GCMStoreImpl::Backend 88 class GCMStoreImpl::Backend
(...skipping 25 matching lines...) Expand all
132 const PersistentIdList& persistent_ids, 114 const PersistentIdList& persistent_ids,
133 const base::Callback<void(bool, const AppIdToMessageCountMap&)> 115 const base::Callback<void(bool, const AppIdToMessageCountMap&)>
134 callback); 116 callback);
135 void AddUserSerialNumber(const std::string& username, 117 void AddUserSerialNumber(const std::string& username,
136 int64 serial_number, 118 int64 serial_number,
137 const UpdateCallback& callback); 119 const UpdateCallback& callback);
138 void RemoveUserSerialNumber(const std::string& username, 120 void RemoveUserSerialNumber(const std::string& username,
139 const UpdateCallback& callback); 121 const UpdateCallback& callback);
140 void SetLastCheckinTime(const base::Time& last_checkin_time, 122 void SetLastCheckinTime(const base::Time& last_checkin_time,
141 const UpdateCallback& callback); 123 const UpdateCallback& callback);
142 void SetGServicesSettings(
143 const std::map<std::string, std::string>& settings,
144 const std::string& digest,
145 const UpdateCallback& callback);
146 124
147 private: 125 private:
148 friend class base::RefCountedThreadSafe<Backend>; 126 friend class base::RefCountedThreadSafe<Backend>;
149 ~Backend(); 127 ~Backend();
150 128
151 bool LoadDeviceCredentials(uint64* android_id, uint64* security_token); 129 bool LoadDeviceCredentials(uint64* android_id, uint64* security_token);
152 bool LoadRegistrations(RegistrationInfoMap* registrations); 130 bool LoadRegistrations(RegistrationInfoMap* registrations);
153 bool LoadIncomingMessages(std::vector<std::string>* incoming_messages); 131 bool LoadIncomingMessages(std::vector<std::string>* incoming_messages);
154 bool LoadOutgoingMessages(OutgoingMessageMap* outgoing_messages); 132 bool LoadOutgoingMessages(OutgoingMessageMap* outgoing_messages);
155 bool LoadLastCheckinTime(base::Time* last_checkin_time); 133 bool LoadLastCheckinTime(base::Time* last_checkin_time);
156 bool LoadGServicesSettings(std::map<std::string, std::string>* settings,
157 std::string* digest);
158 134
159 const base::FilePath path_; 135 const base::FilePath path_;
160 scoped_refptr<base::SequencedTaskRunner> foreground_task_runner_; 136 scoped_refptr<base::SequencedTaskRunner> foreground_task_runner_;
161 137
162 scoped_ptr<leveldb::DB> db_; 138 scoped_ptr<leveldb::DB> db_;
163 }; 139 };
164 140
165 GCMStoreImpl::Backend::Backend( 141 GCMStoreImpl::Backend::Backend(
166 const base::FilePath& path, 142 const base::FilePath& path,
167 scoped_refptr<base::SequencedTaskRunner> foreground_task_runner) 143 scoped_refptr<base::SequencedTaskRunner> foreground_task_runner)
(...skipping 25 matching lines...) Expand all
193 base::Passed(&result))); 169 base::Passed(&result)));
194 return; 170 return;
195 } 171 }
196 db_.reset(db); 172 db_.reset(db);
197 173
198 if (!LoadDeviceCredentials(&result->device_android_id, 174 if (!LoadDeviceCredentials(&result->device_android_id,
199 &result->device_security_token) || 175 &result->device_security_token) ||
200 !LoadRegistrations(&result->registrations) || 176 !LoadRegistrations(&result->registrations) ||
201 !LoadIncomingMessages(&result->incoming_messages) || 177 !LoadIncomingMessages(&result->incoming_messages) ||
202 !LoadOutgoingMessages(&result->outgoing_messages) || 178 !LoadOutgoingMessages(&result->outgoing_messages) ||
203 !LoadLastCheckinTime(&result->last_checkin_time) || 179 !LoadLastCheckinTime(&result->last_checkin_time)) {
204 !LoadGServicesSettings(&result->gservices_settings,
205 &result->gservices_digest)) {
206 result->device_android_id = 0; 180 result->device_android_id = 0;
207 result->device_security_token = 0; 181 result->device_security_token = 0;
208 result->registrations.clear(); 182 result->registrations.clear();
209 result->incoming_messages.clear(); 183 result->incoming_messages.clear();
210 result->outgoing_messages.clear(); 184 result->outgoing_messages.clear();
211 result->gservices_settings.clear();
212 result->gservices_digest.clear();
213 result->last_checkin_time = base::Time::FromInternalValue(0LL); 185 result->last_checkin_time = base::Time::FromInternalValue(0LL);
214 foreground_task_runner_->PostTask(FROM_HERE, 186 foreground_task_runner_->PostTask(FROM_HERE,
215 base::Bind(callback, 187 base::Bind(callback,
216 base::Passed(&result))); 188 base::Passed(&result)));
217 return; 189 return;
218 } 190 }
219 191
220 // Only record histograms if GCM had already been set up for this device. 192 // Only record histograms if GCM had already been set up for this device.
221 if (result->device_android_id != 0 && result->device_security_token != 0) { 193 if (result->device_android_id != 0 && result->device_security_token != 0) {
222 int64 file_size = 0; 194 int64 file_size = 0;
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 write_options.sync = true; 458 write_options.sync = true;
487 459
488 int64 last_checkin_time_internal = last_checkin_time.ToInternalValue(); 460 int64 last_checkin_time_internal = last_checkin_time.ToInternalValue();
489 const leveldb::Status s = 461 const leveldb::Status s =
490 db_->Put(write_options, 462 db_->Put(write_options,
491 MakeSlice(kLastCheckinTimeKey), 463 MakeSlice(kLastCheckinTimeKey),
492 MakeSlice(base::Int64ToString(last_checkin_time_internal))); 464 MakeSlice(base::Int64ToString(last_checkin_time_internal)));
493 465
494 if (!s.ok()) 466 if (!s.ok())
495 LOG(ERROR) << "LevelDB set last checkin time failed: " << s.ToString(); 467 LOG(ERROR) << "LevelDB set last checkin time failed: " << s.ToString();
468
496 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, s.ok())); 469 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, s.ok()));
497 } 470 }
498 471
499 void GCMStoreImpl::Backend::SetGServicesSettings(
500 const std::map<std::string, std::string>& settings,
501 const std::string& settings_digest,
502 const UpdateCallback& callback) {
503 leveldb::WriteBatch write_batch;
504
505 // Remove all existing settings.
506 leveldb::ReadOptions read_options;
507 read_options.verify_checksums = true;
508 scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(read_options));
509 for (iter->Seek(MakeSlice(kGServiceSettingKeyStart));
510 iter->Valid() && iter->key().ToString() < kGServiceSettingKeyEnd;
511 iter->Next()) {
512 write_batch.Delete(iter->key());
513 }
514
515 // Add the new settings.
516 for (std::map<std::string, std::string>::const_iterator iter =
517 settings.begin();
518 iter != settings.end(); ++iter) {
519 write_batch.Put(MakeSlice(MakeGServiceSettingKey(iter->first)),
520 MakeSlice(iter->second));
521 }
522
523 // Update the settings digest.
524 write_batch.Put(MakeSlice(kGServiceSettingsDigestKey),
525 MakeSlice(settings_digest));
526
527 // Write it all in a batch.
528 leveldb::WriteOptions write_options;
529 write_options.sync = true;
530
531 leveldb::Status s = db_->Write(write_options, &write_batch);
532 if (!s.ok())
533 LOG(ERROR) << "LevelDB GService Settings update failed: " << s.ToString();
534 foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, s.ok()));
535 }
536
537 bool GCMStoreImpl::Backend::LoadDeviceCredentials(uint64* android_id, 472 bool GCMStoreImpl::Backend::LoadDeviceCredentials(uint64* android_id,
538 uint64* security_token) { 473 uint64* security_token) {
539 leveldb::ReadOptions read_options; 474 leveldb::ReadOptions read_options;
540 read_options.verify_checksums = true; 475 read_options.verify_checksums = true;
541 476
542 std::string result; 477 std::string result;
543 leveldb::Status s = db_->Get(read_options, MakeSlice(kDeviceAIDKey), &result); 478 leveldb::Status s = db_->Get(read_options, MakeSlice(kDeviceAIDKey), &result);
544 if (s.ok()) { 479 if (s.ok()) {
545 if (!base::StringToUint64(result, android_id)) { 480 if (!base::StringToUint64(result, android_id)) {
546 LOG(ERROR) << "Failed to restore device id."; 481 LOG(ERROR) << "Failed to restore device id.";
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
662 if (s.ok() && !base::StringToInt64(result, &time_internal)) 597 if (s.ok() && !base::StringToInt64(result, &time_internal))
663 LOG(ERROR) << "Failed to restore last checkin time. Using default = 0."; 598 LOG(ERROR) << "Failed to restore last checkin time. Using default = 0.";
664 599
665 // In case we cannot read last checkin time, we default it to 0, as we don't 600 // In case we cannot read last checkin time, we default it to 0, as we don't
666 // want that situation to cause the whole load to fail. 601 // want that situation to cause the whole load to fail.
667 *last_checkin_time = base::Time::FromInternalValue(time_internal); 602 *last_checkin_time = base::Time::FromInternalValue(time_internal);
668 603
669 return true; 604 return true;
670 } 605 }
671 606
672 bool GCMStoreImpl::Backend::LoadGServicesSettings(
673 std::map<std::string, std::string>* settings,
674 std::string* digest) {
675 leveldb::ReadOptions read_options;
676 read_options.verify_checksums = true;
677
678 // Load all of the GServices settings.
679 scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(read_options));
680 for (iter->Seek(MakeSlice(kGServiceSettingKeyStart));
681 iter->Valid() && iter->key().ToString() < kGServiceSettingKeyEnd;
682 iter->Next()) {
683 std::string value = iter->value().ToString();
684 if (value.empty()) {
685 LOG(ERROR) << "Error reading GService Settings " << value;
686 return false;
687 }
688 std::string id = ParseGServiceSettingKey(iter->key().ToString());
689 (*settings)[id] = value;
690 DVLOG(1) << "Found G Service setting with key: " << id
691 << ", and value: " << value;
692 }
693
694 // Load the settings digest. It's ok if it is empty.
695 db_->Get(read_options, MakeSlice(kGServiceSettingsDigestKey), digest);
696
697 return true;
698 }
699
700 GCMStoreImpl::GCMStoreImpl( 607 GCMStoreImpl::GCMStoreImpl(
701 bool use_mock_keychain, 608 bool use_mock_keychain,
702 const base::FilePath& path, 609 const base::FilePath& path,
703 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) 610 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner)
704 : backend_(new Backend(path, base::MessageLoopProxy::current())), 611 : backend_(new Backend(path, base::MessageLoopProxy::current())),
705 blocking_task_runner_(blocking_task_runner), 612 blocking_task_runner_(blocking_task_runner),
706 weak_ptr_factory_(this) { 613 weak_ptr_factory_(this) {
707 // On OSX, prevent the Keychain permissions popup during unit tests. 614 // On OSX, prevent the Keychain permissions popup during unit tests.
708 #if defined(OS_MACOSX) 615 #if defined(OS_MACOSX)
709 OSCrypt::UseMockKeychain(use_mock_keychain); 616 OSCrypt::UseMockKeychain(use_mock_keychain);
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
874 void GCMStoreImpl::SetLastCheckinTime(const base::Time& last_checkin_time, 781 void GCMStoreImpl::SetLastCheckinTime(const base::Time& last_checkin_time,
875 const UpdateCallback& callback) { 782 const UpdateCallback& callback) {
876 blocking_task_runner_->PostTask( 783 blocking_task_runner_->PostTask(
877 FROM_HERE, 784 FROM_HERE,
878 base::Bind(&GCMStoreImpl::Backend::SetLastCheckinTime, 785 base::Bind(&GCMStoreImpl::Backend::SetLastCheckinTime,
879 backend_, 786 backend_,
880 last_checkin_time, 787 last_checkin_time,
881 callback)); 788 callback));
882 } 789 }
883 790
884 void GCMStoreImpl::SetGServicesSettings(
885 const std::map<std::string, std::string>& settings,
886 const std::string& digest,
887 const UpdateCallback& callback) {
888 blocking_task_runner_->PostTask(
889 FROM_HERE,
890 base::Bind(&GCMStoreImpl::Backend::SetGServicesSettings,
891 backend_,
892 settings,
893 digest,
894 callback));
895 }
896
897 void GCMStoreImpl::LoadContinuation(const LoadCallback& callback, 791 void GCMStoreImpl::LoadContinuation(const LoadCallback& callback,
898 scoped_ptr<LoadResult> result) { 792 scoped_ptr<LoadResult> result) {
899 if (!result->success) { 793 if (!result->success) {
900 callback.Run(result.Pass()); 794 callback.Run(result.Pass());
901 return; 795 return;
902 } 796 }
903 int num_throttled_apps = 0; 797 int num_throttled_apps = 0;
904 for (OutgoingMessageMap::const_iterator 798 for (OutgoingMessageMap::const_iterator
905 iter = result->outgoing_messages.begin(); 799 iter = result->outgoing_messages.begin();
906 iter != result->outgoing_messages.end(); ++iter) { 800 iter != result->outgoing_messages.end(); ++iter) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
941 removed_message_counts.begin(); 835 removed_message_counts.begin();
942 iter != removed_message_counts.end(); ++iter) { 836 iter != removed_message_counts.end(); ++iter) {
943 DCHECK_NE(app_message_counts_.count(iter->first), 0U); 837 DCHECK_NE(app_message_counts_.count(iter->first), 0U);
944 app_message_counts_[iter->first] -= iter->second; 838 app_message_counts_[iter->first] -= iter->second;
945 DCHECK_GE(app_message_counts_[iter->first], 0); 839 DCHECK_GE(app_message_counts_[iter->first], 0);
946 } 840 }
947 callback.Run(true); 841 callback.Run(true);
948 } 842 }
949 843
950 } // namespace gcm 844 } // namespace gcm
OLDNEW
« no previous file with comments | « google_apis/gcm/engine/gcm_store_impl.h ('k') | google_apis/gcm/engine/gcm_store_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698