1 // Copyright 2013 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 "ash/display/display_change_observer_chromeos.h" 6 7 #include "ash/display/display_info.h" 8 #include "base/memory/scoped_vector.h" 9 #include "testing/gtest/include/gtest/gtest.h" 10 #include "ui/display/chromeos/display_configurator.h" 11 #include "ui/display/chromeos/test/test_display_snapshot.h" 12 #include "ui/display/types/display_mode.h" 13 14 using ui::DisplayConfigurator; 15 16 typedef testing::Test DisplayChangeObserverTest; 17 18 namespace ash { 19 20 TEST_F(DisplayChangeObserverTest, GetExternalDisplayModeList) { 21 ScopedVector<const ui::DisplayMode> modes; 22 modes.push_back(new ui::DisplayMode(gfx::Size(1920, 1200), false, 60)); 23 24 // All non-interlaced (as would be seen with different refresh rates). 25 modes.push_back(new ui::DisplayMode(gfx::Size(1920, 1080), false, 80)); 26 modes.push_back(new ui::DisplayMode(gfx::Size(1920, 1080), false, 70)); 27 modes.push_back(new ui::DisplayMode(gfx::Size(1920, 1080), false, 60)); 28 29 // Interlaced vs non-interlaced. 30 modes.push_back(new ui::DisplayMode(gfx::Size(1280, 720), true, 60)); 31 modes.push_back(new ui::DisplayMode(gfx::Size(1280, 720), false, 60)); 32 33 // Interlaced only. 34 modes.push_back(new ui::DisplayMode(gfx::Size(1024, 768), true, 70)); 35 modes.push_back(new ui::DisplayMode(gfx::Size(1024, 768), true, 60)); 36 37 // Mixed. 38 modes.push_back(new ui::DisplayMode(gfx::Size(1024, 600), true, 60)); 39 modes.push_back(new ui::DisplayMode(gfx::Size(1024, 600), false, 70)); 40 modes.push_back(new ui::DisplayMode(gfx::Size(1024, 600), false, 60)); 41 42 // Just one interlaced mode. 43 modes.push_back(new ui::DisplayMode(gfx::Size(640, 480), true, 60)); 44 45 ui::TestDisplaySnapshot display_snapshot; 46 display_snapshot.set_modes(modes.get()); 47 DisplayConfigurator::DisplayState output; 48 output.display = &display_snapshot; 49 50 std::vector<DisplayMode> display_modes = 51 DisplayChangeObserver::GetExternalDisplayModeList(output); 52 ASSERT_EQ(6u, display_modes.size()); 53 EXPECT_EQ("640x480", display_modes[0].size.ToString()); 54 EXPECT_TRUE(display_modes[0].interlaced); 55 EXPECT_EQ(display_modes[0].refresh_rate, 60); 56 57 EXPECT_EQ("1024x600", display_modes[1].size.ToString()); 58 EXPECT_FALSE(display_modes[1].interlaced); 59 EXPECT_EQ(display_modes[1].refresh_rate, 70); 60 61 EXPECT_EQ("1024x768", display_modes[2].size.ToString()); 62 EXPECT_TRUE(display_modes[2].interlaced); 63 EXPECT_EQ(display_modes[2].refresh_rate, 70); 64 65 EXPECT_EQ("1280x720", display_modes[3].size.ToString()); 66 EXPECT_FALSE(display_modes[3].interlaced); 67 EXPECT_EQ(display_modes[3].refresh_rate, 60); 68 69 EXPECT_EQ("1920x1080", display_modes[4].size.ToString()); 70 EXPECT_FALSE(display_modes[4].interlaced); 71 EXPECT_EQ(display_modes[4].refresh_rate, 80); 72 73 EXPECT_EQ("1920x1200", display_modes[5].size.ToString()); 74 EXPECT_FALSE(display_modes[5].interlaced); 75 EXPECT_EQ(display_modes[5].refresh_rate, 60); 76 77 // Outputs without any modes shouldn't cause a crash. 78 modes.clear(); 79 display_snapshot.set_modes(modes.get()); 80 81 display_modes = DisplayChangeObserver::GetExternalDisplayModeList(output); 82 EXPECT_EQ(0u, display_modes.size()); 83 } 84 85 TEST_F(DisplayChangeObserverTest, GetInternalDisplayModeList) { 86 ScopedVector<const ui::DisplayMode> modes; 87 // Data picked from peppy. 88 modes.push_back(new ui::DisplayMode(gfx::Size(1366, 768), false, 60)); 89 modes.push_back(new ui::DisplayMode(gfx::Size(1024, 768), false, 60)); 90 modes.push_back(new ui::DisplayMode(gfx::Size(800, 600), false, 60)); 91 modes.push_back(new ui::DisplayMode(gfx::Size(600, 600), false, 56.2)); 92 modes.push_back(new ui::DisplayMode(gfx::Size(640, 480), false, 59.9)); 93 94 ui::TestDisplaySnapshot display_snapshot; 95 display_snapshot.set_modes(modes.get()); 96 display_snapshot.set_native_mode(modes[0]); 97 DisplayConfigurator::DisplayState output; 98 output.display = &display_snapshot; 99 100 DisplayInfo info; 101 info.SetBounds(gfx::Rect(0, 0, 1366, 768)); 102 103 std::vector<DisplayMode> display_modes = 104 DisplayChangeObserver::GetInternalDisplayModeList(info, output); 105 ASSERT_EQ(5u, display_modes.size()); 106 EXPECT_EQ("1366x768", display_modes[0].size.ToString()); 107 EXPECT_FALSE(display_modes[0].native); 108 EXPECT_NEAR(display_modes[0].ui_scale, 0.5, 0.01); 109 EXPECT_EQ(display_modes[0].refresh_rate, 60); 110 111 EXPECT_EQ("1366x768", display_modes[1].size.ToString()); 112 EXPECT_FALSE(display_modes[1].native); 113 EXPECT_NEAR(display_modes[1].ui_scale, 0.6, 0.01); 114 EXPECT_EQ(display_modes[1].refresh_rate, 60); 115 116 EXPECT_EQ("1366x768", display_modes[2].size.ToString()); 117 EXPECT_FALSE(display_modes[2].native); 118 EXPECT_NEAR(display_modes[2].ui_scale, 0.75, 0.01); 119 EXPECT_EQ(display_modes[2].refresh_rate, 60); 120 121 EXPECT_EQ("1366x768", display_modes[3].size.ToString()); 122 EXPECT_TRUE(display_modes[3].native); 123 EXPECT_NEAR(display_modes[3].ui_scale, 1.0, 0.01); 124 EXPECT_EQ(display_modes[3].refresh_rate, 60); 125 126 EXPECT_EQ("1366x768", display_modes[4].size.ToString()); 127 EXPECT_FALSE(display_modes[4].native); 128 EXPECT_NEAR(display_modes[4].ui_scale, 1.125, 0.01); 129 EXPECT_EQ(display_modes[4].refresh_rate, 60); 130 } 131 132 TEST_F(DisplayChangeObserverTest, GetInternalHiDPIDisplayModeList) { 133 ScopedVector<const ui::DisplayMode> modes; 134 // Data picked from peppy. 135 modes.push_back(new ui::DisplayMode(gfx::Size(2560, 1700), false, 60)); 136 modes.push_back(new ui::DisplayMode(gfx::Size(2048, 1536), false, 60)); 137 modes.push_back(new ui::DisplayMode(gfx::Size(1920, 1440), false, 60)); 138 139 ui::TestDisplaySnapshot display_snapshot; 140 display_snapshot.set_modes(modes.get()); 141 display_snapshot.set_native_mode(modes[0]); 142 DisplayConfigurator::DisplayState output; 143 output.display = &display_snapshot; 144 145 DisplayInfo info; 146 info.SetBounds(gfx::Rect(0, 0, 2560, 1700)); 147 info.set_device_scale_factor(2.0f); 148 149 std::vector<DisplayMode> display_modes = 150 DisplayChangeObserver::GetInternalDisplayModeList(info, output); 151 ASSERT_EQ(8u, display_modes.size()); 152 EXPECT_EQ("2560x1700", display_modes[0].size.ToString()); 153 EXPECT_FALSE(display_modes[0].native); 154 EXPECT_NEAR(display_modes[0].ui_scale, 0.5, 0.01); 155 EXPECT_EQ(display_modes[0].refresh_rate, 60); 156 157 EXPECT_EQ("2560x1700", display_modes[1].size.ToString()); 158 EXPECT_FALSE(display_modes[1].native); 159 EXPECT_NEAR(display_modes[1].ui_scale, 0.625, 0.01); 160 EXPECT_EQ(display_modes[1].refresh_rate, 60); 161 162 EXPECT_EQ("2560x1700", display_modes[2].size.ToString()); 163 EXPECT_FALSE(display_modes[2].native); 164 EXPECT_NEAR(display_modes[2].ui_scale, 0.8, 0.01); 165 EXPECT_EQ(display_modes[2].refresh_rate, 60); 166 167 EXPECT_EQ("2560x1700", display_modes[3].size.ToString()); 168 EXPECT_FALSE(display_modes[3].native); 169 EXPECT_NEAR(display_modes[3].ui_scale, 1.0, 0.01); 170 EXPECT_EQ(display_modes[3].refresh_rate, 60); 171 172 EXPECT_EQ("2560x1700", display_modes[4].size.ToString()); 173 EXPECT_FALSE(display_modes[4].native); 174 EXPECT_NEAR(display_modes[4].ui_scale, 1.125, 0.01); 175 EXPECT_EQ(display_modes[4].refresh_rate, 60); 176 177 EXPECT_EQ("2560x1700", display_modes[5].size.ToString()); 178 EXPECT_FALSE(display_modes[5].native); 179 EXPECT_NEAR(display_modes[5].ui_scale, 1.25, 0.01); 180 EXPECT_EQ(display_modes[5].refresh_rate, 60); 181 182 EXPECT_EQ("2560x1700", display_modes[6].size.ToString()); 183 EXPECT_FALSE(display_modes[6].native); 184 EXPECT_NEAR(display_modes[6].ui_scale, 1.5, 0.01); 185 EXPECT_EQ(display_modes[6].refresh_rate, 60); 186 187 EXPECT_EQ("2560x1700", display_modes[7].size.ToString()); 188 EXPECT_TRUE(display_modes[7].native); 189 EXPECT_NEAR(display_modes[7].ui_scale, 2.0, 0.01); 190 EXPECT_EQ(display_modes[7].refresh_rate, 60); 191 } 192 193 TEST_F(DisplayChangeObserverTest, GetInternalDisplayModeList1_25) { 194 ScopedVector<const ui::DisplayMode> modes; 195 // Data picked from peppy. 196 modes.push_back(new ui::DisplayMode(gfx::Size(1920, 1080), false, 60)); 197 198 ui::TestDisplaySnapshot display_snapshot; 199 display_snapshot.set_modes(modes.get()); 200 display_snapshot.set_native_mode(modes[0]); 201 DisplayConfigurator::DisplayState output; 202 output.display = &display_snapshot; 203 204 DisplayInfo info; 205 info.SetBounds(gfx::Rect(0, 0, 1920, 1080)); 206 info.set_device_scale_factor(1.25); 207 208 std::vector<DisplayMode> display_modes = 209 DisplayChangeObserver::GetInternalDisplayModeList(info, output); 210 ASSERT_EQ(5u, display_modes.size()); 211 EXPECT_EQ("1920x1080", display_modes[0].size.ToString()); 212 EXPECT_FALSE(display_modes[0].native); 213 EXPECT_NEAR(display_modes[0].ui_scale, 0.5, 0.01); 214 EXPECT_EQ(display_modes[0].refresh_rate, 60); 215 216 EXPECT_EQ("1920x1080", display_modes[1].size.ToString()); 217 EXPECT_FALSE(display_modes[1].native); 218 EXPECT_NEAR(display_modes[1].ui_scale, 0.625, 0.01); 219 EXPECT_EQ(display_modes[1].refresh_rate, 60); 220 221 EXPECT_EQ("1920x1080", display_modes[2].size.ToString()); 222 EXPECT_FALSE(display_modes[2].native); 223 EXPECT_NEAR(display_modes[2].ui_scale, 0.8, 0.01); 224 EXPECT_EQ(display_modes[2].refresh_rate, 60); 225 226 EXPECT_EQ("1920x1080", display_modes[3].size.ToString()); 227 EXPECT_TRUE(display_modes[3].native); 228 EXPECT_NEAR(display_modes[3].ui_scale, 1.0, 0.01); 229 EXPECT_EQ(display_modes[3].refresh_rate, 60); 230 231 EXPECT_EQ("1920x1080", display_modes[4].size.ToString()); 232 EXPECT_FALSE(display_modes[4].native); 233 EXPECT_NEAR(display_modes[4].ui_scale, 1.25, 0.01); 234 EXPECT_EQ(display_modes[4].refresh_rate, 60); 235 } 236 237 TEST_F(DisplayChangeObserverTest, GetExternalDisplayModeList4K) { 238 ScopedVector<const ui::DisplayMode> modes; 239 modes.push_back(new ui::DisplayMode(gfx::Size(3840, 2160), false, 30)); 240 modes.push_back(new ui::DisplayMode(gfx::Size(1920, 1200), false, 60)); 241 242 // All non-interlaced (as would be seen with different refresh rates). 243 modes.push_back(new ui::DisplayMode(gfx::Size(1920, 1080), false, 80)); 244 modes.push_back(new ui::DisplayMode(gfx::Size(1920, 1080), false, 70)); 245 modes.push_back(new ui::DisplayMode(gfx::Size(1920, 1080), false, 60)); 246 247 // Interlaced vs non-interlaced. 248 modes.push_back(new ui::DisplayMode(gfx::Size(1280, 720), true, 60)); 249 modes.push_back(new ui::DisplayMode(gfx::Size(1280, 720), false, 60)); 250 251 // Interlaced only. 252 modes.push_back(new ui::DisplayMode(gfx::Size(1024, 768), true, 70)); 253 modes.push_back(new ui::DisplayMode(gfx::Size(1024, 768), true, 60)); 254 255 // Mixed. 256 modes.push_back(new ui::DisplayMode(gfx::Size(1024, 600), true, 60)); 257 modes.push_back(new ui::DisplayMode(gfx::Size(1024, 600), false, 70)); 258 modes.push_back(new ui::DisplayMode(gfx::Size(1024, 600), false, 60)); 259 260 // Just one interlaced mode. 261 modes.push_back(new ui::DisplayMode(gfx::Size(640, 480), true, 60)); 262 263 ui::TestDisplaySnapshot display_snapshot; 264 display_snapshot.set_modes(modes.get()); 265 display_snapshot.set_native_mode(modes[0]); 266 DisplayConfigurator::DisplayState output; 267 output.display = &display_snapshot; 268 269 std::vector<DisplayMode> display_modes = 270 DisplayChangeObserver::GetExternalDisplayModeList(output); 271 ASSERT_EQ(9u, display_modes.size()); 272 EXPECT_EQ("640x480", display_modes[0].size.ToString()); 273 EXPECT_TRUE(display_modes[0].interlaced); 274 EXPECT_EQ(display_modes[0].refresh_rate, 60); 275 276 EXPECT_EQ("1024x600", display_modes[1].size.ToString()); 277 EXPECT_FALSE(display_modes[1].interlaced); 278 EXPECT_EQ(display_modes[1].refresh_rate, 70); 279 280 EXPECT_EQ("1024x768", display_modes[2].size.ToString()); 281 EXPECT_TRUE(display_modes[2].interlaced); 282 EXPECT_EQ(display_modes[2].refresh_rate, 70); 283 284 EXPECT_EQ("1280x720", display_modes[3].size.ToString()); 285 EXPECT_FALSE(display_modes[3].interlaced); 286 EXPECT_EQ(display_modes[3].refresh_rate, 60); 287 288 EXPECT_EQ("1920x1080", display_modes[4].size.ToString()); 289 EXPECT_FALSE(display_modes[4].interlaced); 290 EXPECT_EQ(display_modes[4].refresh_rate, 80); 291 292 EXPECT_EQ("3840x2160", display_modes[5].size.ToString()); 293 EXPECT_FALSE(display_modes[5].interlaced); 294 EXPECT_FALSE(display_modes[5].native); 295 EXPECT_EQ(display_modes[5].refresh_rate, 30); 296 EXPECT_EQ(display_modes[5].device_scale_factor, 2.0); 297 298 EXPECT_EQ("1920x1200", display_modes[6].size.ToString()); 299 EXPECT_FALSE(display_modes[6].interlaced); 300 EXPECT_EQ(display_modes[6].refresh_rate, 60); 301 302 EXPECT_EQ("3840x2160", display_modes[7].size.ToString()); 303 EXPECT_FALSE(display_modes[7].interlaced); 304 EXPECT_FALSE(display_modes[7].native); 305 EXPECT_EQ(display_modes[7].refresh_rate, 30); 306 EXPECT_EQ(display_modes[7].device_scale_factor, 1.25); 307 308 EXPECT_EQ("3840x2160", display_modes[8].size.ToString()); 309 EXPECT_FALSE(display_modes[8].interlaced); 310 EXPECT_TRUE(display_modes[8].native); 311 EXPECT_EQ(display_modes[8].refresh_rate, 30); 312 313 // Outputs without any modes shouldn't cause a crash. 314 modes.clear(); 315 display_snapshot.set_modes(modes.get()); 316 317 display_modes = DisplayChangeObserver::GetExternalDisplayModeList(output); 318 EXPECT_EQ(0u, display_modes.size()); 319 } 320 321 TEST_F(DisplayChangeObserverTest, FindDeviceScaleFactor) { 322 // 19.5" 1600x900 323 EXPECT_EQ(1.0f, DisplayChangeObserver::FindDeviceScaleFactor(94.14f)); 324 325 // 21.5" 1920x1080 326 EXPECT_EQ(1.0f, DisplayChangeObserver::FindDeviceScaleFactor(102.46f)); 327 328 // 12.1" 1280x800 329 EXPECT_EQ(1.0f, DisplayChangeObserver::FindDeviceScaleFactor(124.75f)); 330 331 // 13.3" 1920x1080 332 EXPECT_EQ(1.25f, DisplayChangeObserver::FindDeviceScaleFactor(157.35f)); 333 334 // 14" 1920x1080 335 EXPECT_EQ(1.25f, DisplayChangeObserver::FindDeviceScaleFactor(165.63f)); 336 337 // 12.85" 2560x1700 338 EXPECT_EQ(2.0f, DisplayChangeObserver::FindDeviceScaleFactor(239.15f)); 339 340 // Erroneous values should still work. 341 EXPECT_EQ(1.0f, DisplayChangeObserver::FindDeviceScaleFactor(-100.0f)); 342 EXPECT_EQ(1.0f, DisplayChangeObserver::FindDeviceScaleFactor(0.0f)); 343 EXPECT_EQ(2.0f, DisplayChangeObserver::FindDeviceScaleFactor(10000.0f)); 344 } 345 346 } // namespace ash 347