| 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/resource_coordinator/tab_manager.h" | 5 #include "chrome/browser/resource_coordinator/tab_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <map> | 8 #include <map> |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 #include "chrome/test/base/testing_profile.h" | 32 #include "chrome/test/base/testing_profile.h" |
| 33 #include "components/variations/variations_associated_data.h" | 33 #include "components/variations/variations_associated_data.h" |
| 34 #include "content/public/browser/render_process_host.h" | 34 #include "content/public/browser/render_process_host.h" |
| 35 #include "content/public/browser/web_contents.h" | 35 #include "content/public/browser/web_contents.h" |
| 36 #include "content/public/test/mock_render_process_host.h" | 36 #include "content/public/test/mock_render_process_host.h" |
| 37 #include "content/public/test/web_contents_tester.h" | 37 #include "content/public/test/web_contents_tester.h" |
| 38 #include "content/test/test_web_contents.h" | 38 #include "content/test/test_web_contents.h" |
| 39 #include "testing/gtest/include/gtest/gtest.h" | 39 #include "testing/gtest/include/gtest/gtest.h" |
| 40 #include "url/gurl.h" | 40 #include "url/gurl.h" |
| 41 | 41 |
| 42 using content::NavigationHandle; |
| 43 using content::NavigationThrottle; |
| 42 using content::WebContents; | 44 using content::WebContents; |
| 43 using content::WebContentsTester; | 45 using content::WebContentsTester; |
| 44 | 46 |
| 45 namespace resource_coordinator { | 47 namespace resource_coordinator { |
| 46 namespace { | 48 namespace { |
| 47 | 49 |
| 50 const char kTestUrl[] = "http://www.example.com"; |
| 51 |
| 48 class TabStripDummyDelegate : public TestTabStripModelDelegate { | 52 class TabStripDummyDelegate : public TestTabStripModelDelegate { |
| 49 public: | 53 public: |
| 50 TabStripDummyDelegate() {} | 54 TabStripDummyDelegate() {} |
| 51 | 55 |
| 52 bool RunUnloadListenerBeforeClosing(WebContents* contents) override { | 56 bool RunUnloadListenerBeforeClosing(WebContents* contents) override { |
| 53 return false; | 57 return false; |
| 54 } | 58 } |
| 55 | 59 |
| 56 private: | 60 private: |
| 57 DISALLOW_COPY_AND_ASSIGN(TabStripDummyDelegate); | 61 DISALLOW_COPY_AND_ASSIGN(TabStripDummyDelegate); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 | 111 |
| 108 class TabManagerTest : public ChromeRenderViewHostTestHarness { | 112 class TabManagerTest : public ChromeRenderViewHostTestHarness { |
| 109 public: | 113 public: |
| 110 WebContents* CreateWebContents() { | 114 WebContents* CreateWebContents() { |
| 111 content::TestWebContents* web_contents = | 115 content::TestWebContents* web_contents = |
| 112 content::TestWebContents::Create(profile(), nullptr); | 116 content::TestWebContents::Create(profile(), nullptr); |
| 113 // Commit an URL to allow discarding. | 117 // Commit an URL to allow discarding. |
| 114 web_contents->NavigateAndCommit(GURL("https://www.example.com")); | 118 web_contents->NavigateAndCommit(GURL("https://www.example.com")); |
| 115 return web_contents; | 119 return web_contents; |
| 116 } | 120 } |
| 121 |
| 122 std::unique_ptr<NavigationHandle> CreateTabAndNavigation() { |
| 123 content::TestWebContents* web_contents = |
| 124 content::TestWebContents::Create(profile(), nullptr); |
| 125 return content::NavigationHandle::CreateNavigationHandleForTesting( |
| 126 GURL(kTestUrl), web_contents->GetMainFrame()); |
| 127 } |
| 128 |
| 129 // Simulate creating 3 tabs and their navigations. |
| 130 void MaybeThrottleNavigations(TabManager* tab_manager) { |
| 131 nav_handle1_ = CreateTabAndNavigation(); |
| 132 nav_handle2_ = CreateTabAndNavigation(); |
| 133 nav_handle3_ = CreateTabAndNavigation(); |
| 134 contents1_ = nav_handle1_->GetWebContents(); |
| 135 contents2_ = nav_handle2_->GetWebContents(); |
| 136 contents3_ = nav_handle3_->GetWebContents(); |
| 137 |
| 138 NavigationThrottle::ThrottleCheckResult result1 = |
| 139 tab_manager->MaybeThrottleNavigation(nav_handle1_.get()); |
| 140 NavigationThrottle::ThrottleCheckResult result2 = |
| 141 tab_manager->MaybeThrottleNavigation(nav_handle2_.get()); |
| 142 NavigationThrottle::ThrottleCheckResult result3 = |
| 143 tab_manager->MaybeThrottleNavigation(nav_handle3_.get()); |
| 144 |
| 145 // First tab starts navigation right away because there is no tab loading. |
| 146 EXPECT_EQ(content::NavigationThrottle::PROCEED, result1); |
| 147 |
| 148 // The other 2 tabs's navigations are delayed. |
| 149 EXPECT_EQ(content::NavigationThrottle::DEFER, result2); |
| 150 EXPECT_EQ(content::NavigationThrottle::DEFER, result3); |
| 151 } |
| 152 |
| 153 protected: |
| 154 std::unique_ptr<NavigationHandle> nav_handle1_; |
| 155 std::unique_ptr<NavigationHandle> nav_handle2_; |
| 156 std::unique_ptr<NavigationHandle> nav_handle3_; |
| 157 WebContents* contents1_; |
| 158 WebContents* contents2_; |
| 159 WebContents* contents3_; |
| 117 }; | 160 }; |
| 118 | 161 |
| 119 // TODO(georgesak): Add tests for protection to tabs with form input and | 162 // TODO(georgesak): Add tests for protection to tabs with form input and |
| 120 // playing audio; | 163 // playing audio; |
| 121 | 164 |
| 122 // Tests the sorting comparator to make sure it's producing the desired order. | 165 // Tests the sorting comparator to make sure it's producing the desired order. |
| 123 TEST_F(TabManagerTest, Comparator) { | 166 TEST_F(TabManagerTest, Comparator) { |
| 124 TabStatsList test_list; | 167 TabStatsList test_list; |
| 125 const base::TimeTicks now = base::TimeTicks::Now(); | 168 const base::TimeTicks now = base::TimeTicks::Now(); |
| 126 | 169 |
| (...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 685 | 728 |
| 686 histograms.ExpectTotalCount(kHistogramName, 9); | 729 histograms.ExpectTotalCount(kHistogramName, 9); |
| 687 histograms.ExpectBucketCount(kHistogramName, TAB_IS_NOT_LOADING, 2); | 730 histograms.ExpectBucketCount(kHistogramName, TAB_IS_NOT_LOADING, 2); |
| 688 histograms.ExpectBucketCount(kHistogramName, TAB_IS_LOADING, 3); | 731 histograms.ExpectBucketCount(kHistogramName, TAB_IS_LOADING, 3); |
| 689 histograms.ExpectBucketCount(kHistogramName, TAB_IS_LOADED, 4); | 732 histograms.ExpectBucketCount(kHistogramName, TAB_IS_LOADED, 4); |
| 690 | 733 |
| 691 // Tabs with a committed URL must be closed explicitly to avoid DCHECK errors. | 734 // Tabs with a committed URL must be closed explicitly to avoid DCHECK errors. |
| 692 tab_strip.CloseAllTabs(); | 735 tab_strip.CloseAllTabs(); |
| 693 } | 736 } |
| 694 | 737 |
| 738 TEST_F(TabManagerTest, MaybeThrottleNavigation) { |
| 739 TabManager* tab_manager = g_browser_process->GetTabManager(); |
| 740 MaybeThrottleNavigations(tab_manager); |
| 741 tab_manager->GetWebContentsData(contents1_) |
| 742 ->DidStartNavigation(nav_handle1_.get()); |
| 743 |
| 744 // Tab 1 is loading. The other 2 tabs's navigations are delayed. |
| 745 EXPECT_TRUE(tab_manager->IsTabLoadingForTest(contents1_)); |
| 746 EXPECT_FALSE(tab_manager->IsTabLoadingForTest(contents2_)); |
| 747 EXPECT_FALSE(tab_manager->IsTabLoadingForTest(contents3_)); |
| 748 |
| 749 EXPECT_FALSE(tab_manager->IsNavigationDelayedForTest(nav_handle1_.get())); |
| 750 EXPECT_TRUE(tab_manager->IsNavigationDelayedForTest(nav_handle2_.get())); |
| 751 EXPECT_TRUE(tab_manager->IsNavigationDelayedForTest(nav_handle3_.get())); |
| 752 } |
| 753 |
| 754 TEST_F(TabManagerTest, OnDidFinishNavigation) { |
| 755 TabManager* tab_manager = g_browser_process->GetTabManager(); |
| 756 MaybeThrottleNavigations(tab_manager); |
| 757 tab_manager->GetWebContentsData(contents1_) |
| 758 ->DidStartNavigation(nav_handle1_.get()); |
| 759 |
| 760 EXPECT_TRUE(tab_manager->IsNavigationDelayedForTest(nav_handle2_.get())); |
| 761 tab_manager->GetWebContentsData(contents2_) |
| 762 ->DidFinishNavigation(nav_handle2_.get()); |
| 763 EXPECT_FALSE(tab_manager->IsNavigationDelayedForTest(nav_handle2_.get())); |
| 764 } |
| 765 |
| 766 TEST_F(TabManagerTest, OnDidStopLoading) { |
| 767 TabManager* tab_manager = g_browser_process->GetTabManager(); |
| 768 MaybeThrottleNavigations(tab_manager); |
| 769 tab_manager->GetWebContentsData(contents1_) |
| 770 ->DidStartNavigation(nav_handle1_.get()); |
| 771 |
| 772 EXPECT_TRUE(tab_manager->IsTabLoadingForTest(contents1_)); |
| 773 EXPECT_FALSE(tab_manager->IsTabLoadingForTest(contents2_)); |
| 774 EXPECT_TRUE(tab_manager->IsNavigationDelayedForTest(nav_handle2_.get())); |
| 775 |
| 776 // Simulate tab 1 has finished loading. |
| 777 tab_manager->GetWebContentsData(contents1_)->DidStopLoading(); |
| 778 |
| 779 // After tab 1 has finished loading, TabManager starts loading the next tab. |
| 780 EXPECT_FALSE(tab_manager->IsTabLoadingForTest(contents1_)); |
| 781 EXPECT_TRUE(tab_manager->IsTabLoadingForTest(contents2_)); |
| 782 EXPECT_FALSE(tab_manager->IsNavigationDelayedForTest(nav_handle2_.get())); |
| 783 } |
| 784 |
| 785 TEST_F(TabManagerTest, OnWebContentsDestroyed) { |
| 786 TabManager* tab_manager = g_browser_process->GetTabManager(); |
| 787 MaybeThrottleNavigations(tab_manager); |
| 788 tab_manager->GetWebContentsData(contents1_) |
| 789 ->DidStartNavigation(nav_handle1_.get()); |
| 790 |
| 791 // Tab 2 is destroyed when its navigation is still delayed. Its states are |
| 792 // cleaned up. |
| 793 EXPECT_FALSE(tab_manager->IsTabLoadingForTest(contents2_)); |
| 794 EXPECT_TRUE(tab_manager->IsNavigationDelayedForTest(nav_handle2_.get())); |
| 795 tab_manager->OnWebContentsDestroyed(contents2_); |
| 796 EXPECT_FALSE(tab_manager->IsTabLoadingForTest(contents2_)); |
| 797 EXPECT_FALSE(tab_manager->IsNavigationDelayedForTest(nav_handle2_.get())); |
| 798 |
| 799 // Tab 1 is destroyed when it is still loading. Its states are cleaned up and |
| 800 // Tabmanager starts to load the next tab (tab 3). |
| 801 EXPECT_TRUE(tab_manager->IsTabLoadingForTest(contents1_)); |
| 802 EXPECT_FALSE(tab_manager->IsTabLoadingForTest(contents3_)); |
| 803 EXPECT_TRUE(tab_manager->IsNavigationDelayedForTest(nav_handle3_.get())); |
| 804 tab_manager->GetWebContentsData(contents1_)->WebContentsDestroyed(); |
| 805 EXPECT_FALSE(tab_manager->IsTabLoadingForTest(contents1_)); |
| 806 EXPECT_TRUE(tab_manager->IsTabLoadingForTest(contents3_)); |
| 807 EXPECT_FALSE(tab_manager->IsNavigationDelayedForTest(nav_handle3_.get())); |
| 808 } |
| 809 |
| 810 TEST_F(TabManagerTest, OnDelayedTabSelected) { |
| 811 TabManager* tab_manager = g_browser_process->GetTabManager(); |
| 812 MaybeThrottleNavigations(tab_manager); |
| 813 tab_manager->GetWebContentsData(contents1_) |
| 814 ->DidStartNavigation(nav_handle1_.get()); |
| 815 |
| 816 EXPECT_TRUE(tab_manager->IsTabLoadingForTest(contents1_)); |
| 817 EXPECT_FALSE(tab_manager->IsTabLoadingForTest(contents3_)); |
| 818 EXPECT_TRUE(tab_manager->IsNavigationDelayedForTest(nav_handle3_.get())); |
| 819 |
| 820 // Simulate selecting tab 3, which should start loading immediately. |
| 821 tab_manager->ActiveTabChanged( |
| 822 contents1_, contents3_, 2, |
| 823 TabStripModelObserver::CHANGE_REASON_USER_GESTURE); |
| 824 |
| 825 EXPECT_TRUE(tab_manager->IsTabLoadingForTest(contents1_)); |
| 826 EXPECT_TRUE(tab_manager->IsTabLoadingForTest(contents3_)); |
| 827 EXPECT_FALSE(tab_manager->IsNavigationDelayedForTest(nav_handle3_.get())); |
| 828 |
| 829 // Simulate tab 1 has finished loading. TabManager will NOT load the next tab |
| 830 // (tab 2) because tab 3 is still loading. |
| 831 EXPECT_FALSE(tab_manager->IsTabLoadingForTest(contents2_)); |
| 832 EXPECT_TRUE(tab_manager->IsNavigationDelayedForTest(nav_handle2_.get())); |
| 833 tab_manager->GetWebContentsData(contents1_)->DidStopLoading(); |
| 834 EXPECT_FALSE(tab_manager->IsTabLoadingForTest(contents1_)); |
| 835 EXPECT_FALSE(tab_manager->IsTabLoadingForTest(contents2_)); |
| 836 EXPECT_TRUE(tab_manager->IsNavigationDelayedForTest(nav_handle2_.get())); |
| 837 |
| 838 // Simulate tab 3 has finished loading. TabManager starts loading the next tab |
| 839 // (tab 2). |
| 840 tab_manager->GetWebContentsData(contents3_)->DidStopLoading(); |
| 841 EXPECT_FALSE(tab_manager->IsTabLoadingForTest(contents3_)); |
| 842 EXPECT_TRUE(tab_manager->IsTabLoadingForTest(contents2_)); |
| 843 EXPECT_FALSE(tab_manager->IsNavigationDelayedForTest(nav_handle2_.get())); |
| 844 } |
| 845 |
| 695 } // namespace resource_coordinator | 846 } // namespace resource_coordinator |
| OLD | NEW |