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

Side by Side Diff: chrome/renderer/extensions/event_bindings.cc

Issue 12313142: Revert 184837 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 9 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) 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/renderer/extensions/event_bindings.h" 5 #include "chrome/renderer/extensions/event_bindings.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/basictypes.h" 10 #include "base/basictypes.h"
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 // A map of extension IDs to filtered listener counts for that extension. 65 // A map of extension IDs to filtered listener counts for that extension.
66 base::LazyInstance<std::map<std::string, FilteredEventListenerCounts> > 66 base::LazyInstance<std::map<std::string, FilteredEventListenerCounts> >
67 g_filtered_listener_counts = LAZY_INSTANCE_INITIALIZER; 67 g_filtered_listener_counts = LAZY_INSTANCE_INITIALIZER;
68 68
69 base::LazyInstance<extensions::EventFilter> g_event_filter = 69 base::LazyInstance<extensions::EventFilter> g_event_filter =
70 LAZY_INSTANCE_INITIALIZER; 70 LAZY_INSTANCE_INITIALIZER;
71 71
72 // TODO(koz): Merge this into EventBindings. 72 // TODO(koz): Merge this into EventBindings.
73 class ExtensionImpl : public ChromeV8Extension { 73 class ExtensionImpl : public ChromeV8Extension {
74 public: 74 public:
75 explicit ExtensionImpl(Dispatcher* dispatcher, 75 explicit ExtensionImpl(Dispatcher* dispatcher)
76 v8::Handle<v8::Context> v8_context) 76 : ChromeV8Extension(dispatcher) {
77 : ChromeV8Extension(dispatcher, v8_context) {
78 RouteStaticFunction("AttachEvent", &AttachEvent); 77 RouteStaticFunction("AttachEvent", &AttachEvent);
79 RouteStaticFunction("DetachEvent", &DetachEvent); 78 RouteStaticFunction("DetachEvent", &DetachEvent);
80 RouteStaticFunction("AttachFilteredEvent", &AttachFilteredEvent); 79 RouteStaticFunction("AttachFilteredEvent", &AttachFilteredEvent);
81 RouteStaticFunction("DetachFilteredEvent", &DetachFilteredEvent); 80 RouteStaticFunction("DetachFilteredEvent", &DetachFilteredEvent);
82 RouteStaticFunction("MatchAgainstEventFilter", &MatchAgainstEventFilter); 81 RouteStaticFunction("MatchAgainstEventFilter", &MatchAgainstEventFilter);
83 } 82 }
84 83
85 virtual ~ExtensionImpl() {} 84 virtual ~ExtensionImpl() {}
86 85
87 // Attach an event name to an object. 86 // Attach an event name to an object.
88 static v8::Handle<v8::Value> AttachEvent(const v8::Arguments& args) { 87 static v8::Handle<v8::Value> AttachEvent(const v8::Arguments& args) {
89 DCHECK(args.Length() == 1); 88 DCHECK(args.Length() == 1);
90 // TODO(erikkay) should enforce that event name is a string in the bindings 89 // TODO(erikkay) should enforce that event name is a string in the bindings
91 DCHECK(args[0]->IsString() || args[0]->IsUndefined()); 90 DCHECK(args[0]->IsString() || args[0]->IsUndefined());
92 91
93 if (args[0]->IsString()) { 92 if (args[0]->IsString()) {
94 ExtensionImpl* self = GetFromArguments<ExtensionImpl>(args); 93 ExtensionImpl* self = GetFromArguments<ExtensionImpl>(args);
95 std::string event_name = *v8::String::AsciiValue(args[0]->ToString()); 94 std::string event_name = *v8::String::AsciiValue(args[0]->ToString());
96 Dispatcher* dispatcher = self->dispatcher(); 95 Dispatcher* dispatcher = self->dispatcher();
97 const ChromeV8ContextSet& context_set = dispatcher->v8_context_set(); 96 const ChromeV8ContextSet& context_set = dispatcher->v8_context_set();
98 ChromeV8Context* context = context_set.GetByV8Context(self->v8_context()); 97 ChromeV8Context* context = context_set.GetCurrent();
99 CHECK(context); 98 CHECK(context);
100 99
101 if (!dispatcher->CheckContextAccessToExtensionAPI(event_name, context)) 100 if (!dispatcher->CheckCurrentContextAccessToExtensionAPI(event_name))
102 return v8::Undefined(); 101 return v8::Undefined();
103 102
104 std::string extension_id = context->GetExtensionID(); 103 std::string extension_id = context->GetExtensionID();
105 EventListenerCounts& listener_counts = 104 EventListenerCounts& listener_counts =
106 g_listener_counts.Get()[extension_id]; 105 g_listener_counts.Get()[extension_id];
107 if (++listener_counts[event_name] == 1) { 106 if (++listener_counts[event_name] == 1) {
108 content::RenderThread::Get()->Send( 107 content::RenderThread::Get()->Send(
109 new ExtensionHostMsg_AddListener(extension_id, event_name)); 108 new ExtensionHostMsg_AddListener(extension_id, event_name));
110 } 109 }
111 110
112 // This is called the first time the page has added a listener. Since 111 // This is called the first time the page has added a listener. Since
113 // the background page is the only lazy page, we know this is the first 112 // the background page is the only lazy page, we know this is the first
114 // time this listener has been registered. 113 // time this listener has been registered.
115 if (IsLazyBackgroundPage(self->GetRenderView(), context->extension())) { 114 if (IsLazyBackgroundPage(context->extension())) {
116 content::RenderThread::Get()->Send( 115 content::RenderThread::Get()->Send(
117 new ExtensionHostMsg_AddLazyListener(extension_id, event_name)); 116 new ExtensionHostMsg_AddLazyListener(extension_id, event_name));
118 } 117 }
119 } 118 }
120 return v8::Undefined(); 119 return v8::Undefined();
121 } 120 }
122 121
123 static v8::Handle<v8::Value> DetachEvent(const v8::Arguments& args) { 122 static v8::Handle<v8::Value> DetachEvent(const v8::Arguments& args) {
124 DCHECK(args.Length() == 2); 123 DCHECK(args.Length() == 2);
125 // TODO(erikkay) should enforce that event name is a string in the bindings 124 // TODO(erikkay) should enforce that event name is a string in the bindings
126 DCHECK(args[0]->IsString() || args[0]->IsUndefined()); 125 DCHECK(args[0]->IsString() || args[0]->IsUndefined());
127 126
128 if (args[0]->IsString() && args[1]->IsBoolean()) { 127 if (args[0]->IsString() && args[1]->IsBoolean()) {
129 std::string event_name = *v8::String::AsciiValue(args[0]->ToString()); 128 std::string event_name = *v8::String::AsciiValue(args[0]->ToString());
130 bool is_manual = args[1]->BooleanValue(); 129 bool is_manual = args[1]->BooleanValue();
131 130
132 ExtensionImpl* self = GetFromArguments<ExtensionImpl>(args); 131 ExtensionImpl* self = GetFromArguments<ExtensionImpl>(args);
133 Dispatcher* dispatcher = self->dispatcher(); 132 Dispatcher* dispatcher = self->dispatcher();
134 const ChromeV8ContextSet& context_set = dispatcher->v8_context_set(); 133 const ChromeV8ContextSet& context_set = dispatcher->v8_context_set();
135 ChromeV8Context* context = context_set.GetByV8Context(self->v8_context()); 134 ChromeV8Context* context = context_set.GetCurrent();
136 if (!context) 135 if (!context)
137 return v8::Undefined(); 136 return v8::Undefined();
138 137
139 std::string extension_id = context->GetExtensionID(); 138 std::string extension_id = context->GetExtensionID();
140 EventListenerCounts& listener_counts = 139 EventListenerCounts& listener_counts =
141 g_listener_counts.Get()[extension_id]; 140 g_listener_counts.Get()[extension_id];
142 141
143 if (--listener_counts[event_name] == 0) { 142 if (--listener_counts[event_name] == 0) {
144 content::RenderThread::Get()->Send( 143 content::RenderThread::Get()->Send(
145 new ExtensionHostMsg_RemoveListener(extension_id, event_name)); 144 new ExtensionHostMsg_RemoveListener(extension_id, event_name));
146 } 145 }
147 146
148 // DetachEvent is called when the last listener for the context is 147 // DetachEvent is called when the last listener for the context is
149 // removed. If the context is the background page, and it removes the 148 // removed. If the context is the background page, and it removes the
150 // last listener manually, then we assume that it is no longer interested 149 // last listener manually, then we assume that it is no longer interested
151 // in being awakened for this event. 150 // in being awakened for this event.
152 if (is_manual && IsLazyBackgroundPage(self->GetRenderView(), 151 if (is_manual && IsLazyBackgroundPage(context->extension())) {
153 context->extension())) {
154 content::RenderThread::Get()->Send( 152 content::RenderThread::Get()->Send(
155 new ExtensionHostMsg_RemoveLazyListener(extension_id, event_name)); 153 new ExtensionHostMsg_RemoveLazyListener(extension_id, event_name));
156 } 154 }
157 } 155 }
158 return v8::Undefined(); 156 return v8::Undefined();
159 } 157 }
160 158
161 // MatcherID AttachFilteredEvent(string event_name, object filter) 159 // MatcherID AttachFilteredEvent(string event_name, object filter)
162 // event_name - Name of the event to attach. 160 // event_name - Name of the event to attach.
163 // filter - Which instances of the named event are we interested in. 161 // filter - Which instances of the named event are we interested in.
164 // returns the id assigned to the listener, which will be returned from calls 162 // returns the id assigned to the listener, which will be returned from calls
165 // to MatchAgainstEventFilter where this listener matches. 163 // to MatchAgainstEventFilter where this listener matches.
166 static v8::Handle<v8::Value> AttachFilteredEvent(const v8::Arguments& args) { 164 static v8::Handle<v8::Value> AttachFilteredEvent(const v8::Arguments& args) {
167 DCHECK_EQ(2, args.Length()); 165 DCHECK_EQ(2, args.Length());
168 DCHECK(args[0]->IsString()); 166 DCHECK(args[0]->IsString());
169 DCHECK(args[1]->IsObject()); 167 DCHECK(args[1]->IsObject());
170 168
171 ExtensionImpl* self = GetFromArguments<ExtensionImpl>(args); 169 ExtensionImpl* self = GetFromArguments<ExtensionImpl>(args);
172 Dispatcher* dispatcher = self->dispatcher(); 170 Dispatcher* dispatcher = self->dispatcher();
173 const ChromeV8ContextSet& context_set = dispatcher->v8_context_set(); 171 const ChromeV8ContextSet& context_set = dispatcher->v8_context_set();
174 ChromeV8Context* context = context_set.GetByV8Context(self->v8_context()); 172 ChromeV8Context* context = context_set.GetCurrent();
175 DCHECK(context); 173 DCHECK(context);
176 if (!context) 174 if (!context)
177 return v8::Integer::New(-1); 175 return v8::Integer::New(-1);
178 176
179 std::string event_name = *v8::String::AsciiValue(args[0]); 177 std::string event_name = *v8::String::AsciiValue(args[0]);
180 // This method throws an exception if it returns false. 178 // This method throws an exception if it returns false.
181 if (!dispatcher->CheckContextAccessToExtensionAPI(event_name, context)) 179 if (!dispatcher->CheckCurrentContextAccessToExtensionAPI(event_name))
182 return v8::Undefined(); 180 return v8::Undefined();
183 181
184 std::string extension_id = context->GetExtensionID(); 182 std::string extension_id = context->GetExtensionID();
185 if (extension_id.empty()) 183 if (extension_id.empty())
186 return v8::Integer::New(-1); 184 return v8::Integer::New(-1);
187 185
188 scoped_ptr<base::DictionaryValue> filter; 186 scoped_ptr<base::DictionaryValue> filter;
189 scoped_ptr<content::V8ValueConverter> converter( 187 scoped_ptr<content::V8ValueConverter> converter(
190 content::V8ValueConverter::create()); 188 content::V8ValueConverter::create());
191 189
192 base::DictionaryValue* filter_dict = NULL; 190 base::DictionaryValue* filter_dict = NULL;
193 base::Value* filter_value = 191 base::Value* filter_value = converter->FromV8Value(args[1]->ToObject(),
194 converter->FromV8Value(args[1]->ToObject(), context->v8_context()); 192 v8::Context::GetCurrent());
195 if (!filter_value) 193 if (!filter_value)
196 return v8::Integer::New(-1); 194 return v8::Integer::New(-1);
197 if (!filter_value->GetAsDictionary(&filter_dict)) { 195 if (!filter_value->GetAsDictionary(&filter_dict)) {
198 delete filter_value; 196 delete filter_value;
199 return v8::Integer::New(-1); 197 return v8::Integer::New(-1);
200 } 198 }
201 199
202 filter.reset(filter_dict); 200 filter.reset(filter_dict);
203 extensions::EventFilter& event_filter = g_event_filter.Get(); 201 extensions::EventFilter& event_filter = g_event_filter.Get();
204 int id = event_filter.AddEventMatcher(event_name, ParseEventMatcher( 202 int id = event_filter.AddEventMatcher(event_name, ParseEventMatcher(
205 filter.get())); 203 filter.get()));
206 204
207 // Only send IPCs the first time a filter gets added. 205 // Only send IPCs the first time a filter gets added.
208 if (AddFilter(event_name, extension_id, filter.get())) { 206 if (AddFilter(event_name, extension_id, filter.get())) {
209 bool lazy = IsLazyBackgroundPage(self->GetRenderView(), 207 bool lazy = IsLazyBackgroundPage(context->extension());
210 context->extension());
211 content::RenderThread::Get()->Send( 208 content::RenderThread::Get()->Send(
212 new ExtensionHostMsg_AddFilteredListener(extension_id, event_name, 209 new ExtensionHostMsg_AddFilteredListener(extension_id, event_name,
213 *filter, lazy)); 210 *filter, lazy));
214 } 211 }
215 212
216 return v8::Integer::New(id); 213 return v8::Integer::New(id);
217 } 214 }
218 215
219 // Add a filter to |event_name| in |extension_id|, returning true if it 216 // Add a filter to |event_name| in |extension_id|, returning true if it
220 // was the first filter for that event in that extension. 217 // was the first filter for that event in that extension.
(...skipping 28 matching lines...) Expand all
249 // manual - false if this is part of the extension unload process where all 246 // manual - false if this is part of the extension unload process where all
250 // listeners are automatically detached. 247 // listeners are automatically detached.
251 static v8::Handle<v8::Value> DetachFilteredEvent(const v8::Arguments& args) { 248 static v8::Handle<v8::Value> DetachFilteredEvent(const v8::Arguments& args) {
252 DCHECK_EQ(2, args.Length()); 249 DCHECK_EQ(2, args.Length());
253 DCHECK(args[0]->IsInt32()); 250 DCHECK(args[0]->IsInt32());
254 DCHECK(args[1]->IsBoolean()); 251 DCHECK(args[1]->IsBoolean());
255 bool is_manual = args[1]->BooleanValue(); 252 bool is_manual = args[1]->BooleanValue();
256 ExtensionImpl* self = GetFromArguments<ExtensionImpl>(args); 253 ExtensionImpl* self = GetFromArguments<ExtensionImpl>(args);
257 Dispatcher* dispatcher = self->dispatcher(); 254 Dispatcher* dispatcher = self->dispatcher();
258 const ChromeV8ContextSet& context_set = dispatcher->v8_context_set(); 255 const ChromeV8ContextSet& context_set = dispatcher->v8_context_set();
259 ChromeV8Context* context = context_set.GetByV8Context(self->v8_context()); 256 ChromeV8Context* context = context_set.GetCurrent();
260 if (!context) 257 if (!context)
261 return v8::Undefined(); 258 return v8::Undefined();
262 259
263 std::string extension_id = context->GetExtensionID(); 260 std::string extension_id = context->GetExtensionID();
264 if (extension_id.empty()) 261 if (extension_id.empty())
265 return v8::Undefined(); 262 return v8::Undefined();
266 263
267 int matcher_id = args[0]->Int32Value(); 264 int matcher_id = args[0]->Int32Value();
268 extensions::EventFilter& event_filter = g_event_filter.Get(); 265 extensions::EventFilter& event_filter = g_event_filter.Get();
269 extensions::EventMatcher* event_matcher = 266 extensions::EventMatcher* event_matcher =
270 event_filter.GetEventMatcher(matcher_id); 267 event_filter.GetEventMatcher(matcher_id);
271 268
272 const std::string& event_name = event_filter.GetEventName(matcher_id); 269 const std::string& event_name = event_filter.GetEventName(matcher_id);
273 270
274 // Only send IPCs the last time a filter gets removed. 271 // Only send IPCs the last time a filter gets removed.
275 if (RemoveFilter(event_name, extension_id, event_matcher->value())) { 272 if (RemoveFilter(event_name, extension_id, event_matcher->value())) {
276 bool lazy = is_manual && IsLazyBackgroundPage(self->GetRenderView(), 273 bool lazy = is_manual && IsLazyBackgroundPage(context->extension());
277 context->extension());
278 content::RenderThread::Get()->Send( 274 content::RenderThread::Get()->Send(
279 new ExtensionHostMsg_RemoveFilteredListener(extension_id, event_name, 275 new ExtensionHostMsg_RemoveFilteredListener(extension_id, event_name,
280 *event_matcher->value(), 276 *event_matcher->value(),
281 lazy)); 277 lazy));
282 } 278 }
283 279
284 event_filter.RemoveEventMatcher(matcher_id); 280 event_filter.RemoveEventMatcher(matcher_id);
285 281
286 return v8::Undefined(); 282 return v8::Undefined();
287 } 283 }
(...skipping 21 matching lines...) Expand all
309 extensions::EventFilteringInfo info; 305 extensions::EventFilteringInfo info;
310 v8::Handle<v8::String> url(v8::String::New("url")); 306 v8::Handle<v8::String> url(v8::String::New("url"));
311 if (object->Has(url)) { 307 if (object->Has(url)) {
312 v8::Handle<v8::Value> url_value(object->Get(url)); 308 v8::Handle<v8::Value> url_value(object->Get(url));
313 info.SetURL(GURL(*v8::String::AsciiValue(url_value))); 309 info.SetURL(GURL(*v8::String::AsciiValue(url_value)));
314 } 310 }
315 return info; 311 return info;
316 } 312 }
317 313
318 private: 314 private:
319 static bool IsLazyBackgroundPage(content::RenderView* render_view, 315 static bool IsLazyBackgroundPage(const Extension* extension) {
320 const Extension* extension) { 316 content::RenderView* render_view = GetCurrentRenderView();
321 if (!render_view) 317 if (!render_view)
322 return false; 318 return false;
319
323 ExtensionHelper* helper = ExtensionHelper::Get(render_view); 320 ExtensionHelper* helper = ExtensionHelper::Get(render_view);
324 return (extension && extension->has_lazy_background_page() && 321 return (extension && extension->has_lazy_background_page() &&
325 helper->view_type() == chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE); 322 helper->view_type() == chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE);
326 } 323 }
327 324
328 static scoped_ptr<extensions::EventMatcher> ParseEventMatcher( 325 static scoped_ptr<extensions::EventMatcher> ParseEventMatcher(
329 base::DictionaryValue* filter_dict) { 326 base::DictionaryValue* filter_dict) {
330 return scoped_ptr<extensions::EventMatcher>(new extensions::EventMatcher( 327 return scoped_ptr<extensions::EventMatcher>(new extensions::EventMatcher(
331 scoped_ptr<base::DictionaryValue>(filter_dict->DeepCopy()))); 328 scoped_ptr<base::DictionaryValue>(filter_dict->DeepCopy())));
332 } 329 }
333 }; 330 };
334 331
335 } // namespace 332 } // namespace
336 333
337 // static 334 // static
338 ChromeV8Extension* EventBindings::Create(Dispatcher* dispatcher, 335 ChromeV8Extension* EventBindings::Get(Dispatcher* dispatcher) {
339 v8::Handle<v8::Context> context) { 336 return new ExtensionImpl(dispatcher);
340 return new ExtensionImpl(dispatcher, context);
341 } 337 }
342 338
343 } // namespace extensions 339 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/renderer/extensions/event_bindings.h ('k') | chrome/renderer/extensions/event_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698