// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/oom_priority_manager.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_tabstrip.h" #include "chrome/browser/ui/find_bar/find_bar_controller.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/url_constants.h" #include "chrome/test/base/in_process_browser_test.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_types.h" #include "content/public/test/test_utils.h" #include "googleurl/src/gurl.h" using content::OpenURLParams; namespace { typedef InProcessBrowserTest OomPriorityManagerTest; IN_PROC_BROWSER_TEST_F(OomPriorityManagerTest, OomPriorityManagerBasics) { using content::WindowedNotificationObserver; // Get three tabs open. WindowedNotificationObserver load1( content::NOTIFICATION_NAV_ENTRY_COMMITTED, content::NotificationService::AllSources()); OpenURLParams open1(GURL(chrome::kChromeUIAboutURL), content::Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_TYPED, false); browser()->OpenURL(open1); load1.Wait(); WindowedNotificationObserver load2( content::NOTIFICATION_NAV_ENTRY_COMMITTED, content::NotificationService::AllSources()); OpenURLParams open2(GURL(chrome::kChromeUICreditsURL), content::Referrer(), NEW_FOREGROUND_TAB, content::PAGE_TRANSITION_TYPED, false); browser()->OpenURL(open2); load2.Wait(); WindowedNotificationObserver load3( content::NOTIFICATION_NAV_ENTRY_COMMITTED, content::NotificationService::AllSources()); OpenURLParams open3(GURL(chrome::kChromeUITermsURL), content::Referrer(), NEW_FOREGROUND_TAB, content::PAGE_TRANSITION_TYPED, false); browser()->OpenURL(open3); load3.Wait(); EXPECT_EQ(3, browser()->tab_count()); // Navigate the current (third) tab to a different URL, so we can test // back/forward later. WindowedNotificationObserver load4( content::NOTIFICATION_NAV_ENTRY_COMMITTED, content::NotificationService::AllSources()); OpenURLParams open4(GURL(chrome::kChromeUIVersionURL), content::Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_TYPED, false); browser()->OpenURL(open4); load4.Wait(); // Navigate the third tab again, such that we have three navigation entries. WindowedNotificationObserver load5( content::NOTIFICATION_NAV_ENTRY_COMMITTED, content::NotificationService::AllSources()); OpenURLParams open5(GURL("chrome://dns"), content::Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_TYPED, false); browser()->OpenURL(open5); load5.Wait(); EXPECT_EQ(3, browser()->tab_count()); // Discard a tab. It should kill the first tab, since it was the oldest // and was not selected. EXPECT_TRUE(g_browser_process->oom_priority_manager()->DiscardTab()); EXPECT_EQ(3, browser()->tab_count()); EXPECT_TRUE(browser()->tab_strip_model()->IsTabDiscarded(0)); EXPECT_FALSE(browser()->tab_strip_model()->IsTabDiscarded(1)); EXPECT_FALSE(browser()->tab_strip_model()->IsTabDiscarded(2)); // Run discard again, make sure it kills the second tab. EXPECT_TRUE(g_browser_process->oom_priority_manager()->DiscardTab()); EXPECT_EQ(3, browser()->tab_count()); EXPECT_TRUE(browser()->tab_strip_model()->IsTabDiscarded(0)); EXPECT_TRUE(browser()->tab_strip_model()->IsTabDiscarded(1)); EXPECT_FALSE(browser()->tab_strip_model()->IsTabDiscarded(2)); // Kill the third tab. It should not kill the last tab, since it is active // tab. EXPECT_FALSE(g_browser_process->oom_priority_manager()->DiscardTab()); EXPECT_TRUE(browser()->tab_strip_model()->IsTabDiscarded(0)); EXPECT_TRUE(browser()->tab_strip_model()->IsTabDiscarded(1)); EXPECT_FALSE(browser()->tab_strip_model()->IsTabDiscarded(2)); // Kill the third tab after making second tab active. browser()->tab_strip_model()->ActivateTabAt(1, true); EXPECT_EQ(1, browser()->active_index()); EXPECT_FALSE(browser()->tab_strip_model()->IsTabDiscarded(1)); browser()->tab_strip_model()->DiscardTabContentsAt(2); EXPECT_TRUE(browser()->tab_strip_model()->IsTabDiscarded(2)); // Force creation of the FindBarController. browser()->GetFindBarController(); // Select the first tab. It should reload. WindowedNotificationObserver reload1( content::NOTIFICATION_NAV_ENTRY_COMMITTED, content::NotificationService::AllSources()); chrome::SelectNumberedTab(browser(), 0); reload1.Wait(); // Make sure the FindBarController gets the right TabContents. EXPECT_EQ(browser()->GetFindBarController()->tab_contents(), chrome::GetActiveTabContents(browser())); EXPECT_EQ(0, browser()->active_index()); EXPECT_FALSE(browser()->tab_strip_model()->IsTabDiscarded(0)); EXPECT_FALSE(browser()->tab_strip_model()->IsTabDiscarded(1)); EXPECT_TRUE(browser()->tab_strip_model()->IsTabDiscarded(2)); // Select the third tab. It should reload. WindowedNotificationObserver reload2( content::NOTIFICATION_NAV_ENTRY_COMMITTED, content::NotificationService::AllSources()); chrome::SelectNumberedTab(browser(), 2); reload2.Wait(); EXPECT_EQ(2, browser()->active_index()); EXPECT_FALSE(browser()->tab_strip_model()->IsTabDiscarded(0)); EXPECT_FALSE(browser()->tab_strip_model()->IsTabDiscarded(1)); EXPECT_FALSE(browser()->tab_strip_model()->IsTabDiscarded(2)); // Navigate the third tab back twice. We used to crash here due to // crbug.com/121373. EXPECT_TRUE(chrome::CanGoBack(browser())); EXPECT_FALSE(chrome::CanGoForward(browser())); WindowedNotificationObserver back1( content::NOTIFICATION_NAV_ENTRY_COMMITTED, content::NotificationService::AllSources()); chrome::GoBack(browser(), CURRENT_TAB); back1.Wait(); EXPECT_TRUE(chrome::CanGoBack(browser())); EXPECT_TRUE(chrome::CanGoForward(browser())); WindowedNotificationObserver back2( content::NOTIFICATION_NAV_ENTRY_COMMITTED, content::NotificationService::AllSources()); chrome::GoBack(browser(), CURRENT_TAB); back2.Wait(); EXPECT_FALSE(chrome::CanGoBack(browser())); EXPECT_TRUE(chrome::CanGoForward(browser())); } } // namespace