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/ash/launcher/launcher_favicon_loader.h" 6 7 #include "ash/launcher/launcher_types.h" 8 #include "base/memory/scoped_ptr.h" 9 #include "base/strings/stringprintf.h" 10 #include "chrome/browser/ui/browser.h" 11 #include "chrome/browser/ui/tabs/tab_strip_model.h" 12 #include "chrome/test/base/in_process_browser_test.h" 13 #include "chrome/test/base/ui_test_utils.h" 14 #include "content/public/browser/web_contents.h" 15 #include "content/public/browser/web_contents_observer.h" 16 17 using content::WebContents; 18 using content::WebContentsObserver; 19 20 namespace { 21 22 // Observer class to determine when favicons have completed loading. 23 class ContentsObserver : public WebContentsObserver { 24 public: 25 explicit ContentsObserver(WebContents* web_contents) 26 : WebContentsObserver(web_contents), 27 loaded_(false), 28 got_favicons_(false) { 29 } 30 31 virtual ~ContentsObserver() {} 32 33 void Reset() { 34 got_favicons_ = false; 35 } 36 37 bool loaded() const { return loaded_; } 38 bool got_favicons() const { return got_favicons_; } 39 40 // WebContentsObserver overrides. 41 virtual void DidFinishLoad( 42 int64 frame_id, 43 const GURL& validated_url, 44 bool is_main_frame, 45 content::RenderViewHost* render_view_host) OVERRIDE { 46 loaded_ = true; 47 } 48 49 virtual void DidUpdateFaviconURL(int32 page_id, 50 const std::vector<content::FaviconURL>& candidates) OVERRIDE { 51 if (!candidates.empty()) 52 got_favicons_ = true; 53 } 54 55 private: 56 bool loaded_; 57 bool got_favicons_; 58 }; 59 60 } // namespace 61 62 class LauncherFaviconLoaderBrowsertest 63 : public InProcessBrowserTest, 64 public LauncherFaviconLoader::Delegate { 65 public: 66 LauncherFaviconLoaderBrowsertest() : favicon_updated_(false) { 67 } 68 69 virtual ~LauncherFaviconLoaderBrowsertest() { 70 } 71 72 virtual void SetUpOnMainThread() OVERRIDE { 73 WebContents* web_contents = 74 browser()->tab_strip_model()->GetActiveWebContents(); 75 contents_observer_.reset(new ContentsObserver(web_contents)); 76 favicon_loader_.reset(new LauncherFaviconLoader(this, web_contents)); 77 } 78 79 // LauncherFaviconLoader::Delegate overrides: 80 virtual void FaviconUpdated() OVERRIDE { 81 favicon_updated_ = true; 82 } 83 84 protected: 85 bool NavigateTo(const char* url) { 86 std::string url_path = base::StringPrintf("files/ash/launcher/%s", url); 87 ui_test_utils::NavigateToURL(browser(), test_server()->GetURL(url_path)); 88 return true; 89 } 90 91 bool WaitForContentsLoaded() { 92 const int64 max_seconds = 10; 93 base::Time start_time = base::Time::Now(); 94 while (!(contents_observer_->loaded() && 95 contents_observer_->got_favicons())) { 96 content::RunAllPendingInMessageLoop(); 97 base::TimeDelta delta = base::Time::Now() - start_time; 98 if (delta.InSeconds() >= max_seconds) { 99 LOG(ERROR) << " WaitForContentsLoaded timed out."; 100 return false; 101 } 102 } 103 return true; 104 } 105 106 bool WaitForFaviconUpdated() { 107 const int64 max_seconds = 10; 108 base::Time start_time = base::Time::Now(); 109 while (favicon_loader_->HasPendingDownloads()) { 110 content::RunAllPendingInMessageLoop(); 111 base::TimeDelta delta = base::Time::Now() - start_time; 112 if (delta.InSeconds() >= max_seconds) { 113 LOG(ERROR) << " WaitForFaviconDownlads timed out."; 114 return false; 115 } 116 } 117 return true; 118 } 119 120 void ResetDownloads() { 121 contents_observer_->Reset(); 122 } 123 124 bool favicon_updated_; 125 scoped_ptr<ContentsObserver> contents_observer_; 126 scoped_ptr<LauncherFaviconLoader> favicon_loader_; 127 128 private: 129 DISALLOW_COPY_AND_ASSIGN(LauncherFaviconLoaderBrowsertest); 130 }; 131 132 IN_PROC_BROWSER_TEST_F(LauncherFaviconLoaderBrowsertest, SmallLauncherIcon) { 133 ASSERT_TRUE(test_server()->Start()); 134 ASSERT_TRUE(NavigateTo("launcher-smallfavicon.html")); 135 EXPECT_TRUE(WaitForContentsLoaded()); 136 EXPECT_TRUE(WaitForFaviconUpdated()); 137 138 // No large favicons specified, bitmap should be empty. 139 EXPECT_TRUE(favicon_loader_->GetFavicon().empty()); 140 } 141 142 IN_PROC_BROWSER_TEST_F(LauncherFaviconLoaderBrowsertest, LargeLauncherIcon) { 143 ASSERT_TRUE(test_server()->Start()); 144 ASSERT_TRUE(NavigateTo("launcher-largefavicon.html")); 145 EXPECT_TRUE(WaitForContentsLoaded()); 146 EXPECT_TRUE(WaitForFaviconUpdated()); 147 148 EXPECT_FALSE(favicon_loader_->GetFavicon().empty()); 149 EXPECT_EQ(128, favicon_loader_->GetFavicon().height()); 150 } 151 152 IN_PROC_BROWSER_TEST_F(LauncherFaviconLoaderBrowsertest, ManyLauncherIcons) { 153 ASSERT_TRUE(test_server()->Start()); 154 ASSERT_TRUE(NavigateTo("launcher-manyfavicon.html")); 155 EXPECT_TRUE(WaitForContentsLoaded()); 156 EXPECT_TRUE(WaitForFaviconUpdated()); 157 158 EXPECT_FALSE(favicon_loader_->GetFavicon().empty()); 159 // When multiple favicons are present, the correctly sized icon should be 160 // chosen. The icons are sized assuming ash::kLauncherPreferredSize < 128. 161 EXPECT_GT(128, ash::kLauncherPreferredSize); 162 EXPECT_EQ(48, favicon_loader_->GetFavicon().height()); 163 } 164 165 IN_PROC_BROWSER_TEST_F(LauncherFaviconLoaderBrowsertest, ChangeLauncherIcons) { 166 ASSERT_TRUE(test_server()->Start()); 167 ASSERT_TRUE(NavigateTo("launcher-manyfavicon.html")); 168 EXPECT_TRUE(WaitForContentsLoaded()); 169 EXPECT_TRUE(WaitForFaviconUpdated()); 170 171 EXPECT_FALSE(favicon_loader_->GetFavicon().empty()); 172 EXPECT_EQ(48, favicon_loader_->GetFavicon().height()); 173 ASSERT_NO_FATAL_FAILURE(ResetDownloads()); 174 175 ASSERT_TRUE(NavigateTo("launcher-smallfavicon.html")); 176 ASSERT_TRUE(WaitForContentsLoaded()); 177 EXPECT_TRUE(WaitForFaviconUpdated()); 178 179 EXPECT_TRUE(favicon_loader_->GetFavicon().empty()); 180 ASSERT_NO_FATAL_FAILURE(ResetDownloads()); 181 182 ASSERT_TRUE(NavigateTo("launcher-largefavicon.html")); 183 ASSERT_TRUE(WaitForContentsLoaded()); 184 EXPECT_TRUE(WaitForFaviconUpdated()); 185 186 EXPECT_FALSE(favicon_loader_->GetFavicon().empty()); 187 EXPECT_EQ(128, favicon_loader_->GetFavicon().height()); 188 } 189