| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/browser_list.h" | 5 #include "chrome/browser/ui/browser_list.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| 11 #include "build/build_config.h" | 11 #include "build/build_config.h" |
| 12 #include "chrome/browser/browser_process.h" | 12 #include "chrome/browser/browser_process.h" |
| 13 #include "chrome/browser/browser_shutdown.h" | 13 #include "chrome/browser/browser_shutdown.h" |
| 14 #include "chrome/browser/download/download_service.h" | 14 #include "chrome/browser/download/download_service.h" |
| 15 #include "chrome/browser/metrics/thread_watcher.h" | 15 #include "chrome/browser/metrics/thread_watcher.h" |
| 16 #include "chrome/browser/prefs/pref_service.h" | 16 #include "chrome/browser/prefs/pref_service.h" |
| 17 #include "chrome/browser/printing/background_printing_manager.h" | 17 #include "chrome/browser/printing/background_printing_manager.h" |
| 18 #include "chrome/browser/profiles/profile.h" | 18 #include "chrome/browser/profiles/profile.h" |
| 19 #include "chrome/browser/profiles/profile_manager.h" | 19 #include "chrome/browser/profiles/profile_manager.h" |
| 20 #include "chrome/browser/ui/browser.h" |
| 20 #include "chrome/browser/ui/browser_window.h" | 21 #include "chrome/browser/ui/browser_window.h" |
| 21 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" | 22 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" |
| 22 #include "chrome/common/chrome_notification_types.h" | 23 #include "chrome/common/chrome_notification_types.h" |
| 23 #include "chrome/common/chrome_switches.h" | 24 #include "chrome/common/chrome_switches.h" |
| 24 #include "chrome/common/pref_names.h" | 25 #include "chrome/common/pref_names.h" |
| 25 #include "content/public/browser/browser_shutdown.h" | 26 #include "content/public/browser/browser_shutdown.h" |
| 26 #include "content/public/browser/browser_thread.h" | 27 #include "content/public/browser/browser_thread.h" |
| 27 #include "content/public/browser/navigation_details.h" | 28 #include "content/public/browser/navigation_details.h" |
| 28 #include "content/public/browser/notification_registrar.h" | 29 #include "content/public/browser/notification_registrar.h" |
| 29 #include "content/public/browser/notification_service.h" | 30 #include "content/public/browser/notification_service.h" |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 } | 109 } |
| 109 } | 110 } |
| 110 | 111 |
| 111 content::NotificationRegistrar registrar_; | 112 content::NotificationRegistrar registrar_; |
| 112 | 113 |
| 113 DISALLOW_COPY_AND_ASSIGN(BrowserActivityObserver); | 114 DISALLOW_COPY_AND_ASSIGN(BrowserActivityObserver); |
| 114 }; | 115 }; |
| 115 | 116 |
| 116 BrowserActivityObserver* activity_observer = NULL; | 117 BrowserActivityObserver* activity_observer = NULL; |
| 117 | 118 |
| 118 // Type used to indicate to match anything. | |
| 119 const int kMatchAny = 0; | |
| 120 | |
| 121 // See BrowserMatches for details. | |
| 122 const int kMatchOriginalProfile = 1 << 0; | |
| 123 const int kMatchCanSupportWindowFeature = 1 << 1; | |
| 124 const int kMatchTabbed = 1 << 2; | |
| 125 | |
| 126 static BrowserList::BrowserVector& browsers() { | 119 static BrowserList::BrowserVector& browsers() { |
| 127 CR_DEFINE_STATIC_LOCAL(BrowserList::BrowserVector, browser_vector, ()); | 120 CR_DEFINE_STATIC_LOCAL(BrowserList::BrowserVector, browser_vector, ()); |
| 128 return browser_vector; | 121 return browser_vector; |
| 129 } | 122 } |
| 130 | 123 |
| 131 static BrowserList::BrowserVector& last_active_browsers() { | 124 static BrowserList::BrowserVector& last_active_browsers() { |
| 132 CR_DEFINE_STATIC_LOCAL(BrowserList::BrowserVector, last_active_vector, ()); | 125 CR_DEFINE_STATIC_LOCAL(BrowserList::BrowserVector, last_active_vector, ()); |
| 133 return last_active_vector; | 126 return last_active_vector; |
| 134 } | 127 } |
| 135 | 128 |
| 136 static ObserverList<BrowserList::Observer>& observers() { | 129 static ObserverList<BrowserList::Observer>& observers() { |
| 137 CR_DEFINE_STATIC_LOCAL( | 130 CR_DEFINE_STATIC_LOCAL( |
| 138 ObserverList<BrowserList::Observer>, observer_vector, ()); | 131 ObserverList<BrowserList::Observer>, observer_vector, ()); |
| 139 return observer_vector; | 132 return observer_vector; |
| 140 } | 133 } |
| 141 | 134 |
| 142 // Returns true if the specified |browser| matches the specified arguments. | |
| 143 // |match_types| is a bitmask dictating what parameters to match: | |
| 144 // . If it contains kMatchOriginalProfile then the original profile of the | |
| 145 // browser must match |profile->GetOriginalProfile()|. This is used to match | |
| 146 // incognito windows. | |
| 147 // . If it contains kMatchCanSupportWindowFeature | |
| 148 // |CanSupportWindowFeature(window_feature)| must return true. | |
| 149 // . If it contains kMatchTabbed, the browser must be a tabbed browser. | |
| 150 bool BrowserMatches(Browser* browser, | |
| 151 Profile* profile, | |
| 152 Browser::WindowFeature window_feature, | |
| 153 uint32 match_types) { | |
| 154 if (match_types & kMatchCanSupportWindowFeature && | |
| 155 !browser->CanSupportWindowFeature(window_feature)) { | |
| 156 return false; | |
| 157 } | |
| 158 | |
| 159 if (match_types & kMatchOriginalProfile) { | |
| 160 if (browser->profile()->GetOriginalProfile() != | |
| 161 profile->GetOriginalProfile()) | |
| 162 return false; | |
| 163 } else if (browser->profile() != profile) { | |
| 164 return false; | |
| 165 } | |
| 166 | |
| 167 if (match_types & kMatchTabbed) | |
| 168 return browser->is_type_tabbed(); | |
| 169 | |
| 170 return true; | |
| 171 } | |
| 172 | |
| 173 // Returns the first browser in the specified iterator that returns true from | |
| 174 // |BrowserMatches|, or null if no browsers match the arguments. See | |
| 175 // |BrowserMatches| for details on the arguments. | |
| 176 template <class T> | |
| 177 Browser* FindBrowserMatching(const T& begin, | |
| 178 const T& end, | |
| 179 Profile* profile, | |
| 180 Browser::WindowFeature window_feature, | |
| 181 uint32 match_types) { | |
| 182 for (T i = begin; i != end; ++i) { | |
| 183 if (BrowserMatches(*i, profile, window_feature, match_types)) | |
| 184 return *i; | |
| 185 } | |
| 186 return NULL; | |
| 187 } | |
| 188 | |
| 189 Browser* FindBrowserWithTabbedOrAnyType(Profile* profile, | |
| 190 bool match_tabbed, | |
| 191 bool match_original_profiles) { | |
| 192 uint32 match_types = kMatchAny; | |
| 193 if (match_tabbed) | |
| 194 match_types |= kMatchTabbed; | |
| 195 if (match_original_profiles) | |
| 196 match_types |= kMatchOriginalProfile; | |
| 197 Browser* browser = FindBrowserMatching( | |
| 198 BrowserList::begin_last_active(), BrowserList::end_last_active(), | |
| 199 profile, Browser::FEATURE_NONE, match_types); | |
| 200 // Fall back to a forward scan of all Browsers if no active one was found. | |
| 201 return browser ? browser : | |
| 202 FindBrowserMatching(BrowserList::begin(), BrowserList::end(), profile, | |
| 203 Browser::FEATURE_NONE, match_types); | |
| 204 } | |
| 205 | |
| 206 printing::BackgroundPrintingManager* GetBackgroundPrintingManager() { | 135 printing::BackgroundPrintingManager* GetBackgroundPrintingManager() { |
| 207 return g_browser_process->background_printing_manager(); | 136 return g_browser_process->background_printing_manager(); |
| 208 } | 137 } |
| 209 | 138 |
| 210 // Returns true if all browsers can be closed without user interaction. | 139 // Returns true if all browsers can be closed without user interaction. |
| 211 // This currently checks if there is pending download, or if it needs to | 140 // This currently checks if there is pending download, or if it needs to |
| 212 // handle unload handler. | 141 // handle unload handler. |
| 213 bool AreAllBrowsersCloseable() { | 142 bool AreAllBrowsersCloseable() { |
| 214 BrowserList::const_iterator browser_it = BrowserList::begin(); | 143 BrowserList::const_iterator browser_it = BrowserList::begin(); |
| 215 if (browser_it == BrowserList::end()) | 144 if (browser_it == BrowserList::end()) |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 return; | 383 return; |
| 455 } | 384 } |
| 456 } | 385 } |
| 457 } | 386 } |
| 458 } | 387 } |
| 459 | 388 |
| 460 void BrowserList::CloseAllBrowsersWithProfile(Profile* profile) { | 389 void BrowserList::CloseAllBrowsersWithProfile(Profile* profile) { |
| 461 BrowserVector browsers_to_close; | 390 BrowserVector browsers_to_close; |
| 462 for (BrowserList::const_iterator i = BrowserList::begin(); | 391 for (BrowserList::const_iterator i = BrowserList::begin(); |
| 463 i != BrowserList::end(); ++i) { | 392 i != BrowserList::end(); ++i) { |
| 464 if (BrowserMatches(*i, profile, Browser::FEATURE_NONE, | 393 if ((*i)->profile()->GetOriginalProfile() == profile->GetOriginalProfile()) |
| 465 kMatchOriginalProfile)) { | |
| 466 browsers_to_close.push_back(*i); | 394 browsers_to_close.push_back(*i); |
| 467 } | |
| 468 } | 395 } |
| 469 | 396 |
| 470 for (BrowserVector::const_iterator i = browsers_to_close.begin(); | 397 for (BrowserVector::const_iterator i = browsers_to_close.begin(); |
| 471 i != browsers_to_close.end(); ++i) { | 398 i != browsers_to_close.end(); ++i) { |
| 472 (*i)->window()->Close(); | 399 (*i)->window()->Close(); |
| 473 } | 400 } |
| 474 } | 401 } |
| 475 | 402 |
| 476 // static | 403 // static |
| 477 void BrowserList::AttemptUserExit() { | 404 void BrowserList::AttemptUserExit() { |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 content::NotificationService::current()->Notify( | 521 content::NotificationService::current()->Notify( |
| 595 chrome::NOTIFICATION_SESSION_END, | 522 chrome::NOTIFICATION_SESSION_END, |
| 596 content::NotificationService::AllSources(), | 523 content::NotificationService::AllSources(), |
| 597 content::NotificationService::NoDetails()); | 524 content::NotificationService::NoDetails()); |
| 598 | 525 |
| 599 // This will end by terminating the process. | 526 // This will end by terminating the process. |
| 600 content::ImmediateShutdownAndExitProcess(); | 527 content::ImmediateShutdownAndExitProcess(); |
| 601 } | 528 } |
| 602 | 529 |
| 603 // static | 530 // static |
| 604 bool BrowserList::HasBrowserWithProfile(Profile* profile) { | |
| 605 return FindBrowserMatching(BrowserList::begin(), | |
| 606 BrowserList::end(), | |
| 607 profile, | |
| 608 Browser::FEATURE_NONE, | |
| 609 kMatchAny) != NULL; | |
| 610 } | |
| 611 | |
| 612 // static | |
| 613 int BrowserList::keep_alive_count_ = 0; | 531 int BrowserList::keep_alive_count_ = 0; |
| 614 | 532 |
| 615 // static | 533 // static |
| 616 void BrowserList::StartKeepAlive() { | 534 void BrowserList::StartKeepAlive() { |
| 617 // Increment the browser process refcount as long as we're keeping the | 535 // Increment the browser process refcount as long as we're keeping the |
| 618 // application alive. | 536 // application alive. |
| 619 if (!WillKeepAlive()) | 537 if (!WillKeepAlive()) |
| 620 g_browser_process->AddRefModule(); | 538 g_browser_process->AddRefModule(); |
| 621 keep_alive_count_++; | 539 keep_alive_count_++; |
| 622 } | 540 } |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 683 | 601 |
| 684 // static | 602 // static |
| 685 Browser* BrowserList::GetLastActive() { | 603 Browser* BrowserList::GetLastActive() { |
| 686 if (!last_active_browsers().empty()) | 604 if (!last_active_browsers().empty()) |
| 687 return *(last_active_browsers().rbegin()); | 605 return *(last_active_browsers().rbegin()); |
| 688 | 606 |
| 689 return NULL; | 607 return NULL; |
| 690 } | 608 } |
| 691 | 609 |
| 692 // static | 610 // static |
| 693 Browser* BrowserList::GetLastActiveWithProfile(Profile* profile) { | |
| 694 // We are only interested in last active browsers, so we don't fall back to | |
| 695 // all browsers like FindBrowserWith* do. | |
| 696 return FindBrowserMatching( | |
| 697 BrowserList::begin_last_active(), BrowserList::end_last_active(), profile, | |
| 698 Browser::FEATURE_NONE, kMatchAny); | |
| 699 } | |
| 700 | |
| 701 // static | |
| 702 Browser* BrowserList::FindTabbedBrowser(Profile* profile, | |
| 703 bool match_original_profiles) { | |
| 704 return FindBrowserWithTabbedOrAnyType(profile, | |
| 705 true, | |
| 706 match_original_profiles); | |
| 707 } | |
| 708 | |
| 709 // static | |
| 710 Browser* BrowserList::FindAnyBrowser(Profile* profile, | |
| 711 bool match_original_profiles) { | |
| 712 return FindBrowserWithTabbedOrAnyType(profile, | |
| 713 false, | |
| 714 match_original_profiles); | |
| 715 } | |
| 716 | |
| 717 // static | |
| 718 Browser* BrowserList::FindBrowserWithFeature(Profile* profile, | |
| 719 Browser::WindowFeature feature) { | |
| 720 Browser* browser = FindBrowserMatching( | |
| 721 BrowserList::begin_last_active(), BrowserList::end_last_active(), | |
| 722 profile, feature, kMatchCanSupportWindowFeature); | |
| 723 // Fall back to a forward scan of all Browsers if no active one was found. | |
| 724 return browser ? browser : | |
| 725 FindBrowserMatching(BrowserList::begin(), BrowserList::end(), profile, | |
| 726 feature, kMatchCanSupportWindowFeature); | |
| 727 } | |
| 728 | |
| 729 // static | |
| 730 Browser* BrowserList::FindBrowserWithProfile(Profile* profile) { | |
| 731 return FindAnyBrowser(profile, false); | |
| 732 } | |
| 733 | |
| 734 // static | |
| 735 Browser* BrowserList::FindBrowserWithID(SessionID::id_type desired_id) { | |
| 736 for (BrowserList::const_iterator i = BrowserList::begin(); | |
| 737 i != BrowserList::end(); ++i) { | |
| 738 if ((*i)->session_id().id() == desired_id) | |
| 739 return *i; | |
| 740 } | |
| 741 return NULL; | |
| 742 } | |
| 743 | |
| 744 // static | |
| 745 Browser* BrowserList::FindBrowserWithWindow(gfx::NativeWindow window) { | |
| 746 for (BrowserList::const_iterator it = BrowserList::begin(); | |
| 747 it != BrowserList::end(); | |
| 748 ++it) { | |
| 749 Browser* browser = *it; | |
| 750 if (browser->window() && browser->window()->GetNativeHandle() == window) | |
| 751 return browser; | |
| 752 } | |
| 753 return NULL; | |
| 754 } | |
| 755 | |
| 756 // static | |
| 757 Browser* BrowserList::FindBrowserWithWebContents(WebContents* web_contents) { | |
| 758 DCHECK(web_contents); | |
| 759 for (TabContentsIterator it; !it.done(); ++it) { | |
| 760 if (it->web_contents() == web_contents) | |
| 761 return it.browser(); | |
| 762 } | |
| 763 return NULL; | |
| 764 } | |
| 765 | |
| 766 // static | |
| 767 BrowserList::const_reverse_iterator BrowserList::begin_last_active() { | 611 BrowserList::const_reverse_iterator BrowserList::begin_last_active() { |
| 768 return last_active_browsers().rbegin(); | 612 return last_active_browsers().rbegin(); |
| 769 } | 613 } |
| 770 | 614 |
| 771 // static | 615 // static |
| 772 BrowserList::const_reverse_iterator BrowserList::end_last_active() { | 616 BrowserList::const_reverse_iterator BrowserList::end_last_active() { |
| 773 return last_active_browsers().rend(); | 617 return last_active_browsers().rend(); |
| 774 } | 618 } |
| 775 | 619 |
| 776 // static | 620 // static |
| 777 size_t BrowserList::GetBrowserCount(Profile* profile) { | |
| 778 size_t result = 0; | |
| 779 for (BrowserList::const_iterator i = BrowserList::begin(); | |
| 780 i != BrowserList::end(); ++i) { | |
| 781 if (BrowserMatches(*i, profile, Browser::FEATURE_NONE, kMatchAny)) { | |
| 782 ++result; | |
| 783 } | |
| 784 } | |
| 785 return result; | |
| 786 } | |
| 787 | |
| 788 // static | |
| 789 size_t BrowserList::GetBrowserCountForType(Profile* profile, | |
| 790 bool match_tabbed) { | |
| 791 size_t result = 0; | |
| 792 for (BrowserList::const_iterator i = BrowserList::begin(); | |
| 793 i != BrowserList::end(); ++i) { | |
| 794 if (BrowserMatches(*i, profile, Browser::FEATURE_NONE, | |
| 795 match_tabbed ? kMatchTabbed : kMatchAny)) | |
| 796 ++result; | |
| 797 } | |
| 798 return result; | |
| 799 } | |
| 800 | |
| 801 // static | |
| 802 bool BrowserList::IsOffTheRecordSessionActive() { | 621 bool BrowserList::IsOffTheRecordSessionActive() { |
| 803 for (BrowserList::const_iterator i = BrowserList::begin(); | 622 for (BrowserList::const_iterator i = BrowserList::begin(); |
| 804 i != BrowserList::end(); ++i) { | 623 i != BrowserList::end(); ++i) { |
| 805 if ((*i)->profile()->IsOffTheRecord()) | 624 if ((*i)->profile()->IsOffTheRecord()) |
| 806 return true; | 625 return true; |
| 807 } | 626 } |
| 808 return false; | 627 return false; |
| 809 } | 628 } |
| 810 | 629 |
| 811 // static | 630 // static |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 868 // If no more WebContents from Browsers, check the BackgroundPrintingManager. | 687 // If no more WebContents from Browsers, check the BackgroundPrintingManager. |
| 869 while (bg_printing_iterator_ != GetBackgroundPrintingManager()->end()) { | 688 while (bg_printing_iterator_ != GetBackgroundPrintingManager()->end()) { |
| 870 cur_ = *bg_printing_iterator_; | 689 cur_ = *bg_printing_iterator_; |
| 871 CHECK(cur_); | 690 CHECK(cur_); |
| 872 ++bg_printing_iterator_; | 691 ++bg_printing_iterator_; |
| 873 return; | 692 return; |
| 874 } | 693 } |
| 875 // Reached the end - no more WebContents. | 694 // Reached the end - no more WebContents. |
| 876 cur_ = NULL; | 695 cur_ = NULL; |
| 877 } | 696 } |
| OLD | NEW |