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 3 // found in the LICENSE file. 4 5 #include "chrome/browser/extensions/event_router_forwarder.h" 6 7 #include "base/bind.h" 8 #include "base/values.h" 9 #include "chrome/browser/browser_process.h" 10 #include "chrome/browser/extensions/extension_system.h" 11 #include "chrome/browser/profiles/profile_manager.h" 12 #include "content/public/browser/browser_thread.h" 13 #include "extensions/browser/event_router.h" 14 #include "url/gurl.h" 15 16 using content::BrowserThread; 17 18 namespace extensions { 19 20 EventRouterForwarder::EventRouterForwarder() { 21 } 22 23 EventRouterForwarder::~EventRouterForwarder() { 24 } 25 26 void EventRouterForwarder::BroadcastEventToRenderers( 27 const std::string& event_name, 28 scoped_ptr<base::ListValue> event_args, 29 const GURL& event_url) { 30 HandleEvent(std::string(), event_name, event_args.Pass(), 0, true, event_url); 31 } 32 33 void EventRouterForwarder::DispatchEventToRenderers( 34 const std::string& event_name, 35 scoped_ptr<base::ListValue> event_args, 36 void* profile, 37 bool use_profile_to_restrict_events, 38 const GURL& event_url) { 39 if (!profile) 40 return; 41 HandleEvent(std::string(), 42 event_name, 43 event_args.Pass(), 44 profile, 45 use_profile_to_restrict_events, 46 event_url); 47 } 48 49 void EventRouterForwarder::BroadcastEventToExtension( 50 const std::string& extension_id, 51 const std::string& event_name, 52 scoped_ptr<base::ListValue> event_args, 53 const GURL& event_url) { 54 HandleEvent(extension_id, event_name, event_args.Pass(), 0, true, event_url); 55 } 56 57 void EventRouterForwarder::DispatchEventToExtension( 58 const std::string& extension_id, 59 const std::string& event_name, 60 scoped_ptr<base::ListValue> event_args, 61 void* profile, 62 bool use_profile_to_restrict_events, 63 const GURL& event_url) { 64 if (!profile) 65 return; 66 HandleEvent(extension_id, event_name, event_args.Pass(), profile, 67 use_profile_to_restrict_events, event_url); 68 } 69 70 void EventRouterForwarder::HandleEvent(const std::string& extension_id, 71 const std::string& event_name, 72 scoped_ptr<base::ListValue> event_args, 73 void* profile_ptr, 74 bool use_profile_to_restrict_events, 75 const GURL& event_url) { 76 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 77 BrowserThread::PostTask( 78 BrowserThread::UI, FROM_HERE, 79 base::Bind(&EventRouterForwarder::HandleEvent, this, 80 extension_id, event_name, base::Passed(&event_args), 81 profile_ptr, use_profile_to_restrict_events, event_url)); 82 return; 83 } 84 85 if (!g_browser_process || !g_browser_process->profile_manager()) 86 return; 87 88 ProfileManager* profile_manager = g_browser_process->profile_manager(); 89 Profile* profile = NULL; 90 if (profile_ptr) { 91 profile = reinterpret_cast<Profile*>(profile_ptr); 92 if (!profile_manager->IsValidProfile(profile)) 93 return; 94 } 95 if (profile) { 96 CallEventRouter(profile, extension_id, event_name, event_args.Pass(), 97 use_profile_to_restrict_events ? profile : NULL, event_url); 98 } else { 99 std::vector<Profile*> profiles(profile_manager->GetLoadedProfiles()); 100 for (size_t i = 0; i < profiles.size(); ++i) { 101 scoped_ptr<base::ListValue> per_profile_event_args( 102 event_args->DeepCopy()); 103 CallEventRouter( 104 profiles[i], extension_id, event_name, per_profile_event_args.Pass(), 105 use_profile_to_restrict_events ? profiles[i] : NULL, event_url); 106 } 107 } 108 } 109 110 void EventRouterForwarder::CallEventRouter( 111 Profile* profile, 112 const std::string& extension_id, 113 const std::string& event_name, 114 scoped_ptr<base::ListValue> event_args, 115 Profile* restrict_to_profile, 116 const GURL& event_url) { 117 // We may not have an extension in cases like chromeos login 118 // (crosbug.com/12856), chrome_frame_net_tests.exe which reuses the chrome 119 // browser single process framework. 120 if (!extensions::ExtensionSystem::Get(profile)->event_router()) 121 return; 122 123 scoped_ptr<Event> event(new Event(event_name, event_args.Pass())); 124 event->restrict_to_browser_context = restrict_to_profile; 125 event->event_url = event_url; 126 if (extension_id.empty()) { 127 ExtensionSystem::Get(profile)->event_router()->BroadcastEvent(event.Pass()); 128 } else { 129 ExtensionSystem::Get(profile)->event_router()-> 130 DispatchEventToExtension(extension_id, event.Pass()); 131 } 132 } 133 134 } // namespace extensions 135