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.
5 #include "chrome/browser/chromeos/display/display_preferences.h"
7 #include "ash/display/display_controller.h"
8 #include "ash/display/display_layout_store.h"
9 #include "ash/display/display_manager.h"
10 #include "ash/display/resolution_notification_controller.h"
11 #include "ash/screen_util.h"
12 #include "ash/shell.h"
13 #include "ash/test/ash_test_base.h"
14 #include "ash/test/display_manager_test_api.h"
15 #include "base/prefs/scoped_user_pref_update.h"
16 #include "base/prefs/testing_pref_service.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "base/values.h"
19 #include "chrome/browser/chromeos/display/display_configuration_observer.h"
20 #include "chrome/browser/chromeos/login/mock_user_manager.h"
21 #include "chrome/browser/chromeos/login/user_manager.h"
22 #include "chrome/common/pref_names.h"
23 #include "chrome/test/base/testing_browser_process.h"
24 #include "ui/display/chromeos/display_configurator.h"
25 #include "ui/message_center/message_center.h"
27 using ash::ResolutionNotificationController;
31 const char kPrimaryIdKey[] = "primary-id";
32 const char kMirroredKey[] = "mirrored";
33 const char kPositionKey[] = "position";
34 const char kOffsetKey[] = "offset";
36 class DisplayPreferencesTest : public ash::test::AshTestBase {
38 DisplayPreferencesTest()
39 : mock_user_manager_(new MockUserManager),
40 user_manager_enabler_(mock_user_manager_) {
43 virtual ~DisplayPreferencesTest() {}
45 virtual void SetUp() OVERRIDE {
46 EXPECT_CALL(*mock_user_manager_, IsUserLoggedIn())
47 .WillRepeatedly(testing::Return(false));
48 EXPECT_CALL(*mock_user_manager_, Shutdown());
49 ash::test::AshTestBase::SetUp();
50 RegisterDisplayLocalStatePrefs(local_state_.registry());
51 TestingBrowserProcess::GetGlobal()->SetLocalState(&local_state_);
52 observer_.reset(new DisplayConfigurationObserver());
55 virtual void TearDown() OVERRIDE {
57 TestingBrowserProcess::GetGlobal()->SetLocalState(NULL);
58 ash::test::AshTestBase::TearDown();
61 void LoggedInAsUser() {
62 EXPECT_CALL(*mock_user_manager_, IsUserLoggedIn())
63 .WillRepeatedly(testing::Return(true));
64 EXPECT_CALL(*mock_user_manager_, IsLoggedInAsRegularUser())
65 .WillRepeatedly(testing::Return(true));
68 void LoggedInAsGuest() {
69 EXPECT_CALL(*mock_user_manager_, IsUserLoggedIn())
70 .WillRepeatedly(testing::Return(true));
71 EXPECT_CALL(*mock_user_manager_, IsLoggedInAsRegularUser())
72 .WillRepeatedly(testing::Return(false));
73 EXPECT_CALL(*mock_user_manager_, IsLoggedInAsLocallyManagedUser())
74 .WillRepeatedly(testing::Return(false));
77 // Do not use the implementation of display_preferences.cc directly to avoid
78 // notifying the update to the system.
79 void StoreDisplayLayoutPrefForName(const std::string& name,
80 ash::DisplayLayout::Position layout,
83 DictionaryPrefUpdate update(&local_state_, prefs::kSecondaryDisplays);
84 ash::DisplayLayout display_layout(layout, offset);
85 display_layout.primary_id = primary_id;
87 DCHECK(!name.empty());
89 base::DictionaryValue* pref_data = update.Get();
90 scoped_ptr<base::Value>layout_value(new base::DictionaryValue());
91 if (pref_data->HasKey(name)) {
92 base::Value* value = NULL;
93 if (pref_data->Get(name, &value) && value != NULL)
94 layout_value.reset(value->DeepCopy());
96 if (ash::DisplayLayout::ConvertToValue(display_layout, layout_value.get()))
97 pref_data->Set(name, layout_value.release());
100 void StoreDisplayLayoutPrefForPair(int64 id1,
102 ash::DisplayLayout::Position layout,
104 StoreDisplayLayoutPrefForName(
105 base::Int64ToString(id1) + "," + base::Int64ToString(id2),
106 layout, offset, id1);
109 void StoreDisplayLayoutPrefForSecondary(int64 id,
110 ash::DisplayLayout::Position layout,
113 StoreDisplayLayoutPrefForName(
114 base::Int64ToString(id), layout, offset, primary_id);
117 void StoreDisplayOverscan(int64 id, const gfx::Insets& insets) {
118 DictionaryPrefUpdate update(&local_state_, prefs::kDisplayProperties);
119 const std::string name = base::Int64ToString(id);
121 base::DictionaryValue* pref_data = update.Get();
122 base::DictionaryValue* insets_value = new base::DictionaryValue();
123 insets_value->SetInteger("insets_top", insets.top());
124 insets_value->SetInteger("insets_left", insets.left());
125 insets_value->SetInteger("insets_bottom", insets.bottom());
126 insets_value->SetInteger("insets_right", insets.right());
127 pref_data->Set(name, insets_value);
130 void StoreColorProfile(int64 id, const std::string& profile) {
131 DictionaryPrefUpdate update(&local_state_, prefs::kDisplayProperties);
132 const std::string name = base::Int64ToString(id);
134 base::DictionaryValue* pref_data = update.Get();
135 base::DictionaryValue* property = new base::DictionaryValue();
136 property->SetString("color_profile_name", profile);
137 pref_data->Set(name, property);
140 std::string GetRegisteredDisplayLayoutStr(int64 id1, int64 id2) {
141 ash::DisplayIdPair pair;
144 return ash::Shell::GetInstance()->display_manager()->layout_store()->
145 GetRegisteredDisplayLayout(pair).ToString();
148 PrefService* local_state() { return &local_state_; }
151 MockUserManager* mock_user_manager_; // Not owned.
152 ScopedUserManagerEnabler user_manager_enabler_;
153 TestingPrefServiceSimple local_state_;
154 scoped_ptr<DisplayConfigurationObserver> observer_;
156 DISALLOW_COPY_AND_ASSIGN(DisplayPreferencesTest);
161 TEST_F(DisplayPreferencesTest, PairedLayoutOverrides) {
162 UpdateDisplay("100x100,200x200");
163 int64 id1 = gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().id();
164 int64 id2 = ash::ScreenUtil::GetSecondaryDisplay().id();
165 int64 dummy_id = id2 + 1;
166 ASSERT_NE(id1, dummy_id);
168 StoreDisplayLayoutPrefForPair(id1, id2, ash::DisplayLayout::TOP, 20);
169 StoreDisplayLayoutPrefForPair(id1, dummy_id, ash::DisplayLayout::LEFT, 30);
170 StoreDisplayPowerStateForTest(
171 chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON);
173 ash::Shell* shell = ash::Shell::GetInstance();
175 LoadDisplayPreferences(true);
176 // DisplayPowerState should be ignored at boot.
177 EXPECT_EQ(chromeos::DISPLAY_POWER_ALL_ON,
178 shell->display_configurator()->power_state());
180 shell->display_manager()->UpdateDisplays();
181 // Check if the layout settings are notified to the system properly.
182 // The paired layout overrides old layout.
183 // Inverted one of for specified pair (id1, id2). Not used for the pair
184 // (id1, dummy_id) since dummy_id is not connected right now.
186 shell->display_manager()->GetCurrentDisplayLayout().ToString());
187 EXPECT_EQ("top, 20", GetRegisteredDisplayLayoutStr(id1, id2));
188 EXPECT_EQ("left, 30", GetRegisteredDisplayLayoutStr(id1, dummy_id));
191 TEST_F(DisplayPreferencesTest, BasicStores) {
192 ash::DisplayController* display_controller =
193 ash::Shell::GetInstance()->display_controller();
194 ash::DisplayManager* display_manager =
195 ash::Shell::GetInstance()->display_manager();
197 UpdateDisplay("200x200*2, 400x300#400x400|300x200");
198 int64 id1 = gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().id();
199 gfx::Display::SetInternalDisplayId(id1);
200 int64 id2 = ash::ScreenUtil::GetSecondaryDisplay().id();
201 int64 dummy_id = id2 + 1;
202 ASSERT_NE(id1, dummy_id);
203 std::vector<ui::ColorCalibrationProfile> profiles;
204 profiles.push_back(ui::COLOR_PROFILE_STANDARD);
205 profiles.push_back(ui::COLOR_PROFILE_DYNAMIC);
206 profiles.push_back(ui::COLOR_PROFILE_MOVIE);
207 profiles.push_back(ui::COLOR_PROFILE_READING);
208 ash::test::DisplayManagerTestApi test_api(display_manager);
209 // Allows only |id1|.
210 test_api.SetAvailableColorProfiles(id1, profiles);
211 display_manager->SetColorCalibrationProfile(id1, ui::COLOR_PROFILE_DYNAMIC);
212 display_manager->SetColorCalibrationProfile(id2, ui::COLOR_PROFILE_DYNAMIC);
215 ash::DisplayLayout layout(ash::DisplayLayout::TOP, 10);
216 SetCurrentDisplayLayout(layout);
217 StoreDisplayLayoutPrefForTest(
218 id1, dummy_id, ash::DisplayLayout(ash::DisplayLayout::LEFT, 20));
219 // Can't switch to a display that does not exist.
220 display_controller->SetPrimaryDisplayId(dummy_id);
221 EXPECT_NE(dummy_id, ash::Shell::GetScreen()->GetPrimaryDisplay().id());
223 display_controller->SetOverscanInsets(id1, gfx::Insets(10, 11, 12, 13));
224 display_manager->SetDisplayRotation(id1, gfx::Display::ROTATE_90);
225 display_manager->SetDisplayUIScale(id1, 1.25f);
226 display_manager->SetDisplayUIScale(id2, 1.25f);
228 const base::DictionaryValue* displays =
229 local_state()->GetDictionary(prefs::kSecondaryDisplays);
230 const base::DictionaryValue* layout_value = NULL;
231 std::string key = base::Int64ToString(id1) + "," + base::Int64ToString(id2);
232 EXPECT_TRUE(displays->GetDictionary(key, &layout_value));
234 ash::DisplayLayout stored_layout;
235 EXPECT_TRUE(ash::DisplayLayout::ConvertFromValue(*layout_value,
237 EXPECT_EQ(layout.position, stored_layout.position);
238 EXPECT_EQ(layout.offset, stored_layout.offset);
240 bool mirrored = true;
241 EXPECT_TRUE(layout_value->GetBoolean(kMirroredKey, &mirrored));
242 EXPECT_FALSE(mirrored);
244 const base::DictionaryValue* properties =
245 local_state()->GetDictionary(prefs::kDisplayProperties);
246 const base::DictionaryValue* property = NULL;
247 EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id1), &property));
250 EXPECT_TRUE(property->GetInteger("rotation", &rotation));
251 EXPECT_TRUE(property->GetInteger("ui-scale", &ui_scale));
252 EXPECT_EQ(1, rotation);
253 EXPECT_EQ(1250, ui_scale);
255 // Internal display never registered the resolution.
256 int width = 0, height = 0;
257 EXPECT_FALSE(property->GetInteger("width", &width));
258 EXPECT_FALSE(property->GetInteger("height", &height));
260 int top = 0, left = 0, bottom = 0, right = 0;
261 EXPECT_TRUE(property->GetInteger("insets_top", &top));
262 EXPECT_TRUE(property->GetInteger("insets_left", &left));
263 EXPECT_TRUE(property->GetInteger("insets_bottom", &bottom));
264 EXPECT_TRUE(property->GetInteger("insets_right", &right));
267 EXPECT_EQ(12, bottom);
268 EXPECT_EQ(13, right);
270 std::string color_profile;
271 EXPECT_TRUE(property->GetString("color_profile_name", &color_profile));
272 EXPECT_EQ("dynamic", color_profile);
274 EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id2), &property));
275 EXPECT_TRUE(property->GetInteger("rotation", &rotation));
276 EXPECT_TRUE(property->GetInteger("ui-scale", &ui_scale));
277 EXPECT_EQ(0, rotation);
278 // ui_scale works only on 2x scale factor/1st display.
279 EXPECT_EQ(1000, ui_scale);
280 EXPECT_FALSE(property->GetInteger("insets_top", &top));
281 EXPECT_FALSE(property->GetInteger("insets_left", &left));
282 EXPECT_FALSE(property->GetInteger("insets_bottom", &bottom));
283 EXPECT_FALSE(property->GetInteger("insets_right", &right));
285 // |id2| doesn't have the color_profile because it doesn't have 'dynamic' in
286 // its available list.
287 EXPECT_FALSE(property->GetString("color_profile_name", &color_profile));
289 // Resolution is saved only when the resolution is set
290 // by DisplayManager::SetDisplayResolution
293 EXPECT_FALSE(property->GetInteger("width", &width));
294 EXPECT_FALSE(property->GetInteger("height", &height));
296 display_manager->SetDisplayResolution(id2, gfx::Size(300, 200));
298 display_controller->SetPrimaryDisplayId(id2);
300 EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id1), &property));
303 // Internal display shouldn't store its resolution.
304 EXPECT_FALSE(property->GetInteger("width", &width));
305 EXPECT_FALSE(property->GetInteger("height", &height));
307 // External display's resolution must be stored this time because
309 EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id2), &property));
310 EXPECT_TRUE(property->GetInteger("width", &width));
311 EXPECT_TRUE(property->GetInteger("height", &height));
312 EXPECT_EQ(300, width);
313 EXPECT_EQ(200, height);
315 // The layout remains the same.
316 EXPECT_TRUE(displays->GetDictionary(key, &layout_value));
317 EXPECT_TRUE(ash::DisplayLayout::ConvertFromValue(*layout_value,
319 EXPECT_EQ(layout.position, stored_layout.position);
320 EXPECT_EQ(layout.offset, stored_layout.offset);
321 EXPECT_EQ(id2, stored_layout.primary_id);
324 EXPECT_TRUE(layout_value->GetBoolean(kMirroredKey, &mirrored));
325 EXPECT_FALSE(mirrored);
326 std::string primary_id_str;
327 EXPECT_TRUE(layout_value->GetString(kPrimaryIdKey, &primary_id_str));
328 EXPECT_EQ(base::Int64ToString(id2), primary_id_str);
330 SetCurrentDisplayLayout(
331 ash::DisplayLayout(ash::DisplayLayout::BOTTOM, 20));
333 UpdateDisplay("1+0-200x200*2,1+0-200x200");
336 std::string position;
337 EXPECT_TRUE(displays->GetDictionary(key, &layout_value));
338 EXPECT_TRUE(layout_value->GetString(kPositionKey, &position));
339 EXPECT_EQ("top", position);
340 EXPECT_TRUE(layout_value->GetInteger(kOffsetKey, &offset));
341 EXPECT_EQ(-20, offset);
343 EXPECT_TRUE(layout_value->GetBoolean(kMirroredKey, &mirrored));
344 EXPECT_TRUE(mirrored);
345 EXPECT_TRUE(layout_value->GetString(kPrimaryIdKey, &primary_id_str));
346 EXPECT_EQ(base::Int64ToString(id2), primary_id_str);
348 EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id1), &property));
349 EXPECT_FALSE(property->GetInteger("width", &width));
350 EXPECT_FALSE(property->GetInteger("height", &height));
352 // External display's selected resolution must not change
354 EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id2), &property));
355 EXPECT_TRUE(property->GetInteger("width", &width));
356 EXPECT_TRUE(property->GetInteger("height", &height));
357 EXPECT_EQ(300, width);
358 EXPECT_EQ(200, height);
360 // Set new display's selected resolution.
361 display_manager->RegisterDisplayProperty(
362 id2 + 1, gfx::Display::ROTATE_0, 1.0f, NULL, gfx::Size(500, 400),
363 ui::COLOR_PROFILE_STANDARD);
365 UpdateDisplay("200x200*2, 600x500#600x500|500x400");
367 // Update key as the 2nd display gets new id.
368 id2 = ash::ScreenUtil::GetSecondaryDisplay().id();
369 key = base::Int64ToString(id1) + "," + base::Int64ToString(id2);
370 EXPECT_TRUE(displays->GetDictionary(key, &layout_value));
371 EXPECT_TRUE(layout_value->GetString(kPositionKey, &position));
372 EXPECT_EQ("right", position);
373 EXPECT_TRUE(layout_value->GetInteger(kOffsetKey, &offset));
374 EXPECT_EQ(0, offset);
376 EXPECT_TRUE(layout_value->GetBoolean(kMirroredKey, &mirrored));
377 EXPECT_FALSE(mirrored);
378 EXPECT_TRUE(layout_value->GetString(kPrimaryIdKey, &primary_id_str));
379 EXPECT_EQ(base::Int64ToString(id1), primary_id_str);
381 // Best resolution should not be saved.
382 EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id2), &property));
383 EXPECT_FALSE(property->GetInteger("width", &width));
384 EXPECT_FALSE(property->GetInteger("height", &height));
386 // Set yet another new display's selected resolution.
387 display_manager->RegisterDisplayProperty(
388 id2 + 1, gfx::Display::ROTATE_0, 1.0f, NULL, gfx::Size(500, 400),
389 ui::COLOR_PROFILE_STANDARD);
390 // Disconnect 2nd display first to generate new id for external display.
391 UpdateDisplay("200x200*2");
392 UpdateDisplay("200x200*2, 500x400#600x500|500x400%60.0f");
393 // Update key as the 2nd display gets new id.
394 id2 = ash::ScreenUtil::GetSecondaryDisplay().id();
395 key = base::Int64ToString(id1) + "," + base::Int64ToString(id2);
396 EXPECT_TRUE(displays->GetDictionary(key, &layout_value));
397 EXPECT_TRUE(layout_value->GetString(kPositionKey, &position));
398 EXPECT_EQ("right", position);
399 EXPECT_TRUE(layout_value->GetInteger(kOffsetKey, &offset));
400 EXPECT_EQ(0, offset);
402 EXPECT_TRUE(layout_value->GetBoolean(kMirroredKey, &mirrored));
403 EXPECT_FALSE(mirrored);
404 EXPECT_TRUE(layout_value->GetString(kPrimaryIdKey, &primary_id_str));
405 EXPECT_EQ(base::Int64ToString(id1), primary_id_str);
407 // External display's selected resolution must be updated.
408 EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id2), &property));
409 EXPECT_TRUE(property->GetInteger("width", &width));
410 EXPECT_TRUE(property->GetInteger("height", &height));
411 EXPECT_EQ(500, width);
412 EXPECT_EQ(400, height);
415 TEST_F(DisplayPreferencesTest, PreventStore) {
416 ResolutionNotificationController::SuppressTimerForTest();
418 UpdateDisplay("400x300#500x400|400x300|300x200");
419 int64 id = ash::Shell::GetScreen()->GetPrimaryDisplay().id();
420 // Set display's resolution in single display. It creates the notification and
421 // display preferences should not stored meanwhile.
422 ash::Shell::GetInstance()->resolution_notification_controller()->
423 SetDisplayResolutionAndNotify(
424 id, gfx::Size(400, 300), gfx::Size(500, 400), base::Closure());
425 UpdateDisplay("500x400#500x400|400x300|300x200");
427 const base::DictionaryValue* properties =
428 local_state()->GetDictionary(prefs::kDisplayProperties);
429 const base::DictionaryValue* property = NULL;
430 EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id), &property));
431 int width = 0, height = 0;
432 EXPECT_FALSE(property->GetInteger("width", &width));
433 EXPECT_FALSE(property->GetInteger("height", &height));
435 // Revert the change. When timeout, 2nd button is revert.
436 message_center::MessageCenter::Get()->ClickOnNotificationButton(
437 ResolutionNotificationController::kNotificationId, 1);
438 RunAllPendingInMessageLoop();
439 EXPECT_FALSE(message_center::MessageCenter::Get()->HasNotification(
440 ResolutionNotificationController::kNotificationId));
442 // Once the notification is removed, the specified resolution will be stored
443 // by SetDisplayResolution.
444 ash::Shell::GetInstance()->display_manager()->SetDisplayResolution(
445 id, gfx::Size(300, 200));
446 UpdateDisplay("300x200#500x400|400x300|300x200");
449 EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id), &property));
450 EXPECT_TRUE(property->GetInteger("width", &width));
451 EXPECT_TRUE(property->GetInteger("height", &height));
452 EXPECT_EQ(300, width);
453 EXPECT_EQ(200, height);
456 TEST_F(DisplayPreferencesTest, StoreForSwappedDisplay) {
457 UpdateDisplay("100x100,200x200");
458 int64 id1 = gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().id();
459 int64 id2 = ash::ScreenUtil::GetSecondaryDisplay().id();
461 ash::DisplayController* display_controller =
462 ash::Shell::GetInstance()->display_controller();
463 display_controller->SwapPrimaryDisplay();
464 ASSERT_EQ(id1, ash::ScreenUtil::GetSecondaryDisplay().id());
467 ash::DisplayLayout layout(ash::DisplayLayout::TOP, 10);
468 SetCurrentDisplayLayout(layout);
469 layout = layout.Invert();
471 const base::DictionaryValue* displays =
472 local_state()->GetDictionary(prefs::kSecondaryDisplays);
473 const base::DictionaryValue* new_value = NULL;
474 std::string key = base::Int64ToString(id1) + "," + base::Int64ToString(id2);
475 EXPECT_TRUE(displays->GetDictionary(key, &new_value));
477 ash::DisplayLayout stored_layout;
478 EXPECT_TRUE(ash::DisplayLayout::ConvertFromValue(*new_value, &stored_layout));
479 EXPECT_EQ(layout.position, stored_layout.position);
480 EXPECT_EQ(layout.offset, stored_layout.offset);
481 EXPECT_EQ(id2, stored_layout.primary_id);
483 display_controller->SwapPrimaryDisplay();
484 EXPECT_TRUE(displays->GetDictionary(key, &new_value));
485 EXPECT_TRUE(ash::DisplayLayout::ConvertFromValue(*new_value, &stored_layout));
486 EXPECT_EQ(layout.position, stored_layout.position);
487 EXPECT_EQ(layout.offset, stored_layout.offset);
488 EXPECT_EQ(id1, stored_layout.primary_id);
491 TEST_F(DisplayPreferencesTest, RestoreColorProfiles) {
492 ash::DisplayManager* display_manager =
493 ash::Shell::GetInstance()->display_manager();
495 int64 id1 = gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().id();
497 StoreColorProfile(id1, "dynamic");
500 LoadDisplayPreferences(false);
502 // id1's available color profiles list is empty, means somehow the color
503 // profile suport is temporary in trouble.
504 EXPECT_NE(ui::COLOR_PROFILE_DYNAMIC,
505 display_manager->GetDisplayInfo(id1).color_profile());
507 // Once the profile is supported, the color profile should be restored.
508 std::vector<ui::ColorCalibrationProfile> profiles;
509 profiles.push_back(ui::COLOR_PROFILE_STANDARD);
510 profiles.push_back(ui::COLOR_PROFILE_DYNAMIC);
511 profiles.push_back(ui::COLOR_PROFILE_MOVIE);
512 profiles.push_back(ui::COLOR_PROFILE_READING);
513 ash::test::DisplayManagerTestApi test_api(display_manager);
514 test_api.SetAvailableColorProfiles(id1, profiles);
516 LoadDisplayPreferences(false);
517 EXPECT_EQ(ui::COLOR_PROFILE_DYNAMIC,
518 display_manager->GetDisplayInfo(id1).color_profile());
521 TEST_F(DisplayPreferencesTest, DontStoreInGuestMode) {
522 ash::DisplayController* display_controller =
523 ash::Shell::GetInstance()->display_controller();
524 ash::DisplayManager* display_manager =
525 ash::Shell::GetInstance()->display_manager();
527 UpdateDisplay("200x200*2,200x200");
530 int64 id1 = ash::Shell::GetScreen()->GetPrimaryDisplay().id();
531 gfx::Display::SetInternalDisplayId(id1);
532 int64 id2 = ash::ScreenUtil::GetSecondaryDisplay().id();
533 ash::DisplayLayout layout(ash::DisplayLayout::TOP, 10);
534 SetCurrentDisplayLayout(layout);
535 display_manager->SetDisplayUIScale(id1, 1.25f);
536 display_controller->SetPrimaryDisplayId(id2);
537 int64 new_primary = ash::Shell::GetScreen()->GetPrimaryDisplay().id();
538 display_controller->SetOverscanInsets(
540 gfx::Insets(10, 11, 12, 13));
541 display_manager->SetDisplayRotation(new_primary, gfx::Display::ROTATE_90);
543 // Does not store the preferences locally.
544 EXPECT_FALSE(local_state()->FindPreference(
545 prefs::kSecondaryDisplays)->HasUserSetting());
546 EXPECT_FALSE(local_state()->FindPreference(
547 prefs::kDisplayProperties)->HasUserSetting());
549 // Settings are still notified to the system.
550 gfx::Screen* screen = gfx::Screen::GetNativeScreen();
551 EXPECT_EQ(id2, screen->GetPrimaryDisplay().id());
552 EXPECT_EQ(ash::DisplayLayout::BOTTOM,
553 display_manager->GetCurrentDisplayLayout().position);
554 EXPECT_EQ(-10, display_manager->GetCurrentDisplayLayout().offset);
555 const gfx::Display& primary_display = screen->GetPrimaryDisplay();
556 EXPECT_EQ("178x176", primary_display.bounds().size().ToString());
557 EXPECT_EQ(gfx::Display::ROTATE_90, primary_display.rotation());
559 const ash::DisplayInfo& info1 = display_manager->GetDisplayInfo(id1);
560 EXPECT_EQ(1.25f, info1.configured_ui_scale());
562 const ash::DisplayInfo& info_primary =
563 display_manager->GetDisplayInfo(new_primary);
564 EXPECT_EQ(gfx::Display::ROTATE_90, info_primary.rotation());
565 EXPECT_EQ(1.0f, info_primary.configured_ui_scale());
568 TEST_F(DisplayPreferencesTest, StorePowerStateNoLogin) {
569 EXPECT_FALSE(local_state()->HasPrefPath(prefs::kDisplayPowerState));
571 // Stores display prefs without login, which still stores the power state.
573 EXPECT_TRUE(local_state()->HasPrefPath(prefs::kDisplayPowerState));
576 TEST_F(DisplayPreferencesTest, StorePowerStateGuest) {
577 EXPECT_FALSE(local_state()->HasPrefPath(prefs::kDisplayPowerState));
581 EXPECT_TRUE(local_state()->HasPrefPath(prefs::kDisplayPowerState));
584 TEST_F(DisplayPreferencesTest, StorePowerStateNormalUser) {
585 EXPECT_FALSE(local_state()->HasPrefPath(prefs::kDisplayPowerState));
589 EXPECT_TRUE(local_state()->HasPrefPath(prefs::kDisplayPowerState));
592 TEST_F(DisplayPreferencesTest, DisplayPowerStateAfterRestart) {
593 StoreDisplayPowerStateForTest(
594 chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON);
595 LoadDisplayPreferences(false);
596 EXPECT_EQ(chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON,
597 ash::Shell::GetInstance()->display_configurator()->power_state());
600 TEST_F(DisplayPreferencesTest, DontSaveAndRestoreAllOff) {
601 ash::Shell* shell = ash::Shell::GetInstance();
602 StoreDisplayPowerStateForTest(
603 chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON);
604 LoadDisplayPreferences(false);
605 // DisplayPowerState should be ignored at boot.
606 EXPECT_EQ(chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON,
607 shell->display_configurator()->power_state());
609 StoreDisplayPowerStateForTest(
610 chromeos::DISPLAY_POWER_ALL_OFF);
611 EXPECT_EQ(chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON,
612 shell->display_configurator()->power_state());
613 EXPECT_EQ("internal_off_external_on",
614 local_state()->GetString(prefs::kDisplayPowerState));
617 local_state()->SetString(prefs::kDisplayPowerState, "all_off");
618 LoadDisplayPreferences(false);
619 EXPECT_EQ(chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON,
620 shell->display_configurator()->power_state());
623 } // namespace chromeos