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

Side by Side Diff: content/browser/indexed_db/indexed_db_internals_ui.cc

Issue 13949013: Implement download link in chrome://indexeddb-internals/ (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Improve constness for thread-proxied calls Created 7 years, 8 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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/indexed_db/indexed_db_internals_ui.h" 5 #include "content/browser/indexed_db/indexed_db_internals_ui.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string>
8 9
9 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/files/scoped_temp_dir.h"
10 #include "base/memory/scoped_vector.h" 12 #include "base/memory/scoped_vector.h"
11 #include "base/threading/platform_thread.h" 13 #include "base/threading/platform_thread.h"
12 #include "base/values.h" 14 #include "base/values.h"
15 #include "components/zip/zip.h"
16 #include "content/browser/indexed_db/indexed_db_context_impl.h"
13 #include "content/public/browser/browser_context.h" 17 #include "content/public/browser/browser_context.h"
14 #include "content/public/browser/browser_thread.h" 18 #include "content/public/browser/browser_thread.h"
19 #include "content/public/browser/download_manager.h"
20 #include "content/public/browser/download_url_parameters.h"
15 #include "content/public/browser/storage_partition.h" 21 #include "content/public/browser/storage_partition.h"
16 #include "content/public/browser/web_contents.h" 22 #include "content/public/browser/web_contents.h"
17 #include "content/public/browser/web_ui.h" 23 #include "content/public/browser/web_ui.h"
18 #include "content/public/browser/web_ui_data_source.h" 24 #include "content/public/browser/web_ui_data_source.h"
19 #include "content/public/common/url_constants.h" 25 #include "content/public/common/url_constants.h"
20 #include "grit/content_resources.h" 26 #include "grit/content_resources.h"
27 #include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
28 #include "webkit/base/file_path_string_conversions.h"
29 #include "webkit/database/database_util.h"
30
31 using webkit_database::DatabaseUtil;
21 32
22 namespace content { 33 namespace content {
23 34
24 IndexedDBInternalsUI::IndexedDBInternalsUI(WebUI* web_ui) 35 IndexedDBInternalsUI::IndexedDBInternalsUI(WebUI* web_ui)
25 : WebUIController(web_ui) { 36 : WebUIController(web_ui) {
26 web_ui->RegisterMessageCallback( 37 web_ui->RegisterMessageCallback(
27 "getAllOrigins", 38 "getAllOrigins",
28 base::Bind(&IndexedDBInternalsUI::GetAllOrigins, base::Unretained(this))); 39 base::Bind(&IndexedDBInternalsUI::GetAllOrigins, base::Unretained(this)));
29 40
41 web_ui->RegisterMessageCallback(
42 "downloadOriginData",
43 base::Bind(&IndexedDBInternalsUI::DownloadOriginData,
44 base::Unretained(this)));
45
30 WebUIDataSource* source = 46 WebUIDataSource* source =
31 WebUIDataSource::Create(kChromeUIIndexedDBInternalsHost); 47 WebUIDataSource::Create(kChromeUIIndexedDBInternalsHost);
32 source->SetUseJsonJSFormatV2(); 48 source->SetUseJsonJSFormatV2();
33 source->SetJsonPath("strings.js"); 49 source->SetJsonPath("strings.js");
34 source->AddResourcePath("indexeddb_internals.js", 50 source->AddResourcePath("indexeddb_internals.js",
35 IDR_INDEXED_DB_INTERNALS_JS); 51 IDR_INDEXED_DB_INTERNALS_JS);
36 source->AddResourcePath("indexeddb_internals.css", 52 source->AddResourcePath("indexeddb_internals.css",
37 IDR_INDEXED_DB_INTERNALS_CSS); 53 IDR_INDEXED_DB_INTERNALS_CSS);
38 source->SetDefaultResource(IDR_INDEXED_DB_INTERNALS_HTML); 54 source->SetDefaultResource(IDR_INDEXED_DB_INTERNALS_HTML);
39 55
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 base::Unretained(this), 89 base::Unretained(this),
74 base::Passed(&contexts), 90 base::Passed(&contexts),
75 base::Passed(&paths))); 91 base::Passed(&paths)));
76 } 92 }
77 93
78 bool HostNameComparator(const IndexedDBInfo& i, const IndexedDBInfo& j) { 94 bool HostNameComparator(const IndexedDBInfo& i, const IndexedDBInfo& j) {
79 return i.origin_.host() < j.origin_.host(); 95 return i.origin_.host() < j.origin_.host();
80 } 96 }
81 97
82 void IndexedDBInternalsUI::GetAllOriginsOnWebkitThread( 98 void IndexedDBInternalsUI::GetAllOriginsOnWebkitThread(
83 scoped_ptr<ContextList> contexts, 99 const scoped_ptr<ContextList> contexts,
84 scoped_ptr<std::vector<base::FilePath> > context_paths) { 100 const scoped_ptr<std::vector<base::FilePath> > context_paths) {
85 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); 101 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
86 DCHECK_EQ(contexts->size(), context_paths->size()); 102 DCHECK_EQ(contexts->size(), context_paths->size());
87 103
88 std::vector<base::FilePath>::const_iterator path_iter = 104 std::vector<base::FilePath>::const_iterator path_iter =
89 context_paths->begin(); 105 context_paths->begin();
90 for (ContextList::const_iterator iter = contexts->begin(); 106 for (ContextList::const_iterator iter = contexts->begin();
91 iter != contexts->end(); 107 iter != contexts->end();
92 ++iter, ++path_iter) { 108 ++iter, ++path_iter) {
93 IndexedDBContext* context = *iter; 109 IndexedDBContext* context = *iter;
94 const base::FilePath& context_path = *path_iter; 110 const base::FilePath& context_path = *path_iter;
(...skipping 22 matching lines...) Expand all
117 info->SetString("url", iter->origin_.spec()); 133 info->SetString("url", iter->origin_.spec());
118 info->SetDouble("size", iter->size_); 134 info->SetDouble("size", iter->size_);
119 info->SetDouble("last_modified", iter->last_modified_.ToJsTime()); 135 info->SetDouble("last_modified", iter->last_modified_.ToJsTime());
120 info->SetString("path", iter->path_.value()); 136 info->SetString("path", iter->path_.value());
121 urls.Append(info); 137 urls.Append(info);
122 } 138 }
123 web_ui()->CallJavascriptFunction( 139 web_ui()->CallJavascriptFunction(
124 "indexeddb.onOriginsReady", urls, base::StringValue(path.value())); 140 "indexeddb.onOriginsReady", urls, base::StringValue(path.value()));
125 } 141 }
126 142
143 static void FindContext(const base::FilePath& partition_path,
144 StoragePartition** result_partition,
145 scoped_refptr<IndexedDBContextImpl>* result_context,
146 StoragePartition* storage_partition) {
147 if (storage_partition->GetPath() == partition_path) {
148 *result_partition = storage_partition;
149 *result_context = static_cast<IndexedDBContextImpl*>(
150 storage_partition->GetIndexedDBContext());
151 }
152 }
153
154 void IndexedDBInternalsUI::DownloadOriginData(const base::ListValue* args) {
155 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
156
157 base::FilePath::StringType path_string;
158 if (!args->GetString(0, &path_string))
159 return;
160 const base::FilePath partition_path(path_string);
161
162 std::string url_string;
163 if (!args->GetString(1, &url_string))
164 return;
165 const GURL origin_url(url_string);
166
167 // search the origins to find the right context
168
169 BrowserContext* browser_context =
170 web_ui()->GetWebContents()->GetBrowserContext();
171
172 scoped_refptr<IndexedDBContextImpl> result_context;
173 StoragePartition* result_partition;
174 scoped_ptr<ContextList> contexts(new ContextList);
175 BrowserContext::StoragePartitionCallback cb = base::Bind(
176 &FindContext, partition_path, &result_partition, &result_context);
177 BrowserContext::ForEachStoragePartition(browser_context, cb);
178 DCHECK(result_partition);
179 DCHECK(result_context);
180
181 BrowserThread::PostTask(
182 BrowserThread::WEBKIT_DEPRECATED,
183 FROM_HERE,
184 base::Bind(&IndexedDBInternalsUI::DownloadOriginDataOnWebkitThread,
185 base::Unretained(this),
186 result_partition->GetPath(),
187 result_context,
188 origin_url));
189 }
190
191 void IndexedDBInternalsUI::DownloadOriginDataOnWebkitThread(
192 const base::FilePath& partition_path,
193 const scoped_refptr<IndexedDBContextImpl> context,
194 const GURL& origin_url) {
195 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
196
197 if (!context->HasOrigin(origin_url))
198 return;
199
200 context->ForceClose(origin_url);
201
202 base::ScopedTempDir temp_dir;
203 if (!temp_dir.CreateUniqueTempDir())
204 return;
205
206 // This will get cleaned up on the File thread after the download
207 // has completed.
208 base::FilePath temp_path = temp_dir.Take();
209
210 base::string16 origin_id = DatabaseUtil::GetOriginIdentifier(origin_url);
211 base::FilePath::StringType zip_name =
212 webkit_base::WebStringToFilePathString(origin_id);
213 base::FilePath zip_path = temp_path.Append(zip_name).AddExtension("zip");
214
215 // This happens on the "webkit" thread (which is really just the IndexedDB
216 // thread) as a simple way to avoid another script reopening the origin
217 // while we are zipping.
218 zip::Zip(context->GetFilePath(origin_url), zip_path, true);
219
220 BrowserThread::PostTask(BrowserThread::UI,
221 FROM_HERE,
222 base::Bind(&IndexedDBInternalsUI::OnDownloadDataReady,
223 base::Unretained(this),
224 partition_path,
225 origin_url,
226 temp_path,
227 zip_path));
228
229 LOG(ERROR) << "Origin data ready in " << zip_path.value();
jsbell 2013/04/18 22:08:52 Don't forget to remove this.
230 }
231
232 void IndexedDBInternalsUI::OnDownloadDataReady(
233 const base::FilePath& partition_path,
234 const GURL& origin_url,
235 const base::FilePath temp_path,
236 const base::FilePath zip_path) {
237 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
238 const GURL url = GURL("file://" + zip_path.value());
239 BrowserContext* browser_context =
240 web_ui()->GetWebContents()->GetBrowserContext();
241 scoped_ptr<DownloadUrlParameters> dl_params(
242 DownloadUrlParameters::FromWebContents(web_ui()->GetWebContents(), url));
243 DownloadManager* dlm = BrowserContext::GetDownloadManager(browser_context);
244
245 const GURL referrer(web_ui()->GetWebContents()->GetURL());
246 dl_params->set_referrer(
247 content::Referrer(referrer, WebKit::WebReferrerPolicyDefault));
248
249 // This is how to watch for the download to finish: first wait for it
250 // to start, then attach a DownloadItem::Observer to observe the
251 // state change to the finished state.
252 dl_params->set_callback(base::Bind(&IndexedDBInternalsUI::OnDownloadStarted,
253 base::Unretained(this),
254 partition_path,
255 origin_url,
256 temp_path));
257 dlm->DownloadUrl(dl_params.Pass());
258
259 LOG(ERROR) << "I'd start to download: " << url.spec();
jsbell 2013/04/18 22:08:52 Don't forget to remove this.
260 }
261
262 // The entire purpose of this class is to delete the temp file after
263 // the download is complete.
264 class FileDeleter : public DownloadItem::Observer {
265 public:
266 explicit FileDeleter(const base::FilePath& temp_dir) : temp_dir_(temp_dir) {}
267 virtual ~FileDeleter();
268
269 virtual void OnDownloadUpdated(DownloadItem* download) OVERRIDE;
270 virtual void OnDownloadOpened(DownloadItem* item) OVERRIDE {}
271 virtual void OnDownloadRemoved(DownloadItem* item) OVERRIDE {}
272 virtual void OnDownloadDestroyed(DownloadItem* item) OVERRIDE {}
273
274 private:
275 const base::FilePath temp_dir_;
276 };
277
278 void FileDeleter::OnDownloadUpdated(DownloadItem* item) {
279 switch (item->GetState()) {
280 case DownloadItem::IN_PROGRESS:
281 break;
282 case DownloadItem::COMPLETE:
283 case DownloadItem::CANCELLED:
284 case DownloadItem::INTERRUPTED: {
285 item->RemoveObserver(this);
286 BrowserThread::DeleteOnFileThread::Destruct(this);
287 } break;
jsbell 2013/04/18 22:08:52 Put break; inside braces?
288 default:
289 NOTREACHED();
290 }
291 }
292
293 FileDeleter::~FileDeleter() {
294 base::ScopedTempDir path;
295 (void) path.Set(temp_dir_);
296 }
297
298 void IndexedDBInternalsUI::OnDownloadStarted(
299 const base::FilePath& partition_path,
300 const GURL& origin_url,
301 const base::FilePath& temp_path,
302 DownloadItem* item,
303 net::Error error) {
304
305 if (error != net::OK) {
306 LOG(ERROR)
307 << "Error downloading database dump: " << net::ErrorToString(error);
jsbell 2013/04/18 22:08:52 Nit: Put first bit of log on previous line. (I thi
308 return;
309 }
310
311 item->AddObserver(new FileDeleter(temp_path));
312 web_ui()->CallJavascriptFunction("indexeddb.onOriginDownloadReady",
313 base::StringValue(partition_path.value()),
314 base::StringValue(origin_url.spec()));
315 }
316
127 } // namespace content 317 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/indexed_db/indexed_db_internals_ui.h ('k') | content/browser/resources/indexed_db/indexeddb_internals.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698