1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "ui/gfx/display_change_notifier.h" 6 7 #include "testing/gtest/include/gtest/gtest.h" 8 #include "ui/gfx/display.h" 9 #include "ui/gfx/display_observer.h" 10 11 namespace gfx { 12 13 class MockDisplayObserver : public DisplayObserver { 14 public: 15 MockDisplayObserver() 16 : display_added_(0), 17 display_removed_(0), 18 display_changed_(0), 19 latest_metrics_change_(DisplayObserver::DISPLAY_METRIC_NONE) 20 {} 21 22 virtual ~MockDisplayObserver() { } 23 24 virtual void OnDisplayAdded(const Display& display) OVERRIDE { 25 display_added_++; 26 } 27 28 virtual void OnDisplayRemoved(const Display& display) OVERRIDE { 29 display_removed_++; 30 } 31 32 virtual void OnDisplayMetricsChanged(const Display& display, 33 uint32_t metrics) OVERRIDE { 34 display_changed_++; 35 latest_metrics_change_ = metrics; 36 } 37 38 int display_added() const { 39 return display_added_; 40 } 41 42 int display_removed() const { 43 return display_removed_; 44 } 45 46 int display_changed() const { 47 return display_changed_; 48 } 49 50 uint32_t latest_metrics_change() const { 51 return latest_metrics_change_; 52 } 53 54 protected: 55 int display_added_; 56 int display_removed_; 57 int display_changed_; 58 uint32_t latest_metrics_change_; 59 60 DISALLOW_COPY_AND_ASSIGN(MockDisplayObserver); 61 }; 62 63 TEST(DisplayChangeNotifierTest, AddObserver_Smoke) { 64 DisplayChangeNotifier change_notifier; 65 MockDisplayObserver observer; 66 67 change_notifier.NotifyDisplaysChanged( 68 std::vector<Display>(), std::vector<Display>(1, Display())); 69 EXPECT_EQ(0, observer.display_added()); 70 71 change_notifier.AddObserver(&observer); 72 change_notifier.NotifyDisplaysChanged( 73 std::vector<Display>(), std::vector<Display>(1, Display())); 74 EXPECT_EQ(1, observer.display_added()); 75 } 76 77 TEST(DisplayChangeNotifierTest, AddObserver_Null) { 78 DisplayChangeNotifier change_notifier; 79 80 change_notifier.AddObserver(NULL); 81 // Should not crash. 82 } 83 84 TEST(DisplayChangeNotifier, RemoveObserver_Smoke) { 85 DisplayChangeNotifier change_notifier; 86 MockDisplayObserver observer; 87 88 change_notifier.NotifyDisplaysChanged( 89 std::vector<Display>(), std::vector<Display>(1, Display())); 90 EXPECT_EQ(0, observer.display_added()); 91 92 change_notifier.AddObserver(&observer); 93 change_notifier.RemoveObserver(&observer); 94 95 change_notifier.NotifyDisplaysChanged( 96 std::vector<Display>(), std::vector<Display>(1, Display())); 97 EXPECT_EQ(0, observer.display_added()); 98 } 99 100 TEST(DisplayChangeNotifierTest, RemoveObserver_Null) { 101 DisplayChangeNotifier change_notifier; 102 103 change_notifier.RemoveObserver(NULL); 104 // Should not crash. 105 } 106 107 TEST(DisplayChangeNotifierTest, RemoveObserver_Unknown) { 108 DisplayChangeNotifier change_notifier; 109 MockDisplayObserver observer; 110 111 change_notifier.RemoveObserver(&observer); 112 // Should not crash. 113 } 114 115 TEST(DisplayChangeNotifierTest, NotifyDisplaysChanged_Removed) { 116 DisplayChangeNotifier change_notifier; 117 118 // If the previous display array is empty, no removal. 119 { 120 MockDisplayObserver observer; 121 change_notifier.AddObserver(&observer); 122 123 std::vector<Display> old_displays, new_displays; 124 new_displays.push_back(Display()); 125 126 change_notifier.NotifyDisplaysChanged(old_displays, new_displays); 127 EXPECT_EQ(0, observer.display_removed()); 128 129 change_notifier.RemoveObserver(&observer); 130 } 131 132 // If the previous and new display array are empty, no removal. 133 { 134 MockDisplayObserver observer; 135 change_notifier.AddObserver(&observer); 136 137 std::vector<Display> old_displays, new_displays; 138 139 change_notifier.NotifyDisplaysChanged(old_displays, new_displays); 140 EXPECT_EQ(0, observer.display_removed()); 141 142 change_notifier.RemoveObserver(&observer); 143 } 144 145 // If the new display array is empty, there are as many removal as old 146 // displays. 147 { 148 MockDisplayObserver observer; 149 change_notifier.AddObserver(&observer); 150 151 std::vector<Display> old_displays, new_displays; 152 old_displays.push_back(Display()); 153 old_displays.push_back(Display()); 154 old_displays.push_back(Display()); 155 156 change_notifier.NotifyDisplaysChanged(old_displays, new_displays); 157 EXPECT_EQ(3, observer.display_removed()); 158 159 change_notifier.RemoveObserver(&observer); 160 } 161 162 // If displays don't use ids, as long as the new display array has one 163 // element, there are no removals. 164 { 165 MockDisplayObserver observer; 166 change_notifier.AddObserver(&observer); 167 168 std::vector<Display> old_displays, new_displays; 169 old_displays.push_back(Display()); 170 old_displays.push_back(Display()); 171 old_displays.push_back(Display()); 172 new_displays.push_back(Display()); 173 174 change_notifier.NotifyDisplaysChanged(old_displays, new_displays); 175 EXPECT_EQ(0, observer.display_removed()); 176 177 change_notifier.RemoveObserver(&observer); 178 } 179 180 // If displays use ids (and they are unique), ids not present in the new 181 // display array will be marked as removed. 182 { 183 MockDisplayObserver observer; 184 change_notifier.AddObserver(&observer); 185 186 std::vector<Display> old_displays, new_displays; 187 old_displays.push_back(Display(1)); 188 old_displays.push_back(Display(2)); 189 old_displays.push_back(Display(3)); 190 new_displays.push_back(Display(2)); 191 192 change_notifier.NotifyDisplaysChanged(old_displays, new_displays); 193 EXPECT_EQ(2, observer.display_removed()); 194 195 change_notifier.RemoveObserver(&observer); 196 } 197 } 198 199 TEST(DisplayChangeNotifierTest, NotifyDisplaysChanged_Added) { 200 DisplayChangeNotifier change_notifier; 201 202 // If the new display array is empty, no addition. 203 { 204 MockDisplayObserver observer; 205 change_notifier.AddObserver(&observer); 206 207 std::vector<Display> old_displays, new_displays; 208 old_displays.push_back(Display()); 209 210 change_notifier.NotifyDisplaysChanged(old_displays, new_displays); 211 EXPECT_EQ(0, observer.display_added()); 212 213 change_notifier.RemoveObserver(&observer); 214 } 215 216 // If the old and new display arrays are empty, no addition. 217 { 218 MockDisplayObserver observer; 219 change_notifier.AddObserver(&observer); 220 221 std::vector<Display> old_displays, new_displays; 222 223 change_notifier.NotifyDisplaysChanged(old_displays, new_displays); 224 EXPECT_EQ(0, observer.display_added()); 225 226 change_notifier.RemoveObserver(&observer); 227 } 228 229 // If the old display array is empty, there are as many addition as new 230 // displays. 231 { 232 MockDisplayObserver observer; 233 change_notifier.AddObserver(&observer); 234 235 std::vector<Display> old_displays, new_displays; 236 new_displays.push_back(Display()); 237 new_displays.push_back(Display()); 238 new_displays.push_back(Display()); 239 240 change_notifier.NotifyDisplaysChanged(old_displays, new_displays); 241 EXPECT_EQ(3, observer.display_added()); 242 243 change_notifier.RemoveObserver(&observer); 244 } 245 246 // If displays don't use ids, as long as the old display array has one 247 // element, there are no additions. 248 { 249 MockDisplayObserver observer; 250 change_notifier.AddObserver(&observer); 251 252 std::vector<Display> old_displays, new_displays; 253 old_displays.push_back(Display()); 254 new_displays.push_back(Display()); 255 new_displays.push_back(Display()); 256 new_displays.push_back(Display()); 257 258 change_notifier.NotifyDisplaysChanged(old_displays, new_displays); 259 EXPECT_EQ(0, observer.display_added()); 260 261 change_notifier.RemoveObserver(&observer); 262 } 263 264 // If displays use ids (and they are unique), ids not present in the old 265 // display array will be marked as added. 266 { 267 MockDisplayObserver observer; 268 change_notifier.AddObserver(&observer); 269 270 std::vector<Display> old_displays, new_displays; 271 old_displays.push_back(Display(1)); 272 new_displays.push_back(Display(1)); 273 new_displays.push_back(Display(2)); 274 new_displays.push_back(Display(3)); 275 276 change_notifier.NotifyDisplaysChanged(old_displays, new_displays); 277 EXPECT_EQ(2, observer.display_added()); 278 279 change_notifier.RemoveObserver(&observer); 280 } 281 } 282 283 TEST(DisplayChangeNotifierTest, NotifyDisplaysChanged_Changed_Smoke) { 284 DisplayChangeNotifier change_notifier; 285 286 // If the old display array is empty, no change. 287 { 288 MockDisplayObserver observer; 289 change_notifier.AddObserver(&observer); 290 291 std::vector<Display> old_displays, new_displays; 292 new_displays.push_back(Display()); 293 294 change_notifier.NotifyDisplaysChanged(old_displays, new_displays); 295 EXPECT_EQ(0, observer.display_changed()); 296 297 change_notifier.RemoveObserver(&observer); 298 } 299 300 // If the new display array is empty, no change. 301 { 302 MockDisplayObserver observer; 303 change_notifier.AddObserver(&observer); 304 305 std::vector<Display> old_displays, new_displays; 306 old_displays.push_back(Display()); 307 308 change_notifier.NotifyDisplaysChanged(old_displays, new_displays); 309 EXPECT_EQ(0, observer.display_changed()); 310 311 change_notifier.RemoveObserver(&observer); 312 } 313 314 // If the old and new display arrays are empty, no change. 315 { 316 MockDisplayObserver observer; 317 change_notifier.AddObserver(&observer); 318 319 std::vector<Display> old_displays, new_displays; 320 321 change_notifier.NotifyDisplaysChanged(old_displays, new_displays); 322 EXPECT_EQ(0, observer.display_changed()); 323 324 change_notifier.RemoveObserver(&observer); 325 } 326 327 // If there is an intersection between old and new displays but there are no 328 // metrics changes, there is no display change. 329 { 330 MockDisplayObserver observer; 331 change_notifier.AddObserver(&observer); 332 333 std::vector<Display> old_displays, new_displays; 334 old_displays.push_back(Display(1)); 335 new_displays.push_back(Display(1)); 336 new_displays.push_back(Display(2)); 337 new_displays.push_back(Display(3)); 338 339 change_notifier.NotifyDisplaysChanged(old_displays, new_displays); 340 EXPECT_EQ(0, observer.display_changed()); 341 342 change_notifier.RemoveObserver(&observer); 343 } 344 } 345 346 TEST(DisplayChangeNotifierTest, NotifyDisplaysChanged_Changed_Bounds) { 347 DisplayChangeNotifier change_notifier; 348 349 { 350 MockDisplayObserver observer; 351 change_notifier.AddObserver(&observer); 352 353 std::vector<Display> old_displays, new_displays; 354 old_displays.push_back(Display(1, Rect(0, 0, 200, 200))); 355 new_displays.push_back(Display(1, Rect(0, 0, 200, 200))); 356 357 change_notifier.NotifyDisplaysChanged(old_displays, new_displays); 358 EXPECT_EQ(0, observer.display_changed()); 359 360 change_notifier.RemoveObserver(&observer); 361 } 362 363 { 364 MockDisplayObserver observer; 365 change_notifier.AddObserver(&observer); 366 367 std::vector<Display> old_displays, new_displays; 368 old_displays.push_back(Display(1, Rect(0, 0, 200, 200))); 369 new_displays.push_back(Display(1, Rect(10, 10, 300, 300))); 370 371 change_notifier.NotifyDisplaysChanged(old_displays, new_displays); 372 EXPECT_EQ(1, observer.display_changed()); 373 uint32_t metrics_change = DisplayObserver::DISPLAY_METRIC_BOUNDS | 374 DisplayObserver::DISPLAY_METRIC_WORK_AREA; 375 EXPECT_EQ(metrics_change, observer.latest_metrics_change()); 376 377 change_notifier.RemoveObserver(&observer); 378 } 379 380 { 381 MockDisplayObserver observer; 382 change_notifier.AddObserver(&observer); 383 384 std::vector<Display> old_displays, new_displays; 385 old_displays.push_back(Display(1, Rect(0, 0, 200, 200))); 386 new_displays.push_back(Display(1, Rect(0, 0, 200, 200))); 387 new_displays[0].set_bounds(Rect(10, 10, 300, 300)); 388 389 change_notifier.NotifyDisplaysChanged(old_displays, new_displays); 390 EXPECT_EQ(1, observer.display_changed()); 391 EXPECT_EQ(DisplayObserver::DISPLAY_METRIC_BOUNDS, 392 observer.latest_metrics_change()); 393 394 change_notifier.RemoveObserver(&observer); 395 } 396 } 397 398 TEST(DisplayChangeNotifierTest, NotifyDisplaysChanged_Changed_Rotation) { 399 DisplayChangeNotifier change_notifier; 400 MockDisplayObserver observer; 401 change_notifier.AddObserver(&observer); 402 403 std::vector<Display> old_displays, new_displays; 404 old_displays.push_back(Display(1)); 405 old_displays[0].SetRotationAsDegree(0); 406 new_displays.push_back(Display(1)); 407 new_displays[0].SetRotationAsDegree(180); 408 409 change_notifier.NotifyDisplaysChanged(old_displays, new_displays); 410 EXPECT_EQ(1, observer.display_changed()); 411 EXPECT_EQ(DisplayObserver::DISPLAY_METRIC_ROTATION, 412 observer.latest_metrics_change()); 413 } 414 415 TEST(DisplayChangeNotifierTest, NotifyDisplaysChanged_Changed_WorkArea) { 416 DisplayChangeNotifier change_notifier; 417 MockDisplayObserver observer; 418 change_notifier.AddObserver(&observer); 419 420 std::vector<Display> old_displays, new_displays; 421 old_displays.push_back(Display(1)); 422 old_displays[0].set_work_area(Rect(0, 0, 200, 200)); 423 new_displays.push_back(Display(1)); 424 new_displays[0].set_work_area(Rect(20, 20, 300, 300)); 425 426 change_notifier.NotifyDisplaysChanged(old_displays, new_displays); 427 EXPECT_EQ(1, observer.display_changed()); 428 EXPECT_EQ(DisplayObserver::DISPLAY_METRIC_WORK_AREA, 429 observer.latest_metrics_change()); 430 } 431 432 TEST(DisplayChangeNotifierTest, NotifyDisplaysChanged_Changed_DSF) { 433 DisplayChangeNotifier change_notifier; 434 MockDisplayObserver observer; 435 change_notifier.AddObserver(&observer); 436 437 std::vector<Display> old_displays, new_displays; 438 old_displays.push_back(Display(1)); 439 old_displays[0].set_device_scale_factor(1.f); 440 new_displays.push_back(Display(1)); 441 new_displays[0].set_device_scale_factor(2.f); 442 443 change_notifier.NotifyDisplaysChanged(old_displays, new_displays); 444 EXPECT_EQ(1, observer.display_changed()); 445 EXPECT_EQ(DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR, 446 observer.latest_metrics_change()); 447 } 448 449 TEST(DisplayChangeNotifierTest, NotifyDisplaysChanged_Changed_Multi_Displays) { 450 DisplayChangeNotifier change_notifier; 451 MockDisplayObserver observer; 452 change_notifier.AddObserver(&observer); 453 454 std::vector<Display> old_displays, new_displays; 455 old_displays.push_back(Display(1)); 456 old_displays.push_back(Display(2)); 457 old_displays.push_back(Display(3)); 458 new_displays.push_back(Display(1)); 459 new_displays.push_back(Display(2)); 460 new_displays.push_back(Display(3)); 461 462 old_displays[0].set_device_scale_factor(1.f); 463 new_displays[0].set_device_scale_factor(2.f); 464 465 old_displays[1].set_bounds(Rect(0, 0, 200, 200)); 466 new_displays[1].set_bounds(Rect(0, 0, 400, 400)); 467 468 old_displays[2].SetRotationAsDegree(0); 469 new_displays[2].SetRotationAsDegree(90); 470 471 change_notifier.NotifyDisplaysChanged(old_displays, new_displays); 472 EXPECT_EQ(3, observer.display_changed()); 473 } 474 475 TEST(DisplayChangeNotifierTest, NotifyDisplaysChanged_Changed_Multi_Metrics) { 476 DisplayChangeNotifier change_notifier; 477 MockDisplayObserver observer; 478 change_notifier.AddObserver(&observer); 479 480 std::vector<Display> old_displays, new_displays; 481 old_displays.push_back(Display(1, Rect(0, 0, 200, 200))); 482 old_displays[0].set_device_scale_factor(1.f); 483 old_displays[0].SetRotationAsDegree(0); 484 485 new_displays.push_back(Display(1, Rect(100, 100, 200, 200))); 486 new_displays[0].set_device_scale_factor(2.f); 487 new_displays[0].SetRotationAsDegree(90); 488 489 change_notifier.NotifyDisplaysChanged(old_displays, new_displays); 490 EXPECT_EQ(1, observer.display_changed()); 491 uint32_t metrics = DisplayObserver::DISPLAY_METRIC_BOUNDS | 492 DisplayObserver::DISPLAY_METRIC_ROTATION | 493 DisplayObserver::DISPLAY_METRIC_WORK_AREA | 494 DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR; 495 EXPECT_EQ(metrics, observer.latest_metrics_change()); 496 } 497 498 } // namespace gfx 499