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

Side by Side Diff: chrome/browser/extensions/browser_event_router.cc

Issue 10777004: Support chrome.windows extension API events for browserless Panels. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Synced Created 8 years, 5 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/browser/extensions/browser_event_router.h" 5 #include "chrome/browser/extensions/browser_event_router.h"
6 6
7 #include "base/json/json_writer.h" 7 #include "base/json/json_writer.h"
8 #include "base/values.h" 8 #include "base/values.h"
9 #include "chrome/browser/extensions/api/extension_action/extension_page_actions_ api_constants.h" 9 #include "chrome/browser/extensions/api/extension_action/extension_page_actions_ api_constants.h"
10 #include "chrome/browser/extensions/api/tabs/tabs_constants.h" 10 #include "chrome/browser/extensions/api/tabs/tabs_constants.h"
11 #include "chrome/browser/extensions/event_names.h" 11 #include "chrome/browser/extensions/event_names.h"
12 #include "chrome/browser/extensions/event_router.h" 12 #include "chrome/browser/extensions/event_router.h"
13 #include "chrome/browser/extensions/extension_service.h" 13 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/extensions/extension_system.h"
14 #include "chrome/browser/extensions/extension_tab_util.h" 15 #include "chrome/browser/extensions/extension_tab_util.h"
15 #include "chrome/browser/extensions/window_controller.h" 16 #include "chrome/browser/extensions/window_controller.h"
17 #include "chrome/browser/extensions/window_event_router.h"
16 #include "chrome/browser/profiles/profile.h" 18 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/ui/browser.h" 19 #include "chrome/browser/ui/browser.h"
18 #include "chrome/browser/ui/browser_list.h" 20 #include "chrome/browser/ui/browser_list.h"
19 #include "chrome/browser/ui/browser_tabstrip.h" 21 #include "chrome/browser/ui/browser_tabstrip.h"
20 #include "chrome/browser/ui/tab_contents/tab_contents.h" 22 #include "chrome/browser/ui/tab_contents/tab_contents.h"
21 #include "chrome/browser/ui/tabs/tab_strip_model.h" 23 #include "chrome/browser/ui/tabs/tab_strip_model.h"
22 #include "chrome/common/chrome_notification_types.h"
23 #include "chrome/common/extensions/extension.h" 24 #include "chrome/common/extensions/extension.h"
24 #include "chrome/common/extensions/extension_constants.h" 25 #include "chrome/common/extensions/extension_constants.h"
25 #include "content/public/browser/navigation_controller.h" 26 #include "content/public/browser/navigation_controller.h"
26 #include "content/public/browser/notification_service.h" 27 #include "content/public/browser/notification_service.h"
28 #include "content/public/browser/notification_types.h"
27 #include "content/public/browser/web_contents.h" 29 #include "content/public/browser/web_contents.h"
28 30
29 #if defined(TOOLKIT_GTK)
30 #include "ui/base/x/active_window_watcher_x.h"
31 #endif
32
33 namespace events = extensions::event_names; 31 namespace events = extensions::event_names;
34 namespace tab_keys = extensions::tabs_constants; 32 namespace tab_keys = extensions::tabs_constants;
35 namespace page_action_keys = extension_page_actions_api_constants; 33 namespace page_action_keys = extension_page_actions_api_constants;
36 34
37 using content::NavigationController; 35 using content::NavigationController;
38 using content::WebContents; 36 using content::WebContents;
39 37
40 namespace extensions { 38 namespace extensions {
41 39
42 BrowserEventRouter::TabEntry::TabEntry() 40 BrowserEventRouter::TabEntry::TabEntry()
(...skipping 30 matching lines...) Expand all
73 changed_properties->SetString(tab_keys::kUrlKey, url_.spec()); 71 changed_properties->SetString(tab_keys::kUrlKey, url_.spec());
74 } 72 }
75 73
76 return changed_properties; 74 return changed_properties;
77 } 75 }
78 76
79 void BrowserEventRouter::Init() { 77 void BrowserEventRouter::Init() {
80 if (initialized_) 78 if (initialized_)
81 return; 79 return;
82 BrowserList::AddObserver(this); 80 BrowserList::AddObserver(this);
83 #if defined(TOOLKIT_VIEWS)
84 views::WidgetFocusManager::GetInstance()->AddFocusChangeListener(this);
85 #elif defined(TOOLKIT_GTK)
86 ui::ActiveWindowWatcherX::AddObserver(this);
87 #elif defined(OS_MACOSX)
88 // Needed for when no suitable window can be passed to an extension as the
89 // currently focused window.
90 registrar_.Add(this, chrome::NOTIFICATION_NO_KEY_WINDOW,
91 content::NotificationService::AllSources());
92 #endif
93 81
94 // Init() can happen after the browser is running, so catch up with any 82 // Init() can happen after the browser is running, so catch up with any
95 // windows that already exist. 83 // windows that already exist.
96 for (BrowserList::const_iterator iter = BrowserList::begin(); 84 for (BrowserList::const_iterator iter = BrowserList::begin();
97 iter != BrowserList::end(); ++iter) { 85 iter != BrowserList::end(); ++iter) {
98 RegisterForBrowserNotifications(*iter); 86 RegisterForBrowserNotifications(*iter);
99 87
100 // Also catch up our internal bookkeeping of tab entries. 88 // Also catch up our internal bookkeeping of tab entries.
101 Browser* browser = *iter; 89 Browser* browser = *iter;
102 if (browser->tab_strip_model()) { 90 if (browser->tab_strip_model()) {
103 for (int i = 0; i < browser->tab_strip_model()->count(); ++i) { 91 for (int i = 0; i < browser->tab_strip_model()->count(); ++i) {
104 WebContents* contents = 92 WebContents* contents =
105 chrome::GetTabContentsAt(browser, i)->web_contents(); 93 chrome::GetTabContentsAt(browser, i)->web_contents();
106 int tab_id = ExtensionTabUtil::GetTabId(contents); 94 int tab_id = ExtensionTabUtil::GetTabId(contents);
107 tab_entries_[tab_id] = TabEntry(); 95 tab_entries_[tab_id] = TabEntry();
108 } 96 }
109 } 97 }
110 } 98 }
111 99
112 initialized_ = true; 100 initialized_ = true;
113 } 101 }
114 102
115 BrowserEventRouter::BrowserEventRouter(Profile* profile) 103 BrowserEventRouter::BrowserEventRouter(Profile* profile)
116 : initialized_(false), 104 : initialized_(false),
117 profile_(profile), 105 profile_(profile) {
118 focused_profile_(NULL),
119 focused_window_id_(extension_misc::kUnknownWindowId) {
120 DCHECK(!profile->IsOffTheRecord()); 106 DCHECK(!profile->IsOffTheRecord());
121 } 107 }
122 108
123 BrowserEventRouter::~BrowserEventRouter() { 109 BrowserEventRouter::~BrowserEventRouter() {
124 BrowserList::RemoveObserver(this); 110 BrowserList::RemoveObserver(this);
125 #if defined(TOOLKIT_VIEWS)
126 views::WidgetFocusManager::GetInstance()->RemoveFocusChangeListener(this);
127 #elif defined(TOOLKIT_GTK)
128 ui::ActiveWindowWatcherX::RemoveObserver(this);
129 #endif
130 } 111 }
131 112
132 void BrowserEventRouter::OnBrowserAdded(Browser* browser) { 113 void BrowserEventRouter::OnBrowserAdded(Browser* browser) {
133 RegisterForBrowserNotifications(browser); 114 RegisterForBrowserNotifications(browser);
134 } 115 }
135 116
136 void BrowserEventRouter::RegisterForBrowserNotifications(Browser* browser) { 117 void BrowserEventRouter::RegisterForBrowserNotifications(Browser* browser) {
137 if (!profile_->IsSameProfile(browser->profile())) 118 if (!profile_->IsSameProfile(browser->profile()))
138 return; 119 return;
139 // Start listening to TabStripModel events for this browser. 120 // Start listening to TabStripModel events for this browser.
140 browser->tab_strip_model()->AddObserver(this); 121 browser->tab_strip_model()->AddObserver(this);
141 122
142 // If this is a new window, it isn't ready at this point, so we register to be
143 // notified when it is. If this is an existing window, this is a no-op that we
144 // just do to reduce code complexity.
145 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_WINDOW_READY,
146 content::Source<Browser>(browser));
147
148 for (int i = 0; i < browser->tab_strip_model()->count(); ++i) { 123 for (int i = 0; i < browser->tab_strip_model()->count(); ++i) {
149 RegisterForTabNotifications( 124 RegisterForTabNotifications(
150 chrome::GetTabContentsAt(browser, i)->web_contents()); 125 chrome::GetTabContentsAt(browser, i)->web_contents());
151 } 126 }
152 } 127 }
153 128
154 void BrowserEventRouter::RegisterForTabNotifications(WebContents* contents) { 129 void BrowserEventRouter::RegisterForTabNotifications(WebContents* contents) {
155 registrar_.Add( 130 registrar_.Add(
156 this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, 131 this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
157 content::Source<NavigationController>(&contents->GetController())); 132 content::Source<NavigationController>(&contents->GetController()));
158 133
159 // Observing NOTIFICATION_WEB_CONTENTS_DESTROYED is necessary because it's 134 // Observing NOTIFICATION_WEB_CONTENTS_DESTROYED is necessary because it's
160 // possible for tabs to be created, detached and then destroyed without 135 // possible for tabs to be created, detached and then destroyed without
161 // ever having been re-attached and closed. This happens in the case of 136 // ever having been re-attached and closed. This happens in the case of
162 // a devtools WebContents that is opened in window, docked, then closed. 137 // a devtools WebContents that is opened in window, docked, then closed.
163 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 138 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
164 content::Source<WebContents>(contents)); 139 content::Source<WebContents>(contents));
165 } 140 }
166 141
167 void BrowserEventRouter::UnregisterForTabNotifications(WebContents* contents) { 142 void BrowserEventRouter::UnregisterForTabNotifications(WebContents* contents) {
168 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, 143 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
169 content::Source<NavigationController>(&contents->GetController())); 144 content::Source<NavigationController>(&contents->GetController()));
170 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 145 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
171 content::Source<WebContents>(contents)); 146 content::Source<WebContents>(contents));
172 } 147 }
173 148
174 void BrowserEventRouter::OnBrowserWindowReady(Browser* browser) {
175 ListValue args;
176
177 DCHECK(browser->extension_window_controller());
178 DictionaryValue* window_dictionary =
179 browser->extension_window_controller()->CreateWindowValue();
180 args.Append(window_dictionary);
181
182 std::string json_args;
183 base::JSONWriter::Write(&args, &json_args);
184
185 DispatchEvent(browser->profile(), events::kOnWindowCreated, json_args);
186 }
187
188 void BrowserEventRouter::OnBrowserRemoved(Browser* browser) { 149 void BrowserEventRouter::OnBrowserRemoved(Browser* browser) {
189 if (!profile_->IsSameProfile(browser->profile())) 150 if (!profile_->IsSameProfile(browser->profile()))
190 return; 151 return;
191 152
192 // Stop listening to TabStripModel events for this browser. 153 // Stop listening to TabStripModel events for this browser.
193 browser->tab_strip_model()->RemoveObserver(this); 154 browser->tab_strip_model()->RemoveObserver(this);
194
195 registrar_.Remove(this, chrome::NOTIFICATION_BROWSER_WINDOW_READY,
196 content::Source<Browser>(browser));
197
198 DispatchSimpleBrowserEvent(browser->profile(),
199 ExtensionTabUtil::GetWindowId(browser),
200 events::kOnWindowRemoved);
201 } 155 }
202 156
203 #if defined(TOOLKIT_VIEWS)
204 void BrowserEventRouter::OnNativeFocusChange(gfx::NativeView focused_before,
205 gfx::NativeView focused_now) {
206 if (!focused_now)
207 OnBrowserSetLastActive(NULL);
208 }
209 #elif defined(TOOLKIT_GTK)
210 void BrowserEventRouter::ActiveWindowChanged(GdkWindow* active_window) {
211 if (!active_window)
212 OnBrowserSetLastActive(NULL);
213 }
214 #endif
215
216 void BrowserEventRouter::OnBrowserSetLastActive(Browser* browser) { 157 void BrowserEventRouter::OnBrowserSetLastActive(Browser* browser) {
217 Profile* window_profile = NULL; 158 ExtensionService* service =
218 int window_id = extension_misc::kUnknownWindowId; 159 extensions::ExtensionSystem::Get(profile_)->extension_service();
219 if (browser && profile_->IsSameProfile(browser->profile())) { 160 if (service) {
220 window_profile = browser->profile(); 161 service->window_event_router()->OnActiveWindowChanged(
221 window_id = ExtensionTabUtil::GetWindowId(browser); 162 browser ? browser->extension_window_controller() : NULL);
222 } 163 }
223
224 if (focused_window_id_ == window_id)
225 return;
226
227 // window_profile is either this profile's default profile, its
228 // incognito profile, or NULL iff this profile is losing focus.
229 Profile* previous_focused_profile = focused_profile_;
230 focused_profile_ = window_profile;
231 focused_window_id_ = window_id;
232
233 ListValue real_args;
234 real_args.Append(Value::CreateIntegerValue(window_id));
235 std::string real_json_args;
236 base::JSONWriter::Write(&real_args, &real_json_args);
237
238 // When switching between windows in the default and incognitoi profiles,
239 // dispatch WINDOW_ID_NONE to extensions whose profile lost focus that
240 // can't see the new focused window across the incognito boundary.
241 // See crbug.com/46610.
242 std::string none_json_args;
243 if (focused_profile_ != NULL && previous_focused_profile != NULL &&
244 focused_profile_ != previous_focused_profile) {
245 ListValue none_args;
246 none_args.Append(
247 Value::CreateIntegerValue(extension_misc::kUnknownWindowId));
248 base::JSONWriter::Write(&none_args, &none_json_args);
249 }
250
251 DispatchEventsAcrossIncognito((focused_profile_ ? focused_profile_ :
252 previous_focused_profile),
253 events::kOnWindowFocusedChanged,
254 real_json_args,
255 none_json_args);
256 } 164 }
257 165
258 void BrowserEventRouter::TabCreatedAt(WebContents* contents, 166 void BrowserEventRouter::TabCreatedAt(WebContents* contents,
259 int index, 167 int index,
260 bool active) { 168 bool active) {
261 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); 169 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
262 DispatchEventWithTab(profile, "", events::kOnTabCreated, contents, active); 170 DispatchEventWithTab(profile, "", events::kOnTabCreated, contents, active);
263 171
264 RegisterForTabNotifications(contents); 172 RegisterForTabNotifications(contents);
265 } 173 }
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 NavigationController* source_controller = 457 NavigationController* source_controller =
550 content::Source<NavigationController>(source).ptr(); 458 content::Source<NavigationController>(source).ptr();
551 TabUpdated(source_controller->GetWebContents(), true); 459 TabUpdated(source_controller->GetWebContents(), true);
552 } else if (type == content::NOTIFICATION_WEB_CONTENTS_DESTROYED) { 460 } else if (type == content::NOTIFICATION_WEB_CONTENTS_DESTROYED) {
553 // Tab was destroyed after being detached (without being re-attached). 461 // Tab was destroyed after being detached (without being re-attached).
554 WebContents* contents = content::Source<WebContents>(source).ptr(); 462 WebContents* contents = content::Source<WebContents>(source).ptr();
555 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, 463 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
556 content::Source<NavigationController>(&contents->GetController())); 464 content::Source<NavigationController>(&contents->GetController()));
557 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 465 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
558 content::Source<WebContents>(contents)); 466 content::Source<WebContents>(contents));
559 } else if (type == chrome::NOTIFICATION_BROWSER_WINDOW_READY) {
560 Browser* browser = content::Source<Browser>(source).ptr();
561 OnBrowserWindowReady(browser);
562 #if defined(OS_MACOSX)
563 } else if (type == chrome::NOTIFICATION_NO_KEY_WINDOW) {
564 OnBrowserSetLastActive(NULL);
565 #endif
566 } else { 467 } else {
567 NOTREACHED(); 468 NOTREACHED();
568 } 469 }
569 } 470 }
570 471
571 void BrowserEventRouter::TabChangedAt(TabContents* contents, 472 void BrowserEventRouter::TabChangedAt(TabContents* contents,
572 int index, 473 int index,
573 TabChangeType change_type) { 474 TabChangeType change_type) {
574 TabUpdated(contents->web_contents(), false); 475 TabUpdated(contents->web_contents(), false);
575 } 476 }
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 if (event_name) { 593 if (event_name) {
693 DispatchEventWithTab(profile, 594 DispatchEventWithTab(profile,
694 extension_action.extension_id(), 595 extension_action.extension_id(),
695 event_name, 596 event_name,
696 tab_contents->web_contents(), 597 tab_contents->web_contents(),
697 true); 598 true);
698 } 599 }
699 } 600 }
700 601
701 } // namespace extensions 602 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/browser_event_router.h ('k') | chrome/browser/extensions/browser_extension_window_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698