Chromium Code Reviews| 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 |