1 // Copyright 2015 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/ui/browser_tab_strip_tracker.h"
6
7 #include "base/auto_reset.h"
8 #include "chrome/browser/ui/browser.h"
9 #include "chrome/browser/ui/browser_list.h"
10 #include "chrome/browser/ui/browser_tab_strip_tracker_delegate.h"
11 #include "chrome/browser/ui/tabs/tab_strip_model.h"
12
BrowserTabStripTracker(TabStripModelObserver * tab_strip_model_observer,BrowserTabStripTrackerDelegate * delegate)13 BrowserTabStripTracker::BrowserTabStripTracker(
14 TabStripModelObserver* tab_strip_model_observer,
15 BrowserTabStripTrackerDelegate* delegate)
16 : tab_strip_model_observer_(tab_strip_model_observer),
17 delegate_(delegate),
18 is_processing_initial_browsers_(false) {
19 DCHECK(tab_strip_model_observer_);
20 }
21
~BrowserTabStripTracker()22 BrowserTabStripTracker::~BrowserTabStripTracker() {
23 // Per ObserverList::RemoveObserver() documentation, this does nothing if the
24 // observer is not in the ObserverList (i.e. if |browser| is not tracked).
25 for (auto* browser : *BrowserList::GetInstance())
26 browser->tab_strip_model()->RemoveObserver(tab_strip_model_observer_);
27
28 BrowserList::RemoveObserver(this);
29 }
30
Init()31 void BrowserTabStripTracker::Init() {
32 BrowserList::AddObserver(this);
33
34 base::AutoReset<bool> resetter(&is_processing_initial_browsers_, true);
35 for (auto* browser : *BrowserList::GetInstance())
36 MaybeTrackBrowser(browser);
37 }
38
ShouldTrackBrowser(Browser * browser)39 bool BrowserTabStripTracker::ShouldTrackBrowser(Browser* browser) {
40 return !delegate_ || delegate_->ShouldTrackBrowser(browser);
41 }
42
MaybeTrackBrowser(Browser * browser)43 void BrowserTabStripTracker::MaybeTrackBrowser(Browser* browser) {
44 if (!ShouldTrackBrowser(browser))
45 return;
46
47 TabStripModel* tab_strip_model = browser->tab_strip_model();
48 tab_strip_model->AddObserver(tab_strip_model_observer_);
49
50 TabStripModelChange::Insert insert;
51 for (int i = 0; i < tab_strip_model->count(); ++i) {
52 insert.contents.push_back({tab_strip_model->GetWebContentsAt(i), i});
53 }
54
55 TabStripModelChange change(std::move(insert));
56 TabStripSelectionChange selection(tab_strip_model->GetActiveWebContents(),
57 tab_strip_model->selection_model());
58 tab_strip_model_observer_->OnTabStripModelChanged(tab_strip_model, change,
59 selection);
60 }
61
OnBrowserAdded(Browser * browser)62 void BrowserTabStripTracker::OnBrowserAdded(Browser* browser) {
63 // No Browser should be added when iterating on Browsers in Init(), as that
64 // may invalidate the iterator.
65 DCHECK(!is_processing_initial_browsers_);
66
67 MaybeTrackBrowser(browser);
68 }
69
OnBrowserRemoved(Browser * browser)70 void BrowserTabStripTracker::OnBrowserRemoved(Browser* browser) {
71 // No Browser should be removed when iterating on Browsers in Init(), as that
72 // invalidates any iterator that is past the removed Browser.
73 DCHECK(!is_processing_initial_browsers_);
74
75 // Per ObserverList::RemoveObserver() documentation, this does nothing if the
76 // observer is not in the ObserverList (i.e. if |browser| is not tracked).
77 browser->tab_strip_model()->RemoveObserver(tab_strip_model_observer_);
78 }
79