1 // Copyright 2014 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.
8 #include "ash/desktop_background/desktop_background_controller.h"
10 #include "base/command_line.h"
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/run_loop.h"
13 #include "base/time/time.h"
14 #include "chrome/browser/chromeos/customization_document.h"
15 #include "chrome/browser/chromeos/customization_wallpaper_downloader.h"
16 #include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h"
17 #include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_test_utils.h"
18 #include "chrome/test/base/in_process_browser_test.h"
19 #include "chrome/test/base/testing_browser_process.h"
20 #include "chromeos/chromeos_switches.h"
21 #include "components/google/core/browser/google_url_tracker.h"
22 #include "net/http/http_response_headers.h"
23 #include "net/http/http_status_code.h"
24 #include "net/url_request/test_url_fetcher_factory.h"
25 #include "net/url_request/url_fetcher_impl.h"
26 #include "testing/gtest/include/gtest/gtest.h"
32 const char kOEMWallpaperURL
[] = "http://somedomain.com/image.png";
34 const char kServicesManifest
[] =
36 " \"version\": \"1.0\","
37 " \"default_wallpaper\": \"http://somedomain.com/image.png\",\n"
38 " \"default_apps\": [\n"
39 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\n"
40 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"\n"
42 " \"localized_content\": {\n"
44 " \"default_apps_folder_name\": \"EN-US OEM Name\"\n"
47 " \"default_apps_folder_name\": \"EN OEM Name\"\n"
50 " \"default_apps_folder_name\": \"Default OEM Name\"\n"
55 // Expected minimal wallpaper download retry interval in milliseconds.
56 const int kDownloadRetryIntervalMS
= 100;
58 class TestWallpaperObserver
: public WallpaperManager::Observer
{
60 explicit TestWallpaperObserver(WallpaperManager
* wallpaper_manager
)
62 wallpaper_manager_(wallpaper_manager
) {
63 DCHECK(wallpaper_manager_
);
64 wallpaper_manager_
->AddObserver(this);
67 virtual ~TestWallpaperObserver() {
68 wallpaper_manager_
->RemoveObserver(this);
71 virtual void OnWallpaperAnimationFinished(const std::string
&) OVERRIDE
{
73 base::MessageLoop::current()->Quit();
76 void WaitForWallpaperAnimationFinished() {
78 base::RunLoop().Run();
83 WallpaperManager
* wallpaper_manager_
;
85 DISALLOW_COPY_AND_ASSIGN(TestWallpaperObserver
);
90 // This is helper class for net::FakeURLFetcherFactory.
91 class TestWallpaperImageURLFetcherCallback
{
93 TestWallpaperImageURLFetcherCallback(
95 const size_t require_retries
,
96 const std::vector
<unsigned char>& jpeg_data_raw
)
98 require_retries_(require_retries
),
100 jpeg_data_
.resize(jpeg_data_raw
.size());
101 std::copy(jpeg_data_raw
.begin(), jpeg_data_raw
.end(), jpeg_data_
.begin());
104 scoped_ptr
<net::FakeURLFetcher
> CreateURLFetcher(
106 net::URLFetcherDelegate
* delegate
,
107 const std::string
& response_data
,
108 net::HttpStatusCode response_code
,
109 net::URLRequestStatus::Status status
) {
110 chromeos::ServicesCustomizationDocument
* customization
=
111 chromeos::ServicesCustomizationDocument::GetInstance();
112 customization
->wallpaper_downloader_for_testing()
113 ->set_retry_delay_for_testing(
114 base::TimeDelta::FromMilliseconds(kDownloadRetryIntervalMS
));
116 attempts_
.push_back(base::TimeTicks::Now());
117 if (attempts_
.size() > 1) {
118 const int retry
= num_attempts() - 1;
119 const base::TimeDelta current_delay
=
120 customization
->wallpaper_downloader_for_testing()
121 ->retry_current_delay_for_testing();
122 const double base_interval
= base::TimeDelta::FromMilliseconds(
123 kDownloadRetryIntervalMS
).InSecondsF();
124 EXPECT_GE(current_delay
,
125 base::TimeDelta::FromSecondsD(base_interval
* retry
* retry
))
126 << "Retry too fast. Actual interval " << current_delay
.InSecondsF()
127 << " seconds, but expected at least " << base_interval
128 << " * (retry=" << retry
129 << " * retry)= " << base_interval
* retry
* retry
<< " seconds.";
131 if (attempts_
.size() > require_retries_
) {
132 response_code
= net::HTTP_OK
;
133 status
= net::URLRequestStatus::SUCCESS
;
134 factory_
->SetFakeResponse(url
, response_data
, response_code
, status
);
136 scoped_ptr
<net::FakeURLFetcher
> fetcher(new net::FakeURLFetcher(
137 url
, delegate
, response_data
, response_code
, status
));
138 scoped_refptr
<net::HttpResponseHeaders
> download_headers
=
139 new net::HttpResponseHeaders(std::string());
140 download_headers
->AddHeader("Content-Type: image/jpeg");
141 fetcher
->set_response_headers(download_headers
);
142 return fetcher
.Pass();
145 void Initialize(net::FakeURLFetcherFactory
* factory
) {
147 factory_
->SetFakeResponse(url_
,
149 net::HTTP_INTERNAL_SERVER_ERROR
,
150 net::URLRequestStatus::FAILED
);
153 size_t num_attempts() const { return attempts_
.size(); }
157 // Respond with OK on required retry attempt.
158 const size_t require_retries_
;
159 net::FakeURLFetcherFactory
* factory_
;
160 std::vector
<base::TimeTicks
> attempts_
;
161 std::string jpeg_data_
;
163 DISALLOW_COPY_AND_ASSIGN(TestWallpaperImageURLFetcherCallback
);
166 // This implements fake remote source for wallpaper image.
167 // JPEG image is created here and served to CustomizationWallpaperDownloader
168 // via net::FakeURLFetcher.
169 class WallpaperImageFetcherFactory
{
171 WallpaperImageFetcherFactory(const GURL
& url
,
175 const size_t require_retries
) {
176 // ASSERT_TRUE() cannot be directly used in constructor.
177 Initialize(url
, width
, height
, color
, require_retries
);
180 ~WallpaperImageFetcherFactory() {
181 fetcher_factory_
.reset();
182 net::URLFetcherImpl::set_factory(fallback_fetcher_factory_
.get());
183 fallback_fetcher_factory_
.reset();
186 size_t num_attempts() const { return url_callback_
->num_attempts(); }
189 void Initialize(const GURL
& url
,
193 const size_t require_retries
) {
194 std::vector
<unsigned char> oem_wallpaper_
;
195 ASSERT_TRUE(wallpaper_manager_test_utils::CreateJPEGImage(
196 width
, height
, color
, &oem_wallpaper_
));
198 url_callback_
.reset(new TestWallpaperImageURLFetcherCallback(
199 url
, require_retries
, oem_wallpaper_
));
200 fallback_fetcher_factory_
.reset(new net::TestURLFetcherFactory
);
201 net::URLFetcherImpl::set_factory(NULL
);
202 fetcher_factory_
.reset(new net::FakeURLFetcherFactory(
203 fallback_fetcher_factory_
.get(),
204 base::Bind(&TestWallpaperImageURLFetcherCallback::CreateURLFetcher
,
205 base::Unretained(url_callback_
.get()))));
206 url_callback_
->Initialize(fetcher_factory_
.get());
209 scoped_ptr
<TestWallpaperImageURLFetcherCallback
> url_callback_
;
211 // Use a test factory as a fallback so we don't have to deal with other
213 scoped_ptr
<net::TestURLFetcherFactory
> fallback_fetcher_factory_
;
214 scoped_ptr
<net::FakeURLFetcherFactory
> fetcher_factory_
;
216 DISALLOW_COPY_AND_ASSIGN(WallpaperImageFetcherFactory
);
219 class CustomizationWallpaperDownloaderBrowserTest
220 : public InProcessBrowserTest
{
222 CustomizationWallpaperDownloaderBrowserTest()
227 virtual ~CustomizationWallpaperDownloaderBrowserTest() {}
229 virtual void SetUpOnMainThread() OVERRIDE
{
230 controller_
= ash::Shell::GetInstance()->desktop_background_controller();
231 local_state_
= g_browser_process
->local_state();
234 virtual void SetUpCommandLine(CommandLine
* command_line
) OVERRIDE
{
235 command_line
->AppendSwitch(chromeos::switches::kLoginManager
);
236 command_line
->AppendSwitchASCII(chromeos::switches::kLoginProfile
, "user");
239 virtual void CleanUpOnMainThread() OVERRIDE
{ controller_
= NULL
; }
242 void CreateCmdlineWallpapers() {
243 cmdline_wallpaper_dir_
.reset(new base::ScopedTempDir
);
244 ASSERT_TRUE(cmdline_wallpaper_dir_
->CreateUniqueTempDir());
245 wallpaper_manager_test_utils::CreateCmdlineWallpapers(
246 *cmdline_wallpaper_dir_
, &wallpaper_manager_command_line_
);
249 ash::DesktopBackgroundController
* controller_
;
250 PrefService
* local_state_
;
251 scoped_ptr
<base::CommandLine
> wallpaper_manager_command_line_
;
253 // Directory created by CreateCmdlineWallpapersAndSetFlags() to store default
255 scoped_ptr
<base::ScopedTempDir
> cmdline_wallpaper_dir_
;
258 DISALLOW_COPY_AND_ASSIGN(CustomizationWallpaperDownloaderBrowserTest
);
261 IN_PROC_BROWSER_TEST_F(CustomizationWallpaperDownloaderBrowserTest
,
262 OEMWallpaperIsPresent
) {
263 CreateCmdlineWallpapers();
264 WallpaperManager::Get()->SetDefaultWallpaperNow(std::string());
265 wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
266 EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor(
267 controller_
->GetWallpaper(),
268 wallpaper_manager_test_utils::kSmallDefaultWallpaperColor
));
270 WallpaperImageFetcherFactory
url_factory(
271 GURL(kOEMWallpaperURL
),
272 wallpaper_manager_test_utils::kWallpaperSize
,
273 wallpaper_manager_test_utils::kWallpaperSize
,
274 wallpaper_manager_test_utils::kCustomWallpaperColor
,
275 0 /* require_retries */);
277 TestWallpaperObserver
observer(WallpaperManager::Get());
278 chromeos::ServicesCustomizationDocument
* customization
=
279 chromeos::ServicesCustomizationDocument::GetInstance();
281 customization
->LoadManifestFromString(std::string(kServicesManifest
)));
283 observer
.WaitForWallpaperAnimationFinished();
284 EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor(
285 controller_
->GetWallpaper(),
286 wallpaper_manager_test_utils::kCustomWallpaperColor
));
287 EXPECT_EQ(1U, url_factory
.num_attempts());
290 IN_PROC_BROWSER_TEST_F(CustomizationWallpaperDownloaderBrowserTest
,
291 OEMWallpaperRetryFetch
) {
292 CreateCmdlineWallpapers();
293 WallpaperManager::Get()->SetDefaultWallpaperNow(std::string());
294 wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
295 EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor(
296 controller_
->GetWallpaper(),
297 wallpaper_manager_test_utils::kSmallDefaultWallpaperColor
));
299 WallpaperImageFetcherFactory
url_factory(
300 GURL(kOEMWallpaperURL
),
301 wallpaper_manager_test_utils::kWallpaperSize
,
302 wallpaper_manager_test_utils::kWallpaperSize
,
303 wallpaper_manager_test_utils::kCustomWallpaperColor
,
304 1 /* require_retries */);
306 TestWallpaperObserver
observer(WallpaperManager::Get());
307 chromeos::ServicesCustomizationDocument
* customization
=
308 chromeos::ServicesCustomizationDocument::GetInstance();
310 customization
->LoadManifestFromString(std::string(kServicesManifest
)));
312 observer
.WaitForWallpaperAnimationFinished();
313 EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor(
314 controller_
->GetWallpaper(),
315 wallpaper_manager_test_utils::kCustomWallpaperColor
));
317 EXPECT_EQ(2U, url_factory
.num_attempts());
320 } // namespace chromeos