OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 <string> | |
not at google - send to devlin
2015/03/10 22:30:08
not needed, header file already includes <string>
Jared Sohn
2015/03/16 02:34:28
I added that to remove a lint error: (build/includ
| |
5 #include "chrome/browser/extensions/api/tabs/tabs_event_router.h" | 6 #include "chrome/browser/extensions/api/tabs/tabs_event_router.h" |
6 | 7 |
7 #include "base/json/json_writer.h" | 8 #include "base/json/json_writer.h" |
9 #include "base/supports_user_data.h" | |
8 #include "base/values.h" | 10 #include "base/values.h" |
9 #include "chrome/browser/chrome_notification_types.h" | 11 #include "chrome/browser/chrome_notification_types.h" |
10 #include "chrome/browser/extensions/api/tabs/tabs_constants.h" | 12 #include "chrome/browser/extensions/api/tabs/tabs_constants.h" |
11 #include "chrome/browser/extensions/api/tabs/tabs_windows_api.h" | 13 #include "chrome/browser/extensions/api/tabs/tabs_windows_api.h" |
12 #include "chrome/browser/extensions/api/tabs/windows_event_router.h" | 14 #include "chrome/browser/extensions/api/tabs/windows_event_router.h" |
13 #include "chrome/browser/extensions/extension_tab_util.h" | 15 #include "chrome/browser/extensions/extension_tab_util.h" |
14 #include "chrome/browser/profiles/profile.h" | 16 #include "chrome/browser/profiles/profile.h" |
15 #include "chrome/browser/ui/browser.h" | 17 #include "chrome/browser/ui/browser.h" |
16 #include "chrome/browser/ui/browser_iterator.h" | 18 #include "chrome/browser/ui/browser_iterator.h" |
17 #include "chrome/browser/ui/browser_list.h" | 19 #include "chrome/browser/ui/browser_list.h" |
18 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 20 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
21 #include "chrome/browser/ui/tabs/tab_utils.h" | |
19 #include "chrome/common/extensions/extension_constants.h" | 22 #include "chrome/common/extensions/extension_constants.h" |
20 #include "content/public/browser/favicon_status.h" | 23 #include "content/public/browser/favicon_status.h" |
21 #include "content/public/browser/navigation_controller.h" | 24 #include "content/public/browser/navigation_controller.h" |
22 #include "content/public/browser/navigation_entry.h" | 25 #include "content/public/browser/navigation_entry.h" |
23 #include "content/public/browser/notification_service.h" | 26 #include "content/public/browser/notification_service.h" |
24 #include "content/public/browser/notification_types.h" | 27 #include "content/public/browser/notification_types.h" |
25 #include "content/public/browser/web_contents.h" | 28 #include "content/public/browser/web_contents.h" |
29 #include "content/public/browser/web_contents_observer.h" | |
26 | 30 |
27 using base::DictionaryValue; | 31 using base::DictionaryValue; |
28 using base::ListValue; | 32 using base::ListValue; |
29 using base::FundamentalValue; | 33 using base::FundamentalValue; |
30 using content::NavigationController; | 34 using content::NavigationController; |
31 using content::WebContents; | 35 using content::WebContents; |
32 using ui_zoom::ZoomController; | 36 using ui_zoom::ZoomController; |
33 | 37 |
34 namespace extensions { | 38 namespace extensions { |
35 | 39 |
(...skipping 15 matching lines...) Expand all Loading... | |
51 properties_value); | 55 properties_value); |
52 event_args->Set(1, properties_value); | 56 event_args->Set(1, properties_value); |
53 | 57 |
54 // Overwrite the third arg with our tab value as seen by this extension. | 58 // Overwrite the third arg with our tab value as seen by this extension. |
55 event_args->Set(2, ExtensionTabUtil::CreateTabValue(contents, extension)); | 59 event_args->Set(2, ExtensionTabUtil::CreateTabValue(contents, extension)); |
56 return true; | 60 return true; |
57 } | 61 } |
58 | 62 |
59 } // namespace | 63 } // namespace |
60 | 64 |
65 void TabsEventRouter::TabAudibleStateChanged(content::WebContents* contents, | |
66 bool audible) { | |
67 scoped_ptr<base::DictionaryValue> changed_properties( | |
68 new base::DictionaryValue()); | |
not at google - send to devlin
2015/03/10 22:30:08
I just submitted https://codereview.chromium.org/1
| |
69 | |
70 changed_properties->SetBoolean(tabs_constants::kAudibleKey, | |
71 audible); | |
72 DispatchTabUpdatedEvent(contents, changed_properties.Pass()); | |
miu
2015/03/10 18:51:39
Instead of dispatching separate events here and in
Jared Sohn
2015/03/16 02:34:29
Done.
| |
73 } | |
74 | |
75 void TabsEventRouter::TabMutedStateChanged(content::WebContents* contents, | |
76 bool muted, | |
77 const std::string& cause) { | |
78 scoped_ptr<base::DictionaryValue> changed_properties( | |
79 new base::DictionaryValue()); | |
80 | |
81 changed_properties->SetBoolean(tabs_constants::kMutedKey, | |
82 muted); | |
83 changed_properties->SetString(tabs_constants::kCauseKey, | |
84 cause); | |
miu
2015/03/10 18:51:39
nit: indent one less space, and run `git cl format
Jared Sohn
2015/03/16 02:34:29
Done.
| |
85 | |
86 DispatchTabUpdatedEvent(contents, changed_properties.Pass()); | |
87 } | |
88 | |
61 TabsEventRouter::TabEntry::TabEntry() : complete_waiting_on_load_(false), | 89 TabsEventRouter::TabEntry::TabEntry() : complete_waiting_on_load_(false), |
90 wasAudible_(false), | |
miu
2015/03/10 18:51:39
A TabEntry might be constructed after a tab is ali
| |
91 wasMuted_(false), | |
62 url_() { | 92 url_() { |
63 } | 93 } |
64 | 94 |
65 base::DictionaryValue* TabsEventRouter::TabEntry::UpdateLoadState( | 95 base::DictionaryValue* TabsEventRouter::TabEntry::UpdateLoadState( |
66 const WebContents* contents) { | 96 const WebContents* contents) { |
67 // The tab may go in & out of loading (for instance if iframes navigate). | 97 // The tab may go in & out of loading (for instance if iframes navigate). |
68 // We only want to respond to the first change from loading to !loading after | 98 // We only want to respond to the first change from loading to !loading after |
69 // the NAV_ENTRY_COMMITTED was fired. | 99 // the NAV_ENTRY_COMMITTED was fired. |
70 if (!complete_waiting_on_load_ || contents->IsLoading()) | 100 if (!complete_waiting_on_load_ || contents->IsLoading()) |
71 return NULL; | 101 return NULL; |
(...skipping 15 matching lines...) Expand all Loading... | |
87 tabs_constants::kStatusValueLoading); | 117 tabs_constants::kStatusValueLoading); |
88 | 118 |
89 if (contents->GetURL() != url_) { | 119 if (contents->GetURL() != url_) { |
90 url_ = contents->GetURL(); | 120 url_ = contents->GetURL(); |
91 changed_properties->SetString(tabs_constants::kUrlKey, url_.spec()); | 121 changed_properties->SetString(tabs_constants::kUrlKey, url_.spec()); |
92 } | 122 } |
93 | 123 |
94 return changed_properties; | 124 return changed_properties; |
95 } | 125 } |
96 | 126 |
127 bool TabsEventRouter::TabEntry::AudibleChanged(bool val) const { | |
miu
2015/03/10 18:51:39
nit: Your call, but consider combining each pair o
not at google - send to devlin
2015/03/10 22:30:08
+1 and also no parens around these expressions.
Jared Sohn
2015/03/16 02:34:29
Done.
Jared Sohn
2015/03/16 02:34:29
Done.
| |
128 return (wasAudible_ != val); | |
129 } | |
130 | |
131 bool TabsEventRouter::TabEntry::MutedChanged(bool val) const { | |
132 return (wasMuted_ != val); | |
133 } | |
134 | |
135 void TabsEventRouter::TabEntry::ToggleAudible() { | |
136 wasAudible_ = !wasAudible_; | |
137 } | |
138 | |
139 void TabsEventRouter::TabEntry::ToggleMuted() { | |
140 wasMuted_ = !wasMuted_; | |
141 } | |
142 | |
143 | |
144 | |
not at google - send to devlin
2015/03/10 22:30:08
only 1 blank line
Jared Sohn
2015/03/16 02:34:29
Done.
| |
97 TabsEventRouter::TabsEventRouter(Profile* profile) : profile_(profile) { | 145 TabsEventRouter::TabsEventRouter(Profile* profile) : profile_(profile) { |
98 DCHECK(!profile->IsOffTheRecord()); | 146 DCHECK(!profile->IsOffTheRecord()); |
99 | 147 |
100 BrowserList::AddObserver(this); | 148 BrowserList::AddObserver(this); |
101 | 149 |
102 // Init() can happen after the browser is running, so catch up with any | 150 // Init() can happen after the browser is running, so catch up with any |
103 // windows that already exist. | 151 // windows that already exist. |
104 for (chrome::BrowserIterator it; !it.done(); it.Next()) { | 152 for (chrome::BrowserIterator it; !it.done(); it.Next()) { |
105 RegisterForBrowserNotifications(*it); | 153 RegisterForBrowserNotifications(*it); |
106 | 154 |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
389 args.Pass(), | 437 args.Pass(), |
390 EventRouter::USER_GESTURE_UNKNOWN); | 438 EventRouter::USER_GESTURE_UNKNOWN); |
391 } | 439 } |
392 | 440 |
393 void TabsEventRouter::TabUpdated(WebContents* contents, bool did_navigate) { | 441 void TabsEventRouter::TabUpdated(WebContents* contents, bool did_navigate) { |
394 TabEntry* entry = GetTabEntry(contents); | 442 TabEntry* entry = GetTabEntry(contents); |
395 scoped_ptr<base::DictionaryValue> changed_properties; | 443 scoped_ptr<base::DictionaryValue> changed_properties; |
396 | 444 |
397 CHECK(entry); | 445 CHECK(entry); |
398 | 446 |
447 bool audible = contents->WasRecentlyAudible(); | |
448 if (entry->AudibleChanged(audible)) { | |
449 entry->ToggleAudible(); | |
450 | |
451 TabAudibleStateChanged(contents, audible); | |
452 } | |
453 | |
454 bool muted = contents->IsAudioMuted(); | |
455 if (entry->MutedChanged(muted)) { | |
456 entry->ToggleMuted(); | |
457 | |
458 TabMutedStateChanged(contents, muted, | |
459 chrome::GetTabAudioMutedCause(contents)); | |
460 } | |
not at google - send to devlin
2015/03/10 22:30:08
This code should be consistent with the existing c
Jared Sohn
2015/03/16 02:34:29
At the moment, I am choosing to pass an extensions
not at google - send to devlin
2015/03/16 17:47:08
Passing a DictionaryBuilder is fine. I hadn't thou
| |
461 | |
399 if (did_navigate) | 462 if (did_navigate) |
400 changed_properties.reset(entry->DidNavigate(contents)); | 463 changed_properties.reset(entry->DidNavigate(contents)); |
401 else | 464 else |
402 changed_properties.reset(entry->UpdateLoadState(contents)); | 465 changed_properties.reset(entry->UpdateLoadState(contents)); |
403 | 466 |
404 if (changed_properties) | 467 if (changed_properties) |
405 DispatchTabUpdatedEvent(contents, changed_properties.Pass()); | 468 DispatchTabUpdatedEvent(contents, changed_properties.Pass()); |
406 } | 469 } |
407 | 470 |
408 void TabsEventRouter::FaviconUrlUpdated(WebContents* contents) { | 471 void TabsEventRouter::FaviconUrlUpdated(WebContents* contents) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
443 | 506 |
444 DispatchEvent(profile, | 507 DispatchEvent(profile, |
445 event_name, | 508 event_name, |
446 args.Pass(), | 509 args.Pass(), |
447 EventRouter::USER_GESTURE_UNKNOWN); | 510 EventRouter::USER_GESTURE_UNKNOWN); |
448 } | 511 } |
449 | 512 |
450 void TabsEventRouter::DispatchTabUpdatedEvent( | 513 void TabsEventRouter::DispatchTabUpdatedEvent( |
451 WebContents* contents, | 514 WebContents* contents, |
452 scoped_ptr<base::DictionaryValue> changed_properties) { | 515 scoped_ptr<base::DictionaryValue> changed_properties) { |
516 | |
miu
2015/03/10 18:51:39
nit: remove added newlines throughout this method
Jared Sohn
2015/03/16 02:34:28
Done.
| |
453 DCHECK(changed_properties); | 517 DCHECK(changed_properties); |
454 DCHECK(contents); | 518 DCHECK(contents); |
455 | 519 |
456 // The state of the tab (as seen from the extension point of view) has | 520 // The state of the tab (as seen from the extension point of view) has |
457 // changed. Send a notification to the extension. | 521 // changed. Send a notification to the extension. |
458 scoped_ptr<base::ListValue> args_base(new base::ListValue); | 522 scoped_ptr<base::ListValue> args_base(new base::ListValue); |
459 | 523 |
460 // First arg: The id of the tab that changed. | 524 // First arg: The id of the tab that changed. |
461 args_base->AppendInteger(ExtensionTabUtil::GetTabId(contents)); | 525 args_base->AppendInteger(ExtensionTabUtil::GetTabId(contents)); |
462 | 526 |
463 // Second arg: An object containing the changes to the tab state. Filled in | 527 // Second arg: An object containing the changes to the tab state. Filled in |
464 // by WillDispatchTabUpdatedEvent as a copy of changed_properties, if the | 528 // by WillDispatchTabUpdatedEvent as a copy of changed_properties, if the |
465 // extension has the tabs permission. | 529 // extension has the tabs permission. |
466 | 530 |
467 // Third arg: An object containing the state of the tab. Filled in by | 531 // Third arg: An object containing the state of the tab. Filled in by |
468 // WillDispatchTabUpdatedEvent. | 532 // WillDispatchTabUpdatedEvent. |
469 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); | 533 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); |
470 | 534 |
535 | |
471 scoped_ptr<Event> event( | 536 scoped_ptr<Event> event( |
472 new Event(tabs::OnUpdated::kEventName, args_base.Pass())); | 537 new Event(tabs::OnUpdated::kEventName, args_base.Pass())); |
473 event->restrict_to_browser_context = profile; | 538 event->restrict_to_browser_context = profile; |
539 | |
474 event->user_gesture = EventRouter::USER_GESTURE_NOT_ENABLED; | 540 event->user_gesture = EventRouter::USER_GESTURE_NOT_ENABLED; |
475 event->will_dispatch_callback = | 541 event->will_dispatch_callback = |
476 base::Bind(&WillDispatchTabUpdatedEvent, | 542 base::Bind(&WillDispatchTabUpdatedEvent, |
477 contents, | 543 contents, |
478 changed_properties.get()); | 544 changed_properties.get()); |
545 | |
479 EventRouter::Get(profile)->BroadcastEvent(event.Pass()); | 546 EventRouter::Get(profile)->BroadcastEvent(event.Pass()); |
480 } | 547 } |
481 | 548 |
482 TabsEventRouter::TabEntry* TabsEventRouter::GetTabEntry(WebContents* contents) { | 549 TabsEventRouter::TabEntry* TabsEventRouter::GetTabEntry(WebContents* contents) { |
483 int tab_id = ExtensionTabUtil::GetTabId(contents); | 550 int tab_id = ExtensionTabUtil::GetTabId(contents); |
484 std::map<int, TabEntry>::iterator i = tab_entries_.find(tab_id); | 551 std::map<int, TabEntry>::iterator i = tab_entries_.find(tab_id); |
485 if (tab_entries_.end() == i) | 552 if (tab_entries_.end() == i) |
486 return NULL; | 553 return NULL; |
487 return &i->second; | 554 return &i->second; |
488 } | 555 } |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
579 // Dispatch the |onZoomChange| event. | 646 // Dispatch the |onZoomChange| event. |
580 Profile* profile = Profile::FromBrowserContext( | 647 Profile* profile = Profile::FromBrowserContext( |
581 data.web_contents->GetBrowserContext()); | 648 data.web_contents->GetBrowserContext()); |
582 DispatchEvent(profile, | 649 DispatchEvent(profile, |
583 tabs::OnZoomChange::kEventName, | 650 tabs::OnZoomChange::kEventName, |
584 api::tabs::OnZoomChange::Create(zoom_change_info), | 651 api::tabs::OnZoomChange::Create(zoom_change_info), |
585 EventRouter::USER_GESTURE_UNKNOWN); | 652 EventRouter::USER_GESTURE_UNKNOWN); |
586 } | 653 } |
587 | 654 |
588 } // namespace extensions | 655 } // namespace extensions |
OLD | NEW |