Home | History | Annotate | Download | only in ui
      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* FindAnyBrowser(Profile* profile,
    129                         bool match_original_profiles,
    130                         HostDesktopType type) {
    131   return FindBrowserWithTabbedOrAnyType(profile,
    132                                         type,
    133                                         false,
    134                                         match_original_profiles);
    135 }
    136 
    137 Browser* FindBrowserWithProfile(Profile* profile,
    138                                 HostDesktopType desktop_type) {
    139   return FindBrowserWithTabbedOrAnyType(profile, desktop_type, false, false);
    140 }
    141 
    142 Browser* FindBrowserWithID(SessionID::id_type desired_id) {
    143   for (BrowserIterator it; !it.done(); it.Next()) {
    144     if (it->session_id().id() == desired_id)
    145       return *it;
    146   }
    147   return NULL;
    148 }
    149 
    150 Browser* FindBrowserWithWindow(gfx::NativeWindow window) {
    151   if (!window)
    152     return NULL;
    153   for (BrowserIterator it; !it.done(); it.Next()) {
    154     Browser* browser = *it;
    155     if (browser->window() && browser->window()->GetNativeWindow() == window)
    156       return browser;
    157   }
    158   return NULL;
    159 }
    160 
    161 Browser* FindBrowserWithWebContents(const WebContents* web_contents) {
    162   DCHECK(web_contents);
    163   for (TabContentsIterator it; !it.done(); it.Next()) {
    164     if (*it == web_contents)
    165       return it.browser();
    166   }
    167   return NULL;
    168 }
    169 
    170 Browser* FindLastActiveWithProfile(Profile* profile, HostDesktopType type) {
    171   BrowserList* list = BrowserList::GetInstance(type);
    172   // We are only interested in last active browsers, so we don't fall back to
    173   // all browsers like FindBrowserWith* do.
    174   return FindBrowserMatching(list->begin_last_active(), list->end_last_active(),
    175                              profile, Browser::FEATURE_NONE, kMatchAny);
    176 }
    177 
    178 Browser* FindLastActiveWithHostDesktopType(HostDesktopType type) {
    179   BrowserList* browser_list_impl = BrowserList::GetInstance(type);
    180   if (browser_list_impl)
    181     return browser_list_impl->GetLastActive();
    182   return NULL;
    183 }
    184 
    185 size_t GetTotalBrowserCount() {
    186   size_t count = 0;
    187   for (HostDesktopType t = HOST_DESKTOP_TYPE_FIRST; t < HOST_DESKTOP_TYPE_COUNT;
    188        t = static_cast<HostDesktopType>(t + 1)) {
    189     count += BrowserList::GetInstance(t)->size();
    190   }
    191   return count;
    192 }
    193 
    194 size_t GetTotalBrowserCountForProfile(Profile* profile) {
    195   size_t count = 0;
    196   for (HostDesktopType t = HOST_DESKTOP_TYPE_FIRST; t < HOST_DESKTOP_TYPE_COUNT;
    197        t = static_cast<HostDesktopType>(t + 1)) {
    198     count += GetBrowserCount(profile, t);
    199   }
    200   return count;
    201 }
    202 
    203 size_t GetBrowserCount(Profile* profile, HostDesktopType type) {
    204   return GetBrowserCountImpl(profile, type, kMatchAny);
    205 }
    206 
    207 size_t GetTabbedBrowserCount(Profile* profile, HostDesktopType type) {
    208   return GetBrowserCountImpl(profile, type, kMatchTabbed);
    209 }
    210 
    211 }  // namespace chrome
    212