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 <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <memory> | 10 #include <memory> |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 std::string sub_event_name; | 390 std::string sub_event_name; |
391 RequestFilter filter; | 391 RequestFilter filter; |
392 int extra_info_spec; | 392 int extra_info_spec; |
393 int embedder_process_id; | 393 int embedder_process_id; |
394 int web_view_instance_id; | 394 int web_view_instance_id; |
395 base::WeakPtr<IPC::Sender> ipc_sender; | 395 base::WeakPtr<IPC::Sender> ipc_sender; |
396 mutable std::set<uint64_t> blocked_requests; | 396 mutable std::set<uint64_t> blocked_requests; |
397 | 397 |
398 // Comparator to work with std::set. | 398 // Comparator to work with std::set. |
399 bool operator<(const EventListener& that) const { | 399 bool operator<(const EventListener& that) const { |
400 if (extension_id != that.extension_id) | 400 return std::tie(extension_id, sub_event_name, web_view_instance_id, |
401 return extension_id < that.extension_id; | 401 embedder_process_id) < |
402 | 402 std::tie(that.extension_id, that.sub_event_name, |
403 if (sub_event_name != that.sub_event_name) | 403 that.web_view_instance_id, that.embedder_process_id); |
404 return sub_event_name < that.sub_event_name; | |
405 | |
406 if (web_view_instance_id != that.web_view_instance_id) | |
407 return web_view_instance_id < that.web_view_instance_id; | |
408 | |
409 if (web_view_instance_id == 0) { | |
410 // Do not filter by process ID for non-webviews, because this comparator | |
411 // is also used to find and remove an event listener when an extension is | |
412 // unloaded. At this point, the event listener cannot be mapped back to | |
413 // the original process, so 0 is used instead of the actual process ID. | |
414 if (embedder_process_id == 0 || that.embedder_process_id == 0) | |
415 return false; | |
416 } | |
417 | |
418 if (embedder_process_id != that.embedder_process_id) | |
419 return embedder_process_id < that.embedder_process_id; | |
420 | |
421 return false; | |
422 } | 404 } |
423 | 405 |
424 EventListener() | 406 EventListener() |
425 : histogram_value(events::UNKNOWN), | 407 : histogram_value(events::UNKNOWN), |
426 extra_info_spec(0), | 408 extra_info_spec(0), |
427 embedder_process_id(0), | 409 embedder_process_id(0), |
428 web_view_instance_id(0) {} | 410 web_view_instance_id(0) {} |
429 }; | 411 }; |
430 | 412 |
431 // Contains info about requests that are blocked waiting for a response from | 413 // Contains info about requests that are blocked waiting for a response from |
(...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1140 } | 1122 } |
1141 | 1123 |
1142 if (ContainsKey(listeners_[browser_context][event_name], listener)) { | 1124 if (ContainsKey(listeners_[browser_context][event_name], listener)) { |
1143 // This is likely an abuse of the API by a malicious extension. | 1125 // This is likely an abuse of the API by a malicious extension. |
1144 return false; | 1126 return false; |
1145 } | 1127 } |
1146 listeners_[browser_context][event_name].insert(listener); | 1128 listeners_[browser_context][event_name].insert(listener); |
1147 return true; | 1129 return true; |
1148 } | 1130 } |
1149 | 1131 |
| 1132 int ExtensionWebRequestEventRouter::GetListenerCount( |
| 1133 void* browser_context, |
| 1134 const std::string& event_name) { |
| 1135 return listeners_[browser_context][event_name].size(); |
| 1136 } |
| 1137 |
1150 void ExtensionWebRequestEventRouter::RemoveEventListener( | 1138 void ExtensionWebRequestEventRouter::RemoveEventListener( |
1151 void* browser_context, | 1139 void* browser_context, |
1152 const std::string& extension_id, | 1140 const std::string& extension_id, |
1153 const std::string& sub_event_name, | 1141 const std::string& sub_event_name, |
1154 int embedder_process_id, | 1142 int embedder_process_id, |
1155 int web_view_instance_id) { | 1143 int web_view_instance_id) { |
1156 std::string event_name = EventRouter::GetBaseEventName(sub_event_name); | 1144 std::string event_name = EventRouter::GetBaseEventName(sub_event_name); |
1157 DCHECK(IsWebRequestEvent(event_name)); | 1145 DCHECK(IsWebRequestEvent(event_name)); |
1158 | 1146 |
| 1147 std::set<EventListener>& event_listeners = |
| 1148 listeners_[browser_context][event_name]; |
| 1149 |
1159 EventListener listener; | 1150 EventListener listener; |
1160 listener.extension_id = extension_id; | 1151 listener.extension_id = extension_id; |
1161 listener.sub_event_name = sub_event_name; | 1152 listener.sub_event_name = sub_event_name; |
1162 listener.embedder_process_id = embedder_process_id; | |
1163 listener.web_view_instance_id = web_view_instance_id; | |
1164 | 1153 |
1165 std::set<EventListener>& event_listeners = | 1154 if (web_view_instance_id != 0) { |
1166 listeners_[browser_context][event_name]; | 1155 listener.embedder_process_id = embedder_process_id; |
| 1156 listener.web_view_instance_id = web_view_instance_id; |
| 1157 } else { |
| 1158 for (const EventListener& l : event_listeners) { |
| 1159 if (l.extension_id == extension_id && l.sub_event_name == sub_event_name) |
| 1160 listener.embedder_process_id = l.embedder_process_id; |
| 1161 } |
| 1162 } |
| 1163 |
1167 // It's possible for AddEventListener to fail asynchronously. In that case, | 1164 // It's possible for AddEventListener to fail asynchronously. In that case, |
1168 // the renderer believes the listener exists, while the browser does not. | 1165 // the renderer believes the listener exists, while the browser does not. |
1169 // Ignore a RemoveEventListener in that case. | 1166 // Ignore a RemoveEventListener in that case. |
1170 std::set<EventListener>::const_iterator it = event_listeners.find(listener); | 1167 std::set<EventListener>::const_iterator it = event_listeners.find(listener); |
1171 if (it == event_listeners.end()) | 1168 if (it == event_listeners.end()) |
1172 return; | 1169 return; |
1173 | 1170 |
1174 #if defined(OS_WIN) | |
1175 // Debugging https://crbug.com/589735 | |
1176 // Please post crash reports at the following lines to the above issue. | |
1177 unsigned event_listener_count = event_listeners.count(listener); | |
1178 CHECK_GE(event_listener_count, 0u); | |
1179 CHECK_GE(event_listener_count, 1u); | |
1180 CHECK_LE(event_listener_count, 2u); | |
1181 CHECK_EQ(event_listener_count, 1u); | |
1182 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | |
1183 #endif // OS_WIN | |
1184 CHECK_EQ(event_listeners.count(listener), 1u) << | 1171 CHECK_EQ(event_listeners.count(listener), 1u) << |
1185 "extension=" << extension_id << " event=" << event_name; | 1172 "extension=" << extension_id << " event=" << event_name; |
1186 | 1173 |
1187 // Unblock any request that this event listener may have been blocking. | 1174 // Unblock any request that this event listener may have been blocking. |
1188 for (uint64_t id : it->blocked_requests) | 1175 for (uint64_t id : it->blocked_requests) |
1189 DecrementBlockCount(browser_context, extension_id, event_name, id, NULL); | 1176 DecrementBlockCount(browser_context, extension_id, event_name, id, NULL); |
1190 | 1177 |
1191 event_listeners.erase(listener); | 1178 event_listeners.erase(listener); |
1192 | 1179 |
1193 helpers::ClearCacheOnNavigation(); | 1180 helpers::ClearCacheOnNavigation(); |
(...skipping 1071 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2265 // Continue gracefully. | 2252 // Continue gracefully. |
2266 RunSync(); | 2253 RunSync(); |
2267 } | 2254 } |
2268 | 2255 |
2269 bool WebRequestHandlerBehaviorChangedFunction::RunSync() { | 2256 bool WebRequestHandlerBehaviorChangedFunction::RunSync() { |
2270 helpers::ClearCacheOnNavigation(); | 2257 helpers::ClearCacheOnNavigation(); |
2271 return true; | 2258 return true; |
2272 } | 2259 } |
2273 | 2260 |
2274 } // namespace extensions | 2261 } // namespace extensions |
OLD | NEW |