Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/renderer/event_bindings.h" | 5 #include "extensions/renderer/event_bindings.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
| 13 #include "base/bind.h" | 13 #include "base/bind.h" |
| 14 #include "base/lazy_instance.h" | 14 #include "base/lazy_instance.h" |
| 15 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
| 16 #include "components/crx_file/id_util.h" | |
| 16 #include "content/public/renderer/render_thread.h" | 17 #include "content/public/renderer/render_thread.h" |
| 17 #include "content/public/renderer/render_view.h" | 18 #include "content/public/renderer/render_view.h" |
| 18 #include "content/public/renderer/v8_value_converter.h" | 19 #include "content/public/renderer/v8_value_converter.h" |
| 19 #include "extensions/common/event_filter.h" | 20 #include "extensions/common/event_filter.h" |
| 20 #include "extensions/common/extension.h" | 21 #include "extensions/common/extension.h" |
| 21 #include "extensions/common/extension_messages.h" | 22 #include "extensions/common/extension_messages.h" |
| 22 #include "extensions/common/manifest_handlers/background_info.h" | 23 #include "extensions/common/manifest_handlers/background_info.h" |
| 23 #include "extensions/common/value_counter.h" | 24 #include "extensions/common/value_counter.h" |
| 24 #include "extensions/renderer/dispatcher.h" | 25 #include "extensions/renderer/dispatcher.h" |
| 25 #include "extensions/renderer/extension_helper.h" | 26 #include "extensions/renderer/extension_helper.h" |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 46 // between 0 and 1. | 47 // between 0 and 1. |
| 47 typedef std::map<std::string, linked_ptr<ValueCounter> > | 48 typedef std::map<std::string, linked_ptr<ValueCounter> > |
| 48 FilteredEventListenerCounts; | 49 FilteredEventListenerCounts; |
| 49 | 50 |
| 50 // A map of extension IDs to filtered listener counts for that extension. | 51 // A map of extension IDs to filtered listener counts for that extension. |
| 51 base::LazyInstance<std::map<std::string, FilteredEventListenerCounts> > | 52 base::LazyInstance<std::map<std::string, FilteredEventListenerCounts> > |
| 52 g_filtered_listener_counts = LAZY_INSTANCE_INITIALIZER; | 53 g_filtered_listener_counts = LAZY_INSTANCE_INITIALIZER; |
| 53 | 54 |
| 54 base::LazyInstance<EventFilter> g_event_filter = LAZY_INSTANCE_INITIALIZER; | 55 base::LazyInstance<EventFilter> g_event_filter = LAZY_INSTANCE_INITIALIZER; |
| 55 | 56 |
| 57 std::string GetKeyForScriptContext(ScriptContext* script_context) { | |
| 58 const std::string& extension_id = script_context->GetExtensionID(); | |
| 59 return crx_file::id_util::IdIsValid(extension_id) | |
| 60 ? extension_id | |
| 61 : script_context->GetURL().spec(); | |
| 62 } | |
| 63 | |
| 64 // Increments the number of event-listeners for the given |event_name| and | |
| 65 // ScriptContext. Returns the count after the increment. | |
| 66 int IncrementEventListenerCount(ScriptContext* script_context, | |
| 67 const std::string& event_name) { | |
| 68 return ++g_listener_counts | |
| 69 .Get()[GetKeyForScriptContext(script_context)][event_name]; | |
| 70 } | |
| 71 | |
| 72 // Decrements the number of event-listeners for the given |event_name| and | |
| 73 // ScriptContext. Returns the count after the increment. | |
| 74 int DecrementEventListenerCount(ScriptContext* script_context, | |
| 75 const std::string& event_name) { | |
| 76 return --g_listener_counts | |
| 77 .Get()[GetKeyForScriptContext(script_context)][event_name]; | |
| 78 } | |
| 79 | |
| 56 bool IsLazyBackgroundPage(content::RenderView* render_view, | 80 bool IsLazyBackgroundPage(content::RenderView* render_view, |
| 57 const Extension* extension) { | 81 const Extension* extension) { |
| 58 if (!render_view) | 82 if (!render_view) |
| 59 return false; | 83 return false; |
| 60 ExtensionHelper* helper = ExtensionHelper::Get(render_view); | 84 ExtensionHelper* helper = ExtensionHelper::Get(render_view); |
| 61 return (extension && BackgroundInfo::HasLazyBackgroundPage(extension) && | 85 return (extension && BackgroundInfo::HasLazyBackgroundPage(extension) && |
| 62 helper->view_type() == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE); | 86 helper->view_type() == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE); |
| 63 } | 87 } |
| 64 | 88 |
| 65 EventFilteringInfo ParseFromObject(v8::Handle<v8::Object> object, | 89 EventFilteringInfo ParseFromObject(v8::Handle<v8::Object> object, |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 140 void EventBindings::AttachEvent( | 164 void EventBindings::AttachEvent( |
| 141 const v8::FunctionCallbackInfo<v8::Value>& args) { | 165 const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 142 CHECK_EQ(1, args.Length()); | 166 CHECK_EQ(1, args.Length()); |
| 143 CHECK(args[0]->IsString()); | 167 CHECK(args[0]->IsString()); |
| 144 | 168 |
| 145 std::string event_name = *v8::String::Utf8Value(args[0]); | 169 std::string event_name = *v8::String::Utf8Value(args[0]); |
| 146 | 170 |
| 147 if (!dispatcher_->CheckContextAccessToExtensionAPI(event_name, context())) | 171 if (!dispatcher_->CheckContextAccessToExtensionAPI(event_name, context())) |
| 148 return; | 172 return; |
| 149 | 173 |
| 150 std::string extension_id = context()->GetExtensionID(); | 174 const std::string& extension_id = context()->GetExtensionID(); |
| 151 EventListenerCounts& listener_counts = g_listener_counts.Get()[extension_id]; | 175 if (IncrementEventListenerCount(context(), event_name) == 1) { |
| 152 if (++listener_counts[event_name] == 1) { | 176 CHECK(crx_file::id_util::IdIsValid(extension_id) || |
|
not at google - send to devlin
2014/12/03 17:15:45
Can you do this CHECK inside the GetKeyForScriptCo
sadrul
2014/12/03 20:53:37
Done.
| |
| 177 context()->GetURL().is_valid()); | |
| 153 content::RenderThread::Get()->Send(new ExtensionHostMsg_AddListener( | 178 content::RenderThread::Get()->Send(new ExtensionHostMsg_AddListener( |
| 154 extension_id, context()->GetURL(), event_name)); | 179 extension_id, context()->GetURL(), event_name)); |
| 155 } | 180 } |
| 156 | 181 |
| 157 // This is called the first time the page has added a listener. Since | 182 // This is called the first time the page has added a listener. Since |
| 158 // the background page is the only lazy page, we know this is the first | 183 // the background page is the only lazy page, we know this is the first |
| 159 // time this listener has been registered. | 184 // time this listener has been registered. |
| 160 if (IsLazyBackgroundPage(context()->GetRenderView(), | 185 if (IsLazyBackgroundPage(context()->GetRenderView(), |
| 161 context()->extension())) { | 186 context()->extension())) { |
| 162 content::RenderThread::Get()->Send( | 187 content::RenderThread::Get()->Send( |
| 163 new ExtensionHostMsg_AddLazyListener(extension_id, event_name)); | 188 new ExtensionHostMsg_AddLazyListener(extension_id, event_name)); |
| 164 } | 189 } |
| 165 } | 190 } |
| 166 | 191 |
| 167 void EventBindings::DetachEvent( | 192 void EventBindings::DetachEvent( |
| 168 const v8::FunctionCallbackInfo<v8::Value>& args) { | 193 const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 169 CHECK_EQ(2, args.Length()); | 194 CHECK_EQ(2, args.Length()); |
| 170 CHECK(args[0]->IsString()); | 195 CHECK(args[0]->IsString()); |
| 171 CHECK(args[1]->IsBoolean()); | 196 CHECK(args[1]->IsBoolean()); |
| 172 | 197 |
| 173 std::string event_name = *v8::String::Utf8Value(args[0]); | 198 std::string event_name = *v8::String::Utf8Value(args[0]); |
| 174 bool is_manual = args[1]->BooleanValue(); | 199 bool is_manual = args[1]->BooleanValue(); |
| 175 | 200 |
| 176 std::string extension_id = context()->GetExtensionID(); | 201 const std::string& extension_id = context()->GetExtensionID(); |
| 177 EventListenerCounts& listener_counts = g_listener_counts.Get()[extension_id]; | 202 if (DecrementEventListenerCount(context(), event_name) == 0) { |
| 178 | 203 CHECK(crx_file::id_util::IdIsValid(extension_id) || |
| 179 if (--listener_counts[event_name] == 0) { | 204 context()->GetURL().is_valid()); |
| 180 content::RenderThread::Get()->Send(new ExtensionHostMsg_RemoveListener( | 205 content::RenderThread::Get()->Send(new ExtensionHostMsg_RemoveListener( |
| 181 extension_id, context()->GetURL(), event_name)); | 206 extension_id, context()->GetURL(), event_name)); |
| 182 } | 207 } |
| 183 | 208 |
| 184 // DetachEvent is called when the last listener for the context is | 209 // DetachEvent is called when the last listener for the context is |
| 185 // removed. If the context is the background page, and it removes the | 210 // removed. If the context is the background page, and it removes the |
| 186 // last listener manually, then we assume that it is no longer interested | 211 // last listener manually, then we assume that it is no longer interested |
| 187 // in being awakened for this event. | 212 // in being awakened for this event. |
| 188 if (is_manual && IsLazyBackgroundPage(context()->GetRenderView(), | 213 if (is_manual && IsLazyBackgroundPage(context()->GetRenderView(), |
| 189 context()->extension())) { | 214 context()->extension())) { |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 295 } | 320 } |
| 296 | 321 |
| 297 scoped_ptr<EventMatcher> EventBindings::ParseEventMatcher( | 322 scoped_ptr<EventMatcher> EventBindings::ParseEventMatcher( |
| 298 base::DictionaryValue* filter_dict) { | 323 base::DictionaryValue* filter_dict) { |
| 299 return scoped_ptr<EventMatcher>(new EventMatcher( | 324 return scoped_ptr<EventMatcher>(new EventMatcher( |
| 300 scoped_ptr<base::DictionaryValue>(filter_dict->DeepCopy()), | 325 scoped_ptr<base::DictionaryValue>(filter_dict->DeepCopy()), |
| 301 context()->GetRenderView()->GetRoutingID())); | 326 context()->GetRenderView()->GetRoutingID())); |
| 302 } | 327 } |
| 303 | 328 |
| 304 } // namespace extensions | 329 } // namespace extensions |
| OLD | NEW |