ExtensionSyncService: listen for relevant changes instead of being explicitly called...
[chromium-blink-merge.git] / chrome / browser / ui / browser_finder.cc
blobe4198d48bab1a9e1645d232f8e95dd0e489dd5c0
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.
5 #include "chrome/browser/ui/browser_finder.h"
7 #include "chrome/browser/profiles/profile.h"
8 #include "chrome/browser/ui/browser_iterator.h"
9 #include "chrome/browser/ui/browser_list.h"
10 #include "chrome/browser/ui/browser_window.h"
11 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
12 #include "chrome/browser/ui/tabs/tab_strip_model.h"
13 #include "content/public/browser/navigation_controller.h"
15 #if defined(OS_CHROMEOS)
16 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
17 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
18 #endif
20 using content::WebContents;
22 namespace {
25 // Type used to indicate to match anything.
26 const int kMatchAny = 0;
28 // See BrowserMatches for details.
29 const int kMatchOriginalProfile = 1 << 0;
30 const int kMatchCanSupportWindowFeature = 1 << 1;
31 const int kMatchTabbed = 1 << 2;
33 // Returns true if the specified |browser| matches the specified arguments.
34 // |match_types| is a bitmask dictating what parameters to match:
35 // . If it contains kMatchOriginalProfile then the original profile of the
36 // browser must match |profile->GetOriginalProfile()|. This is used to match
37 // incognito windows.
38 // . If it contains kMatchCanSupportWindowFeature
39 // |CanSupportWindowFeature(window_feature)| must return true.
40 // . If it contains kMatchTabbed, the browser must be a tabbed browser.
41 bool BrowserMatches(Browser* browser,
42 Profile* profile,
43 Browser::WindowFeature window_feature,
44 uint32 match_types) {
45 if ((match_types & kMatchCanSupportWindowFeature) &&
46 !browser->CanSupportWindowFeature(window_feature)) {
47 return false;
50 #if defined(OS_CHROMEOS)
51 // Get the profile on which the window is currently shown.
52 // MultiUserWindowManager might be NULL under test scenario.
53 chrome::MultiUserWindowManager* const window_manager =
54 chrome::MultiUserWindowManager::GetInstance();
55 Profile* shown_profile = nullptr;
56 if (window_manager) {
57 const std::string& shown_user_id = window_manager->GetUserPresentingWindow(
58 browser->window()->GetNativeWindow());
59 shown_profile = shown_user_id.empty()
60 ? nullptr
61 : multi_user_util::GetProfileFromUserID(shown_user_id);
63 #endif
65 if (match_types & kMatchOriginalProfile) {
66 if (browser->profile()->GetOriginalProfile() !=
67 profile->GetOriginalProfile())
68 return false;
69 #if defined(OS_CHROMEOS)
70 if (shown_profile &&
71 shown_profile->GetOriginalProfile() != profile->GetOriginalProfile()) {
72 return false;
74 #endif
75 } else {
76 if (browser->profile() != profile)
77 return false;
78 #if defined(OS_CHROMEOS)
79 if (shown_profile && shown_profile != profile)
80 return false;
81 #endif
84 if (match_types & kMatchTabbed)
85 return browser->is_type_tabbed();
87 return true;
90 // Returns the first browser in the specified iterator that returns true from
91 // |BrowserMatches|, or null if no browsers match the arguments. See
92 // |BrowserMatches| for details on the arguments.
93 template <class T>
94 Browser* FindBrowserMatching(const T& begin,
95 const T& end,
96 Profile* profile,
97 Browser::WindowFeature window_feature,
98 uint32 match_types) {
99 for (T i = begin; i != end; ++i) {
100 if (BrowserMatches(*i, profile, window_feature, match_types))
101 return *i;
103 return NULL;
106 Browser* FindBrowserWithTabbedOrAnyType(Profile* profile,
107 chrome::HostDesktopType desktop_type,
108 bool match_tabbed,
109 bool match_original_profiles) {
110 BrowserList* browser_list_impl = BrowserList::GetInstance(desktop_type);
111 if (!browser_list_impl)
112 return NULL;
113 uint32 match_types = kMatchAny;
114 if (match_tabbed)
115 match_types |= kMatchTabbed;
116 if (match_original_profiles)
117 match_types |= kMatchOriginalProfile;
118 Browser* browser = FindBrowserMatching(browser_list_impl->begin_last_active(),
119 browser_list_impl->end_last_active(),
120 profile,
121 Browser::FEATURE_NONE,
122 match_types);
123 // Fall back to a forward scan of all Browsers if no active one was found.
124 return browser ? browser : FindBrowserMatching(browser_list_impl->begin(),
125 browser_list_impl->end(),
126 profile,
127 Browser::FEATURE_NONE,
128 match_types);
131 size_t GetBrowserCountImpl(Profile* profile,
132 chrome::HostDesktopType desktop_type,
133 uint32 match_types) {
134 BrowserList* browser_list_impl = BrowserList::GetInstance(desktop_type);
135 size_t count = 0;
136 if (browser_list_impl) {
137 for (BrowserList::const_iterator i = browser_list_impl->begin();
138 i != browser_list_impl->end(); ++i) {
139 if (BrowserMatches(*i, profile, Browser::FEATURE_NONE, match_types))
140 count++;
143 return count;
146 } // namespace
148 namespace chrome {
150 Browser* FindTabbedBrowser(Profile* profile,
151 bool match_original_profiles,
152 HostDesktopType type) {
153 return FindBrowserWithTabbedOrAnyType(profile,
154 type,
155 true,
156 match_original_profiles);
159 Browser* FindAnyBrowser(Profile* profile,
160 bool match_original_profiles,
161 HostDesktopType type) {
162 return FindBrowserWithTabbedOrAnyType(profile,
163 type,
164 false,
165 match_original_profiles);
168 Browser* FindBrowserWithProfile(Profile* profile,
169 HostDesktopType desktop_type) {
170 return FindBrowserWithTabbedOrAnyType(profile, desktop_type, false, false);
173 Browser* FindBrowserWithID(SessionID::id_type desired_id) {
174 for (BrowserIterator it; !it.done(); it.Next()) {
175 if (it->session_id().id() == desired_id)
176 return *it;
178 return NULL;
181 Browser* FindBrowserWithWindow(gfx::NativeWindow window) {
182 if (!window)
183 return NULL;
184 for (BrowserIterator it; !it.done(); it.Next()) {
185 Browser* browser = *it;
186 if (browser->window() && browser->window()->GetNativeWindow() == window)
187 return browser;
189 return NULL;
192 Browser* FindBrowserWithWebContents(const WebContents* web_contents) {
193 DCHECK(web_contents);
194 for (TabContentsIterator it; !it.done(); it.Next()) {
195 if (*it == web_contents)
196 return it.browser();
198 return NULL;
201 Browser* FindLastActiveWithProfile(Profile* profile, HostDesktopType type) {
202 BrowserList* list = BrowserList::GetInstance(type);
203 // We are only interested in last active browsers, so we don't fall back to
204 // all browsers like FindBrowserWith* do.
205 return FindBrowserMatching(list->begin_last_active(), list->end_last_active(),
206 profile, Browser::FEATURE_NONE, kMatchAny);
209 Browser* FindLastActiveWithHostDesktopType(HostDesktopType type) {
210 BrowserList* browser_list_impl = BrowserList::GetInstance(type);
211 if (browser_list_impl)
212 return browser_list_impl->GetLastActive();
213 return NULL;
216 size_t GetTotalBrowserCount() {
217 size_t count = 0;
218 for (HostDesktopType t = HOST_DESKTOP_TYPE_FIRST; t < HOST_DESKTOP_TYPE_COUNT;
219 t = static_cast<HostDesktopType>(t + 1)) {
220 count += BrowserList::GetInstance(t)->size();
222 return count;
225 size_t GetTotalBrowserCountForProfile(Profile* profile) {
226 size_t count = 0;
227 for (HostDesktopType t = HOST_DESKTOP_TYPE_FIRST; t < HOST_DESKTOP_TYPE_COUNT;
228 t = static_cast<HostDesktopType>(t + 1)) {
229 count += GetBrowserCount(profile, t);
231 return count;
234 size_t GetBrowserCount(Profile* profile, HostDesktopType type) {
235 return GetBrowserCountImpl(profile, type, kMatchAny);
238 size_t GetTabbedBrowserCount(Profile* profile, HostDesktopType type) {
239 return GetBrowserCountImpl(profile, type, kMatchTabbed);
242 } // namespace chrome