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

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

Issue 10696208: Move ExtensionEventRouter and related into extensions namespace (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Fixed bug + latest master 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
OLDNEW
(Empty)
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/extension_browser_event_router.h"
6
7 #include "base/json/json_writer.h"
8 #include "base/values.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"
11 #include "chrome/browser/extensions/extension_event_names.h"
12 #include "chrome/browser/extensions/extension_event_router.h"
13 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/extensions/extension_tab_util.h"
15 #include "chrome/browser/extensions/window_controller.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/ui/browser.h"
18 #include "chrome/browser/ui/browser_list.h"
19 #include "chrome/browser/ui/browser_tabstrip.h"
20 #include "chrome/browser/ui/tab_contents/tab_contents.h"
21 #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_constants.h"
25 #include "content/public/browser/navigation_controller.h"
26 #include "content/public/browser/notification_service.h"
27 #include "content/public/browser/web_contents.h"
28
29 #if defined(TOOLKIT_GTK)
30 #include "ui/base/x/active_window_watcher_x.h"
31 #endif
32
33 namespace events = extension_event_names;
34 namespace tab_keys = extensions::tabs_constants;
35 namespace page_action_keys = extension_page_actions_api_constants;
36
37 using content::NavigationController;
38 using content::WebContents;
39
40 ExtensionBrowserEventRouter::TabEntry::TabEntry()
41 : complete_waiting_on_load_(false),
42 url_() {
43 }
44
45 DictionaryValue* ExtensionBrowserEventRouter::TabEntry::UpdateLoadState(
46 const WebContents* contents) {
47 // The tab may go in & out of loading (for instance if iframes navigate).
48 // We only want to respond to the first change from loading to !loading after
49 // the NAV_ENTRY_COMMITTED was fired.
50 if (!complete_waiting_on_load_ || contents->IsLoading())
51 return NULL;
52
53 // Send "complete" state change.
54 complete_waiting_on_load_ = false;
55 DictionaryValue* changed_properties = new DictionaryValue();
56 changed_properties->SetString(tab_keys::kStatusKey,
57 tab_keys::kStatusValueComplete);
58 return changed_properties;
59 }
60
61 DictionaryValue* ExtensionBrowserEventRouter::TabEntry::DidNavigate(
62 const WebContents* contents) {
63 // Send "loading" state change.
64 complete_waiting_on_load_ = true;
65 DictionaryValue* changed_properties = new DictionaryValue();
66 changed_properties->SetString(tab_keys::kStatusKey,
67 tab_keys::kStatusValueLoading);
68
69 if (contents->GetURL() != url_) {
70 url_ = contents->GetURL();
71 changed_properties->SetString(tab_keys::kUrlKey, url_.spec());
72 }
73
74 return changed_properties;
75 }
76
77 void ExtensionBrowserEventRouter::Init() {
78 if (initialized_)
79 return;
80 BrowserList::AddObserver(this);
81 #if defined(TOOLKIT_VIEWS)
82 views::WidgetFocusManager::GetInstance()->AddFocusChangeListener(this);
83 #elif defined(TOOLKIT_GTK)
84 ui::ActiveWindowWatcherX::AddObserver(this);
85 #elif defined(OS_MACOSX)
86 // Needed for when no suitable window can be passed to an extension as the
87 // currently focused window.
88 registrar_.Add(this, chrome::NOTIFICATION_NO_KEY_WINDOW,
89 content::NotificationService::AllSources());
90 #endif
91
92 // Init() can happen after the browser is running, so catch up with any
93 // windows that already exist.
94 for (BrowserList::const_iterator iter = BrowserList::begin();
95 iter != BrowserList::end(); ++iter) {
96 RegisterForBrowserNotifications(*iter);
97
98 // Also catch up our internal bookkeeping of tab entries.
99 Browser* browser = *iter;
100 if (browser->tab_strip_model()) {
101 for (int i = 0; i < browser->tab_strip_model()->count(); ++i) {
102 WebContents* contents =
103 chrome::GetTabContentsAt(browser, i)->web_contents();
104 int tab_id = ExtensionTabUtil::GetTabId(contents);
105 tab_entries_[tab_id] = TabEntry();
106 }
107 }
108 }
109
110 initialized_ = true;
111 }
112
113 ExtensionBrowserEventRouter::ExtensionBrowserEventRouter(Profile* profile)
114 : initialized_(false),
115 profile_(profile),
116 focused_profile_(NULL),
117 focused_window_id_(extension_misc::kUnknownWindowId) {
118 DCHECK(!profile->IsOffTheRecord());
119 }
120
121 ExtensionBrowserEventRouter::~ExtensionBrowserEventRouter() {
122 BrowserList::RemoveObserver(this);
123 #if defined(TOOLKIT_VIEWS)
124 views::WidgetFocusManager::GetInstance()->RemoveFocusChangeListener(this);
125 #elif defined(TOOLKIT_GTK)
126 ui::ActiveWindowWatcherX::RemoveObserver(this);
127 #endif
128 }
129
130 void ExtensionBrowserEventRouter::OnBrowserAdded(Browser* browser) {
131 RegisterForBrowserNotifications(browser);
132 }
133
134 void ExtensionBrowserEventRouter::RegisterForBrowserNotifications(
135 Browser* browser) {
136 if (!profile_->IsSameProfile(browser->profile()))
137 return;
138 // Start listening to TabStripModel events for this browser.
139 browser->tab_strip_model()->AddObserver(this);
140
141 // If this is a new window, it isn't ready at this point, so we register to be
142 // notified when it is. If this is an existing window, this is a no-op that we
143 // just do to reduce code complexity.
144 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_WINDOW_READY,
145 content::Source<Browser>(browser));
146
147 for (int i = 0; i < browser->tab_strip_model()->count(); ++i) {
148 RegisterForTabNotifications(
149 chrome::GetTabContentsAt(browser, i)->web_contents());
150 }
151 }
152
153 void ExtensionBrowserEventRouter::RegisterForTabNotifications(
154 WebContents* contents) {
155 registrar_.Add(
156 this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
157 content::Source<NavigationController>(&contents->GetController()));
158
159 // Observing NOTIFICATION_WEB_CONTENTS_DESTROYED is necessary because it's
160 // 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
162 // a devtools WebContents that is opened in window, docked, then closed.
163 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
164 content::Source<WebContents>(contents));
165 }
166
167 void ExtensionBrowserEventRouter::UnregisterForTabNotifications(
168 WebContents* contents) {
169 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
170 content::Source<NavigationController>(&contents->GetController()));
171 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
172 content::Source<WebContents>(contents));
173 }
174
175 void ExtensionBrowserEventRouter::OnBrowserWindowReady(Browser* browser) {
176 ListValue args;
177
178 DCHECK(browser->extension_window_controller());
179 DictionaryValue* window_dictionary =
180 browser->extension_window_controller()->CreateWindowValue();
181 args.Append(window_dictionary);
182
183 std::string json_args;
184 base::JSONWriter::Write(&args, &json_args);
185
186 DispatchEvent(browser->profile(), events::kOnWindowCreated, json_args);
187 }
188
189 void ExtensionBrowserEventRouter::OnBrowserRemoved(Browser* browser) {
190 if (!profile_->IsSameProfile(browser->profile()))
191 return;
192
193 // Stop listening to TabStripModel events for this browser.
194 browser->tab_strip_model()->RemoveObserver(this);
195
196 registrar_.Remove(this, chrome::NOTIFICATION_BROWSER_WINDOW_READY,
197 content::Source<Browser>(browser));
198
199 DispatchSimpleBrowserEvent(browser->profile(),
200 ExtensionTabUtil::GetWindowId(browser),
201 events::kOnWindowRemoved);
202 }
203
204 #if defined(TOOLKIT_VIEWS)
205 void ExtensionBrowserEventRouter::OnNativeFocusChange(
206 gfx::NativeView focused_before,
207 gfx::NativeView focused_now) {
208 if (!focused_now)
209 OnBrowserSetLastActive(NULL);
210 }
211 #elif defined(TOOLKIT_GTK)
212 void ExtensionBrowserEventRouter::ActiveWindowChanged(
213 GdkWindow* active_window) {
214 if (!active_window)
215 OnBrowserSetLastActive(NULL);
216 }
217 #endif
218
219 void ExtensionBrowserEventRouter::OnBrowserSetLastActive(
220 Browser* browser) {
221 Profile* window_profile = NULL;
222 int window_id = extension_misc::kUnknownWindowId;
223 if (browser && profile_->IsSameProfile(browser->profile())) {
224 window_profile = browser->profile();
225 window_id = ExtensionTabUtil::GetWindowId(browser);
226 }
227
228 if (focused_window_id_ == window_id)
229 return;
230
231 // window_profile is either this profile's default profile, its
232 // incognito profile, or NULL iff this profile is losing focus.
233 Profile* previous_focused_profile = focused_profile_;
234 focused_profile_ = window_profile;
235 focused_window_id_ = window_id;
236
237 ListValue real_args;
238 real_args.Append(Value::CreateIntegerValue(window_id));
239 std::string real_json_args;
240 base::JSONWriter::Write(&real_args, &real_json_args);
241
242 // When switching between windows in the default and incognitoi profiles,
243 // dispatch WINDOW_ID_NONE to extensions whose profile lost focus that
244 // can't see the new focused window across the incognito boundary.
245 // See crbug.com/46610.
246 std::string none_json_args;
247 if (focused_profile_ != NULL && previous_focused_profile != NULL &&
248 focused_profile_ != previous_focused_profile) {
249 ListValue none_args;
250 none_args.Append(
251 Value::CreateIntegerValue(extension_misc::kUnknownWindowId));
252 base::JSONWriter::Write(&none_args, &none_json_args);
253 }
254
255 DispatchEventsAcrossIncognito((focused_profile_ ? focused_profile_ :
256 previous_focused_profile),
257 events::kOnWindowFocusedChanged,
258 real_json_args,
259 none_json_args);
260 }
261
262 void ExtensionBrowserEventRouter::TabCreatedAt(WebContents* contents,
263 int index,
264 bool active) {
265 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
266 DispatchEventWithTab(profile, "", events::kOnTabCreated, contents, active);
267
268 RegisterForTabNotifications(contents);
269 }
270
271 void ExtensionBrowserEventRouter::TabInsertedAt(TabContents* contents,
272 int index,
273 bool active) {
274 // If tab is new, send created event.
275 int tab_id = ExtensionTabUtil::GetTabId(contents->web_contents());
276 if (!GetTabEntry(contents->web_contents())) {
277 tab_entries_[tab_id] = TabEntry();
278
279 TabCreatedAt(contents->web_contents(), index, active);
280 return;
281 }
282
283 ListValue args;
284 args.Append(Value::CreateIntegerValue(tab_id));
285
286 DictionaryValue* object_args = new DictionaryValue();
287 object_args->Set(tab_keys::kNewWindowIdKey, Value::CreateIntegerValue(
288 ExtensionTabUtil::GetWindowIdOfTab(contents->web_contents())));
289 object_args->Set(tab_keys::kNewPositionKey, Value::CreateIntegerValue(
290 index));
291 args.Append(object_args);
292
293 std::string json_args;
294 base::JSONWriter::Write(&args, &json_args);
295
296 DispatchEvent(contents->profile(), events::kOnTabAttached, json_args);
297 }
298
299 void ExtensionBrowserEventRouter::TabDetachedAt(TabContents* contents,
300 int index) {
301 if (!GetTabEntry(contents->web_contents())) {
302 // The tab was removed. Don't send detach event.
303 return;
304 }
305
306 ListValue args;
307 args.Append(Value::CreateIntegerValue(
308 ExtensionTabUtil::GetTabId(contents->web_contents())));
309
310 DictionaryValue* object_args = new DictionaryValue();
311 object_args->Set(tab_keys::kOldWindowIdKey, Value::CreateIntegerValue(
312 ExtensionTabUtil::GetWindowIdOfTab(contents->web_contents())));
313 object_args->Set(tab_keys::kOldPositionKey, Value::CreateIntegerValue(
314 index));
315 args.Append(object_args);
316
317 std::string json_args;
318 base::JSONWriter::Write(&args, &json_args);
319
320 DispatchEvent(contents->profile(), events::kOnTabDetached, json_args);
321 }
322
323 void ExtensionBrowserEventRouter::TabClosingAt(TabStripModel* tab_strip_model,
324 TabContents* contents,
325 int index) {
326 int tab_id = ExtensionTabUtil::GetTabId(contents->web_contents());
327
328 ListValue args;
329 args.Append(Value::CreateIntegerValue(tab_id));
330
331 DictionaryValue* object_args = new DictionaryValue();
332 object_args->SetBoolean(tab_keys::kWindowClosing,
333 tab_strip_model->closing_all());
334 args.Append(object_args);
335
336 std::string json_args;
337 base::JSONWriter::Write(&args, &json_args);
338
339 DispatchEvent(contents->profile(), events::kOnTabRemoved, json_args);
340
341 int removed_count = tab_entries_.erase(tab_id);
342 DCHECK_GT(removed_count, 0);
343
344 UnregisterForTabNotifications(contents->web_contents());
345 }
346
347 void ExtensionBrowserEventRouter::ActiveTabChanged(
348 TabContents* old_contents,
349 TabContents* new_contents,
350 int index,
351 bool user_gesture) {
352 ListValue args;
353 int tab_id = ExtensionTabUtil::GetTabId(new_contents->web_contents());
354 args.Append(Value::CreateIntegerValue(tab_id));
355
356 DictionaryValue* object_args = new DictionaryValue();
357 object_args->Set(tab_keys::kWindowIdKey, Value::CreateIntegerValue(
358 ExtensionTabUtil::GetWindowIdOfTab(new_contents->web_contents())));
359 args.Append(object_args);
360
361 // The onActivated event replaced onActiveChanged and onSelectionChanged. The
362 // deprecated events take two arguments: tabId, {windowId}.
363 std::string old_json_args;
364 base::JSONWriter::Write(&args, &old_json_args);
365
366 // The onActivated event takes one argument: {windowId, tabId}.
367 std::string new_json_args;
368 args.Remove(0, NULL);
369 object_args->Set(tab_keys::kTabIdKey, Value::CreateIntegerValue(tab_id));
370 base::JSONWriter::Write(&args, &new_json_args);
371
372 Profile* profile = new_contents->profile();
373 DispatchEvent(profile, events::kOnTabSelectionChanged, old_json_args);
374 DispatchEvent(profile, events::kOnTabActiveChanged, old_json_args);
375 DispatchEvent(profile, events::kOnTabActivated, new_json_args);
376 }
377
378 void ExtensionBrowserEventRouter::TabSelectionChanged(
379 TabStripModel* tab_strip_model,
380 const TabStripSelectionModel& old_model) {
381 TabStripSelectionModel::SelectedIndices new_selection =
382 tab_strip_model->selection_model().selected_indices();
383 ListValue* all = new ListValue();
384
385 for (size_t i = 0; i < new_selection.size(); ++i) {
386 int index = new_selection[i];
387 TabContents* contents = tab_strip_model->GetTabContentsAt(index);
388 if (!contents)
389 break;
390 int tab_id = ExtensionTabUtil::GetTabId(contents->web_contents());
391 all->Append(Value::CreateIntegerValue(tab_id));
392 }
393
394 ListValue args;
395 DictionaryValue* select_info = new DictionaryValue();
396
397 select_info->Set(tab_keys::kWindowIdKey, Value::CreateIntegerValue(
398 ExtensionTabUtil::GetWindowIdOfTabStripModel(tab_strip_model)));
399
400 select_info->Set(tab_keys::kTabIdsKey, all);
401 args.Append(select_info);
402
403 std::string json_args;
404 base::JSONWriter::Write(&args, &json_args);
405
406 // The onHighlighted event replaced onHighlightChanged.
407 Profile* profile = tab_strip_model->profile();
408 DispatchEvent(profile, events::kOnTabHighlightChanged, json_args);
409 DispatchEvent(profile, events::kOnTabHighlighted, json_args);
410 }
411
412 void ExtensionBrowserEventRouter::TabMoved(TabContents* contents,
413 int from_index,
414 int to_index) {
415 ListValue args;
416 args.Append(Value::CreateIntegerValue(
417 ExtensionTabUtil::GetTabId(contents->web_contents())));
418
419 DictionaryValue* object_args = new DictionaryValue();
420 object_args->Set(tab_keys::kWindowIdKey, Value::CreateIntegerValue(
421 ExtensionTabUtil::GetWindowIdOfTab(contents->web_contents())));
422 object_args->Set(tab_keys::kFromIndexKey, Value::CreateIntegerValue(
423 from_index));
424 object_args->Set(tab_keys::kToIndexKey, Value::CreateIntegerValue(
425 to_index));
426 args.Append(object_args);
427
428 std::string json_args;
429 base::JSONWriter::Write(&args, &json_args);
430
431 DispatchEvent(contents->profile(), events::kOnTabMoved, json_args);
432 }
433
434 void ExtensionBrowserEventRouter::TabUpdated(WebContents* contents,
435 bool did_navigate) {
436 TabEntry* entry = GetTabEntry(contents);
437 DictionaryValue* changed_properties = NULL;
438
439 DCHECK(entry);
440
441 if (did_navigate)
442 changed_properties = entry->DidNavigate(contents);
443 else
444 changed_properties = entry->UpdateLoadState(contents);
445
446 if (changed_properties)
447 DispatchTabUpdatedEvent(contents, changed_properties);
448 }
449
450 void ExtensionBrowserEventRouter::DispatchEvent(Profile* profile,
451 const char* event_name,
452 const std::string& json_args) {
453 if (!profile_->IsSameProfile(profile) || !profile->GetExtensionEventRouter())
454 return;
455
456 profile->GetExtensionEventRouter()->DispatchEventToRenderers(
457 event_name, json_args, profile, GURL(), extensions::EventFilteringInfo());
458 }
459
460 void ExtensionBrowserEventRouter::DispatchEventToExtension(
461 Profile* profile,
462 const std::string& extension_id,
463 const char* event_name,
464 const std::string& json_args) {
465 if (!profile_->IsSameProfile(profile) || !profile->GetExtensionEventRouter())
466 return;
467
468 profile->GetExtensionEventRouter()->DispatchEventToExtension(
469 extension_id, event_name, json_args, profile, GURL());
470 }
471
472 void ExtensionBrowserEventRouter::DispatchEventsAcrossIncognito(
473 Profile* profile,
474 const char* event_name,
475 const std::string& json_args,
476 const std::string& cross_incognito_args) {
477 if (!profile_->IsSameProfile(profile) || !profile->GetExtensionEventRouter())
478 return;
479
480 profile->GetExtensionEventRouter()->DispatchEventsToRenderersAcrossIncognito(
481 event_name, json_args, profile, cross_incognito_args, GURL());
482 }
483
484 void ExtensionBrowserEventRouter::DispatchEventWithTab(
485 Profile* profile,
486 const std::string& extension_id,
487 const char* event_name,
488 const WebContents* web_contents,
489 bool active) {
490 if (!profile_->IsSameProfile(profile))
491 return;
492
493 ListValue args;
494 args.Append(ExtensionTabUtil::CreateTabValueActive(
495 web_contents, active));
496 std::string json_args;
497 base::JSONWriter::Write(&args, &json_args);
498 if (!extension_id.empty()) {
499 DispatchEventToExtension(profile, extension_id, event_name, json_args);
500 } else {
501 DispatchEvent(profile, event_name, json_args);
502 }
503 }
504
505 void ExtensionBrowserEventRouter::DispatchSimpleBrowserEvent(
506 Profile* profile, const int window_id, const char* event_name) {
507 if (!profile_->IsSameProfile(profile))
508 return;
509
510 ListValue args;
511 args.Append(Value::CreateIntegerValue(window_id));
512
513 std::string json_args;
514 base::JSONWriter::Write(&args, &json_args);
515
516 DispatchEvent(profile, event_name, json_args);
517 }
518
519 void ExtensionBrowserEventRouter::DispatchTabUpdatedEvent(
520 WebContents* contents, DictionaryValue* changed_properties) {
521 DCHECK(changed_properties);
522 DCHECK(contents);
523
524 // The state of the tab (as seen from the extension point of view) has
525 // changed. Send a notification to the extension.
526 ListValue args;
527
528 // First arg: The id of the tab that changed.
529 args.Append(Value::CreateIntegerValue(ExtensionTabUtil::GetTabId(contents)));
530
531 // Second arg: An object containing the changes to the tab state.
532 args.Append(changed_properties);
533
534 // Third arg: An object containing the state of the tab.
535 args.Append(ExtensionTabUtil::CreateTabValue(contents));
536
537 std::string json_args;
538 base::JSONWriter::Write(&args, &json_args);
539
540 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
541 DispatchEvent(profile, events::kOnTabUpdated, json_args);
542 }
543
544 ExtensionBrowserEventRouter::TabEntry* ExtensionBrowserEventRouter::GetTabEntry(
545 const WebContents* contents) {
546 int tab_id = ExtensionTabUtil::GetTabId(contents);
547 std::map<int, TabEntry>::iterator i = tab_entries_.find(tab_id);
548 if (tab_entries_.end() == i)
549 return NULL;
550 return &i->second;
551 }
552
553 void ExtensionBrowserEventRouter::Observe(
554 int type,
555 const content::NotificationSource& source,
556 const content::NotificationDetails& details) {
557 if (type == content::NOTIFICATION_NAV_ENTRY_COMMITTED) {
558 NavigationController* source_controller =
559 content::Source<NavigationController>(source).ptr();
560 TabUpdated(source_controller->GetWebContents(), true);
561 } else if (type == content::NOTIFICATION_WEB_CONTENTS_DESTROYED) {
562 // Tab was destroyed after being detached (without being re-attached).
563 WebContents* contents = content::Source<WebContents>(source).ptr();
564 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
565 content::Source<NavigationController>(&contents->GetController()));
566 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
567 content::Source<WebContents>(contents));
568 } else if (type == chrome::NOTIFICATION_BROWSER_WINDOW_READY) {
569 Browser* browser = content::Source<Browser>(source).ptr();
570 OnBrowserWindowReady(browser);
571 #if defined(OS_MACOSX)
572 } else if (type == chrome::NOTIFICATION_NO_KEY_WINDOW) {
573 OnBrowserSetLastActive(NULL);
574 #endif
575 } else {
576 NOTREACHED();
577 }
578 }
579
580 void ExtensionBrowserEventRouter::TabChangedAt(TabContents* contents,
581 int index,
582 TabChangeType change_type) {
583 TabUpdated(contents->web_contents(), false);
584 }
585
586 void ExtensionBrowserEventRouter::TabReplacedAt(
587 TabStripModel* tab_strip_model,
588 TabContents* old_contents,
589 TabContents* new_contents,
590 int index) {
591 TabClosingAt(tab_strip_model, old_contents, index);
592 TabInsertedAt(new_contents, index, tab_strip_model->active_index() == index);
593 }
594
595 void ExtensionBrowserEventRouter::TabPinnedStateChanged(
596 TabContents* contents,
597 int index) {
598 TabStripModel* tab_strip = NULL;
599 int tab_index;
600
601 if (ExtensionTabUtil::GetTabStripModel(
602 contents->web_contents(), &tab_strip, &tab_index)) {
603 DictionaryValue* changed_properties = new DictionaryValue();
604 changed_properties->SetBoolean(tab_keys::kPinnedKey,
605 tab_strip->IsTabPinned(tab_index));
606 DispatchTabUpdatedEvent(contents->web_contents(), changed_properties);
607 }
608 }
609
610 void ExtensionBrowserEventRouter::TabStripEmpty() {}
611
612 void ExtensionBrowserEventRouter::DispatchOldPageActionEvent(
613 Profile* profile,
614 const std::string& extension_id,
615 const std::string& page_action_id,
616 int tab_id,
617 const std::string& url,
618 int button) {
619 ListValue args;
620 args.Append(Value::CreateStringValue(page_action_id));
621
622 DictionaryValue* data = new DictionaryValue();
623 data->Set(tab_keys::kTabIdKey, Value::CreateIntegerValue(tab_id));
624 data->Set(tab_keys::kTabUrlKey, Value::CreateStringValue(url));
625 data->Set(page_action_keys::kButtonKey, Value::CreateIntegerValue(button));
626 args.Append(data);
627
628 std::string json_args;
629 base::JSONWriter::Write(&args, &json_args);
630
631 DispatchEventToExtension(profile, extension_id, "pageActions", json_args);
632 }
633
634 void ExtensionBrowserEventRouter::BrowserActionExecuted(
635 const ExtensionAction& browser_action,
636 Browser* browser) {
637 Profile* profile = browser->profile();
638 TabContents* tab_contents = NULL;
639 int tab_id = 0;
640 if (!ExtensionTabUtil::GetDefaultTab(browser, &tab_contents, &tab_id))
641 return;
642 ExtensionActionExecuted(profile, browser_action, tab_contents);
643 }
644
645 void ExtensionBrowserEventRouter::PageActionExecuted(
646 Profile* profile,
647 const ExtensionAction& page_action,
648 int tab_id,
649 const std::string& url,
650 int button) {
651 DispatchOldPageActionEvent(profile, page_action.extension_id(),
652 page_action.id(), tab_id, url, button);
653 TabContents* tab_contents = NULL;
654 if (!ExtensionTabUtil::GetTabById(tab_id, profile, profile->IsOffTheRecord(),
655 NULL, NULL, &tab_contents, NULL)) {
656 return;
657 }
658 ExtensionActionExecuted(profile, page_action, tab_contents);
659 }
660
661 void ExtensionBrowserEventRouter::ScriptBadgeExecuted(
662 Profile* profile,
663 const ExtensionAction& script_badge,
664 int tab_id) {
665 TabContents* tab_contents = NULL;
666 if (!ExtensionTabUtil::GetTabById(tab_id, profile, profile->IsOffTheRecord(),
667 NULL, NULL, &tab_contents, NULL)) {
668 return;
669 }
670 ExtensionActionExecuted(profile, script_badge, tab_contents);
671 }
672
673 void ExtensionBrowserEventRouter::CommandExecuted(
674 Profile* profile,
675 const std::string& extension_id,
676 const std::string& command) {
677 ListValue args;
678 args.Append(Value::CreateStringValue(command));
679 std::string json_args;
680 base::JSONWriter::Write(&args, &json_args);
681
682 DispatchEventToExtension(profile,
683 extension_id,
684 "experimental.keybinding.onCommand",
685 json_args);
686 }
687
688 void ExtensionBrowserEventRouter::ExtensionActionExecuted(
689 Profile* profile,
690 const ExtensionAction& extension_action,
691 TabContents* tab_contents) {
692 const char* event_name = NULL;
693 switch (extension_action.action_type()) {
694 case ExtensionAction::TYPE_BROWSER:
695 event_name = "browserAction.onClicked";
696 break;
697 case ExtensionAction::TYPE_PAGE:
698 event_name = "pageAction.onClicked";
699 break;
700 case ExtensionAction::TYPE_SCRIPT_BADGE:
701 event_name = "scriptBadge.onClicked";
702 break;
703 }
704
705 if (event_name) {
706 DispatchEventWithTab(profile,
707 extension_action.extension_id(),
708 event_name,
709 tab_contents->web_contents(),
710 true);
711 }
712 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_browser_event_router.h ('k') | chrome/browser/extensions/extension_devtools_bridge.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698