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

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

Issue 15855010: Make ExtensionMsg_MessageInvoke run a module system function rather than a (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix test compile Created 7 years, 6 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
« no previous file with comments | « chrome/renderer/extensions/dispatcher.h ('k') | chrome/renderer/extensions/event_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/dispatcher.h" 5 #include "chrome/renderer/extensions/dispatcher.h"
6 6
7 #include "base/callback.h" 7 #include "base/callback.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/debug/alias.h" 9 #include "base/debug/alias.h"
10 #include "base/json/json_reader.h" 10 #include "base/json/json_reader.h"
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 using WebKit::WebView; 92 using WebKit::WebView;
93 using content::RenderThread; 93 using content::RenderThread;
94 using content::RenderView; 94 using content::RenderView;
95 95
96 namespace extensions { 96 namespace extensions {
97 97
98 namespace { 98 namespace {
99 99
100 static const int64 kInitialExtensionIdleHandlerDelayMs = 5*1000; 100 static const int64 kInitialExtensionIdleHandlerDelayMs = 5*1000;
101 static const int64 kMaxExtensionIdleHandlerDelayMs = 5*60*1000; 101 static const int64 kMaxExtensionIdleHandlerDelayMs = 5*60*1000;
102 static const char kEventDispatchFunction[] = "Event.dispatchEvent"; 102 static const char kEventModule[] = "event_bindings";
103 static const char kEventDispatchFunction[] = "dispatchEvent";
103 static const char kOnSuspendEvent[] = "runtime.onSuspend"; 104 static const char kOnSuspendEvent[] = "runtime.onSuspend";
104 static const char kOnSuspendCanceledEvent[] = "runtime.onSuspendCanceled"; 105 static const char kOnSuspendCanceledEvent[] = "runtime.onSuspendCanceled";
105 106
106 static v8::Handle<v8::Object> GetOrCreateChrome( 107 static v8::Handle<v8::Object> GetOrCreateChrome(
107 v8::Handle<v8::Context> context) { 108 v8::Handle<v8::Context> context) {
108 v8::Handle<v8::String> chrome_string(v8::String::New("chrome")); 109 v8::Handle<v8::String> chrome_string(v8::String::New("chrome"));
109 v8::Handle<v8::Object> global(context->Global()); 110 v8::Handle<v8::Object> global(context->Global());
110 v8::Handle<v8::Value> chrome(global->Get(chrome_string)); 111 v8::Handle<v8::Value> chrome(global->Get(chrome_string));
111 if (chrome.IsEmpty() || chrome->IsUndefined()) { 112 if (chrome.IsEmpty() || chrome->IsUndefined()) {
112 v8::Handle<v8::Object> chrome_object(v8::Object::New()); 113 v8::Handle<v8::Object> chrome_object(v8::Object::New());
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 }; 361 };
361 362
362 class LoggingNativeHandler : public ObjectBackedNativeHandler { 363 class LoggingNativeHandler : public ObjectBackedNativeHandler {
363 public: 364 public:
364 explicit LoggingNativeHandler(ChromeV8Context* context) 365 explicit LoggingNativeHandler(ChromeV8Context* context)
365 : ObjectBackedNativeHandler(context) { 366 : ObjectBackedNativeHandler(context) {
366 RouteFunction("DCHECK", 367 RouteFunction("DCHECK",
367 base::Bind(&LoggingNativeHandler::Dcheck, base::Unretained(this))); 368 base::Bind(&LoggingNativeHandler::Dcheck, base::Unretained(this)));
368 RouteFunction("CHECK", 369 RouteFunction("CHECK",
369 base::Bind(&LoggingNativeHandler::Check, base::Unretained(this))); 370 base::Bind(&LoggingNativeHandler::Check, base::Unretained(this)));
371 RouteFunction("DCHECK_IS_ON",
372 base::Bind(&LoggingNativeHandler::DcheckIsOn, base::Unretained(this)));
370 } 373 }
371 374
372 v8::Handle<v8::Value> Check(const v8::Arguments& args) { 375 v8::Handle<v8::Value> Check(const v8::Arguments& args) {
373 bool check_value; 376 bool check_value;
374 std::string error_message; 377 std::string error_message;
375 ParseArgs(args, &check_value, &error_message); 378 ParseArgs(args, &check_value, &error_message);
376 CHECK(check_value) << error_message; 379 CHECK(check_value) << error_message;
377 return v8::Undefined(); 380 return v8::Undefined();
378 } 381 }
379 382
380 v8::Handle<v8::Value> Dcheck(const v8::Arguments& args) { 383 v8::Handle<v8::Value> Dcheck(const v8::Arguments& args) {
381 bool check_value; 384 bool check_value;
382 std::string error_message; 385 std::string error_message;
383 ParseArgs(args, &check_value, &error_message); 386 ParseArgs(args, &check_value, &error_message);
384 DCHECK(check_value) << error_message; 387 DCHECK(check_value) << error_message;
385 return v8::Undefined(); 388 return v8::Undefined();
386 } 389 }
387 390
391 v8::Handle<v8::Value> DcheckIsOn(const v8::Arguments& args) {
392 return v8::Boolean::New(DCHECK_IS_ON());
393 }
394
388 private: 395 private:
389 void ParseArgs(const v8::Arguments& args, 396 void ParseArgs(const v8::Arguments& args,
390 bool* check_value, 397 bool* check_value,
391 std::string* error_message) { 398 std::string* error_message) {
392 CHECK_LE(args.Length(), 2); 399 CHECK_LE(args.Length(), 2);
393 *check_value = args[0]->BooleanValue(); 400 *check_value = args[0]->BooleanValue();
394 if (args.Length() == 2) 401 if (args.Length() == 2)
395 *error_message = "Error: " + std::string( 402 *error_message = "Error: " + std::string(
396 *v8::String::AsciiValue(args[1])); 403 *v8::String::AsciiValue(args[1]));
397 404
(...skipping 20 matching lines...) Expand all
418 return dflt; 425 return dflt;
419 std::string ascii_value = *v8::String::AsciiValue(v8_string); 426 std::string ascii_value = *v8::String::AsciiValue(v8_string);
420 return ascii_value.empty() ? dflt : ascii_value; 427 return ascii_value.empty() ? dflt : ascii_value;
421 } 428 }
422 }; 429 };
423 430
424 void InstallAppBindings(ModuleSystem* module_system, 431 void InstallAppBindings(ModuleSystem* module_system,
425 v8::Handle<v8::Object> chrome, 432 v8::Handle<v8::Object> chrome,
426 v8::Handle<v8::Object> chrome_hidden) { 433 v8::Handle<v8::Object> chrome_hidden) {
427 module_system->SetLazyField(chrome, "app", "app", "chromeApp"); 434 module_system->SetLazyField(chrome, "app", "app", "chromeApp");
428 module_system->SetLazyField(chrome_hidden, "app", "app",
429 "chromeHiddenApp");
430 } 435 }
431 436
432 void InstallWebstoreBindings(ModuleSystem* module_system, 437 void InstallWebstoreBindings(ModuleSystem* module_system,
433 v8::Handle<v8::Object> chrome, 438 v8::Handle<v8::Object> chrome,
434 v8::Handle<v8::Object> chrome_hidden) { 439 v8::Handle<v8::Object> chrome_hidden) {
435 module_system->SetLazyField(chrome, "webstore", "webstore", "chromeWebstore"); 440 module_system->SetLazyField(chrome, "webstore", "webstore", "chromeWebstore");
436 module_system->SetLazyField(chrome_hidden, "webstore", "webstore", 441 module_system->SetLazyField(chrome_hidden, "webstore", "webstore",
437 "chromeHiddenWebstore"); 442 "chromeHiddenWebstore");
438 } 443 }
439 444
445 // Calls a method |method_name| in a module |module_name| belonging to the
446 // module system from |context|. Intended as a callback target from
447 // ChromeV8ContextSet::ForEach.
448 void CallModuleMethod(const std::string& module_name,
449 const std::string& method_name,
450 const base::ListValue* args,
451 ChromeV8Context* context) {
452 v8::HandleScope handle_scope;
453 v8::Context::Scope context_scope(context->v8_context());
454
455 scoped_ptr<content::V8ValueConverter> converter(
456 content::V8ValueConverter::create());
457
458 std::vector<v8::Handle<v8::Value> > arguments;
459 for (base::ListValue::const_iterator it = args->begin(); it != args->end();
460 ++it) {
461 arguments.push_back(converter->ToV8Value(*it, context->v8_context()));
462 }
463
464 context->module_system()->CallModuleMethod(
465 module_name, method_name, &arguments);
466 }
467
440 } // namespace 468 } // namespace
441 469
442 Dispatcher::Dispatcher() 470 Dispatcher::Dispatcher()
443 : content_watcher_(new ContentWatcher(this)), 471 : content_watcher_(new ContentWatcher(this)),
444 is_webkit_initialized_(false), 472 is_webkit_initialized_(false),
445 webrequest_adblock_(false), 473 webrequest_adblock_(false),
446 webrequest_adblock_plus_(false), 474 webrequest_adblock_plus_(false),
447 webrequest_other_(false), 475 webrequest_other_(false),
448 source_map_(&ResourceBundle::GetSharedInstance()) { 476 source_map_(&ResourceBundle::GetSharedInstance()) {
449 const CommandLine& command_line = *(CommandLine::ForCurrentProcess()); 477 const CommandLine& command_line = *(CommandLine::ForCurrentProcess());
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
539 for (size_t i = 0; i < names.size(); ++i) 567 for (size_t i = 0; i < names.size(); ++i)
540 function_names_.insert(names[i]); 568 function_names_.insert(names[i]);
541 } 569 }
542 570
543 void Dispatcher::OnSetChannel(int channel) { 571 void Dispatcher::OnSetChannel(int channel) {
544 Feature::SetCurrentChannel( 572 Feature::SetCurrentChannel(
545 static_cast<chrome::VersionInfo::Channel>(channel)); 573 static_cast<chrome::VersionInfo::Channel>(channel));
546 } 574 }
547 575
548 void Dispatcher::OnMessageInvoke(const std::string& extension_id, 576 void Dispatcher::OnMessageInvoke(const std::string& extension_id,
577 const std::string& module_name,
549 const std::string& function_name, 578 const std::string& function_name,
550 const base::ListValue& args, 579 const base::ListValue& args,
551 bool user_gesture) { 580 bool user_gesture) {
552 scoped_ptr<WebScopedUserGesture> web_user_gesture; 581 InvokeModuleSystemMethod(
553 if (user_gesture) { 582 NULL, extension_id, module_name, function_name, args, user_gesture);
554 web_user_gesture.reset(new WebScopedUserGesture);
555 }
556
557 v8_context_set_.DispatchChromeHiddenMethod(
558 extension_id, function_name, args, NULL);
559
560 // Reset the idle handler each time there's any activity like event or message
561 // dispatch, for which Invoke is the chokepoint.
562 if (is_extension_process_) {
563 RenderThread::Get()->ScheduleIdleHandler(
564 kInitialExtensionIdleHandlerDelayMs);
565 }
566
567 // Tell the browser process when an event has been dispatched with a lazy
568 // background page active.
569 const Extension* extension = extensions_.GetByID(extension_id);
570 if (extension && BackgroundInfo::HasLazyBackgroundPage(extension) &&
571 function_name == kEventDispatchFunction) {
572 RenderView* background_view =
573 ExtensionHelper::GetBackgroundPage(extension_id);
574 if (background_view) {
575 background_view->Send(new ExtensionHostMsg_EventAck(
576 background_view->GetRoutingID()));
577 }
578 }
579 } 583 }
580 584
581 void Dispatcher::OnDispatchOnConnect( 585 void Dispatcher::OnDispatchOnConnect(
582 int target_port_id, 586 int target_port_id,
583 const std::string& channel_name, 587 const std::string& channel_name,
584 const base::DictionaryValue& source_tab, 588 const base::DictionaryValue& source_tab,
585 const ExtensionMsg_ExternalConnectionInfo& info) { 589 const ExtensionMsg_ExternalConnectionInfo& info) {
586 MiscellaneousBindings::DispatchOnConnect( 590 MiscellaneousBindings::DispatchOnConnect(
587 v8_context_set_.GetAll(), 591 v8_context_set_.GetAll(),
588 target_port_id, channel_name, source_tab, 592 target_port_id, channel_name, source_tab,
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
864 source_map_.RegisterSource("json_schema", IDR_JSON_SCHEMA_JS); 868 source_map_.RegisterSource("json_schema", IDR_JSON_SCHEMA_JS);
865 source_map_.RegisterSource("test", IDR_TEST_CUSTOM_BINDINGS_JS); 869 source_map_.RegisterSource("test", IDR_TEST_CUSTOM_BINDINGS_JS);
866 870
867 // Libraries. 871 // Libraries.
868 source_map_.RegisterSource("contentWatcher", IDR_CONTENT_WATCHER_JS); 872 source_map_.RegisterSource("contentWatcher", IDR_CONTENT_WATCHER_JS);
869 source_map_.RegisterSource("imageUtil", IDR_IMAGE_UTIL_JS); 873 source_map_.RegisterSource("imageUtil", IDR_IMAGE_UTIL_JS);
870 source_map_.RegisterSource("lastError", IDR_LAST_ERROR_JS); 874 source_map_.RegisterSource("lastError", IDR_LAST_ERROR_JS);
871 source_map_.RegisterSource("schemaUtils", IDR_SCHEMA_UTILS_JS); 875 source_map_.RegisterSource("schemaUtils", IDR_SCHEMA_UTILS_JS);
872 source_map_.RegisterSource("sendRequest", IDR_SEND_REQUEST_JS); 876 source_map_.RegisterSource("sendRequest", IDR_SEND_REQUEST_JS);
873 source_map_.RegisterSource("setIcon", IDR_SET_ICON_JS); 877 source_map_.RegisterSource("setIcon", IDR_SET_ICON_JS);
878 source_map_.RegisterSource("unload_event", IDR_UNLOAD_EVENT_JS);
874 source_map_.RegisterSource("utils", IDR_UTILS_JS); 879 source_map_.RegisterSource("utils", IDR_UTILS_JS);
875 source_map_.RegisterSource("entryIdManager", IDR_ENTRY_ID_MANAGER); 880 source_map_.RegisterSource("entryIdManager", IDR_ENTRY_ID_MANAGER);
876 881
877 // Custom bindings. 882 // Custom bindings.
878 source_map_.RegisterSource("app", IDR_APP_CUSTOM_BINDINGS_JS); 883 source_map_.RegisterSource("app", IDR_APP_CUSTOM_BINDINGS_JS);
879 source_map_.RegisterSource("app.runtime", IDR_APP_RUNTIME_CUSTOM_BINDINGS_JS); 884 source_map_.RegisterSource("app.runtime", IDR_APP_RUNTIME_CUSTOM_BINDINGS_JS);
880 source_map_.RegisterSource("app.window", IDR_APP_WINDOW_CUSTOM_BINDINGS_JS); 885 source_map_.RegisterSource("app.window", IDR_APP_WINDOW_CUSTOM_BINDINGS_JS);
881 source_map_.RegisterSource("bluetooth", IDR_BLUETOOTH_CUSTOM_BINDINGS_JS); 886 source_map_.RegisterSource("bluetooth", IDR_BLUETOOTH_CUSTOM_BINDINGS_JS);
882 source_map_.RegisterSource("browserAction", 887 source_map_.RegisterSource("browserAction",
883 IDR_BROWSER_ACTION_CUSTOM_BINDINGS_JS); 888 IDR_BROWSER_ACTION_CUSTOM_BINDINGS_JS);
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
1056 switch (context_type) { 1061 switch (context_type) {
1057 case Feature::UNSPECIFIED_CONTEXT: 1062 case Feature::UNSPECIFIED_CONTEXT:
1058 case Feature::WEB_PAGE_CONTEXT: 1063 case Feature::WEB_PAGE_CONTEXT:
1059 // TODO(kalman): see comment below about ExtensionAPI. 1064 // TODO(kalman): see comment below about ExtensionAPI.
1060 InstallBindings(module_system.get(), v8_context, "app"); 1065 InstallBindings(module_system.get(), v8_context, "app");
1061 InstallBindings(module_system.get(), v8_context, "webstore"); 1066 InstallBindings(module_system.get(), v8_context, "webstore");
1062 break; 1067 break;
1063 case Feature::BLESSED_EXTENSION_CONTEXT: 1068 case Feature::BLESSED_EXTENSION_CONTEXT:
1064 case Feature::UNBLESSED_EXTENSION_CONTEXT: 1069 case Feature::UNBLESSED_EXTENSION_CONTEXT:
1065 case Feature::CONTENT_SCRIPT_CONTEXT: 1070 case Feature::CONTENT_SCRIPT_CONTEXT:
1066 if (extension && !extension->is_platform_app())
1067 module_system->Require("miscellaneous_bindings");
1068 module_system->Require("json"); // see paranoid comment in json.js 1071 module_system->Require("json"); // see paranoid comment in json.js
1069 1072
1070 // TODO(kalman): move this code back out of the switch and execute it 1073 // TODO(kalman): move this code back out of the switch and execute it
1071 // regardless of |context_type|. ExtensionAPI knows how to return the 1074 // regardless of |context_type|. ExtensionAPI knows how to return the
1072 // correct APIs, however, until it doesn't have a 2MB overhead we can't 1075 // correct APIs, however, until it doesn't have a 2MB overhead we can't
1073 // load it in every process. 1076 // load it in every process.
1074 RegisterSchemaGeneratedBindings(module_system.get(), context); 1077 RegisterSchemaGeneratedBindings(module_system.get(), context);
1075 break; 1078 break;
1076 } 1079 }
1077 1080
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
1342 RenderThread::Get()->Send( 1345 RenderThread::Get()->Send(
1343 new ExtensionHostMsg_ShouldSuspendAck(extension_id, sequence_id)); 1346 new ExtensionHostMsg_ShouldSuspendAck(extension_id, sequence_id));
1344 } 1347 }
1345 1348
1346 void Dispatcher::OnSuspend(const std::string& extension_id) { 1349 void Dispatcher::OnSuspend(const std::string& extension_id) {
1347 // Dispatch the suspend event. This doesn't go through the standard event 1350 // Dispatch the suspend event. This doesn't go through the standard event
1348 // dispatch machinery because it requires special handling. We need to let 1351 // dispatch machinery because it requires special handling. We need to let
1349 // the browser know when we are starting and stopping the event dispatch, so 1352 // the browser know when we are starting and stopping the event dispatch, so
1350 // that it still considers the extension idle despite any activity the suspend 1353 // that it still considers the extension idle despite any activity the suspend
1351 // event creates. 1354 // event creates.
1352 base::ListValue args; 1355 DispatchEvent(extension_id, kOnSuspendEvent);
1353 args.Set(0, new base::StringValue(kOnSuspendEvent));
1354 args.Set(1, new base::ListValue());
1355 v8_context_set_.DispatchChromeHiddenMethod(
1356 extension_id, kEventDispatchFunction, args, NULL);
1357
1358 RenderThread::Get()->Send(new ExtensionHostMsg_SuspendAck(extension_id)); 1356 RenderThread::Get()->Send(new ExtensionHostMsg_SuspendAck(extension_id));
1359 } 1357 }
1360 1358
1361 void Dispatcher::OnCancelSuspend(const std::string& extension_id) { 1359 void Dispatcher::OnCancelSuspend(const std::string& extension_id) {
1362 base::ListValue args; 1360 DispatchEvent(extension_id, kOnSuspendCanceledEvent);
1363 args.Set(0, new base::StringValue(kOnSuspendCanceledEvent));
1364 args.Set(1, new base::ListValue());
1365 v8_context_set_.DispatchChromeHiddenMethod(
1366 extension_id, kEventDispatchFunction, args, NULL);
1367 } 1361 }
1368 1362
1369 Feature::Context Dispatcher::ClassifyJavaScriptContext( 1363 Feature::Context Dispatcher::ClassifyJavaScriptContext(
1370 const std::string& extension_id, 1364 const std::string& extension_id,
1371 int extension_group, 1365 int extension_group,
1372 const ExtensionURLInfo& url_info) { 1366 const ExtensionURLInfo& url_info) {
1373 if (extension_group == EXTENSION_GROUP_CONTENT_SCRIPTS) { 1367 if (extension_group == EXTENSION_GROUP_CONTENT_SCRIPTS) {
1374 return extensions_.Contains(extension_id) ? 1368 return extensions_.Contains(extension_id) ?
1375 Feature::CONTENT_SCRIPT_CONTEXT : Feature::UNSPECIFIED_CONTEXT; 1369 Feature::CONTENT_SCRIPT_CONTEXT : Feature::UNSPECIFIED_CONTEXT;
1376 } 1370 }
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1452 "%s cannot be used within a sandboxed frame."; 1446 "%s cannot be used within a sandboxed frame.";
1453 std::string error_msg = base::StringPrintf(kMessage, function_name.c_str()); 1447 std::string error_msg = base::StringPrintf(kMessage, function_name.c_str());
1454 v8::ThrowException( 1448 v8::ThrowException(
1455 v8::Exception::Error(v8::String::New(error_msg.c_str()))); 1449 v8::Exception::Error(v8::String::New(error_msg.c_str())));
1456 return false; 1450 return false;
1457 } 1451 }
1458 1452
1459 return true; 1453 return true;
1460 } 1454 }
1461 1455
1456 void Dispatcher::DispatchEvent(const std::string& extension_id,
1457 const std::string& event_name) const {
1458 base::ListValue args;
1459 args.Set(0, new base::StringValue(event_name));
1460 args.Set(1, new base::ListValue());
1461 v8_context_set_.ForEach(
1462 extension_id,
1463 NULL, // all render views
1464 base::Bind(&CallModuleMethod,
1465 kEventModule,
1466 kEventDispatchFunction,
1467 &args));
1468 }
1469
1470 void Dispatcher::InvokeModuleSystemMethod(
1471 content::RenderView* render_view,
1472 const std::string& extension_id,
1473 const std::string& module_name,
1474 const std::string& function_name,
1475 const base::ListValue& args,
1476 bool user_gesture) {
1477 scoped_ptr<WebScopedUserGesture> web_user_gesture;
1478 if (user_gesture)
1479 web_user_gesture.reset(new WebScopedUserGesture);
1480
1481 v8_context_set_.ForEach(
1482 extension_id,
1483 render_view,
1484 base::Bind(&CallModuleMethod, module_name, function_name, &args));
1485
1486 // Reset the idle handler each time there's any activity like event or message
1487 // dispatch, for which Invoke is the chokepoint.
1488 if (is_extension_process_) {
1489 RenderThread::Get()->ScheduleIdleHandler(
1490 kInitialExtensionIdleHandlerDelayMs);
1491 }
1492
1493 // Tell the browser process when an event has been dispatched with a lazy
1494 // background page active.
1495 const Extension* extension = extensions_.GetByID(extension_id);
1496 if (extension && BackgroundInfo::HasLazyBackgroundPage(extension) &&
1497 module_name == kEventModule &&
1498 function_name == kEventDispatchFunction) {
1499 RenderView* background_view =
1500 ExtensionHelper::GetBackgroundPage(extension_id);
1501 if (background_view) {
1502 background_view->Send(new ExtensionHostMsg_EventAck(
1503 background_view->GetRoutingID()));
1504 }
1505 }
1506 }
1507
1462 } // namespace extensions 1508 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/renderer/extensions/dispatcher.h ('k') | chrome/renderer/extensions/event_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698