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

Side by Side Diff: content/browser/download/save_package.cc

Issue 2168403003: Avoid file IO on UI thread by moving more save-page-as stuff to the FILE thread. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Comment tweaks for base::nix::GetFileMimeType + two extra DCHECK_CURRENTLY_ON asserts in SavePackag… Created 4 years, 4 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/download/save_package.h" 5 #include "content/browser/download/save_package.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 1216 matching lines...) Expand 10 before | Expand all | Expand 10 after
1227 // Give backend the lists which contain all resource links that have local 1227 // Give backend the lists which contain all resource links that have local
1228 // storage, after which, render process will serialize DOM for generating 1228 // storage, after which, render process will serialize DOM for generating
1229 // HTML data. 1229 // HTML data.
1230 DoSavingProcess(); 1230 DoSavingProcess();
1231 } else { 1231 } else {
1232 // No savable frames and/or resources - treat it as user cancel. 1232 // No savable frames and/or resources - treat it as user cancel.
1233 Cancel(true); 1233 Cancel(true);
1234 } 1234 }
1235 } 1235 }
1236 1236
1237 // static
1237 base::FilePath SavePackage::GetSuggestedNameForSaveAs( 1238 base::FilePath SavePackage::GetSuggestedNameForSaveAs(
1239 const base::string16& title,
1240 const GURL& page_url,
1238 bool can_save_as_complete, 1241 bool can_save_as_complete,
1239 const std::string& contents_mime_type) { 1242 const std::string& contents_mime_type) {
1240 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1243 base::FilePath name_with_proper_ext = base::FilePath::FromUTF16Unsafe(title);
1241 base::FilePath name_with_proper_ext = base::FilePath::FromUTF16Unsafe(title_);
1242 1244
1243 // If the page's title matches its URL, use the URL. Try to use the last path 1245 // If the page's title matches its URL, use the URL. Try to use the last path
1244 // component or if there is none, the domain as the file name. 1246 // component or if there is none, the domain as the file name.
1245 // Normally we want to base the filename on the page title, or if it doesn't 1247 // Normally we want to base the filename on the page title, or if it doesn't
1246 // exist, on the URL. It's not easy to tell if the page has no title, because 1248 // exist, on the URL. It's not easy to tell if the page has no title, because
1247 // if the page has no title, WebContents::GetTitle() will return the page's 1249 // if the page has no title, WebContents::GetTitle() will return the page's
1248 // URL (adjusted for display purposes). Therefore, we convert the "title" 1250 // URL (adjusted for display purposes). Therefore, we convert the "title"
1249 // back to a URL, and if it matches the original page URL, we know the page 1251 // back to a URL, and if it matches the original page URL, we know the page
1250 // had no title (or had a title equal to its URL, which is fine to treat 1252 // had no title (or had a title equal to its URL, which is fine to treat
1251 // similarly). 1253 // similarly).
1252 if (title_ == url_formatter::FormatUrl(page_url_)) { 1254 if (title == url_formatter::FormatUrl(page_url)) {
1253 std::string url_path; 1255 std::string url_path;
1254 if (!page_url_.SchemeIs(url::kDataScheme)) { 1256 if (!page_url.SchemeIs(url::kDataScheme)) {
1255 std::vector<std::string> url_parts = base::SplitString( 1257 std::vector<std::string> url_parts = base::SplitString(
1256 page_url_.path(), "/", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); 1258 page_url.path(), "/", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
1257 if (!url_parts.empty()) { 1259 if (!url_parts.empty()) {
1258 for (int i = static_cast<int>(url_parts.size()) - 1; i >= 0; --i) { 1260 for (int i = static_cast<int>(url_parts.size()) - 1; i >= 0; --i) {
1259 url_path = url_parts[i]; 1261 url_path = url_parts[i];
1260 if (!url_path.empty()) 1262 if (!url_path.empty())
1261 break; 1263 break;
1262 } 1264 }
1263 } 1265 }
1264 if (url_path.empty()) 1266 if (url_path.empty())
1265 url_path = page_url_.host(); 1267 url_path = page_url.host();
1266 } else { 1268 } else {
1267 url_path = "dataurl"; 1269 url_path = "dataurl";
1268 } 1270 }
1269 name_with_proper_ext = base::FilePath::FromUTF8Unsafe(url_path); 1271 name_with_proper_ext = base::FilePath::FromUTF8Unsafe(url_path);
1270 } 1272 }
1271 1273
1272 // Ask user for getting final saving name. 1274 // Ask user for getting final saving name.
1273 name_with_proper_ext = EnsureMimeExtension(name_with_proper_ext, 1275 name_with_proper_ext = EnsureMimeExtension(name_with_proper_ext,
1274 contents_mime_type); 1276 contents_mime_type);
1275 // Adjust extension for complete types. 1277 // Adjust extension for complete types.
1276 if (can_save_as_complete) 1278 if (can_save_as_complete)
1277 name_with_proper_ext = EnsureHtmlExtension(name_with_proper_ext); 1279 name_with_proper_ext = EnsureHtmlExtension(name_with_proper_ext);
1278 1280
1279 base::FilePath::StringType file_name = name_with_proper_ext.value(); 1281 base::FilePath::StringType file_name = name_with_proper_ext.value();
1280 base::i18n::ReplaceIllegalCharactersInPath(&file_name, '_'); 1282 base::i18n::ReplaceIllegalCharactersInPath(&file_name, '_');
1281 return base::FilePath(file_name); 1283 return base::FilePath(file_name);
1282 } 1284 }
1283 1285
1284 // static 1286 // static
1285 base::FilePath SavePackage::EnsureHtmlExtension(const base::FilePath& name) { 1287 base::FilePath SavePackage::EnsureHtmlExtension(const base::FilePath& name) {
1288 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
1289
1286 base::FilePath::StringType ext = name.Extension(); 1290 base::FilePath::StringType ext = name.Extension();
1287 if (!ext.empty()) 1291 if (!ext.empty())
1288 ext.erase(ext.begin()); // Erase preceding '.'. 1292 ext.erase(ext.begin()); // Erase preceding '.'.
1289 std::string mime_type; 1293 std::string mime_type;
1290 if (!net::GetMimeTypeFromExtension(ext, &mime_type) || 1294 if (!net::GetMimeTypeFromExtension(ext, &mime_type) ||
1291 !CanSaveAsComplete(mime_type)) { 1295 !CanSaveAsComplete(mime_type)) {
1292 return base::FilePath(name.value() + FILE_PATH_LITERAL(".") + 1296 return base::FilePath(name.value() + FILE_PATH_LITERAL(".") +
1293 kDefaultHtmlExtension); 1297 kDefaultHtmlExtension);
1294 } 1298 }
1295 return name; 1299 return name;
1296 } 1300 }
1297 1301
1298 // static 1302 // static
1299 base::FilePath SavePackage::EnsureMimeExtension(const base::FilePath& name, 1303 base::FilePath SavePackage::EnsureMimeExtension(const base::FilePath& name,
1300 const std::string& contents_mime_type) { 1304 const std::string& contents_mime_type) {
1305 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
1306
1301 // Start extension at 1 to skip over period if non-empty. 1307 // Start extension at 1 to skip over period if non-empty.
1302 base::FilePath::StringType ext = name.Extension(); 1308 base::FilePath::StringType ext = name.Extension();
1303 if (!ext.empty()) 1309 if (!ext.empty())
1304 ext = ext.substr(1); 1310 ext = ext.substr(1);
1305 base::FilePath::StringType suggested_extension = 1311 base::FilePath::StringType suggested_extension =
1306 ExtensionForMimeType(contents_mime_type); 1312 ExtensionForMimeType(contents_mime_type);
1307 std::string mime_type; 1313 std::string mime_type;
1308 if (!suggested_extension.empty() && 1314 if (!suggested_extension.empty() &&
1309 !net::GetMimeTypeFromExtension(ext, &mime_type)) { 1315 !net::GetMimeTypeFromExtension(ext, &mime_type)) {
1310 // Extension is absent or needs to be updated. 1316 // Extension is absent or needs to be updated.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1342 base::FilePath download_save_dir; 1348 base::FilePath download_save_dir;
1343 bool skip_dir_check = false; 1349 bool skip_dir_check = false;
1344 auto* delegate = download_manager_->GetDelegate(); 1350 auto* delegate = download_manager_->GetDelegate();
1345 if (delegate) { 1351 if (delegate) {
1346 delegate->GetSaveDir( 1352 delegate->GetSaveDir(
1347 web_contents()->GetBrowserContext(), &website_save_dir, 1353 web_contents()->GetBrowserContext(), &website_save_dir,
1348 &download_save_dir, &skip_dir_check); 1354 &download_save_dir, &skip_dir_check);
1349 } 1355 }
1350 std::string mime_type = web_contents()->GetContentsMimeType(); 1356 std::string mime_type = web_contents()->GetContentsMimeType();
1351 bool can_save_as_complete = CanSaveAsComplete(mime_type); 1357 bool can_save_as_complete = CanSaveAsComplete(mime_type);
1352 base::FilePath suggested_filename =
1353 GetSuggestedNameForSaveAs(can_save_as_complete, mime_type);
1354 BrowserThread::PostTaskAndReplyWithResult( 1358 BrowserThread::PostTaskAndReplyWithResult(
1355 BrowserThread::FILE, FROM_HERE, 1359 BrowserThread::FILE, FROM_HERE,
1356 base::Bind(&SavePackage::CreateDirectoryOnFileThread, website_save_dir, 1360 base::Bind(&SavePackage::CreateDirectoryOnFileThread, title_, page_url_,
1357 download_save_dir, suggested_filename, skip_dir_check), 1361 can_save_as_complete, mime_type, website_save_dir,
1362 download_save_dir, skip_dir_check),
1358 base::Bind(&SavePackage::ContinueGetSaveInfo, this, 1363 base::Bind(&SavePackage::ContinueGetSaveInfo, this,
1359 can_save_as_complete)); 1364 can_save_as_complete));
1360 } 1365 }
1361 1366
1362 // static 1367 // static
1363 base::FilePath SavePackage::CreateDirectoryOnFileThread( 1368 base::FilePath SavePackage::CreateDirectoryOnFileThread(
1369 const base::string16& title,
1370 const GURL& page_url,
1371 bool can_save_as_complete,
1372 const std::string& mime_type,
1364 const base::FilePath& website_save_dir, 1373 const base::FilePath& website_save_dir,
1365 const base::FilePath& download_save_dir, 1374 const base::FilePath& download_save_dir,
1366 const base::FilePath& suggested_filename,
1367 bool skip_dir_check) { 1375 bool skip_dir_check) {
1368 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 1376 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
1369 1377
1378 base::FilePath suggested_filename = GetSuggestedNameForSaveAs(
1379 title, page_url, can_save_as_complete, mime_type);
1380
1370 base::FilePath save_dir; 1381 base::FilePath save_dir;
1371 // If the default html/websites save folder doesn't exist... 1382 // If the default html/websites save folder doesn't exist...
1372 // We skip the directory check for gdata directories on ChromeOS. 1383 // We skip the directory check for gdata directories on ChromeOS.
1373 if (!skip_dir_check && !base::DirectoryExists(website_save_dir)) { 1384 if (!skip_dir_check && !base::DirectoryExists(website_save_dir)) {
1374 // If the default download dir doesn't exist, create it. 1385 // If the default download dir doesn't exist, create it.
1375 if (!base::DirectoryExists(download_save_dir)) { 1386 if (!base::DirectoryExists(download_save_dir)) {
1376 bool res = base::CreateDirectory(download_save_dir); 1387 bool res = base::CreateDirectory(download_save_dir);
1377 DCHECK(res); 1388 DCHECK(res);
1378 } 1389 }
1379 save_dir = download_save_dir; 1390 save_dir = download_save_dir;
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1464 } 1475 }
1465 1476
1466 void SavePackage::FinalizeDownloadEntry() { 1477 void SavePackage::FinalizeDownloadEntry() {
1467 DCHECK(download_); 1478 DCHECK(download_);
1468 1479
1469 download_manager_->OnSavePackageSuccessfullyFinished(download_); 1480 download_manager_->OnSavePackageSuccessfullyFinished(download_);
1470 RemoveObservers(); 1481 RemoveObservers();
1471 } 1482 }
1472 1483
1473 } // namespace content 1484 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/download/save_package.h ('k') | content/browser/download/save_package_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698