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

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

Powered by Google App Engine
This is Rietveld 408576698