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

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: Address more feedback Created 5 years, 1 month 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 database_.reset(new leveldb_proto::ProtoDatabaseImpl<OfflinePageEntry>(
155 DVLOG(1) << "Offline pages database init failed."; 111 background_task_runner_));
156 ResetDB(); 112 database_->Init(kDatabaseUMAClientName, database_dir_,
157 return; 113 base::Bind(&OfflinePageMetadataStoreImpl::LoadContinuation,
158 } 114 weak_ptr_factory_.GetWeakPtr(),
115 callback));
159 } 116 }
160 117
161 void OfflinePageMetadataStoreImpl::Load(const LoadCallback& callback) { 118 void OfflinePageMetadataStoreImpl::LoadContinuation(
162 if (!database_.get()) { 119 const LoadCallback& callback,
163 // Failing fast here, because DB is not initialized, and there is nothing 120 bool success) {
164 // that can be done about it. 121 if (!success) {
165 // Callback is invoked through message loop to avoid improper retry and 122 NotifyLoadResult(callback,
166 // simplify testing. 123 STORE_INIT_FAILED,
167 DVLOG(1) << "Offline pages database not available in Load."; 124 std::vector<OfflinePageItem>());
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::LoadDone,
131 weak_ptr_factory_.GetWeakPtr(),
132 callback));
133 }
134
135 void OfflinePageMetadataStoreImpl::LoadDone(
136 const LoadCallback& callback,
137 bool success,
138 scoped_ptr<std::vector<OfflinePageEntry>> entries) {
139 DCHECK(entries);
140
141 std::vector<OfflinePageItem> result;
142 LoadStatus status = LOAD_SUCCEEDED;
143
144 if (success) {
145 for (const auto& entry : *entries) {
146 OfflinePageItem item;
147 if (!OfflinePageItemFromEntry(entry, &item)) {
148 status = DATA_PARSING_FAILED;
149 result.clear();
150 break;
151 }
152 result.push_back(item);
153 }
154
155 } else {
156 status = STORE_LOAD_FAILED;
157 }
158
159 NotifyLoadResult(callback, status, result);
160 }
161
162 void OfflinePageMetadataStoreImpl::NotifyLoadResult(
163 const LoadCallback& callback,
164 LoadStatus status,
165 const std::vector<OfflinePageItem>& result) {
166 UMA_HISTOGRAM_ENUMERATION("OfflinePages.LoadStatus",
167 status,
168 OfflinePageMetadataStore::LOAD_STATUS_COUNT);
169 if (status == LOAD_SUCCEEDED) {
170 UMA_HISTOGRAM_COUNTS("OfflinePages.SavedPageCount", result.size());
171 } else {
172 DVLOG(1) << "Offline pages database loading failed: " << status;
173 database_.reset();
174 }
175 callback.Run(status, result);
176 } 176 }
177 177
178 void OfflinePageMetadataStoreImpl::AddOrUpdateOfflinePage( 178 void OfflinePageMetadataStoreImpl::AddOrUpdateOfflinePage(
179 const OfflinePageItem& offline_page_item, 179 const OfflinePageItem& offline_page_item,
180 const UpdateCallback& callback) { 180 const UpdateCallback& callback) {
181 scoped_ptr<ProtoDatabase<OfflinePageEntry>::KeyEntryVector> entries_to_save( 181 scoped_ptr<ProtoDatabase<OfflinePageEntry>::KeyEntryVector> entries_to_save(
182 new ProtoDatabase<OfflinePageEntry>::KeyEntryVector()); 182 new ProtoDatabase<OfflinePageEntry>::KeyEntryVector());
183 scoped_ptr<std::vector<std::string>> keys_to_remove( 183 scoped_ptr<std::vector<std::string>> keys_to_remove(
184 new std::vector<std::string>()); 184 new std::vector<std::string>());
185 185
(...skipping 30 matching lines...) Expand all
216 // Callback is invoked through message loop to avoid improper retry and 216 // Callback is invoked through message loop to avoid improper retry and
217 // simplify testing. 217 // simplify testing.
218 DVLOG(1) << "Offline pages database not available in UpdateEntries."; 218 DVLOG(1) << "Offline pages database not available in UpdateEntries.";
219 base::MessageLoop::current()->PostTask(FROM_HERE, 219 base::MessageLoop::current()->PostTask(FROM_HERE,
220 base::Bind(callback, false)); 220 base::Bind(callback, false));
221 return; 221 return;
222 } 222 }
223 223
224 database_->UpdateEntries( 224 database_->UpdateEntries(
225 entries_to_save.Pass(), keys_to_remove.Pass(), 225 entries_to_save.Pass(), keys_to_remove.Pass(),
226 base::Bind(&OnUpdateDone, callback, 226 base::Bind(&OfflinePageMetadataStoreImpl::UpdateDone,
227 base::Bind(&OfflinePageMetadataStoreImpl::ResetDB, 227 weak_ptr_factory_.GetWeakPtr(),
228 weak_ptr_factory_.GetWeakPtr()))); 228 callback));
229 } 229 }
230 230
231 void OfflinePageMetadataStoreImpl::ResetDB() { 231 void OfflinePageMetadataStoreImpl::UpdateDone(
232 const OfflinePageMetadataStore::UpdateCallback& callback,
233 bool success) {
234 if (!success) {
235 // TODO(fgorski): Add UMA for this case. Consider rebuilding the store.
236 DVLOG(1) << "Offline pages database update failed.";
237 }
238
239 callback.Run(success);
240 }
241
242 void OfflinePageMetadataStoreImpl::Reset(const ResetCallback& callback) {
243 database_->Destroy(
244 base::Bind(&OfflinePageMetadataStoreImpl::ResetDone,
245 weak_ptr_factory_.GetWeakPtr(),
246 callback));
247 }
248
249 void OfflinePageMetadataStoreImpl::ResetDone(
250 const ResetCallback& callback,
251 bool success) {
232 database_.reset(); 252 database_.reset();
233 weak_ptr_factory_.InvalidateWeakPtrs(); 253 weak_ptr_factory_.InvalidateWeakPtrs();
254 callback.Run(success);
234 } 255 }
235 256
236 } // namespace offline_pages 257 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698