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.
5 #include "chrome/browser/ui/ash/launcher/launcher_favicon_loader.h"
7 #include "ash/shelf/shelf_constants.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 #include "third_party/skia/include/core/SkBitmap.h"
18 using content::WebContents;
19 using content::WebContentsObserver;
23 // Observer class to determine when favicons have completed loading.
24 class ContentsObserver : public WebContentsObserver {
26 explicit ContentsObserver(WebContents* web_contents)
27 : WebContentsObserver(web_contents),
29 got_favicons_(false) {
32 virtual ~ContentsObserver() {}
35 got_favicons_ = false;
38 bool loaded() const { return loaded_; }
39 bool got_favicons() const { return got_favicons_; }
41 // WebContentsObserver overrides.
42 virtual void DidFinishLoad(content::RenderFrameHost* render_frame_host,
43 const GURL& validated_url) override {
47 virtual void DidUpdateFaviconURL(
48 const std::vector<content::FaviconURL>& candidates) override {
49 if (!candidates.empty())
60 class LauncherFaviconLoaderBrowsertest
61 : public InProcessBrowserTest,
62 public LauncherFaviconLoader::Delegate {
64 LauncherFaviconLoaderBrowsertest() : favicon_updated_(false) {
67 virtual ~LauncherFaviconLoaderBrowsertest() {
70 virtual void SetUpOnMainThread() override {
71 WebContents* web_contents =
72 browser()->tab_strip_model()->GetActiveWebContents();
73 contents_observer_.reset(new ContentsObserver(web_contents));
74 favicon_loader_.reset(new LauncherFaviconLoader(this, web_contents));
77 // LauncherFaviconLoader::Delegate overrides:
78 virtual void FaviconUpdated() override {
79 favicon_updated_ = true;
83 bool NavigateTo(const char* url) {
84 std::string url_path = base::StringPrintf("files/ash/launcher/%s", url);
85 ui_test_utils::NavigateToURL(browser(), test_server()->GetURL(url_path));
89 bool WaitForContentsLoaded() {
90 const int64 max_seconds = 10;
91 base::Time start_time = base::Time::Now();
92 while (!(contents_observer_->loaded() &&
93 contents_observer_->got_favicons())) {
94 content::RunAllPendingInMessageLoop();
95 base::TimeDelta delta = base::Time::Now() - start_time;
96 if (delta.InSeconds() >= max_seconds) {
97 LOG(ERROR) << " WaitForContentsLoaded timed out.";
104 bool WaitForFaviconUpdated() {
105 const int64 max_seconds = 10;
106 base::Time start_time = base::Time::Now();
107 while (favicon_loader_->HasPendingDownloads()) {
108 content::RunAllPendingInMessageLoop();
109 base::TimeDelta delta = base::Time::Now() - start_time;
110 if (delta.InSeconds() >= max_seconds) {
111 LOG(ERROR) << " WaitForFaviconDownlads timed out.";
118 void ResetDownloads() {
119 contents_observer_->Reset();
122 bool favicon_updated_;
123 scoped_ptr<ContentsObserver> contents_observer_;
124 scoped_ptr<LauncherFaviconLoader> favicon_loader_;
127 DISALLOW_COPY_AND_ASSIGN(LauncherFaviconLoaderBrowsertest);
130 IN_PROC_BROWSER_TEST_F(LauncherFaviconLoaderBrowsertest, SmallLauncherIcon) {
131 ASSERT_TRUE(test_server()->Start());
132 ASSERT_TRUE(NavigateTo("launcher-smallfavicon.html"));
133 EXPECT_TRUE(WaitForContentsLoaded());
134 EXPECT_TRUE(WaitForFaviconUpdated());
136 // No large favicons specified, bitmap should be empty.
137 EXPECT_TRUE(favicon_loader_->GetFavicon().empty());
140 IN_PROC_BROWSER_TEST_F(LauncherFaviconLoaderBrowsertest, LargeLauncherIcon) {
141 ASSERT_TRUE(test_server()->Start());
142 ASSERT_TRUE(NavigateTo("launcher-largefavicon.html"));
143 EXPECT_TRUE(WaitForContentsLoaded());
144 EXPECT_TRUE(WaitForFaviconUpdated());
146 EXPECT_FALSE(favicon_loader_->GetFavicon().empty());
147 EXPECT_EQ(128, favicon_loader_->GetFavicon().height());
150 IN_PROC_BROWSER_TEST_F(LauncherFaviconLoaderBrowsertest, ManyLauncherIcons) {
151 ASSERT_TRUE(test_server()->Start());
152 ASSERT_TRUE(NavigateTo("launcher-manyfavicon.html"));
153 EXPECT_TRUE(WaitForContentsLoaded());
154 EXPECT_TRUE(WaitForFaviconUpdated());
156 EXPECT_FALSE(favicon_loader_->GetFavicon().empty());
157 // When multiple favicons are present, the correctly sized icon should be
158 // chosen. The icons are sized assuming ash::kShelfSize < 128.
159 EXPECT_GT(128, ash::kShelfSize);
160 EXPECT_EQ(48, favicon_loader_->GetFavicon().height());
163 IN_PROC_BROWSER_TEST_F(LauncherFaviconLoaderBrowsertest, ChangeLauncherIcons) {
164 ASSERT_TRUE(test_server()->Start());
165 ASSERT_TRUE(NavigateTo("launcher-manyfavicon.html"));
166 EXPECT_TRUE(WaitForContentsLoaded());
167 EXPECT_TRUE(WaitForFaviconUpdated());
169 EXPECT_FALSE(favicon_loader_->GetFavicon().empty());
170 EXPECT_EQ(48, favicon_loader_->GetFavicon().height());
171 ASSERT_NO_FATAL_FAILURE(ResetDownloads());
173 ASSERT_TRUE(NavigateTo("launcher-smallfavicon.html"));
174 ASSERT_TRUE(WaitForContentsLoaded());
175 EXPECT_TRUE(WaitForFaviconUpdated());
177 EXPECT_TRUE(favicon_loader_->GetFavicon().empty());
178 ASSERT_NO_FATAL_FAILURE(ResetDownloads());
180 ASSERT_TRUE(NavigateTo("launcher-largefavicon.html"));
181 ASSERT_TRUE(WaitForContentsLoaded());
182 EXPECT_TRUE(WaitForFaviconUpdated());
184 EXPECT_FALSE(favicon_loader_->GetFavicon().empty());
185 EXPECT_EQ(128, favicon_loader_->GetFavicon().height());