blob: dd4271f18cd638183a59953582f0892e946bb6af [file] [log] [blame]
[email protected]78e237042013-01-02 22:35:091// 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
avi8a07d53892015-12-24 22:13:537#include <stdint.h>
dcheng24002d02016-04-08 02:42:408
[email protected]2a57beb52014-06-09 20:02:269#include <string>
dcheng7c802f02015-12-31 16:09:5510#include <utility>
[email protected]2a57beb52014-06-09 20:02:2611#include <vector>
12
oshima81d33282015-07-27 21:16:0113#include "ash/display/display_util.h"
[email protected]6ef71d72013-08-10 18:13:4414#include "ash/display/resolution_notification_controller.h"
benf6de9852015-10-06 21:29:2815#include "ash/display/screen_orientation_controller_chromeos.h"
oshimae2818922015-07-28 01:18:5216#include "ash/display/window_tree_host_manager.h"
rjkroege980ccfd2016-10-06 18:00:2417#include "ash/shell.h"
[email protected]78e237042013-01-02 22:35:0918#include "ash/test/ash_test_base.h"
Mitsuru Oshima0e9b7a62017-07-19 18:23:0319#include "ash/wm/tablet_mode/tablet_mode_controller.h"
avi8a07d53892015-12-24 22:13:5320#include "base/macros.h"
dcheng24002d02016-04-08 02:42:4021#include "base/memory/ptr_util.h"
jonrossd6b77052015-03-11 22:04:3522#include "base/memory/ref_counted.h"
[email protected]3ea1b182013-02-08 22:38:4123#include "base/strings/string_number_conversions.h"
[email protected]78e237042013-01-02 22:35:0924#include "base/values.h"
[email protected]945ece962013-03-21 06:42:3925#include "chrome/browser/chromeos/display/display_configuration_observer.h"
[email protected]83d82d42014-05-16 02:04:4226#include "chrome/browser/chromeos/login/users/mock_user_manager.h"
[email protected]4d390782014-08-15 09:22:5827#include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
[email protected]78e237042013-01-02 22:35:0928#include "chrome/common/pref_names.h"
29#include "chrome/test/base/testing_browser_process.h"
brettwb1fc1b82016-02-02 00:19:0830#include "components/prefs/scoped_user_pref_update.h"
31#include "components/prefs/testing_pref_service.h"
kylechar731f85f92016-12-01 20:50:4632#include "ui/display/display_layout_builder.h"
33#include "ui/display/manager/chromeos/display_configurator.h"
F#m4791c3d72017-11-03 21:39:5834#include "ui/display/manager/chromeos/test/touch_device_manager_test_api.h"
kylechar7eaccca2016-08-19 15:16:0735#include "ui/display/manager/display_layout_store.h"
rjkroege72f8154f2016-10-29 00:49:0236#include "ui/display/manager/display_manager.h"
rjkroege0458f012016-08-31 00:31:3637#include "ui/display/manager/display_manager_utilities.h"
thanhph9a5d2652017-03-18 18:57:1138#include "ui/display/manager/json_converter.h"
oshimad5c972e2016-04-28 23:17:1439#include "ui/display/screen.h"
rjkroege72f8154f2016-10-29 00:49:0240#include "ui/display/test/display_manager_test_api.h"
tfarinaa2a039f2014-10-23 03:40:0241#include "ui/gfx/geometry/vector3d_f.h"
[email protected]6ef71d72013-08-10 18:13:4442#include "ui/message_center/message_center.h"
43
[email protected]093b8d642014-04-03 20:59:2844using ash::ResolutionNotificationController;
[email protected]78e237042013-01-02 22:35:0945
46namespace chromeos {
47namespace {
[email protected]29190fd2013-03-30 16:09:5048const char kPrimaryIdKey[] = "primary-id";
49const char kMirroredKey[] = "mirrored";
50const char kPositionKey[] = "position";
51const char kOffsetKey[] = "offset";
oshima61af6e12016-02-12 01:00:5252const char kPlacementDisplayIdKey[] = "placement.display_id";
53const char kPlacementParentDisplayIdKey[] = "placement.parent_display_id";
[email protected]78e237042013-01-02 22:35:0954
flackr45f31ae72014-09-02 18:50:2555// The mean acceleration due to gravity on Earth in m/s^2.
jonross01d453e2015-08-28 15:06:3056const float kMeanGravity = -9.80665f;
flackr45f31ae72014-09-02 18:50:2557
jonross0af45212015-01-13 18:55:4658bool IsRotationLocked() {
skycb4be5b2017-04-06 17:52:4559 return ash::Shell::Get()->screen_orientation_controller()->rotation_locked();
jonross0af45212015-01-13 18:55:4660}
61
F#m4791c3d72017-11-03 21:39:5862bool CompareTouchAssociations(
63 const display::TouchDeviceManager::TouchAssociationMap& map_1,
64 const display::TouchDeviceManager::TouchAssociationMap& map_2) {
65 if (map_1.size() != map_2.size())
66 return false;
67 // Each iterator instance |entry| is a pair of type
68 // std::pair<display::TouchDeviceIdentifier,
69 // display::TouchDeviceManager::AssociationInfoMap>
70 for (const auto& entry : map_1) {
71 if (!map_2.count(entry.first))
72 return false;
73
74 const auto& association_info_map_1 = entry.second;
75 const auto& association_info_map_2 = map_2.at(entry.first);
76 if (association_info_map_1.size() != association_info_map_2.size())
77 return false;
78
79 // Each iterator instance is a pair of type:
80 // std::pair<int64_t, display::TouchDeviceManager::TouchAssociationInfo>
81 for (const auto& info_1 : association_info_map_1) {
82 if (!association_info_map_2.count(info_1.first))
83 return false;
84
85 const auto& info_2 = association_info_map_2.at(info_1.first);
86 if (!(info_1.second.timestamp == info_2.timestamp &&
87 info_1.second.calibration_data == info_2.calibration_data)) {
88 return false;
89 }
90 }
91 }
92 return true;
93}
94
James Cook317781a2017-07-18 02:08:0695class DisplayPreferencesTest : public ash::AshTestBase {
[email protected]78e237042013-01-02 22:35:0996 protected:
[email protected]5e4891b2014-01-08 19:24:3597 DisplayPreferencesTest()
98 : mock_user_manager_(new MockUserManager),
99 user_manager_enabler_(mock_user_manager_) {
[email protected]9a68d3a2013-04-22 16:26:54100 }
101
dchengc97a0282015-01-15 23:04:24102 ~DisplayPreferencesTest() override {}
[email protected]78e237042013-01-02 22:35:09103
dchengc97a0282015-01-15 23:04:24104 void SetUp() override {
[email protected]9a68d3a2013-04-22 16:26:54105 EXPECT_CALL(*mock_user_manager_, IsUserLoggedIn())
[email protected]dcc990722013-03-24 16:35:20106 .WillRepeatedly(testing::Return(false));
[email protected]6ef71d72013-08-10 18:13:44107 EXPECT_CALL(*mock_user_manager_, Shutdown());
James Cook317781a2017-07-18 02:08:06108 ash::AshTestBase::SetUp();
[email protected]b1de2c72013-02-06 02:45:47109 RegisterDisplayLocalStatePrefs(local_state_.registry());
[email protected]c494d082013-01-04 20:41:22110 TestingBrowserProcess::GetGlobal()->SetLocalState(&local_state_);
Mitsuru Oshima3695b8be2017-10-09 14:18:36111 observer_ = std::make_unique<DisplayConfigurationObserver>();
112 observer_->OnDisplaysInitialized();
[email protected]78e237042013-01-02 22:35:09113 }
114
dchengc97a0282015-01-15 23:04:24115 void TearDown() override {
[email protected]945ece962013-03-21 06:42:39116 observer_.reset();
oshima95d499b2016-02-10 03:49:56117 TestingBrowserProcess::GetGlobal()->SetLocalState(nullptr);
James Cook317781a2017-07-18 02:08:06118 ash::AshTestBase::TearDown();
[email protected]78e237042013-01-02 22:35:09119 }
120
121 void LoggedInAsUser() {
[email protected]9a68d3a2013-04-22 16:26:54122 EXPECT_CALL(*mock_user_manager_, IsUserLoggedIn())
[email protected]78e237042013-01-02 22:35:09123 .WillRepeatedly(testing::Return(true));
merkulovac3ae44d2014-11-17 09:35:07124 EXPECT_CALL(*mock_user_manager_, IsLoggedInAsUserWithGaiaAccount())
[email protected]1ccbac12013-09-13 06:55:54125 .WillRepeatedly(testing::Return(true));
[email protected]78e237042013-01-02 22:35:09126 }
127
128 void LoggedInAsGuest() {
[email protected]9a68d3a2013-04-22 16:26:54129 EXPECT_CALL(*mock_user_manager_, IsUserLoggedIn())
[email protected]78e237042013-01-02 22:35:09130 .WillRepeatedly(testing::Return(true));
merkulovac3ae44d2014-11-17 09:35:07131 EXPECT_CALL(*mock_user_manager_, IsLoggedInAsUserWithGaiaAccount())
[email protected]78e237042013-01-02 22:35:09132 .WillRepeatedly(testing::Return(false));
[email protected]933cc2e22014-07-18 13:26:57133 EXPECT_CALL(*mock_user_manager_, IsLoggedInAsSupervisedUser())
[email protected]78e237042013-01-02 22:35:09134 .WillRepeatedly(testing::Return(false));
135 }
136
137 // Do not use the implementation of display_preferences.cc directly to avoid
138 // notifying the update to the system.
robliaoc0dfd6b2016-04-07 21:33:56139 void StoreDisplayLayoutPrefForList(
140 const display::DisplayIdList& list,
141 display::DisplayPlacement::Position position,
142 int offset,
143 int64_t primary_id) {
rjkroege0458f012016-08-31 00:31:36144 std::string name = display::DisplayIdListToString(list);
[email protected]78e237042013-01-02 22:35:09145 DictionaryPrefUpdate update(&local_state_, prefs::kSecondaryDisplays);
robliaoc0dfd6b2016-04-07 21:33:56146 display::DisplayLayout display_layout;
robliaodf372032016-03-23 00:42:34147 display_layout.placement_list.emplace_back(position, offset);
[email protected]29190fd2013-03-30 16:09:50148 display_layout.primary_id = primary_id;
[email protected]78e237042013-01-02 22:35:09149
[email protected]78e237042013-01-02 22:35:09150 DCHECK(!name.empty());
151
152 base::DictionaryValue* pref_data = update.Get();
dcheng24002d02016-04-08 02:42:40153 std::unique_ptr<base::Value> layout_value(new base::DictionaryValue());
Mitsuru Oshima3695b8be2017-10-09 14:18:36154 base::Value* value = nullptr;
155 if (pref_data->Get(name, &value) && value != nullptr)
156 layout_value.reset(value->DeepCopy());
thanhph9a5d2652017-03-18 18:57:11157 if (display::DisplayLayoutToJson(display_layout, layout_value.get()))
vabr6e421c602017-03-23 23:27:55158 pref_data->Set(name, std::move(layout_value));
[email protected]78e237042013-01-02 22:35:09159 }
160
Mitsuru Oshima3695b8be2017-10-09 14:18:36161 bool GetDisplayPropertyFromList(const display::DisplayIdList& list,
162 const std::string& key,
163 base::Value** out_value) {
164 std::string name = display::DisplayIdListToString(list);
165
166 DictionaryPrefUpdate update(&local_state_, prefs::kSecondaryDisplays);
167 base::DictionaryValue* pref_data = update.Get();
168
jdoerrie8deeec22017-10-27 13:39:48169 base::Value* layout_value = pref_data->FindKey(name);
Mitsuru Oshima3695b8be2017-10-09 14:18:36170 if (layout_value) {
171 return static_cast<base::DictionaryValue*>(layout_value)
172 ->Get(key, out_value);
173 }
174 return false;
175 }
176
robliaoc0dfd6b2016-04-07 21:33:56177 void StoreDisplayPropertyForList(const display::DisplayIdList& list,
Mitsuru Oshima3695b8be2017-10-09 14:18:36178 const std::string& key,
dcheng24002d02016-04-08 02:42:40179 std::unique_ptr<base::Value> value) {
rjkroege0458f012016-08-31 00:31:36180 std::string name = display::DisplayIdListToString(list);
oshimabba2d992015-05-22 19:21:39181
182 DictionaryPrefUpdate update(&local_state_, prefs::kSecondaryDisplays);
183 base::DictionaryValue* pref_data = update.Get();
184
jdoerrie8deeec22017-10-27 13:39:48185 base::Value* layout_value = pref_data->FindKey(name);
Mitsuru Oshima3695b8be2017-10-09 14:18:36186 if (layout_value) {
187 static_cast<base::DictionaryValue*>(layout_value)
188 ->Set(key, std::move(value));
oshimabba2d992015-05-22 19:21:39189 } else {
dcheng24002d02016-04-08 02:42:40190 std::unique_ptr<base::DictionaryValue> layout_value(
oshimabba2d992015-05-22 19:21:39191 new base::DictionaryValue());
dcheng6e5c22f92016-03-03 22:09:15192 layout_value->SetBoolean(key, value != nullptr);
vabr6e421c602017-03-23 23:27:55193 pref_data->Set(name, std::move(layout_value));
oshimabba2d992015-05-22 19:21:39194 }
battrede0c9e022015-05-22 09:48:00195 }
196
robliaoc0dfd6b2016-04-07 21:33:56197 void StoreDisplayBoolPropertyForList(const display::DisplayIdList& list,
oshimabba2d992015-05-22 19:21:39198 const std::string& key,
199 bool value) {
jdoerrie239723572017-03-02 12:09:19200 StoreDisplayPropertyForList(list, key,
201 base::MakeUnique<base::Value>(value));
oshimabba2d992015-05-22 19:21:39202 }
203
robliaoc0dfd6b2016-04-07 21:33:56204 void StoreDisplayLayoutPrefForList(const display::DisplayIdList& list,
205 display::DisplayPlacement::Position layout,
oshimabba2d992015-05-22 19:21:39206 int offset) {
oshima4763f822016-02-01 20:19:18207 StoreDisplayLayoutPrefForList(list, layout, offset, list[0]);
[email protected]0622b362013-03-02 17:43:16208 }
209
avi8a07d53892015-12-24 22:13:53210 void StoreDisplayOverscan(int64_t id, const gfx::Insets& insets) {
[email protected]8b2447e2013-03-22 21:13:31211 DictionaryPrefUpdate update(&local_state_, prefs::kDisplayProperties);
[email protected]78e237042013-01-02 22:35:09212 const std::string name = base::Int64ToString(id);
213
214 base::DictionaryValue* pref_data = update.Get();
vabr6e421c602017-03-23 23:27:55215 auto insets_value = base::MakeUnique<base::DictionaryValue>();
[email protected]8b2447e2013-03-22 21:13:31216 insets_value->SetInteger("insets_top", insets.top());
217 insets_value->SetInteger("insets_left", insets.left());
218 insets_value->SetInteger("insets_bottom", insets.bottom());
219 insets_value->SetInteger("insets_right", insets.right());
vabr6e421c602017-03-23 23:27:55220 pref_data->Set(name, std::move(insets_value));
[email protected]78e237042013-01-02 22:35:09221 }
222
[email protected]62e90d42014-08-20 15:23:32223 void StoreDisplayRotationPrefsForTest(bool rotation_lock,
oshimad5c972e2016-04-28 23:17:14224 display::Display::Rotation rotation) {
[email protected]62e90d42014-08-20 15:23:32225 DictionaryPrefUpdate update(local_state(), prefs::kDisplayRotationLock);
226 base::DictionaryValue* pref_data = update.Get();
227 pref_data->SetBoolean("lock", rotation_lock);
228 pref_data->SetInteger("orientation", static_cast<int>(rotation));
229 }
230
robliaoc0dfd6b2016-04-07 21:33:56231 std::string GetRegisteredDisplayPlacementStr(
232 const display::DisplayIdList& list) {
skycb4be5b2017-04-06 17:52:45233 return ash::Shell::Get()
oshima4763f822016-02-01 20:19:18234 ->display_manager()
235 ->layout_store()
236 ->GetRegisteredDisplayLayout(list)
oshimaf571c4a2016-02-24 18:51:05237 .placement_list[0]
robliaodf372032016-03-23 00:42:34238 .ToString();
[email protected]0622b362013-03-02 17:43:16239 }
240
[email protected]b732a6d2013-11-13 05:52:12241 PrefService* local_state() { return &local_state_; }
[email protected]78e237042013-01-02 22:35:09242
243 private:
[email protected]9a68d3a2013-04-22 16:26:54244 MockUserManager* mock_user_manager_; // Not owned.
245 ScopedUserManagerEnabler user_manager_enabler_;
[email protected]78e237042013-01-02 22:35:09246 TestingPrefServiceSimple local_state_;
Mitsuru Oshima3695b8be2017-10-09 14:18:36247 std::unique_ptr<ash::WindowTreeHostManager::Observer> observer_;
[email protected]78e237042013-01-02 22:35:09248
249 DISALLOW_COPY_AND_ASSIGN(DisplayPreferencesTest);
250};
251
[email protected]6ef71d72013-08-10 18:13:44252} // namespace
253
oshima4763f822016-02-01 20:19:18254TEST_F(DisplayPreferencesTest, ListedLayoutOverrides) {
[email protected]0622b362013-03-02 17:43:16255 UpdateDisplay("100x100,200x200");
[email protected]0622b362013-03-02 17:43:16256
rjkroege980ccfd2016-10-06 18:00:24257 display::DisplayIdList list = display_manager()->GetCurrentDisplayIdList();
robliaoc0dfd6b2016-04-07 21:33:56258 display::DisplayIdList dummy_list =
rjkroege72f8154f2016-10-29 00:49:02259 display::test::CreateDisplayIdList2(list[0], list[1] + 1);
oshima4763f822016-02-01 20:19:18260 ASSERT_NE(list[0], dummy_list[1]);
oshimabba2d992015-05-22 19:21:39261
robliaoc0dfd6b2016-04-07 21:33:56262 StoreDisplayLayoutPrefForList(list, display::DisplayPlacement::TOP, 20);
263 StoreDisplayLayoutPrefForList(dummy_list, display::DisplayPlacement::LEFT,
264 30);
[email protected]29190fd2013-03-30 16:09:50265 StoreDisplayPowerStateForTest(
266 chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON);
[email protected]0622b362013-03-02 17:43:16267
skycb4be5b2017-04-06 17:52:45268 ash::Shell* shell = ash::Shell::Get();
[email protected]29190fd2013-03-30 16:09:50269
270 LoadDisplayPreferences(true);
271 // DisplayPowerState should be ignored at boot.
272 EXPECT_EQ(chromeos::DISPLAY_POWER_ALL_ON,
derat4a062782014-09-25 21:46:13273 shell->display_configurator()->requested_power_state());
[email protected]29190fd2013-03-30 16:09:50274
275 shell->display_manager()->UpdateDisplays();
[email protected]0622b362013-03-02 17:43:16276 // Check if the layout settings are notified to the system properly.
oshima4763f822016-02-01 20:19:18277 // The new layout overrides old layout.
278 // Inverted one of for specified pair (id1, id2). Not used for the list
[email protected]0622b362013-03-02 17:43:16279 // (id1, dummy_id) since dummy_id is not connected right now.
oshimaf571c4a2016-02-24 18:51:05280 EXPECT_EQ("id=2200000001, parent=2200000000, top, 20",
281 shell->display_manager()
282 ->GetCurrentDisplayLayout()
283 .placement_list[0]
robliaodf372032016-03-23 00:42:34284 .ToString());
oshimaf571c4a2016-02-24 18:51:05285 EXPECT_EQ("id=2200000001, parent=2200000000, top, 20",
286 GetRegisteredDisplayPlacementStr(list));
287 EXPECT_EQ("id=2200000002, parent=2200000000, left, 30",
288 GetRegisteredDisplayPlacementStr(dummy_list));
[email protected]0622b362013-03-02 17:43:16289}
290
291TEST_F(DisplayPreferencesTest, BasicStores) {
oshimae2818922015-07-28 01:18:52292 ash::WindowTreeHostManager* window_tree_host_manager =
skycb4be5b2017-04-06 17:52:45293 ash::Shell::Get()->window_tree_host_manager();
[email protected]8b2447e2013-03-22 21:13:31294
[email protected]2f6bc702014-08-08 19:23:23295 UpdateDisplay("200x200*2, 400x300#400x400|300x200*1.25");
oshimad5c972e2016-04-28 23:17:14296 int64_t id1 = display::Screen::GetScreen()->GetPrimaryDisplay().id();
rjkroege72f8154f2016-10-29 00:49:02297 display::test::ScopedSetInternalDisplayId set_internal(display_manager(),
298 id1);
rjkroege980ccfd2016-10-06 18:00:24299 int64_t id2 = display_manager()->GetSecondaryDisplay().id();
avi8a07d53892015-12-24 22:13:53300 int64_t dummy_id = id2 + 1;
[email protected]78e237042013-01-02 22:35:09301 ASSERT_NE(id1, dummy_id);
302
303 LoggedInAsUser();
oshima61af6e12016-02-12 01:00:52304
rjkroege72f8154f2016-10-29 00:49:02305 display_manager()->SetLayoutForCurrentDisplays(
306 display::test::CreateDisplayLayout(display_manager(),
307 display::DisplayPlacement::TOP, 10));
robliaoc0dfd6b2016-04-07 21:33:56308 const display::DisplayLayout& layout =
rjkroege980ccfd2016-10-06 18:00:24309 display_manager()->GetCurrentDisplayLayout();
robliaoc0dfd6b2016-04-07 21:33:56310 EXPECT_EQ(display::DisplayPlacement::TOP, layout.placement_list[0].position);
robliaodf372032016-03-23 00:42:34311 EXPECT_EQ(10, layout.placement_list[0].offset);
oshima61af6e12016-02-12 01:00:52312
robliaoc0dfd6b2016-04-07 21:33:56313 display::DisplayLayoutBuilder dummy_layout_builder(id1);
314 dummy_layout_builder.SetSecondaryPlacement(
315 dummy_id, display::DisplayPlacement::LEFT, 20);
dcheng24002d02016-04-08 02:42:40316 std::unique_ptr<display::DisplayLayout> dummy_layout(
317 dummy_layout_builder.Build());
rjkroege72f8154f2016-10-29 00:49:02318 display::DisplayIdList list =
319 display::test::CreateDisplayIdList2(id1, dummy_id);
oshimaf571c4a2016-02-24 18:51:05320 StoreDisplayLayoutPrefForTest(list, *dummy_layout);
oshima61af6e12016-02-12 01:00:52321
[email protected]945ece962013-03-21 06:42:39322 // Can't switch to a display that does not exist.
oshimae2818922015-07-28 01:18:52323 window_tree_host_manager->SetPrimaryDisplayId(dummy_id);
oshimad5c972e2016-04-28 23:17:14324 EXPECT_NE(dummy_id, display::Screen::GetScreen()->GetPrimaryDisplay().id());
[email protected]945ece962013-03-21 06:42:39325
oshimae2818922015-07-28 01:18:52326 window_tree_host_manager->SetOverscanInsets(id1, gfx::Insets(10, 11, 12, 13));
rjkroege980ccfd2016-10-06 18:00:24327 display_manager()->SetDisplayRotation(id1, display::Display::ROTATE_90,
328 display::Display::ROTATION_SOURCE_USER);
rjkroege72f8154f2016-10-29 00:49:02329 EXPECT_TRUE(display::test::DisplayManagerTestApi(display_manager())
afakhry8571a9c2016-10-26 22:03:41330 .SetDisplayUIScale(id1, 1.25f));
rjkroege72f8154f2016-10-29 00:49:02331 EXPECT_FALSE(display::test::DisplayManagerTestApi(display_manager())
afakhry8571a9c2016-10-26 22:03:41332 .SetDisplayUIScale(id2, 1.25f));
[email protected]78e237042013-01-02 22:35:09333
malaykeshav4d3a49e2016-12-06 00:03:11334 // Set touch calibration data for display |id2|.
F#m6662d832017-10-27 16:55:01335 uint32_t id_1 = 1234;
336 const display::TouchDeviceIdentifier touch_device_identifier_1(id_1);
F#m02490122017-09-28 22:47:24337 display::TouchCalibrationData::CalibrationPointPairQuad point_pair_quad_1 = {
malaykeshav4d3a49e2016-12-06 00:03:11338 {std::make_pair(gfx::Point(10, 10), gfx::Point(11, 12)),
339 std::make_pair(gfx::Point(190, 10), gfx::Point(195, 8)),
340 std::make_pair(gfx::Point(10, 90), gfx::Point(12, 94)),
341 std::make_pair(gfx::Point(190, 90), gfx::Point(189, 88))}};
F#m02490122017-09-28 22:47:24342 gfx::Size touch_size_1(200, 150);
343
F#m6662d832017-10-27 16:55:01344 uint32_t id_2 = 2345;
345 const display::TouchDeviceIdentifier touch_device_identifier_2(id_2);
F#m02490122017-09-28 22:47:24346 display::TouchCalibrationData::CalibrationPointPairQuad point_pair_quad_2 = {
347 {std::make_pair(gfx::Point(10, 10), gfx::Point(11, 12)),
348 std::make_pair(gfx::Point(190, 10), gfx::Point(195, 8)),
349 std::make_pair(gfx::Point(10, 90), gfx::Point(12, 94)),
350 std::make_pair(gfx::Point(190, 90), gfx::Point(189, 88))}};
351 gfx::Size touch_size_2(150, 150);
352
353 display_manager()->SetTouchCalibrationData(
354 id2, point_pair_quad_1, touch_size_1, touch_device_identifier_1);
355 display_manager()->SetTouchCalibrationData(
356 id2, point_pair_quad_2, touch_size_2, touch_device_identifier_2);
malaykeshav4d3a49e2016-12-06 00:03:11357
[email protected]78e237042013-01-02 22:35:09358 const base::DictionaryValue* displays =
359 local_state()->GetDictionary(prefs::kSecondaryDisplays);
oshima95d499b2016-02-10 03:49:56360 const base::DictionaryValue* layout_value = nullptr;
[email protected]0622b362013-03-02 17:43:16361 std::string key = base::Int64ToString(id1) + "," + base::Int64ToString(id2);
oshima61af6e12016-02-12 01:00:52362 std::string dummy_key =
363 base::Int64ToString(id1) + "," + base::Int64ToString(dummy_id);
364 EXPECT_TRUE(displays->GetDictionary(dummy_key, &layout_value));
[email protected]29190fd2013-03-30 16:09:50365
robliaoc0dfd6b2016-04-07 21:33:56366 display::DisplayLayout stored_layout;
thanhph9a5d2652017-03-18 18:57:11367 EXPECT_TRUE(display::JsonToDisplayLayout(*layout_value, &stored_layout));
oshimaf571c4a2016-02-24 18:51:05368 ASSERT_EQ(1u, stored_layout.placement_list.size());
369
robliaodf372032016-03-23 00:42:34370 EXPECT_EQ(dummy_layout->placement_list[0].position,
371 stored_layout.placement_list[0].position);
372 EXPECT_EQ(dummy_layout->placement_list[0].offset,
373 stored_layout.placement_list[0].offset);
[email protected]78e237042013-01-02 22:35:09374
[email protected]dcc990722013-03-24 16:35:20375 bool mirrored = true;
[email protected]29190fd2013-03-30 16:09:50376 EXPECT_TRUE(layout_value->GetBoolean(kMirroredKey, &mirrored));
[email protected]dcc990722013-03-24 16:35:20377 EXPECT_FALSE(mirrored);
378
[email protected]8b2447e2013-03-22 21:13:31379 const base::DictionaryValue* properties =
380 local_state()->GetDictionary(prefs::kDisplayProperties);
oshima95d499b2016-02-10 03:49:56381 const base::DictionaryValue* property = nullptr;
[email protected]8b2447e2013-03-22 21:13:31382 EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id1), &property));
383 int ui_scale = 0;
384 int rotation = 0;
385 EXPECT_TRUE(property->GetInteger("rotation", &rotation));
386 EXPECT_TRUE(property->GetInteger("ui-scale", &ui_scale));
387 EXPECT_EQ(1, rotation);
388 EXPECT_EQ(1250, ui_scale);
389
[email protected]2bd1fcf02014-02-12 22:35:53390 // Internal display never registered the resolution.
[email protected]a5792d32013-08-01 11:18:21391 int width = 0, height = 0;
392 EXPECT_FALSE(property->GetInteger("width", &width));
393 EXPECT_FALSE(property->GetInteger("height", &height));
394
[email protected]78e237042013-01-02 22:35:09395 int top = 0, left = 0, bottom = 0, right = 0;
[email protected]8b2447e2013-03-22 21:13:31396 EXPECT_TRUE(property->GetInteger("insets_top", &top));
397 EXPECT_TRUE(property->GetInteger("insets_left", &left));
398 EXPECT_TRUE(property->GetInteger("insets_bottom", &bottom));
399 EXPECT_TRUE(property->GetInteger("insets_right", &right));
[email protected]78e237042013-01-02 22:35:09400 EXPECT_EQ(10, top);
401 EXPECT_EQ(11, left);
402 EXPECT_EQ(12, bottom);
403 EXPECT_EQ(13, right);
[email protected]945ece962013-03-21 06:42:39404
F#m4791c3d72017-11-03 21:39:58405 display::TouchDeviceManager* tdm = display_manager()->touch_device_manager();
406 display::test::TouchDeviceManagerTestApi tdm_test_api(tdm);
407 display::TouchDeviceManager::TouchAssociationMap
408 expected_touch_associations_map = tdm->touch_associations();
409 tdm_test_api.ResetTouchDeviceManager();
410
411 EXPECT_FALSE(CompareTouchAssociations(expected_touch_associations_map,
412 tdm->touch_associations()));
413
414 LoadTouchAssociationPreferenceForTest();
415
416 display::TouchDeviceManager::TouchAssociationMap
417 actual_touch_associations_map = tdm->touch_associations();
418
419 EXPECT_TRUE(CompareTouchAssociations(actual_touch_associations_map,
420 expected_touch_associations_map));
421
malaykeshav4d3a49e2016-12-06 00:03:11422 std::string touch_str;
malaykeshav4d3a49e2016-12-06 00:03:11423
[email protected]8b2447e2013-03-22 21:13:31424 EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id2), &property));
425 EXPECT_TRUE(property->GetInteger("rotation", &rotation));
426 EXPECT_TRUE(property->GetInteger("ui-scale", &ui_scale));
427 EXPECT_EQ(0, rotation);
428 // ui_scale works only on 2x scale factor/1st display.
429 EXPECT_EQ(1000, ui_scale);
430 EXPECT_FALSE(property->GetInteger("insets_top", &top));
431 EXPECT_FALSE(property->GetInteger("insets_left", &left));
432 EXPECT_FALSE(property->GetInteger("insets_bottom", &bottom));
433 EXPECT_FALSE(property->GetInteger("insets_right", &right));
434
[email protected]a5792d32013-08-01 11:18:21435 // Resolution is saved only when the resolution is set
[email protected]2f6bc702014-08-08 19:23:23436 // by DisplayManager::SetDisplayMode
[email protected]a5792d32013-08-01 11:18:21437 width = 0;
438 height = 0;
439 EXPECT_FALSE(property->GetInteger("width", &width));
440 EXPECT_FALSE(property->GetInteger("height", &height));
441
Miguel Casas-Sanchezbe6c66632017-10-19 16:40:23442 display::ManagedDisplayMode mode(gfx::Size(300, 200), 60.0f, false, true,
443 1.0 /* ui_scale */,
444 1.25f /* device_scale_factor */);
rjkroege980ccfd2016-10-06 18:00:24445 display_manager()->SetDisplayMode(id2, mode);
[email protected]a5792d32013-08-01 11:18:21446
oshimae2818922015-07-28 01:18:52447 window_tree_host_manager->SetPrimaryDisplayId(id2);
[email protected]29190fd2013-03-30 16:09:50448
oshimad5c972e2016-04-28 23:17:14449 EXPECT_EQ(id2, display::Screen::GetScreen()->GetPrimaryDisplay().id());
oshimaf571c4a2016-02-24 18:51:05450
[email protected]a5792d32013-08-01 11:18:21451 EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id1), &property));
452 width = 0;
453 height = 0;
[email protected]2bd1fcf02014-02-12 22:35:53454 // Internal display shouldn't store its resolution.
[email protected]a5792d32013-08-01 11:18:21455 EXPECT_FALSE(property->GetInteger("width", &width));
456 EXPECT_FALSE(property->GetInteger("height", &height));
457
[email protected]2bd1fcf02014-02-12 22:35:53458 // External display's resolution must be stored this time because
[email protected]885f26722013-08-13 06:37:47459 // it's not best.
[email protected]2f6bc702014-08-08 19:23:23460 int device_scale_factor = 0;
[email protected]a5792d32013-08-01 11:18:21461 EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id2), &property));
462 EXPECT_TRUE(property->GetInteger("width", &width));
463 EXPECT_TRUE(property->GetInteger("height", &height));
[email protected]2f6bc702014-08-08 19:23:23464 EXPECT_TRUE(property->GetInteger(
465 "device-scale-factor", &device_scale_factor));
[email protected]885f26722013-08-13 06:37:47466 EXPECT_EQ(300, width);
467 EXPECT_EQ(200, height);
[email protected]2f6bc702014-08-08 19:23:23468 EXPECT_EQ(1250, device_scale_factor);
[email protected]a5792d32013-08-01 11:18:21469
oshima61af6e12016-02-12 01:00:52470 // The layout is swapped.
[email protected]29190fd2013-03-30 16:09:50471 EXPECT_TRUE(displays->GetDictionary(key, &layout_value));
oshimaf571c4a2016-02-24 18:51:05472
thanhph9a5d2652017-03-18 18:57:11473 EXPECT_TRUE(display::JsonToDisplayLayout(*layout_value, &stored_layout));
oshimaf571c4a2016-02-24 18:51:05474 ASSERT_EQ(1u, stored_layout.placement_list.size());
robliaoc0dfd6b2016-04-07 21:33:56475 const display::DisplayPlacement& stored_placement =
robliaodf372032016-03-23 00:42:34476 stored_layout.placement_list[0];
robliaoc0dfd6b2016-04-07 21:33:56477 EXPECT_EQ(display::DisplayPlacement::BOTTOM, stored_placement.position);
oshimaf571c4a2016-02-24 18:51:05478 EXPECT_EQ(-10, stored_placement.offset);
479 EXPECT_EQ(id1, stored_placement.display_id);
480 EXPECT_EQ(id2, stored_placement.parent_display_id);
[email protected]29190fd2013-03-30 16:09:50481 EXPECT_EQ(id2, stored_layout.primary_id);
482
oshimaf571c4a2016-02-24 18:51:05483 if (true)
484 return;
485
[email protected]dcc990722013-03-24 16:35:20486 mirrored = true;
[email protected]29190fd2013-03-30 16:09:50487 EXPECT_TRUE(layout_value->GetBoolean(kMirroredKey, &mirrored));
[email protected]dcc990722013-03-24 16:35:20488 EXPECT_FALSE(mirrored);
[email protected]29190fd2013-03-30 16:09:50489 std::string primary_id_str;
490 EXPECT_TRUE(layout_value->GetString(kPrimaryIdKey, &primary_id_str));
491 EXPECT_EQ(base::Int64ToString(id2), primary_id_str);
[email protected]dcc990722013-03-24 16:35:20492
rjkroege72f8154f2016-10-29 00:49:02493 display_manager()->SetLayoutForCurrentDisplays(
skycb4be5b2017-04-06 17:52:45494 display::test::CreateDisplayLayout(ash::Shell::Get()->display_manager(),
495 display::DisplayPlacement::BOTTOM,
496 20));
[email protected]dcc990722013-03-24 16:35:20497
[email protected]d41e8892013-07-11 08:03:49498 UpdateDisplay("1+0-200x200*2,1+0-200x200");
[email protected]dcc990722013-03-24 16:35:20499 // Mirrored.
500 int offset = 0;
501 std::string position;
[email protected]29190fd2013-03-30 16:09:50502 EXPECT_TRUE(displays->GetDictionary(key, &layout_value));
503 EXPECT_TRUE(layout_value->GetString(kPositionKey, &position));
oshima61af6e12016-02-12 01:00:52504 EXPECT_EQ("bottom", position);
[email protected]29190fd2013-03-30 16:09:50505 EXPECT_TRUE(layout_value->GetInteger(kOffsetKey, &offset));
oshima61af6e12016-02-12 01:00:52506 EXPECT_EQ(20, offset);
507 std::string id;
508 EXPECT_TRUE(layout_value->GetString(kPlacementDisplayIdKey, &id));
509 EXPECT_EQ(base::Int64ToString(id1), id);
510 EXPECT_TRUE(layout_value->GetString(kPlacementParentDisplayIdKey, &id));
511 EXPECT_EQ(base::Int64ToString(id2), id);
512
[email protected]dcc990722013-03-24 16:35:20513 mirrored = false;
[email protected]29190fd2013-03-30 16:09:50514 EXPECT_TRUE(layout_value->GetBoolean(kMirroredKey, &mirrored));
[email protected]dcc990722013-03-24 16:35:20515 EXPECT_TRUE(mirrored);
[email protected]29190fd2013-03-30 16:09:50516 EXPECT_TRUE(layout_value->GetString(kPrimaryIdKey, &primary_id_str));
517 EXPECT_EQ(base::Int64ToString(id2), primary_id_str);
[email protected]dcc990722013-03-24 16:35:20518
[email protected]a5792d32013-08-01 11:18:21519 EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id1), &property));
520 EXPECT_FALSE(property->GetInteger("width", &width));
521 EXPECT_FALSE(property->GetInteger("height", &height));
522
[email protected]2bd1fcf02014-02-12 22:35:53523 // External display's selected resolution must not change
[email protected]a5792d32013-08-01 11:18:21524 // by mirroring.
525 EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id2), &property));
526 EXPECT_TRUE(property->GetInteger("width", &width));
527 EXPECT_TRUE(property->GetInteger("height", &height));
[email protected]885f26722013-08-13 06:37:47528 EXPECT_EQ(300, width);
529 EXPECT_EQ(200, height);
[email protected]a5792d32013-08-01 11:18:21530
531 // Set new display's selected resolution.
rjkroege980ccfd2016-10-06 18:00:24532 display_manager()->RegisterDisplayProperty(
533 id2 + 1, display::Display::ROTATE_0, 1.0f, nullptr, gfx::Size(500, 400),
F#m4791c3d72017-11-03 21:39:58534 1.0f);
[email protected]885f26722013-08-13 06:37:47535
536 UpdateDisplay("200x200*2, 600x500#600x500|500x400");
537
[email protected]dcc990722013-03-24 16:35:20538 // Update key as the 2nd display gets new id.
rjkroege980ccfd2016-10-06 18:00:24539 id2 = display_manager()->GetSecondaryDisplay().id();
[email protected]dcc990722013-03-24 16:35:20540 key = base::Int64ToString(id1) + "," + base::Int64ToString(id2);
[email protected]29190fd2013-03-30 16:09:50541 EXPECT_TRUE(displays->GetDictionary(key, &layout_value));
542 EXPECT_TRUE(layout_value->GetString(kPositionKey, &position));
[email protected]dcc990722013-03-24 16:35:20543 EXPECT_EQ("right", position);
[email protected]29190fd2013-03-30 16:09:50544 EXPECT_TRUE(layout_value->GetInteger(kOffsetKey, &offset));
[email protected]dcc990722013-03-24 16:35:20545 EXPECT_EQ(0, offset);
546 mirrored = true;
[email protected]29190fd2013-03-30 16:09:50547 EXPECT_TRUE(layout_value->GetBoolean(kMirroredKey, &mirrored));
[email protected]dcc990722013-03-24 16:35:20548 EXPECT_FALSE(mirrored);
[email protected]29190fd2013-03-30 16:09:50549 EXPECT_TRUE(layout_value->GetString(kPrimaryIdKey, &primary_id_str));
550 EXPECT_EQ(base::Int64ToString(id1), primary_id_str);
[email protected]a5792d32013-08-01 11:18:21551
[email protected]5e4891b2014-01-08 19:24:35552 // Best resolution should not be saved.
553 EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id2), &property));
554 EXPECT_FALSE(property->GetInteger("width", &width));
555 EXPECT_FALSE(property->GetInteger("height", &height));
556
557 // Set yet another new display's selected resolution.
rjkroege980ccfd2016-10-06 18:00:24558 display_manager()->RegisterDisplayProperty(
559 id2 + 1, display::Display::ROTATE_0, 1.0f, nullptr, gfx::Size(500, 400),
F#m4791c3d72017-11-03 21:39:58560 1.0f);
[email protected]5e4891b2014-01-08 19:24:35561 // Disconnect 2nd display first to generate new id for external display.
562 UpdateDisplay("200x200*2");
[email protected]2bd1fcf02014-02-12 22:35:53563 UpdateDisplay("200x200*2, 500x400#600x500|500x400%60.0f");
[email protected]5e4891b2014-01-08 19:24:35564 // Update key as the 2nd display gets new id.
rjkroege980ccfd2016-10-06 18:00:24565 id2 = display_manager()->GetSecondaryDisplay().id();
[email protected]5e4891b2014-01-08 19:24:35566 key = base::Int64ToString(id1) + "," + base::Int64ToString(id2);
567 EXPECT_TRUE(displays->GetDictionary(key, &layout_value));
568 EXPECT_TRUE(layout_value->GetString(kPositionKey, &position));
569 EXPECT_EQ("right", position);
570 EXPECT_TRUE(layout_value->GetInteger(kOffsetKey, &offset));
571 EXPECT_EQ(0, offset);
572 mirrored = true;
573 EXPECT_TRUE(layout_value->GetBoolean(kMirroredKey, &mirrored));
574 EXPECT_FALSE(mirrored);
575 EXPECT_TRUE(layout_value->GetString(kPrimaryIdKey, &primary_id_str));
576 EXPECT_EQ(base::Int64ToString(id1), primary_id_str);
577
[email protected]2bd1fcf02014-02-12 22:35:53578 // External display's selected resolution must be updated.
[email protected]a5792d32013-08-01 11:18:21579 EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id2), &property));
580 EXPECT_TRUE(property->GetInteger("width", &width));
581 EXPECT_TRUE(property->GetInteger("height", &height));
582 EXPECT_EQ(500, width);
583 EXPECT_EQ(400, height);
[email protected]78e237042013-01-02 22:35:09584}
585
[email protected]6ef71d72013-08-10 18:13:44586TEST_F(DisplayPreferencesTest, PreventStore) {
587 ResolutionNotificationController::SuppressTimerForTest();
588 LoggedInAsUser();
[email protected]885f26722013-08-13 06:37:47589 UpdateDisplay("400x300#500x400|400x300|300x200");
oshimad5c972e2016-04-28 23:17:14590 int64_t id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
[email protected]6ef71d72013-08-10 18:13:44591 // Set display's resolution in single display. It creates the notification and
592 // display preferences should not stored meanwhile.
skycb4be5b2017-04-06 17:52:45593 ash::Shell* shell = ash::Shell::Get();
rjkroege8503c152016-08-05 21:19:42594
Miguel Casas-Sanchezbe6c66632017-10-19 16:40:23595 display::ManagedDisplayMode old_mode(gfx::Size(400, 300));
596 display::ManagedDisplayMode new_mode(gfx::Size(500, 400));
afakhryd5fd8d942017-04-13 23:34:10597 EXPECT_TRUE(shell->resolution_notification_controller()
598 ->PrepareNotificationAndSetDisplayMode(id, old_mode, new_mode,
599 base::Closure()));
[email protected]885f26722013-08-13 06:37:47600 UpdateDisplay("500x400#500x400|400x300|300x200");
[email protected]6ef71d72013-08-10 18:13:44601
602 const base::DictionaryValue* properties =
603 local_state()->GetDictionary(prefs::kDisplayProperties);
oshima95d499b2016-02-10 03:49:56604 const base::DictionaryValue* property = nullptr;
[email protected]6ef71d72013-08-10 18:13:44605 EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id), &property));
606 int width = 0, height = 0;
607 EXPECT_FALSE(property->GetInteger("width", &width));
608 EXPECT_FALSE(property->GetInteger("height", &height));
609
610 // Revert the change. When timeout, 2nd button is revert.
611 message_center::MessageCenter::Get()->ClickOnNotificationButton(
612 ResolutionNotificationController::kNotificationId, 1);
613 RunAllPendingInMessageLoop();
[email protected]91ff44d82014-06-12 18:37:37614 EXPECT_FALSE(
615 message_center::MessageCenter::Get()->FindVisibleNotificationById(
616 ResolutionNotificationController::kNotificationId));
[email protected]6ef71d72013-08-10 18:13:44617
618 // Once the notification is removed, the specified resolution will be stored
[email protected]2f6bc702014-08-08 19:23:23619 // by SetDisplayMode.
skycb4be5b2017-04-06 17:52:45620 ash::Shell::Get()->display_manager()->SetDisplayMode(
Miguel Casas-Sanchezbe6c66632017-10-19 16:40:23621 id, display::ManagedDisplayMode(gfx::Size(300, 200), 60.0f, false, true));
[email protected]885f26722013-08-13 06:37:47622 UpdateDisplay("300x200#500x400|400x300|300x200");
[email protected]6ef71d72013-08-10 18:13:44623
oshima95d499b2016-02-10 03:49:56624 property = nullptr;
[email protected]6ef71d72013-08-10 18:13:44625 EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id), &property));
626 EXPECT_TRUE(property->GetInteger("width", &width));
627 EXPECT_TRUE(property->GetInteger("height", &height));
628 EXPECT_EQ(300, width);
629 EXPECT_EQ(200, height);
630}
631
[email protected]0622b362013-03-02 17:43:16632TEST_F(DisplayPreferencesTest, StoreForSwappedDisplay) {
633 UpdateDisplay("100x100,200x200");
oshimad5c972e2016-04-28 23:17:14634 int64_t id1 = display::Screen::GetScreen()->GetPrimaryDisplay().id();
rjkroege980ccfd2016-10-06 18:00:24635 int64_t id2 = display_manager()->GetSecondaryDisplay().id();
[email protected]0622b362013-03-02 17:43:16636
oshima61af6e12016-02-12 01:00:52637 LoggedInAsUser();
638
rjkroege980ccfd2016-10-06 18:00:24639 SwapPrimaryDisplay();
640 ASSERT_EQ(id1, display_manager()->GetSecondaryDisplay().id());
[email protected]0622b362013-03-02 17:43:16641
oshima61af6e12016-02-12 01:00:52642 std::string key = base::Int64ToString(id1) + "," + base::Int64ToString(id2);
[email protected]0622b362013-03-02 17:43:16643 const base::DictionaryValue* displays =
644 local_state()->GetDictionary(prefs::kSecondaryDisplays);
oshima61af6e12016-02-12 01:00:52645 // Initial saved value is swapped.
646 {
647 const base::DictionaryValue* new_value = nullptr;
648 EXPECT_TRUE(displays->GetDictionary(key, &new_value));
robliaoc0dfd6b2016-04-07 21:33:56649 display::DisplayLayout stored_layout;
thanhph9a5d2652017-03-18 18:57:11650 EXPECT_TRUE(display::JsonToDisplayLayout(*new_value, &stored_layout));
oshimaf571c4a2016-02-24 18:51:05651 ASSERT_EQ(1u, stored_layout.placement_list.size());
robliaoc0dfd6b2016-04-07 21:33:56652 const display::DisplayPlacement& stored_placement =
robliaodf372032016-03-23 00:42:34653 stored_layout.placement_list[0];
robliaoc0dfd6b2016-04-07 21:33:56654 EXPECT_EQ(display::DisplayPlacement::LEFT, stored_placement.position);
oshimaf571c4a2016-02-24 18:51:05655 EXPECT_EQ(0, stored_placement.offset);
656 EXPECT_EQ(id1, stored_placement.display_id);
657 EXPECT_EQ(id2, stored_placement.parent_display_id);
oshima61af6e12016-02-12 01:00:52658 EXPECT_EQ(id2, stored_layout.primary_id);
659 }
[email protected]29190fd2013-03-30 16:09:50660
oshima61af6e12016-02-12 01:00:52661 // Updating layout with primary swapped should save the correct value.
662 {
rjkroege980ccfd2016-10-06 18:00:24663 display_manager()->SetLayoutForCurrentDisplays(
rjkroege72f8154f2016-10-29 00:49:02664 display::test::CreateDisplayLayout(display_manager(),
665 display::DisplayPlacement::TOP, 10));
oshima61af6e12016-02-12 01:00:52666 const base::DictionaryValue* new_value = nullptr;
667 EXPECT_TRUE(displays->GetDictionary(key, &new_value));
robliaoc0dfd6b2016-04-07 21:33:56668 display::DisplayLayout stored_layout;
thanhph9a5d2652017-03-18 18:57:11669 EXPECT_TRUE(display::JsonToDisplayLayout(*new_value, &stored_layout));
oshimaf571c4a2016-02-24 18:51:05670 ASSERT_EQ(1u, stored_layout.placement_list.size());
robliaoc0dfd6b2016-04-07 21:33:56671 const display::DisplayPlacement& stored_placement =
robliaodf372032016-03-23 00:42:34672 stored_layout.placement_list[0];
robliaoc0dfd6b2016-04-07 21:33:56673 EXPECT_EQ(display::DisplayPlacement::TOP, stored_placement.position);
oshimaf571c4a2016-02-24 18:51:05674 EXPECT_EQ(10, stored_placement.offset);
675 EXPECT_EQ(id1, stored_placement.display_id);
676 EXPECT_EQ(id2, stored_placement.parent_display_id);
oshima61af6e12016-02-12 01:00:52677 EXPECT_EQ(id2, stored_layout.primary_id);
678 }
[email protected]0622b362013-03-02 17:43:16679
oshima61af6e12016-02-12 01:00:52680 // Swapping primary will save the swapped value.
681 {
rjkroege980ccfd2016-10-06 18:00:24682 SwapPrimaryDisplay();
oshima61af6e12016-02-12 01:00:52683 const base::DictionaryValue* new_value = nullptr;
684 EXPECT_TRUE(displays->GetDictionary(key, &new_value));
robliaoc0dfd6b2016-04-07 21:33:56685 display::DisplayLayout stored_layout;
oshima61af6e12016-02-12 01:00:52686
687 EXPECT_TRUE(displays->GetDictionary(key, &new_value));
thanhph9a5d2652017-03-18 18:57:11688 EXPECT_TRUE(display::JsonToDisplayLayout(*new_value, &stored_layout));
oshimaf571c4a2016-02-24 18:51:05689 ASSERT_EQ(1u, stored_layout.placement_list.size());
robliaoc0dfd6b2016-04-07 21:33:56690 const display::DisplayPlacement& stored_placement =
robliaodf372032016-03-23 00:42:34691 stored_layout.placement_list[0];
robliaoc0dfd6b2016-04-07 21:33:56692 EXPECT_EQ(display::DisplayPlacement::BOTTOM, stored_placement.position);
oshimaf571c4a2016-02-24 18:51:05693 EXPECT_EQ(-10, stored_placement.offset);
694 EXPECT_EQ(id2, stored_placement.display_id);
695 EXPECT_EQ(id1, stored_placement.parent_display_id);
oshima61af6e12016-02-12 01:00:52696 EXPECT_EQ(id1, stored_layout.primary_id);
697 }
[email protected]0622b362013-03-02 17:43:16698}
699
700TEST_F(DisplayPreferencesTest, DontStoreInGuestMode) {
oshimae2818922015-07-28 01:18:52701 ash::WindowTreeHostManager* window_tree_host_manager =
skycb4be5b2017-04-06 17:52:45702 ash::Shell::Get()->window_tree_host_manager();
[email protected]8b2447e2013-03-22 21:13:31703
704 UpdateDisplay("200x200*2,200x200");
[email protected]78e237042013-01-02 22:35:09705
706 LoggedInAsGuest();
oshimad5c972e2016-04-28 23:17:14707 int64_t id1 = display::Screen::GetScreen()->GetPrimaryDisplay().id();
rjkroege72f8154f2016-10-29 00:49:02708 display::test::ScopedSetInternalDisplayId set_internal(
skycb4be5b2017-04-06 17:52:45709 ash::Shell::Get()->display_manager(), id1);
rjkroege980ccfd2016-10-06 18:00:24710 int64_t id2 = display_manager()->GetSecondaryDisplay().id();
rjkroege72f8154f2016-10-29 00:49:02711 display_manager()->SetLayoutForCurrentDisplays(
712 display::test::CreateDisplayLayout(display_manager(),
713 display::DisplayPlacement::TOP, 10));
714 display::test::DisplayManagerTestApi(display_manager())
afakhry8571a9c2016-10-26 22:03:41715 .SetDisplayUIScale(id1, 1.25f);
oshimae2818922015-07-28 01:18:52716 window_tree_host_manager->SetPrimaryDisplayId(id2);
oshimad5c972e2016-04-28 23:17:14717 int64_t new_primary = display::Screen::GetScreen()->GetPrimaryDisplay().id();
oshimae2818922015-07-28 01:18:52718 window_tree_host_manager->SetOverscanInsets(new_primary,
719 gfx::Insets(10, 11, 12, 13));
rjkroege980ccfd2016-10-06 18:00:24720 display_manager()->SetDisplayRotation(new_primary,
721 display::Display::ROTATE_90,
722 display::Display::ROTATION_SOURCE_USER);
[email protected]78e237042013-01-02 22:35:09723
724 // Does not store the preferences locally.
725 EXPECT_FALSE(local_state()->FindPreference(
726 prefs::kSecondaryDisplays)->HasUserSetting());
727 EXPECT_FALSE(local_state()->FindPreference(
[email protected]8b2447e2013-03-22 21:13:31728 prefs::kDisplayProperties)->HasUserSetting());
[email protected]78e237042013-01-02 22:35:09729
730 // Settings are still notified to the system.
oshimad5c972e2016-04-28 23:17:14731 display::Screen* screen = display::Screen::GetScreen();
[email protected]78e237042013-01-02 22:35:09732 EXPECT_EQ(id2, screen->GetPrimaryDisplay().id());
robliaoc0dfd6b2016-04-07 21:33:56733 const display::DisplayPlacement& placement =
rjkroege980ccfd2016-10-06 18:00:24734 display_manager()->GetCurrentDisplayLayout().placement_list[0];
robliaoc0dfd6b2016-04-07 21:33:56735 EXPECT_EQ(display::DisplayPlacement::BOTTOM, placement.position);
oshimaf571c4a2016-02-24 18:51:05736 EXPECT_EQ(-10, placement.offset);
oshimad5c972e2016-04-28 23:17:14737 const display::Display& primary_display = screen->GetPrimaryDisplay();
[email protected]8b2447e2013-03-22 21:13:31738 EXPECT_EQ("178x176", primary_display.bounds().size().ToString());
oshimad5c972e2016-04-28 23:17:14739 EXPECT_EQ(display::Display::ROTATE_90, primary_display.rotation());
[email protected]8b2447e2013-03-22 21:13:31740
rjkroege259c01882016-08-30 19:29:50741 const display::ManagedDisplayInfo& info1 =
rjkroege980ccfd2016-10-06 18:00:24742 display_manager()->GetDisplayInfo(id1);
[email protected]ccb962d2013-11-20 02:54:01743 EXPECT_EQ(1.25f, info1.configured_ui_scale());
[email protected]8b2447e2013-03-22 21:13:31744
rjkroege259c01882016-08-30 19:29:50745 const display::ManagedDisplayInfo& info_primary =
rjkroege980ccfd2016-10-06 18:00:24746 display_manager()->GetDisplayInfo(new_primary);
oshimad5c972e2016-04-28 23:17:14747 EXPECT_EQ(display::Display::ROTATE_90, info_primary.GetActiveRotation());
[email protected]ccb962d2013-11-20 02:54:01748 EXPECT_EQ(1.0f, info_primary.configured_ui_scale());
[email protected]78e237042013-01-02 22:35:09749}
750
[email protected]1ccbac12013-09-13 06:55:54751TEST_F(DisplayPreferencesTest, StorePowerStateNoLogin) {
752 EXPECT_FALSE(local_state()->HasPrefPath(prefs::kDisplayPowerState));
753
754 // Stores display prefs without login, which still stores the power state.
755 StoreDisplayPrefs();
756 EXPECT_TRUE(local_state()->HasPrefPath(prefs::kDisplayPowerState));
757}
758
759TEST_F(DisplayPreferencesTest, StorePowerStateGuest) {
760 EXPECT_FALSE(local_state()->HasPrefPath(prefs::kDisplayPowerState));
761
762 LoggedInAsGuest();
763 StoreDisplayPrefs();
764 EXPECT_TRUE(local_state()->HasPrefPath(prefs::kDisplayPowerState));
765}
766
767TEST_F(DisplayPreferencesTest, StorePowerStateNormalUser) {
768 EXPECT_FALSE(local_state()->HasPrefPath(prefs::kDisplayPowerState));
769
770 LoggedInAsUser();
771 StoreDisplayPrefs();
772 EXPECT_TRUE(local_state()->HasPrefPath(prefs::kDisplayPowerState));
773}
774
[email protected]29190fd2013-03-30 16:09:50775TEST_F(DisplayPreferencesTest, DisplayPowerStateAfterRestart) {
776 StoreDisplayPowerStateForTest(
777 chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON);
778 LoadDisplayPreferences(false);
[email protected]1e31cbd2014-04-07 20:06:11779 EXPECT_EQ(chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON,
skycb4be5b2017-04-06 17:52:45780 ash::Shell::Get()->display_configurator()->requested_power_state());
[email protected]29190fd2013-03-30 16:09:50781}
782
[email protected]b732a6d2013-11-13 05:52:12783TEST_F(DisplayPreferencesTest, DontSaveAndRestoreAllOff) {
skycb4be5b2017-04-06 17:52:45784 ash::Shell* shell = ash::Shell::Get();
[email protected]b732a6d2013-11-13 05:52:12785 StoreDisplayPowerStateForTest(
786 chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON);
787 LoadDisplayPreferences(false);
788 // DisplayPowerState should be ignored at boot.
789 EXPECT_EQ(chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON,
derat4a062782014-09-25 21:46:13790 shell->display_configurator()->requested_power_state());
[email protected]b732a6d2013-11-13 05:52:12791
792 StoreDisplayPowerStateForTest(
793 chromeos::DISPLAY_POWER_ALL_OFF);
794 EXPECT_EQ(chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON,
derat4a062782014-09-25 21:46:13795 shell->display_configurator()->requested_power_state());
[email protected]b732a6d2013-11-13 05:52:12796 EXPECT_EQ("internal_off_external_on",
797 local_state()->GetString(prefs::kDisplayPowerState));
798
799 // Don't try to load
800 local_state()->SetString(prefs::kDisplayPowerState, "all_off");
801 LoadDisplayPreferences(false);
802 EXPECT_EQ(chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON,
derat4a062782014-09-25 21:46:13803 shell->display_configurator()->requested_power_state());
[email protected]b732a6d2013-11-13 05:52:12804}
805
Mitsuru Oshima0e9b7a62017-07-19 18:23:03806// Tests that display configuration changes caused by TabletModeController
[email protected]da285852014-05-27 19:53:43807// are not saved.
Mitsuru Oshima0e9b7a62017-07-19 18:23:03808TEST_F(DisplayPreferencesTest, DontSaveTabletModeControllerRotations) {
skycb4be5b2017-04-06 17:52:45809 ash::Shell* shell = ash::Shell::Get();
oshimad5c972e2016-04-28 23:17:14810 display::Display::SetInternalDisplayId(
811 display::Screen::GetScreen()->GetPrimaryDisplay().id());
[email protected]da285852014-05-27 19:53:43812 LoggedInAsUser();
813 // Populate the properties.
rjkroege980ccfd2016-10-06 18:00:24814 display_manager()->SetDisplayRotation(display::Display::InternalDisplayId(),
815 display::Display::ROTATE_180,
816 display::Display::ROTATION_SOURCE_USER);
[email protected]da285852014-05-27 19:53:43817 // Reset property to avoid rotation lock
rjkroege980ccfd2016-10-06 18:00:24818 display_manager()->SetDisplayRotation(display::Display::InternalDisplayId(),
819 display::Display::ROTATE_0,
820 display::Display::ROTATION_SOURCE_USER);
[email protected]da285852014-05-27 19:53:43821
Mitsuru Oshima0e9b7a62017-07-19 18:23:03822 // Open up 270 degrees to trigger tablet mode
jonrossd6b77052015-03-11 22:04:35823 scoped_refptr<chromeos::AccelerometerUpdate> update(
824 new chromeos::AccelerometerUpdate());
825 update->Set(chromeos::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD, 0.0f, 0.0f,
jonrossc47d12e22015-02-04 00:44:21826 kMeanGravity);
jonrossd6b77052015-03-11 22:04:35827 update->Set(chromeos::ACCELEROMETER_SOURCE_SCREEN, 0.0f, -kMeanGravity, 0.0f);
Mitsuru Oshima0e9b7a62017-07-19 18:23:03828 ash::TabletModeController* controller =
829 ash::Shell::Get()->tablet_mode_controller();
flackr45f31ae72014-09-02 18:50:25830 controller->OnAccelerometerUpdated(update);
Mitsuru Oshima0e9b7a62017-07-19 18:23:03831 EXPECT_TRUE(controller->IsTabletModeWindowManagerEnabled());
[email protected]da285852014-05-27 19:53:43832
833 // Trigger 90 degree rotation
jonrossd6b77052015-03-11 22:04:35834 update->Set(chromeos::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD, -kMeanGravity,
jonrossc47d12e22015-02-04 00:44:21835 0.0f, 0.0f);
jonrossd6b77052015-03-11 22:04:35836 update->Set(chromeos::ACCELEROMETER_SOURCE_SCREEN, -kMeanGravity, 0.0f, 0.0f);
flackr45f31ae72014-09-02 18:50:25837 controller->OnAccelerometerUpdated(update);
jonross0af45212015-01-13 18:55:46838 shell->screen_orientation_controller()->OnAccelerometerUpdated(update);
oshimad5c972e2016-04-28 23:17:14839 EXPECT_EQ(display::Display::ROTATE_90, GetCurrentInternalDisplayRotation());
[email protected]da285852014-05-27 19:53:43840
841 const base::DictionaryValue* properties =
842 local_state()->GetDictionary(prefs::kDisplayProperties);
oshima95d499b2016-02-10 03:49:56843 const base::DictionaryValue* property = nullptr;
[email protected]da285852014-05-27 19:53:43844 EXPECT_TRUE(properties->GetDictionary(
oshimad5c972e2016-04-28 23:17:14845 base::Int64ToString(display::Display::InternalDisplayId()), &property));
[email protected]da285852014-05-27 19:53:43846 int rotation = -1;
847 EXPECT_TRUE(property->GetInteger("rotation", &rotation));
oshimad5c972e2016-04-28 23:17:14848 EXPECT_EQ(display::Display::ROTATE_0, rotation);
jonrossd01de7f2015-04-23 19:52:00849
850 // Trigger a save, the acceleration rotation should not be saved as the user
851 // rotation.
852 StoreDisplayPrefs();
853 properties = local_state()->GetDictionary(prefs::kDisplayProperties);
oshima95d499b2016-02-10 03:49:56854 property = nullptr;
jonrossd01de7f2015-04-23 19:52:00855 EXPECT_TRUE(properties->GetDictionary(
oshimad5c972e2016-04-28 23:17:14856 base::Int64ToString(display::Display::InternalDisplayId()), &property));
jonrossd01de7f2015-04-23 19:52:00857 rotation = -1;
858 EXPECT_TRUE(property->GetInteger("rotation", &rotation));
oshimad5c972e2016-04-28 23:17:14859 EXPECT_EQ(display::Display::ROTATE_0, rotation);
[email protected]da285852014-05-27 19:53:43860}
861
[email protected]62e90d42014-08-20 15:23:32862// Tests that the rotation state is saved without a user being logged in.
863TEST_F(DisplayPreferencesTest, StoreRotationStateNoLogin) {
oshimad5c972e2016-04-28 23:17:14864 display::Display::SetInternalDisplayId(
865 display::Screen::GetScreen()->GetPrimaryDisplay().id());
[email protected]62e90d42014-08-20 15:23:32866 EXPECT_FALSE(local_state()->HasPrefPath(prefs::kDisplayRotationLock));
867
jonross0af45212015-01-13 18:55:46868 bool current_rotation_lock = IsRotationLocked();
[email protected]62e90d42014-08-20 15:23:32869 StoreDisplayRotationPrefs(current_rotation_lock);
870 EXPECT_TRUE(local_state()->HasPrefPath(prefs::kDisplayRotationLock));
871
872 const base::DictionaryValue* properties =
873 local_state()->GetDictionary(prefs::kDisplayRotationLock);
874 bool rotation_lock;
875 EXPECT_TRUE(properties->GetBoolean("lock", &rotation_lock));
876 EXPECT_EQ(current_rotation_lock, rotation_lock);
877
878 int orientation;
oshimad5c972e2016-04-28 23:17:14879 display::Display::Rotation current_rotation =
880 GetCurrentInternalDisplayRotation();
[email protected]62e90d42014-08-20 15:23:32881 EXPECT_TRUE(properties->GetInteger("orientation", &orientation));
882 EXPECT_EQ(current_rotation, orientation);
883}
884
885// Tests that the rotation state is saved when a guest is logged in.
886TEST_F(DisplayPreferencesTest, StoreRotationStateGuest) {
oshimad5c972e2016-04-28 23:17:14887 display::Display::SetInternalDisplayId(
888 display::Screen::GetScreen()->GetPrimaryDisplay().id());
[email protected]62e90d42014-08-20 15:23:32889 EXPECT_FALSE(local_state()->HasPrefPath(prefs::kDisplayRotationLock));
890 LoggedInAsGuest();
891
jonross0af45212015-01-13 18:55:46892 bool current_rotation_lock = IsRotationLocked();
[email protected]62e90d42014-08-20 15:23:32893 StoreDisplayRotationPrefs(current_rotation_lock);
894 EXPECT_TRUE(local_state()->HasPrefPath(prefs::kDisplayRotationLock));
895
896 const base::DictionaryValue* properties =
897 local_state()->GetDictionary(prefs::kDisplayRotationLock);
898 bool rotation_lock;
899 EXPECT_TRUE(properties->GetBoolean("lock", &rotation_lock));
900 EXPECT_EQ(current_rotation_lock, rotation_lock);
901
902 int orientation;
oshimad5c972e2016-04-28 23:17:14903 display::Display::Rotation current_rotation =
904 GetCurrentInternalDisplayRotation();
[email protected]62e90d42014-08-20 15:23:32905 EXPECT_TRUE(properties->GetInteger("orientation", &orientation));
906 EXPECT_EQ(current_rotation, orientation);
907}
908
909// Tests that the rotation state is saved when a normal user is logged in.
910TEST_F(DisplayPreferencesTest, StoreRotationStateNormalUser) {
oshimad5c972e2016-04-28 23:17:14911 display::Display::SetInternalDisplayId(
912 display::Screen::GetScreen()->GetPrimaryDisplay().id());
[email protected]62e90d42014-08-20 15:23:32913 EXPECT_FALSE(local_state()->HasPrefPath(prefs::kDisplayRotationLock));
914 LoggedInAsGuest();
915
jonross0af45212015-01-13 18:55:46916 bool current_rotation_lock = IsRotationLocked();
[email protected]62e90d42014-08-20 15:23:32917 StoreDisplayRotationPrefs(current_rotation_lock);
918 EXPECT_TRUE(local_state()->HasPrefPath(prefs::kDisplayRotationLock));
919
920 const base::DictionaryValue* properties =
921 local_state()->GetDictionary(prefs::kDisplayRotationLock);
922 bool rotation_lock;
923 EXPECT_TRUE(properties->GetBoolean("lock", &rotation_lock));
924 EXPECT_EQ(current_rotation_lock, rotation_lock);
925
926 int orientation;
oshimad5c972e2016-04-28 23:17:14927 display::Display::Rotation current_rotation =
928 GetCurrentInternalDisplayRotation();
[email protected]62e90d42014-08-20 15:23:32929 EXPECT_TRUE(properties->GetInteger("orientation", &orientation));
930 EXPECT_EQ(current_rotation, orientation);
931}
932
933// Tests that rotation state is loaded without a user being logged in, and that
Mitsuru Oshima0e9b7a62017-07-19 18:23:03934// entering tablet mode applies the state.
[email protected]62e90d42014-08-20 15:23:32935TEST_F(DisplayPreferencesTest, LoadRotationNoLogin) {
oshimad5c972e2016-04-28 23:17:14936 display::Display::SetInternalDisplayId(
937 display::Screen::GetScreen()->GetPrimaryDisplay().id());
[email protected]62e90d42014-08-20 15:23:32938 ASSERT_FALSE(local_state()->HasPrefPath(prefs::kDisplayRotationLock));
939
jonross0af45212015-01-13 18:55:46940 bool initial_rotation_lock = IsRotationLocked();
[email protected]62e90d42014-08-20 15:23:32941 ASSERT_FALSE(initial_rotation_lock);
oshimad5c972e2016-04-28 23:17:14942 display::Display::Rotation initial_rotation =
943 GetCurrentInternalDisplayRotation();
944 ASSERT_EQ(display::Display::ROTATE_0, initial_rotation);
[email protected]62e90d42014-08-20 15:23:32945
946 StoreDisplayRotationPrefs(initial_rotation_lock);
947 ASSERT_TRUE(local_state()->HasPrefPath(prefs::kDisplayRotationLock));
948
oshimad5c972e2016-04-28 23:17:14949 StoreDisplayRotationPrefsForTest(true, display::Display::ROTATE_90);
[email protected]62e90d42014-08-20 15:23:32950 LoadDisplayPreferences(false);
951
952 bool display_rotation_lock =
rjkroege980ccfd2016-10-06 18:00:24953 display_manager()->registered_internal_display_rotation_lock();
[email protected]62e90d42014-08-20 15:23:32954 bool display_rotation =
rjkroege980ccfd2016-10-06 18:00:24955 display_manager()->registered_internal_display_rotation();
[email protected]62e90d42014-08-20 15:23:32956 EXPECT_TRUE(display_rotation_lock);
oshimad5c972e2016-04-28 23:17:14957 EXPECT_EQ(display::Display::ROTATE_90, display_rotation);
[email protected]62e90d42014-08-20 15:23:32958
jonross0af45212015-01-13 18:55:46959 bool rotation_lock = IsRotationLocked();
Mitsuru Oshima0e9b7a62017-07-19 18:23:03960 display::Display::Rotation before_tablet_mode_rotation =
jonrossd01de7f2015-04-23 19:52:00961 GetCurrentInternalDisplayRotation();
[email protected]62e90d42014-08-20 15:23:32962
Mitsuru Oshima0e9b7a62017-07-19 18:23:03963 // Settings should not be applied until tablet mode activates
[email protected]62e90d42014-08-20 15:23:32964 EXPECT_FALSE(rotation_lock);
Mitsuru Oshima0e9b7a62017-07-19 18:23:03965 EXPECT_EQ(display::Display::ROTATE_0, before_tablet_mode_rotation);
[email protected]62e90d42014-08-20 15:23:32966
Mitsuru Oshima0e9b7a62017-07-19 18:23:03967 // Open up 270 degrees to trigger tablet mode
jonrossd6b77052015-03-11 22:04:35968 scoped_refptr<chromeos::AccelerometerUpdate> update(
969 new chromeos::AccelerometerUpdate());
970 update->Set(chromeos::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD, 0.0f, 0.0f,
jonrossc47d12e22015-02-04 00:44:21971 kMeanGravity);
jonrossd6b77052015-03-11 22:04:35972 update->Set(chromeos::ACCELEROMETER_SOURCE_SCREEN, 0.0f, -kMeanGravity, 0.0f);
Mitsuru Oshima0e9b7a62017-07-19 18:23:03973 ash::TabletModeController* tablet_mode_controller =
974 ash::Shell::Get()->tablet_mode_controller();
975 tablet_mode_controller->OnAccelerometerUpdated(update);
976 EXPECT_TRUE(tablet_mode_controller->IsTabletModeWindowManagerEnabled());
jonross0af45212015-01-13 18:55:46977 bool screen_orientation_rotation_lock = IsRotationLocked();
Mitsuru Oshima0e9b7a62017-07-19 18:23:03978 display::Display::Rotation tablet_mode_rotation =
jonrossd01de7f2015-04-23 19:52:00979 GetCurrentInternalDisplayRotation();
jonross0af45212015-01-13 18:55:46980 EXPECT_TRUE(screen_orientation_rotation_lock);
Mitsuru Oshima0e9b7a62017-07-19 18:23:03981 EXPECT_EQ(display::Display::ROTATE_90, tablet_mode_rotation);
[email protected]62e90d42014-08-20 15:23:32982}
983
[email protected]62e90d42014-08-20 15:23:32984// Tests that rotation lock being set causes the rotation state to be saved.
985TEST_F(DisplayPreferencesTest, RotationLockTriggersStore) {
oshimad5c972e2016-04-28 23:17:14986 display::Display::SetInternalDisplayId(
987 display::Screen::GetScreen()->GetPrimaryDisplay().id());
[email protected]62e90d42014-08-20 15:23:32988 ASSERT_FALSE(local_state()->HasPrefPath(prefs::kDisplayRotationLock));
989
skycb4be5b2017-04-06 17:52:45990 ash::Shell::Get()->screen_orientation_controller()->ToggleUserRotationLock();
[email protected]62e90d42014-08-20 15:23:32991
992 EXPECT_TRUE(local_state()->HasPrefPath(prefs::kDisplayRotationLock));
993
994 const base::DictionaryValue* properties =
995 local_state()->GetDictionary(prefs::kDisplayRotationLock);
996 bool rotation_lock;
997 EXPECT_TRUE(properties->GetBoolean("lock", &rotation_lock));
998}
999
oshimabba2d992015-05-22 19:21:391000TEST_F(DisplayPreferencesTest, SaveUnifiedMode) {
oshimabba2d992015-05-22 19:21:391001 LoggedInAsUser();
rjkroege980ccfd2016-10-06 18:00:241002 display_manager()->SetUnifiedDesktopEnabled(true);
oshima5337ca92015-07-18 02:23:571003
oshimaaf6e8572015-07-30 19:41:571004 UpdateDisplay("200x200,100x100");
rjkroege980ccfd2016-10-06 18:00:241005 display::DisplayIdList list = display_manager()->GetCurrentDisplayIdList();
oshimad5c972e2016-04-28 23:17:141006 EXPECT_EQ(
1007 "400x200",
1008 display::Screen::GetScreen()->GetPrimaryDisplay().size().ToString());
oshimabba2d992015-05-22 19:21:391009
oshima5337ca92015-07-18 02:23:571010 const base::DictionaryValue* secondary_displays =
oshimabba2d992015-05-22 19:21:391011 local_state()->GetDictionary(prefs::kSecondaryDisplays);
oshima95d499b2016-02-10 03:49:561012 const base::DictionaryValue* new_value = nullptr;
oshima4763f822016-02-01 20:19:181013 EXPECT_TRUE(secondary_displays->GetDictionary(
rjkroege0458f012016-08-31 00:31:361014 display::DisplayIdListToString(list), &new_value));
oshimabba2d992015-05-22 19:21:391015
robliaoc0dfd6b2016-04-07 21:33:561016 display::DisplayLayout stored_layout;
thanhph9a5d2652017-03-18 18:57:111017 EXPECT_TRUE(display::JsonToDisplayLayout(*new_value, &stored_layout));
oshimabba2d992015-05-22 19:21:391018 EXPECT_TRUE(stored_layout.default_unified);
1019 EXPECT_FALSE(stored_layout.mirrored);
1020
oshima5337ca92015-07-18 02:23:571021 const base::DictionaryValue* displays =
1022 local_state()->GetDictionary(prefs::kDisplayProperties);
oshimad5c972e2016-04-28 23:17:141023 int64_t unified_id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
oshima2190eb612015-07-28 22:44:431024 EXPECT_FALSE(
oshima5337ca92015-07-18 02:23:571025 displays->GetDictionary(base::Int64ToString(unified_id), &new_value));
oshima5337ca92015-07-18 02:23:571026
rjkroege72f8154f2016-10-29 00:49:021027 display::test::SetDisplayResolution(display_manager(), unified_id,
1028 gfx::Size(200, 100));
oshimad5c972e2016-04-28 23:17:141029 EXPECT_EQ(
1030 "200x100",
1031 display::Screen::GetScreen()->GetPrimaryDisplay().size().ToString());
oshima2190eb612015-07-28 22:44:431032 EXPECT_FALSE(
oshima5337ca92015-07-18 02:23:571033 displays->GetDictionary(base::Int64ToString(unified_id), &new_value));
oshima5337ca92015-07-18 02:23:571034
oshimabba2d992015-05-22 19:21:391035 // Mirror mode should remember if the default mode was unified.
rjkroege980ccfd2016-10-06 18:00:241036 display_manager()->SetMirrorMode(true);
oshima4763f822016-02-01 20:19:181037 ASSERT_TRUE(secondary_displays->GetDictionary(
rjkroege0458f012016-08-31 00:31:361038 display::DisplayIdListToString(list), &new_value));
thanhph9a5d2652017-03-18 18:57:111039 EXPECT_TRUE(display::JsonToDisplayLayout(*new_value, &stored_layout));
oshimabba2d992015-05-22 19:21:391040 EXPECT_TRUE(stored_layout.default_unified);
1041 EXPECT_TRUE(stored_layout.mirrored);
1042
rjkroege980ccfd2016-10-06 18:00:241043 display_manager()->SetMirrorMode(false);
oshima4763f822016-02-01 20:19:181044 ASSERT_TRUE(secondary_displays->GetDictionary(
rjkroege0458f012016-08-31 00:31:361045 display::DisplayIdListToString(list), &new_value));
thanhph9a5d2652017-03-18 18:57:111046 EXPECT_TRUE(display::JsonToDisplayLayout(*new_value, &stored_layout));
oshimabba2d992015-05-22 19:21:391047 EXPECT_TRUE(stored_layout.default_unified);
1048 EXPECT_FALSE(stored_layout.mirrored);
1049
1050 // Exit unified mode.
rjkroege980ccfd2016-10-06 18:00:241051 display_manager()->SetDefaultMultiDisplayModeForCurrentDisplays(
rjkroege72f8154f2016-10-29 00:49:021052 display::DisplayManager::EXTENDED);
oshima4763f822016-02-01 20:19:181053 ASSERT_TRUE(secondary_displays->GetDictionary(
rjkroege0458f012016-08-31 00:31:361054 display::DisplayIdListToString(list), &new_value));
thanhph9a5d2652017-03-18 18:57:111055 EXPECT_TRUE(display::JsonToDisplayLayout(*new_value, &stored_layout));
oshimabba2d992015-05-22 19:21:391056 EXPECT_FALSE(stored_layout.default_unified);
1057 EXPECT_FALSE(stored_layout.mirrored);
1058}
1059
1060TEST_F(DisplayPreferencesTest, RestoreUnifiedMode) {
oshimad5c972e2016-04-28 23:17:141061 int64_t id1 = display::Screen::GetScreen()->GetPrimaryDisplay().id();
rjkroege72f8154f2016-10-29 00:49:021062 display::DisplayIdList list =
1063 display::test::CreateDisplayIdList2(id1, id1 + 1);
oshima4763f822016-02-01 20:19:181064 StoreDisplayBoolPropertyForList(list, "default_unified", true);
1065 StoreDisplayPropertyForList(
1066 list, "primary-id",
jdoerrie122c4da2017-03-06 11:12:041067 base::MakeUnique<base::Value>(base::Int64ToString(id1)));
oshimabba2d992015-05-22 19:21:391068 LoadDisplayPreferences(false);
1069
1070 // Should not restore to unified unless unified desktop is enabled.
1071 UpdateDisplay("100x100,200x200");
rjkroege980ccfd2016-10-06 18:00:241072 EXPECT_FALSE(display_manager()->IsInUnifiedMode());
oshimabba2d992015-05-22 19:21:391073
1074 // Restored to unified.
rjkroege980ccfd2016-10-06 18:00:241075 display_manager()->SetUnifiedDesktopEnabled(true);
oshima4763f822016-02-01 20:19:181076 StoreDisplayBoolPropertyForList(list, "default_unified", true);
oshimabba2d992015-05-22 19:21:391077 LoadDisplayPreferences(false);
1078 UpdateDisplay("100x100,200x200");
rjkroege980ccfd2016-10-06 18:00:241079 EXPECT_TRUE(display_manager()->IsInUnifiedMode());
oshimabba2d992015-05-22 19:21:391080
1081 // Restored to mirror, then unified.
oshima4763f822016-02-01 20:19:181082 StoreDisplayBoolPropertyForList(list, "mirrored", true);
1083 StoreDisplayBoolPropertyForList(list, "default_unified", true);
oshimabba2d992015-05-22 19:21:391084 LoadDisplayPreferences(false);
1085 UpdateDisplay("100x100,200x200");
rjkroege980ccfd2016-10-06 18:00:241086 EXPECT_TRUE(display_manager()->IsInMirrorMode());
oshimabba2d992015-05-22 19:21:391087
rjkroege980ccfd2016-10-06 18:00:241088 display_manager()->SetMirrorMode(false);
1089 EXPECT_TRUE(display_manager()->IsInUnifiedMode());
oshimabba2d992015-05-22 19:21:391090
1091 // Sanity check. Restore to extended.
oshima4763f822016-02-01 20:19:181092 StoreDisplayBoolPropertyForList(list, "default_unified", false);
1093 StoreDisplayBoolPropertyForList(list, "mirrored", false);
oshimabba2d992015-05-22 19:21:391094 LoadDisplayPreferences(false);
1095 UpdateDisplay("100x100,200x200");
rjkroege980ccfd2016-10-06 18:00:241096 EXPECT_FALSE(display_manager()->IsInMirrorMode());
1097 EXPECT_FALSE(display_manager()->IsInUnifiedMode());
oshimabba2d992015-05-22 19:21:391098}
1099
oshima77570cb2016-03-24 21:33:231100TEST_F(DisplayPreferencesTest, SaveThreeDisplays) {
1101 LoggedInAsUser();
oshima77570cb2016-03-24 21:33:231102 UpdateDisplay("200x200,200x200,300x300");
1103
rjkroege980ccfd2016-10-06 18:00:241104 display::DisplayIdList list = display_manager()->GetCurrentDisplayIdList();
oshima77570cb2016-03-24 21:33:231105 ASSERT_EQ(3u, list.size());
1106
robliaoc0dfd6b2016-04-07 21:33:561107 display::DisplayLayoutBuilder builder(list[0]);
1108 builder.AddDisplayPlacement(list[1], list[0],
1109 display::DisplayPlacement::RIGHT, 0);
1110 builder.AddDisplayPlacement(list[2], list[0],
1111 display::DisplayPlacement::BOTTOM, 100);
rjkroege980ccfd2016-10-06 18:00:241112 display_manager()->SetLayoutForCurrentDisplays(builder.Build());
oshima77570cb2016-03-24 21:33:231113
1114 const base::DictionaryValue* secondary_displays =
1115 local_state()->GetDictionary(prefs::kSecondaryDisplays);
1116 const base::DictionaryValue* new_value = nullptr;
1117 EXPECT_TRUE(secondary_displays->GetDictionary(
rjkroege0458f012016-08-31 00:31:361118 display::DisplayIdListToString(list), &new_value));
oshima77570cb2016-03-24 21:33:231119}
1120
1121TEST_F(DisplayPreferencesTest, RestoreThreeDisplays) {
1122 LoggedInAsUser();
oshimad5c972e2016-04-28 23:17:141123 int64_t id1 = display::Screen::GetScreen()->GetPrimaryDisplay().id();
robliaoc0dfd6b2016-04-07 21:33:561124 display::DisplayIdList list =
rjkroege72f8154f2016-10-29 00:49:021125 display::test::CreateDisplayIdListN(3, id1, id1 + 1, id1 + 2);
oshima77570cb2016-03-24 21:33:231126
robliaoc0dfd6b2016-04-07 21:33:561127 display::DisplayLayoutBuilder builder(list[0]);
1128 builder.AddDisplayPlacement(list[1], list[0], display::DisplayPlacement::LEFT,
1129 0);
1130 builder.AddDisplayPlacement(list[2], list[1],
1131 display::DisplayPlacement::BOTTOM, 100);
oshima77570cb2016-03-24 21:33:231132 StoreDisplayLayoutPrefForTest(list, *builder.Build());
1133 LoadDisplayPreferences(false);
1134
1135 UpdateDisplay("200x200,200x200,300x300");
rjkroege980ccfd2016-10-06 18:00:241136 display::DisplayIdList new_list =
1137 display_manager()->GetCurrentDisplayIdList();
oshima77570cb2016-03-24 21:33:231138 ASSERT_EQ(3u, list.size());
1139 ASSERT_EQ(list[0], new_list[0]);
1140 ASSERT_EQ(list[1], new_list[1]);
1141 ASSERT_EQ(list[2], new_list[2]);
1142
1143 EXPECT_EQ(gfx::Rect(0, 0, 200, 200),
rjkroege980ccfd2016-10-06 18:00:241144 display_manager()->GetDisplayForId(list[0]).bounds());
oshima77570cb2016-03-24 21:33:231145 EXPECT_EQ(gfx::Rect(-200, 0, 200, 200),
rjkroege980ccfd2016-10-06 18:00:241146 display_manager()->GetDisplayForId(list[1]).bounds());
oshima77570cb2016-03-24 21:33:231147 EXPECT_EQ(gfx::Rect(-100, 200, 300, 300),
rjkroege980ccfd2016-10-06 18:00:241148 display_manager()->GetDisplayForId(list[2]).bounds());
oshima77570cb2016-03-24 21:33:231149}
1150
Mitsuru Oshima3695b8be2017-10-09 14:18:361151TEST_F(DisplayPreferencesTest, MirrorWhenEnterTableMode) {
1152 display::Display::SetInternalDisplayId(
1153 display::Screen::GetScreen()->GetPrimaryDisplay().id());
1154 LoggedInAsUser();
1155 UpdateDisplay("800x600,1200x800");
1156 EXPECT_FALSE(display_manager()->IsInMirrorMode());
1157 ash::TabletModeController* controller =
1158 ash::Shell::Get()->tablet_mode_controller();
1159 controller->EnableTabletModeWindowManager(true);
1160 ASSERT_TRUE(controller->IsTabletModeWindowManagerEnabled());
1161 EXPECT_TRUE(display_manager()->IsInMirrorMode());
1162
1163 // Make sure the mirror mode is not saved in the preference.
1164 display::DisplayIdList list = display_manager()->GetCurrentDisplayIdList();
1165 ASSERT_EQ(2u, list.size());
1166 base::Value* value;
1167 EXPECT_TRUE(GetDisplayPropertyFromList(list, "mirrored", &value));
1168 bool mirrored;
1169 EXPECT_TRUE(value->GetAsBoolean(&mirrored));
1170 EXPECT_FALSE(mirrored);
1171
1172 // Exiting the tablet mode should exit mirror mode.
1173 controller->EnableTabletModeWindowManager(false);
1174 ASSERT_FALSE(controller->IsTabletModeWindowManagerEnabled());
1175 EXPECT_FALSE(display_manager()->IsInMirrorMode());
1176}
1177
1178TEST_F(DisplayPreferencesTest, AlreadyMirrorWhenEnterTableMode) {
1179 display::Display::SetInternalDisplayId(
1180 display::Screen::GetScreen()->GetPrimaryDisplay().id());
1181 LoggedInAsUser();
1182 UpdateDisplay("800x600,1200x800");
1183 display_manager()->SetMirrorMode(true);
1184 EXPECT_TRUE(display_manager()->IsInMirrorMode());
1185 ash::TabletModeController* controller =
1186 ash::Shell::Get()->tablet_mode_controller();
1187 controller->EnableTabletModeWindowManager(true);
1188 ASSERT_TRUE(controller->IsTabletModeWindowManagerEnabled());
1189 EXPECT_TRUE(display_manager()->IsInMirrorMode());
1190
1191 // Exiting the tablet mode should stay in mirror mode.
1192 controller->EnableTabletModeWindowManager(false);
1193 ASSERT_FALSE(controller->IsTabletModeWindowManagerEnabled());
1194 EXPECT_TRUE(display_manager()->IsInMirrorMode());
1195}
1196
F#m4791c3d72017-11-03 21:39:581197TEST_F(DisplayPreferencesTest, LegacyTouchCalibrationDataSupport) {
1198 UpdateDisplay("800x600,1200x800");
1199 LoggedInAsUser();
1200 int64_t id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
1201 display::TouchCalibrationData::CalibrationPointPairQuad point_pair_quad = {
1202 {std::make_pair(gfx::Point(10, 10), gfx::Point(11, 12)),
1203 std::make_pair(gfx::Point(190, 10), gfx::Point(195, 8)),
1204 std::make_pair(gfx::Point(10, 90), gfx::Point(12, 94)),
1205 std::make_pair(gfx::Point(190, 90), gfx::Point(189, 88))}};
1206 gfx::Size touch_size(200, 150);
1207 display::TouchCalibrationData data(point_pair_quad, touch_size);
1208
1209 StoreLegacyTouchDataForTest(id, data);
1210
1211 display::TouchDeviceManager* tdm = display_manager()->touch_device_manager();
1212 display::test::TouchDeviceManagerTestApi tdm_test_api(tdm);
1213 tdm_test_api.ResetTouchDeviceManager();
1214
1215 LoadTouchAssociationPreferenceForTest();
1216
1217 const display::TouchDeviceManager::TouchAssociationMap& association_map =
1218 tdm->touch_associations();
1219
1220 const display::TouchDeviceIdentifier& fallback_identifier =
1221 display::TouchDeviceIdentifier::GetFallbackTouchDeviceIdentifier();
1222
1223 EXPECT_TRUE(association_map.count(fallback_identifier));
1224 EXPECT_TRUE(association_map.at(fallback_identifier).count(id));
1225 EXPECT_EQ(association_map.at(fallback_identifier).at(id).calibration_data,
1226 data);
1227
1228 int64_t id_2 = display_manager()->GetSecondaryDisplay().id();
1229 gfx::Size touch_size_2(300, 300);
1230 display::TouchCalibrationData data_2(point_pair_quad, touch_size_2);
1231
1232 display::TouchDeviceIdentifier identifier(12345);
1233 display_manager()->SetTouchCalibrationData(id_2, point_pair_quad,
1234 touch_size_2, identifier);
1235
1236 EXPECT_TRUE(tdm->touch_associations().count(identifier));
1237 EXPECT_TRUE(tdm->touch_associations().at(identifier).count(id_2));
1238 EXPECT_EQ(tdm->touch_associations().at(identifier).at(id_2).calibration_data,
1239 data_2);
1240
1241 tdm_test_api.ResetTouchDeviceManager();
1242 EXPECT_TRUE(tdm->touch_associations().empty());
1243
1244 LoadTouchAssociationPreferenceForTest();
1245
1246 EXPECT_TRUE(tdm->touch_associations().count(fallback_identifier));
1247 EXPECT_TRUE(tdm->touch_associations().at(fallback_identifier).count(id));
1248 EXPECT_EQ(
1249 tdm->touch_associations().at(fallback_identifier).at(id).calibration_data,
1250 data);
1251 EXPECT_TRUE(tdm->touch_associations().count(identifier));
1252 EXPECT_TRUE(tdm->touch_associations().at(identifier).count(id_2));
1253 EXPECT_EQ(tdm->touch_associations().at(identifier).at(id_2).calibration_data,
1254 data_2);
1255}
1256
[email protected]78e237042013-01-02 22:35:091257} // namespace chromeos