Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / login / wallpaper_manager_policy_browsertest.cc
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.
4
5 #include <string>
6 #include <vector>
7
8 #include "ash/desktop_background/desktop_background_controller.h"
9 #include "ash/desktop_background/desktop_background_controller_observer.h"
10 #include "ash/shell.h"
11 #include "base/basictypes.h"
12 #include "base/command_line.h"
13 #include "base/compiler_specific.h"
14 #include "base/file_util.h"
15 #include "base/files/file_path.h"
16 #include "base/json/json_writer.h"
17 #include "base/memory/scoped_ptr.h"
18 #include "base/path_service.h"
19 #include "base/run_loop.h"
20 #include "chrome/browser/chromeos/login/login_display_host_impl.h"
21 #include "chrome/browser/chromeos/login/login_manager_test.h"
22 #include "chrome/browser/chromeos/login/startup_utils.h"
23 #include "chrome/browser/chromeos/login/user.h"
24 #include "chrome/browser/chromeos/login/user_manager.h"
25 #include "chrome/browser/chromeos/login/wallpaper_manager.h"
26 #include "chrome/browser/chromeos/policy/cloud_external_data_manager_base_test_util.h"
27 #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h"
28 #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_factory_chromeos.h"
29 #include "chrome/browser/profiles/profile.h"
30 #include "chrome/common/chrome_paths.h"
31 #include "chrome/common/chrome_switches.h"
32 #include "chromeos/chromeos_paths.h"
33 #include "chromeos/chromeos_switches.h"
34 #include "chromeos/dbus/cryptohome_client.h"
35 #include "chromeos/dbus/dbus_thread_manager.h"
36 #include "chromeos/dbus/fake_dbus_thread_manager.h"
37 #include "chromeos/dbus/fake_session_manager_client.h"
38 #include "chromeos/dbus/session_manager_client.h"
39 #include "components/policy/core/common/cloud/cloud_policy_core.h"
40 #include "components/policy/core/common/cloud/cloud_policy_store.h"
41 #include "components/policy/core/common/cloud/cloud_policy_validator.h"
42 #include "components/policy/core/common/cloud/policy_builder.h"
43 #include "content/public/test/browser_test_utils.h"
44 #include "crypto/rsa_private_key.h"
45 #include "net/test/embedded_test_server/embedded_test_server.h"
46 #include "policy/proto/cloud_policy.pb.h"
47 #include "testing/gtest/include/gtest/gtest.h"
48 #include "third_party/skia/include/core/SkBitmap.h"
49 #include "third_party/skia/include/core/SkColor.h"
50 #include "ui/gfx/image/image_skia.h"
51 #include "url/gurl.h"
52
53 namespace chromeos {
54
55 namespace {
56
57 const char kTestUsers[2][19] = { "test-0@example.com", "test-1@example.com" };
58
59 const char kRedImageFileName[] = "chromeos/wallpapers/red.jpg";
60 const char kGreenImageFileName[] = "chromeos/wallpapers/green.jpg";
61 const char kBlueImageFileName[] = "chromeos/wallpapers/blue.jpg";
62
63 const SkColor kRedImageColor = SkColorSetARGB(255, 199, 6, 7);
64 const SkColor kGreenImageColor = SkColorSetARGB(255, 38, 196, 15);
65
66 policy::CloudPolicyStore* GetStoreForUser(const User* user) {
67   Profile* profile = UserManager::Get()->GetProfileByUser(user);
68   if (!profile) {
69     ADD_FAILURE();
70     return NULL;
71   }
72   policy::UserCloudPolicyManagerChromeOS* policy_manager =
73       policy::UserCloudPolicyManagerFactoryChromeOS::GetForProfile(profile);
74   if (!policy_manager) {
75     ADD_FAILURE();
76     return NULL;
77   }
78   return policy_manager->core()->store();
79 }
80
81 // Compute the average ARGB color of |bitmap|.
82 SkColor ComputeAverageColor(const SkBitmap& bitmap) {
83   if (bitmap.empty() || bitmap.width() < 1 || bitmap.height() < 1) {
84     ADD_FAILURE() << "Empty or invalid bitmap.";
85     return SkColorSetARGB(0, 0, 0, 0);
86   }
87   if (bitmap.isNull()) {
88     ADD_FAILURE() << "Bitmap has no pixelref.";
89     return SkColorSetARGB(0, 0, 0, 0);
90   }
91   if (bitmap.config() == SkBitmap::kNo_Config) {
92     ADD_FAILURE() << "Bitmap has not been configured.";
93     return SkColorSetARGB(0, 0, 0, 0);
94   }
95   uint64 a = 0, r = 0, g = 0, b = 0;
96   bitmap.lockPixels();
97   for (int x = 0; x < bitmap.width(); ++x) {
98     for (int y = 0; y < bitmap.height(); ++y) {
99       const SkColor color = bitmap.getColor(x, y);
100       a += SkColorGetA(color);
101       r += SkColorGetR(color);
102       g += SkColorGetG(color);
103       b += SkColorGetB(color);
104     }
105   }
106   bitmap.unlockPixels();
107   uint64 pixel_number = bitmap.width() * bitmap.height();
108   return SkColorSetARGB((a + pixel_number / 2) / pixel_number,
109                         (r + pixel_number / 2) / pixel_number,
110                         (g + pixel_number / 2) / pixel_number,
111                         (b + pixel_number / 2) / pixel_number);
112 }
113
114 // Obtain background image and return its average ARGB color.
115 SkColor GetAverageBackgroundColor() {
116   const gfx::ImageSkia image =
117       ash::Shell::GetInstance()->desktop_background_controller()->
118       GetWallpaper();
119
120   const gfx::ImageSkiaRep& representation = image.GetRepresentation(1.);
121   if (representation.is_null()) {
122     ADD_FAILURE() << "No image representation.";
123     return SkColorSetARGB(0, 0, 0, 0);
124   }
125
126   const SkBitmap& bitmap = representation.sk_bitmap();
127   return ComputeAverageColor(bitmap);
128 }
129
130 }  // namespace
131
132 class WallpaperManagerPolicyTest
133     : public LoginManagerTest,
134       public ash::DesktopBackgroundControllerObserver,
135       public testing::WithParamInterface<bool> {
136  protected:
137   WallpaperManagerPolicyTest()
138       : LoginManagerTest(true),
139         wallpaper_change_count_(0),
140         fake_dbus_thread_manager_(new FakeDBusThreadManager),
141         fake_session_manager_client_(new FakeSessionManagerClient) {
142     fake_dbus_thread_manager_->SetFakeClients();
143     fake_dbus_thread_manager_->SetSessionManagerClient(
144         scoped_ptr<SessionManagerClient>(fake_session_manager_client_));
145   }
146
147   scoped_ptr<policy::UserPolicyBuilder> GetUserPolicyBuilder(
148       const std::string& user_id) {
149     scoped_ptr<policy::UserPolicyBuilder>
150         user_policy_builder(new policy::UserPolicyBuilder());
151     base::FilePath user_keys_dir;
152     EXPECT_TRUE(PathService::Get(DIR_USER_POLICY_KEYS, &user_keys_dir));
153     const std::string sanitized_user_id =
154         CryptohomeClient::GetStubSanitizedUsername(user_id);
155     const base::FilePath user_key_file =
156         user_keys_dir.AppendASCII(sanitized_user_id)
157                      .AppendASCII("policy.pub");
158     std::vector<uint8> user_key_bits;
159     EXPECT_TRUE(user_policy_builder->GetSigningKey()->
160                 ExportPublicKey(&user_key_bits));
161     EXPECT_TRUE(base::CreateDirectory(user_key_file.DirName()));
162     EXPECT_EQ(base::WriteFile(
163                   user_key_file,
164                   reinterpret_cast<const char*>(user_key_bits.data()),
165                   user_key_bits.size()),
166               static_cast<int>(user_key_bits.size()));
167     user_policy_builder->policy_data().set_username(user_id);
168     return user_policy_builder.Pass();
169   }
170
171   // LoginManagerTest:
172   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
173     DBusThreadManager::SetInstanceForTesting(fake_dbus_thread_manager_);
174     LoginManagerTest::SetUpInProcessBrowserTestFixture();
175     ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_));
176   }
177
178   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
179     // Set the same switches as LoginManagerTest, except that kMultiProfiles is
180     // only set when GetParam() is true and except that kLoginProfile is set
181     // when GetParam() is false.  The latter seems to be required for the sane
182     // start-up of user profiles.
183     command_line->AppendSwitch(switches::kLoginManager);
184     command_line->AppendSwitch(switches::kForceLoginManagerInTests);
185     if (GetParam())
186       command_line->AppendSwitch(::switches::kMultiProfiles);
187     else
188       command_line->AppendSwitchASCII(switches::kLoginProfile, "user");
189   }
190
191   virtual void SetUpOnMainThread() OVERRIDE {
192     LoginManagerTest::SetUpOnMainThread();
193     ash::Shell::GetInstance()->
194         desktop_background_controller()->AddObserver(this);
195
196     // Set up policy signing.
197     user_policy_builders_[0] = GetUserPolicyBuilder(kTestUsers[0]);
198     user_policy_builders_[1] = GetUserPolicyBuilder(kTestUsers[1]);
199
200     ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
201   }
202
203   virtual void TearDownOnMainThread() OVERRIDE {
204     ash::Shell::GetInstance()->
205         desktop_background_controller()->RemoveObserver(this);
206     LoginManagerTest::TearDownOnMainThread();
207   }
208
209   // ash::DesktopBackgroundControllerObserver:
210   virtual void OnWallpaperDataChanged() OVERRIDE {
211     ++wallpaper_change_count_;
212     if (run_loop_)
213       run_loop_->Quit();
214   }
215
216   // Runs the loop until wallpaper has changed at least |count| times in total.
217   void RunUntilWallpaperChangeCount(int count) {
218     while (wallpaper_change_count_ < count) {
219       run_loop_.reset(new base::RunLoop);
220       run_loop_->Run();
221     }
222   }
223
224   std::string ConstructPolicy(const std::string& relative_path) const {
225     std::string image_data;
226     if (!base::ReadFileToString(test_data_dir_.Append(relative_path),
227                                 &image_data)) {
228       ADD_FAILURE();
229     }
230     std::string policy;
231     base::JSONWriter::Write(policy::test::ConstructExternalDataReference(
232         embedded_test_server()->GetURL(std::string("/") + relative_path).spec(),
233         image_data).get(),
234         &policy);
235     return policy;
236   }
237
238   // Inject |filename| as wallpaper policy for test user |user_number|.  Set
239   // empty |filename| to clear policy.
240   void InjectPolicy(int user_number, const std::string& filename) {
241     ASSERT_TRUE(user_number == 0 || user_number == 1);
242     const std::string user_id = kTestUsers[user_number];
243     policy::UserPolicyBuilder* builder =
244         user_policy_builders_[user_number].get();
245     if (filename != "") {
246       builder->payload().
247           mutable_wallpaperimage()->set_value(ConstructPolicy(filename));
248     } else {
249       builder->payload().Clear();
250     }
251     builder->Build();
252     fake_session_manager_client_->set_user_policy(user_id, builder->GetBlob());
253     const User* user = UserManager::Get()->FindUser(user_id);
254     ASSERT_TRUE(user);
255     policy::CloudPolicyStore* store = GetStoreForUser(user);
256     ASSERT_TRUE(store);
257     store->Load();
258     ASSERT_EQ(policy::CloudPolicyStore::STATUS_OK, store->status());
259     ASSERT_EQ(policy::CloudPolicyValidatorBase::VALIDATION_OK,
260               store->validation_status());
261   }
262
263   // Obtain WallpaperInfo for |user_number| from WallpaperManager.
264   void GetUserWallpaperInfo(int user_number, WallpaperInfo* wallpaper_info) {
265     WallpaperManager::Get()->
266         GetUserWallpaperInfo(kTestUsers[user_number], wallpaper_info);
267   }
268
269   base::FilePath test_data_dir_;
270   scoped_ptr<base::RunLoop> run_loop_;
271   int wallpaper_change_count_;
272   scoped_ptr<policy::UserPolicyBuilder> user_policy_builders_[2];
273   FakeDBusThreadManager* fake_dbus_thread_manager_;
274   FakeSessionManagerClient* fake_session_manager_client_;
275
276  private:
277   DISALLOW_COPY_AND_ASSIGN(WallpaperManagerPolicyTest);
278 };
279
280 IN_PROC_BROWSER_TEST_P(WallpaperManagerPolicyTest, PRE_SetResetClear) {
281   RegisterUser(kTestUsers[0]);
282   RegisterUser(kTestUsers[1]);
283   StartupUtils::MarkOobeCompleted();
284 }
285
286 // Verifies that the wallpaper can be set and re-set through policy and that
287 // setting policy for a user that is not logged in doesn't affect the current
288 // user.  Also verifies that after the policy has been cleared, the wallpaper
289 // reverts to default.
290 IN_PROC_BROWSER_TEST_P(WallpaperManagerPolicyTest, SetResetClear) {
291   WallpaperInfo info;
292   LoginUser(kTestUsers[0]);
293   base::RunLoop().RunUntilIdle();
294
295   // First user: Wait until default wallpaper has been loaded (happens
296   // automatically) and store color to recognize it later.
297   RunUntilWallpaperChangeCount(1);
298   const SkColor original_background_color = GetAverageBackgroundColor();
299
300   // Second user: Set wallpaper policy to blue image.  This should not result in
301   // a wallpaper change, which is checked at the very end of this test.
302   InjectPolicy(1, kBlueImageFileName);
303
304   // First user: Set wallpaper policy to red image and verify average color.
305   InjectPolicy(0, kRedImageFileName);
306   RunUntilWallpaperChangeCount(2);
307   GetUserWallpaperInfo(0, &info);
308   ASSERT_EQ(User::POLICY, info.type);
309   ASSERT_EQ(kRedImageColor, GetAverageBackgroundColor());
310
311   // First user: Set wallpaper policy to green image and verify average color.
312   InjectPolicy(0, kGreenImageFileName);
313   RunUntilWallpaperChangeCount(3);
314   GetUserWallpaperInfo(0, &info);
315   ASSERT_EQ(User::POLICY, info.type);
316   ASSERT_EQ(kGreenImageColor, GetAverageBackgroundColor());
317
318   // First user: Clear wallpaper policy and verify that the default wallpaper is
319   // set again.
320   InjectPolicy(0, "");
321   RunUntilWallpaperChangeCount(4);
322   GetUserWallpaperInfo(0, &info);
323   ASSERT_EQ(User::DEFAULT, info.type);
324   ASSERT_EQ(original_background_color, GetAverageBackgroundColor());
325
326   // Check wallpaper change count to ensure that setting the second user's
327   // wallpaper didn't have any effect.
328   ASSERT_EQ(4, wallpaper_change_count_);
329 }
330
331 IN_PROC_BROWSER_TEST_P(WallpaperManagerPolicyTest,
332                        PRE_PRE_PRE_WallpaperOnLoginScreen) {
333   RegisterUser(kTestUsers[0]);
334   RegisterUser(kTestUsers[1]);
335   StartupUtils::MarkOobeCompleted();
336 }
337
338 IN_PROC_BROWSER_TEST_P(WallpaperManagerPolicyTest,
339                        PRE_PRE_WallpaperOnLoginScreen) {
340   LoginUser(kTestUsers[0]);
341
342   // Wait until default wallpaper has been loaded.
343   RunUntilWallpaperChangeCount(1);
344
345   // Set wallpaper policy to red image.
346   InjectPolicy(0, kRedImageFileName);
347
348   // Run until wallpaper has changed.
349   RunUntilWallpaperChangeCount(2);
350   ASSERT_EQ(kRedImageColor, GetAverageBackgroundColor());
351 }
352
353 IN_PROC_BROWSER_TEST_P(WallpaperManagerPolicyTest, PRE_WallpaperOnLoginScreen) {
354   LoginUser(kTestUsers[1]);
355
356   // Wait until default wallpaper has been loaded.
357   RunUntilWallpaperChangeCount(1);
358
359   // Set wallpaper policy to green image.
360   InjectPolicy(1, kGreenImageFileName);
361
362   // Run until wallpaper has changed.
363   RunUntilWallpaperChangeCount(2);
364   ASSERT_EQ(kGreenImageColor, GetAverageBackgroundColor());
365 }
366
367 IN_PROC_BROWSER_TEST_P(WallpaperManagerPolicyTest, WallpaperOnLoginScreen) {
368   // Wait for active pod's wallpaper to be loaded.
369   RunUntilWallpaperChangeCount(1);
370   ASSERT_EQ(kGreenImageColor, GetAverageBackgroundColor());
371
372   // Select the second pod (belonging to user 1).
373   ASSERT_TRUE(content::ExecuteScript(
374       static_cast<chromeos::LoginDisplayHostImpl*>(
375           chromeos::LoginDisplayHostImpl::default_host())->GetOobeUI()->
376               web_ui()->GetWebContents(),
377       "document.getElementsByClassName('pod')[1].focus();"));
378   RunUntilWallpaperChangeCount(2);
379   ASSERT_EQ(kRedImageColor, GetAverageBackgroundColor());
380 }
381
382 IN_PROC_BROWSER_TEST_P(WallpaperManagerPolicyTest, PRE_PRE_PersistOverLogout) {
383   RegisterUser(kTestUsers[0]);
384   StartupUtils::MarkOobeCompleted();
385 }
386
387 IN_PROC_BROWSER_TEST_P(WallpaperManagerPolicyTest, PRE_PersistOverLogout) {
388   LoginUser(kTestUsers[0]);
389
390   // Wait until default wallpaper has been loaded.
391   RunUntilWallpaperChangeCount(1);
392
393   // Set wallpaper policy to red image.
394   InjectPolicy(0, kRedImageFileName);
395
396   // Run until wallpaper has changed.
397   RunUntilWallpaperChangeCount(2);
398   ASSERT_EQ(kRedImageColor, GetAverageBackgroundColor());
399 }
400
401 IN_PROC_BROWSER_TEST_P(WallpaperManagerPolicyTest, PersistOverLogout) {
402   LoginUser(kTestUsers[0]);
403
404   // Wait until wallpaper has been loaded.
405   RunUntilWallpaperChangeCount(1);
406   ASSERT_EQ(kRedImageColor, GetAverageBackgroundColor());
407 }
408
409 INSTANTIATE_TEST_CASE_P(WallpaperManagerPolicyTestInstantiation,
410                         WallpaperManagerPolicyTest, testing::Bool());
411
412 }  // namespace chromeos