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

Side by Side Diff: chrome/browser/extensions/extension_webrequest_api.cc

Issue 7693004: Added tracking of time spent waiting on extensions to the webRequest API. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: compile Created 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/extension_webrequest_api.h" 5 #include "chrome/browser/extensions/extension_webrequest_api.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/json/json_writer.h" 9 #include "base/json/json_writer.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
11 #include "base/string_number_conversions.h" 11 #include "base/string_number_conversions.h"
12 #include "base/utf_string_conversions.h" 12 #include "base/utf_string_conversions.h"
13 #include "base/values.h" 13 #include "base/values.h"
14 #include "chrome/browser/extensions/extension_event_router.h" 14 #include "chrome/browser/extensions/extension_event_router.h"
15 #include "chrome/browser/extensions/extension_info_map.h" 15 #include "chrome/browser/extensions/extension_info_map.h"
16 #include "chrome/browser/extensions/extension_prefs.h" 16 #include "chrome/browser/extensions/extension_prefs.h"
17 #include "chrome/browser/extensions/extension_service.h" 17 #include "chrome/browser/extensions/extension_service.h"
18 #include "chrome/browser/extensions/extension_tab_id_map.h" 18 #include "chrome/browser/extensions/extension_tab_id_map.h"
19 #include "chrome/browser/extensions/extension_webrequest_api_constants.h" 19 #include "chrome/browser/extensions/extension_webrequest_api_constants.h"
20 #include "chrome/browser/extensions/extension_webrequest_time_tracker.h"
20 #include "chrome/browser/profiles/profile.h" 21 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/renderer_host/chrome_render_message_filter.h" 22 #include "chrome/browser/renderer_host/chrome_render_message_filter.h"
22 #include "chrome/common/extensions/extension.h" 23 #include "chrome/common/extensions/extension.h"
23 #include "chrome/common/extensions/extension_error_utils.h" 24 #include "chrome/common/extensions/extension_error_utils.h"
24 #include "chrome/common/extensions/url_pattern.h" 25 #include "chrome/common/extensions/url_pattern.h"
25 #include "chrome/common/url_constants.h" 26 #include "chrome/common/url_constants.h"
26 #include "content/browser/browser_message_filter.h" 27 #include "content/browser/browser_message_filter.h"
27 #include "content/browser/browser_thread.h" 28 #include "content/browser/browser_thread.h"
28 #include "content/browser/renderer_host/resource_dispatcher_host.h" 29 #include "content/browser/renderer_host/resource_dispatcher_host.h"
29 #include "content/browser/renderer_host/resource_dispatcher_host_request_info.h" 30 #include "content/browser/renderer_host/resource_dispatcher_host_request_info.h"
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 // static 425 // static
425 void ExtensionWebRequestEventRouter::SetAllowChromeExtensionScheme() { 426 void ExtensionWebRequestEventRouter::SetAllowChromeExtensionScheme() {
426 allow_extension_scheme = true; 427 allow_extension_scheme = true;
427 } 428 }
428 429
429 // static 430 // static
430 ExtensionWebRequestEventRouter* ExtensionWebRequestEventRouter::GetInstance() { 431 ExtensionWebRequestEventRouter* ExtensionWebRequestEventRouter::GetInstance() {
431 return Singleton<ExtensionWebRequestEventRouter>::get(); 432 return Singleton<ExtensionWebRequestEventRouter>::get();
432 } 433 }
433 434
434 ExtensionWebRequestEventRouter::ExtensionWebRequestEventRouter() { 435 ExtensionWebRequestEventRouter::ExtensionWebRequestEventRouter()
436 : request_time_tracker_(new ExtensionWebRequestTimeTracker) {
435 } 437 }
436 438
437 ExtensionWebRequestEventRouter::~ExtensionWebRequestEventRouter() { 439 ExtensionWebRequestEventRouter::~ExtensionWebRequestEventRouter() {
438 } 440 }
439 441
440 int ExtensionWebRequestEventRouter::OnBeforeRequest( 442 int ExtensionWebRequestEventRouter::OnBeforeRequest(
441 void* profile, 443 void* profile,
442 ExtensionInfoMap* extension_info_map, 444 ExtensionInfoMap* extension_info_map,
443 net::URLRequest* request, 445 net::URLRequest* request,
444 net::CompletionCallback* callback, 446 net::CompletionCallback* callback,
445 GURL* new_url) { 447 GURL* new_url) {
446 // TODO(jochen): Figure out what to do with events from the system context. 448 // TODO(jochen): Figure out what to do with events from the system context.
447 if (!profile) 449 if (!profile)
448 return net::OK; 450 return net::OK;
449 451
450 if (!HasWebRequestScheme(request->url())) 452 if (!HasWebRequestScheme(request->url()))
451 return net::OK; 453 return net::OK;
452 454
455 request_time_tracker_->LogRequestStartTime(request->identifier(),
456 base::Time::Now(),
457 request->url());
458
453 bool is_main_frame = false; 459 bool is_main_frame = false;
454 int64 frame_id = -1; 460 int64 frame_id = -1;
455 int frame_id_for_extension = -1; 461 int frame_id_for_extension = -1;
456 int tab_id = -1; 462 int tab_id = -1;
457 int window_id = -1; 463 int window_id = -1;
458 ResourceType::Type resource_type = ResourceType::LAST_TYPE; 464 ResourceType::Type resource_type = ResourceType::LAST_TYPE;
459 ExtractRequestInfo(request, &is_main_frame, &frame_id, &tab_id, &window_id, 465 ExtractRequestInfo(request, &is_main_frame, &frame_id, &tab_id, &window_id,
460 &resource_type); 466 &resource_type);
461 frame_id_for_extension = GetFrameId(is_main_frame, frame_id); 467 frame_id_for_extension = GetFrameId(is_main_frame, frame_id);
462 468
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 void ExtensionWebRequestEventRouter::OnCompleted( 733 void ExtensionWebRequestEventRouter::OnCompleted(
728 void* profile, 734 void* profile,
729 ExtensionInfoMap* extension_info_map, 735 ExtensionInfoMap* extension_info_map,
730 net::URLRequest* request) { 736 net::URLRequest* request) {
731 if (!profile) 737 if (!profile)
732 return; 738 return;
733 739
734 if (!HasWebRequestScheme(request->url())) 740 if (!HasWebRequestScheme(request->url()))
735 return; 741 return;
736 742
743 request_time_tracker_->LogRequestEndTime(request->identifier(),
744 base::Time::Now());
745
737 DCHECK(request->status().status() == net::URLRequestStatus::SUCCESS); 746 DCHECK(request->status().status() == net::URLRequestStatus::SUCCESS);
738 747
739 DCHECK(!GetAndSetSignaled(request->identifier(), kOnCompleted)); 748 DCHECK(!GetAndSetSignaled(request->identifier(), kOnCompleted));
740 749
741 base::Time time(base::Time::Now()); 750 base::Time time(base::Time::Now());
742 751
743 int extra_info_spec = 0; 752 int extra_info_spec = 0;
744 std::vector<const EventListener*> listeners = 753 std::vector<const EventListener*> listeners =
745 GetMatchingListeners(profile, extension_info_map, 754 GetMatchingListeners(profile, extension_info_map,
746 keys::kOnCompleted, request, &extra_info_spec); 755 keys::kOnCompleted, request, &extra_info_spec);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
778 void ExtensionWebRequestEventRouter::OnErrorOccurred( 787 void ExtensionWebRequestEventRouter::OnErrorOccurred(
779 void* profile, 788 void* profile,
780 ExtensionInfoMap* extension_info_map, 789 ExtensionInfoMap* extension_info_map,
781 net::URLRequest* request) { 790 net::URLRequest* request) {
782 if (!profile) 791 if (!profile)
783 return; 792 return;
784 793
785 if (!HasWebRequestScheme(request->url())) 794 if (!HasWebRequestScheme(request->url()))
786 return; 795 return;
787 796
797 request_time_tracker_->LogRequestEndTime(request->identifier(),
798 base::Time::Now());
799
788 DCHECK(request->status().status() == net::URLRequestStatus::FAILED || 800 DCHECK(request->status().status() == net::URLRequestStatus::FAILED ||
789 request->status().status() == net::URLRequestStatus::CANCELED); 801 request->status().status() == net::URLRequestStatus::CANCELED);
790 802
791 DCHECK(!GetAndSetSignaled(request->identifier(), kOnErrorOccurred)); 803 DCHECK(!GetAndSetSignaled(request->identifier(), kOnErrorOccurred));
792 804
793 base::Time time(base::Time::Now()); 805 base::Time time(base::Time::Now());
794 806
795 int extra_info_spec = 0; 807 int extra_info_spec = 0;
796 std::vector<const EventListener*> listeners = 808 std::vector<const EventListener*> listeners =
797 GetMatchingListeners(profile, extension_info_map, 809 GetMatchingListeners(profile, extension_info_map,
(...skipping 16 matching lines...) Expand all
814 dict->SetDouble(keys::kTimeStampKey, time.ToDoubleT() * 1000); 826 dict->SetDouble(keys::kTimeStampKey, time.ToDoubleT() * 1000);
815 args.Append(dict); 827 args.Append(dict);
816 828
817 DispatchEvent(profile, request, listeners, args); 829 DispatchEvent(profile, request, listeners, args);
818 } 830 }
819 831
820 void ExtensionWebRequestEventRouter::OnURLRequestDestroyed( 832 void ExtensionWebRequestEventRouter::OnURLRequestDestroyed(
821 void* profile, net::URLRequest* request) { 833 void* profile, net::URLRequest* request) {
822 blocked_requests_.erase(request->identifier()); 834 blocked_requests_.erase(request->identifier());
823 signaled_requests_.erase(request->identifier()); 835 signaled_requests_.erase(request->identifier());
836
837 request_time_tracker_->LogRequestEndTime(request->identifier(),
838 base::Time::Now());
824 } 839 }
825 840
826 bool ExtensionWebRequestEventRouter::DispatchEvent( 841 bool ExtensionWebRequestEventRouter::DispatchEvent(
827 void* profile, 842 void* profile,
828 net::URLRequest* request, 843 net::URLRequest* request,
829 const std::vector<const EventListener*>& listeners, 844 const std::vector<const EventListener*>& listeners,
830 const ListValue& args) { 845 const ListValue& args) {
831 std::string json_args; 846 std::string json_args;
832 847
833 // TODO(mpcomplete): Consider consolidating common (extension_id,json_args) 848 // TODO(mpcomplete): Consider consolidating common (extension_id,json_args)
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
886 listener.extension_id = extension_id; 901 listener.extension_id = extension_id;
887 listener.sub_event_name = sub_event_name; 902 listener.sub_event_name = sub_event_name;
888 903
889 // The listener may have been removed (e.g. due to the process going away) 904 // The listener may have been removed (e.g. due to the process going away)
890 // before we got here. 905 // before we got here.
891 std::set<EventListener>::iterator found = 906 std::set<EventListener>::iterator found =
892 listeners_[profile][event_name].find(listener); 907 listeners_[profile][event_name].find(listener);
893 if (found != listeners_[profile][event_name].end()) 908 if (found != listeners_[profile][event_name].end())
894 found->blocked_requests.erase(request_id); 909 found->blocked_requests.erase(request_id);
895 910
896 DecrementBlockCount(profile, event_name, request_id, response); 911 DecrementBlockCount(profile, extension_id, event_name, request_id, response);
897 } 912 }
898 913
899 void ExtensionWebRequestEventRouter::AddEventListener( 914 void ExtensionWebRequestEventRouter::AddEventListener(
900 void* profile, 915 void* profile,
901 const std::string& extension_id, 916 const std::string& extension_id,
902 const std::string& extension_name, 917 const std::string& extension_name,
903 const std::string& event_name, 918 const std::string& event_name,
904 const std::string& sub_event_name, 919 const std::string& sub_event_name,
905 const RequestFilter& filter, 920 const RequestFilter& filter,
906 int extra_info_spec, 921 int extra_info_spec,
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
942 listeners_[profile][event_name].find(listener); 957 listeners_[profile][event_name].find(listener);
943 if (found == listeners_[profile][event_name].end()) 958 if (found == listeners_[profile][event_name].end())
944 return; 959 return;
945 960
946 CHECK_EQ(listeners_[profile][event_name].count(listener), 1u) << 961 CHECK_EQ(listeners_[profile][event_name].count(listener), 1u) <<
947 "extension=" << extension_id << " event=" << event_name; 962 "extension=" << extension_id << " event=" << event_name;
948 963
949 // Unblock any request that this event listener may have been blocking. 964 // Unblock any request that this event listener may have been blocking.
950 for (std::set<uint64>::iterator it = found->blocked_requests.begin(); 965 for (std::set<uint64>::iterator it = found->blocked_requests.begin();
951 it != found->blocked_requests.end(); ++it) { 966 it != found->blocked_requests.end(); ++it) {
952 DecrementBlockCount(profile, event_name, *it, NULL); 967 DecrementBlockCount(profile, extension_id, event_name, *it, NULL);
953 } 968 }
954 969
955 listeners_[profile][event_name].erase(listener); 970 listeners_[profile][event_name].erase(listener);
956 } 971 }
957 972
958 void ExtensionWebRequestEventRouter::OnOTRProfileCreated( 973 void ExtensionWebRequestEventRouter::OnOTRProfileCreated(
959 void* original_profile, void* otr_profile) { 974 void* original_profile, void* otr_profile) {
960 cross_profile_map_[original_profile] = otr_profile; 975 cross_profile_map_[original_profile] = otr_profile;
961 cross_profile_map_[otr_profile] = original_profile; 976 cross_profile_map_[otr_profile] = original_profile;
962 } 977 }
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
1230 request->net_log->AddEvent( 1245 request->net_log->AddEvent(
1231 net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, 1246 net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT,
1232 make_scoped_refptr( 1247 make_scoped_refptr(
1233 new NetLogExtensionIdParameter((*delta)->extension_id))); 1248 new NetLogExtensionIdParameter((*delta)->extension_id)));
1234 } 1249 }
1235 } 1250 }
1236 } 1251 }
1237 1252
1238 void ExtensionWebRequestEventRouter::DecrementBlockCount( 1253 void ExtensionWebRequestEventRouter::DecrementBlockCount(
1239 void* profile, 1254 void* profile,
1255 const std::string& extension_id,
1240 const std::string& event_name, 1256 const std::string& event_name,
1241 uint64 request_id, 1257 uint64 request_id,
1242 EventResponse* response) { 1258 EventResponse* response) {
1243 scoped_ptr<EventResponse> response_scoped(response); 1259 scoped_ptr<EventResponse> response_scoped(response);
1244 1260
1245 // It's possible that this request was deleted, or cancelled by a previous 1261 // It's possible that this request was deleted, or cancelled by a previous
1246 // event handler. If so, ignore this response. 1262 // event handler. If so, ignore this response.
1247 if (blocked_requests_.find(request_id) == blocked_requests_.end()) 1263 if (blocked_requests_.find(request_id) == blocked_requests_.end())
1248 return; 1264 return;
1249 1265
1250 BlockedRequest& blocked_request = blocked_requests_[request_id]; 1266 BlockedRequest& blocked_request = blocked_requests_[request_id];
1251 int num_handlers_blocking = --blocked_request.num_handlers_blocking; 1267 int num_handlers_blocking = --blocked_request.num_handlers_blocking;
1252 CHECK_GE(num_handlers_blocking, 0); 1268 CHECK_GE(num_handlers_blocking, 0);
1253 1269
1254 if (response) { 1270 if (response) {
1255 blocked_request.response_deltas.push_back( 1271 blocked_request.response_deltas.push_back(
1256 CalculateDelta(&blocked_request, response)); 1272 CalculateDelta(&blocked_request, response));
1257 } 1273 }
1258 1274
1275 base::TimeDelta block_time =
1276 base::Time::Now() - blocked_request.blocking_time;
1277 request_time_tracker_->IncrementExtensionBlockTime(
1278 extension_id, request_id, block_time);
1279
1259 if (num_handlers_blocking == 0) { 1280 if (num_handlers_blocking == 0) {
1260 // TODO(mpcomplete): it would be better if we accumulated the blocking times 1281 request_time_tracker_->IncrementTotalBlockTime(request_id, block_time);
1261 // for a given request over all events.
1262 HISTOGRAM_TIMES("Extensions.NetworkDelay",
1263 base::Time::Now() - blocked_request.blocking_time);
1264 1282
1265 EventResponseDeltas::iterator i; 1283 EventResponseDeltas::iterator i;
1266 EventResponseDeltas& deltas = blocked_request.response_deltas; 1284 EventResponseDeltas& deltas = blocked_request.response_deltas;
1267 1285
1268 bool canceled = false; 1286 bool canceled = false;
1269 for (i = deltas.begin(); i != deltas.end(); ++i) { 1287 for (i = deltas.begin(); i != deltas.end(); ++i) {
1270 if ((*i)->cancel) { 1288 if ((*i)->cancel) {
1271 canceled = true; 1289 canceled = true;
1272 blocked_request.net_log->AddEvent( 1290 blocked_request.net_log->AddEvent(
1273 net::NetLog::TYPE_CHROME_EXTENSION_ABORTED_REQUEST, 1291 net::NetLog::TYPE_CHROME_EXTENSION_ABORTED_REQUEST,
(...skipping 19 matching lines...) Expand all
1293 std::list<std::string>::iterator conflict_iter; 1311 std::list<std::string>::iterator conflict_iter;
1294 for (conflict_iter = conflicting_extensions.begin(); 1312 for (conflict_iter = conflicting_extensions.begin();
1295 conflict_iter != conflicting_extensions.end(); 1313 conflict_iter != conflicting_extensions.end();
1296 ++conflict_iter) { 1314 ++conflict_iter) {
1297 // TODO(mpcomplete): Do some fancy notification in the UI. 1315 // TODO(mpcomplete): Do some fancy notification in the UI.
1298 LOG(ERROR) << "Extension " << *conflict_iter << " was ignored in " 1316 LOG(ERROR) << "Extension " << *conflict_iter << " was ignored in "
1299 "webRequest API because of conflicting request " 1317 "webRequest API because of conflicting request "
1300 "modifications."; 1318 "modifications.";
1301 } 1319 }
1302 1320
1321 if (canceled) {
1322 request_time_tracker_->SetRequestCanceled(request_id);
1323 } else if (blocked_request.new_url &&
1324 !blocked_request.new_url->is_empty()) {
1325 request_time_tracker_->SetRequestRedirected(request_id);
1326 }
1327
1303 // This signals a failed request to subscribers of onErrorOccurred in case 1328 // This signals a failed request to subscribers of onErrorOccurred in case
1304 // a request is cancelled because net::ERR_EMPTY_RESPONSE cannot be 1329 // a request is cancelled because net::ERR_EMPTY_RESPONSE cannot be
1305 // distinguished from a regular failure. 1330 // distinguished from a regular failure.
1306 if (blocked_request.callback) { 1331 if (blocked_request.callback) {
1307 int rv = canceled ? net::ERR_EMPTY_RESPONSE : net::OK; 1332 int rv = canceled ? net::ERR_EMPTY_RESPONSE : net::OK;
1308 net::CompletionCallback* callback = blocked_request.callback; 1333 net::CompletionCallback* callback = blocked_request.callback;
1309 // Ensure that request is removed before callback because the callback 1334 // Ensure that request is removed before callback because the callback
1310 // might trigger the next event. 1335 // might trigger the next event.
1311 blocked_requests_.erase(request_id); 1336 blocked_requests_.erase(request_id);
1312 callback->Run(rv); 1337 callback->Run(rv);
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
1461 } 1486 }
1462 } 1487 }
1463 } 1488 }
1464 1489
1465 ExtensionWebRequestEventRouter::GetInstance()->OnEventHandled( 1490 ExtensionWebRequestEventRouter::GetInstance()->OnEventHandled(
1466 profile(), extension_id(), event_name, sub_event_name, request_id, 1491 profile(), extension_id(), event_name, sub_event_name, request_id,
1467 response.release()); 1492 response.release());
1468 1493
1469 return true; 1494 return true;
1470 } 1495 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_webrequest_api.h ('k') | chrome/browser/extensions/extension_webrequest_time_tracker.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698