| OLD | NEW | 
|---|
| 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" | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
| 28 namespace { | 28 namespace { | 
| 29 | 29 | 
| 30 // Limit to the number of outstanding messages per app. | 30 // Limit to the number of outstanding messages per app. | 
| 31 const int kMessagesPerAppLimit = 20; | 31 const int kMessagesPerAppLimit = 20; | 
| 32 | 32 | 
| 33 // ---- LevelDB keys. ---- | 33 // ---- LevelDB keys. ---- | 
| 34 // Key for this device's android id. | 34 // Key for this device's android id. | 
| 35 const char kDeviceAIDKey[] = "device_aid_key"; | 35 const char kDeviceAIDKey[] = "device_aid_key"; | 
| 36 // Key for this device's android security token. | 36 // Key for this device's android security token. | 
| 37 const char kDeviceTokenKey[] = "device_token_key"; | 37 const char kDeviceTokenKey[] = "device_token_key"; | 
|  | 38 // Lowest lexicographically ordered app ids. | 
|  | 39 // Used for prefixing app id. | 
|  | 40 const char kRegistrationKeyStart[] = "reg1-"; | 
|  | 41 // Key guaranteed to be higher than all app ids. | 
|  | 42 // Used for limiting iteration. | 
|  | 43 const char kRegistrationKeyEnd[] = "reg2-"; | 
| 38 // Lowest lexicographically ordered incoming message key. | 44 // Lowest lexicographically ordered incoming message key. | 
| 39 // Used for prefixing messages. | 45 // Used for prefixing messages. | 
| 40 const char kIncomingMsgKeyStart[] = "incoming1-"; | 46 const char kIncomingMsgKeyStart[] = "incoming1-"; | 
| 41 // Key guaranteed to be higher than all incoming message keys. | 47 // Key guaranteed to be higher than all incoming message keys. | 
| 42 // Used for limiting iteration. | 48 // Used for limiting iteration. | 
| 43 const char kIncomingMsgKeyEnd[] = "incoming2-"; | 49 const char kIncomingMsgKeyEnd[] = "incoming2-"; | 
| 44 // Key for next serial number assigned to the user. |  | 
| 45 const char kNextSerialNumberKey[] = "next_serial_number_key"; |  | 
| 46 // Lowest lexicographically ordered outgoing message key. | 50 // Lowest lexicographically ordered outgoing message key. | 
| 47 // Used for prefixing outgoing messages. | 51 // Used for prefixing outgoing messages. | 
| 48 const char kOutgoingMsgKeyStart[] = "outgoing1-"; | 52 const char kOutgoingMsgKeyStart[] = "outgoing1-"; | 
| 49 // Key guaranteed to be higher than all outgoing message keys. | 53 // Key guaranteed to be higher than all outgoing message keys. | 
| 50 // Used for limiting iteration. | 54 // Used for limiting iteration. | 
| 51 const char kOutgoingMsgKeyEnd[] = "outgoing2-"; | 55 const char kOutgoingMsgKeyEnd[] = "outgoing2-"; | 
| 52 // Lowest lexicographically ordered username. |  | 
| 53 // Used for prefixing username to serial number mappings. |  | 
| 54 const char kUserSerialNumberKeyStart[] = "user1-"; |  | 
| 55 // Key guaranteed to be higher than all usernames. |  | 
| 56 // Used for limiting iteration. |  | 
| 57 const char kUserSerialNumberKeyEnd[] = "user2-"; |  | 
| 58 | 56 | 
| 59 // Value indicating that serial number was not assigned. | 57 std::string MakeRegistrationKey(const std::string& app_id) { | 
| 60 const int64 kSerialNumberMissing = -1LL; | 58   return kRegistrationKeyStart + app_id; | 
|  | 59 } | 
|  | 60 | 
|  | 61 std::string ParseRegistrationKey(const std::string& key) { | 
|  | 62   return key.substr(arraysize(kRegistrationKeyStart) - 1); | 
|  | 63 } | 
| 61 | 64 | 
| 62 std::string MakeIncomingKey(const std::string& persistent_id) { | 65 std::string MakeIncomingKey(const std::string& persistent_id) { | 
| 63   return kIncomingMsgKeyStart + persistent_id; | 66   return kIncomingMsgKeyStart + persistent_id; | 
| 64 } | 67 } | 
| 65 | 68 | 
| 66 std::string MakeOutgoingKey(const std::string& persistent_id) { | 69 std::string MakeOutgoingKey(const std::string& persistent_id) { | 
| 67   return kOutgoingMsgKeyStart + persistent_id; | 70   return kOutgoingMsgKeyStart + persistent_id; | 
| 68 } | 71 } | 
| 69 | 72 | 
| 70 std::string MakeUserSerialNumberKey(const std::string& username) { |  | 
| 71   return kUserSerialNumberKeyStart + username; |  | 
| 72 } |  | 
| 73 |  | 
| 74 std::string ParseOutgoingKey(const std::string& key) { | 73 std::string ParseOutgoingKey(const std::string& key) { | 
| 75   return key.substr(arraysize(kOutgoingMsgKeyStart) - 1); | 74   return key.substr(arraysize(kOutgoingMsgKeyStart) - 1); | 
| 76 } | 75 } | 
| 77 | 76 | 
| 78 std::string ParseUsername(const std::string& key) { |  | 
| 79   return key.substr(arraysize(kUserSerialNumberKeyStart) - 1); |  | 
| 80 } |  | 
| 81 |  | 
| 82 // Note: leveldb::Slice keeps a pointer to the data in |s|, which must therefore | 77 // Note: leveldb::Slice keeps a pointer to the data in |s|, which must therefore | 
| 83 // outlive the slice. | 78 // outlive the slice. | 
| 84 // For example: MakeSlice(MakeOutgoingKey(x)) is invalid. | 79 // For example: MakeSlice(MakeOutgoingKey(x)) is invalid. | 
| 85 leveldb::Slice MakeSlice(const base::StringPiece& s) { | 80 leveldb::Slice MakeSlice(const base::StringPiece& s) { | 
| 86   return leveldb::Slice(s.begin(), s.size()); | 81   return leveldb::Slice(s.begin(), s.size()); | 
| 87 } | 82 } | 
| 88 | 83 | 
| 89 }  // namespace | 84 }  // namespace | 
| 90 | 85 | 
| 91 class GCMStoreImpl::Backend | 86 class GCMStoreImpl::Backend | 
| 92     : public base::RefCountedThreadSafe<GCMStoreImpl::Backend> { | 87     : public base::RefCountedThreadSafe<GCMStoreImpl::Backend> { | 
| 93  public: | 88  public: | 
| 94   Backend(const base::FilePath& path, | 89   Backend(const base::FilePath& path, | 
| 95           scoped_refptr<base::SequencedTaskRunner> foreground_runner); | 90           scoped_refptr<base::SequencedTaskRunner> foreground_runner); | 
| 96 | 91 | 
| 97   // Blocking implementations of GCMStoreImpl methods. | 92   // Blocking implementations of GCMStoreImpl methods. | 
| 98   void Load(const LoadCallback& callback); | 93   void Load(const LoadCallback& callback); | 
| 99   void Close(); | 94   void Close(); | 
| 100   void Destroy(const UpdateCallback& callback); | 95   void Destroy(const UpdateCallback& callback); | 
| 101   void SetDeviceCredentials(uint64 device_android_id, | 96   void SetDeviceCredentials(uint64 device_android_id, | 
| 102                             uint64 device_security_token, | 97                             uint64 device_security_token, | 
| 103                             const UpdateCallback& callback); | 98                             const UpdateCallback& callback); | 
|  | 99   void AddRegistration(const std::string& app_id, | 
|  | 100                        const linked_ptr<RegistrationInfo>& registration, | 
|  | 101                        const UpdateCallback& callback); | 
|  | 102   void RemoveRegistration(const std::string& app_id, | 
|  | 103                           const UpdateCallback& callback); | 
| 104   void AddIncomingMessage(const std::string& persistent_id, | 104   void AddIncomingMessage(const std::string& persistent_id, | 
| 105                           const UpdateCallback& callback); | 105                           const UpdateCallback& callback); | 
| 106   void RemoveIncomingMessages(const PersistentIdList& persistent_ids, | 106   void RemoveIncomingMessages(const PersistentIdList& persistent_ids, | 
| 107                               const UpdateCallback& callback); | 107                               const UpdateCallback& callback); | 
| 108   void AddOutgoingMessage(const std::string& persistent_id, | 108   void AddOutgoingMessage(const std::string& persistent_id, | 
| 109                           const MCSMessage& message, | 109                           const MCSMessage& message, | 
| 110                           const UpdateCallback& callback); | 110                           const UpdateCallback& callback); | 
| 111   void RemoveOutgoingMessages( | 111   void RemoveOutgoingMessages( | 
| 112       const PersistentIdList& persistent_ids, | 112       const PersistentIdList& persistent_ids, | 
| 113       const base::Callback<void(bool, const AppIdToMessageCountMap&)> | 113       const base::Callback<void(bool, const AppIdToMessageCountMap&)> | 
| 114           callback); | 114           callback); | 
| 115   void AddUserSerialNumber(const std::string& username, | 115   void AddUserSerialNumber(const std::string& username, | 
| 116                            int64 serial_number, | 116                            int64 serial_number, | 
| 117                            const UpdateCallback& callback); | 117                            const UpdateCallback& callback); | 
| 118   void RemoveUserSerialNumber(const std::string& username, | 118   void RemoveUserSerialNumber(const std::string& username, | 
| 119                               const UpdateCallback& callback); | 119                               const UpdateCallback& callback); | 
| 120   void SetNextSerialNumber(int64 serial_number, const UpdateCallback& callback); | 120   void SetNextSerialNumber(int64 serial_number, const UpdateCallback& callback); | 
| 121 | 121 | 
| 122  private: | 122  private: | 
| 123   friend class base::RefCountedThreadSafe<Backend>; | 123   friend class base::RefCountedThreadSafe<Backend>; | 
| 124   ~Backend(); | 124   ~Backend(); | 
| 125 | 125 | 
| 126   bool LoadDeviceCredentials(uint64* android_id, uint64* security_token); | 126   bool LoadDeviceCredentials(uint64* android_id, uint64* security_token); | 
|  | 127   bool LoadRegistrations(RegistrationInfoMap* registrations); | 
| 127   bool LoadIncomingMessages(std::vector<std::string>* incoming_messages); | 128   bool LoadIncomingMessages(std::vector<std::string>* incoming_messages); | 
| 128   bool LoadOutgoingMessages(OutgoingMessageMap* outgoing_messages); | 129   bool LoadOutgoingMessages(OutgoingMessageMap* outgoing_messages); | 
| 129   bool LoadNextSerialNumber(int64* next_serial_number); |  | 
| 130   bool LoadUserSerialNumberMap( |  | 
| 131       std::map<std::string, int64>* user_serial_number_map); |  | 
| 132 | 130 | 
| 133   const base::FilePath path_; | 131   const base::FilePath path_; | 
| 134   scoped_refptr<base::SequencedTaskRunner> foreground_task_runner_; | 132   scoped_refptr<base::SequencedTaskRunner> foreground_task_runner_; | 
| 135 | 133 | 
| 136   scoped_ptr<leveldb::DB> db_; | 134   scoped_ptr<leveldb::DB> db_; | 
| 137 }; | 135 }; | 
| 138 | 136 | 
| 139 GCMStoreImpl::Backend::Backend( | 137 GCMStoreImpl::Backend::Backend( | 
| 140     const base::FilePath& path, | 138     const base::FilePath& path, | 
| 141     scoped_refptr<base::SequencedTaskRunner> foreground_task_runner) | 139     scoped_refptr<base::SequencedTaskRunner> foreground_task_runner) | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
| 164                << status.ToString(); | 162                << status.ToString(); | 
| 165     foreground_task_runner_->PostTask(FROM_HERE, | 163     foreground_task_runner_->PostTask(FROM_HERE, | 
| 166                                       base::Bind(callback, | 164                                       base::Bind(callback, | 
| 167                                                  base::Passed(&result))); | 165                                                  base::Passed(&result))); | 
| 168     return; | 166     return; | 
| 169   } | 167   } | 
| 170   db_.reset(db); | 168   db_.reset(db); | 
| 171 | 169 | 
| 172   if (!LoadDeviceCredentials(&result->device_android_id, | 170   if (!LoadDeviceCredentials(&result->device_android_id, | 
| 173                              &result->device_security_token) || | 171                              &result->device_security_token) || | 
|  | 172       !LoadRegistrations(&result->registrations) || | 
| 174       !LoadIncomingMessages(&result->incoming_messages) || | 173       !LoadIncomingMessages(&result->incoming_messages) || | 
| 175       !LoadOutgoingMessages(&result->outgoing_messages) || | 174       !LoadOutgoingMessages(&result->outgoing_messages)) { | 
| 176       !LoadNextSerialNumber( |  | 
| 177            &result->serial_number_mappings.next_serial_number) || |  | 
| 178       !LoadUserSerialNumberMap( |  | 
| 179            &result->serial_number_mappings.user_serial_numbers)) { |  | 
| 180     result->device_android_id = 0; | 175     result->device_android_id = 0; | 
| 181     result->device_security_token = 0; | 176     result->device_security_token = 0; | 
|  | 177     result->registrations.clear(); | 
| 182     result->incoming_messages.clear(); | 178     result->incoming_messages.clear(); | 
| 183     result->outgoing_messages.clear(); | 179     result->outgoing_messages.clear(); | 
| 184     foreground_task_runner_->PostTask(FROM_HERE, | 180     foreground_task_runner_->PostTask(FROM_HERE, | 
| 185                                       base::Bind(callback, | 181                                       base::Bind(callback, | 
| 186                                                  base::Passed(&result))); | 182                                                  base::Passed(&result))); | 
| 187     return; | 183     return; | 
| 188   } | 184   } | 
| 189 | 185 | 
| 190   // Only record histograms if GCM had already been set up for this device. | 186   // Only record histograms if GCM had already been set up for this device. | 
| 191   if (result->device_android_id != 0 && result->device_security_token != 0) { | 187   if (result->device_android_id != 0 && result->device_security_token != 0) { | 
| 192     int64 file_size = 0; | 188     int64 file_size = 0; | 
| 193     if (base::GetFileSize(path_, &file_size)) { | 189     if (base::GetFileSize(path_, &file_size)) { | 
| 194       UMA_HISTOGRAM_COUNTS("GCM.StoreSizeKB", | 190       UMA_HISTOGRAM_COUNTS("GCM.StoreSizeKB", | 
| 195                            static_cast<int>(file_size / 1024)); | 191                            static_cast<int>(file_size / 1024)); | 
| 196     } | 192     } | 
|  | 193     UMA_HISTOGRAM_COUNTS("GCM.RestoredRegistrations", | 
|  | 194                          result->registrations.size()); | 
| 197     UMA_HISTOGRAM_COUNTS("GCM.RestoredOutgoingMessages", | 195     UMA_HISTOGRAM_COUNTS("GCM.RestoredOutgoingMessages", | 
| 198                          result->outgoing_messages.size()); | 196                          result->outgoing_messages.size()); | 
| 199     UMA_HISTOGRAM_COUNTS("GCM.RestoredIncomingMessages", | 197     UMA_HISTOGRAM_COUNTS("GCM.RestoredIncomingMessages", | 
| 200                          result->incoming_messages.size()); | 198                          result->incoming_messages.size()); | 
| 201     UMA_HISTOGRAM_COUNTS( |  | 
| 202         "GCM.NumUsers", |  | 
| 203         result->serial_number_mappings.user_serial_numbers.size()); |  | 
| 204   } | 199   } | 
| 205 | 200 | 
| 206   DVLOG(1) << "Succeeded in loading " << result->incoming_messages.size() | 201   DVLOG(1) << "Succeeded in loading " << result->registrations.size() | 
|  | 202            << " registrations, " | 
|  | 203            << result->incoming_messages.size() | 
| 207            << " unacknowledged incoming messages and " | 204            << " unacknowledged incoming messages and " | 
| 208            << result->outgoing_messages.size() | 205            << result->outgoing_messages.size() | 
| 209            << " unacknowledged outgoing messages."; | 206            << " unacknowledged outgoing messages."; | 
| 210   result->success = true; | 207   result->success = true; | 
| 211   foreground_task_runner_->PostTask(FROM_HERE, | 208   foreground_task_runner_->PostTask(FROM_HERE, | 
| 212                                     base::Bind(callback, | 209                                     base::Bind(callback, | 
| 213                                                base::Passed(&result))); | 210                                                base::Passed(&result))); | 
| 214   return; | 211   return; | 
| 215 } | 212 } | 
| 216 | 213 | 
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 259         write_options, MakeSlice(kDeviceTokenKey), MakeSlice(encrypted_token)); | 256         write_options, MakeSlice(kDeviceTokenKey), MakeSlice(encrypted_token)); | 
| 260   } | 257   } | 
| 261   if (s.ok()) { | 258   if (s.ok()) { | 
| 262     foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, true)); | 259     foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, true)); | 
| 263     return; | 260     return; | 
| 264   } | 261   } | 
| 265   LOG(ERROR) << "LevelDB put failed: " << s.ToString(); | 262   LOG(ERROR) << "LevelDB put failed: " << s.ToString(); | 
| 266   foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); | 263   foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); | 
| 267 } | 264 } | 
| 268 | 265 | 
|  | 266 void GCMStoreImpl::Backend::AddRegistration( | 
|  | 267     const std::string& app_id, | 
|  | 268     const linked_ptr<RegistrationInfo>& registration, | 
|  | 269     const UpdateCallback& callback) { | 
|  | 270   DVLOG(1) << "Saving registration info for app: " << app_id; | 
|  | 271   if (!db_.get()) { | 
|  | 272     LOG(ERROR) << "GCMStore db doesn't exist."; | 
|  | 273     foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); | 
|  | 274     return; | 
|  | 275   } | 
|  | 276   leveldb::WriteOptions write_options; | 
|  | 277   write_options.sync = true; | 
|  | 278 | 
|  | 279   std::string key = MakeRegistrationKey(app_id); | 
|  | 280   std::string value = registration->SerializeAsString(); | 
|  | 281   const leveldb::Status status = db_->Put(write_options, | 
|  | 282                                           MakeSlice(key), | 
|  | 283                                           MakeSlice(value)); | 
|  | 284   if (status.ok()) { | 
|  | 285     foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, true)); | 
|  | 286     return; | 
|  | 287   } | 
|  | 288   LOG(ERROR) << "LevelDB put failed: " << status.ToString(); | 
|  | 289   foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); | 
|  | 290 } | 
|  | 291 | 
|  | 292 void GCMStoreImpl::Backend::RemoveRegistration(const std::string& app_id, | 
|  | 293                                                const UpdateCallback& callback) { | 
|  | 294   if (!db_.get()) { | 
|  | 295     LOG(ERROR) << "GCMStore db doesn't exist."; | 
|  | 296     foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); | 
|  | 297     return; | 
|  | 298   } | 
|  | 299   leveldb::WriteOptions write_options; | 
|  | 300   write_options.sync = true; | 
|  | 301 | 
|  | 302   leveldb::Status status = db_->Delete(write_options, MakeSlice(app_id)); | 
|  | 303   if (status.ok()) { | 
|  | 304     foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, true)); | 
|  | 305     return; | 
|  | 306   } | 
|  | 307   LOG(ERROR) << "LevelDB remove failed: " << status.ToString(); | 
|  | 308   foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); | 
|  | 309 } | 
|  | 310 | 
| 269 void GCMStoreImpl::Backend::AddIncomingMessage(const std::string& persistent_id, | 311 void GCMStoreImpl::Backend::AddIncomingMessage(const std::string& persistent_id, | 
| 270                                                const UpdateCallback& callback) { | 312                                                const UpdateCallback& callback) { | 
| 271   DVLOG(1) << "Saving incoming message with id " << persistent_id; | 313   DVLOG(1) << "Saving incoming message with id " << persistent_id; | 
| 272   if (!db_.get()) { | 314   if (!db_.get()) { | 
| 273     LOG(ERROR) << "GCMStore db doesn't exist."; | 315     LOG(ERROR) << "GCMStore db doesn't exist."; | 
| 274     foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); | 316     foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); | 
| 275     return; | 317     return; | 
| 276   } | 318   } | 
| 277 | 319 | 
| 278   leveldb::WriteOptions write_options; | 320   leveldb::WriteOptions write_options; | 
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 396                                                  removed_message_counts)); | 438                                                  removed_message_counts)); | 
| 397     return; | 439     return; | 
| 398   } | 440   } | 
| 399   LOG(ERROR) << "LevelDB remove failed: " << s.ToString(); | 441   LOG(ERROR) << "LevelDB remove failed: " << s.ToString(); | 
| 400   foreground_task_runner_->PostTask(FROM_HERE, | 442   foreground_task_runner_->PostTask(FROM_HERE, | 
| 401                                     base::Bind(callback, | 443                                     base::Bind(callback, | 
| 402                                                false, | 444                                                false, | 
| 403                                                AppIdToMessageCountMap())); | 445                                                AppIdToMessageCountMap())); | 
| 404 } | 446 } | 
| 405 | 447 | 
| 406 void GCMStoreImpl::Backend::AddUserSerialNumber( |  | 
| 407     const std::string& username, |  | 
| 408     int64 serial_number, |  | 
| 409     const UpdateCallback& callback) { |  | 
| 410   DVLOG(1) << "Saving username to serial number mapping for user: " << username; |  | 
| 411   if (!db_.get()) { |  | 
| 412     LOG(ERROR) << "GCMStore db doesn't exist."; |  | 
| 413     foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); |  | 
| 414     return; |  | 
| 415   } |  | 
| 416   leveldb::WriteOptions write_options; |  | 
| 417   write_options.sync = true; |  | 
| 418 |  | 
| 419   std::string key = MakeUserSerialNumberKey(username); |  | 
| 420   std::string serial_number_str = base::Int64ToString(serial_number); |  | 
| 421   const leveldb::Status status = |  | 
| 422       db_->Put(write_options, |  | 
| 423                MakeSlice(key), |  | 
| 424                MakeSlice(serial_number_str)); |  | 
| 425   if (status.ok()) { |  | 
| 426     foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, true)); |  | 
| 427     return; |  | 
| 428   } |  | 
| 429   LOG(ERROR) << "LevelDB put failed: " << status.ToString(); |  | 
| 430   foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); |  | 
| 431 } |  | 
| 432 |  | 
| 433 void GCMStoreImpl::Backend::RemoveUserSerialNumber( |  | 
| 434     const std::string& username, |  | 
| 435     const UpdateCallback& callback) { |  | 
| 436   if (!db_.get()) { |  | 
| 437     LOG(ERROR) << "GCMStore db doesn't exist."; |  | 
| 438     foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); |  | 
| 439     return; |  | 
| 440   } |  | 
| 441   leveldb::WriteOptions write_options; |  | 
| 442   write_options.sync = true; |  | 
| 443 |  | 
| 444   leveldb::Status status = db_->Delete(write_options, MakeSlice(username)); |  | 
| 445   if (status.ok()) { |  | 
| 446     foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, true)); |  | 
| 447     return; |  | 
| 448   } |  | 
| 449   LOG(ERROR) << "LevelDB remove failed: " << status.ToString(); |  | 
| 450   foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); |  | 
| 451 } |  | 
| 452 |  | 
| 453 void GCMStoreImpl::Backend::SetNextSerialNumber( |  | 
| 454     int64 next_serial_number, |  | 
| 455     const UpdateCallback& callback) { |  | 
| 456   DVLOG(1) << "Updating the value of next user serial number to: " |  | 
| 457            << next_serial_number; |  | 
| 458   if (!db_.get()) { |  | 
| 459     LOG(ERROR) << "GCMStore db doesn't exist."; |  | 
| 460     foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); |  | 
| 461     return; |  | 
| 462   } |  | 
| 463   leveldb::WriteOptions write_options; |  | 
| 464   write_options.sync = true; |  | 
| 465 |  | 
| 466   std::string serial_number_str = base::Int64ToString(next_serial_number); |  | 
| 467   const leveldb::Status status = |  | 
| 468       db_->Put(write_options, |  | 
| 469                MakeSlice(kNextSerialNumberKey), |  | 
| 470                MakeSlice(serial_number_str)); |  | 
| 471   if (status.ok()) { |  | 
| 472     foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, true)); |  | 
| 473     return; |  | 
| 474   } |  | 
| 475   LOG(ERROR) << "LevelDB put failed: " << status.ToString(); |  | 
| 476   foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); |  | 
| 477 } |  | 
| 478 |  | 
| 479 bool GCMStoreImpl::Backend::LoadDeviceCredentials(uint64* android_id, | 448 bool GCMStoreImpl::Backend::LoadDeviceCredentials(uint64* android_id, | 
| 480                                                   uint64* security_token) { | 449                                                   uint64* security_token) { | 
| 481   leveldb::ReadOptions read_options; | 450   leveldb::ReadOptions read_options; | 
| 482   read_options.verify_checksums = true; | 451   read_options.verify_checksums = true; | 
| 483 | 452 | 
| 484   std::string result; | 453   std::string result; | 
| 485   leveldb::Status s = db_->Get(read_options, MakeSlice(kDeviceAIDKey), &result); | 454   leveldb::Status s = db_->Get(read_options, MakeSlice(kDeviceAIDKey), &result); | 
| 486   if (s.ok()) { | 455   if (s.ok()) { | 
| 487     if (!base::StringToUint64(result, android_id)) { | 456     if (!base::StringToUint64(result, android_id)) { | 
| 488       LOG(ERROR) << "Failed to restore device id."; | 457       LOG(ERROR) << "Failed to restore device id."; | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 503 | 472 | 
| 504   if (s.IsNotFound()) { | 473   if (s.IsNotFound()) { | 
| 505     DVLOG(1) << "No credentials found."; | 474     DVLOG(1) << "No credentials found."; | 
| 506     return true; | 475     return true; | 
| 507   } | 476   } | 
| 508 | 477 | 
| 509   LOG(ERROR) << "Error reading credentials from store."; | 478   LOG(ERROR) << "Error reading credentials from store."; | 
| 510   return false; | 479   return false; | 
| 511 } | 480 } | 
| 512 | 481 | 
|  | 482 bool GCMStoreImpl::Backend::LoadRegistrations( | 
|  | 483     RegistrationInfoMap* registrations) { | 
|  | 484   leveldb::ReadOptions read_options; | 
|  | 485   read_options.verify_checksums = true; | 
|  | 486 | 
|  | 487   scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(read_options)); | 
|  | 488   for (iter->Seek(MakeSlice(kRegistrationKeyStart)); | 
|  | 489        iter->Valid() && iter->key().ToString() < kRegistrationKeyEnd; | 
|  | 490        iter->Next()) { | 
|  | 491     leveldb::Slice s = iter->value(); | 
|  | 492     if (s.size() <= 1) { | 
|  | 493       LOG(ERROR) << "Error reading registration with key " << s.ToString(); | 
|  | 494       return false; | 
|  | 495     } | 
|  | 496     std::string app_id = ParseRegistrationKey(iter->key().ToString()); | 
|  | 497     linked_ptr<RegistrationInfo> registration(new RegistrationInfo); | 
|  | 498     if (!registration->ParseFromString(iter->value().ToString())) { | 
|  | 499       LOG(ERROR) << "Failed to parse registration with app id " << app_id; | 
|  | 500       return false; | 
|  | 501     } | 
|  | 502     DVLOG(1) << "Found registration with app id " << app_id; | 
|  | 503     (*registrations)[app_id] = registration; | 
|  | 504   } | 
|  | 505 | 
|  | 506   return true; | 
|  | 507 } | 
|  | 508 | 
| 513 bool GCMStoreImpl::Backend::LoadIncomingMessages( | 509 bool GCMStoreImpl::Backend::LoadIncomingMessages( | 
| 514     std::vector<std::string>* incoming_messages) { | 510     std::vector<std::string>* incoming_messages) { | 
| 515   leveldb::ReadOptions read_options; | 511   leveldb::ReadOptions read_options; | 
| 516   read_options.verify_checksums = true; | 512   read_options.verify_checksums = true; | 
| 517 | 513 | 
| 518   scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(read_options)); | 514   scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(read_options)); | 
| 519   for (iter->Seek(MakeSlice(kIncomingMsgKeyStart)); | 515   for (iter->Seek(MakeSlice(kIncomingMsgKeyStart)); | 
| 520        iter->Valid() && iter->key().ToString() < kIncomingMsgKeyEnd; | 516        iter->Valid() && iter->key().ToString() < kIncomingMsgKeyEnd; | 
| 521        iter->Next()) { | 517        iter->Next()) { | 
| 522     leveldb::Slice s = iter->value(); | 518     leveldb::Slice s = iter->value(); | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 557       return false; | 553       return false; | 
| 558     } | 554     } | 
| 559     DVLOG(1) << "Found outgoing message with id " << id << " of type " | 555     DVLOG(1) << "Found outgoing message with id " << id << " of type " | 
| 560              << base::IntToString(tag); | 556              << base::IntToString(tag); | 
| 561     (*outgoing_messages)[id] = make_linked_ptr(message.release()); | 557     (*outgoing_messages)[id] = make_linked_ptr(message.release()); | 
| 562   } | 558   } | 
| 563 | 559 | 
| 564   return true; | 560   return true; | 
| 565 } | 561 } | 
| 566 | 562 | 
| 567 bool GCMStoreImpl::Backend::LoadNextSerialNumber(int64* next_serial_number) { |  | 
| 568   leveldb::ReadOptions read_options; |  | 
| 569   read_options.verify_checksums = true; |  | 
| 570 |  | 
| 571   std::string result; |  | 
| 572   leveldb::Status status = |  | 
| 573       db_->Get(read_options, MakeSlice(kNextSerialNumberKey), &result); |  | 
| 574   if (status.ok()) { |  | 
| 575     if (!base::StringToInt64(result, next_serial_number)) { |  | 
| 576       LOG(ERROR) << "Failed to restore the next serial number."; |  | 
| 577       return false; |  | 
| 578     } |  | 
| 579     return true; |  | 
| 580   } |  | 
| 581 |  | 
| 582   if (status.IsNotFound()) { |  | 
| 583     DVLOG(1) << "No next serial number found."; |  | 
| 584     return true; |  | 
| 585   } |  | 
| 586 |  | 
| 587   LOG(ERROR) << "Error when reading the next serial number."; |  | 
| 588   return false; |  | 
| 589 } |  | 
| 590 |  | 
| 591 bool GCMStoreImpl::Backend::LoadUserSerialNumberMap( |  | 
| 592     std::map<std::string, int64>* user_serial_number_map) { |  | 
| 593   leveldb::ReadOptions read_options; |  | 
| 594   read_options.verify_checksums = true; |  | 
| 595 |  | 
| 596   scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(read_options)); |  | 
| 597   for (iter->Seek(MakeSlice(kUserSerialNumberKeyStart)); |  | 
| 598        iter->Valid() && iter->key().ToString() < kUserSerialNumberKeyEnd; |  | 
| 599        iter->Next()) { |  | 
| 600     std::string username = ParseUsername(iter->key().ToString()); |  | 
| 601     if (username.empty()) { |  | 
| 602       LOG(ERROR) << "Error reading username. It should not be empty."; |  | 
| 603       return false; |  | 
| 604     } |  | 
| 605     std::string serial_number_string = iter->value().ToString(); |  | 
| 606     int64 serial_number = kSerialNumberMissing; |  | 
| 607     if (!base::StringToInt64(serial_number_string, &serial_number)) { |  | 
| 608       LOG(ERROR) << "Error reading user serial number for user: " << username; |  | 
| 609       return false; |  | 
| 610     } |  | 
| 611 |  | 
| 612     (*user_serial_number_map)[username] = serial_number; |  | 
| 613   } |  | 
| 614 |  | 
| 615   return true; |  | 
| 616 } |  | 
| 617 |  | 
| 618 GCMStoreImpl::GCMStoreImpl( | 563 GCMStoreImpl::GCMStoreImpl( | 
| 619     bool use_mock_keychain, | 564     bool use_mock_keychain, | 
| 620     const base::FilePath& path, | 565     const base::FilePath& path, | 
| 621     scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) | 566     scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) | 
| 622     : backend_(new Backend(path, base::MessageLoopProxy::current())), | 567     : backend_(new Backend(path, base::MessageLoopProxy::current())), | 
| 623       blocking_task_runner_(blocking_task_runner), | 568       blocking_task_runner_(blocking_task_runner), | 
| 624       weak_ptr_factory_(this) { | 569       weak_ptr_factory_(this) { | 
| 625 // On OSX, prevent the Keychain permissions popup during unit tests. | 570 // On OSX, prevent the Keychain permissions popup during unit tests. | 
| 626 #if defined(OS_MACOSX) | 571 #if defined(OS_MACOSX) | 
| 627   OSCrypt::UseMockKeychain(use_mock_keychain); | 572   OSCrypt::UseMockKeychain(use_mock_keychain); | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
| 657                                         const UpdateCallback& callback) { | 602                                         const UpdateCallback& callback) { | 
| 658   blocking_task_runner_->PostTask( | 603   blocking_task_runner_->PostTask( | 
| 659       FROM_HERE, | 604       FROM_HERE, | 
| 660       base::Bind(&GCMStoreImpl::Backend::SetDeviceCredentials, | 605       base::Bind(&GCMStoreImpl::Backend::SetDeviceCredentials, | 
| 661                  backend_, | 606                  backend_, | 
| 662                  device_android_id, | 607                  device_android_id, | 
| 663                  device_security_token, | 608                  device_security_token, | 
| 664                  callback)); | 609                  callback)); | 
| 665 } | 610 } | 
| 666 | 611 | 
|  | 612 void GCMStoreImpl::AddRegistration( | 
|  | 613     const std::string& app_id, | 
|  | 614     const linked_ptr<RegistrationInfo>& registration, | 
|  | 615     const UpdateCallback& callback) { | 
|  | 616   blocking_task_runner_->PostTask( | 
|  | 617       FROM_HERE, | 
|  | 618       base::Bind(&GCMStoreImpl::Backend::AddRegistration, | 
|  | 619                  backend_, | 
|  | 620                  app_id, | 
|  | 621                  registration, | 
|  | 622                  callback)); | 
|  | 623 } | 
|  | 624 | 
|  | 625 void GCMStoreImpl::RemoveRegistration(const std::string& app_id, | 
|  | 626                                           const UpdateCallback& callback) { | 
|  | 627   blocking_task_runner_->PostTask( | 
|  | 628       FROM_HERE, | 
|  | 629       base::Bind(&GCMStoreImpl::Backend::RemoveRegistration, | 
|  | 630                  backend_, | 
|  | 631                  app_id, | 
|  | 632                  callback)); | 
|  | 633 } | 
|  | 634 | 
| 667 void GCMStoreImpl::AddIncomingMessage(const std::string& persistent_id, | 635 void GCMStoreImpl::AddIncomingMessage(const std::string& persistent_id, | 
| 668                                       const UpdateCallback& callback) { | 636                                       const UpdateCallback& callback) { | 
| 669   blocking_task_runner_->PostTask( | 637   blocking_task_runner_->PostTask( | 
| 670       FROM_HERE, | 638       FROM_HERE, | 
| 671       base::Bind(&GCMStoreImpl::Backend::AddIncomingMessage, | 639       base::Bind(&GCMStoreImpl::Backend::AddIncomingMessage, | 
| 672                  backend_, | 640                  backend_, | 
| 673                  persistent_id, | 641                  persistent_id, | 
| 674                  callback)); | 642                  callback)); | 
| 675 } | 643 } | 
| 676 | 644 | 
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 759   blocking_task_runner_->PostTask( | 727   blocking_task_runner_->PostTask( | 
| 760       FROM_HERE, | 728       FROM_HERE, | 
| 761       base::Bind(&GCMStoreImpl::Backend::RemoveOutgoingMessages, | 729       base::Bind(&GCMStoreImpl::Backend::RemoveOutgoingMessages, | 
| 762                  backend_, | 730                  backend_, | 
| 763                  persistent_ids, | 731                  persistent_ids, | 
| 764                  base::Bind(&GCMStoreImpl::RemoveOutgoingMessagesContinuation, | 732                  base::Bind(&GCMStoreImpl::RemoveOutgoingMessagesContinuation, | 
| 765                             weak_ptr_factory_.GetWeakPtr(), | 733                             weak_ptr_factory_.GetWeakPtr(), | 
| 766                             callback))); | 734                             callback))); | 
| 767 } | 735 } | 
| 768 | 736 | 
| 769 void GCMStoreImpl::SetNextSerialNumber(int64 next_serial_number, |  | 
| 770                                        const UpdateCallback& callback) { |  | 
| 771   blocking_task_runner_->PostTask( |  | 
| 772       FROM_HERE, |  | 
| 773       base::Bind(&GCMStoreImpl::Backend::SetNextSerialNumber, |  | 
| 774                  backend_, |  | 
| 775                  next_serial_number, |  | 
| 776                  callback)); |  | 
| 777 } |  | 
| 778 |  | 
| 779 void GCMStoreImpl::AddUserSerialNumber(const std::string& username, |  | 
| 780                                        int64 serial_number, |  | 
| 781                                        const UpdateCallback& callback) { |  | 
| 782   blocking_task_runner_->PostTask( |  | 
| 783       FROM_HERE, |  | 
| 784       base::Bind(&GCMStoreImpl::Backend::AddUserSerialNumber, |  | 
| 785                  backend_, |  | 
| 786                  username, |  | 
| 787                  serial_number, |  | 
| 788                  callback)); |  | 
| 789 } |  | 
| 790 |  | 
| 791 void GCMStoreImpl::RemoveUserSerialNumber(const std::string& username, |  | 
| 792                                           const UpdateCallback& callback) { |  | 
| 793   blocking_task_runner_->PostTask( |  | 
| 794       FROM_HERE, |  | 
| 795       base::Bind(&GCMStoreImpl::Backend::RemoveUserSerialNumber, |  | 
| 796                  backend_, |  | 
| 797                  username, |  | 
| 798                  callback)); |  | 
| 799 } |  | 
| 800 |  | 
| 801 void GCMStoreImpl::LoadContinuation(const LoadCallback& callback, | 737 void GCMStoreImpl::LoadContinuation(const LoadCallback& callback, | 
| 802                                     scoped_ptr<LoadResult> result) { | 738                                     scoped_ptr<LoadResult> result) { | 
| 803   if (!result->success) { | 739   if (!result->success) { | 
| 804     callback.Run(result.Pass()); | 740     callback.Run(result.Pass()); | 
| 805     return; | 741     return; | 
| 806   } | 742   } | 
| 807   int num_throttled_apps = 0; | 743   int num_throttled_apps = 0; | 
| 808   for (OutgoingMessageMap::const_iterator | 744   for (OutgoingMessageMap::const_iterator | 
| 809            iter = result->outgoing_messages.begin(); | 745            iter = result->outgoing_messages.begin(); | 
| 810        iter != result->outgoing_messages.end(); ++iter) { | 746        iter != result->outgoing_messages.end(); ++iter) { | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 845            removed_message_counts.begin(); | 781            removed_message_counts.begin(); | 
| 846        iter != removed_message_counts.end(); ++iter) { | 782        iter != removed_message_counts.end(); ++iter) { | 
| 847     DCHECK_NE(app_message_counts_.count(iter->first), 0U); | 783     DCHECK_NE(app_message_counts_.count(iter->first), 0U); | 
| 848     app_message_counts_[iter->first] -= iter->second; | 784     app_message_counts_[iter->first] -= iter->second; | 
| 849     DCHECK_GE(app_message_counts_[iter->first], 0); | 785     DCHECK_GE(app_message_counts_[iter->first], 0); | 
| 850   } | 786   } | 
| 851   callback.Run(true); | 787   callback.Run(true); | 
| 852 } | 788 } | 
| 853 | 789 | 
| 854 }  // namespace gcm | 790 }  // namespace gcm | 
| OLD | NEW | 
|---|