Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / display / display_preferences_unittest.cc
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.
4
5 #include "chrome/browser/chromeos/display/display_preferences.h"
6
7 #include <string>
8 #include <vector>
9
10 #include "ash/display/display_controller.h"
11 #include "ash/display/display_layout_store.h"
12 #include "ash/display/display_manager.h"
13 #include "ash/display/resolution_notification_controller.h"
14 #include "ash/screen_util.h"
15 #include "ash/shell.h"
16 #include "ash/test/ash_test_base.h"
17 #include "ash/test/display_manager_test_api.h"
18 #include "ash/wm/maximize_mode/maximize_mode_controller.h"
19 #include "base/prefs/scoped_user_pref_update.h"
20 #include "base/prefs/testing_pref_service.h"
21 #include "base/strings/string_number_conversions.h"
22 #include "base/values.h"
23 #include "chrome/browser/chromeos/display/display_configuration_observer.h"
24 #include "chrome/browser/chromeos/login/users/mock_user_manager.h"
25 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
26 #include "chrome/common/pref_names.h"
27 #include "chrome/test/base/testing_browser_process.h"
28 #include "ui/display/chromeos/display_configurator.h"
29 #include "ui/gfx/geometry/vector3d_f.h"
30 #include "ui/message_center/message_center.h"
31
32 using ash::ResolutionNotificationController;
33
34 namespace chromeos {
35 namespace {
36 const char kPrimaryIdKey[] = "primary-id";
37 const char kMirroredKey[] = "mirrored";
38 const char kPositionKey[] = "position";
39 const char kOffsetKey[] = "offset";
40
41 // The mean acceleration due to gravity on Earth in m/s^2.
42 const float kMeanGravity = 9.80665f;
43
44 class DisplayPreferencesTest : public ash::test::AshTestBase {
45  protected:
46   DisplayPreferencesTest()
47       : mock_user_manager_(new MockUserManager),
48         user_manager_enabler_(mock_user_manager_) {
49   }
50
51   virtual ~DisplayPreferencesTest() {}
52
53   virtual void SetUp() override {
54     EXPECT_CALL(*mock_user_manager_, IsUserLoggedIn())
55         .WillRepeatedly(testing::Return(false));
56     EXPECT_CALL(*mock_user_manager_, Shutdown());
57     ash::test::AshTestBase::SetUp();
58     RegisterDisplayLocalStatePrefs(local_state_.registry());
59     TestingBrowserProcess::GetGlobal()->SetLocalState(&local_state_);
60     observer_.reset(new DisplayConfigurationObserver());
61   }
62
63   virtual void TearDown() override {
64     observer_.reset();
65     TestingBrowserProcess::GetGlobal()->SetLocalState(NULL);
66     ash::test::AshTestBase::TearDown();
67   }
68
69   void LoggedInAsUser() {
70     EXPECT_CALL(*mock_user_manager_, IsUserLoggedIn())
71         .WillRepeatedly(testing::Return(true));
72     EXPECT_CALL(*mock_user_manager_, IsLoggedInAsRegularUser())
73         .WillRepeatedly(testing::Return(true));
74   }
75
76   void LoggedInAsGuest() {
77     EXPECT_CALL(*mock_user_manager_, IsUserLoggedIn())
78         .WillRepeatedly(testing::Return(true));
79     EXPECT_CALL(*mock_user_manager_, IsLoggedInAsRegularUser())
80         .WillRepeatedly(testing::Return(false));
81     EXPECT_CALL(*mock_user_manager_, IsLoggedInAsSupervisedUser())
82         .WillRepeatedly(testing::Return(false));
83   }
84
85   // Do not use the implementation of display_preferences.cc directly to avoid
86   // notifying the update to the system.
87   void StoreDisplayLayoutPrefForName(const std::string& name,
88                                      ash::DisplayLayout::Position layout,
89                                      int offset,
90                                      int64 primary_id) {
91     DictionaryPrefUpdate update(&local_state_, prefs::kSecondaryDisplays);
92     ash::DisplayLayout display_layout(layout, offset);
93     display_layout.primary_id = primary_id;
94
95     DCHECK(!name.empty());
96
97     base::DictionaryValue* pref_data = update.Get();
98     scoped_ptr<base::Value>layout_value(new base::DictionaryValue());
99     if (pref_data->HasKey(name)) {
100       base::Value* value = NULL;
101       if (pref_data->Get(name, &value) && value != NULL)
102         layout_value.reset(value->DeepCopy());
103     }
104     if (ash::DisplayLayout::ConvertToValue(display_layout, layout_value.get()))
105       pref_data->Set(name, layout_value.release());
106   }
107
108   void StoreDisplayLayoutPrefForPair(int64 id1,
109                                      int64 id2,
110                                      ash::DisplayLayout::Position layout,
111                                      int offset) {
112     StoreDisplayLayoutPrefForName(
113         base::Int64ToString(id1) + "," + base::Int64ToString(id2),
114         layout, offset, id1);
115   }
116
117   void StoreDisplayLayoutPrefForSecondary(int64 id,
118                                           ash::DisplayLayout::Position layout,
119                                           int offset,
120                                           int64 primary_id) {
121     StoreDisplayLayoutPrefForName(
122         base::Int64ToString(id), layout, offset, primary_id);
123   }
124
125   void StoreDisplayOverscan(int64 id, const gfx::Insets& insets) {
126     DictionaryPrefUpdate update(&local_state_, prefs::kDisplayProperties);
127     const std::string name = base::Int64ToString(id);
128
129     base::DictionaryValue* pref_data = update.Get();
130     base::DictionaryValue* insets_value = new base::DictionaryValue();
131     insets_value->SetInteger("insets_top", insets.top());
132     insets_value->SetInteger("insets_left", insets.left());
133     insets_value->SetInteger("insets_bottom", insets.bottom());
134     insets_value->SetInteger("insets_right", insets.right());
135     pref_data->Set(name, insets_value);
136   }
137
138   void StoreColorProfile(int64 id, const std::string& profile) {
139     DictionaryPrefUpdate update(&local_state_, prefs::kDisplayProperties);
140     const std::string name = base::Int64ToString(id);
141
142     base::DictionaryValue* pref_data = update.Get();
143     base::DictionaryValue* property = new base::DictionaryValue();
144     property->SetString("color_profile_name", profile);
145     pref_data->Set(name, property);
146   }
147
148   void StoreDisplayRotationPrefsForTest(bool rotation_lock,
149                                         gfx::Display::Rotation rotation) {
150     DictionaryPrefUpdate update(local_state(), prefs::kDisplayRotationLock);
151     base::DictionaryValue* pref_data = update.Get();
152     pref_data->SetBoolean("lock", rotation_lock);
153     pref_data->SetInteger("orientation", static_cast<int>(rotation));
154   }
155
156   std::string GetRegisteredDisplayLayoutStr(int64 id1, int64 id2) {
157     ash::DisplayIdPair pair;
158     pair.first = id1;
159     pair.second = id2;
160     return ash::Shell::GetInstance()->display_manager()->layout_store()->
161         GetRegisteredDisplayLayout(pair).ToString();
162   }
163
164   PrefService* local_state() { return &local_state_; }
165
166  private:
167   MockUserManager* mock_user_manager_;  // Not owned.
168   ScopedUserManagerEnabler user_manager_enabler_;
169   TestingPrefServiceSimple local_state_;
170   scoped_ptr<DisplayConfigurationObserver> observer_;
171
172   DISALLOW_COPY_AND_ASSIGN(DisplayPreferencesTest);
173 };
174
175 }  // namespace
176
177 TEST_F(DisplayPreferencesTest, PairedLayoutOverrides) {
178   UpdateDisplay("100x100,200x200");
179   int64 id1 = gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().id();
180   int64 id2 = ash::ScreenUtil::GetSecondaryDisplay().id();
181   int64 dummy_id = id2 + 1;
182   ASSERT_NE(id1, dummy_id);
183
184   StoreDisplayLayoutPrefForPair(id1, id2, ash::DisplayLayout::TOP, 20);
185   StoreDisplayLayoutPrefForPair(id1, dummy_id, ash::DisplayLayout::LEFT, 30);
186   StoreDisplayPowerStateForTest(
187       chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON);
188
189   ash::Shell* shell = ash::Shell::GetInstance();
190
191   LoadDisplayPreferences(true);
192   // DisplayPowerState should be ignored at boot.
193   EXPECT_EQ(chromeos::DISPLAY_POWER_ALL_ON,
194             shell->display_configurator()->requested_power_state());
195
196   shell->display_manager()->UpdateDisplays();
197   // Check if the layout settings are notified to the system properly.
198   // The paired layout overrides old layout.
199   // Inverted one of for specified pair (id1, id2).  Not used for the pair
200   // (id1, dummy_id) since dummy_id is not connected right now.
201   EXPECT_EQ("top, 20",
202             shell->display_manager()->GetCurrentDisplayLayout().ToString());
203   EXPECT_EQ("top, 20", GetRegisteredDisplayLayoutStr(id1, id2));
204   EXPECT_EQ("left, 30", GetRegisteredDisplayLayoutStr(id1, dummy_id));
205 }
206
207 TEST_F(DisplayPreferencesTest, BasicStores) {
208   ash::DisplayController* display_controller =
209       ash::Shell::GetInstance()->display_controller();
210   ash::DisplayManager* display_manager =
211       ash::Shell::GetInstance()->display_manager();
212
213   UpdateDisplay("200x200*2, 400x300#400x400|300x200*1.25");
214   int64 id1 = gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().id();
215   gfx::Display::SetInternalDisplayId(id1);
216   int64 id2 = ash::ScreenUtil::GetSecondaryDisplay().id();
217   int64 dummy_id = id2 + 1;
218   ASSERT_NE(id1, dummy_id);
219   std::vector<ui::ColorCalibrationProfile> profiles;
220   profiles.push_back(ui::COLOR_PROFILE_STANDARD);
221   profiles.push_back(ui::COLOR_PROFILE_DYNAMIC);
222   profiles.push_back(ui::COLOR_PROFILE_MOVIE);
223   profiles.push_back(ui::COLOR_PROFILE_READING);
224   ash::test::DisplayManagerTestApi test_api(display_manager);
225   // Allows only |id1|.
226   test_api.SetAvailableColorProfiles(id1, profiles);
227   display_manager->SetColorCalibrationProfile(id1, ui::COLOR_PROFILE_DYNAMIC);
228   display_manager->SetColorCalibrationProfile(id2, ui::COLOR_PROFILE_DYNAMIC);
229
230   LoggedInAsUser();
231   ash::DisplayLayout layout(ash::DisplayLayout::TOP, 10);
232   SetCurrentDisplayLayout(layout);
233   StoreDisplayLayoutPrefForTest(
234       id1, dummy_id, ash::DisplayLayout(ash::DisplayLayout::LEFT, 20));
235   // Can't switch to a display that does not exist.
236   display_controller->SetPrimaryDisplayId(dummy_id);
237   EXPECT_NE(dummy_id, ash::Shell::GetScreen()->GetPrimaryDisplay().id());
238
239   display_controller->SetOverscanInsets(id1, gfx::Insets(10, 11, 12, 13));
240   display_manager->SetDisplayRotation(id1, gfx::Display::ROTATE_90);
241   display_manager->SetDisplayUIScale(id1, 1.25f);
242   display_manager->SetDisplayUIScale(id2, 1.25f);
243
244   const base::DictionaryValue* displays =
245       local_state()->GetDictionary(prefs::kSecondaryDisplays);
246   const base::DictionaryValue* layout_value = NULL;
247   std::string key = base::Int64ToString(id1) + "," + base::Int64ToString(id2);
248   EXPECT_TRUE(displays->GetDictionary(key, &layout_value));
249
250   ash::DisplayLayout stored_layout;
251   EXPECT_TRUE(ash::DisplayLayout::ConvertFromValue(*layout_value,
252                                                    &stored_layout));
253   EXPECT_EQ(layout.position, stored_layout.position);
254   EXPECT_EQ(layout.offset, stored_layout.offset);
255
256   bool mirrored = true;
257   EXPECT_TRUE(layout_value->GetBoolean(kMirroredKey, &mirrored));
258   EXPECT_FALSE(mirrored);
259
260   const base::DictionaryValue* properties =
261       local_state()->GetDictionary(prefs::kDisplayProperties);
262   const base::DictionaryValue* property = NULL;
263   EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id1), &property));
264   int ui_scale = 0;
265   int rotation = 0;
266   EXPECT_TRUE(property->GetInteger("rotation", &rotation));
267   EXPECT_TRUE(property->GetInteger("ui-scale", &ui_scale));
268   EXPECT_EQ(1, rotation);
269   EXPECT_EQ(1250, ui_scale);
270
271   // Internal display never registered the resolution.
272   int width = 0, height = 0;
273   EXPECT_FALSE(property->GetInteger("width", &width));
274   EXPECT_FALSE(property->GetInteger("height", &height));
275
276   int top = 0, left = 0, bottom = 0, right = 0;
277   EXPECT_TRUE(property->GetInteger("insets_top", &top));
278   EXPECT_TRUE(property->GetInteger("insets_left", &left));
279   EXPECT_TRUE(property->GetInteger("insets_bottom", &bottom));
280   EXPECT_TRUE(property->GetInteger("insets_right", &right));
281   EXPECT_EQ(10, top);
282   EXPECT_EQ(11, left);
283   EXPECT_EQ(12, bottom);
284   EXPECT_EQ(13, right);
285
286   std::string color_profile;
287   EXPECT_TRUE(property->GetString("color_profile_name", &color_profile));
288   EXPECT_EQ("dynamic", color_profile);
289
290   EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id2), &property));
291   EXPECT_TRUE(property->GetInteger("rotation", &rotation));
292   EXPECT_TRUE(property->GetInteger("ui-scale", &ui_scale));
293   EXPECT_EQ(0, rotation);
294   // ui_scale works only on 2x scale factor/1st display.
295   EXPECT_EQ(1000, ui_scale);
296   EXPECT_FALSE(property->GetInteger("insets_top", &top));
297   EXPECT_FALSE(property->GetInteger("insets_left", &left));
298   EXPECT_FALSE(property->GetInteger("insets_bottom", &bottom));
299   EXPECT_FALSE(property->GetInteger("insets_right", &right));
300
301   // |id2| doesn't have the color_profile because it doesn't have 'dynamic' in
302   // its available list.
303   EXPECT_FALSE(property->GetString("color_profile_name", &color_profile));
304
305   // Resolution is saved only when the resolution is set
306   // by DisplayManager::SetDisplayMode
307   width = 0;
308   height = 0;
309   EXPECT_FALSE(property->GetInteger("width", &width));
310   EXPECT_FALSE(property->GetInteger("height", &height));
311
312   ash::DisplayMode mode(gfx::Size(300, 200), 60.0f, false, true);
313   mode.device_scale_factor = 1.25f;
314   display_manager->SetDisplayMode(id2, mode);
315
316   display_controller->SetPrimaryDisplayId(id2);
317
318   EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id1), &property));
319   width = 0;
320   height = 0;
321   // Internal display shouldn't store its resolution.
322   EXPECT_FALSE(property->GetInteger("width", &width));
323   EXPECT_FALSE(property->GetInteger("height", &height));
324
325   // External display's resolution must be stored this time because
326   // it's not best.
327   int device_scale_factor = 0;
328   EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id2), &property));
329   EXPECT_TRUE(property->GetInteger("width", &width));
330   EXPECT_TRUE(property->GetInteger("height", &height));
331   EXPECT_TRUE(property->GetInteger(
332       "device-scale-factor", &device_scale_factor));
333   EXPECT_EQ(300, width);
334   EXPECT_EQ(200, height);
335   EXPECT_EQ(1250, device_scale_factor);
336
337   // The layout remains the same.
338   EXPECT_TRUE(displays->GetDictionary(key, &layout_value));
339   EXPECT_TRUE(ash::DisplayLayout::ConvertFromValue(*layout_value,
340                                                    &stored_layout));
341   EXPECT_EQ(layout.position, stored_layout.position);
342   EXPECT_EQ(layout.offset, stored_layout.offset);
343   EXPECT_EQ(id2, stored_layout.primary_id);
344
345   mirrored = true;
346   EXPECT_TRUE(layout_value->GetBoolean(kMirroredKey, &mirrored));
347   EXPECT_FALSE(mirrored);
348   std::string primary_id_str;
349   EXPECT_TRUE(layout_value->GetString(kPrimaryIdKey, &primary_id_str));
350   EXPECT_EQ(base::Int64ToString(id2), primary_id_str);
351
352   SetCurrentDisplayLayout(
353       ash::DisplayLayout(ash::DisplayLayout::BOTTOM, 20));
354
355   UpdateDisplay("1+0-200x200*2,1+0-200x200");
356   // Mirrored.
357   int offset = 0;
358   std::string position;
359   EXPECT_TRUE(displays->GetDictionary(key, &layout_value));
360   EXPECT_TRUE(layout_value->GetString(kPositionKey, &position));
361   EXPECT_EQ("top", position);
362   EXPECT_TRUE(layout_value->GetInteger(kOffsetKey, &offset));
363   EXPECT_EQ(-20, offset);
364   mirrored = false;
365   EXPECT_TRUE(layout_value->GetBoolean(kMirroredKey, &mirrored));
366   EXPECT_TRUE(mirrored);
367   EXPECT_TRUE(layout_value->GetString(kPrimaryIdKey, &primary_id_str));
368   EXPECT_EQ(base::Int64ToString(id2), primary_id_str);
369
370   EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id1), &property));
371   EXPECT_FALSE(property->GetInteger("width", &width));
372   EXPECT_FALSE(property->GetInteger("height", &height));
373
374   // External display's selected resolution must not change
375   // by mirroring.
376   EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id2), &property));
377   EXPECT_TRUE(property->GetInteger("width", &width));
378   EXPECT_TRUE(property->GetInteger("height", &height));
379   EXPECT_EQ(300, width);
380   EXPECT_EQ(200, height);
381
382   // Set new display's selected resolution.
383   display_manager->RegisterDisplayProperty(
384       id2 + 1, gfx::Display::ROTATE_0, 1.0f, NULL, gfx::Size(500, 400), 1.0f,
385       ui::COLOR_PROFILE_STANDARD);
386
387   UpdateDisplay("200x200*2, 600x500#600x500|500x400");
388
389   // Update key as the 2nd display gets new id.
390   id2 = ash::ScreenUtil::GetSecondaryDisplay().id();
391   key = base::Int64ToString(id1) + "," + base::Int64ToString(id2);
392   EXPECT_TRUE(displays->GetDictionary(key, &layout_value));
393   EXPECT_TRUE(layout_value->GetString(kPositionKey, &position));
394   EXPECT_EQ("right", position);
395   EXPECT_TRUE(layout_value->GetInteger(kOffsetKey, &offset));
396   EXPECT_EQ(0, offset);
397   mirrored = true;
398   EXPECT_TRUE(layout_value->GetBoolean(kMirroredKey, &mirrored));
399   EXPECT_FALSE(mirrored);
400   EXPECT_TRUE(layout_value->GetString(kPrimaryIdKey, &primary_id_str));
401   EXPECT_EQ(base::Int64ToString(id1), primary_id_str);
402
403   // Best resolution should not be saved.
404   EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id2), &property));
405   EXPECT_FALSE(property->GetInteger("width", &width));
406   EXPECT_FALSE(property->GetInteger("height", &height));
407
408   // Set yet another new display's selected resolution.
409   display_manager->RegisterDisplayProperty(
410       id2 + 1, gfx::Display::ROTATE_0, 1.0f, NULL, gfx::Size(500, 400), 1.0f,
411       ui::COLOR_PROFILE_STANDARD);
412   // Disconnect 2nd display first to generate new id for external display.
413   UpdateDisplay("200x200*2");
414   UpdateDisplay("200x200*2, 500x400#600x500|500x400%60.0f");
415   // Update key as the 2nd display gets new id.
416   id2 = ash::ScreenUtil::GetSecondaryDisplay().id();
417   key = base::Int64ToString(id1) + "," + base::Int64ToString(id2);
418   EXPECT_TRUE(displays->GetDictionary(key, &layout_value));
419   EXPECT_TRUE(layout_value->GetString(kPositionKey, &position));
420   EXPECT_EQ("right", position);
421   EXPECT_TRUE(layout_value->GetInteger(kOffsetKey, &offset));
422   EXPECT_EQ(0, offset);
423   mirrored = true;
424   EXPECT_TRUE(layout_value->GetBoolean(kMirroredKey, &mirrored));
425   EXPECT_FALSE(mirrored);
426   EXPECT_TRUE(layout_value->GetString(kPrimaryIdKey, &primary_id_str));
427   EXPECT_EQ(base::Int64ToString(id1), primary_id_str);
428
429   // External display's selected resolution must be updated.
430   EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id2), &property));
431   EXPECT_TRUE(property->GetInteger("width", &width));
432   EXPECT_TRUE(property->GetInteger("height", &height));
433   EXPECT_EQ(500, width);
434   EXPECT_EQ(400, height);
435 }
436
437 TEST_F(DisplayPreferencesTest, PreventStore) {
438   ResolutionNotificationController::SuppressTimerForTest();
439   LoggedInAsUser();
440   UpdateDisplay("400x300#500x400|400x300|300x200");
441   int64 id = ash::Shell::GetScreen()->GetPrimaryDisplay().id();
442   // Set display's resolution in single display. It creates the notification and
443   // display preferences should not stored meanwhile.
444   ash::Shell* shell = ash::Shell::GetInstance();
445   ash::DisplayMode old_mode;
446   ash::DisplayMode new_mode;
447   old_mode.size = gfx::Size(400, 300);
448   new_mode.size = gfx::Size(500, 400);
449   if (shell->display_manager()->SetDisplayMode(id, new_mode)) {
450     shell->resolution_notification_controller()->PrepareNotification(
451         id, old_mode, new_mode, base::Closure());
452   }
453   UpdateDisplay("500x400#500x400|400x300|300x200");
454
455   const base::DictionaryValue* properties =
456       local_state()->GetDictionary(prefs::kDisplayProperties);
457   const base::DictionaryValue* property = NULL;
458   EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id), &property));
459   int width = 0, height = 0;
460   EXPECT_FALSE(property->GetInteger("width", &width));
461   EXPECT_FALSE(property->GetInteger("height", &height));
462
463   // Revert the change. When timeout, 2nd button is revert.
464   message_center::MessageCenter::Get()->ClickOnNotificationButton(
465       ResolutionNotificationController::kNotificationId, 1);
466   RunAllPendingInMessageLoop();
467   EXPECT_FALSE(
468       message_center::MessageCenter::Get()->FindVisibleNotificationById(
469           ResolutionNotificationController::kNotificationId));
470
471   // Once the notification is removed, the specified resolution will be stored
472   // by SetDisplayMode.
473   ash::Shell::GetInstance()->display_manager()->SetDisplayMode(
474       id, ash::DisplayMode(gfx::Size(300, 200), 60.0f, false, true));
475   UpdateDisplay("300x200#500x400|400x300|300x200");
476
477   property = NULL;
478   EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id), &property));
479   EXPECT_TRUE(property->GetInteger("width", &width));
480   EXPECT_TRUE(property->GetInteger("height", &height));
481   EXPECT_EQ(300, width);
482   EXPECT_EQ(200, height);
483 }
484
485 TEST_F(DisplayPreferencesTest, StoreForSwappedDisplay) {
486   UpdateDisplay("100x100,200x200");
487   int64 id1 = gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().id();
488   int64 id2 = ash::ScreenUtil::GetSecondaryDisplay().id();
489
490   ash::DisplayController* display_controller =
491       ash::Shell::GetInstance()->display_controller();
492   display_controller->SwapPrimaryDisplay();
493   ASSERT_EQ(id1, ash::ScreenUtil::GetSecondaryDisplay().id());
494
495   LoggedInAsUser();
496   ash::DisplayLayout layout(ash::DisplayLayout::TOP, 10);
497   SetCurrentDisplayLayout(layout);
498   layout = layout.Invert();
499
500   const base::DictionaryValue* displays =
501       local_state()->GetDictionary(prefs::kSecondaryDisplays);
502   const base::DictionaryValue* new_value = NULL;
503   std::string key = base::Int64ToString(id1) + "," + base::Int64ToString(id2);
504   EXPECT_TRUE(displays->GetDictionary(key, &new_value));
505
506   ash::DisplayLayout stored_layout;
507   EXPECT_TRUE(ash::DisplayLayout::ConvertFromValue(*new_value, &stored_layout));
508   EXPECT_EQ(layout.position, stored_layout.position);
509   EXPECT_EQ(layout.offset, stored_layout.offset);
510   EXPECT_EQ(id2, stored_layout.primary_id);
511
512   display_controller->SwapPrimaryDisplay();
513   EXPECT_TRUE(displays->GetDictionary(key, &new_value));
514   EXPECT_TRUE(ash::DisplayLayout::ConvertFromValue(*new_value, &stored_layout));
515   EXPECT_EQ(layout.position, stored_layout.position);
516   EXPECT_EQ(layout.offset, stored_layout.offset);
517   EXPECT_EQ(id1, stored_layout.primary_id);
518 }
519
520 TEST_F(DisplayPreferencesTest, RestoreColorProfiles) {
521   ash::DisplayManager* display_manager =
522       ash::Shell::GetInstance()->display_manager();
523
524   int64 id1 = gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().id();
525
526   StoreColorProfile(id1, "dynamic");
527
528   LoggedInAsUser();
529   LoadDisplayPreferences(false);
530
531   // id1's available color profiles list is empty, means somehow the color
532   // profile suport is temporary in trouble.
533   EXPECT_NE(ui::COLOR_PROFILE_DYNAMIC,
534             display_manager->GetDisplayInfo(id1).color_profile());
535
536   // Once the profile is supported, the color profile should be restored.
537   std::vector<ui::ColorCalibrationProfile> profiles;
538   profiles.push_back(ui::COLOR_PROFILE_STANDARD);
539   profiles.push_back(ui::COLOR_PROFILE_DYNAMIC);
540   profiles.push_back(ui::COLOR_PROFILE_MOVIE);
541   profiles.push_back(ui::COLOR_PROFILE_READING);
542   ash::test::DisplayManagerTestApi test_api(display_manager);
543   test_api.SetAvailableColorProfiles(id1, profiles);
544
545   LoadDisplayPreferences(false);
546   EXPECT_EQ(ui::COLOR_PROFILE_DYNAMIC,
547             display_manager->GetDisplayInfo(id1).color_profile());
548 }
549
550 TEST_F(DisplayPreferencesTest, DontStoreInGuestMode) {
551   ash::DisplayController* display_controller =
552       ash::Shell::GetInstance()->display_controller();
553   ash::DisplayManager* display_manager =
554       ash::Shell::GetInstance()->display_manager();
555
556   UpdateDisplay("200x200*2,200x200");
557
558   LoggedInAsGuest();
559   int64 id1 = ash::Shell::GetScreen()->GetPrimaryDisplay().id();
560   gfx::Display::SetInternalDisplayId(id1);
561   int64 id2 = ash::ScreenUtil::GetSecondaryDisplay().id();
562   ash::DisplayLayout layout(ash::DisplayLayout::TOP, 10);
563   SetCurrentDisplayLayout(layout);
564   display_manager->SetDisplayUIScale(id1, 1.25f);
565   display_controller->SetPrimaryDisplayId(id2);
566   int64 new_primary = ash::Shell::GetScreen()->GetPrimaryDisplay().id();
567   display_controller->SetOverscanInsets(
568       new_primary,
569       gfx::Insets(10, 11, 12, 13));
570   display_manager->SetDisplayRotation(new_primary, gfx::Display::ROTATE_90);
571
572   // Does not store the preferences locally.
573   EXPECT_FALSE(local_state()->FindPreference(
574       prefs::kSecondaryDisplays)->HasUserSetting());
575   EXPECT_FALSE(local_state()->FindPreference(
576       prefs::kDisplayProperties)->HasUserSetting());
577
578   // Settings are still notified to the system.
579   gfx::Screen* screen = gfx::Screen::GetNativeScreen();
580   EXPECT_EQ(id2, screen->GetPrimaryDisplay().id());
581   EXPECT_EQ(ash::DisplayLayout::BOTTOM,
582             display_manager->GetCurrentDisplayLayout().position);
583   EXPECT_EQ(-10, display_manager->GetCurrentDisplayLayout().offset);
584   const gfx::Display& primary_display = screen->GetPrimaryDisplay();
585   EXPECT_EQ("178x176", primary_display.bounds().size().ToString());
586   EXPECT_EQ(gfx::Display::ROTATE_90, primary_display.rotation());
587
588   const ash::DisplayInfo& info1 = display_manager->GetDisplayInfo(id1);
589   EXPECT_EQ(1.25f, info1.configured_ui_scale());
590
591   const ash::DisplayInfo& info_primary =
592       display_manager->GetDisplayInfo(new_primary);
593   EXPECT_EQ(gfx::Display::ROTATE_90, info_primary.rotation());
594   EXPECT_EQ(1.0f, info_primary.configured_ui_scale());
595 }
596
597 TEST_F(DisplayPreferencesTest, StorePowerStateNoLogin) {
598   EXPECT_FALSE(local_state()->HasPrefPath(prefs::kDisplayPowerState));
599
600   // Stores display prefs without login, which still stores the power state.
601   StoreDisplayPrefs();
602   EXPECT_TRUE(local_state()->HasPrefPath(prefs::kDisplayPowerState));
603 }
604
605 TEST_F(DisplayPreferencesTest, StorePowerStateGuest) {
606   EXPECT_FALSE(local_state()->HasPrefPath(prefs::kDisplayPowerState));
607
608   LoggedInAsGuest();
609   StoreDisplayPrefs();
610   EXPECT_TRUE(local_state()->HasPrefPath(prefs::kDisplayPowerState));
611 }
612
613 TEST_F(DisplayPreferencesTest, StorePowerStateNormalUser) {
614   EXPECT_FALSE(local_state()->HasPrefPath(prefs::kDisplayPowerState));
615
616   LoggedInAsUser();
617   StoreDisplayPrefs();
618   EXPECT_TRUE(local_state()->HasPrefPath(prefs::kDisplayPowerState));
619 }
620
621 TEST_F(DisplayPreferencesTest, DisplayPowerStateAfterRestart) {
622   StoreDisplayPowerStateForTest(
623       chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON);
624   LoadDisplayPreferences(false);
625   EXPECT_EQ(chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON,
626             ash::Shell::GetInstance()->display_configurator()->
627                 requested_power_state());
628 }
629
630 TEST_F(DisplayPreferencesTest, DontSaveAndRestoreAllOff) {
631   ash::Shell* shell = ash::Shell::GetInstance();
632   StoreDisplayPowerStateForTest(
633       chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON);
634   LoadDisplayPreferences(false);
635   // DisplayPowerState should be ignored at boot.
636   EXPECT_EQ(chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON,
637             shell->display_configurator()->requested_power_state());
638
639   StoreDisplayPowerStateForTest(
640       chromeos::DISPLAY_POWER_ALL_OFF);
641   EXPECT_EQ(chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON,
642             shell->display_configurator()->requested_power_state());
643   EXPECT_EQ("internal_off_external_on",
644             local_state()->GetString(prefs::kDisplayPowerState));
645
646   // Don't try to load
647   local_state()->SetString(prefs::kDisplayPowerState, "all_off");
648   LoadDisplayPreferences(false);
649   EXPECT_EQ(chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON,
650             shell->display_configurator()->requested_power_state());
651 }
652
653 // Tests that display configuration changes caused by MaximizeModeController
654 // are not saved.
655 TEST_F(DisplayPreferencesTest, DontSaveMaximizeModeControllerRotations) {
656   ash::Shell* shell = ash::Shell::GetInstance();
657   ash::MaximizeModeController* controller = shell->maximize_mode_controller();
658   gfx::Display::SetInternalDisplayId(
659       gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().id());
660   ash::DisplayManager* display_manager = shell->display_manager();
661   LoggedInAsUser();
662   // Populate the properties.
663   display_manager->SetDisplayRotation(gfx::Display::InternalDisplayId(),
664                                       gfx::Display::ROTATE_180);
665   // Reset property to avoid rotation lock
666   display_manager->SetDisplayRotation(gfx::Display::InternalDisplayId(),
667                                       gfx::Display::ROTATE_0);
668
669   // Open up 270 degrees to trigger maximize mode
670   ui::AccelerometerUpdate update;
671   update.Set(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD,
672              0.0f, 0.0f, kMeanGravity);
673   update.Set(ui::ACCELEROMETER_SOURCE_SCREEN,
674              0.0f, -kMeanGravity, 0.0f);
675   controller->OnAccelerometerUpdated(update);
676   EXPECT_TRUE(controller->IsMaximizeModeWindowManagerEnabled());
677
678   // Trigger 90 degree rotation
679   update.Set(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD,
680              -kMeanGravity, 0.0f, 0.0f);
681   update.Set(ui::ACCELEROMETER_SOURCE_SCREEN,
682              -kMeanGravity, 0.0f, 0.0f);
683   controller->OnAccelerometerUpdated(update);
684   EXPECT_EQ(gfx::Display::ROTATE_90, display_manager->
685                 GetDisplayInfo(gfx::Display::InternalDisplayId()).rotation());
686
687   const base::DictionaryValue* properties =
688       local_state()->GetDictionary(prefs::kDisplayProperties);
689   const base::DictionaryValue* property = NULL;
690   EXPECT_TRUE(properties->GetDictionary(
691       base::Int64ToString(gfx::Display::InternalDisplayId()), &property));
692   int rotation = -1;
693   EXPECT_TRUE(property->GetInteger("rotation", &rotation));
694   EXPECT_EQ(gfx::Display::ROTATE_0, rotation);
695 }
696
697 // Tests that the rotation state is saved without a user being logged in.
698 TEST_F(DisplayPreferencesTest, StoreRotationStateNoLogin) {
699   gfx::Display::SetInternalDisplayId(
700             gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().id());
701   EXPECT_FALSE(local_state()->HasPrefPath(prefs::kDisplayRotationLock));
702
703   bool current_rotation_lock =
704       ash::Shell::GetInstance()->maximize_mode_controller()->rotation_locked();
705   StoreDisplayRotationPrefs(current_rotation_lock);
706   EXPECT_TRUE(local_state()->HasPrefPath(prefs::kDisplayRotationLock));
707
708   const base::DictionaryValue* properties =
709       local_state()->GetDictionary(prefs::kDisplayRotationLock);
710   bool rotation_lock;
711   EXPECT_TRUE(properties->GetBoolean("lock", &rotation_lock));
712   EXPECT_EQ(current_rotation_lock, rotation_lock);
713
714   int orientation;
715   gfx::Display::Rotation current_rotation = ash::Shell::GetInstance()->
716       display_manager()->
717           GetDisplayInfo(gfx::Display::InternalDisplayId()).rotation();
718   EXPECT_TRUE(properties->GetInteger("orientation", &orientation));
719   EXPECT_EQ(current_rotation, orientation);
720 }
721
722 // Tests that the rotation state is saved when a guest is logged in.
723 TEST_F(DisplayPreferencesTest, StoreRotationStateGuest) {
724   gfx::Display::SetInternalDisplayId(
725       gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().id());
726   EXPECT_FALSE(local_state()->HasPrefPath(prefs::kDisplayRotationLock));
727   LoggedInAsGuest();
728
729   bool current_rotation_lock =
730       ash::Shell::GetInstance()->maximize_mode_controller()->rotation_locked();
731   StoreDisplayRotationPrefs(current_rotation_lock);
732   EXPECT_TRUE(local_state()->HasPrefPath(prefs::kDisplayRotationLock));
733
734   const base::DictionaryValue* properties =
735       local_state()->GetDictionary(prefs::kDisplayRotationLock);
736   bool rotation_lock;
737   EXPECT_TRUE(properties->GetBoolean("lock", &rotation_lock));
738   EXPECT_EQ(current_rotation_lock, rotation_lock);
739
740   int orientation;
741   gfx::Display::Rotation current_rotation = ash::Shell::GetInstance()->
742       display_manager()->
743           GetDisplayInfo(gfx::Display::InternalDisplayId()).rotation();
744   EXPECT_TRUE(properties->GetInteger("orientation", &orientation));
745   EXPECT_EQ(current_rotation, orientation);
746 }
747
748 // Tests that the rotation state is saved when a normal user is logged in.
749 TEST_F(DisplayPreferencesTest, StoreRotationStateNormalUser) {
750   gfx::Display::SetInternalDisplayId(
751       gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().id());
752   EXPECT_FALSE(local_state()->HasPrefPath(prefs::kDisplayRotationLock));
753   LoggedInAsGuest();
754
755   bool current_rotation_lock =
756       ash::Shell::GetInstance()->maximize_mode_controller()->rotation_locked();
757   StoreDisplayRotationPrefs(current_rotation_lock);
758   EXPECT_TRUE(local_state()->HasPrefPath(prefs::kDisplayRotationLock));
759
760   const base::DictionaryValue* properties =
761       local_state()->GetDictionary(prefs::kDisplayRotationLock);
762   bool rotation_lock;
763   EXPECT_TRUE(properties->GetBoolean("lock", &rotation_lock));
764   EXPECT_EQ(current_rotation_lock, rotation_lock);
765
766   int orientation;
767   gfx::Display::Rotation current_rotation = ash::Shell::GetInstance()->
768       display_manager()->
769           GetDisplayInfo(gfx::Display::InternalDisplayId()).rotation();
770   EXPECT_TRUE(properties->GetInteger("orientation", &orientation));
771   EXPECT_EQ(current_rotation, orientation);
772 }
773
774 // Tests that rotation state is loaded without a user being logged in, and that
775 // entering maximize mode applies the state.
776 TEST_F(DisplayPreferencesTest, LoadRotationNoLogin) {
777   gfx::Display::SetInternalDisplayId(
778       gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().id());
779   ASSERT_FALSE(local_state()->HasPrefPath(prefs::kDisplayRotationLock));
780
781   ash::Shell* shell = ash::Shell::GetInstance();
782   ash::MaximizeModeController* maximize_mode_controller =
783       shell->maximize_mode_controller();
784   bool initial_rotation_lock = maximize_mode_controller->rotation_locked();
785   ASSERT_FALSE(initial_rotation_lock);
786   ash::DisplayManager* display_manager = shell->display_manager();
787   gfx::Display::Rotation initial_rotation = display_manager->
788       GetDisplayInfo(gfx::Display::InternalDisplayId()).rotation();
789   ASSERT_EQ(gfx::Display::ROTATE_0, initial_rotation);
790
791   StoreDisplayRotationPrefs(initial_rotation_lock);
792   ASSERT_TRUE(local_state()->HasPrefPath(prefs::kDisplayRotationLock));
793
794   StoreDisplayRotationPrefsForTest(true, gfx::Display::ROTATE_90);
795   LoadDisplayPreferences(false);
796
797   bool display_rotation_lock =
798       display_manager->registered_internal_display_rotation_lock();
799   bool display_rotation =
800       display_manager->registered_internal_display_rotation();
801   EXPECT_TRUE(display_rotation_lock);
802   EXPECT_EQ(gfx::Display::ROTATE_90, display_rotation);
803
804   bool rotation_lock = maximize_mode_controller->rotation_locked();
805   gfx::Display::Rotation before_maximize_mode_rotation = display_manager->
806       GetDisplayInfo(gfx::Display::InternalDisplayId()).rotation();
807
808   // Settings should not be applied until maximize mode activates
809   EXPECT_FALSE(rotation_lock);
810   EXPECT_EQ(gfx::Display::ROTATE_0, before_maximize_mode_rotation);
811
812   // Open up 270 degrees to trigger maximize mode
813   ui::AccelerometerUpdate update;
814   update.Set(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD,
815              0.0f, 0.0f, kMeanGravity);
816   update.Set(ui::ACCELEROMETER_SOURCE_SCREEN,
817              0.0f, -kMeanGravity, 0.0f);
818   maximize_mode_controller->OnAccelerometerUpdated(update);
819   EXPECT_TRUE(maximize_mode_controller->IsMaximizeModeWindowManagerEnabled());
820   bool maximize_mode_rotation_lock =
821       maximize_mode_controller->rotation_locked();
822   gfx::Display::Rotation maximize_mode_rotation = display_manager->
823       GetDisplayInfo(gfx::Display::InternalDisplayId()).rotation();
824   EXPECT_TRUE(maximize_mode_rotation_lock);
825   EXPECT_EQ(gfx::Display::ROTATE_90, maximize_mode_rotation);
826 }
827
828 // Tests that loaded rotation state is ignored if the device starts in normal
829 // mode, and that they are not applied upon first entering maximize mode.
830 TEST_F(DisplayPreferencesTest, LoadRotationIgnoredInNormalMode) {
831   gfx::Display::SetInternalDisplayId(
832       gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().id());
833   ASSERT_FALSE(local_state()->HasPrefPath(prefs::kDisplayRotationLock));
834   StoreDisplayRotationPrefs(false /* rotation_lock*/);
835   ASSERT_TRUE(local_state()->HasPrefPath(prefs::kDisplayRotationLock));
836
837   StoreDisplayRotationPrefsForTest(true, gfx::Display::ROTATE_90);
838   LoadDisplayPreferences(false);
839
840   ash::MaximizeModeController* maximize_mode_controller =
841       ash::Shell::GetInstance()->maximize_mode_controller();
842   // Lid open to 90 degrees
843   ui::AccelerometerUpdate update;
844   update.Set(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD,
845              -kMeanGravity, 0.0f, 0.0f);
846   update.Set(ui::ACCELEROMETER_SOURCE_SCREEN,
847              -kMeanGravity, 0.0f, 0.0f);
848   maximize_mode_controller->OnAccelerometerUpdated(update);
849   EXPECT_FALSE(maximize_mode_controller->IsMaximizeModeWindowManagerEnabled());
850   EXPECT_FALSE(maximize_mode_controller->rotation_locked());
851
852   // Open up 270 degrees to trigger maximize mode
853   update.Set(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD,
854              0.0f, 0.0f, kMeanGravity);
855   update.Set(ui::ACCELEROMETER_SOURCE_SCREEN,
856              0.0f, -kMeanGravity, 0.0f);
857   maximize_mode_controller->OnAccelerometerUpdated(update);
858   EXPECT_TRUE(maximize_mode_controller->IsMaximizeModeWindowManagerEnabled());
859   EXPECT_FALSE(maximize_mode_controller->rotation_locked());
860 }
861
862 // Tests that rotation lock being set causes the rotation state to be saved.
863 TEST_F(DisplayPreferencesTest, RotationLockTriggersStore) {
864   gfx::Display::SetInternalDisplayId(
865     gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().id());
866   ASSERT_FALSE(local_state()->HasPrefPath(prefs::kDisplayRotationLock));
867
868   ash::MaximizeModeController* maximize_mode_controller =
869       ash::Shell::GetInstance()->maximize_mode_controller();
870   maximize_mode_controller->SetRotationLocked(true);
871
872   EXPECT_TRUE(local_state()->HasPrefPath(prefs::kDisplayRotationLock));
873
874   const base::DictionaryValue* properties =
875       local_state()->GetDictionary(prefs::kDisplayRotationLock);
876   bool rotation_lock;
877   EXPECT_TRUE(properties->GetBoolean("lock", &rotation_lock));
878 }
879
880 }  // namespace chromeos