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/customization_document.h"
15 #include "chrome/browser/chromeos/customization/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 "net/http/http_response_headers.h"
22 #include "net/http/http_status_code.h"
23 #include "net/url_request/test_url_fetcher_factory.h"
24 #include "net/url_request/url_fetcher_impl.h"
25 #include "testing/gtest/include/gtest/gtest.h"
31 const char kOEMWallpaperURL
[] = "http://somedomain.com/image.png";
33 const char kServicesManifest
[] =
35 " \"version\": \"1.0\","
36 " \"default_wallpaper\": \"http://somedomain.com/image.png\",\n"
37 " \"default_apps\": [\n"
38 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\n"
39 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"\n"
41 " \"localized_content\": {\n"
43 " \"default_apps_folder_name\": \"EN-US OEM Name\"\n"
46 " \"default_apps_folder_name\": \"EN OEM Name\"\n"
49 " \"default_apps_folder_name\": \"Default OEM Name\"\n"
54 // Expected minimal wallpaper download retry interval in milliseconds.
55 const int kDownloadRetryIntervalMS
= 100;
57 class TestWallpaperObserver
: public WallpaperManager::Observer
{
59 explicit TestWallpaperObserver(WallpaperManager
* wallpaper_manager
)
61 wallpaper_manager_(wallpaper_manager
) {
62 DCHECK(wallpaper_manager_
);
63 wallpaper_manager_
->AddObserver(this);
66 ~TestWallpaperObserver() override
{
67 wallpaper_manager_
->RemoveObserver(this);
70 void OnWallpaperAnimationFinished(const std::string
&) override
{
72 base::MessageLoop::current()->Quit();
75 void WaitForWallpaperAnimationFinished() {
77 base::RunLoop().Run();
82 WallpaperManager
* wallpaper_manager_
;
84 DISALLOW_COPY_AND_ASSIGN(TestWallpaperObserver
);
89 // This is helper class for net::FakeURLFetcherFactory.
90 class TestWallpaperImageURLFetcherCallback
{
92 TestWallpaperImageURLFetcherCallback(
94 const size_t require_retries
,
95 const std::vector
<unsigned char>& jpeg_data_raw
)
97 require_retries_(require_retries
),
99 jpeg_data_
.resize(jpeg_data_raw
.size());
100 std::copy(jpeg_data_raw
.begin(), jpeg_data_raw
.end(), jpeg_data_
.begin());
103 scoped_ptr
<net::FakeURLFetcher
> CreateURLFetcher(
105 net::URLFetcherDelegate
* delegate
,
106 const std::string
& response_data
,
107 net::HttpStatusCode response_code
,
108 net::URLRequestStatus::Status status
) {
109 chromeos::ServicesCustomizationDocument
* customization
=
110 chromeos::ServicesCustomizationDocument::GetInstance();
111 customization
->wallpaper_downloader_for_testing()
112 ->set_retry_delay_for_testing(
113 base::TimeDelta::FromMilliseconds(kDownloadRetryIntervalMS
));
115 attempts_
.push_back(base::TimeTicks::Now());
116 if (attempts_
.size() > 1) {
117 const int retry
= num_attempts() - 1;
118 const base::TimeDelta current_delay
=
119 customization
->wallpaper_downloader_for_testing()
120 ->retry_current_delay_for_testing();
121 const double base_interval
= base::TimeDelta::FromMilliseconds(
122 kDownloadRetryIntervalMS
).InSecondsF();
123 EXPECT_GE(current_delay
,
124 base::TimeDelta::FromSecondsD(base_interval
* retry
* retry
))
125 << "Retry too fast. Actual interval " << current_delay
.InSecondsF()
126 << " seconds, but expected at least " << base_interval
127 << " * (retry=" << retry
128 << " * retry)= " << base_interval
* retry
* retry
<< " seconds.";
130 if (attempts_
.size() > require_retries_
) {
131 response_code
= net::HTTP_OK
;
132 status
= net::URLRequestStatus::SUCCESS
;
133 factory_
->SetFakeResponse(url
, response_data
, response_code
, status
);
135 scoped_ptr
<net::FakeURLFetcher
> fetcher(new net::FakeURLFetcher(
136 url
, delegate
, response_data
, response_code
, status
));
137 scoped_refptr
<net::HttpResponseHeaders
> download_headers
=
138 new net::HttpResponseHeaders(std::string());
139 download_headers
->AddHeader("Content-Type: image/jpeg");
140 fetcher
->set_response_headers(download_headers
);
141 return fetcher
.Pass();
144 void Initialize(net::FakeURLFetcherFactory
* factory
) {
146 factory_
->SetFakeResponse(url_
,
148 net::HTTP_INTERNAL_SERVER_ERROR
,
149 net::URLRequestStatus::FAILED
);
152 size_t num_attempts() const { return attempts_
.size(); }
156 // Respond with OK on required retry attempt.
157 const size_t require_retries_
;
158 net::FakeURLFetcherFactory
* factory_
;
159 std::vector
<base::TimeTicks
> attempts_
;
160 std::string jpeg_data_
;
162 DISALLOW_COPY_AND_ASSIGN(TestWallpaperImageURLFetcherCallback
);
165 // This implements fake remote source for wallpaper image.
166 // JPEG image is created here and served to CustomizationWallpaperDownloader
167 // via net::FakeURLFetcher.
168 class WallpaperImageFetcherFactory
{
170 WallpaperImageFetcherFactory(const GURL
& url
,
174 const size_t require_retries
) {
175 // ASSERT_TRUE() cannot be directly used in constructor.
176 Initialize(url
, width
, height
, color
, require_retries
);
179 ~WallpaperImageFetcherFactory() {
180 fetcher_factory_
.reset();
181 net::URLFetcherImpl::set_factory(fallback_fetcher_factory_
.get());
182 fallback_fetcher_factory_
.reset();
185 size_t num_attempts() const { return url_callback_
->num_attempts(); }
188 void Initialize(const GURL
& url
,
192 const size_t require_retries
) {
193 std::vector
<unsigned char> oem_wallpaper_
;
194 ASSERT_TRUE(wallpaper_manager_test_utils::CreateJPEGImage(
195 width
, height
, color
, &oem_wallpaper_
));
197 url_callback_
.reset(new TestWallpaperImageURLFetcherCallback(
198 url
, require_retries
, oem_wallpaper_
));
199 fallback_fetcher_factory_
.reset(new net::TestURLFetcherFactory
);
200 net::URLFetcherImpl::set_factory(NULL
);
201 fetcher_factory_
.reset(new net::FakeURLFetcherFactory(
202 fallback_fetcher_factory_
.get(),
203 base::Bind(&TestWallpaperImageURLFetcherCallback::CreateURLFetcher
,
204 base::Unretained(url_callback_
.get()))));
205 url_callback_
->Initialize(fetcher_factory_
.get());
208 scoped_ptr
<TestWallpaperImageURLFetcherCallback
> url_callback_
;
210 // Use a test factory as a fallback so we don't have to deal with other
212 scoped_ptr
<net::TestURLFetcherFactory
> fallback_fetcher_factory_
;
213 scoped_ptr
<net::FakeURLFetcherFactory
> fetcher_factory_
;
215 DISALLOW_COPY_AND_ASSIGN(WallpaperImageFetcherFactory
);
218 class CustomizationWallpaperDownloaderBrowserTest
219 : public InProcessBrowserTest
{
221 CustomizationWallpaperDownloaderBrowserTest()
226 ~CustomizationWallpaperDownloaderBrowserTest() override
{}
228 void SetUpOnMainThread() override
{
229 controller_
= ash::Shell::GetInstance()->desktop_background_controller();
230 local_state_
= g_browser_process
->local_state();
233 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
234 command_line
->AppendSwitch(chromeos::switches::kLoginManager
);
235 command_line
->AppendSwitchASCII(chromeos::switches::kLoginProfile
, "user");
238 void TearDownOnMainThread() override
{ controller_
= NULL
; }
241 void CreateCmdlineWallpapers() {
242 cmdline_wallpaper_dir_
.reset(new base::ScopedTempDir
);
243 ASSERT_TRUE(cmdline_wallpaper_dir_
->CreateUniqueTempDir());
244 wallpaper_manager_test_utils::CreateCmdlineWallpapers(
245 *cmdline_wallpaper_dir_
, &wallpaper_manager_command_line_
);
248 ash::DesktopBackgroundController
* controller_
;
249 PrefService
* local_state_
;
250 scoped_ptr
<base::CommandLine
> wallpaper_manager_command_line_
;
252 // Directory created by CreateCmdlineWallpapersAndSetFlags() to store default
254 scoped_ptr
<base::ScopedTempDir
> cmdline_wallpaper_dir_
;
257 DISALLOW_COPY_AND_ASSIGN(CustomizationWallpaperDownloaderBrowserTest
);
260 IN_PROC_BROWSER_TEST_F(CustomizationWallpaperDownloaderBrowserTest
,
261 OEMWallpaperIsPresent
) {
262 CreateCmdlineWallpapers();
263 WallpaperManager::Get()->SetDefaultWallpaperNow(std::string());
264 wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
265 EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor(
266 controller_
->GetWallpaper(),
267 wallpaper_manager_test_utils::kSmallDefaultWallpaperColor
));
269 WallpaperImageFetcherFactory
url_factory(
270 GURL(kOEMWallpaperURL
),
271 wallpaper_manager_test_utils::kWallpaperSize
,
272 wallpaper_manager_test_utils::kWallpaperSize
,
273 wallpaper_manager_test_utils::kCustomWallpaperColor
,
274 0 /* require_retries */);
276 TestWallpaperObserver
observer(WallpaperManager::Get());
277 chromeos::ServicesCustomizationDocument
* customization
=
278 chromeos::ServicesCustomizationDocument::GetInstance();
280 customization
->LoadManifestFromString(std::string(kServicesManifest
)));
282 observer
.WaitForWallpaperAnimationFinished();
283 EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor(
284 controller_
->GetWallpaper(),
285 wallpaper_manager_test_utils::kCustomWallpaperColor
));
286 EXPECT_EQ(1U, url_factory
.num_attempts());
289 IN_PROC_BROWSER_TEST_F(CustomizationWallpaperDownloaderBrowserTest
,
290 OEMWallpaperRetryFetch
) {
291 CreateCmdlineWallpapers();
292 WallpaperManager::Get()->SetDefaultWallpaperNow(std::string());
293 wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
294 EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor(
295 controller_
->GetWallpaper(),
296 wallpaper_manager_test_utils::kSmallDefaultWallpaperColor
));
298 WallpaperImageFetcherFactory
url_factory(
299 GURL(kOEMWallpaperURL
),
300 wallpaper_manager_test_utils::kWallpaperSize
,
301 wallpaper_manager_test_utils::kWallpaperSize
,
302 wallpaper_manager_test_utils::kCustomWallpaperColor
,
303 1 /* require_retries */);
305 TestWallpaperObserver
observer(WallpaperManager::Get());
306 chromeos::ServicesCustomizationDocument
* customization
=
307 chromeos::ServicesCustomizationDocument::GetInstance();
309 customization
->LoadManifestFromString(std::string(kServicesManifest
)));
311 observer
.WaitForWallpaperAnimationFinished();
312 EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor(
313 controller_
->GetWallpaper(),
314 wallpaper_manager_test_utils::kCustomWallpaperColor
));
316 EXPECT_EQ(2U, url_factory
.num_attempts());
319 } // namespace chromeos