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. 4 5 #include "chrome/browser/ui/browser_finder.h" 6 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" 14 15 using content::WebContents; 16 17 namespace { 18 19 20 // Type used to indicate to match anything. 21 const int kMatchAny = 0; 22 23 // See BrowserMatches for details. 24 const int kMatchOriginalProfile = 1 << 0; 25 const int kMatchCanSupportWindowFeature = 1 << 1; 26 const int kMatchTabbed = 1 << 2; 27 28 // Returns true if the specified |browser| matches the specified arguments. 29 // |match_types| is a bitmask dictating what parameters to match: 30 // . If it contains kMatchOriginalProfile then the original profile of the 31 // browser must match |profile->GetOriginalProfile()|. This is used to match 32 // incognito windows. 33 // . If it contains kMatchCanSupportWindowFeature 34 // |CanSupportWindowFeature(window_feature)| must return true. 35 // . If it contains kMatchTabbed, the browser must be a tabbed browser. 36 bool BrowserMatches(Browser* browser, 37 Profile* profile, 38 Browser::WindowFeature window_feature, 39 uint32 match_types) { 40 if (match_types & kMatchCanSupportWindowFeature && 41 !browser->CanSupportWindowFeature(window_feature)) { 42 return false; 43 } 44 45 if (match_types & kMatchOriginalProfile) { 46 if (browser->profile()->GetOriginalProfile() != 47 profile->GetOriginalProfile()) 48 return false; 49 } else if (browser->profile() != profile) { 50 return false; 51 } 52 53 if (match_types & kMatchTabbed) 54 return browser->is_type_tabbed(); 55 56 return true; 57 } 58 59 // Returns the first browser in the specified iterator that returns true from 60 // |BrowserMatches|, or null if no browsers match the arguments. See 61 // |BrowserMatches| for details on the arguments. 62 template <class T> 63 Browser* FindBrowserMatching(const T& begin, 64 const T& end, 65 Profile* profile, 66 Browser::WindowFeature window_feature, 67 uint32 match_types) { 68 for (T i = begin; i != end; ++i) { 69 if (BrowserMatches(*i, profile, window_feature, match_types)) 70 return *i; 71 } 72 return NULL; 73 } 74 75 Browser* FindBrowserWithTabbedOrAnyType(Profile* profile, 76 chrome::HostDesktopType desktop_type, 77 bool match_tabbed, 78 bool match_original_profiles) { 79 BrowserList* browser_list_impl = BrowserList::GetInstance(desktop_type); 80 if (!browser_list_impl) 81 return NULL; 82 uint32 match_types = kMatchAny; 83 if (match_tabbed) 84 match_types |= kMatchTabbed; 85 if (match_original_profiles) 86 match_types |= kMatchOriginalProfile; 87 Browser* browser = FindBrowserMatching(browser_list_impl->begin_last_active(), 88 browser_list_impl->end_last_active(), 89 profile, 90 Browser::FEATURE_NONE, 91 match_types); 92 // Fall back to a forward scan of all Browsers if no active one was found. 93 return browser ? browser : FindBrowserMatching(browser_list_impl->begin(), 94 browser_list_impl->end(), 95 profile, 96 Browser::FEATURE_NONE, 97 match_types); 98 } 99 100 size_t GetBrowserCountImpl(Profile* profile, 101 chrome::HostDesktopType desktop_type, 102 uint32 match_types) { 103 BrowserList* browser_list_impl = BrowserList::GetInstance(desktop_type); 104 size_t count = 0; 105 if (browser_list_impl) { 106 for (BrowserList::const_iterator i = browser_list_impl->begin(); 107 i != browser_list_impl->end(); ++i) { 108 if (BrowserMatches(*i, profile, Browser::FEATURE_NONE, match_types)) 109 count++; 110 } 111 } 112 return count; 113 } 114 115 } // namespace 116 117 namespace chrome { 118 119 Browser* FindTabbedBrowser(Profile* profile, 120 bool match_original_profiles, 121 HostDesktopType type) { 122 return FindBrowserWithTabbedOrAnyType(profile, 123 type, 124 true, 125 match_original_profiles); 126 } 127 128 Browser* FindOrCreateTabbedBrowser(Profile* profile, HostDesktopType type) { 129 Browser* browser = FindTabbedBrowser(profile, false, type); 130 if (!browser) 131 browser = new Browser(Browser::CreateParams(profile, type)); 132 return browser; 133 } 134 135 Browser* FindAnyBrowser(Profile* profile, 136 bool match_original_profiles, 137 HostDesktopType type) { 138 return FindBrowserWithTabbedOrAnyType(profile, 139 type, 140 false, 141 match_original_profiles); 142 } 143 144 Browser* FindBrowserWithProfile(Profile* profile, 145 HostDesktopType desktop_type) { 146 return FindBrowserWithTabbedOrAnyType(profile, desktop_type, false, false); 147 } 148 149 Browser* FindBrowserWithID(SessionID::id_type desired_id) { 150 for (BrowserIterator it; !it.done(); it.Next()) { 151 if (it->session_id().id() == desired_id) 152 return *it; 153 } 154 return NULL; 155 } 156 157 Browser* FindBrowserWithWindow(gfx::NativeWindow window) { 158 if (!window) 159 return NULL; 160 for (BrowserIterator it; !it.done(); it.Next()) { 161 Browser* browser = *it; 162 if (browser->window() && browser->window()->GetNativeWindow() == window) 163 return browser; 164 } 165 return NULL; 166 } 167 168 Browser* FindBrowserWithWebContents(const WebContents* web_contents) { 169 DCHECK(web_contents); 170 for (TabContentsIterator it; !it.done(); it.Next()) { 171 if (*it == web_contents) 172 return it.browser(); 173 } 174 return NULL; 175 } 176 177 Browser* FindLastActiveWithProfile(Profile* profile, HostDesktopType type) { 178 BrowserList* list = BrowserList::GetInstance(type); 179 // We are only interested in last active browsers, so we don't fall back to 180 // all browsers like FindBrowserWith* do. 181 return FindBrowserMatching(list->begin_last_active(), list->end_last_active(), 182 profile, Browser::FEATURE_NONE, kMatchAny); 183 } 184 185 Browser* FindLastActiveWithHostDesktopType(HostDesktopType type) { 186 BrowserList* browser_list_impl = BrowserList::GetInstance(type); 187 if (browser_list_impl) 188 return browser_list_impl->GetLastActive(); 189 return NULL; 190 } 191 192 size_t GetTotalBrowserCount() { 193 size_t count = 0; 194 for (HostDesktopType t = HOST_DESKTOP_TYPE_FIRST; t < HOST_DESKTOP_TYPE_COUNT; 195 t = static_cast<HostDesktopType>(t + 1)) { 196 count += BrowserList::GetInstance(t)->size(); 197 } 198 return count; 199 } 200 201 size_t GetTotalBrowserCountForProfile(Profile* profile) { 202 size_t count = 0; 203 for (HostDesktopType t = HOST_DESKTOP_TYPE_FIRST; t < HOST_DESKTOP_TYPE_COUNT; 204 t = static_cast<HostDesktopType>(t + 1)) { 205 count += GetBrowserCount(profile, t); 206 } 207 return count; 208 } 209 210 size_t GetBrowserCount(Profile* profile, HostDesktopType type) { 211 return GetBrowserCountImpl(profile, type, kMatchAny); 212 } 213 214 size_t GetTabbedBrowserCount(Profile* profile, HostDesktopType type) { 215 return GetBrowserCountImpl(profile, type, kMatchTabbed); 216 } 217 218 } // namespace chrome 219