 Chromium Code Reviews
 Chromium Code Reviews Issue 1413543005:
  Use FrameTreeNode ID as frameId in extension APIs  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master
    
  
    Issue 1413543005:
  Use FrameTreeNode ID as frameId in extension APIs  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master| OLD | NEW | 
|---|---|
| 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 "extensions/browser/api/web_request/web_request_api.h" | 5 #include "extensions/browser/api/web_request/web_request_api.h" | 
| 6 | 6 | 
| 7 #include <algorithm> | 7 #include <algorithm> | 
| 8 #include <utility> | 8 #include <utility> | 
| 9 #include <vector> | 9 #include <vector> | 
| 10 | 10 | 
| (...skipping 20 matching lines...) Expand all Loading... | |
| 31 #include "extensions/browser/api/declarative_webrequest/request_stage.h" | 31 #include "extensions/browser/api/declarative_webrequest/request_stage.h" | 
| 32 #include "extensions/browser/api/declarative_webrequest/webrequest_constants.h" | 32 #include "extensions/browser/api/declarative_webrequest/webrequest_constants.h" | 
| 33 #include "extensions/browser/api/declarative_webrequest/webrequest_rules_registr y.h" | 33 #include "extensions/browser/api/declarative_webrequest/webrequest_rules_registr y.h" | 
| 34 #include "extensions/browser/api/extensions_api_client.h" | 34 #include "extensions/browser/api/extensions_api_client.h" | 
| 35 #include "extensions/browser/api/web_request/upload_data_presenter.h" | 35 #include "extensions/browser/api/web_request/upload_data_presenter.h" | 
| 36 #include "extensions/browser/api/web_request/web_request_api_constants.h" | 36 #include "extensions/browser/api/web_request/web_request_api_constants.h" | 
| 37 #include "extensions/browser/api/web_request/web_request_api_helpers.h" | 37 #include "extensions/browser/api/web_request/web_request_api_helpers.h" | 
| 38 #include "extensions/browser/api/web_request/web_request_event_router_delegate.h " | 38 #include "extensions/browser/api/web_request/web_request_event_router_delegate.h " | 
| 39 #include "extensions/browser/api/web_request/web_request_time_tracker.h" | 39 #include "extensions/browser/api/web_request/web_request_time_tracker.h" | 
| 40 #include "extensions/browser/event_router.h" | 40 #include "extensions/browser/event_router.h" | 
| 41 #include "extensions/browser/extension_api_frame_id_map.h" | |
| 41 #include "extensions/browser/extension_prefs.h" | 42 #include "extensions/browser/extension_prefs.h" | 
| 42 #include "extensions/browser/extension_registry.h" | 43 #include "extensions/browser/extension_registry.h" | 
| 43 #include "extensions/browser/extension_system.h" | 44 #include "extensions/browser/extension_system.h" | 
| 44 #include "extensions/browser/extensions_browser_client.h" | 45 #include "extensions/browser/extensions_browser_client.h" | 
| 45 #include "extensions/browser/guest_view/guest_view_events.h" | 46 #include "extensions/browser/guest_view/guest_view_events.h" | 
| 46 #include "extensions/browser/guest_view/web_view/web_view_constants.h" | 47 #include "extensions/browser/guest_view/web_view/web_view_constants.h" | 
| 47 #include "extensions/browser/guest_view/web_view/web_view_renderer_state.h" | 48 #include "extensions/browser/guest_view/web_view/web_view_renderer_state.h" | 
| 48 #include "extensions/browser/info_map.h" | 49 #include "extensions/browser/info_map.h" | 
| 49 #include "extensions/browser/io_thread_extension_message_filter.h" | 50 #include "extensions/browser/io_thread_extension_message_filter.h" | 
| 50 #include "extensions/browser/runtime_data.h" | 51 #include "extensions/browser/runtime_data.h" | 
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 122 return keys::kOnResponseStarted; | 123 return keys::kOnResponseStarted; | 
| 123 case ExtensionWebRequestEventRouter::kOnErrorOccurred: | 124 case ExtensionWebRequestEventRouter::kOnErrorOccurred: | 
| 124 return keys::kOnErrorOccurred; | 125 return keys::kOnErrorOccurred; | 
| 125 case ExtensionWebRequestEventRouter::kOnCompleted: | 126 case ExtensionWebRequestEventRouter::kOnCompleted: | 
| 126 return keys::kOnCompleted; | 127 return keys::kOnCompleted; | 
| 127 } | 128 } | 
| 128 NOTREACHED(); | 129 NOTREACHED(); | 
| 129 return "Not reached"; | 130 return "Not reached"; | 
| 130 } | 131 } | 
| 131 | 132 | 
| 132 int GetFrameId(bool is_main_frame, int frame_id) { | |
| 133 return is_main_frame ? 0 : frame_id; | |
| 134 } | |
| 135 | |
| 136 bool IsWebRequestEvent(const std::string& event_name) { | 133 bool IsWebRequestEvent(const std::string& event_name) { | 
| 137 std::string web_request_event_name(event_name); | 134 std::string web_request_event_name(event_name); | 
| 138 if (base::StartsWith(web_request_event_name, | 135 if (base::StartsWith(web_request_event_name, | 
| 139 webview::kWebViewEventPrefix, | 136 webview::kWebViewEventPrefix, | 
| 140 base::CompareCase::SENSITIVE)) { | 137 base::CompareCase::SENSITIVE)) { | 
| 141 web_request_event_name.replace( | 138 web_request_event_name.replace( | 
| 142 0, strlen(webview::kWebViewEventPrefix), kWebRequestEventPrefix); | 139 0, strlen(webview::kWebViewEventPrefix), kWebRequestEventPrefix); | 
| 143 } | 140 } | 
| 144 const auto web_request_events_end = | 141 const auto web_request_events_end = | 
| 145 kWebRequestEvents + arraysize(kWebRequestEvents); | 142 kWebRequestEvents + arraysize(kWebRequestEvents); | 
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 196 WebViewRendererState::WebViewInfo* web_view_info) { | 193 WebViewRendererState::WebViewInfo* web_view_info) { | 
| 197 int render_process_host_id = -1; | 194 int render_process_host_id = -1; | 
| 198 int routing_id = -1; | 195 int routing_id = -1; | 
| 199 ExtractRequestRoutingInfo(request, &render_process_host_id, &routing_id); | 196 ExtractRequestRoutingInfo(request, &render_process_host_id, &routing_id); | 
| 200 return WebViewRendererState::GetInstance()->GetInfo( | 197 return WebViewRendererState::GetInstance()->GetInfo( | 
| 201 render_process_host_id, routing_id, web_view_info); | 198 render_process_host_id, routing_id, web_view_info); | 
| 202 } | 199 } | 
| 203 | 200 | 
| 204 void ExtractRequestInfoDetails(const net::URLRequest* request, | 201 void ExtractRequestInfoDetails(const net::URLRequest* request, | 
| 205 bool* is_main_frame, | 202 bool* is_main_frame, | 
| 206 int* frame_id, | 203 int* render_frame_id, | 
| 207 bool* parent_is_main_frame, | |
| 208 int* parent_frame_id, | |
| 209 int* render_process_host_id, | 204 int* render_process_host_id, | 
| 210 int* routing_id, | 205 int* routing_id, | 
| 211 ResourceType* resource_type) { | 206 ResourceType* resource_type) { | 
| 212 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); | 207 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); | 
| 213 if (!info) | 208 if (!info) | 
| 214 return; | 209 return; | 
| 215 | 210 | 
| 216 *frame_id = info->GetRenderFrameID(); | 211 *render_frame_id = info->GetRenderFrameID(); | 
| 217 *is_main_frame = info->IsMainFrame(); | 212 *is_main_frame = info->IsMainFrame(); | 
| 218 *parent_frame_id = info->GetParentRenderFrameID(); | |
| 219 *parent_is_main_frame = info->ParentIsMainFrame(); | |
| 220 *render_process_host_id = info->GetChildID(); | 213 *render_process_host_id = info->GetChildID(); | 
| 221 *routing_id = info->GetRouteID(); | 214 *routing_id = info->GetRouteID(); | 
| 222 | 215 | 
| 223 // Restrict the resource type to the values we care about. | 216 // Restrict the resource type to the values we care about. | 
| 224 if (helpers::IsRelevantResourceType(info->GetResourceType())) | 217 if (helpers::IsRelevantResourceType(info->GetResourceType())) | 
| 225 *resource_type = info->GetResourceType(); | 218 *resource_type = info->GetResourceType(); | 
| 226 else | 219 else | 
| 227 *resource_type = content::RESOURCE_TYPE_LAST_TYPE; | 220 *resource_type = content::RESOURCE_TYPE_LAST_TYPE; | 
| 228 } | 221 } | 
| 229 | 222 | 
| 223 // Extract a pair of IDs to identify the RenderFrameHost and store it in |dict|. | |
| 
battre
2015/12/23 14:02:12
Comment needs to be updated because this function
 
robwu
2015/12/26 11:05:50
Done.
 | |
| 224 // The caller will then map this pair of IDs frame IDs for the public extension | |
| 225 // API, and finally store these IDs in |dict| using ExtractApiFrameIdInfo. | |
| 226 void ExtractRenderFrameInfo(base::DictionaryValue* dict, | |
| 227 int* render_process_id, | |
| 228 int* render_frame_id) { | |
| 229 if (!dict->GetInteger(keys::kFrameIdKey, render_frame_id) || | |
| 230 !dict->GetInteger(keys::kProcessIdKey, render_process_id)) { | |
| 231 *render_process_id = -1; | |
| 232 *render_frame_id = -1; | |
| 233 } | |
| 234 // ExtractApiFrameIdInfo will overwrite kFrameIdKey, so it's not removed here. | |
| 235 dict->Remove(keys::kProcessIdKey, nullptr); | |
| 236 } | |
| 237 | |
| 238 // Extracts the extension frame IDs from |extension_api_frame_id| and store it | |
| 239 // |dict|. See ExtractRenderFrameInfo() for more details. | |
| 240 void ExtractApiFrameIdInfo(const ExtensionApiFrameId& extension_api_frame_id, | |
| 241 base::DictionaryValue* dict) { | |
| 242 dict->SetInteger(keys::kFrameIdKey, extension_api_frame_id.frame_id); | |
| 243 dict->SetInteger(keys::kParentFrameIdKey, | |
| 244 extension_api_frame_id.parent_frame_id); | |
| 245 } | |
| 246 | |
| 230 // Extracts the body from |request| and writes the data into |out|. | 247 // Extracts the body from |request| and writes the data into |out|. | 
| 231 void ExtractRequestInfoBody(const net::URLRequest* request, | 248 void ExtractRequestInfoBody(const net::URLRequest* request, | 
| 232 base::DictionaryValue* out) { | 249 base::DictionaryValue* out) { | 
| 233 const net::UploadDataStream* upload_data = request->get_upload(); | 250 const net::UploadDataStream* upload_data = request->get_upload(); | 
| 234 if (!upload_data || | 251 if (!upload_data || | 
| 235 (request->method() != "POST" && request->method() != "PUT")) { | 252 (request->method() != "POST" && request->method() != "PUT")) { | 
| 236 return; // Need to exit without "out->Set(keys::kRequestBodyKey, ...);" . | 253 return; // Need to exit without "out->Set(keys::kRequestBodyKey, ...);" . | 
| 237 } | 254 } | 
| 238 | 255 | 
| 239 base::DictionaryValue* request_body = new base::DictionaryValue(); | 256 base::DictionaryValue* request_body = new base::DictionaryValue(); | 
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 352 const WebViewRendererState::WebViewInfo& web_view_info, | 369 const WebViewRendererState::WebViewInfo& web_view_info, | 
| 353 scoped_ptr<base::DictionaryValue> event_argument) { | 370 scoped_ptr<base::DictionaryValue> event_argument) { | 
| 354 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 371 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 
| 355 | 372 | 
| 356 content::BrowserContext* browser_context = | 373 content::BrowserContext* browser_context = | 
| 357 reinterpret_cast<content::BrowserContext*>(browser_context_id); | 374 reinterpret_cast<content::BrowserContext*>(browser_context_id); | 
| 358 if (!ExtensionsBrowserClient::Get()->IsValidContext(browser_context)) | 375 if (!ExtensionsBrowserClient::Get()->IsValidContext(browser_context)) | 
| 359 return; | 376 return; | 
| 360 | 377 | 
| 361 scoped_ptr<base::ListValue> event_args(new base::ListValue); | 378 scoped_ptr<base::ListValue> event_args(new base::ListValue); | 
| 379 int render_process_host_id = -1; | |
| 380 int render_frame_id = -1; | |
| 381 ExtractRenderFrameInfo(event_argument.get(), &render_process_host_id, | |
| 382 &render_frame_id); | |
| 383 const ExtensionApiFrameId& extension_api_frame_id = | |
| 
battre
2015/12/23 14:02:12
why a reference (const EAFI&)?
 
robwu
2015/12/26 11:05:50
Previously GetFrameId returned EAFI&. I've now rem
 | |
| 384 ExtensionApiFrameIdMap::Get()->GetFrameId(render_process_host_id, | |
| 385 render_frame_id); | |
| 386 ExtractApiFrameIdInfo(extension_api_frame_id, event_argument.get()); | |
| 362 event_args->Append(event_argument.release()); | 387 event_args->Append(event_argument.release()); | 
| 363 | 388 | 
| 364 EventRouter* event_router = EventRouter::Get(browser_context); | 389 EventRouter* event_router = EventRouter::Get(browser_context); | 
| 365 | 390 | 
| 366 EventFilteringInfo event_filtering_info; | 391 EventFilteringInfo event_filtering_info; | 
| 367 | 392 | 
| 368 events::HistogramValue histogram_value = events::UNKNOWN; | 393 events::HistogramValue histogram_value = events::UNKNOWN; | 
| 369 std::string event_name; | 394 std::string event_name; | 
| 370 // The instance ID uniquely identifies a <webview> instance within an embedder | 395 // The instance ID uniquely identifies a <webview> instance within an embedder | 
| 371 // process. We use a filter here so that only event listeners for a particular | 396 // process. We use a filter here so that only event listeners for a particular | 
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 518 return sub_event_name < that.sub_event_name; | 543 return sub_event_name < that.sub_event_name; | 
| 519 | 544 | 
| 520 if (web_view_instance_id != that.web_view_instance_id) | 545 if (web_view_instance_id != that.web_view_instance_id) | 
| 521 return web_view_instance_id < that.web_view_instance_id; | 546 return web_view_instance_id < that.web_view_instance_id; | 
| 522 | 547 | 
| 523 if (web_view_instance_id == 0) { | 548 if (web_view_instance_id == 0) { | 
| 524 // Do not filter by process ID for non-webviews, because this comparator | 549 // Do not filter by process ID for non-webviews, because this comparator | 
| 525 // is also used to find and remove an event listener when an extension is | 550 // is also used to find and remove an event listener when an extension is | 
| 526 // unloaded. At this point, the event listener cannot be mapped back to | 551 // unloaded. At this point, the event listener cannot be mapped back to | 
| 527 // the original process, so 0 is used instead of the actual process ID. | 552 // the original process, so 0 is used instead of the actual process ID. | 
| 528 DCHECK(embedder_process_id == 0 || that.embedder_process_id == 0); | 553 if (embedder_process_id == 0 || that.embedder_process_id == 0) | 
| 529 return false; | 554 return false; | 
| 530 } | 555 } | 
| 531 | 556 | 
| 532 if (embedder_process_id != that.embedder_process_id) | 557 if (embedder_process_id != that.embedder_process_id) | 
| 533 return embedder_process_id < that.embedder_process_id; | 558 return embedder_process_id < that.embedder_process_id; | 
| 534 | 559 | 
| 535 return false; | 560 return false; | 
| 536 } | 561 } | 
| 537 | 562 | 
| 538 EventListener() | 563 EventListener() | 
| 539 : histogram_value(events::UNKNOWN), | 564 : histogram_value(events::UNKNOWN), | 
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 735 if (rules_registry.get()) | 760 if (rules_registry.get()) | 
| 736 rules_registries_[key] = rules_registry; | 761 rules_registries_[key] = rules_registry; | 
| 737 else | 762 else | 
| 738 rules_registries_.erase(key); | 763 rules_registries_.erase(key); | 
| 739 } | 764 } | 
| 740 | 765 | 
| 741 void ExtensionWebRequestEventRouter::ExtractRequestInfo( | 766 void ExtensionWebRequestEventRouter::ExtractRequestInfo( | 
| 742 const net::URLRequest* request, | 767 const net::URLRequest* request, | 
| 743 base::DictionaryValue* out) { | 768 base::DictionaryValue* out) { | 
| 744 bool is_main_frame = false; | 769 bool is_main_frame = false; | 
| 745 int frame_id = -1; | 770 int render_frame_id = -1; | 
| 746 bool parent_is_main_frame = false; | |
| 747 int parent_frame_id = -1; | |
| 748 int frame_id_for_extension = -1; | |
| 749 int parent_frame_id_for_extension = -1; | |
| 750 int render_process_host_id = -1; | 771 int render_process_host_id = -1; | 
| 751 int routing_id = -1; | 772 int routing_id = -1; | 
| 752 ResourceType resource_type = content::RESOURCE_TYPE_LAST_TYPE; | 773 ResourceType resource_type = content::RESOURCE_TYPE_LAST_TYPE; | 
| 753 ExtractRequestInfoDetails(request, &is_main_frame, &frame_id, | 774 ExtractRequestInfoDetails(request, &is_main_frame, &render_frame_id, | 
| 754 &parent_is_main_frame, &parent_frame_id, | |
| 755 &render_process_host_id, &routing_id, | 775 &render_process_host_id, &routing_id, | 
| 756 &resource_type); | 776 &resource_type); | 
| 757 frame_id_for_extension = GetFrameId(is_main_frame, frame_id); | |
| 758 parent_frame_id_for_extension = GetFrameId(parent_is_main_frame, | |
| 759 parent_frame_id); | |
| 760 | 777 | 
| 761 out->SetString(keys::kRequestIdKey, | 778 out->SetString(keys::kRequestIdKey, | 
| 762 base::Uint64ToString(request->identifier())); | 779 base::Uint64ToString(request->identifier())); | 
| 763 out->SetString(keys::kUrlKey, request->url().spec()); | 780 out->SetString(keys::kUrlKey, request->url().spec()); | 
| 764 out->SetString(keys::kMethodKey, request->method()); | 781 out->SetString(keys::kMethodKey, request->method()); | 
| 765 out->SetInteger(keys::kFrameIdKey, frame_id_for_extension); | 782 // Note: This (frameId, processId) pair is removed by ExtractRenderFrameInfo, | 
| 766 out->SetInteger(keys::kParentFrameIdKey, parent_frame_id_for_extension); | 783 // and then finally set by ExtractApiFrameIdInfo. | 
| 784 // TODO(robwu): This is ugly. Create a proper data structure to separate these | |
| 785 // two IDs from the dictionary, so that kFrameIdKey has only one meaning. | |
| 786 out->SetInteger(keys::kFrameIdKey, render_frame_id); | |
| 787 out->SetInteger(keys::kProcessIdKey, render_process_host_id); | |
| 767 out->SetString(keys::kTypeKey, helpers::ResourceTypeToString(resource_type)); | 788 out->SetString(keys::kTypeKey, helpers::ResourceTypeToString(resource_type)); | 
| 768 out->SetDouble(keys::kTimeStampKey, base::Time::Now().ToDoubleT() * 1000); | 789 out->SetDouble(keys::kTimeStampKey, base::Time::Now().ToDoubleT() * 1000); | 
| 769 if (web_request_event_router_delegate_) { | 790 if (web_request_event_router_delegate_) { | 
| 770 web_request_event_router_delegate_->ExtractExtraRequestDetails( | 791 web_request_event_router_delegate_->ExtractExtraRequestDetails( | 
| 771 request, out); | 792 request, out); | 
| 772 } | 793 } | 
| 773 } | 794 } | 
| 774 | 795 | 
| 775 int ExtensionWebRequestEventRouter::OnBeforeRequest( | 796 int ExtensionWebRequestEventRouter::OnBeforeRequest( | 
| 776 void* browser_context, | 797 void* browser_context, | 
| (...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1235 } | 1256 } | 
| 1236 | 1257 | 
| 1237 bool ExtensionWebRequestEventRouter::DispatchEvent( | 1258 bool ExtensionWebRequestEventRouter::DispatchEvent( | 
| 1238 void* browser_context, | 1259 void* browser_context, | 
| 1239 net::URLRequest* request, | 1260 net::URLRequest* request, | 
| 1240 const std::vector<const EventListener*>& listeners, | 1261 const std::vector<const EventListener*>& listeners, | 
| 1241 const base::ListValue& args) { | 1262 const base::ListValue& args) { | 
| 1242 // TODO(mpcomplete): Consider consolidating common (extension_id,json_args) | 1263 // TODO(mpcomplete): Consider consolidating common (extension_id,json_args) | 
| 1243 // pairs into a single message sent to a list of sub_event_names. | 1264 // pairs into a single message sent to a list of sub_event_names. | 
| 1244 int num_handlers_blocking = 0; | 1265 int num_handlers_blocking = 0; | 
| 1266 | |
| 1267 scoped_ptr<std::vector<EventListener>> listeners_to_dispatch( | |
| 1268 new std::vector<EventListener>()); | |
| 1269 listeners_to_dispatch->reserve(listeners.size()); | |
| 1245 for (const EventListener* listener : listeners) { | 1270 for (const EventListener* listener : listeners) { | 
| 1246 // Filter out the optional keys that this listener didn't request. | 1271 listeners_to_dispatch->push_back(*listener); | 
| 1247 scoped_ptr<base::ListValue> args_filtered(args.DeepCopy()); | |
| 1248 base::DictionaryValue* dict = NULL; | |
| 1249 CHECK(args_filtered->GetDictionary(0, &dict) && dict); | |
| 1250 if (!(listener->extra_info_spec & ExtraInfoSpec::REQUEST_HEADERS)) | |
| 1251 dict->Remove(keys::kRequestHeadersKey, NULL); | |
| 1252 if (!(listener->extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS)) | |
| 1253 dict->Remove(keys::kResponseHeadersKey, NULL); | |
| 1254 | |
| 1255 EventRouter::DispatchEventToSender( | |
| 1256 listener->ipc_sender.get(), browser_context, listener->extension_id, | |
| 1257 listener->histogram_value, listener->sub_event_name, | |
| 1258 std::move(args_filtered), EventRouter::USER_GESTURE_UNKNOWN, | |
| 1259 EventFilteringInfo()); | |
| 1260 if (listener->extra_info_spec & | 1272 if (listener->extra_info_spec & | 
| 1261 (ExtraInfoSpec::BLOCKING | ExtraInfoSpec::ASYNC_BLOCKING)) { | 1273 (ExtraInfoSpec::BLOCKING | ExtraInfoSpec::ASYNC_BLOCKING)) { | 
| 1262 listener->blocked_requests.insert(request->identifier()); | 1274 listener->blocked_requests.insert(request->identifier()); | 
| 1263 // If this is the first delegate blocking the request, go ahead and log | 1275 // If this is the first delegate blocking the request, go ahead and log | 
| 1264 // it. | 1276 // it. | 
| 1265 if (num_handlers_blocking == 0) { | 1277 if (num_handlers_blocking == 0) { | 
| 1266 std::string delegate_info = l10n_util::GetStringFUTF8( | 1278 std::string delegate_info = l10n_util::GetStringFUTF8( | 
| 1267 IDS_LOAD_STATE_PARAMETER_EXTENSION, | 1279 IDS_LOAD_STATE_PARAMETER_EXTENSION, | 
| 1268 base::UTF8ToUTF16(listener->extension_name)); | 1280 base::UTF8ToUTF16(listener->extension_name)); | 
| 1269 // LobAndReport allows extensions that block requests to be displayed in | 1281 // LobAndReport allows extensions that block requests to be displayed in | 
| 1270 // the load status bar. | 1282 // the load status bar. | 
| 1271 request->LogAndReportBlockedBy(delegate_info.c_str()); | 1283 request->LogAndReportBlockedBy(delegate_info.c_str()); | 
| 1272 } | 1284 } | 
| 1273 ++num_handlers_blocking; | 1285 ++num_handlers_blocking; | 
| 1274 } | 1286 } | 
| 1275 } | 1287 } | 
| 1276 | 1288 | 
| 1289 // TODO(robwu): Avoid unnecessary copy, by changing |args| to be a | |
| 1290 // scoped_ptr<base::DictionaryValue> and transferring the ownership. | |
| 1291 const base::DictionaryValue* dict = nullptr; | |
| 1292 CHECK(args.GetDictionary(0, &dict) && dict); | |
| 1293 base::DictionaryValue* args_copy = dict->DeepCopy(); | |
| 1294 | |
| 1295 int render_process_host_id = -1; | |
| 1296 int render_frame_id = -1; | |
| 1297 ExtractRenderFrameInfo(args_copy, &render_process_host_id, &render_frame_id); | |
| 1298 | |
| 1299 ExtensionApiFrameIdMap::Get()->GetFrameIdOnIO( | |
| 1300 render_process_host_id, render_frame_id, | |
| 1301 base::Bind(&ExtensionWebRequestEventRouter::DispatchEventToListeners, | |
| 1302 AsWeakPtr(), browser_context, | |
| 1303 base::Passed(&listeners_to_dispatch), base::Owned(args_copy))); | |
| 1304 | |
| 1277 if (num_handlers_blocking > 0) { | 1305 if (num_handlers_blocking > 0) { | 
| 1278 BlockedRequest& blocked_request = blocked_requests_[request->identifier()]; | 1306 BlockedRequest& blocked_request = blocked_requests_[request->identifier()]; | 
| 1279 blocked_request.request = request; | 1307 blocked_request.request = request; | 
| 1280 blocked_request.is_incognito |= IsIncognitoBrowserContext(browser_context); | 1308 blocked_request.is_incognito |= IsIncognitoBrowserContext(browser_context); | 
| 1281 blocked_request.num_handlers_blocking += num_handlers_blocking; | 1309 blocked_request.num_handlers_blocking += num_handlers_blocking; | 
| 1282 blocked_request.blocking_time = base::Time::Now(); | 1310 blocked_request.blocking_time = base::Time::Now(); | 
| 1283 return true; | 1311 return true; | 
| 1284 } | 1312 } | 
| 1285 | 1313 | 
| 1286 return false; | 1314 return false; | 
| 1287 } | 1315 } | 
| 1288 | 1316 | 
| 1317 void ExtensionWebRequestEventRouter::DispatchEventToListeners( | |
| 1318 void* browser_context, | |
| 1319 scoped_ptr<std::vector<EventListener>> listeners, | |
| 1320 base::DictionaryValue* dict, | |
| 1321 const ExtensionApiFrameId extension_api_frame_id) { | |
| 1322 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 1323 DCHECK(listeners.get()); | |
| 1324 DCHECK_GT(listeners->size(), 0UL); | |
| 1325 DCHECK(dict); | |
| 1326 | |
| 1327 ExtractApiFrameIdInfo(extension_api_frame_id, dict); | |
| 1328 | |
| 1329 std::string event_name = | |
| 1330 EventRouter::GetBaseEventName((*listeners)[0].sub_event_name); | |
| 1331 DCHECK(IsWebRequestEvent(event_name)); | |
| 1332 | |
| 1333 const std::set<EventListener>& event_listeners = | |
| 1334 listeners_[browser_context][event_name]; | |
| 1335 void* cross_browser_context = GetCrossBrowserContext(browser_context); | |
| 1336 const std::set<EventListener>* cross_event_listeners = | |
| 1337 cross_browser_context ? &listeners_[cross_browser_context][event_name] | |
| 1338 : nullptr; | |
| 1339 | |
| 1340 for (const EventListener& target : *listeners) { | |
| 1341 std::set<EventListener>::const_iterator listener = | |
| 1342 event_listeners.find(target); | |
| 1343 // Ignore listener if it was removed between the thread hops. | |
| 1344 if (listener == event_listeners.end()) { | |
| 1345 if (!cross_event_listeners) | |
| 1346 continue; | |
| 1347 listener = cross_event_listeners->find(target); | |
| 1348 if (listener == cross_event_listeners->end()) | |
| 1349 continue; | |
| 1350 } | |
| 1351 | |
| 1352 // Filter out the optional keys that this listener didn't request. | |
| 1353 scoped_ptr<base::ListValue> args_filtered(new base::ListValue); | |
| 1354 args_filtered->Append(dict->DeepCopy()); | |
| 1355 if (!(listener->extra_info_spec & ExtraInfoSpec::REQUEST_HEADERS)) | |
| 1356 dict->Remove(keys::kRequestHeadersKey, nullptr); | |
| 1357 if (!(listener->extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS)) | |
| 1358 dict->Remove(keys::kResponseHeadersKey, nullptr); | |
| 1359 | |
| 1360 EventRouter::DispatchEventToSender( | |
| 1361 listener->ipc_sender.get(), browser_context, listener->extension_id, | |
| 1362 listener->histogram_value, listener->sub_event_name, | |
| 1363 std::move(args_filtered), EventRouter::USER_GESTURE_UNKNOWN, | |
| 1364 EventFilteringInfo()); | |
| 1365 } | |
| 1366 } | |
| 1367 | |
| 1289 void ExtensionWebRequestEventRouter::OnEventHandled( | 1368 void ExtensionWebRequestEventRouter::OnEventHandled( | 
| 1290 void* browser_context, | 1369 void* browser_context, | 
| 1291 const std::string& extension_id, | 1370 const std::string& extension_id, | 
| 1292 const std::string& event_name, | 1371 const std::string& event_name, | 
| 1293 const std::string& sub_event_name, | 1372 const std::string& sub_event_name, | 
| 1294 uint64_t request_id, | 1373 uint64_t request_id, | 
| 1295 EventResponse* response) { | 1374 EventResponse* response) { | 
| 1296 // TODO(robwu): Does this also work with webviews? operator< (used by find) | 1375 // TODO(robwu): Does this also work with webviews? operator< (used by find) | 
| 1297 // takes the webview ID into account, which is not set on |listener|. | 1376 // takes the webview ID into account, which is not set on |listener|. | 
| 1298 EventListener listener; | 1377 EventListener listener; | 
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1432 } | 1511 } | 
| 1433 | 1512 | 
| 1434 void ExtensionWebRequestEventRouter::AddCallbackForPageLoad( | 1513 void ExtensionWebRequestEventRouter::AddCallbackForPageLoad( | 
| 1435 const base::Closure& callback) { | 1514 const base::Closure& callback) { | 
| 1436 callbacks_for_page_load_.push_back(callback); | 1515 callbacks_for_page_load_.push_back(callback); | 
| 1437 } | 1516 } | 
| 1438 | 1517 | 
| 1439 bool ExtensionWebRequestEventRouter::IsPageLoad( | 1518 bool ExtensionWebRequestEventRouter::IsPageLoad( | 
| 1440 const net::URLRequest* request) const { | 1519 const net::URLRequest* request) const { | 
| 1441 bool is_main_frame = false; | 1520 bool is_main_frame = false; | 
| 1442 int frame_id = -1; | 1521 int render_frame_id = -1; | 
| 1443 bool parent_is_main_frame = false; | |
| 1444 int parent_frame_id = -1; | |
| 1445 int render_process_host_id = -1; | 1522 int render_process_host_id = -1; | 
| 1446 int routing_id = -1; | 1523 int routing_id = -1; | 
| 1447 ResourceType resource_type = content::RESOURCE_TYPE_LAST_TYPE; | 1524 ResourceType resource_type = content::RESOURCE_TYPE_LAST_TYPE; | 
| 1448 | 1525 | 
| 1449 ExtractRequestInfoDetails(request, &is_main_frame, &frame_id, | 1526 ExtractRequestInfoDetails(request, &is_main_frame, &render_frame_id, | 
| 1450 &parent_is_main_frame, &parent_frame_id, | 1527 &render_process_host_id, &routing_id, | 
| 1451 &render_process_host_id, | 1528 &resource_type); | 
| 1452 &routing_id, &resource_type); | |
| 1453 | 1529 | 
| 1454 return resource_type == content::RESOURCE_TYPE_MAIN_FRAME; | 1530 return resource_type == content::RESOURCE_TYPE_MAIN_FRAME; | 
| 1455 } | 1531 } | 
| 1456 | 1532 | 
| 1457 void ExtensionWebRequestEventRouter::NotifyPageLoad() { | 1533 void ExtensionWebRequestEventRouter::NotifyPageLoad() { | 
| 1458 for (const auto& callback : callbacks_for_page_load_) | 1534 for (const auto& callback : callbacks_for_page_load_) | 
| 1459 callback.Run(); | 1535 callback.Run(); | 
| 1460 callbacks_for_page_load_.clear(); | 1536 callbacks_for_page_load_.clear(); | 
| 1461 } | 1537 } | 
| 1462 | 1538 | 
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1582 void* browser_context, | 1658 void* browser_context, | 
| 1583 const InfoMap* extension_info_map, | 1659 const InfoMap* extension_info_map, | 
| 1584 const std::string& event_name, | 1660 const std::string& event_name, | 
| 1585 const net::URLRequest* request, | 1661 const net::URLRequest* request, | 
| 1586 int* extra_info_spec) { | 1662 int* extra_info_spec) { | 
| 1587 // TODO(mpcomplete): handle browser_context == NULL (should collect all | 1663 // TODO(mpcomplete): handle browser_context == NULL (should collect all | 
| 1588 // listeners). | 1664 // listeners). | 
| 1589 *extra_info_spec = 0; | 1665 *extra_info_spec = 0; | 
| 1590 | 1666 | 
| 1591 bool is_main_frame = false; | 1667 bool is_main_frame = false; | 
| 1592 int frame_id = -1; | 1668 int render_frame_id = -1; | 
| 1593 bool parent_is_main_frame = false; | |
| 1594 int parent_frame_id = -1; | |
| 1595 int render_process_host_id = -1; | 1669 int render_process_host_id = -1; | 
| 1596 int routing_id = -1; | 1670 int routing_id = -1; | 
| 1597 ResourceType resource_type = content::RESOURCE_TYPE_LAST_TYPE; | 1671 ResourceType resource_type = content::RESOURCE_TYPE_LAST_TYPE; | 
| 1598 const GURL& url = request->url(); | 1672 const GURL& url = request->url(); | 
| 1599 | 1673 | 
| 1600 ExtractRequestInfoDetails(request, &is_main_frame, &frame_id, | 1674 ExtractRequestInfoDetails(request, &is_main_frame, &render_frame_id, | 
| 1601 &parent_is_main_frame, &parent_frame_id, | 1675 &render_process_host_id, &routing_id, | 
| 1602 &render_process_host_id, | 1676 &resource_type); | 
| 1603 &routing_id, &resource_type); | |
| 1604 | 1677 | 
| 1605 bool is_request_from_extension = | 1678 bool is_request_from_extension = | 
| 1606 IsRequestFromExtension(request, extension_info_map); | 1679 IsRequestFromExtension(request, extension_info_map); | 
| 1607 | 1680 | 
| 1608 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); | 1681 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); | 
| 1609 // We are conservative here and assume requests are asynchronous in case | 1682 // We are conservative here and assume requests are asynchronous in case | 
| 1610 // we don't have an info object. We don't want to risk a deadlock. | 1683 // we don't have an info object. We don't want to risk a deadlock. | 
| 1611 bool is_async_request = !info || info->IsAsync(); | 1684 bool is_async_request = !info || info->IsAsync(); | 
| 1612 | 1685 | 
| 1613 EventListeners matching_listeners; | 1686 EventListeners matching_listeners; | 
| (...skipping 856 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2470 // Continue gracefully. | 2543 // Continue gracefully. | 
| 2471 RunSync(); | 2544 RunSync(); | 
| 2472 } | 2545 } | 
| 2473 | 2546 | 
| 2474 bool WebRequestHandlerBehaviorChangedFunction::RunSync() { | 2547 bool WebRequestHandlerBehaviorChangedFunction::RunSync() { | 
| 2475 helpers::ClearCacheOnNavigation(); | 2548 helpers::ClearCacheOnNavigation(); | 
| 2476 return true; | 2549 return true; | 
| 2477 } | 2550 } | 
| 2478 | 2551 | 
| 2479 } // namespace extensions | 2552 } // namespace extensions | 
| OLD | NEW |