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"
20 using content::WebContents
;
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
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
,
43 Browser::WindowFeature window_feature
,
45 if ((match_types
& kMatchCanSupportWindowFeature
) &&
46 !browser
->CanSupportWindowFeature(window_feature
)) {
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;
57 const std::string
& shown_user_id
= window_manager
->GetUserPresentingWindow(
58 browser
->window()->GetNativeWindow());
59 shown_profile
= shown_user_id
.empty()
61 : multi_user_util::GetProfileFromUserID(shown_user_id
);
65 if (match_types
& kMatchOriginalProfile
) {
66 if (browser
->profile()->GetOriginalProfile() !=
67 profile
->GetOriginalProfile())
69 #if defined(OS_CHROMEOS)
71 shown_profile
->GetOriginalProfile() != profile
->GetOriginalProfile()) {
76 if (browser
->profile() != profile
)
78 #if defined(OS_CHROMEOS)
79 if (shown_profile
&& shown_profile
!= profile
)
84 if (match_types
& kMatchTabbed
)
85 return browser
->is_type_tabbed();
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.
94 Browser
* FindBrowserMatching(const T
& begin
,
97 Browser::WindowFeature window_feature
,
99 for (T i
= begin
; i
!= end
; ++i
) {
100 if (BrowserMatches(*i
, profile
, window_feature
, match_types
))
106 Browser
* FindBrowserWithTabbedOrAnyType(Profile
* profile
,
107 chrome::HostDesktopType desktop_type
,
109 bool match_original_profiles
) {
110 BrowserList
* browser_list_impl
= BrowserList::GetInstance(desktop_type
);
111 if (!browser_list_impl
)
113 uint32 match_types
= kMatchAny
;
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(),
121 Browser::FEATURE_NONE
,
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(),
127 Browser::FEATURE_NONE
,
131 size_t GetBrowserCountImpl(Profile
* profile
,
132 chrome::HostDesktopType desktop_type
,
133 uint32 match_types
) {
134 BrowserList
* browser_list_impl
= BrowserList::GetInstance(desktop_type
);
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
))
150 Browser
* FindTabbedBrowser(Profile
* profile
,
151 bool match_original_profiles
,
152 HostDesktopType type
) {
153 return FindBrowserWithTabbedOrAnyType(profile
,
156 match_original_profiles
);
159 Browser
* FindAnyBrowser(Profile
* profile
,
160 bool match_original_profiles
,
161 HostDesktopType type
) {
162 return FindBrowserWithTabbedOrAnyType(profile
,
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
)
181 Browser
* FindBrowserWithWindow(gfx::NativeWindow window
) {
184 for (BrowserIterator it
; !it
.done(); it
.Next()) {
185 Browser
* browser
= *it
;
186 if (browser
->window() && browser
->window()->GetNativeWindow() == window
)
192 Browser
* FindBrowserWithWebContents(const WebContents
* web_contents
) {
193 DCHECK(web_contents
);
194 for (TabContentsIterator it
; !it
.done(); it
.Next()) {
195 if (*it
== web_contents
)
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();
216 size_t GetTotalBrowserCount() {
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();
225 size_t GetTotalBrowserCountForProfile(Profile
* profile
) {
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
);
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