 Chromium Code Reviews
 Chromium Code Reviews Issue 987583004:
  Add audible, muted to Tab, c.t.query, c.t.update, and c.t.onUpdated where relevant  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@patch1
    
  
    Issue 987583004:
  Add audible, muted to Tab, c.t.query, c.t.update, and c.t.onUpdated where relevant  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@patch1| 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 "chrome/browser/extensions/api/tabs/tabs_event_router.h" | 5 #include "chrome/browser/extensions/api/tabs/tabs_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/chrome_notification_types.h" | 9 #include "chrome/browser/chrome_notification_types.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/api/tabs/tabs_windows_api.h" | 11 #include "chrome/browser/extensions/api/tabs/tabs_windows_api.h" | 
| 12 #include "chrome/browser/extensions/api/tabs/windows_event_router.h" | 12 #include "chrome/browser/extensions/api/tabs/windows_event_router.h" | 
| 13 #include "chrome/browser/extensions/extension_tab_util.h" | 13 #include "chrome/browser/extensions/extension_tab_util.h" | 
| 14 #include "chrome/browser/profiles/profile.h" | 14 #include "chrome/browser/profiles/profile.h" | 
| 15 #include "chrome/browser/ui/browser.h" | 15 #include "chrome/browser/ui/browser.h" | 
| 16 #include "chrome/browser/ui/browser_iterator.h" | 16 #include "chrome/browser/ui/browser_iterator.h" | 
| 17 #include "chrome/browser/ui/browser_list.h" | 17 #include "chrome/browser/ui/browser_list.h" | 
| 18 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 18 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 
| 19 #include "chrome/browser/ui/tabs/tab_utils.h" | |
| 19 #include "chrome/common/extensions/extension_constants.h" | 20 #include "chrome/common/extensions/extension_constants.h" | 
| 20 #include "content/public/browser/favicon_status.h" | 21 #include "content/public/browser/favicon_status.h" | 
| 21 #include "content/public/browser/navigation_controller.h" | 22 #include "content/public/browser/navigation_controller.h" | 
| 22 #include "content/public/browser/navigation_entry.h" | 23 #include "content/public/browser/navigation_entry.h" | 
| 23 #include "content/public/browser/notification_service.h" | 24 #include "content/public/browser/notification_service.h" | 
| 24 #include "content/public/browser/notification_types.h" | 25 #include "content/public/browser/notification_types.h" | 
| 25 #include "content/public/browser/web_contents.h" | 26 #include "content/public/browser/web_contents.h" | 
| 26 | 27 | 
| 27 using base::DictionaryValue; | 28 using base::DictionaryValue; | 
| 28 using base::ListValue; | 29 using base::ListValue; | 
| (...skipping 22 matching lines...) Expand all Loading... | |
| 51 properties_value); | 52 properties_value); | 
| 52 event_args->Set(1, properties_value); | 53 event_args->Set(1, properties_value); | 
| 53 | 54 | 
| 54 // Overwrite the third arg with our tab value as seen by this extension. | 55 // Overwrite the third arg with our tab value as seen by this extension. | 
| 55 event_args->Set(2, ExtensionTabUtil::CreateTabValue(contents, extension)); | 56 event_args->Set(2, ExtensionTabUtil::CreateTabValue(contents, extension)); | 
| 56 return true; | 57 return true; | 
| 57 } | 58 } | 
| 58 | 59 | 
| 59 } // namespace | 60 } // namespace | 
| 60 | 61 | 
| 61 TabsEventRouter::TabEntry::TabEntry() : complete_waiting_on_load_(false), | 62 TabsEventRouter::TabEntry::TabEntry() | 
| 62 url_() { | 63 : contents_(NULL), | 
| 64 complete_waiting_on_load_(false), | |
| 65 was_audible_(false), | |
| 66 was_muted_(false), | |
| 67 url_() { | |
| 
not at google - send to devlin
2015/03/16 18:11:54
It's not necessary to initialize url()
 | |
| 63 } | 68 } | 
| 64 | 69 | 
| 65 base::DictionaryValue* TabsEventRouter::TabEntry::UpdateLoadState( | 70 TabsEventRouter::TabEntry::TabEntry(content::WebContents* contents) | 
| 66 const WebContents* contents) { | 71 : contents_(contents), | 
| 72 complete_waiting_on_load_(false), | |
| 73 was_audible_(contents->WasRecentlyAudible()), | |
| 74 was_muted_(contents->IsAudioMuted()), | |
| 75 url_() { | |
| 76 } | |
| 77 | |
| 78 DictionaryBuilder* TabsEventRouter::TabEntry::UpdateLoadState() { | |
| 67 // The tab may go in & out of loading (for instance if iframes navigate). | 79 // 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 | 80 // We only want to respond to the first change from loading to !loading after | 
| 69 // the NAV_ENTRY_COMMITTED was fired. | 81 // the NAV_ENTRY_COMMITTED was fired. | 
| 70 if (!complete_waiting_on_load_ || contents->IsLoading()) | 82 if (!complete_waiting_on_load_ || contents_->IsLoading()) { | 
| 71 return NULL; | 83 return new DictionaryBuilder(); | 
| 84 } | |
| 72 | 85 | 
| 73 // Send "complete" state change. | 86 // Send "complete" state change. | 
| 74 complete_waiting_on_load_ = false; | 87 complete_waiting_on_load_ = false; | 
| 75 base::DictionaryValue* changed_properties = new base::DictionaryValue(); | 88 DictionaryBuilder* changed_properties = new DictionaryBuilder(); | 
| 76 changed_properties->SetString(tabs_constants::kStatusKey, | 89 changed_properties->Set(tabs_constants::kStatusKey, | 
| 77 tabs_constants::kStatusValueComplete); | 90 tabs_constants::kStatusValueComplete); | 
| 78 return changed_properties; | 91 return changed_properties; | 
| 
not at google - send to devlin
2015/03/16 18:11:55
Builder lets you do:
return DictionaryValue()
 | |
| 79 } | 92 } | 
| 80 | 93 | 
| 81 base::DictionaryValue* TabsEventRouter::TabEntry::DidNavigate( | 94 DictionaryBuilder* TabsEventRouter::TabEntry::DidNavigate() { | 
| 82 const WebContents* contents) { | |
| 83 // Send "loading" state change. | 95 // Send "loading" state change. | 
| 84 complete_waiting_on_load_ = true; | 96 complete_waiting_on_load_ = true; | 
| 85 base::DictionaryValue* changed_properties = new base::DictionaryValue(); | 97 DictionaryBuilder* changed_properties = new DictionaryBuilder(); | 
| 86 changed_properties->SetString(tabs_constants::kStatusKey, | 98 changed_properties->Set(tabs_constants::kStatusKey, | 
| 87 tabs_constants::kStatusValueLoading); | 99 tabs_constants::kStatusValueLoading); | 
| 88 | 100 | 
| 89 if (contents->GetURL() != url_) { | 101 if (contents_->GetURL() != url_) { | 
| 90 url_ = contents->GetURL(); | 102 url_ = contents_->GetURL(); | 
| 91 changed_properties->SetString(tabs_constants::kUrlKey, url_.spec()); | 103 changed_properties->Set(tabs_constants::kUrlKey, url_.spec()); | 
| 92 } | 104 } | 
| 93 | 105 | 
| 94 return changed_properties; | 106 return changed_properties; | 
| 95 } | 107 } | 
| 96 | 108 | 
| 109 bool TabsEventRouter::TabEntry::SetAudible(bool new_val) { | |
| 110 if (was_audible_ == new_val) | |
| 111 return false; | |
| 112 was_audible_ = new_val; | |
| 113 return true; | |
| 114 } | |
| 115 | |
| 116 bool TabsEventRouter::TabEntry::SetMuted(bool new_val) { | |
| 117 if (was_muted_ == new_val) | |
| 118 return false; | |
| 119 was_muted_ = new_val; | |
| 120 return true; | |
| 121 } | |
| 122 | |
| 97 TabsEventRouter::TabsEventRouter(Profile* profile) : profile_(profile) { | 123 TabsEventRouter::TabsEventRouter(Profile* profile) : profile_(profile) { | 
| 98 DCHECK(!profile->IsOffTheRecord()); | 124 DCHECK(!profile->IsOffTheRecord()); | 
| 99 | 125 | 
| 100 BrowserList::AddObserver(this); | 126 BrowserList::AddObserver(this); | 
| 101 | 127 | 
| 102 // Init() can happen after the browser is running, so catch up with any | 128 // Init() can happen after the browser is running, so catch up with any | 
| 103 // windows that already exist. | 129 // windows that already exist. | 
| 104 for (chrome::BrowserIterator it; !it.done(); it.Next()) { | 130 for (chrome::BrowserIterator it; !it.done(); it.Next()) { | 
| 105 RegisterForBrowserNotifications(*it); | 131 RegisterForBrowserNotifications(*it); | 
| 106 | 132 | 
| 107 // Also catch up our internal bookkeeping of tab entries. | 133 // Also catch up our internal bookkeeping of tab entries. | 
| 108 Browser* browser = *it; | 134 Browser* browser = *it; | 
| 109 if (browser->tab_strip_model()) { | 135 if (browser->tab_strip_model()) { | 
| 110 for (int i = 0; i < browser->tab_strip_model()->count(); ++i) { | 136 for (int i = 0; i < browser->tab_strip_model()->count(); ++i) { | 
| 111 WebContents* contents = browser->tab_strip_model()->GetWebContentsAt(i); | 137 WebContents* contents = browser->tab_strip_model()->GetWebContentsAt(i); | 
| 112 int tab_id = ExtensionTabUtil::GetTabId(contents); | 138 int tab_id = ExtensionTabUtil::GetTabId(contents); | 
| 113 tab_entries_[tab_id] = TabEntry(); | 139 tab_entries_[tab_id] = TabEntry(contents); | 
| 114 } | 140 } | 
| 115 } | 141 } | 
| 116 } | 142 } | 
| 117 } | 143 } | 
| 118 | 144 | 
| 119 TabsEventRouter::~TabsEventRouter() { | 145 TabsEventRouter::~TabsEventRouter() { | 
| 120 BrowserList::RemoveObserver(this); | 146 BrowserList::RemoveObserver(this); | 
| 121 } | 147 } | 
| 122 | 148 | 
| 123 void TabsEventRouter::OnBrowserAdded(Browser* browser) { | 149 void TabsEventRouter::OnBrowserAdded(Browser* browser) { | 
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 208 | 234 | 
| 209 RegisterForTabNotifications(contents); | 235 RegisterForTabNotifications(contents); | 
| 210 } | 236 } | 
| 211 | 237 | 
| 212 void TabsEventRouter::TabInsertedAt(WebContents* contents, | 238 void TabsEventRouter::TabInsertedAt(WebContents* contents, | 
| 213 int index, | 239 int index, | 
| 214 bool active) { | 240 bool active) { | 
| 215 // If tab is new, send created event. | 241 // If tab is new, send created event. | 
| 216 int tab_id = ExtensionTabUtil::GetTabId(contents); | 242 int tab_id = ExtensionTabUtil::GetTabId(contents); | 
| 217 if (!GetTabEntry(contents)) { | 243 if (!GetTabEntry(contents)) { | 
| 218 tab_entries_[tab_id] = TabEntry(); | 244 tab_entries_[tab_id] = TabEntry(contents); | 
| 219 | 245 | 
| 220 TabCreatedAt(contents, index, active); | 246 TabCreatedAt(contents, index, active); | 
| 221 return; | 247 return; | 
| 222 } | 248 } | 
| 223 | 249 | 
| 224 scoped_ptr<base::ListValue> args(new base::ListValue); | 250 scoped_ptr<base::ListValue> args(new base::ListValue); | 
| 225 args->Append(new FundamentalValue(tab_id)); | 251 args->Append(new FundamentalValue(tab_id)); | 
| 226 | 252 | 
| 227 base::DictionaryValue* object_args = new base::DictionaryValue(); | 253 base::DictionaryValue* object_args = new base::DictionaryValue(); | 
| 228 object_args->Set(tabs_constants::kNewWindowIdKey, | 254 object_args->Set(tabs_constants::kNewWindowIdKey, | 
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 383 new FundamentalValue(to_index)); | 409 new FundamentalValue(to_index)); | 
| 384 args->Append(object_args); | 410 args->Append(object_args); | 
| 385 | 411 | 
| 386 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); | 412 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); | 
| 387 DispatchEvent(profile, | 413 DispatchEvent(profile, | 
| 388 tabs::OnMoved::kEventName, | 414 tabs::OnMoved::kEventName, | 
| 389 args.Pass(), | 415 args.Pass(), | 
| 390 EventRouter::USER_GESTURE_UNKNOWN); | 416 EventRouter::USER_GESTURE_UNKNOWN); | 
| 391 } | 417 } | 
| 392 | 418 | 
| 393 void TabsEventRouter::TabUpdated(WebContents* contents, bool did_navigate) { | 419 void TabsEventRouter::TabUpdated(TabsEventRouter::TabEntry* entry, | 
| 394 TabEntry* entry = GetTabEntry(contents); | 420 DictionaryBuilder* changed_properties) { | 
| 
not at google - send to devlin
2015/03/16 18:11:55
Yeah, I think that passing a DictionaryValue in he
 | |
| 395 scoped_ptr<base::DictionaryValue> changed_properties; | 421 CHECK(entry->contents_); | 
| 396 | 422 | 
| 397 CHECK(entry); | 423 bool audible = entry->contents_->WasRecentlyAudible(); | 
| 424 if (entry->SetAudible(audible)) { | |
| 425 changed_properties->SetBoolean(tabs_constants::kAudibleKey, audible); | |
| 426 } | |
| 398 | 427 | 
| 399 if (did_navigate) | 428 bool muted = entry->contents_->IsAudioMuted(); | 
| 400 changed_properties.reset(entry->DidNavigate(contents)); | 429 if (entry->SetMuted(muted)) { | 
| 401 else | 430 changed_properties->SetBoolean(tabs_constants::kMutedKey, muted); | 
| 402 changed_properties.reset(entry->UpdateLoadState(contents)); | 431 changed_properties->Set(tabs_constants::kMutedCauseKey, | 
| 432 chrome::GetTabAudioMutedCause(entry->contents_)); | |
| 433 } | |
| 403 | 434 | 
| 404 if (changed_properties) | 435 if (changed_properties->size() > 0) { | 
| 
not at google - send to devlin
2015/03/16 18:11:55
use .empty() preferably.
 | |
| 405 DispatchTabUpdatedEvent(contents, changed_properties.Pass()); | 436 DispatchTabUpdatedEvent(entry->contents_, changed_properties->Build()); | 
| 437 } | |
| 406 } | 438 } | 
| 407 | 439 | 
| 408 void TabsEventRouter::FaviconUrlUpdated(WebContents* contents) { | 440 void TabsEventRouter::FaviconUrlUpdated(WebContents* contents) { | 
| 409 content::NavigationEntry* entry = | 441 content::NavigationEntry* entry = | 
| 410 contents->GetController().GetVisibleEntry(); | 442 contents->GetController().GetVisibleEntry(); | 
| 411 if (!entry || !entry->GetFavicon().valid) | 443 if (!entry || !entry->GetFavicon().valid) | 
| 412 return; | 444 return; | 
| 413 scoped_ptr<base::DictionaryValue> changed_properties( | 445 scoped_ptr<base::DictionaryValue> changed_properties( | 
| 414 new base::DictionaryValue); | 446 new base::DictionaryValue); | 
| 415 changed_properties->SetString( | 447 changed_properties->SetString( | 
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 486 return NULL; | 518 return NULL; | 
| 487 return &i->second; | 519 return &i->second; | 
| 488 } | 520 } | 
| 489 | 521 | 
| 490 void TabsEventRouter::Observe(int type, | 522 void TabsEventRouter::Observe(int type, | 
| 491 const content::NotificationSource& source, | 523 const content::NotificationSource& source, | 
| 492 const content::NotificationDetails& details) { | 524 const content::NotificationDetails& details) { | 
| 493 if (type == content::NOTIFICATION_NAV_ENTRY_COMMITTED) { | 525 if (type == content::NOTIFICATION_NAV_ENTRY_COMMITTED) { | 
| 494 NavigationController* source_controller = | 526 NavigationController* source_controller = | 
| 495 content::Source<NavigationController>(source).ptr(); | 527 content::Source<NavigationController>(source).ptr(); | 
| 496 TabUpdated(source_controller->GetWebContents(), true); | 528 TabEntry* entry = GetTabEntry(source_controller->GetWebContents()); | 
| 529 CHECK(entry); | |
| 530 TabUpdated(entry, entry->DidNavigate()); | |
| 497 } else if (type == content::NOTIFICATION_WEB_CONTENTS_DESTROYED) { | 531 } else if (type == content::NOTIFICATION_WEB_CONTENTS_DESTROYED) { | 
| 498 // Tab was destroyed after being detached (without being re-attached). | 532 // Tab was destroyed after being detached (without being re-attached). | 
| 499 WebContents* contents = content::Source<WebContents>(source).ptr(); | 533 WebContents* contents = content::Source<WebContents>(source).ptr(); | 
| 500 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, | 534 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, | 
| 501 content::Source<NavigationController>(&contents->GetController())); | 535 content::Source<NavigationController>(&contents->GetController())); | 
| 502 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, | 536 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, | 
| 503 content::Source<WebContents>(contents)); | 537 content::Source<WebContents>(contents)); | 
| 504 registrar_.Remove(this, chrome::NOTIFICATION_FAVICON_UPDATED, | 538 registrar_.Remove(this, chrome::NOTIFICATION_FAVICON_UPDATED, | 
| 505 content::Source<WebContents>(contents)); | 539 content::Source<WebContents>(contents)); | 
| 506 } else if (type == chrome::NOTIFICATION_FAVICON_UPDATED) { | 540 } else if (type == chrome::NOTIFICATION_FAVICON_UPDATED) { | 
| 507 bool icon_url_changed = *content::Details<bool>(details).ptr(); | 541 bool icon_url_changed = *content::Details<bool>(details).ptr(); | 
| 508 if (icon_url_changed) | 542 if (icon_url_changed) | 
| 509 FaviconUrlUpdated(content::Source<WebContents>(source).ptr()); | 543 FaviconUrlUpdated(content::Source<WebContents>(source).ptr()); | 
| 510 } else { | 544 } else { | 
| 511 NOTREACHED(); | 545 NOTREACHED(); | 
| 512 } | 546 } | 
| 513 } | 547 } | 
| 514 | 548 | 
| 515 void TabsEventRouter::TabChangedAt(WebContents* contents, | 549 void TabsEventRouter::TabChangedAt(WebContents* contents, | 
| 516 int index, | 550 int index, | 
| 517 TabChangeType change_type) { | 551 TabChangeType change_type) { | 
| 518 TabUpdated(contents, false); | 552 TabEntry* entry = GetTabEntry(contents); | 
| 553 CHECK(entry); | |
| 554 TabUpdated(entry, entry->UpdateLoadState()); | |
| 519 } | 555 } | 
| 520 | 556 | 
| 521 void TabsEventRouter::TabReplacedAt(TabStripModel* tab_strip_model, | 557 void TabsEventRouter::TabReplacedAt(TabStripModel* tab_strip_model, | 
| 522 WebContents* old_contents, | 558 WebContents* old_contents, | 
| 523 WebContents* new_contents, | 559 WebContents* new_contents, | 
| 524 int index) { | 560 int index) { | 
| 525 // Notify listeners that the next tabs closing or being added are due to | 561 // Notify listeners that the next tabs closing or being added are due to | 
| 526 // WebContents being swapped. | 562 // WebContents being swapped. | 
| 527 const int new_tab_id = ExtensionTabUtil::GetTabId(new_contents); | 563 const int new_tab_id = ExtensionTabUtil::GetTabId(new_contents); | 
| 528 const int old_tab_id = ExtensionTabUtil::GetTabId(old_contents); | 564 const int old_tab_id = ExtensionTabUtil::GetTabId(old_contents); | 
| 529 scoped_ptr<base::ListValue> args(new base::ListValue); | 565 scoped_ptr<base::ListValue> args(new base::ListValue); | 
| 530 args->Append(new FundamentalValue(new_tab_id)); | 566 args->Append(new FundamentalValue(new_tab_id)); | 
| 531 args->Append(new FundamentalValue(old_tab_id)); | 567 args->Append(new FundamentalValue(old_tab_id)); | 
| 532 | 568 | 
| 533 DispatchEvent(Profile::FromBrowserContext(new_contents->GetBrowserContext()), | 569 DispatchEvent(Profile::FromBrowserContext(new_contents->GetBrowserContext()), | 
| 534 tabs::OnReplaced::kEventName, | 570 tabs::OnReplaced::kEventName, | 
| 535 args.Pass(), | 571 args.Pass(), | 
| 536 EventRouter::USER_GESTURE_UNKNOWN); | 572 EventRouter::USER_GESTURE_UNKNOWN); | 
| 537 | 573 | 
| 538 // Update tab_entries_. | 574 // Update tab_entries_. | 
| 539 const int removed_count = tab_entries_.erase(old_tab_id); | 575 const int removed_count = tab_entries_.erase(old_tab_id); | 
| 540 DCHECK_GT(removed_count, 0); | 576 DCHECK_GT(removed_count, 0); | 
| 541 UnregisterForTabNotifications(old_contents); | 577 UnregisterForTabNotifications(old_contents); | 
| 542 | 578 | 
| 543 if (!GetTabEntry(new_contents)) { | 579 if (!GetTabEntry(new_contents)) { | 
| 544 tab_entries_[new_tab_id] = TabEntry(); | 580 tab_entries_[new_tab_id] = TabEntry(new_contents); | 
| 545 RegisterForTabNotifications(new_contents); | 581 RegisterForTabNotifications(new_contents); | 
| 546 } | 582 } | 
| 547 } | 583 } | 
| 548 | 584 | 
| 549 void TabsEventRouter::TabPinnedStateChanged(WebContents* contents, int index) { | 585 void TabsEventRouter::TabPinnedStateChanged(WebContents* contents, int index) { | 
| 550 TabStripModel* tab_strip = NULL; | 586 TabStripModel* tab_strip = NULL; | 
| 551 int tab_index; | 587 int tab_index; | 
| 552 | 588 | 
| 553 if (ExtensionTabUtil::GetTabStripModel(contents, &tab_strip, &tab_index)) { | 589 if (ExtensionTabUtil::GetTabStripModel(contents, &tab_strip, &tab_index)) { | 
| 554 scoped_ptr<base::DictionaryValue> changed_properties( | 590 scoped_ptr<base::DictionaryValue> changed_properties( | 
| (...skipping 24 matching lines...) Expand all Loading... | |
| 579 // Dispatch the |onZoomChange| event. | 615 // Dispatch the |onZoomChange| event. | 
| 580 Profile* profile = Profile::FromBrowserContext( | 616 Profile* profile = Profile::FromBrowserContext( | 
| 581 data.web_contents->GetBrowserContext()); | 617 data.web_contents->GetBrowserContext()); | 
| 582 DispatchEvent(profile, | 618 DispatchEvent(profile, | 
| 583 tabs::OnZoomChange::kEventName, | 619 tabs::OnZoomChange::kEventName, | 
| 584 api::tabs::OnZoomChange::Create(zoom_change_info), | 620 api::tabs::OnZoomChange::Create(zoom_change_info), | 
| 585 EventRouter::USER_GESTURE_UNKNOWN); | 621 EventRouter::USER_GESTURE_UNKNOWN); | 
| 586 } | 622 } | 
| 587 | 623 | 
| 588 } // namespace extensions | 624 } // namespace extensions | 
| OLD | NEW |