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

Side by Side Diff: chrome/browser/extensions/api/downloads/downloads_api.cc

Issue 14308002: Save memory in the downloads extension API. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: @r194365 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "chrome/browser/extensions/api/downloads/downloads_api.h" 5 #include "chrome/browser/extensions/api/downloads/downloads_api.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cctype> 8 #include <cctype>
9 #include <iterator> 9 #include <iterator>
10 #include <set> 10 #include <set>
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 } 516 }
517 517
518 class ExtensionDownloadsEventRouterData : public base::SupportsUserData::Data { 518 class ExtensionDownloadsEventRouterData : public base::SupportsUserData::Data {
519 public: 519 public:
520 static ExtensionDownloadsEventRouterData* Get(DownloadItem* download_item) { 520 static ExtensionDownloadsEventRouterData* Get(DownloadItem* download_item) {
521 base::SupportsUserData::Data* data = download_item->GetUserData(kKey); 521 base::SupportsUserData::Data* data = download_item->GetUserData(kKey);
522 return (data == NULL) ? NULL : 522 return (data == NULL) ? NULL :
523 static_cast<ExtensionDownloadsEventRouterData*>(data); 523 static_cast<ExtensionDownloadsEventRouterData*>(data);
524 } 524 }
525 525
526 static void Remove(DownloadItem* download_item) {
527 download_item->RemoveUserData(kKey);
528 }
529
526 explicit ExtensionDownloadsEventRouterData( 530 explicit ExtensionDownloadsEventRouterData(
527 DownloadItem* download_item, 531 DownloadItem* download_item,
528 scoped_ptr<base::DictionaryValue> json_item) 532 scoped_ptr<base::DictionaryValue> json_item)
529 : updated_(0), 533 : updated_(0),
530 changed_fired_(0), 534 changed_fired_(0),
531 json_(json_item.Pass()), 535 json_(json_item.Pass()),
532 determined_conflict_action_( 536 determined_conflict_action_(
533 extensions::api::downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY) { 537 extensions::api::downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY) {
534 download_item->SetUserData(kKey, this); 538 download_item->SetUserData(kKey, this);
535 } 539 }
(...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after
1239 // then the extension that was last installed wins. 1243 // then the extension that was last installed wins.
1240 1244
1241 void ExtensionDownloadsEventRouter::OnDeterminingFilename( 1245 void ExtensionDownloadsEventRouter::OnDeterminingFilename(
1242 DownloadItem* item, 1246 DownloadItem* item,
1243 const base::FilePath& suggested_path, 1247 const base::FilePath& suggested_path,
1244 const base::Closure& no_change, 1248 const base::Closure& no_change,
1245 const FilenameChangedCallback& change) { 1249 const FilenameChangedCallback& change) {
1246 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1250 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1247 ExtensionDownloadsEventRouterData* data = 1251 ExtensionDownloadsEventRouterData* data =
1248 ExtensionDownloadsEventRouterData::Get(item); 1252 ExtensionDownloadsEventRouterData::Get(item);
1253 if (!data) {
1254 no_change.Run();
1255 return;
1256 }
1249 data->ClearPendingDeterminers(); 1257 data->ClearPendingDeterminers();
1250 data->set_filename_change_callbacks(no_change, change); 1258 data->set_filename_change_callbacks(no_change, change);
1251 bool any_determiners = false; 1259 bool any_determiners = false;
1252 base::DictionaryValue* json = DownloadItemToJSON( 1260 base::DictionaryValue* json = DownloadItemToJSON(
1253 item, profile_->IsOffTheRecord()).release(); 1261 item, profile_->IsOffTheRecord()).release();
1254 json->SetString(kFilenameKey, suggested_path.LossyDisplayName()); 1262 json->SetString(kFilenameKey, suggested_path.LossyDisplayName());
1255 DispatchEvent(extensions::event_names::kOnDownloadDeterminingFilename, 1263 DispatchEvent(extensions::event_names::kOnDownloadDeterminingFilename,
1256 false, 1264 false,
1257 base::Bind(&OnDeterminingFilenameWillDispatchCallback, 1265 base::Bind(&OnDeterminingFilenameWillDispatchCallback,
1258 &any_determiners, 1266 &any_determiners,
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1306 // forever waiting for this ext_id to report. 1314 // forever waiting for this ext_id to report.
1307 *error = download_extension_errors::kInvalidFilenameError; 1315 *error = download_extension_errors::kInvalidFilenameError;
1308 return false; 1316 return false;
1309 } 1317 }
1310 return true; 1318 return true;
1311 } 1319 }
1312 1320
1313 void ExtensionDownloadsEventRouter::OnListenerRemoved( 1321 void ExtensionDownloadsEventRouter::OnListenerRemoved(
1314 const extensions::EventListenerInfo& details) { 1322 const extensions::EventListenerInfo& details) {
1315 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1323 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1316 if (details.event_name !=
1317 extensions::event_names::kOnDownloadDeterminingFilename)
1318 return;
1319 DownloadManager* manager = notifier_.GetManager(); 1324 DownloadManager* manager = notifier_.GetManager();
1320 if (!manager) 1325 if (!manager)
1321 return; 1326 return;
1327 bool determiner_removed = (
1328 details.event_name ==
1329 extensions::event_names::kOnDownloadDeterminingFilename);
Matt Perry 2013/04/17 02:01:28 nit: might help to put namespace events = extens
benjhayden 2013/04/18 18:17:55 Done.
1330 extensions::EventRouter* router = extensions::ExtensionSystem::Get(profile_)->
1331 event_router();
Matt Perry 2013/04/17 02:01:28 Use 4 space indent when wrapping a line like this.
benjhayden 2013/04/18 18:17:55 Done.
1332 bool any_listeners =
1333 router->HasEventListener(extensions::event_names::kOnDownloadChanged) ||
1334 router->HasEventListener(
1335 extensions::event_names::kOnDownloadDeterminingFilename);
1336 if (!determiner_removed && any_listeners)
1337 return;
1322 DownloadManager::DownloadVector items; 1338 DownloadManager::DownloadVector items;
1323 manager->GetAllDownloads(&items); 1339 manager->GetAllDownloads(&items);
1324 // Notify any items that may be waiting for callbacks from this
1325 // extension/determiner.
1326 for (DownloadManager::DownloadVector::const_iterator iter = 1340 for (DownloadManager::DownloadVector::const_iterator iter =
1327 items.begin(); 1341 items.begin();
1328 iter != items.end(); ++iter) { 1342 iter != items.end(); ++iter) {
1329 ExtensionDownloadsEventRouterData* data = 1343 ExtensionDownloadsEventRouterData* data =
1330 ExtensionDownloadsEventRouterData::Get(*iter); 1344 ExtensionDownloadsEventRouterData::Get(*iter);
1331 // This will almost always be a no-op, however, it is possible for an 1345 if (!data)
1332 // extension renderer to be unloaded while a download item is waiting 1346 continue;
1333 // for a determiner. In that case, the download item should proceed. 1347 if (determiner_removed) {
1334 if (data) 1348 // Notify any items that may be waiting for callbacks from this
1349 // extension/determiner. This will almost always be a no-op, however, it
1350 // is possible for an extension renderer to be unloaded while a download
1351 // item is waiting for a determiner. In that case, the download item
1352 // should proceed.
1335 data->DeterminerRemoved(details.extension_id); 1353 data->DeterminerRemoved(details.extension_id);
1354 }
1355 if (!any_listeners) {
1356 ExtensionDownloadsEventRouterData::Remove(*iter);
1357 }
1336 } 1358 }
1337 } 1359 }
1338 1360
1339 // That's all the methods that have to do with filename determination. The rest 1361 // That's all the methods that have to do with filename determination. The rest
1340 // have to do with the other, less special events. 1362 // have to do with the other, less special events.
1341 1363
1342 void ExtensionDownloadsEventRouter::OnDownloadCreated( 1364 void ExtensionDownloadsEventRouter::OnDownloadCreated(
1343 DownloadManager* manager, DownloadItem* download_item) { 1365 DownloadManager* manager, DownloadItem* download_item) {
1344 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1366 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1345 if (download_item->IsTemporary()) 1367 if (download_item->IsTemporary())
1346 return; 1368 return;
1347 1369
1370 extensions::EventRouter* router = extensions::ExtensionSystem::Get(profile_)->
1371 event_router();
1372 // Avoid allocating a bunch of memory in DownloadItemToJSON if it isn't going
1373 // to be used.
1374 if (!router ||
1375 (!router->HasEventListener(extensions::event_names::kOnDownloadCreated) &&
1376 !router->HasEventListener(extensions::event_names::kOnDownloadChanged) &&
1377 !router->HasEventListener(
1378 extensions::event_names::kOnDownloadDeterminingFilename))) {
1379 return;
1380 }
1348 scoped_ptr<base::DictionaryValue> json_item( 1381 scoped_ptr<base::DictionaryValue> json_item(
1349 DownloadItemToJSON(download_item, profile_->IsOffTheRecord())); 1382 DownloadItemToJSON(download_item, profile_->IsOffTheRecord()));
1350 DispatchEvent(extensions::event_names::kOnDownloadCreated, 1383 DispatchEvent(extensions::event_names::kOnDownloadCreated,
1351 true, 1384 true,
1352 extensions::Event::WillDispatchCallback(), 1385 extensions::Event::WillDispatchCallback(),
1353 json_item->DeepCopy()); 1386 json_item->DeepCopy());
1354 if (!ExtensionDownloadsEventRouterData::Get(download_item)) 1387 if (!ExtensionDownloadsEventRouterData::Get(download_item) &&
1388 (router->HasEventListener(extensions::event_names::kOnDownloadChanged) ||
1389 router->HasEventListener(
1390 extensions::event_names::kOnDownloadDeterminingFilename))) {
1355 new ExtensionDownloadsEventRouterData(download_item, json_item.Pass()); 1391 new ExtensionDownloadsEventRouterData(download_item, json_item.Pass());
1392 }
1356 } 1393 }
1357 1394
1358 void ExtensionDownloadsEventRouter::OnDownloadUpdated( 1395 void ExtensionDownloadsEventRouter::OnDownloadUpdated(
1359 DownloadManager* manager, DownloadItem* download_item) { 1396 DownloadManager* manager, DownloadItem* download_item) {
1360 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1397 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1361 if (download_item->IsTemporary()) 1398 extensions::EventRouter* router = extensions::ExtensionSystem::Get(profile_)->
1362 return; 1399 event_router();
1363
1364 ExtensionDownloadsEventRouterData* data = 1400 ExtensionDownloadsEventRouterData* data =
1365 ExtensionDownloadsEventRouterData::Get(download_item); 1401 ExtensionDownloadsEventRouterData::Get(download_item);
1402 if (download_item->IsTemporary() ||
1403 !router->HasEventListener(extensions::event_names::kOnDownloadChanged)) {
1404 return;
1405 }
1366 if (!data) { 1406 if (!data) {
1367 // The download_item probably transitioned from temporary to not temporary. 1407 // The download_item probably transitioned from temporary to not temporary,
1368 OnDownloadCreated(manager, download_item); 1408 // or else an event listener was added.
1369 return; 1409 data = new ExtensionDownloadsEventRouterData(
1410 download_item,
1411 scoped_ptr<base::DictionaryValue>(new base::DictionaryValue()));
1370 } 1412 }
1371 scoped_ptr<base::DictionaryValue> new_json(DownloadItemToJSON( 1413 scoped_ptr<base::DictionaryValue> new_json(DownloadItemToJSON(
1372 download_item, profile_->IsOffTheRecord())); 1414 download_item, profile_->IsOffTheRecord()));
1373 scoped_ptr<base::DictionaryValue> delta(new base::DictionaryValue()); 1415 scoped_ptr<base::DictionaryValue> delta(new base::DictionaryValue());
1374 delta->SetInteger(kIdKey, download_item->GetId()); 1416 delta->SetInteger(kIdKey, download_item->GetId());
1375 std::set<std::string> new_fields; 1417 std::set<std::string> new_fields;
1376 bool changed = false; 1418 bool changed = false;
1377 1419
1378 // For each field in the new json representation of the download_item except 1420 // For each field in the new json representation of the download_item except
1379 // the bytesReceived field, if the field has changed from the previous old 1421 // the bytesReceived field, if the field has changed from the previous old
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1456 DownloadsNotificationSource notification_source; 1498 DownloadsNotificationSource notification_source;
1457 notification_source.event_name = event_name; 1499 notification_source.event_name = event_name;
1458 notification_source.profile = profile_; 1500 notification_source.profile = profile_;
1459 content::Source<DownloadsNotificationSource> content_source( 1501 content::Source<DownloadsNotificationSource> content_source(
1460 &notification_source); 1502 &notification_source);
1461 content::NotificationService::current()->Notify( 1503 content::NotificationService::current()->Notify(
1462 chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT, 1504 chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT,
1463 content_source, 1505 content_source,
1464 content::Details<std::string>(&json_args)); 1506 content::Details<std::string>(&json_args));
1465 } 1507 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698