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

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: use FILE_PATH_LITERAL Created 7 years, 7 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 "content/browser/indexed_db/indexed_db_context_impl.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 "third_party/zlib/google/zip.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->IsInOriginSet(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 =
214 temp_path.Append(zip_name).AddExtension(FILE_PATH_LITERAL("zip"));
215
216 // This happens on the "webkit" thread (which is really just the IndexedDB
217 // thread) as a simple way to avoid another script reopening the origin
218 // while we are zipping.
219 zip::Zip(context->GetFilePath(origin_url), zip_path, true);
220
221 BrowserThread::PostTask(BrowserThread::UI,
222 FROM_HERE,
223 base::Bind(&IndexedDBInternalsUI::OnDownloadDataReady,
224 base::Unretained(this),
225 partition_path,
226 origin_url,
227 temp_path,
228 zip_path));
229 }
230
231 void IndexedDBInternalsUI::OnDownloadDataReady(
232 const base::FilePath& partition_path,
233 const GURL& origin_url,
234 const base::FilePath temp_path,
235 const base::FilePath zip_path) {
236 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
237 const GURL url = GURL(FILE_PATH_LITERAL("file://") + zip_path.value());
238 BrowserContext* browser_context =
239 web_ui()->GetWebContents()->GetBrowserContext();
240 scoped_ptr<DownloadUrlParameters> dl_params(
241 DownloadUrlParameters::FromWebContents(web_ui()->GetWebContents(), url));
242 DownloadManager* dlm = BrowserContext::GetDownloadManager(browser_context);
243
244 const GURL referrer(web_ui()->GetWebContents()->GetURL());
245 dl_params->set_referrer(
246 content::Referrer(referrer, WebKit::WebReferrerPolicyDefault));
247
248 // This is how to watch for the download to finish: first wait for it
249 // to start, then attach a DownloadItem::Observer to observe the
250 // state change to the finished state.
251 dl_params->set_callback(base::Bind(&IndexedDBInternalsUI::OnDownloadStarted,
252 base::Unretained(this),
253 partition_path,
254 origin_url,
255 temp_path));
256 dlm->DownloadUrl(dl_params.Pass());
257 }
258
259 // The entire purpose of this class is to delete the temp file after
260 // the download is complete.
261 class FileDeleter : public DownloadItem::Observer {
262 public:
263 explicit FileDeleter(const base::FilePath& temp_dir) : temp_dir_(temp_dir) {}
264 virtual ~FileDeleter();
265
266 virtual void OnDownloadUpdated(DownloadItem* download) OVERRIDE;
267 virtual void OnDownloadOpened(DownloadItem* item) OVERRIDE {}
268 virtual void OnDownloadRemoved(DownloadItem* item) OVERRIDE {}
269 virtual void OnDownloadDestroyed(DownloadItem* item) OVERRIDE {}
270
271 private:
272 const base::FilePath temp_dir_;
273 };
274
275 void FileDeleter::OnDownloadUpdated(DownloadItem* item) {
276 switch (item->GetState()) {
277 case DownloadItem::IN_PROGRESS:
278 break;
279 case DownloadItem::COMPLETE:
280 case DownloadItem::CANCELLED:
281 case DownloadItem::INTERRUPTED: {
282 item->RemoveObserver(this);
283 BrowserThread::DeleteOnFileThread::Destruct(this);
284 break;
285 }
286 default:
287 NOTREACHED();
288 }
289 }
290
291 FileDeleter::~FileDeleter() {
292 base::ScopedTempDir path;
293 bool will_delete ALLOW_UNUSED = path.Set(temp_dir_);
294 DCHECK(will_delete);
295 }
296
297 void IndexedDBInternalsUI::OnDownloadStarted(
298 const base::FilePath& partition_path,
299 const GURL& origin_url,
300 const base::FilePath& temp_path,
301 DownloadItem* item,
302 net::Error error) {
303
304 if (error != net::OK) {
305 LOG(ERROR) << "Error downloading database dump: "
306 << net::ErrorToString(error);
307 return;
308 }
309
310 item->AddObserver(new FileDeleter(temp_path));
311 web_ui()->CallJavascriptFunction("indexeddb.onOriginDownloadReady",
312 base::StringValue(partition_path.value()),
313 base::StringValue(origin_url.spec()));
314 }
315
127 } // namespace content 316 } // 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