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

Side by Side Diff: content/browser/notifications/notification_database.cc

Issue 2300093002: Make //content responsible for generating notification Ids (Closed)
Patch Set: Make //content responsible for generating notification Ids Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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 &notification_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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698