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

Side by Side Diff: components/offline_pages/offline_page_metadata_store_impl.cc

Issue 1420003004: Wipe out offline page data on clearing cookie and site data (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 2 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 "components/offline_pages/offline_page_metadata_store_impl.h" 5 #include "components/offline_pages/offline_page_metadata_store_impl.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/files/file_path.h" 11 #include "base/files/file_path.h"
12 #include "base/location.h" 12 #include "base/location.h"
13 #include "base/message_loop/message_loop.h" 13 #include "base/message_loop/message_loop.h"
14 #include "base/metrics/histogram_macros.h" 14 #include "base/metrics/histogram_macros.h"
15 #include "base/sequenced_task_runner.h" 15 #include "base/sequenced_task_runner.h"
16 #include "base/strings/string_number_conversions.h" 16 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/utf_string_conversions.h" 17 #include "base/strings/utf_string_conversions.h"
18 #include "base/thread_task_runner_handle.h" 18 #include "base/thread_task_runner_handle.h"
19 #include "components/leveldb_proto/proto_database.h" 19 #include "components/leveldb_proto/proto_database_impl.h"
20 #include "components/offline_pages/offline_page_item.h" 20 #include "components/offline_pages/offline_page_item.h"
21 #include "components/offline_pages/proto/offline_pages.pb.h" 21 #include "components/offline_pages/proto/offline_pages.pb.h"
22 #include "third_party/leveldatabase/env_chromium.h" 22 #include "third_party/leveldatabase/env_chromium.h"
23 #include "third_party/leveldatabase/src/include/leveldb/db.h" 23 #include "third_party/leveldatabase/src/include/leveldb/db.h"
24 #include "url/gurl.h" 24 #include "url/gurl.h"
25 25
26 using leveldb_proto::ProtoDatabase; 26 using leveldb_proto::ProtoDatabase;
27 27
28 namespace { 28 namespace {
29 // Statistics are logged to UMA with this string as part of histogram name. They 29 // Statistics are logged to UMA with this string as part of histogram name. They
30 // can all be found under LevelDB.*.OfflinePageMetadataStore. Changing this 30 // can all be found under LevelDB.*.OfflinePageMetadataStore. Changing this
31 // needs to synchronize with histograms.xml, AND will also become incompatible 31 // needs to synchronize with histograms.xml, AND will also become incompatible
32 // with older browsers still reporting the previous values. 32 // with older browsers still reporting the previous values.
33 const char kDatabaseUMAClientName[] = "OfflinePageMetadataStore"; 33 const char kDatabaseUMAClientName[] = "OfflinePageMetadataStore";
34 } 34 }
35 35
36 namespace offline_pages { 36 namespace offline_pages {
37 namespace { 37 namespace {
38 38
39 typedef std::vector<OfflinePageEntry> OfflinePageEntryVector;
40
41 void OfflinePageItemToEntry(const OfflinePageItem& item, 39 void OfflinePageItemToEntry(const OfflinePageItem& item,
42 offline_pages::OfflinePageEntry* item_proto) { 40 offline_pages::OfflinePageEntry* item_proto) {
43 DCHECK(item_proto); 41 DCHECK(item_proto);
44 item_proto->set_url(item.url.spec()); 42 item_proto->set_url(item.url.spec());
45 item_proto->set_bookmark_id(item.bookmark_id); 43 item_proto->set_bookmark_id(item.bookmark_id);
46 item_proto->set_version(item.version); 44 item_proto->set_version(item.version);
47 std::string path_string; 45 std::string path_string;
48 #if defined(OS_POSIX) 46 #if defined(OS_POSIX)
49 path_string = item.file_path.value(); 47 path_string = item.file_path.value();
50 #elif defined(OS_WIN) 48 #elif defined(OS_WIN)
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 } 85 }
88 if (item_proto.has_access_count()) { 86 if (item_proto.has_access_count()) {
89 item->access_count = item_proto.access_count(); 87 item->access_count = item_proto.access_count();
90 } 88 }
91 if (item_proto.has_flags()) { 89 if (item_proto.has_flags()) {
92 item->flags = static_cast<OfflinePageItem::Flags>(item_proto.flags()); 90 item->flags = static_cast<OfflinePageItem::Flags>(item_proto.flags());
93 } 91 }
94 return true; 92 return true;
95 } 93 }
96 94
97 void OnLoadDone(const OfflinePageMetadataStore::LoadCallback& callback,
98 const base::Callback<void()>& failure_callback,
99 bool success,
100 scoped_ptr<OfflinePageEntryVector> entries) {
101 UMA_HISTOGRAM_BOOLEAN("OfflinePages.LoadSuccess", success);
102 if (!success) {
103 DVLOG(1) << "Offline pages database load failed.";
104 failure_callback.Run();
105 base::MessageLoop::current()->PostTask(
106 FROM_HERE, base::Bind(callback, false, std::vector<OfflinePageItem>()));
107 return;
108 }
109
110 std::vector<OfflinePageItem> result;
111 for (OfflinePageEntryVector::iterator it = entries->begin();
112 it != entries->end(); ++it) {
113 OfflinePageItem item;
114 if (OfflinePageItemFromEntry(*it, &item))
115 result.push_back(item);
116 else
117 DVLOG(1) << "Failed to create offline page item from proto.";
118 }
119 UMA_HISTOGRAM_COUNTS("OfflinePages.SavedPageCount", result.size());
120
121 base::MessageLoop::current()->PostTask(FROM_HERE,
122 base::Bind(callback, true, result));
123 }
124
125 void OnUpdateDone(const OfflinePageMetadataStore::UpdateCallback& callback,
126 const base::Callback<void()>& failure_callback,
127 bool success) {
128 if (!success) {
129 // TODO(fgorski): Add UMA for this case.
130 DVLOG(1) << "Offline pages database update failed.";
131 failure_callback.Run();
132 }
133
134 base::MessageLoop::current()->PostTask(FROM_HERE,
135 base::Bind(callback, success));
136 }
137
138 } // namespace 95 } // namespace
139 96
140 OfflinePageMetadataStoreImpl::OfflinePageMetadataStoreImpl( 97 OfflinePageMetadataStoreImpl::OfflinePageMetadataStoreImpl(
141 scoped_ptr<ProtoDatabase<OfflinePageEntry>> database, 98 scoped_refptr<base::SequencedTaskRunner> background_task_runner,
142 const base::FilePath& database_dir) 99 const base::FilePath& database_dir)
143 : database_(database.Pass()), weak_ptr_factory_(this) { 100 : background_task_runner_(background_task_runner),
144 database_->Init(kDatabaseUMAClientName, database_dir, 101 database_dir_(database_dir),
145 base::Bind(&OfflinePageMetadataStoreImpl::OnInitDone, 102 weak_ptr_factory_(this) {
146 weak_ptr_factory_.GetWeakPtr()));
147 } 103 }
148 104
149 OfflinePageMetadataStoreImpl::~OfflinePageMetadataStoreImpl() { 105 OfflinePageMetadataStoreImpl::~OfflinePageMetadataStoreImpl() {
150 } 106 }
151 107
152 void OfflinePageMetadataStoreImpl::OnInitDone(bool success) { 108 void OfflinePageMetadataStoreImpl::Load(const LoadCallback& callback) {
153 if (!success) { 109 // First initialize the database.
154 // TODO(fgorski): Add UMA for this case. 110 DCHECK(!database_);
155 DVLOG(1) << "Offline pages database init failed."; 111 database_.reset(new leveldb_proto::ProtoDatabaseImpl<OfflinePageEntry>(
156 ResetDB(); 112 background_task_runner_));
157 return; 113 database_->Init(kDatabaseUMAClientName, database_dir_,
158 } 114 base::Bind(&OfflinePageMetadataStoreImpl::LoadContinuation,
115 weak_ptr_factory_.GetWeakPtr(),
116 callback));
159 } 117 }
160 118
161 void OfflinePageMetadataStoreImpl::Load(const LoadCallback& callback) { 119 void OfflinePageMetadataStoreImpl::LoadContinuation(
162 if (!database_.get()) { 120 const LoadCallback& callback,
163 // Failing fast here, because DB is not initialized, and there is nothing 121 bool success) {
164 // that can be done about it. 122 if (!success) {
165 // Callback is invoked through message loop to avoid improper retry and 123 UMA_HISTOGRAM_BOOLEAN("OfflinePages.LoadSuccess", false);
fgorski 2015/10/23 20:55:03 does it make sense to database_.reset() here? to n
jianli 2015/10/26 21:42:43 Done.
166 // simplify testing. 124 callback.Run(false, std::vector<OfflinePageItem>());
167 DVLOG(1) << "Offline pages database not available in Load.";
168 base::MessageLoop::current()->PostTask(
169 FROM_HERE, base::Bind(callback, false, std::vector<OfflinePageItem>()));
170 return; 125 return;
171 } 126 }
172 127
173 database_->LoadEntries(base::Bind( 128 // After initialization, start to load the data.
174 &OnLoadDone, callback, base::Bind(&OfflinePageMetadataStoreImpl::ResetDB, 129 database_->LoadEntries(
175 weak_ptr_factory_.GetWeakPtr()))); 130 base::Bind(&OfflinePageMetadataStoreImpl::LoadCompleted,
131 weak_ptr_factory_.GetWeakPtr(),
132 callback));
133 }
134
135 void OfflinePageMetadataStoreImpl::LoadCompleted(
136 const LoadCallback& callback,
137 bool success,
138 scoped_ptr<std::vector<OfflinePageEntry>> entries) {
139 DCHECK(entries);
140
141 if (!success) {
142 DVLOG(1) << "Offline pages database load failed.";
143 UMA_HISTOGRAM_BOOLEAN("OfflinePages.LoadSuccess", false);
fgorski 2015/10/23 20:55:03 It would likely make sense to distinguish this cas
jianli 2015/10/26 21:42:43 Done.
144 callback.Run(false, std::vector<OfflinePageItem>());
145 return;
146 }
147
148 std::vector<OfflinePageItem> result;
149 for (const auto& entry : *entries) {
150 OfflinePageItem item;
151 if (!OfflinePageItemFromEntry(entry, &item)) {
fgorski 2015/10/23 20:55:03 Explain why you are changing this. This sounds too
jianli 2015/10/26 21:42:43 I don't think it is safe to allow partial load whe
152 DVLOG(1) << "Failed to create offline page item from proto.";
153 UMA_HISTOGRAM_BOOLEAN("OfflinePages.LoadSuccess", false);
154 callback.Run(false, std::vector<OfflinePageItem>());
155 return;
156 }
157 result.push_back(item);
158 }
159 UMA_HISTOGRAM_COUNTS("OfflinePages.SavedPageCount", result.size());
160
161 callback.Run(true, result);
176 } 162 }
177 163
178 void OfflinePageMetadataStoreImpl::AddOrUpdateOfflinePage( 164 void OfflinePageMetadataStoreImpl::AddOrUpdateOfflinePage(
179 const OfflinePageItem& offline_page_item, 165 const OfflinePageItem& offline_page_item,
180 const UpdateCallback& callback) { 166 const UpdateCallback& callback) {
181 scoped_ptr<ProtoDatabase<OfflinePageEntry>::KeyEntryVector> entries_to_save( 167 scoped_ptr<ProtoDatabase<OfflinePageEntry>::KeyEntryVector> entries_to_save(
182 new ProtoDatabase<OfflinePageEntry>::KeyEntryVector()); 168 new ProtoDatabase<OfflinePageEntry>::KeyEntryVector());
183 scoped_ptr<std::vector<std::string>> keys_to_remove( 169 scoped_ptr<std::vector<std::string>> keys_to_remove(
184 new std::vector<std::string>()); 170 new std::vector<std::string>());
185 171
(...skipping 30 matching lines...) Expand all
216 // Callback is invoked through message loop to avoid improper retry and 202 // Callback is invoked through message loop to avoid improper retry and
217 // simplify testing. 203 // simplify testing.
218 DVLOG(1) << "Offline pages database not available in UpdateEntries."; 204 DVLOG(1) << "Offline pages database not available in UpdateEntries.";
219 base::MessageLoop::current()->PostTask(FROM_HERE, 205 base::MessageLoop::current()->PostTask(FROM_HERE,
220 base::Bind(callback, false)); 206 base::Bind(callback, false));
221 return; 207 return;
222 } 208 }
223 209
224 database_->UpdateEntries( 210 database_->UpdateEntries(
225 entries_to_save.Pass(), keys_to_remove.Pass(), 211 entries_to_save.Pass(), keys_to_remove.Pass(),
226 base::Bind(&OnUpdateDone, callback, 212 base::Bind(&OfflinePageMetadataStoreImpl::UpdateCompleted,
227 base::Bind(&OfflinePageMetadataStoreImpl::ResetDB, 213 weak_ptr_factory_.GetWeakPtr(),
228 weak_ptr_factory_.GetWeakPtr()))); 214 callback));
229 } 215 }
230 216
231 void OfflinePageMetadataStoreImpl::ResetDB() { 217 void OfflinePageMetadataStoreImpl::UpdateCompleted(
218 const OfflinePageMetadataStore::UpdateCallback& callback,
219 bool success) {
220 if (!success) {
221 // TODO(fgorski): Add UMA for this case. Consider rebuilding the store.
222 DVLOG(1) << "Offline pages database update failed.";
223 }
224
225 callback.Run(success);
226 }
227
228 void OfflinePageMetadataStoreImpl::Reset(const ResetCallback& callback) {
229 database_->Destroy(
230 base::Bind(&OfflinePageMetadataStoreImpl::ResetCompleted,
231 weak_ptr_factory_.GetWeakPtr(),
fgorski 2015/10/23 20:55:03 nit: git cl format is your friend.
jianli 2015/10/26 21:42:43 Done.
232 callback));
233 }
234
235 void OfflinePageMetadataStoreImpl::ResetCompleted(
236 const ResetCallback& callback,
237 bool success) {
232 database_.reset(); 238 database_.reset();
233 weak_ptr_factory_.InvalidateWeakPtrs(); 239 weak_ptr_factory_.InvalidateWeakPtrs();
240 callback.Run(success);
234 } 241 }
235 242
236 } // namespace offline_pages 243 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698