Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "content/browser/notifications/notification_database.h" | 5 #include "content/browser/notifications/notification_database.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
| 10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
| 11 #include "base/strings/stringprintf.h" | 11 #include "base/strings/stringprintf.h" |
| 12 #include "content/browser/notifications/notification_database_data_conversions.h " | 12 #include "content/browser/notifications/notification_database_data_conversions.h " |
| 13 #include "content/common/service_worker/service_worker_types.h" | 13 #include "content/common/service_worker/service_worker_types.h" |
| 14 #include "content/public/browser/browser_thread.h" | 14 #include "content/public/browser/browser_thread.h" |
| 15 #include "content/public/browser/notification_database_data.h" | 15 #include "content/public/browser/notification_database_data.h" |
| 16 #include "storage/common/database/database_identifier.h" | 16 #include "storage/common/database/database_identifier.h" |
| 17 #include "third_party/leveldatabase/env_chromium.h" | 17 #include "third_party/leveldatabase/env_chromium.h" |
| 18 #include "third_party/leveldatabase/src/helpers/memenv/memenv.h" | 18 #include "third_party/leveldatabase/src/helpers/memenv/memenv.h" |
| 19 #include "third_party/leveldatabase/src/include/leveldb/db.h" | 19 #include "third_party/leveldatabase/src/include/leveldb/db.h" |
| 20 #include "third_party/leveldatabase/src/include/leveldb/env.h" | 20 #include "third_party/leveldatabase/src/include/leveldb/env.h" |
| 21 #include "third_party/leveldatabase/src/include/leveldb/filter_policy.h" | 21 #include "third_party/leveldatabase/src/include/leveldb/filter_policy.h" |
| 22 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" | 22 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" |
| 23 #include "url/gurl.h" | 23 #include "url/gurl.h" |
| 24 | 24 |
| 25 // Notification LevelDB database schema (in alphabetized order) | 25 // Notification LevelDB database schema (in alphabetized order) |
| 26 // ======================= | 26 // ======================= |
| 27 // | 27 // |
| 28 // key: "DATA:" <origin identifier> '\x00' <notification_id> | 28 // key: "DATA:" <origin identifier> '\x00' <notification_id> |
|
johnme
2016/09/02 15:07:44
persistent_notification_id
Peter Beverloo
2016/09/05 15:11:01
Done.
| |
| 29 // value: String containing the NotificationDatabaseDataProto protocol buffer | 29 // value: String containing the NotificationDatabaseDataProto protocol buffer |
| 30 // in serialized form. | 30 // in serialized form. |
| 31 // | 31 // |
| 32 // key: "ASSOC:" <notification id> | |
| 33 // value: String containing the associated persistent notification id as an | |
| 34 // int64_t in textual representation. | |
| 35 // | |
| 32 // key: "NEXT_NOTIFICATION_ID" | 36 // key: "NEXT_NOTIFICATION_ID" |
| 33 // value: Decimal string which fits into an int64_t. | 37 // value: Decimal string which fits into an int64_t. |
| 34 | 38 |
| 35 namespace content { | 39 namespace content { |
| 36 namespace { | 40 namespace { |
| 37 | 41 |
| 38 // Keys of the fields defined in the database. | 42 // Keys of the fields defined in the database. |
| 39 const char kNextNotificationIdKey[] = "NEXT_NOTIFICATION_ID"; | 43 const char kNextNotificationIdKey[] = "NEXT_NOTIFICATION_ID"; |
| 40 const char kDataKeyPrefix[] = "DATA:"; | 44 const char kDataKeyPrefix[] = "DATA:"; |
| 45 const char kAssociatedKeyPrefix[] = "ASSOC:"; | |
| 41 | 46 |
| 42 // Separates the components of compound keys. | 47 // Separates the components of compound keys. |
| 43 const char kKeySeparator = '\x00'; | 48 const char kKeySeparator = '\x00'; |
| 44 | 49 |
| 45 // The first notification id which to be handed out by the database. | 50 // The first notification id which to be handed out by the database. |
| 46 const int64_t kFirstNotificationId = 1; | 51 const int64_t kFirstNotificationId = 1; |
| 47 | 52 |
| 48 // Converts the LevelDB |status| to one of the notification database's values. | 53 // Converts the LevelDB |status| to one of the notification database's values. |
| 49 NotificationDatabase::Status LevelDBStatusToStatus( | 54 NotificationDatabase::Status LevelDBStatusToStatus( |
| 50 const leveldb::Status& status) { | 55 const leveldb::Status& status) { |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 68 std::string CreateDataPrefix(const GURL& origin) { | 73 std::string CreateDataPrefix(const GURL& origin) { |
| 69 if (!origin.is_valid()) | 74 if (!origin.is_valid()) |
| 70 return kDataKeyPrefix; | 75 return kDataKeyPrefix; |
| 71 | 76 |
| 72 return base::StringPrintf("%s%s%c", kDataKeyPrefix, | 77 return base::StringPrintf("%s%s%c", kDataKeyPrefix, |
| 73 storage::GetIdentifierFromOrigin(origin).c_str(), | 78 storage::GetIdentifierFromOrigin(origin).c_str(), |
| 74 kKeySeparator); | 79 kKeySeparator); |
| 75 } | 80 } |
| 76 | 81 |
| 77 // Creates the compound data key in which notification data is stored. | 82 // Creates the compound data key in which notification data is stored. |
| 78 std::string CreateDataKey(const GURL& origin, int64_t notification_id) { | 83 std::string CreateDataKey(const GURL& origin, |
| 84 int64_t persistent_notification_id) { | |
| 79 DCHECK(origin.is_valid()); | 85 DCHECK(origin.is_valid()); |
| 80 return CreateDataPrefix(origin) + base::Int64ToString(notification_id); | 86 return CreateDataPrefix(origin) + |
| 87 base::Int64ToString(persistent_notification_id); | |
| 88 } | |
| 89 | |
| 90 // Creates the compound key for mapping the given |notification_id| to the | |
| 91 // latest persistent notification id in the database. | |
| 92 std::string CreateAssociatedKey(const std::string& notification_id) { | |
| 93 return base::StringPrintf("%s%s", kAssociatedKeyPrefix, | |
| 94 notification_id.c_str()); | |
| 81 } | 95 } |
| 82 | 96 |
| 83 // Deserializes data in |serialized_data| to |notification_database_data|. | 97 // Deserializes data in |serialized_data| to |notification_database_data|. |
| 84 // Will return if the deserialization was successful. | 98 // Will return if the deserialization was successful. |
| 85 NotificationDatabase::Status DeserializedNotificationData( | 99 NotificationDatabase::Status DeserializedNotificationData( |
| 86 const std::string& serialized_data, | 100 const std::string& serialized_data, |
| 87 NotificationDatabaseData* notification_database_data) { | 101 NotificationDatabaseData* notification_database_data) { |
| 88 DCHECK(notification_database_data); | 102 DCHECK(notification_database_data); |
| 89 if (DeserializeNotificationDatabaseData(serialized_data, | 103 if (DeserializeNotificationDatabaseData(serialized_data, |
| 90 notification_database_data)) { | 104 notification_database_data)) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 134 if (status != STATUS_OK) | 148 if (status != STATUS_OK) |
| 135 return status; | 149 return status; |
| 136 | 150 |
| 137 state_ = STATE_INITIALIZED; | 151 state_ = STATE_INITIALIZED; |
| 138 db_.reset(db); | 152 db_.reset(db); |
| 139 | 153 |
| 140 return ReadNextNotificationId(); | 154 return ReadNextNotificationId(); |
| 141 } | 155 } |
| 142 | 156 |
| 143 NotificationDatabase::Status NotificationDatabase::ReadNotificationData( | 157 NotificationDatabase::Status NotificationDatabase::ReadNotificationData( |
| 144 int64_t notification_id, | 158 int64_t persistent_notification_id, |
| 145 const GURL& origin, | 159 const GURL& origin, |
| 146 NotificationDatabaseData* notification_database_data) const { | 160 NotificationDatabaseData* notification_database_data) const { |
| 147 DCHECK(sequence_checker_.CalledOnValidSequence()); | 161 DCHECK(sequence_checker_.CalledOnValidSequence()); |
| 148 DCHECK_EQ(STATE_INITIALIZED, state_); | 162 DCHECK_EQ(STATE_INITIALIZED, state_); |
| 149 DCHECK_GE(notification_id, kFirstNotificationId); | 163 DCHECK_GE(persistent_notification_id, kFirstNotificationId); |
| 150 DCHECK(origin.is_valid()); | 164 DCHECK(origin.is_valid()); |
| 151 DCHECK(notification_database_data); | 165 DCHECK(notification_database_data); |
| 152 | 166 |
| 153 std::string key = CreateDataKey(origin, notification_id); | 167 std::string key = CreateDataKey(origin, persistent_notification_id); |
| 154 std::string serialized_data; | 168 std::string serialized_data; |
| 155 | 169 |
| 156 Status status = LevelDBStatusToStatus( | 170 Status status = LevelDBStatusToStatus( |
| 157 db_->Get(leveldb::ReadOptions(), key, &serialized_data)); | 171 db_->Get(leveldb::ReadOptions(), key, &serialized_data)); |
| 158 if (status != STATUS_OK) | 172 if (status != STATUS_OK) |
| 159 return status; | 173 return status; |
| 160 | 174 |
| 161 return DeserializedNotificationData(serialized_data, | 175 return DeserializedNotificationData(serialized_data, |
| 162 notification_database_data); | 176 notification_database_data); |
| 163 } | 177 } |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 182 const GURL& origin, | 196 const GURL& origin, |
| 183 int64_t service_worker_registration_id, | 197 int64_t service_worker_registration_id, |
| 184 std::vector<NotificationDatabaseData>* notification_data_vector) const { | 198 std::vector<NotificationDatabaseData>* notification_data_vector) const { |
| 185 return ReadAllNotificationDataInternal(origin, service_worker_registration_id, | 199 return ReadAllNotificationDataInternal(origin, service_worker_registration_id, |
| 186 notification_data_vector); | 200 notification_data_vector); |
| 187 } | 201 } |
| 188 | 202 |
| 189 NotificationDatabase::Status NotificationDatabase::WriteNotificationData( | 203 NotificationDatabase::Status NotificationDatabase::WriteNotificationData( |
| 190 const GURL& origin, | 204 const GURL& origin, |
| 191 const NotificationDatabaseData& notification_database_data, | 205 const NotificationDatabaseData& notification_database_data, |
| 192 int64_t* notification_id) { | 206 int64_t* persistent_notification_id) { |
| 193 DCHECK(sequence_checker_.CalledOnValidSequence()); | 207 DCHECK(sequence_checker_.CalledOnValidSequence()); |
| 194 DCHECK_EQ(STATE_INITIALIZED, state_); | 208 DCHECK_EQ(STATE_INITIALIZED, state_); |
| 195 DCHECK(notification_id); | 209 DCHECK(persistent_notification_id); |
| 196 DCHECK(origin.is_valid()); | 210 DCHECK(origin.is_valid()); |
| 197 | 211 |
| 198 DCHECK_GE(next_notification_id_, kFirstNotificationId); | 212 DCHECK_GE(next_notification_id_, kFirstNotificationId); |
| 199 | 213 |
| 200 NotificationDatabaseData storage_data = notification_database_data; | 214 NotificationDatabaseData storage_data = notification_database_data; |
| 201 storage_data.notification_id = next_notification_id_; | 215 storage_data.notification_id = next_notification_id_; |
|
johnme
2016/09/02 15:07:44
Please also rename notification_id in content/brow
Peter Beverloo
2016/09/05 15:11:01
Done, also in the NotificationDatabaseData class,
| |
| 202 | 216 |
| 203 std::string serialized_data; | 217 std::string serialized_data; |
| 204 if (!SerializeNotificationDatabaseData(storage_data, &serialized_data)) { | 218 if (!SerializeNotificationDatabaseData(storage_data, &serialized_data)) { |
| 205 DLOG(ERROR) << "Unable to serialize data for a notification belonging " | 219 DLOG(ERROR) << "Unable to serialize data for a notification belonging " |
| 206 << "to: " << origin; | 220 << "to: " << origin; |
| 207 return STATUS_ERROR_FAILED; | 221 return STATUS_ERROR_FAILED; |
| 208 } | 222 } |
| 209 | 223 |
| 210 leveldb::WriteBatch batch; | 224 leveldb::WriteBatch batch; |
| 211 batch.Put(CreateDataKey(origin, next_notification_id_), serialized_data); | 225 batch.Put(CreateDataKey(origin, next_notification_id_), serialized_data); |
| 212 batch.Put(kNextNotificationIdKey, | 226 batch.Put(kNextNotificationIdKey, |
| 213 base::Int64ToString(next_notification_id_ + 1)); | 227 base::Int64ToString(next_notification_id_ + 1)); |
| 214 | 228 |
| 215 Status status = | 229 Status status = |
| 216 LevelDBStatusToStatus(db_->Write(leveldb::WriteOptions(), &batch)); | 230 LevelDBStatusToStatus(db_->Write(leveldb::WriteOptions(), &batch)); |
| 217 if (status != STATUS_OK) | 231 if (status != STATUS_OK) |
| 218 return status; | 232 return status; |
| 219 | 233 |
| 220 *notification_id = next_notification_id_++; | 234 *persistent_notification_id = next_notification_id_++; |
| 221 return STATUS_OK; | 235 return STATUS_OK; |
| 222 } | 236 } |
| 223 | 237 |
| 224 NotificationDatabase::Status NotificationDatabase::DeleteNotificationData( | 238 NotificationDatabase::Status NotificationDatabase::DeleteNotificationData( |
| 225 int64_t notification_id, | 239 int64_t persistent_notification_id, |
| 226 const GURL& origin) { | 240 const GURL& origin) { |
| 227 DCHECK(sequence_checker_.CalledOnValidSequence()); | 241 DCHECK(sequence_checker_.CalledOnValidSequence()); |
| 228 DCHECK_EQ(STATE_INITIALIZED, state_); | 242 DCHECK_EQ(STATE_INITIALIZED, state_); |
| 229 DCHECK_GE(notification_id, kFirstNotificationId); | 243 DCHECK_GE(persistent_notification_id, kFirstNotificationId); |
| 230 DCHECK(origin.is_valid()); | 244 DCHECK(origin.is_valid()); |
| 231 | 245 |
| 232 std::string key = CreateDataKey(origin, notification_id); | 246 std::string key = CreateDataKey(origin, persistent_notification_id); |
| 233 return LevelDBStatusToStatus(db_->Delete(leveldb::WriteOptions(), key)); | 247 return LevelDBStatusToStatus(db_->Delete(leveldb::WriteOptions(), key)); |
| 234 } | 248 } |
| 235 | 249 |
| 236 NotificationDatabase::Status | 250 NotificationDatabase::Status |
| 237 NotificationDatabase::DeleteAllNotificationDataForOrigin( | 251 NotificationDatabase::DeleteAllNotificationDataForOrigin( |
| 238 const GURL& origin, | 252 const GURL& origin, |
| 239 const std::string& tag, | 253 const std::string& tag, |
| 240 std::set<int64_t>* deleted_notification_set) { | 254 std::set<int64_t>* deleted_notification_set) { |
| 241 return DeleteAllNotificationDataInternal(origin, tag, | 255 return DeleteAllNotificationDataInternal(origin, tag, |
| 242 kInvalidServiceWorkerRegistrationId, | 256 kInvalidServiceWorkerRegistrationId, |
| 243 deleted_notification_set); | 257 deleted_notification_set); |
| 244 } | 258 } |
| 245 | 259 |
| 246 NotificationDatabase::Status | 260 NotificationDatabase::Status |
| 247 NotificationDatabase::DeleteAllNotificationDataForServiceWorkerRegistration( | 261 NotificationDatabase::DeleteAllNotificationDataForServiceWorkerRegistration( |
| 248 const GURL& origin, | 262 const GURL& origin, |
| 249 int64_t service_worker_registration_id, | 263 int64_t service_worker_registration_id, |
| 250 std::set<int64_t>* deleted_notification_set) { | 264 std::set<int64_t>* deleted_notification_set) { |
| 251 return DeleteAllNotificationDataInternal(origin, "" /* tag */, | 265 return DeleteAllNotificationDataInternal(origin, "" /* tag */, |
| 252 service_worker_registration_id, | 266 service_worker_registration_id, |
| 253 deleted_notification_set); | 267 deleted_notification_set); |
| 254 } | 268 } |
| 255 | 269 |
| 270 NotificationDatabase::Status NotificationDatabase::StoreIdAssociation( | |
| 271 const std::string& notification_id, | |
| 272 int64_t persistent_notification_id) { | |
| 273 DCHECK(sequence_checker_.CalledOnValidSequence()); | |
| 274 | |
| 275 std::string key = CreateAssociatedKey(notification_id); | |
| 276 std::string serialized_persistent_notification_id = | |
| 277 base::Int64ToString(persistent_notification_id); | |
| 278 | |
| 279 Status status = LevelDBStatusToStatus(db_->Put( | |
| 280 leveldb::WriteOptions(), key, serialized_persistent_notification_id)); | |
| 281 | |
| 282 return status; | |
| 283 } | |
| 284 | |
| 285 NotificationDatabase::Status NotificationDatabase::ReadIdAssociation( | |
| 286 const std::string& notification_id, | |
| 287 int64_t* persistent_notification_id) { | |
| 288 DCHECK(sequence_checker_.CalledOnValidSequence()); | |
| 289 | |
| 290 std::string key = CreateAssociatedKey(notification_id); | |
| 291 std::string serialized_persistent_notification_id; | |
| 292 | |
| 293 Status status = LevelDBStatusToStatus(db_->Get( | |
| 294 leveldb::ReadOptions(), key, &serialized_persistent_notification_id)); | |
| 295 | |
| 296 if (status != STATUS_OK) | |
| 297 return status; | |
| 298 | |
| 299 if (!base::StringToInt64(serialized_persistent_notification_id, | |
| 300 persistent_notification_id)) { | |
| 301 return STATUS_ERROR_CORRUPTED; | |
| 302 } | |
| 303 | |
| 304 return status; | |
| 305 } | |
| 306 | |
| 307 NotificationDatabase::Status NotificationDatabase::DeleteIdAssociation( | |
| 308 const std::string& notification_id) { | |
| 309 DCHECK(sequence_checker_.CalledOnValidSequence()); | |
| 310 | |
| 311 std::string key = CreateAssociatedKey(notification_id); | |
| 312 | |
| 313 return LevelDBStatusToStatus(db_->Delete(leveldb::WriteOptions(), key)); | |
| 314 } | |
| 315 | |
| 256 NotificationDatabase::Status NotificationDatabase::Destroy() { | 316 NotificationDatabase::Status NotificationDatabase::Destroy() { |
| 257 DCHECK(sequence_checker_.CalledOnValidSequence()); | 317 DCHECK(sequence_checker_.CalledOnValidSequence()); |
| 258 | 318 |
| 259 leveldb::Options options; | 319 leveldb::Options options; |
| 260 if (IsInMemoryDatabase()) { | 320 if (IsInMemoryDatabase()) { |
| 261 if (!env_) | 321 if (!env_) |
| 262 return STATUS_OK; // The database has not been initialized. | 322 return STATUS_OK; // The database has not been initialized. |
| 263 | 323 |
| 264 options.env = env_.get(); | 324 options.env = env_.get(); |
| 265 } | 325 } |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 368 kInvalidServiceWorkerRegistrationId && | 428 kInvalidServiceWorkerRegistrationId && |
| 369 notification_database_data.service_worker_registration_id != | 429 notification_database_data.service_worker_registration_id != |
| 370 service_worker_registration_id) { | 430 service_worker_registration_id) { |
| 371 continue; | 431 continue; |
| 372 } | 432 } |
| 373 } | 433 } |
| 374 | 434 |
| 375 leveldb::Slice notification_id_slice = iter->key(); | 435 leveldb::Slice notification_id_slice = iter->key(); |
| 376 notification_id_slice.remove_prefix(prefix_slice.size()); | 436 notification_id_slice.remove_prefix(prefix_slice.size()); |
| 377 | 437 |
| 378 int64_t notification_id = 0; | 438 int64_t persistent_notification_id = 0; |
| 379 if (!base::StringToInt64(notification_id_slice.ToString(), | 439 if (!base::StringToInt64(notification_id_slice.ToString(), |
| 380 ¬ification_id)) { | 440 &persistent_notification_id)) { |
| 381 return STATUS_ERROR_CORRUPTED; | 441 return STATUS_ERROR_CORRUPTED; |
| 382 } | 442 } |
| 383 | 443 |
| 384 deleted_notification_set->insert(notification_id); | 444 deleted_notification_set->insert(persistent_notification_id); |
| 385 batch.Delete(iter->key()); | 445 batch.Delete(iter->key()); |
| 386 } | 446 } |
| 387 | 447 |
| 388 if (deleted_notification_set->empty()) | 448 if (deleted_notification_set->empty()) |
| 389 return STATUS_OK; | 449 return STATUS_OK; |
| 390 | 450 |
| 391 return LevelDBStatusToStatus(db_->Write(leveldb::WriteOptions(), &batch)); | 451 return LevelDBStatusToStatus(db_->Write(leveldb::WriteOptions(), &batch)); |
| 392 } | 452 } |
| 393 | 453 |
| 394 } // namespace content | 454 } // namespace content |
| OLD | NEW |