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 |