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" |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 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> |
| 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: "NEXT_NOTIFICATION_ID" | 32 // key: "NEXT_NOTIFICATION_ID" |
| 33 // value: Decimal string which fits into an int64_t. | 33 // value: Decimal string which fits into an int64_t, containing the next |
| 34 // persistent notification ID. | |
| 34 | 35 |
| 35 namespace content { | 36 namespace content { |
| 36 namespace { | 37 namespace { |
| 37 | 38 |
| 38 // Keys of the fields defined in the database. | 39 // Keys of the fields defined in the database. |
| 39 const char kNextNotificationIdKey[] = "NEXT_NOTIFICATION_ID"; | 40 const char kNextNotificationIdKey[] = "NEXT_NOTIFICATION_ID"; |
| 40 const char kDataKeyPrefix[] = "DATA:"; | 41 const char kDataKeyPrefix[] = "DATA:"; |
| 41 | 42 |
| 42 // Separates the components of compound keys. | 43 // Separates the components of compound keys. |
| 43 const char kKeySeparator = '\x00'; | 44 const char kKeySeparator = '\x00'; |
| 44 | 45 |
| 45 // The first notification id which to be handed out by the database. | 46 // The first notification id which to be handed out by the database. |
| 46 const int64_t kFirstNotificationId = 1; | 47 const int64_t kFirstPersistentNotificationId = 1; |
| 47 | 48 |
| 48 // Converts the LevelDB |status| to one of the notification database's values. | 49 // Converts the LevelDB |status| to one of the notification database's values. |
| 49 NotificationDatabase::Status LevelDBStatusToStatus( | 50 NotificationDatabase::Status LevelDBStatusToStatus( |
| 50 const leveldb::Status& status) { | 51 const leveldb::Status& status) { |
| 51 if (status.ok()) | 52 if (status.ok()) |
| 52 return NotificationDatabase::STATUS_OK; | 53 return NotificationDatabase::STATUS_OK; |
| 53 else if (status.IsNotFound()) | 54 else if (status.IsNotFound()) |
| 54 return NotificationDatabase::STATUS_ERROR_NOT_FOUND; | 55 return NotificationDatabase::STATUS_ERROR_NOT_FOUND; |
| 55 else if (status.IsCorruption()) | 56 else if (status.IsCorruption()) |
| 56 return NotificationDatabase::STATUS_ERROR_CORRUPTED; | 57 return NotificationDatabase::STATUS_ERROR_CORRUPTED; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 68 std::string CreateDataPrefix(const GURL& origin) { | 69 std::string CreateDataPrefix(const GURL& origin) { |
| 69 if (!origin.is_valid()) | 70 if (!origin.is_valid()) |
| 70 return kDataKeyPrefix; | 71 return kDataKeyPrefix; |
| 71 | 72 |
| 72 return base::StringPrintf("%s%s%c", kDataKeyPrefix, | 73 return base::StringPrintf("%s%s%c", kDataKeyPrefix, |
| 73 storage::GetIdentifierFromOrigin(origin).c_str(), | 74 storage::GetIdentifierFromOrigin(origin).c_str(), |
| 74 kKeySeparator); | 75 kKeySeparator); |
| 75 } | 76 } |
| 76 | 77 |
| 77 // Creates the compound data key in which notification data is stored. | 78 // Creates the compound data key in which notification data is stored. |
| 78 std::string CreateDataKey(const GURL& origin, int64_t notification_id) { | 79 std::string CreateDataKey(const GURL& origin, |
| 80 const std::string& notification_id) { | |
| 79 DCHECK(origin.is_valid()); | 81 DCHECK(origin.is_valid()); |
| 80 return CreateDataPrefix(origin) + base::Int64ToString(notification_id); | 82 DCHECK(!notification_id.empty()); |
| 83 | |
| 84 return CreateDataPrefix(origin) + notification_id; | |
| 81 } | 85 } |
| 82 | 86 |
| 83 // Deserializes data in |serialized_data| to |notification_database_data|. | 87 // Deserializes data in |serialized_data| to |notification_database_data|. |
| 84 // Will return if the deserialization was successful. | 88 // Will return if the deserialization was successful. |
| 85 NotificationDatabase::Status DeserializedNotificationData( | 89 NotificationDatabase::Status DeserializedNotificationData( |
| 86 const std::string& serialized_data, | 90 const std::string& serialized_data, |
| 87 NotificationDatabaseData* notification_database_data) { | 91 NotificationDatabaseData* notification_database_data) { |
| 88 DCHECK(notification_database_data); | 92 DCHECK(notification_database_data); |
| 89 if (DeserializeNotificationDatabaseData(serialized_data, | 93 if (DeserializeNotificationDatabaseData(serialized_data, |
| 90 notification_database_data)) { | 94 notification_database_data)) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 130 | 134 |
| 131 leveldb::DB* db = nullptr; | 135 leveldb::DB* db = nullptr; |
| 132 Status status = LevelDBStatusToStatus( | 136 Status status = LevelDBStatusToStatus( |
| 133 leveldb::DB::Open(options, path_.AsUTF8Unsafe(), &db)); | 137 leveldb::DB::Open(options, path_.AsUTF8Unsafe(), &db)); |
| 134 if (status != STATUS_OK) | 138 if (status != STATUS_OK) |
| 135 return status; | 139 return status; |
| 136 | 140 |
| 137 state_ = STATE_INITIALIZED; | 141 state_ = STATE_INITIALIZED; |
| 138 db_.reset(db); | 142 db_.reset(db); |
| 139 | 143 |
| 140 return ReadNextNotificationId(); | 144 return ReadNextPersistentNotificationId(); |
| 145 } | |
| 146 | |
| 147 int64_t NotificationDatabase::GetNextPersistentNotificationId() { | |
| 148 return next_persistent_notification_id_++; | |
| 141 } | 149 } |
| 142 | 150 |
| 143 NotificationDatabase::Status NotificationDatabase::ReadNotificationData( | 151 NotificationDatabase::Status NotificationDatabase::ReadNotificationData( |
| 144 int64_t notification_id, | 152 const std::string& notification_id, |
| 145 const GURL& origin, | 153 const GURL& origin, |
| 146 NotificationDatabaseData* notification_database_data) const { | 154 NotificationDatabaseData* notification_database_data) const { |
| 147 DCHECK(sequence_checker_.CalledOnValidSequence()); | 155 DCHECK(sequence_checker_.CalledOnValidSequence()); |
| 148 DCHECK_EQ(STATE_INITIALIZED, state_); | 156 DCHECK_EQ(STATE_INITIALIZED, state_); |
| 149 DCHECK_GE(notification_id, kFirstNotificationId); | 157 DCHECK(!notification_id.empty()); |
| 150 DCHECK(origin.is_valid()); | 158 DCHECK(origin.is_valid()); |
| 151 DCHECK(notification_database_data); | 159 DCHECK(notification_database_data); |
| 152 | 160 |
| 153 std::string key = CreateDataKey(origin, notification_id); | 161 std::string key = CreateDataKey(origin, notification_id); |
| 154 std::string serialized_data; | 162 std::string serialized_data; |
| 155 | 163 |
| 156 Status status = LevelDBStatusToStatus( | 164 Status status = LevelDBStatusToStatus( |
| 157 db_->Get(leveldb::ReadOptions(), key, &serialized_data)); | 165 db_->Get(leveldb::ReadOptions(), key, &serialized_data)); |
| 158 if (status != STATUS_OK) | 166 if (status != STATUS_OK) |
| 159 return status; | 167 return status; |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 181 NotificationDatabase::ReadAllNotificationDataForServiceWorkerRegistration( | 189 NotificationDatabase::ReadAllNotificationDataForServiceWorkerRegistration( |
| 182 const GURL& origin, | 190 const GURL& origin, |
| 183 int64_t service_worker_registration_id, | 191 int64_t service_worker_registration_id, |
| 184 std::vector<NotificationDatabaseData>* notification_data_vector) const { | 192 std::vector<NotificationDatabaseData>* notification_data_vector) const { |
| 185 return ReadAllNotificationDataInternal(origin, service_worker_registration_id, | 193 return ReadAllNotificationDataInternal(origin, service_worker_registration_id, |
| 186 notification_data_vector); | 194 notification_data_vector); |
| 187 } | 195 } |
| 188 | 196 |
| 189 NotificationDatabase::Status NotificationDatabase::WriteNotificationData( | 197 NotificationDatabase::Status NotificationDatabase::WriteNotificationData( |
| 190 const GURL& origin, | 198 const GURL& origin, |
| 191 const NotificationDatabaseData& notification_database_data, | 199 const NotificationDatabaseData& notification_data) { |
| 192 int64_t* notification_id) { | |
| 193 DCHECK(sequence_checker_.CalledOnValidSequence()); | 200 DCHECK(sequence_checker_.CalledOnValidSequence()); |
| 194 DCHECK_EQ(STATE_INITIALIZED, state_); | 201 DCHECK_EQ(STATE_INITIALIZED, state_); |
| 195 DCHECK(notification_id); | |
| 196 DCHECK(origin.is_valid()); | 202 DCHECK(origin.is_valid()); |
| 197 | 203 |
| 198 DCHECK_GE(next_notification_id_, kFirstNotificationId); | 204 const std::string& notification_id = notification_data.notification_id; |
| 199 | 205 DCHECK(!notification_id.empty()); |
| 200 NotificationDatabaseData storage_data = notification_database_data; | |
| 201 storage_data.notification_id = next_notification_id_; | |
| 202 | 206 |
| 203 std::string serialized_data; | 207 std::string serialized_data; |
| 204 if (!SerializeNotificationDatabaseData(storage_data, &serialized_data)) { | 208 if (!SerializeNotificationDatabaseData(notification_data, &serialized_data)) { |
| 205 DLOG(ERROR) << "Unable to serialize data for a notification belonging " | 209 DLOG(ERROR) << "Unable to serialize data for a notification belonging " |
| 206 << "to: " << origin; | 210 << "to: " << origin; |
| 207 return STATUS_ERROR_FAILED; | 211 return STATUS_ERROR_FAILED; |
| 208 } | 212 } |
| 209 | 213 |
| 210 leveldb::WriteBatch batch; | 214 leveldb::WriteBatch batch; |
| 211 batch.Put(CreateDataKey(origin, next_notification_id_), serialized_data); | 215 batch.Put(CreateDataKey(origin, notification_id), serialized_data); |
| 212 batch.Put(kNextNotificationIdKey, | |
| 213 base::Int64ToString(next_notification_id_ + 1)); | |
| 214 | 216 |
| 215 Status status = | 217 if (written_persistent_notification_id_ != next_persistent_notification_id_) { |
| 216 LevelDBStatusToStatus(db_->Write(leveldb::WriteOptions(), &batch)); | 218 written_persistent_notification_id_ = next_persistent_notification_id_; |
| 217 if (status != STATUS_OK) | 219 batch.Put(kNextNotificationIdKey, |
| 218 return status; | 220 base::Int64ToString(next_persistent_notification_id_)); |
| 221 } | |
| 219 | 222 |
| 220 *notification_id = next_notification_id_++; | 223 return LevelDBStatusToStatus(db_->Write(leveldb::WriteOptions(), &batch)); |
| 221 return STATUS_OK; | |
| 222 } | 224 } |
| 223 | 225 |
| 224 NotificationDatabase::Status NotificationDatabase::DeleteNotificationData( | 226 NotificationDatabase::Status NotificationDatabase::DeleteNotificationData( |
| 225 int64_t notification_id, | 227 const std::string& notification_id, |
| 226 const GURL& origin) { | 228 const GURL& origin) { |
| 227 DCHECK(sequence_checker_.CalledOnValidSequence()); | 229 DCHECK(sequence_checker_.CalledOnValidSequence()); |
| 228 DCHECK_EQ(STATE_INITIALIZED, state_); | 230 DCHECK_EQ(STATE_INITIALIZED, state_); |
| 229 DCHECK_GE(notification_id, kFirstNotificationId); | 231 DCHECK(!notification_id.empty()); |
| 230 DCHECK(origin.is_valid()); | 232 DCHECK(origin.is_valid()); |
| 231 | 233 |
| 232 std::string key = CreateDataKey(origin, notification_id); | 234 std::string key = CreateDataKey(origin, notification_id); |
| 233 return LevelDBStatusToStatus(db_->Delete(leveldb::WriteOptions(), key)); | 235 return LevelDBStatusToStatus(db_->Delete(leveldb::WriteOptions(), key)); |
| 234 } | 236 } |
| 235 | 237 |
| 236 NotificationDatabase::Status | 238 NotificationDatabase::Status |
| 237 NotificationDatabase::DeleteAllNotificationDataForOrigin( | 239 NotificationDatabase::DeleteAllNotificationDataForOrigin( |
| 238 const GURL& origin, | 240 const GURL& origin, |
| 239 const std::string& tag, | 241 const std::string& tag, |
| 240 std::set<int64_t>* deleted_notification_set) { | 242 std::set<std::string>* deleted_notification_ids) { |
| 241 return DeleteAllNotificationDataInternal(origin, tag, | 243 return DeleteAllNotificationDataInternal(origin, tag, |
| 242 kInvalidServiceWorkerRegistrationId, | 244 kInvalidServiceWorkerRegistrationId, |
| 243 deleted_notification_set); | 245 deleted_notification_ids); |
| 244 } | 246 } |
| 245 | 247 |
| 246 NotificationDatabase::Status | 248 NotificationDatabase::Status |
| 247 NotificationDatabase::DeleteAllNotificationDataForServiceWorkerRegistration( | 249 NotificationDatabase::DeleteAllNotificationDataForServiceWorkerRegistration( |
| 248 const GURL& origin, | 250 const GURL& origin, |
| 249 int64_t service_worker_registration_id, | 251 int64_t service_worker_registration_id, |
| 250 std::set<int64_t>* deleted_notification_set) { | 252 std::set<std::string>* deleted_notification_ids) { |
| 251 return DeleteAllNotificationDataInternal(origin, "" /* tag */, | 253 return DeleteAllNotificationDataInternal(origin, "" /* tag */, |
| 252 service_worker_registration_id, | 254 service_worker_registration_id, |
| 253 deleted_notification_set); | 255 deleted_notification_ids); |
| 254 } | 256 } |
| 255 | 257 |
| 256 NotificationDatabase::Status NotificationDatabase::Destroy() { | 258 NotificationDatabase::Status NotificationDatabase::Destroy() { |
| 257 DCHECK(sequence_checker_.CalledOnValidSequence()); | 259 DCHECK(sequence_checker_.CalledOnValidSequence()); |
| 258 | 260 |
| 259 leveldb::Options options; | 261 leveldb::Options options; |
| 260 if (IsInMemoryDatabase()) { | 262 if (IsInMemoryDatabase()) { |
| 261 if (!env_) | 263 if (!env_) |
| 262 return STATUS_OK; // The database has not been initialized. | 264 return STATUS_OK; // The database has not been initialized. |
| 263 | 265 |
| 264 options.env = env_.get(); | 266 options.env = env_.get(); |
| 265 } | 267 } |
| 266 | 268 |
| 267 state_ = STATE_DISABLED; | 269 state_ = STATE_DISABLED; |
| 268 db_.reset(); | 270 db_.reset(); |
| 269 | 271 |
| 270 return LevelDBStatusToStatus( | 272 return LevelDBStatusToStatus( |
| 271 leveldb::DestroyDB(path_.AsUTF8Unsafe(), options)); | 273 leveldb::DestroyDB(path_.AsUTF8Unsafe(), options)); |
| 272 } | 274 } |
| 273 | 275 |
| 274 NotificationDatabase::Status NotificationDatabase::ReadNextNotificationId() { | 276 NotificationDatabase::Status |
| 277 NotificationDatabase::ReadNextPersistentNotificationId() { | |
| 275 std::string value; | 278 std::string value; |
| 276 Status status = LevelDBStatusToStatus( | 279 Status status = LevelDBStatusToStatus( |
| 277 db_->Get(leveldb::ReadOptions(), kNextNotificationIdKey, &value)); | 280 db_->Get(leveldb::ReadOptions(), kNextNotificationIdKey, &value)); |
| 278 | 281 |
| 279 if (status == STATUS_ERROR_NOT_FOUND) { | 282 if (status == STATUS_ERROR_NOT_FOUND) { |
| 280 next_notification_id_ = kFirstNotificationId; | 283 next_persistent_notification_id_ = kFirstPersistentNotificationId; |
| 284 written_persistent_notification_id_ = kFirstPersistentNotificationId; | |
| 281 return STATUS_OK; | 285 return STATUS_OK; |
| 282 } | 286 } |
| 283 | 287 |
| 284 if (status != STATUS_OK) | 288 if (status != STATUS_OK) |
| 285 return status; | 289 return status; |
| 286 | 290 |
| 287 if (!base::StringToInt64(value, &next_notification_id_) || | 291 if (!base::StringToInt64(value, &next_persistent_notification_id_) || |
| 288 next_notification_id_ < kFirstNotificationId) { | 292 next_persistent_notification_id_ < kFirstPersistentNotificationId) { |
| 289 return STATUS_ERROR_CORRUPTED; | 293 return STATUS_ERROR_CORRUPTED; |
| 290 } | 294 } |
| 291 | 295 |
| 296 written_persistent_notification_id_ = next_persistent_notification_id_; | |
| 297 | |
| 292 return STATUS_OK; | 298 return STATUS_OK; |
| 293 } | 299 } |
| 294 | 300 |
| 295 NotificationDatabase::Status | 301 NotificationDatabase::Status |
| 296 NotificationDatabase::ReadAllNotificationDataInternal( | 302 NotificationDatabase::ReadAllNotificationDataInternal( |
| 297 const GURL& origin, | 303 const GURL& origin, |
| 298 int64_t service_worker_registration_id, | 304 int64_t service_worker_registration_id, |
| 299 std::vector<NotificationDatabaseData>* notification_data_vector) const { | 305 std::vector<NotificationDatabaseData>* notification_data_vector) const { |
| 300 DCHECK(sequence_checker_.CalledOnValidSequence()); | 306 DCHECK(sequence_checker_.CalledOnValidSequence()); |
| 301 DCHECK(notification_data_vector); | 307 DCHECK(notification_data_vector); |
| 302 | 308 |
| 303 const std::string prefix = CreateDataPrefix(origin); | 309 const std::string prefix = CreateDataPrefix(origin); |
| 304 | 310 |
| 305 leveldb::Slice prefix_slice(prefix); | 311 leveldb::Slice prefix_slice(prefix); |
| 306 | 312 |
| 307 NotificationDatabaseData notification_database_data; | 313 NotificationDatabaseData notification_database_data; |
| 308 std::unique_ptr<leveldb::Iterator> iter( | 314 std::unique_ptr<leveldb::Iterator> iter( |
| 309 db_->NewIterator(leveldb::ReadOptions())); | 315 db_->NewIterator(leveldb::ReadOptions())); |
| 310 for (iter->Seek(prefix_slice); iter->Valid(); iter->Next()) { | 316 for (iter->Seek(prefix_slice); iter->Valid(); iter->Next()) { |
| 311 if (!iter->key().starts_with(prefix_slice)) | 317 if (!iter->key().starts_with(prefix_slice)) |
| 312 break; | 318 break; |
| 313 | 319 |
| 314 Status status = DeserializedNotificationData(iter->value().ToString(), | 320 Status status = DeserializedNotificationData(iter->value().ToString(), |
| 315 ¬ification_database_data); | 321 ¬ification_database_data); |
| 316 if (status != STATUS_OK) | 322 if (status != STATUS_OK) |
| 317 return status; | 323 return status; |
|
johnme
2016/09/08 15:21:50
I'm concerned that notifications that pre-date the
Peter Beverloo
2016/09/08 18:56:03
Why would it fail to deserialize? That'd work just
| |
| 318 | 324 |
| 319 if (service_worker_registration_id != kInvalidServiceWorkerRegistrationId && | 325 if (service_worker_registration_id != kInvalidServiceWorkerRegistrationId && |
| 320 notification_database_data.service_worker_registration_id != | 326 notification_database_data.service_worker_registration_id != |
| 321 service_worker_registration_id) { | 327 service_worker_registration_id) { |
| 322 continue; | 328 continue; |
| 323 } | 329 } |
| 324 | 330 |
| 325 notification_data_vector->push_back(notification_database_data); | 331 notification_data_vector->push_back(notification_database_data); |
| 326 } | 332 } |
| 327 | 333 |
| 328 return LevelDBStatusToStatus(iter->status()); | 334 return LevelDBStatusToStatus(iter->status()); |
| 329 } | 335 } |
| 330 | 336 |
| 331 NotificationDatabase::Status | 337 NotificationDatabase::Status |
| 332 NotificationDatabase::DeleteAllNotificationDataInternal( | 338 NotificationDatabase::DeleteAllNotificationDataInternal( |
| 333 const GURL& origin, | 339 const GURL& origin, |
| 334 const std::string& tag, | 340 const std::string& tag, |
| 335 int64_t service_worker_registration_id, | 341 int64_t service_worker_registration_id, |
| 336 std::set<int64_t>* deleted_notification_set) { | 342 std::set<std::string>* deleted_notification_ids) { |
| 337 DCHECK(sequence_checker_.CalledOnValidSequence()); | 343 DCHECK(sequence_checker_.CalledOnValidSequence()); |
| 338 DCHECK(deleted_notification_set); | 344 DCHECK(deleted_notification_ids); |
| 339 DCHECK(origin.is_valid()); | 345 DCHECK(origin.is_valid()); |
| 340 | 346 |
| 341 const std::string prefix = CreateDataPrefix(origin); | 347 const std::string prefix = CreateDataPrefix(origin); |
| 342 const bool should_deserialize = | |
| 343 service_worker_registration_id != kInvalidServiceWorkerRegistrationId || | |
| 344 !tag.empty(); | |
| 345 | 348 |
| 346 leveldb::Slice prefix_slice(prefix); | 349 leveldb::Slice prefix_slice(prefix); |
| 347 leveldb::WriteBatch batch; | 350 leveldb::WriteBatch batch; |
| 348 | 351 |
| 349 NotificationDatabaseData notification_database_data; | 352 NotificationDatabaseData notification_database_data; |
| 350 std::unique_ptr<leveldb::Iterator> iter( | 353 std::unique_ptr<leveldb::Iterator> iter( |
| 351 db_->NewIterator(leveldb::ReadOptions())); | 354 db_->NewIterator(leveldb::ReadOptions())); |
| 352 for (iter->Seek(prefix_slice); iter->Valid(); iter->Next()) { | 355 for (iter->Seek(prefix_slice); iter->Valid(); iter->Next()) { |
| 353 if (!iter->key().starts_with(prefix_slice)) | 356 if (!iter->key().starts_with(prefix_slice)) |
| 354 break; | 357 break; |
| 355 | 358 |
| 356 if (should_deserialize) { | 359 Status status = DeserializedNotificationData(iter->value().ToString(), |
| 357 Status status = DeserializedNotificationData(iter->value().ToString(), | 360 ¬ification_database_data); |
| 358 ¬ification_database_data); | 361 if (status != STATUS_OK) |
| 359 if (status != STATUS_OK) | 362 return status; |
| 360 return status; | |
| 361 | 363 |
| 362 if (!tag.empty() && | 364 if (!tag.empty() && |
| 363 notification_database_data.notification_data.tag != tag) { | 365 notification_database_data.notification_data.tag != tag) { |
| 364 continue; | 366 continue; |
| 365 } | |
| 366 | |
| 367 if (service_worker_registration_id != | |
| 368 kInvalidServiceWorkerRegistrationId && | |
| 369 notification_database_data.service_worker_registration_id != | |
| 370 service_worker_registration_id) { | |
| 371 continue; | |
| 372 } | |
| 373 } | 367 } |
| 374 | 368 |
| 375 leveldb::Slice notification_id_slice = iter->key(); | 369 if (service_worker_registration_id != kInvalidServiceWorkerRegistrationId && |
| 376 notification_id_slice.remove_prefix(prefix_slice.size()); | 370 notification_database_data.service_worker_registration_id != |
| 377 | 371 service_worker_registration_id) { |
| 378 int64_t notification_id = 0; | 372 continue; |
| 379 if (!base::StringToInt64(notification_id_slice.ToString(), | |
| 380 ¬ification_id)) { | |
| 381 return STATUS_ERROR_CORRUPTED; | |
| 382 } | 373 } |
| 383 | 374 |
| 384 deleted_notification_set->insert(notification_id); | |
| 385 batch.Delete(iter->key()); | 375 batch.Delete(iter->key()); |
| 376 deleted_notification_ids->insert( | |
| 377 notification_database_data.notification_id); | |
| 386 } | 378 } |
| 387 | 379 |
| 388 if (deleted_notification_set->empty()) | 380 if (deleted_notification_ids->empty()) |
| 389 return STATUS_OK; | 381 return STATUS_OK; |
| 390 | 382 |
| 391 return LevelDBStatusToStatus(db_->Write(leveldb::WriteOptions(), &batch)); | 383 return LevelDBStatusToStatus(db_->Write(leveldb::WriteOptions(), &batch)); |
| 392 } | 384 } |
| 393 | 385 |
| 394 } // namespace content | 386 } // namespace content |
| OLD | NEW |