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