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