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 |