Home | History | Annotate | Download | only in gfx
      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