Home | History | Annotate | Download | only in views
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <map>
      6 
      7 #include "base/memory/scoped_ptr.h"
      8 #include "base/rand_util.h"
      9 #include "base/strings/string_util.h"
     10 #include "base/strings/stringprintf.h"
     11 #include "base/strings/utf_string_conversions.h"
     12 #include "ui/base/accelerators/accelerator.h"
     13 #include "ui/base/clipboard/clipboard.h"
     14 #include "ui/base/l10n/l10n_util.h"
     15 #include "ui/compositor/compositor.h"
     16 #include "ui/compositor/layer.h"
     17 #include "ui/compositor/layer_animator.h"
     18 #include "ui/compositor/test/draw_waiter_for_test.h"
     19 #include "ui/events/event.h"
     20 #include "ui/events/keycodes/keyboard_codes.h"
     21 #include "ui/gfx/canvas.h"
     22 #include "ui/gfx/path.h"
     23 #include "ui/gfx/transform.h"
     24 #include "ui/strings/grit/ui_strings.h"
     25 #include "ui/views/background.h"
     26 #include "ui/views/controls/native/native_view_host.h"
     27 #include "ui/views/controls/scroll_view.h"
     28 #include "ui/views/controls/textfield/textfield.h"
     29 #include "ui/views/focus/view_storage.h"
     30 #include "ui/views/test/views_test_base.h"
     31 #include "ui/views/view.h"
     32 #include "ui/views/views_delegate.h"
     33 #include "ui/views/widget/native_widget.h"
     34 #include "ui/views/widget/root_view.h"
     35 #include "ui/views/window/dialog_client_view.h"
     36 #include "ui/views/window/dialog_delegate.h"
     37 
     38 using base::ASCIIToUTF16;
     39 
     40 namespace {
     41 
     42 // Returns true if |ancestor| is an ancestor of |layer|.
     43 bool LayerIsAncestor(const ui::Layer* ancestor, const ui::Layer* layer) {
     44   while (layer && layer != ancestor)
     45     layer = layer->parent();
     46   return layer == ancestor;
     47 }
     48 
     49 // Convenience functions for walking a View tree.
     50 const views::View* FirstView(const views::View* view) {
     51   const views::View* v = view;
     52   while (v->has_children())
     53     v = v->child_at(0);
     54   return v;
     55 }
     56 
     57 const views::View* NextView(const views::View* view) {
     58   const views::View* v = view;
     59   const views::View* parent = v->parent();
     60   if (!parent)
     61     return NULL;
     62   int next = parent->GetIndexOf(v) + 1;
     63   if (next != parent->child_count())
     64     return FirstView(parent->child_at(next));
     65   return parent;
     66 }
     67 
     68 // Convenience functions for walking a Layer tree.
     69 const ui::Layer* FirstLayer(const ui::Layer* layer) {
     70   const ui::Layer* l = layer;
     71   while (l->children().size() > 0)
     72     l = l->children()[0];
     73   return l;
     74 }
     75 
     76 const ui::Layer* NextLayer(const ui::Layer* layer) {
     77   const ui::Layer* parent = layer->parent();
     78   if (!parent)
     79     return NULL;
     80   const std::vector<ui::Layer*> children = parent->children();
     81   size_t index;
     82   for (index = 0; index < children.size(); index++) {
     83     if (children[index] == layer)
     84       break;
     85   }
     86   size_t next = index + 1;
     87   if (next < children.size())
     88     return FirstLayer(children[next]);
     89   return parent;
     90 }
     91 
     92 // Given the root nodes of a View tree and a Layer tree, makes sure the two
     93 // trees are in sync.
     94 bool ViewAndLayerTreeAreConsistent(const views::View* view,
     95                                    const ui::Layer* layer) {
     96   const views::View* v = FirstView(view);
     97   const ui::Layer* l = FirstLayer(layer);
     98   while (v && l) {
     99     // Find the view with a layer.
    100     while (v && !v->layer())
    101       v = NextView(v);
    102     EXPECT_TRUE(v);
    103     if (!v)
    104       return false;
    105 
    106     // Check if the View tree and the Layer tree are in sync.
    107     EXPECT_EQ(l, v->layer());
    108     if (v->layer() != l)
    109       return false;
    110 
    111     // Check if the visibility states of the View and the Layer are in sync.
    112     EXPECT_EQ(l->IsDrawn(), v->IsDrawn());
    113     if (v->IsDrawn() != l->IsDrawn()) {
    114       for (const views::View* vv = v; vv; vv = vv->parent())
    115         LOG(ERROR) << "V: " << vv << " " << vv->visible() << " "
    116                    << vv->IsDrawn() << " " << vv->layer();
    117       for (const ui::Layer* ll = l; ll; ll = ll->parent())
    118         LOG(ERROR) << "L: " << ll << " " << ll->IsDrawn();
    119       return false;
    120     }
    121 
    122     // Check if the size of the View and the Layer are in sync.
    123     EXPECT_EQ(l->bounds(), v->bounds());
    124     if (v->bounds() != l->bounds())
    125       return false;
    126 
    127     if (v == view || l == layer)
    128       return v == view && l == layer;
    129 
    130     v = NextView(v);
    131     l = NextLayer(l);
    132   }
    133 
    134   return false;
    135 }
    136 
    137 // Constructs a View tree with the specified depth.
    138 void ConstructTree(views::View* view, int depth) {
    139   if (depth == 0)
    140     return;
    141   int count = base::RandInt(1, 5);
    142   for (int i = 0; i < count; i++) {
    143     views::View* v = new views::View;
    144     view->AddChildView(v);
    145     if (base::RandDouble() > 0.5)
    146       v->SetPaintToLayer(true);
    147     if (base::RandDouble() < 0.2)
    148       v->SetVisible(false);
    149 
    150     ConstructTree(v, depth - 1);
    151   }
    152 }
    153 
    154 void ScrambleTree(views::View* view) {
    155   int count = view->child_count();
    156   if (count == 0)
    157     return;
    158   for (int i = 0; i < count; i++) {
    159     ScrambleTree(view->child_at(i));
    160   }
    161 
    162   if (count > 1) {
    163     int a = base::RandInt(0, count - 1);
    164     int b = base::RandInt(0, count - 1);
    165 
    166     views::View* view_a = view->child_at(a);
    167     views::View* view_b = view->child_at(b);
    168     view->ReorderChildView(view_a, b);
    169     view->ReorderChildView(view_b, a);
    170   }
    171 
    172   if (!view->layer() && base::RandDouble() < 0.1)
    173     view->SetPaintToLayer(true);
    174 
    175   if (base::RandDouble() < 0.1)
    176     view->SetVisible(!view->visible());
    177 }
    178 
    179 }  // namespace
    180 
    181 namespace views {
    182 
    183 typedef ViewsTestBase ViewTest;
    184 
    185 // A derived class for testing purpose.
    186 class TestView : public View {
    187  public:
    188   TestView()
    189       : View(),
    190         delete_on_pressed_(false),
    191         native_theme_(NULL),
    192         can_process_events_within_subtree_(true) {}
    193   virtual ~TestView() {}
    194 
    195   // Reset all test state
    196   void Reset() {
    197     did_change_bounds_ = false;
    198     last_mouse_event_type_ = 0;
    199     location_.SetPoint(0, 0);
    200     received_mouse_enter_ = false;
    201     received_mouse_exit_ = false;
    202     last_clip_.setEmpty();
    203     accelerator_count_map_.clear();
    204     can_process_events_within_subtree_ = true;
    205   }
    206 
    207   // Exposed as public for testing.
    208   void DoFocus() {
    209     views::View::Focus();
    210   }
    211 
    212   void DoBlur() {
    213     views::View::Blur();
    214   }
    215 
    216   bool focusable() const { return View::focusable(); }
    217 
    218   void set_can_process_events_within_subtree(bool can_process) {
    219     can_process_events_within_subtree_ = can_process;
    220   }
    221 
    222   virtual bool CanProcessEventsWithinSubtree() const OVERRIDE {
    223     return can_process_events_within_subtree_;
    224   }
    225 
    226   virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE;
    227   virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE;
    228   virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE;
    229   virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE;
    230   virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE;
    231   virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE;
    232 
    233   virtual void Paint(gfx::Canvas* canvas, const CullSet& cull_set) OVERRIDE;
    234   virtual void SchedulePaintInRect(const gfx::Rect& rect) OVERRIDE;
    235   virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
    236 
    237   virtual void OnNativeThemeChanged(const ui::NativeTheme* native_theme)
    238       OVERRIDE;
    239 
    240   // OnBoundsChanged.
    241   bool did_change_bounds_;
    242   gfx::Rect new_bounds_;
    243 
    244   // MouseEvent.
    245   int last_mouse_event_type_;
    246   gfx::Point location_;
    247   bool received_mouse_enter_;
    248   bool received_mouse_exit_;
    249   bool delete_on_pressed_;
    250 
    251   // Painting.
    252   std::vector<gfx::Rect> scheduled_paint_rects_;
    253 
    254   // Painting.
    255   SkRect last_clip_;
    256 
    257   // Accelerators.
    258   std::map<ui::Accelerator, int> accelerator_count_map_;
    259 
    260   // Native theme.
    261   const ui::NativeTheme* native_theme_;
    262 
    263   // Value to return from CanProcessEventsWithinSubtree().
    264   bool can_process_events_within_subtree_;
    265 };
    266 
    267 ////////////////////////////////////////////////////////////////////////////////
    268 // OnBoundsChanged
    269 ////////////////////////////////////////////////////////////////////////////////
    270 
    271 void TestView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
    272   did_change_bounds_ = true;
    273   new_bounds_ = bounds();
    274 }
    275 
    276 TEST_F(ViewTest, OnBoundsChanged) {
    277   TestView v;
    278 
    279   gfx::Rect prev_rect(0, 0, 200, 200);
    280   gfx::Rect new_rect(100, 100, 250, 250);
    281 
    282   v.SetBoundsRect(prev_rect);
    283   v.Reset();
    284   v.SetBoundsRect(new_rect);
    285 
    286   EXPECT_TRUE(v.did_change_bounds_);
    287   EXPECT_EQ(v.new_bounds_, new_rect);
    288   EXPECT_EQ(v.bounds(), new_rect);
    289 }
    290 
    291 ////////////////////////////////////////////////////////////////////////////////
    292 // MouseEvent
    293 ////////////////////////////////////////////////////////////////////////////////
    294 
    295 bool TestView::OnMousePressed(const ui::MouseEvent& event) {
    296   last_mouse_event_type_ = event.type();
    297   location_.SetPoint(event.x(), event.y());
    298   if (delete_on_pressed_)
    299     delete this;
    300   return true;
    301 }
    302 
    303 bool TestView::OnMouseDragged(const ui::MouseEvent& event) {
    304   last_mouse_event_type_ = event.type();
    305   location_.SetPoint(event.x(), event.y());
    306   return true;
    307 }
    308 
    309 void TestView::OnMouseReleased(const ui::MouseEvent& event) {
    310   last_mouse_event_type_ = event.type();
    311   location_.SetPoint(event.x(), event.y());
    312 }
    313 
    314 void TestView::OnMouseEntered(const ui::MouseEvent& event) {
    315   received_mouse_enter_ = true;
    316 }
    317 
    318 void TestView::OnMouseExited(const ui::MouseEvent& event) {
    319   received_mouse_exit_ = true;
    320 }
    321 
    322 TEST_F(ViewTest, MouseEvent) {
    323   TestView* v1 = new TestView();
    324   v1->SetBoundsRect(gfx::Rect(0, 0, 300, 300));
    325 
    326   TestView* v2 = new TestView();
    327   v2->SetBoundsRect(gfx::Rect(100, 100, 100, 100));
    328 
    329   scoped_ptr<Widget> widget(new Widget);
    330   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
    331   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
    332   params.bounds = gfx::Rect(50, 50, 650, 650);
    333   widget->Init(params);
    334   internal::RootView* root =
    335       static_cast<internal::RootView*>(widget->GetRootView());
    336 
    337   root->AddChildView(v1);
    338   v1->AddChildView(v2);
    339 
    340   v1->Reset();
    341   v2->Reset();
    342 
    343   gfx::Point p1(110, 120);
    344   ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED, p1, p1,
    345                          ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
    346   root->OnMousePressed(pressed);
    347   EXPECT_EQ(v2->last_mouse_event_type_, ui::ET_MOUSE_PRESSED);
    348   EXPECT_EQ(v2->location_.x(), 10);
    349   EXPECT_EQ(v2->location_.y(), 20);
    350   // Make sure v1 did not receive the event
    351   EXPECT_EQ(v1->last_mouse_event_type_, 0);
    352 
    353   // Drag event out of bounds. Should still go to v2
    354   v1->Reset();
    355   v2->Reset();
    356   gfx::Point p2(50, 40);
    357   ui::MouseEvent dragged(ui::ET_MOUSE_DRAGGED, p2, p2,
    358                          ui::EF_LEFT_MOUSE_BUTTON, 0);
    359   root->OnMouseDragged(dragged);
    360   EXPECT_EQ(v2->last_mouse_event_type_, ui::ET_MOUSE_DRAGGED);
    361   EXPECT_EQ(v2->location_.x(), -50);
    362   EXPECT_EQ(v2->location_.y(), -60);
    363   // Make sure v1 did not receive the event
    364   EXPECT_EQ(v1->last_mouse_event_type_, 0);
    365 
    366   // Releasted event out of bounds. Should still go to v2
    367   v1->Reset();
    368   v2->Reset();
    369   ui::MouseEvent released(ui::ET_MOUSE_RELEASED, gfx::Point(), gfx::Point(), 0,
    370                           0);
    371   root->OnMouseDragged(released);
    372   EXPECT_EQ(v2->last_mouse_event_type_, ui::ET_MOUSE_RELEASED);
    373   EXPECT_EQ(v2->location_.x(), -100);
    374   EXPECT_EQ(v2->location_.y(), -100);
    375   // Make sure v1 did not receive the event
    376   EXPECT_EQ(v1->last_mouse_event_type_, 0);
    377 
    378   widget->CloseNow();
    379 }
    380 
    381 // Confirm that a view can be deleted as part of processing a mouse press.
    382 TEST_F(ViewTest, DeleteOnPressed) {
    383   TestView* v1 = new TestView();
    384   v1->SetBoundsRect(gfx::Rect(0, 0, 300, 300));
    385 
    386   TestView* v2 = new TestView();
    387   v2->SetBoundsRect(gfx::Rect(100, 100, 100, 100));
    388 
    389   v1->Reset();
    390   v2->Reset();
    391 
    392   scoped_ptr<Widget> widget(new Widget);
    393   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
    394   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
    395   params.bounds = gfx::Rect(50, 50, 650, 650);
    396   widget->Init(params);
    397   View* root = widget->GetRootView();
    398 
    399   root->AddChildView(v1);
    400   v1->AddChildView(v2);
    401 
    402   v2->delete_on_pressed_ = true;
    403   gfx::Point point(110, 120);
    404   ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED, point, point,
    405                          ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
    406   root->OnMousePressed(pressed);
    407   EXPECT_EQ(0, v1->child_count());
    408 
    409   widget->CloseNow();
    410 }
    411 
    412 ////////////////////////////////////////////////////////////////////////////////
    413 // Painting
    414 ////////////////////////////////////////////////////////////////////////////////
    415 
    416 void TestView::Paint(gfx::Canvas* canvas, const CullSet& cull_set) {
    417   canvas->sk_canvas()->getClipBounds(&last_clip_);
    418 }
    419 
    420 void TestView::SchedulePaintInRect(const gfx::Rect& rect) {
    421   scheduled_paint_rects_.push_back(rect);
    422   View::SchedulePaintInRect(rect);
    423 }
    424 
    425 void CheckRect(const SkRect& check_rect, const SkRect& target_rect) {
    426   EXPECT_EQ(target_rect.fLeft, check_rect.fLeft);
    427   EXPECT_EQ(target_rect.fRight, check_rect.fRight);
    428   EXPECT_EQ(target_rect.fTop, check_rect.fTop);
    429   EXPECT_EQ(target_rect.fBottom, check_rect.fBottom);
    430 }
    431 
    432 TEST_F(ViewTest, RemoveNotification) {
    433   ViewStorage* vs = ViewStorage::GetInstance();
    434   Widget* widget = new Widget;
    435   widget->Init(CreateParams(Widget::InitParams::TYPE_POPUP));
    436   View* root_view = widget->GetRootView();
    437 
    438   View* v1 = new View;
    439   int s1 = vs->CreateStorageID();
    440   vs->StoreView(s1, v1);
    441   root_view->AddChildView(v1);
    442   View* v11 = new View;
    443   int s11 = vs->CreateStorageID();
    444   vs->StoreView(s11, v11);
    445   v1->AddChildView(v11);
    446   View* v111 = new View;
    447   int s111 = vs->CreateStorageID();
    448   vs->StoreView(s111, v111);
    449   v11->AddChildView(v111);
    450   View* v112 = new View;
    451   int s112 = vs->CreateStorageID();
    452   vs->StoreView(s112, v112);
    453   v11->AddChildView(v112);
    454   View* v113 = new View;
    455   int s113 = vs->CreateStorageID();
    456   vs->StoreView(s113, v113);
    457   v11->AddChildView(v113);
    458   View* v1131 = new View;
    459   int s1131 = vs->CreateStorageID();
    460   vs->StoreView(s1131, v1131);
    461   v113->AddChildView(v1131);
    462   View* v12 = new View;
    463   int s12 = vs->CreateStorageID();
    464   vs->StoreView(s12, v12);
    465   v1->AddChildView(v12);
    466 
    467   View* v2 = new View;
    468   int s2 = vs->CreateStorageID();
    469   vs->StoreView(s2, v2);
    470   root_view->AddChildView(v2);
    471   View* v21 = new View;
    472   int s21 = vs->CreateStorageID();
    473   vs->StoreView(s21, v21);
    474   v2->AddChildView(v21);
    475   View* v211 = new View;
    476   int s211 = vs->CreateStorageID();
    477   vs->StoreView(s211, v211);
    478   v21->AddChildView(v211);
    479 
    480   size_t stored_views = vs->view_count();
    481 
    482   // Try removing a leaf view.
    483   v21->RemoveChildView(v211);
    484   EXPECT_EQ(stored_views - 1, vs->view_count());
    485   EXPECT_EQ(NULL, vs->RetrieveView(s211));
    486   delete v211;  // We won't use this one anymore.
    487 
    488   // Now try removing a view with a hierarchy of depth 1.
    489   v11->RemoveChildView(v113);
    490   EXPECT_EQ(stored_views - 3, vs->view_count());
    491   EXPECT_EQ(NULL, vs->RetrieveView(s113));
    492   EXPECT_EQ(NULL, vs->RetrieveView(s1131));
    493   delete v113;  // We won't use this one anymore.
    494 
    495   // Now remove even more.
    496   root_view->RemoveChildView(v1);
    497   EXPECT_EQ(NULL, vs->RetrieveView(s1));
    498   EXPECT_EQ(NULL, vs->RetrieveView(s11));
    499   EXPECT_EQ(NULL, vs->RetrieveView(s12));
    500   EXPECT_EQ(NULL, vs->RetrieveView(s111));
    501   EXPECT_EQ(NULL, vs->RetrieveView(s112));
    502 
    503   // Put v1 back for more tests.
    504   root_view->AddChildView(v1);
    505   vs->StoreView(s1, v1);
    506 
    507   // Synchronously closing the window deletes the view hierarchy, which should
    508   // remove all its views from ViewStorage.
    509   widget->CloseNow();
    510   EXPECT_EQ(stored_views - 10, vs->view_count());
    511   EXPECT_EQ(NULL, vs->RetrieveView(s1));
    512   EXPECT_EQ(NULL, vs->RetrieveView(s12));
    513   EXPECT_EQ(NULL, vs->RetrieveView(s11));
    514   EXPECT_EQ(NULL, vs->RetrieveView(s12));
    515   EXPECT_EQ(NULL, vs->RetrieveView(s21));
    516   EXPECT_EQ(NULL, vs->RetrieveView(s111));
    517   EXPECT_EQ(NULL, vs->RetrieveView(s112));
    518 }
    519 
    520 namespace {
    521 
    522 void RotateCounterclockwise(gfx::Transform* transform) {
    523   transform->matrix().set3x3(0, -1, 0,
    524                              1,  0, 0,
    525                              0,  0, 1);
    526 }
    527 
    528 void RotateClockwise(gfx::Transform* transform) {
    529   transform->matrix().set3x3( 0, 1, 0,
    530                              -1, 0, 0,
    531                               0, 0, 1);
    532 }
    533 
    534 }  // namespace
    535 
    536 // Tests the correctness of the rect-based targeting algorithm implemented in
    537 // View::GetEventHandlerForRect(). See http://goo.gl/3Jp2BD for a description
    538 // of rect-based targeting.
    539 TEST_F(ViewTest, GetEventHandlerForRect) {
    540   Widget* widget = new Widget;
    541   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
    542   widget->Init(params);
    543   View* root_view = widget->GetRootView();
    544   root_view->SetBoundsRect(gfx::Rect(0, 0, 500, 500));
    545 
    546   // Have this hierarchy of views (the coordinates here are all in
    547   // the root view's coordinate space):
    548   // v1 (0, 0, 100, 100)
    549   // v2 (150, 0, 250, 100)
    550   // v3 (0, 200, 150, 100)
    551   //     v31 (10, 210, 80, 80)
    552   //     v32 (110, 210, 30, 80)
    553   // v4 (300, 200, 100, 100)
    554   //     v41 (310, 210, 80, 80)
    555   //         v411 (370, 275, 10, 5)
    556   // v5 (450, 197, 30, 36)
    557   //     v51 (450, 200, 30, 30)
    558 
    559   // The coordinates used for SetBounds are in parent coordinates.
    560 
    561   TestView* v1 = new TestView;
    562   v1->SetBounds(0, 0, 100, 100);
    563   root_view->AddChildView(v1);
    564 
    565   TestView* v2 = new TestView;
    566   v2->SetBounds(150, 0, 250, 100);
    567   root_view->AddChildView(v2);
    568 
    569   TestView* v3 = new TestView;
    570   v3->SetBounds(0, 200, 150, 100);
    571   root_view->AddChildView(v3);
    572 
    573   TestView* v4 = new TestView;
    574   v4->SetBounds(300, 200, 100, 100);
    575   root_view->AddChildView(v4);
    576 
    577   TestView* v31 = new TestView;
    578   v31->SetBounds(10, 10, 80, 80);
    579   v3->AddChildView(v31);
    580 
    581   TestView* v32 = new TestView;
    582   v32->SetBounds(110, 10, 30, 80);
    583   v3->AddChildView(v32);
    584 
    585   TestView* v41 = new TestView;
    586   v41->SetBounds(10, 10, 80, 80);
    587   v4->AddChildView(v41);
    588 
    589   TestView* v411 = new TestView;
    590   v411->SetBounds(60, 65, 10, 5);
    591   v41->AddChildView(v411);
    592 
    593   TestView* v5 = new TestView;
    594   v5->SetBounds(450, 197, 30, 36);
    595   root_view->AddChildView(v5);
    596 
    597   TestView* v51 = new TestView;
    598   v51->SetBounds(0, 3, 30, 30);
    599   v5->AddChildView(v51);
    600 
    601   // |touch_rect| does not intersect any descendant view of |root_view|.
    602   gfx::Rect touch_rect(105, 105, 30, 45);
    603   View* result_view = root_view->GetEventHandlerForRect(touch_rect);
    604   EXPECT_EQ(root_view, result_view);
    605   result_view = NULL;
    606 
    607   // Covers |v1| by at least 60%.
    608   touch_rect.SetRect(15, 15, 100, 100);
    609   result_view = root_view->GetEventHandlerForRect(touch_rect);
    610   EXPECT_EQ(v1, result_view);
    611   result_view = NULL;
    612 
    613   // Intersects |v1| but does not cover it by at least 60%. The center
    614   // of |touch_rect| is within |v1|.
    615   touch_rect.SetRect(50, 50, 5, 10);
    616   result_view = root_view->GetEventHandlerForRect(touch_rect);
    617   EXPECT_EQ(v1, result_view);
    618   result_view = NULL;
    619 
    620   // Intersects |v1| but does not cover it by at least 60%. The center
    621   // of |touch_rect| is not within |v1|.
    622   touch_rect.SetRect(95, 96, 21, 22);
    623   result_view = root_view->GetEventHandlerForRect(touch_rect);
    624   EXPECT_EQ(root_view, result_view);
    625   result_view = NULL;
    626 
    627   // Intersects |v1| and |v2|, but only covers |v2| by at least 60%.
    628   touch_rect.SetRect(95, 10, 300, 120);
    629   result_view = root_view->GetEventHandlerForRect(touch_rect);
    630   EXPECT_EQ(v2, result_view);
    631   result_view = NULL;
    632 
    633   // Covers both |v1| and |v2| by at least 60%, but the center point
    634   // of |touch_rect| is closer to the center point of |v2|.
    635   touch_rect.SetRect(20, 20, 400, 100);
    636   result_view = root_view->GetEventHandlerForRect(touch_rect);
    637   EXPECT_EQ(v2, result_view);
    638   result_view = NULL;
    639 
    640   // Covers both |v1| and |v2| by at least 60%, but the center point
    641   // of |touch_rect| is closer to the center point of |v1|.
    642   touch_rect.SetRect(-700, -15, 1050, 110);
    643   result_view = root_view->GetEventHandlerForRect(touch_rect);
    644   EXPECT_EQ(v1, result_view);
    645   result_view = NULL;
    646 
    647   // A mouse click within |v1| will target |v1|.
    648   touch_rect.SetRect(15, 15, 1, 1);
    649   result_view = root_view->GetEventHandlerForRect(touch_rect);
    650   EXPECT_EQ(v1, result_view);
    651   result_view = NULL;
    652 
    653   // Intersects |v3| and |v31| by at least 60% and the center point
    654   // of |touch_rect| is closer to the center point of |v31|.
    655   touch_rect.SetRect(0, 200, 110, 100);
    656   result_view = root_view->GetEventHandlerForRect(touch_rect);
    657   EXPECT_EQ(v31, result_view);
    658   result_view = NULL;
    659 
    660   // Intersects |v3| and |v31|, but neither by at least 60%. The
    661   // center point of |touch_rect| lies within |v31|.
    662   touch_rect.SetRect(80, 280, 15, 15);
    663   result_view = root_view->GetEventHandlerForRect(touch_rect);
    664   EXPECT_EQ(v31, result_view);
    665   result_view = NULL;
    666 
    667   // Covers |v3|, |v31|, and |v32| all by at least 60%, and the
    668   // center point of |touch_rect| is closest to the center point
    669   // of |v32|.
    670   touch_rect.SetRect(0, 200, 200, 100);
    671   result_view = root_view->GetEventHandlerForRect(touch_rect);
    672   EXPECT_EQ(v32, result_view);
    673   result_view = NULL;
    674 
    675   // Intersects all of |v3|, |v31|, and |v32|, but only covers
    676   // |v31| and |v32| by at least 60%. The center point of
    677   // |touch_rect| is closest to the center point of |v32|.
    678   touch_rect.SetRect(30, 225, 180, 115);
    679   result_view = root_view->GetEventHandlerForRect(touch_rect);
    680   EXPECT_EQ(v32, result_view);
    681   result_view = NULL;
    682 
    683   // A mouse click at the corner of |v3| will target |v3|.
    684   touch_rect.SetRect(0, 200, 1, 1);
    685   result_view = root_view->GetEventHandlerForRect(touch_rect);
    686   EXPECT_EQ(v3, result_view);
    687   result_view = NULL;
    688 
    689   // A mouse click within |v32| will target |v32|.
    690   touch_rect.SetRect(112, 211, 1, 1);
    691   result_view = root_view->GetEventHandlerForRect(touch_rect);
    692   EXPECT_EQ(v32, result_view);
    693   result_view = NULL;
    694 
    695   // Covers all of |v4|, |v41|, and |v411| by at least 60%.
    696   // The center point of |touch_rect| is equally close to
    697   // the center points of |v4| and |v41|.
    698   touch_rect.SetRect(310, 210, 80, 80);
    699   result_view = root_view->GetEventHandlerForRect(touch_rect);
    700   EXPECT_EQ(v41, result_view);
    701   result_view = NULL;
    702 
    703   // Intersects all of |v4|, |v41|, and |v411| but only covers
    704   // |v411| by at least 60%.
    705   touch_rect.SetRect(370, 275, 7, 5);
    706   result_view = root_view->GetEventHandlerForRect(touch_rect);
    707   EXPECT_EQ(v411, result_view);
    708   result_view = NULL;
    709 
    710   // Intersects |v4| and |v41| but covers neither by at least 60%.
    711   // The center point of |touch_rect| is equally close to the center
    712   // points of |v4| and |v41|.
    713   touch_rect.SetRect(345, 245, 7, 7);
    714   result_view = root_view->GetEventHandlerForRect(touch_rect);
    715   EXPECT_EQ(v41, result_view);
    716   result_view = NULL;
    717 
    718   // Intersects all of |v4|, |v41|, and |v411| and covers none of
    719   // them by at least 60%. The center point of |touch_rect| lies
    720   // within |v411|.
    721   touch_rect.SetRect(368, 272, 4, 6);
    722   result_view = root_view->GetEventHandlerForRect(touch_rect);
    723   EXPECT_EQ(v411, result_view);
    724   result_view = NULL;
    725 
    726   // Intersects all of |v4|, |v41|, and |v411| and covers none of
    727   // them by at least 60%. The center point of |touch_rect| lies
    728   // within |v41|.
    729   touch_rect.SetRect(365, 270, 7, 7);
    730   result_view = root_view->GetEventHandlerForRect(touch_rect);
    731   EXPECT_EQ(v41, result_view);
    732   result_view = NULL;
    733 
    734   // Intersects all of |v4|, |v41|, and |v411| and covers none of
    735   // them by at least 60%. The center point of |touch_rect| lies
    736   // within |v4|.
    737   touch_rect.SetRect(205, 275, 200, 2);
    738   result_view = root_view->GetEventHandlerForRect(touch_rect);
    739   EXPECT_EQ(v4, result_view);
    740   result_view = NULL;
    741 
    742   // Intersects all of |v4|, |v41|, and |v411| but only covers
    743   // |v41| by at least 60%.
    744   touch_rect.SetRect(310, 210, 61, 66);
    745   result_view = root_view->GetEventHandlerForRect(touch_rect);
    746   EXPECT_EQ(v41, result_view);
    747   result_view = NULL;
    748 
    749   // A mouse click within |v411| will target |v411|.
    750   touch_rect.SetRect(372, 275, 1, 1);
    751   result_view = root_view->GetEventHandlerForRect(touch_rect);
    752   EXPECT_EQ(v411, result_view);
    753   result_view = NULL;
    754 
    755   // A mouse click within |v41| will target |v41|.
    756   touch_rect.SetRect(350, 215, 1, 1);
    757   result_view = root_view->GetEventHandlerForRect(touch_rect);
    758   EXPECT_EQ(v41, result_view);
    759   result_view = NULL;
    760 
    761   // Covers |v3|, |v4|, and all of their descendants by at
    762   // least 60%. The center point of |touch_rect| is closest
    763   // to the center point of |v32|.
    764   touch_rect.SetRect(0, 200, 400, 100);
    765   result_view = root_view->GetEventHandlerForRect(touch_rect);
    766   EXPECT_EQ(v32, result_view);
    767   result_view = NULL;
    768 
    769   // Intersects all of |v2|, |v3|, |v32|, |v4|, |v41|, and |v411|.
    770   // Covers |v2|, |v32|, |v4|, |v41|, and |v411| by at least 60%.
    771   // The center point of |touch_rect| is closest to the center
    772   // point of |root_view|.
    773   touch_rect.SetRect(110, 15, 375, 450);
    774   result_view = root_view->GetEventHandlerForRect(touch_rect);
    775   EXPECT_EQ(root_view, result_view);
    776   result_view = NULL;
    777 
    778   // Covers all views (except |v5| and |v51|) by at least 60%. The
    779   // center point of |touch_rect| is equally close to the center
    780   // points of |v2| and |v32|. One is not a descendant of the other,
    781   // so in this case the view selected is arbitrary (i.e.,
    782   // it depends only on the ordering of nodes in the views
    783   // hierarchy).
    784   touch_rect.SetRect(0, 0, 400, 300);
    785   result_view = root_view->GetEventHandlerForRect(touch_rect);
    786   EXPECT_EQ(v32, result_view);
    787   result_view = NULL;
    788 
    789   // Covers |v5| and |v51| by at least 60%, and the center point of
    790   // the touch is located within both views. Since both views share
    791   // the same center point, the child view should be selected.
    792   touch_rect.SetRect(440, 190, 40, 40);
    793   result_view = root_view->GetEventHandlerForRect(touch_rect);
    794   EXPECT_EQ(v51, result_view);
    795   result_view = NULL;
    796 
    797   // Covers |v5| and |v51| by at least 60%, but the center point of
    798   // the touch is not located within either view. Since both views
    799   // share the same center point, the child view should be selected.
    800   touch_rect.SetRect(455, 187, 60, 60);
    801   result_view = root_view->GetEventHandlerForRect(touch_rect);
    802   EXPECT_EQ(v51, result_view);
    803   result_view = NULL;
    804 
    805   // Covers neither |v5| nor |v51| by at least 60%, but the center
    806   // of the touch is located within |v51|.
    807   touch_rect.SetRect(450, 197, 10, 10);
    808   result_view = root_view->GetEventHandlerForRect(touch_rect);
    809   EXPECT_EQ(v51, result_view);
    810   result_view = NULL;
    811 
    812   // Covers neither |v5| nor |v51| by at least 60% but intersects both.
    813   // The center point is located outside of both views.
    814   touch_rect.SetRect(433, 180, 24, 24);
    815   result_view = root_view->GetEventHandlerForRect(touch_rect);
    816   EXPECT_EQ(root_view, result_view);
    817   result_view = NULL;
    818 
    819   // Only intersects |v5| but does not cover it by at least 60%. The
    820   // center point of the touch region is located within |v5|.
    821   touch_rect.SetRect(449, 196, 3, 3);
    822   result_view = root_view->GetEventHandlerForRect(touch_rect);
    823   EXPECT_EQ(v5, result_view);
    824   result_view = NULL;
    825 
    826   // A mouse click within |v5| (but not |v51|) should target |v5|.
    827   touch_rect.SetRect(462, 199, 1, 1);
    828   result_view = root_view->GetEventHandlerForRect(touch_rect);
    829   EXPECT_EQ(v5, result_view);
    830   result_view = NULL;
    831 
    832   // A mouse click |v5| and |v51| should target the child view.
    833   touch_rect.SetRect(452, 226, 1, 1);
    834   result_view = root_view->GetEventHandlerForRect(touch_rect);
    835   EXPECT_EQ(v51, result_view);
    836   result_view = NULL;
    837 
    838   // A mouse click on the center of |v5| and |v51| should target
    839   // the child view.
    840   touch_rect.SetRect(465, 215, 1, 1);
    841   result_view = root_view->GetEventHandlerForRect(touch_rect);
    842   EXPECT_EQ(v51, result_view);
    843   result_view = NULL;
    844 
    845   widget->CloseNow();
    846 }
    847 
    848 // Tests that GetEventHandlerForRect() and GetTooltipHandlerForPoint() behave
    849 // as expected when different views in the view hierarchy return false
    850 // when CanProcessEventsWithinSubtree() is called.
    851 TEST_F(ViewTest, CanProcessEventsWithinSubtree) {
    852   Widget* widget = new Widget;
    853   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
    854   widget->Init(params);
    855   View* root_view = widget->GetRootView();
    856   root_view->SetBoundsRect(gfx::Rect(0, 0, 500, 500));
    857 
    858   // Have this hierarchy of views (the coords here are in the coordinate
    859   // space of the root view):
    860   // v (0, 0, 100, 100)
    861   //  - v_child (0, 0, 20, 30)
    862   //    - v_grandchild (5, 5, 5, 15)
    863 
    864   TestView* v = new TestView;
    865   v->SetBounds(0, 0, 100, 100);
    866   root_view->AddChildView(v);
    867   v->set_notify_enter_exit_on_child(true);
    868 
    869   TestView* v_child = new TestView;
    870   v_child->SetBounds(0, 0, 20, 30);
    871   v->AddChildView(v_child);
    872 
    873   TestView* v_grandchild = new TestView;
    874   v_grandchild->SetBounds(5, 5, 5, 15);
    875   v_child->AddChildView(v_grandchild);
    876 
    877   v->Reset();
    878   v_child->Reset();
    879   v_grandchild->Reset();
    880 
    881   // Define rects and points within the views in the hierarchy.
    882   gfx::Rect rect_in_v_grandchild(7, 7, 3, 3);
    883   gfx::Point point_in_v_grandchild(rect_in_v_grandchild.origin());
    884   gfx::Rect rect_in_v_child(12, 3, 5, 5);
    885   gfx::Point point_in_v_child(rect_in_v_child.origin());
    886   gfx::Rect rect_in_v(50, 50, 25, 30);
    887   gfx::Point point_in_v(rect_in_v.origin());
    888 
    889   // When all three views return true when CanProcessEventsWithinSubtree()
    890   // is called, targeting should behave as expected.
    891 
    892   View* result_view = root_view->GetEventHandlerForRect(rect_in_v_grandchild);
    893   EXPECT_EQ(v_grandchild, result_view);
    894   result_view = NULL;
    895   result_view = root_view->GetTooltipHandlerForPoint(point_in_v_grandchild);
    896   EXPECT_EQ(v_grandchild, result_view);
    897   result_view = NULL;
    898 
    899   result_view = root_view->GetEventHandlerForRect(rect_in_v_child);
    900   EXPECT_EQ(v_child, result_view);
    901   result_view = NULL;
    902   result_view = root_view->GetTooltipHandlerForPoint(point_in_v_child);
    903   EXPECT_EQ(v_child, result_view);
    904   result_view = NULL;
    905 
    906   result_view = root_view->GetEventHandlerForRect(rect_in_v);
    907   EXPECT_EQ(v, result_view);
    908   result_view = NULL;
    909   result_view = root_view->GetTooltipHandlerForPoint(point_in_v);
    910   EXPECT_EQ(v, result_view);
    911   result_view = NULL;
    912 
    913   // When |v_grandchild| returns false when CanProcessEventsWithinSubtree()
    914   // is called, then |v_grandchild| cannot be returned as a target.
    915 
    916   v_grandchild->set_can_process_events_within_subtree(false);
    917 
    918   result_view = root_view->GetEventHandlerForRect(rect_in_v_grandchild);
    919   EXPECT_EQ(v_child, result_view);
    920   result_view = NULL;
    921   result_view = root_view->GetTooltipHandlerForPoint(point_in_v_grandchild);
    922   EXPECT_EQ(v_child, result_view);
    923   result_view = NULL;
    924 
    925   result_view = root_view->GetEventHandlerForRect(rect_in_v_child);
    926   EXPECT_EQ(v_child, result_view);
    927   result_view = NULL;
    928   result_view = root_view->GetTooltipHandlerForPoint(point_in_v_child);
    929   EXPECT_EQ(v_child, result_view);
    930   result_view = NULL;
    931 
    932   result_view = root_view->GetEventHandlerForRect(rect_in_v);
    933   EXPECT_EQ(v, result_view);
    934   result_view = NULL;
    935   result_view = root_view->GetTooltipHandlerForPoint(point_in_v);
    936   EXPECT_EQ(v, result_view);
    937 
    938   // When |v_grandchild| returns false when CanProcessEventsWithinSubtree()
    939   // is called, then NULL should be returned as a target if we call
    940   // GetTooltipHandlerForPoint() with |v_grandchild| as the root of the
    941   // views tree. Note that the location must be in the coordinate space
    942   // of the root view (|v_grandchild| in this case), so use (1, 1).
    943 
    944   result_view = v_grandchild;
    945   result_view = v_grandchild->GetTooltipHandlerForPoint(gfx::Point(1, 1));
    946   EXPECT_EQ(NULL, result_view);
    947   result_view = NULL;
    948 
    949   // When |v_child| returns false when CanProcessEventsWithinSubtree()
    950   // is called, then neither |v_child| nor |v_grandchild| can be returned
    951   // as a target (|v| should be returned as the target for each case).
    952 
    953   v_grandchild->Reset();
    954   v_child->set_can_process_events_within_subtree(false);
    955 
    956   result_view = root_view->GetEventHandlerForRect(rect_in_v_grandchild);
    957   EXPECT_EQ(v, result_view);
    958   result_view = NULL;
    959   result_view = root_view->GetTooltipHandlerForPoint(point_in_v_grandchild);
    960   EXPECT_EQ(v, result_view);
    961   result_view = NULL;
    962 
    963   result_view = root_view->GetEventHandlerForRect(rect_in_v_child);
    964   EXPECT_EQ(v, result_view);
    965   result_view = NULL;
    966   result_view = root_view->GetTooltipHandlerForPoint(point_in_v_child);
    967   EXPECT_EQ(v, result_view);
    968   result_view = NULL;
    969 
    970   result_view = root_view->GetEventHandlerForRect(rect_in_v);
    971   EXPECT_EQ(v, result_view);
    972   result_view = NULL;
    973   result_view = root_view->GetTooltipHandlerForPoint(point_in_v);
    974   EXPECT_EQ(v, result_view);
    975   result_view = NULL;
    976 
    977   // When |v| returns false when CanProcessEventsWithinSubtree()
    978   // is called, then none of |v|, |v_child|, and |v_grandchild| can be returned
    979   // as a target (|root_view| should be returned as the target for each case).
    980 
    981   v_child->Reset();
    982   v->set_can_process_events_within_subtree(false);
    983 
    984   result_view = root_view->GetEventHandlerForRect(rect_in_v_grandchild);
    985   EXPECT_EQ(root_view, result_view);
    986   result_view = NULL;
    987   result_view = root_view->GetTooltipHandlerForPoint(point_in_v_grandchild);
    988   EXPECT_EQ(root_view, result_view);
    989   result_view = NULL;
    990 
    991   result_view = root_view->GetEventHandlerForRect(rect_in_v_child);
    992   EXPECT_EQ(root_view, result_view);
    993   result_view = NULL;
    994   result_view = root_view->GetTooltipHandlerForPoint(point_in_v_child);
    995   EXPECT_EQ(root_view, result_view);
    996   result_view = NULL;
    997 
    998   result_view = root_view->GetEventHandlerForRect(rect_in_v);
    999   EXPECT_EQ(root_view, result_view);
   1000   result_view = NULL;
   1001   result_view = root_view->GetTooltipHandlerForPoint(point_in_v);
   1002   EXPECT_EQ(root_view, result_view);
   1003 }
   1004 
   1005 TEST_F(ViewTest, NotifyEnterExitOnChild) {
   1006   Widget* widget = new Widget;
   1007   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
   1008   widget->Init(params);
   1009   View* root_view = widget->GetRootView();
   1010   root_view->SetBoundsRect(gfx::Rect(0, 0, 500, 500));
   1011 
   1012   // Have this hierarchy of views (the coords here are in root coord):
   1013   // v1 (0, 0, 100, 100)
   1014   //  - v11 (0, 0, 20, 30)
   1015   //    - v111 (5, 5, 5, 15)
   1016   //  - v12 (50, 10, 30, 90)
   1017   //    - v121 (60, 20, 10, 10)
   1018   // v2 (105, 0, 100, 100)
   1019   //  - v21 (120, 10, 50, 20)
   1020 
   1021   TestView* v1 = new TestView;
   1022   v1->SetBounds(0, 0, 100, 100);
   1023   root_view->AddChildView(v1);
   1024   v1->set_notify_enter_exit_on_child(true);
   1025 
   1026   TestView* v11 = new TestView;
   1027   v11->SetBounds(0, 0, 20, 30);
   1028   v1->AddChildView(v11);
   1029 
   1030   TestView* v111 = new TestView;
   1031   v111->SetBounds(5, 5, 5, 15);
   1032   v11->AddChildView(v111);
   1033 
   1034   TestView* v12 = new TestView;
   1035   v12->SetBounds(50, 10, 30, 90);
   1036   v1->AddChildView(v12);
   1037 
   1038   TestView* v121 = new TestView;
   1039   v121->SetBounds(10, 10, 10, 10);
   1040   v12->AddChildView(v121);
   1041 
   1042   TestView* v2 = new TestView;
   1043   v2->SetBounds(105, 0, 100, 100);
   1044   root_view->AddChildView(v2);
   1045 
   1046   TestView* v21 = new TestView;
   1047   v21->SetBounds(15, 10, 50, 20);
   1048   v2->AddChildView(v21);
   1049 
   1050   v1->Reset();
   1051   v11->Reset();
   1052   v111->Reset();
   1053   v12->Reset();
   1054   v121->Reset();
   1055   v2->Reset();
   1056   v21->Reset();
   1057 
   1058   // Move the mouse in v111.
   1059   gfx::Point p1(6, 6);
   1060   ui::MouseEvent move1(ui::ET_MOUSE_MOVED, p1, p1, 0, 0);
   1061   root_view->OnMouseMoved(move1);
   1062   EXPECT_TRUE(v111->received_mouse_enter_);
   1063   EXPECT_FALSE(v11->last_mouse_event_type_);
   1064   EXPECT_TRUE(v1->received_mouse_enter_);
   1065 
   1066   v111->Reset();
   1067   v1->Reset();
   1068 
   1069   // Now, move into v121.
   1070   gfx::Point p2(65, 21);
   1071   ui::MouseEvent move2(ui::ET_MOUSE_MOVED, p2, p2, 0, 0);
   1072   root_view->OnMouseMoved(move2);
   1073   EXPECT_TRUE(v111->received_mouse_exit_);
   1074   EXPECT_TRUE(v121->received_mouse_enter_);
   1075   EXPECT_FALSE(v1->last_mouse_event_type_);
   1076 
   1077   v111->Reset();
   1078   v121->Reset();
   1079 
   1080   // Now, move into v11.
   1081   gfx::Point p3(1, 1);
   1082   ui::MouseEvent move3(ui::ET_MOUSE_MOVED, p3, p3, 0, 0);
   1083   root_view->OnMouseMoved(move3);
   1084   EXPECT_TRUE(v121->received_mouse_exit_);
   1085   EXPECT_TRUE(v11->received_mouse_enter_);
   1086   EXPECT_FALSE(v1->last_mouse_event_type_);
   1087 
   1088   v121->Reset();
   1089   v11->Reset();
   1090 
   1091   // Move to v21.
   1092   gfx::Point p4(121, 15);
   1093   ui::MouseEvent move4(ui::ET_MOUSE_MOVED, p4, p4, 0, 0);
   1094   root_view->OnMouseMoved(move4);
   1095   EXPECT_TRUE(v21->received_mouse_enter_);
   1096   EXPECT_FALSE(v2->last_mouse_event_type_);
   1097   EXPECT_TRUE(v11->received_mouse_exit_);
   1098   EXPECT_TRUE(v1->received_mouse_exit_);
   1099 
   1100   v21->Reset();
   1101   v11->Reset();
   1102   v1->Reset();
   1103 
   1104   // Move to v1.
   1105   gfx::Point p5(21, 0);
   1106   ui::MouseEvent move5(ui::ET_MOUSE_MOVED, p5, p5, 0, 0);
   1107   root_view->OnMouseMoved(move5);
   1108   EXPECT_TRUE(v21->received_mouse_exit_);
   1109   EXPECT_TRUE(v1->received_mouse_enter_);
   1110 
   1111   v21->Reset();
   1112   v1->Reset();
   1113 
   1114   // Now, move into v11.
   1115   gfx::Point p6(15, 15);
   1116   ui::MouseEvent mouse6(ui::ET_MOUSE_MOVED, p6, p6, 0, 0);
   1117   root_view->OnMouseMoved(mouse6);
   1118   EXPECT_TRUE(v11->received_mouse_enter_);
   1119   EXPECT_FALSE(v1->last_mouse_event_type_);
   1120 
   1121   v11->Reset();
   1122   v1->Reset();
   1123 
   1124   // Move back into v1. Although |v1| had already received an ENTER for mouse6,
   1125   // and the mouse remains inside |v1| the whole time, it receives another ENTER
   1126   // when the mouse leaves v11.
   1127   gfx::Point p7(21, 0);
   1128   ui::MouseEvent mouse7(ui::ET_MOUSE_MOVED, p7, p7, 0, 0);
   1129   root_view->OnMouseMoved(mouse7);
   1130   EXPECT_TRUE(v11->received_mouse_exit_);
   1131   EXPECT_FALSE(v1->received_mouse_enter_);
   1132 
   1133   widget->CloseNow();
   1134 }
   1135 
   1136 TEST_F(ViewTest, Textfield) {
   1137   const base::string16 kText = ASCIIToUTF16(
   1138       "Reality is that which, when you stop believing it, doesn't go away.");
   1139   const base::string16 kExtraText = ASCIIToUTF16("Pretty deep, Philip!");
   1140 
   1141   Widget* widget = new Widget;
   1142   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
   1143   params.bounds = gfx::Rect(0, 0, 100, 100);
   1144   widget->Init(params);
   1145   View* root_view = widget->GetRootView();
   1146 
   1147   Textfield* textfield = new Textfield();
   1148   root_view->AddChildView(textfield);
   1149 
   1150   // Test setting, appending text.
   1151   textfield->SetText(kText);
   1152   EXPECT_EQ(kText, textfield->text());
   1153   textfield->AppendText(kExtraText);
   1154   EXPECT_EQ(kText + kExtraText, textfield->text());
   1155   textfield->SetText(base::string16());
   1156   EXPECT_TRUE(textfield->text().empty());
   1157 
   1158   // Test selection related methods.
   1159   textfield->SetText(kText);
   1160   EXPECT_TRUE(textfield->GetSelectedText().empty());
   1161   textfield->SelectAll(false);
   1162   EXPECT_EQ(kText, textfield->text());
   1163   textfield->ClearSelection();
   1164   EXPECT_TRUE(textfield->GetSelectedText().empty());
   1165 
   1166   widget->CloseNow();
   1167 }
   1168 
   1169 // Tests that the Textfield view respond appropiately to cut/copy/paste.
   1170 TEST_F(ViewTest, TextfieldCutCopyPaste) {
   1171   const base::string16 kNormalText = ASCIIToUTF16("Normal");
   1172   const base::string16 kReadOnlyText = ASCIIToUTF16("Read only");
   1173   const base::string16 kPasswordText =
   1174       ASCIIToUTF16("Password! ** Secret stuff **");
   1175 
   1176   ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
   1177 
   1178   Widget* widget = new Widget;
   1179   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
   1180   params.bounds = gfx::Rect(0, 0, 100, 100);
   1181   widget->Init(params);
   1182   View* root_view = widget->GetRootView();
   1183 
   1184   Textfield* normal = new Textfield();
   1185   Textfield* read_only = new Textfield();
   1186   read_only->SetReadOnly(true);
   1187   Textfield* password = new Textfield();
   1188   password->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD);
   1189 
   1190   root_view->AddChildView(normal);
   1191   root_view->AddChildView(read_only);
   1192   root_view->AddChildView(password);
   1193 
   1194   normal->SetText(kNormalText);
   1195   read_only->SetText(kReadOnlyText);
   1196   password->SetText(kPasswordText);
   1197 
   1198   //
   1199   // Test cut.
   1200   //
   1201 
   1202   normal->SelectAll(false);
   1203   normal->ExecuteCommand(IDS_APP_CUT);
   1204   base::string16 result;
   1205   clipboard->ReadText(ui::CLIPBOARD_TYPE_COPY_PASTE, &result);
   1206   EXPECT_EQ(kNormalText, result);
   1207   normal->SetText(kNormalText);  // Let's revert to the original content.
   1208 
   1209   read_only->SelectAll(false);
   1210   read_only->ExecuteCommand(IDS_APP_CUT);
   1211   result.clear();
   1212   clipboard->ReadText(ui::CLIPBOARD_TYPE_COPY_PASTE, &result);
   1213   // Cut should have failed, so the clipboard content should not have changed.
   1214   EXPECT_EQ(kNormalText, result);
   1215 
   1216   password->SelectAll(false);
   1217   password->ExecuteCommand(IDS_APP_CUT);
   1218   result.clear();
   1219   clipboard->ReadText(ui::CLIPBOARD_TYPE_COPY_PASTE, &result);
   1220   // Cut should have failed, so the clipboard content should not have changed.
   1221   EXPECT_EQ(kNormalText, result);
   1222 
   1223   //
   1224   // Test copy.
   1225   //
   1226 
   1227   // Start with |read_only| to observe a change in clipboard text.
   1228   read_only->SelectAll(false);
   1229   read_only->ExecuteCommand(IDS_APP_COPY);
   1230   result.clear();
   1231   clipboard->ReadText(ui::CLIPBOARD_TYPE_COPY_PASTE, &result);
   1232   EXPECT_EQ(kReadOnlyText, result);
   1233 
   1234   normal->SelectAll(false);
   1235   normal->ExecuteCommand(IDS_APP_COPY);
   1236   result.clear();
   1237   clipboard->ReadText(ui::CLIPBOARD_TYPE_COPY_PASTE, &result);
   1238   EXPECT_EQ(kNormalText, result);
   1239 
   1240   password->SelectAll(false);
   1241   password->ExecuteCommand(IDS_APP_COPY);
   1242   result.clear();
   1243   clipboard->ReadText(ui::CLIPBOARD_TYPE_COPY_PASTE, &result);
   1244   // Text cannot be copied from an obscured field; the clipboard won't change.
   1245   EXPECT_EQ(kNormalText, result);
   1246 
   1247   //
   1248   // Test paste.
   1249   //
   1250 
   1251   // Attempting to paste kNormalText in a read-only text-field should fail.
   1252   read_only->SelectAll(false);
   1253   read_only->ExecuteCommand(IDS_APP_PASTE);
   1254   EXPECT_EQ(kReadOnlyText, read_only->text());
   1255 
   1256   password->SelectAll(false);
   1257   password->ExecuteCommand(IDS_APP_PASTE);
   1258   EXPECT_EQ(kNormalText, password->text());
   1259 
   1260   // Copy from |read_only| to observe a change in the normal textfield text.
   1261   read_only->SelectAll(false);
   1262   read_only->ExecuteCommand(IDS_APP_COPY);
   1263   normal->SelectAll(false);
   1264   normal->ExecuteCommand(IDS_APP_PASTE);
   1265   EXPECT_EQ(kReadOnlyText, normal->text());
   1266   widget->CloseNow();
   1267 }
   1268 
   1269 ////////////////////////////////////////////////////////////////////////////////
   1270 // Accelerators
   1271 ////////////////////////////////////////////////////////////////////////////////
   1272 bool TestView::AcceleratorPressed(const ui::Accelerator& accelerator) {
   1273   accelerator_count_map_[accelerator]++;
   1274   return true;
   1275 }
   1276 
   1277 // TODO: these tests were initially commented out when getting aura to
   1278 // run. Figure out if still valuable and either nuke or fix.
   1279 #if 0
   1280 TEST_F(ViewTest, ActivateAccelerator) {
   1281   // Register a keyboard accelerator before the view is added to a window.
   1282   ui::Accelerator return_accelerator(ui::VKEY_RETURN, ui::EF_NONE);
   1283   TestView* view = new TestView();
   1284   view->Reset();
   1285   view->AddAccelerator(return_accelerator);
   1286   EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 0);
   1287 
   1288   // Create a window and add the view as its child.
   1289   scoped_ptr<Widget> widget(new Widget);
   1290   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
   1291   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
   1292   params.bounds = gfx::Rect(0, 0, 100, 100);
   1293   widget->Init(params);
   1294   View* root = widget->GetRootView();
   1295   root->AddChildView(view);
   1296   widget->Show();
   1297 
   1298   // Get the focus manager.
   1299   FocusManager* focus_manager = widget->GetFocusManager();
   1300   ASSERT_TRUE(focus_manager);
   1301 
   1302   // Hit the return key and see if it takes effect.
   1303   EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
   1304   EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 1);
   1305 
   1306   // Hit the escape key. Nothing should happen.
   1307   ui::Accelerator escape_accelerator(ui::VKEY_ESCAPE, ui::EF_NONE);
   1308   EXPECT_FALSE(focus_manager->ProcessAccelerator(escape_accelerator));
   1309   EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 1);
   1310   EXPECT_EQ(view->accelerator_count_map_[escape_accelerator], 0);
   1311 
   1312   // Now register the escape key and hit it again.
   1313   view->AddAccelerator(escape_accelerator);
   1314   EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator));
   1315   EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 1);
   1316   EXPECT_EQ(view->accelerator_count_map_[escape_accelerator], 1);
   1317 
   1318   // Remove the return key accelerator.
   1319   view->RemoveAccelerator(return_accelerator);
   1320   EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator));
   1321   EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 1);
   1322   EXPECT_EQ(view->accelerator_count_map_[escape_accelerator], 1);
   1323 
   1324   // Add it again. Hit the return key and the escape key.
   1325   view->AddAccelerator(return_accelerator);
   1326   EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
   1327   EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 2);
   1328   EXPECT_EQ(view->accelerator_count_map_[escape_accelerator], 1);
   1329   EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator));
   1330   EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 2);
   1331   EXPECT_EQ(view->accelerator_count_map_[escape_accelerator], 2);
   1332 
   1333   // Remove all the accelerators.
   1334   view->ResetAccelerators();
   1335   EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator));
   1336   EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 2);
   1337   EXPECT_EQ(view->accelerator_count_map_[escape_accelerator], 2);
   1338   EXPECT_FALSE(focus_manager->ProcessAccelerator(escape_accelerator));
   1339   EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 2);
   1340   EXPECT_EQ(view->accelerator_count_map_[escape_accelerator], 2);
   1341 
   1342   widget->CloseNow();
   1343 }
   1344 
   1345 TEST_F(ViewTest, HiddenViewWithAccelerator) {
   1346   ui::Accelerator return_accelerator(ui::VKEY_RETURN, ui::EF_NONE);
   1347   TestView* view = new TestView();
   1348   view->Reset();
   1349   view->AddAccelerator(return_accelerator);
   1350   EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 0);
   1351 
   1352   scoped_ptr<Widget> widget(new Widget);
   1353   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
   1354   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
   1355   params.bounds = gfx::Rect(0, 0, 100, 100);
   1356   widget->Init(params);
   1357   View* root = widget->GetRootView();
   1358   root->AddChildView(view);
   1359   widget->Show();
   1360 
   1361   FocusManager* focus_manager = widget->GetFocusManager();
   1362   ASSERT_TRUE(focus_manager);
   1363 
   1364   view->SetVisible(false);
   1365   EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator));
   1366 
   1367   view->SetVisible(true);
   1368   EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
   1369 
   1370   widget->CloseNow();
   1371 }
   1372 
   1373 TEST_F(ViewTest, ViewInHiddenWidgetWithAccelerator) {
   1374   ui::Accelerator return_accelerator(ui::VKEY_RETURN, ui::EF_NONE);
   1375   TestView* view = new TestView();
   1376   view->Reset();
   1377   view->AddAccelerator(return_accelerator);
   1378   EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 0);
   1379 
   1380   scoped_ptr<Widget> widget(new Widget);
   1381   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
   1382   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
   1383   params.bounds = gfx::Rect(0, 0, 100, 100);
   1384   widget->Init(params);
   1385   View* root = widget->GetRootView();
   1386   root->AddChildView(view);
   1387 
   1388   FocusManager* focus_manager = widget->GetFocusManager();
   1389   ASSERT_TRUE(focus_manager);
   1390 
   1391   EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator));
   1392   EXPECT_EQ(0, view->accelerator_count_map_[return_accelerator]);
   1393 
   1394   widget->Show();
   1395   EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
   1396   EXPECT_EQ(1, view->accelerator_count_map_[return_accelerator]);
   1397 
   1398   widget->Hide();
   1399   EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator));
   1400   EXPECT_EQ(1, view->accelerator_count_map_[return_accelerator]);
   1401 
   1402   widget->CloseNow();
   1403 }
   1404 
   1405 ////////////////////////////////////////////////////////////////////////////////
   1406 // Mouse-wheel message rerouting
   1407 ////////////////////////////////////////////////////////////////////////////////
   1408 class ScrollableTestView : public View {
   1409  public:
   1410   ScrollableTestView() { }
   1411 
   1412   virtual gfx::Size GetPreferredSize() {
   1413     return gfx::Size(100, 10000);
   1414   }
   1415 
   1416   virtual void Layout() {
   1417     SizeToPreferredSize();
   1418   }
   1419 };
   1420 
   1421 class TestViewWithControls : public View {
   1422  public:
   1423   TestViewWithControls() {
   1424     text_field_ = new Textfield();
   1425     AddChildView(text_field_);
   1426   }
   1427 
   1428   Textfield* text_field_;
   1429 };
   1430 
   1431 class SimpleWidgetDelegate : public WidgetDelegate {
   1432  public:
   1433   explicit SimpleWidgetDelegate(View* contents) : contents_(contents) {  }
   1434 
   1435   virtual void DeleteDelegate() { delete this; }
   1436 
   1437   virtual View* GetContentsView() { return contents_; }
   1438 
   1439   virtual Widget* GetWidget() { return contents_->GetWidget(); }
   1440   virtual const Widget* GetWidget() const { return contents_->GetWidget(); }
   1441 
   1442  private:
   1443   View* contents_;
   1444 };
   1445 
   1446 // Tests that the mouse-wheel messages are correctly rerouted to the window
   1447 // under the mouse.
   1448 // TODO(jcampan): http://crbug.com/10572 Disabled as it fails on the Vista build
   1449 //                bot.
   1450 // Note that this fails for a variety of reasons:
   1451 // - focused view is apparently reset across window activations and never
   1452 //   properly restored
   1453 // - this test depends on you not having any other window visible open under the
   1454 //   area that it opens the test windows. --beng
   1455 TEST_F(ViewTest, DISABLED_RerouteMouseWheelTest) {
   1456   TestViewWithControls* view_with_controls = new TestViewWithControls();
   1457   Widget* window1 = Widget::CreateWindowWithBounds(
   1458       new SimpleWidgetDelegate(view_with_controls),
   1459       gfx::Rect(0, 0, 100, 100));
   1460   window1->Show();
   1461   ScrollView* scroll_view = new ScrollView();
   1462   scroll_view->SetContents(new ScrollableTestView());
   1463   Widget* window2 = Widget::CreateWindowWithBounds(
   1464       new SimpleWidgetDelegate(scroll_view),
   1465       gfx::Rect(200, 200, 100, 100));
   1466   window2->Show();
   1467   EXPECT_EQ(0, scroll_view->GetVisibleRect().y());
   1468 
   1469   // Make the window1 active, as this is what it would be in real-world.
   1470   window1->Activate();
   1471 
   1472   // Let's send a mouse-wheel message to the different controls and check that
   1473   // it is rerouted to the window under the mouse (effectively scrolling the
   1474   // scroll-view).
   1475 
   1476   // First to the Window's HWND.
   1477   ::SendMessage(view_with_controls->GetWidget()->GetNativeView(),
   1478                 WM_MOUSEWHEEL, MAKEWPARAM(0, -20), MAKELPARAM(250, 250));
   1479   EXPECT_EQ(20, scroll_view->GetVisibleRect().y());
   1480 
   1481   window1->CloseNow();
   1482   window2->CloseNow();
   1483 }
   1484 #endif  // 0
   1485 
   1486 ////////////////////////////////////////////////////////////////////////////////
   1487 // Native view hierachy
   1488 ////////////////////////////////////////////////////////////////////////////////
   1489 class ToplevelWidgetObserverView : public View {
   1490  public:
   1491   ToplevelWidgetObserverView() : toplevel_(NULL) {
   1492   }
   1493   virtual ~ToplevelWidgetObserverView() {
   1494   }
   1495 
   1496   // View overrides:
   1497   virtual void ViewHierarchyChanged(
   1498       const ViewHierarchyChangedDetails& details) OVERRIDE {
   1499     if (details.is_add) {
   1500       toplevel_ = GetWidget() ? GetWidget()->GetTopLevelWidget() : NULL;
   1501     } else {
   1502       toplevel_ = NULL;
   1503     }
   1504   }
   1505   virtual void NativeViewHierarchyChanged() OVERRIDE {
   1506     toplevel_ = GetWidget() ? GetWidget()->GetTopLevelWidget() : NULL;
   1507   }
   1508 
   1509   Widget* toplevel() { return toplevel_; }
   1510 
   1511  private:
   1512   Widget* toplevel_;
   1513 
   1514   DISALLOW_COPY_AND_ASSIGN(ToplevelWidgetObserverView);
   1515 };
   1516 
   1517 // Test that a view can track the current top level widget by overriding
   1518 // View::ViewHierarchyChanged() and View::NativeViewHierarchyChanged().
   1519 TEST_F(ViewTest, NativeViewHierarchyChanged) {
   1520   scoped_ptr<Widget> toplevel1(new Widget);
   1521   Widget::InitParams toplevel1_params =
   1522       CreateParams(Widget::InitParams::TYPE_POPUP);
   1523   toplevel1_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
   1524   toplevel1->Init(toplevel1_params);
   1525 
   1526   scoped_ptr<Widget> toplevel2(new Widget);
   1527   Widget::InitParams toplevel2_params =
   1528       CreateParams(Widget::InitParams::TYPE_POPUP);
   1529   toplevel2_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
   1530   toplevel2->Init(toplevel2_params);
   1531 
   1532   Widget* child = new Widget;
   1533   Widget::InitParams child_params(Widget::InitParams::TYPE_CONTROL);
   1534   child_params.parent = toplevel1->GetNativeView();
   1535   child->Init(child_params);
   1536 
   1537   ToplevelWidgetObserverView* observer_view =
   1538       new ToplevelWidgetObserverView();
   1539   EXPECT_EQ(NULL, observer_view->toplevel());
   1540 
   1541   child->SetContentsView(observer_view);
   1542   EXPECT_EQ(toplevel1, observer_view->toplevel());
   1543 
   1544   Widget::ReparentNativeView(child->GetNativeView(),
   1545                              toplevel2->GetNativeView());
   1546   EXPECT_EQ(toplevel2, observer_view->toplevel());
   1547 
   1548   observer_view->parent()->RemoveChildView(observer_view);
   1549   EXPECT_EQ(NULL, observer_view->toplevel());
   1550 
   1551   // Make |observer_view| |child|'s contents view again so that it gets deleted
   1552   // with the widget.
   1553   child->SetContentsView(observer_view);
   1554 }
   1555 
   1556 ////////////////////////////////////////////////////////////////////////////////
   1557 // Transformations
   1558 ////////////////////////////////////////////////////////////////////////////////
   1559 
   1560 class TransformPaintView : public TestView {
   1561  public:
   1562   TransformPaintView() {}
   1563   virtual ~TransformPaintView() {}
   1564 
   1565   void ClearScheduledPaintRect() {
   1566     scheduled_paint_rect_ = gfx::Rect();
   1567   }
   1568 
   1569   gfx::Rect scheduled_paint_rect() const { return scheduled_paint_rect_; }
   1570 
   1571   // Overridden from View:
   1572   virtual void SchedulePaintInRect(const gfx::Rect& rect) OVERRIDE {
   1573     gfx::Rect xrect = ConvertRectToParent(rect);
   1574     scheduled_paint_rect_.Union(xrect);
   1575   }
   1576 
   1577  private:
   1578   gfx::Rect scheduled_paint_rect_;
   1579 
   1580   DISALLOW_COPY_AND_ASSIGN(TransformPaintView);
   1581 };
   1582 
   1583 TEST_F(ViewTest, TransformPaint) {
   1584   TransformPaintView* v1 = new TransformPaintView();
   1585   v1->SetBoundsRect(gfx::Rect(0, 0, 500, 300));
   1586 
   1587   TestView* v2 = new TestView();
   1588   v2->SetBoundsRect(gfx::Rect(100, 100, 200, 100));
   1589 
   1590   Widget* widget = new Widget;
   1591   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
   1592   params.bounds = gfx::Rect(50, 50, 650, 650);
   1593   widget->Init(params);
   1594   widget->Show();
   1595   View* root = widget->GetRootView();
   1596 
   1597   root->AddChildView(v1);
   1598   v1->AddChildView(v2);
   1599 
   1600   // At this moment, |v2| occupies (100, 100) to (300, 200) in |root|.
   1601   v1->ClearScheduledPaintRect();
   1602   v2->SchedulePaint();
   1603 
   1604   EXPECT_EQ(gfx::Rect(100, 100, 200, 100), v1->scheduled_paint_rect());
   1605 
   1606   // Rotate |v1| counter-clockwise.
   1607   gfx::Transform transform;
   1608   RotateCounterclockwise(&transform);
   1609   transform.matrix().set(1, 3, 500.0);
   1610   v1->SetTransform(transform);
   1611 
   1612   // |v2| now occupies (100, 200) to (200, 400) in |root|.
   1613 
   1614   v1->ClearScheduledPaintRect();
   1615   v2->SchedulePaint();
   1616 
   1617   EXPECT_EQ(gfx::Rect(100, 200, 100, 200), v1->scheduled_paint_rect());
   1618 
   1619   widget->CloseNow();
   1620 }
   1621 
   1622 TEST_F(ViewTest, TransformEvent) {
   1623   TestView* v1 = new TestView();
   1624   v1->SetBoundsRect(gfx::Rect(0, 0, 500, 300));
   1625 
   1626   TestView* v2 = new TestView();
   1627   v2->SetBoundsRect(gfx::Rect(100, 100, 200, 100));
   1628 
   1629   Widget* widget = new Widget;
   1630   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
   1631   params.bounds = gfx::Rect(50, 50, 650, 650);
   1632   widget->Init(params);
   1633   View* root = widget->GetRootView();
   1634 
   1635   root->AddChildView(v1);
   1636   v1->AddChildView(v2);
   1637 
   1638   // At this moment, |v2| occupies (100, 100) to (300, 200) in |root|.
   1639 
   1640   // Rotate |v1| counter-clockwise.
   1641   gfx::Transform transform(v1->GetTransform());
   1642   RotateCounterclockwise(&transform);
   1643   transform.matrix().set(1, 3, 500.0);
   1644   v1->SetTransform(transform);
   1645 
   1646   // |v2| now occupies (100, 200) to (200, 400) in |root|.
   1647   v1->Reset();
   1648   v2->Reset();
   1649 
   1650   gfx::Point p1(110, 210);
   1651   ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED, p1, p1,
   1652                          ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
   1653   root->OnMousePressed(pressed);
   1654   EXPECT_EQ(0, v1->last_mouse_event_type_);
   1655   EXPECT_EQ(ui::ET_MOUSE_PRESSED, v2->last_mouse_event_type_);
   1656   EXPECT_EQ(190, v2->location_.x());
   1657   EXPECT_EQ(10, v2->location_.y());
   1658 
   1659   ui::MouseEvent released(ui::ET_MOUSE_RELEASED, gfx::Point(), gfx::Point(), 0,
   1660                           0);
   1661   root->OnMouseReleased(released);
   1662 
   1663   // Now rotate |v2| inside |v1| clockwise.
   1664   transform = v2->GetTransform();
   1665   RotateClockwise(&transform);
   1666   transform.matrix().set(0, 3, 100.f);
   1667   v2->SetTransform(transform);
   1668 
   1669   // Now, |v2| occupies (100, 100) to (200, 300) in |v1|, and (100, 300) to
   1670   // (300, 400) in |root|.
   1671 
   1672   v1->Reset();
   1673   v2->Reset();
   1674 
   1675   gfx::Point point2(110, 320);
   1676   ui::MouseEvent p2(ui::ET_MOUSE_PRESSED, point2, point2,
   1677                     ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
   1678   root->OnMousePressed(p2);
   1679   EXPECT_EQ(0, v1->last_mouse_event_type_);
   1680   EXPECT_EQ(ui::ET_MOUSE_PRESSED, v2->last_mouse_event_type_);
   1681   EXPECT_EQ(10, v2->location_.x());
   1682   EXPECT_EQ(20, v2->location_.y());
   1683 
   1684   root->OnMouseReleased(released);
   1685 
   1686   v1->SetTransform(gfx::Transform());
   1687   v2->SetTransform(gfx::Transform());
   1688 
   1689   TestView* v3 = new TestView();
   1690   v3->SetBoundsRect(gfx::Rect(10, 10, 20, 30));
   1691   v2->AddChildView(v3);
   1692 
   1693   // Rotate |v3| clockwise with respect to |v2|.
   1694   transform = v1->GetTransform();
   1695   RotateClockwise(&transform);
   1696   transform.matrix().set(0, 3, 30.f);
   1697   v3->SetTransform(transform);
   1698 
   1699   // Scale |v2| with respect to |v1| along both axis.
   1700   transform = v2->GetTransform();
   1701   transform.matrix().set(0, 0, 0.8f);
   1702   transform.matrix().set(1, 1, 0.5f);
   1703   v2->SetTransform(transform);
   1704 
   1705   // |v3| occupies (108, 105) to (132, 115) in |root|.
   1706 
   1707   v1->Reset();
   1708   v2->Reset();
   1709   v3->Reset();
   1710 
   1711   gfx::Point point(112, 110);
   1712   ui::MouseEvent p3(ui::ET_MOUSE_PRESSED, point, point,
   1713                     ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
   1714   root->OnMousePressed(p3);
   1715 
   1716   EXPECT_EQ(ui::ET_MOUSE_PRESSED, v3->last_mouse_event_type_);
   1717   EXPECT_EQ(10, v3->location_.x());
   1718   EXPECT_EQ(25, v3->location_.y());
   1719 
   1720   root->OnMouseReleased(released);
   1721 
   1722   v1->SetTransform(gfx::Transform());
   1723   v2->SetTransform(gfx::Transform());
   1724   v3->SetTransform(gfx::Transform());
   1725 
   1726   v1->Reset();
   1727   v2->Reset();
   1728   v3->Reset();
   1729 
   1730   // Rotate |v3| clockwise with respect to |v2|, and scale it along both axis.
   1731   transform = v3->GetTransform();
   1732   RotateClockwise(&transform);
   1733   transform.matrix().set(0, 3, 30.f);
   1734   // Rotation sets some scaling transformation. Using SetScale would overwrite
   1735   // that and pollute the rotation. So combine the scaling with the existing
   1736   // transforamtion.
   1737   gfx::Transform scale;
   1738   scale.Scale(0.8f, 0.5f);
   1739   transform.ConcatTransform(scale);
   1740   v3->SetTransform(transform);
   1741 
   1742   // Translate |v2| with respect to |v1|.
   1743   transform = v2->GetTransform();
   1744   transform.matrix().set(0, 3, 10.f);
   1745   transform.matrix().set(1, 3, 10.f);
   1746   v2->SetTransform(transform);
   1747 
   1748   // |v3| now occupies (120, 120) to (144, 130) in |root|.
   1749 
   1750   gfx::Point point3(124, 125);
   1751   ui::MouseEvent p4(ui::ET_MOUSE_PRESSED, point3, point3,
   1752                     ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
   1753   root->OnMousePressed(p4);
   1754 
   1755   EXPECT_EQ(ui::ET_MOUSE_PRESSED, v3->last_mouse_event_type_);
   1756   EXPECT_EQ(10, v3->location_.x());
   1757   EXPECT_EQ(25, v3->location_.y());
   1758 
   1759   root->OnMouseReleased(released);
   1760 
   1761   widget->CloseNow();
   1762 }
   1763 
   1764 TEST_F(ViewTest, TransformVisibleBound) {
   1765   gfx::Rect viewport_bounds(0, 0, 100, 100);
   1766 
   1767   scoped_ptr<Widget> widget(new Widget);
   1768   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
   1769   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
   1770   params.bounds = viewport_bounds;
   1771   widget->Init(params);
   1772   widget->GetRootView()->SetBoundsRect(viewport_bounds);
   1773 
   1774   View* viewport = new View;
   1775   widget->SetContentsView(viewport);
   1776   View* contents = new View;
   1777   viewport->AddChildView(contents);
   1778   viewport->SetBoundsRect(viewport_bounds);
   1779   contents->SetBoundsRect(gfx::Rect(0, 0, 100, 200));
   1780 
   1781   View* child = new View;
   1782   contents->AddChildView(child);
   1783   child->SetBoundsRect(gfx::Rect(10, 90, 50, 50));
   1784   EXPECT_EQ(gfx::Rect(0, 0, 50, 10), child->GetVisibleBounds());
   1785 
   1786   // Rotate |child| counter-clockwise
   1787   gfx::Transform transform;
   1788   RotateCounterclockwise(&transform);
   1789   transform.matrix().set(1, 3, 50.f);
   1790   child->SetTransform(transform);
   1791   EXPECT_EQ(gfx::Rect(40, 0, 10, 50), child->GetVisibleBounds());
   1792 
   1793   widget->CloseNow();
   1794 }
   1795 
   1796 ////////////////////////////////////////////////////////////////////////////////
   1797 // OnVisibleBoundsChanged()
   1798 
   1799 class VisibleBoundsView : public View {
   1800  public:
   1801   VisibleBoundsView() : received_notification_(false) {}
   1802   virtual ~VisibleBoundsView() {}
   1803 
   1804   bool received_notification() const { return received_notification_; }
   1805   void set_received_notification(bool received) {
   1806     received_notification_ = received;
   1807   }
   1808 
   1809  private:
   1810   // Overridden from View:
   1811   virtual bool GetNeedsNotificationWhenVisibleBoundsChange() const OVERRIDE {
   1812      return true;
   1813   }
   1814   virtual void OnVisibleBoundsChanged() OVERRIDE {
   1815     received_notification_ = true;
   1816   }
   1817 
   1818   bool received_notification_;
   1819 
   1820   DISALLOW_COPY_AND_ASSIGN(VisibleBoundsView);
   1821 };
   1822 
   1823 TEST_F(ViewTest, OnVisibleBoundsChanged) {
   1824   gfx::Rect viewport_bounds(0, 0, 100, 100);
   1825 
   1826   scoped_ptr<Widget> widget(new Widget);
   1827   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
   1828   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
   1829   params.bounds = viewport_bounds;
   1830   widget->Init(params);
   1831   widget->GetRootView()->SetBoundsRect(viewport_bounds);
   1832 
   1833   View* viewport = new View;
   1834   widget->SetContentsView(viewport);
   1835   View* contents = new View;
   1836   viewport->AddChildView(contents);
   1837   viewport->SetBoundsRect(viewport_bounds);
   1838   contents->SetBoundsRect(gfx::Rect(0, 0, 100, 200));
   1839 
   1840   // Create a view that cares about visible bounds notifications, and position
   1841   // it just outside the visible bounds of the viewport.
   1842   VisibleBoundsView* child = new VisibleBoundsView;
   1843   contents->AddChildView(child);
   1844   child->SetBoundsRect(gfx::Rect(10, 110, 50, 50));
   1845 
   1846   // The child bound should be fully clipped.
   1847   EXPECT_TRUE(child->GetVisibleBounds().IsEmpty());
   1848 
   1849   // Now scroll the contents, but not enough to make the child visible.
   1850   contents->SetY(contents->y() - 1);
   1851 
   1852   // We should have received the notification since the visible bounds may have
   1853   // changed (even though they didn't).
   1854   EXPECT_TRUE(child->received_notification());
   1855   EXPECT_TRUE(child->GetVisibleBounds().IsEmpty());
   1856   child->set_received_notification(false);
   1857 
   1858   // Now scroll the contents, this time by enough to make the child visible by
   1859   // one pixel.
   1860   contents->SetY(contents->y() - 10);
   1861   EXPECT_TRUE(child->received_notification());
   1862   EXPECT_EQ(1, child->GetVisibleBounds().height());
   1863   child->set_received_notification(false);
   1864 
   1865   widget->CloseNow();
   1866 }
   1867 
   1868 TEST_F(ViewTest, SetBoundsPaint) {
   1869   TestView top_view;
   1870   TestView* child_view = new TestView;
   1871 
   1872   top_view.SetBoundsRect(gfx::Rect(0, 0, 100, 100));
   1873   top_view.scheduled_paint_rects_.clear();
   1874   child_view->SetBoundsRect(gfx::Rect(10, 10, 20, 20));
   1875   top_view.AddChildView(child_view);
   1876 
   1877   top_view.scheduled_paint_rects_.clear();
   1878   child_view->SetBoundsRect(gfx::Rect(30, 30, 20, 20));
   1879   EXPECT_EQ(2U, top_view.scheduled_paint_rects_.size());
   1880 
   1881   // There should be 2 rects, spanning from (10, 10) to (50, 50).
   1882   gfx::Rect paint_rect = top_view.scheduled_paint_rects_[0];
   1883   paint_rect.Union(top_view.scheduled_paint_rects_[1]);
   1884   EXPECT_EQ(gfx::Rect(10, 10, 40, 40), paint_rect);
   1885 }
   1886 
   1887 // Assertions around painting and focus gain/lost.
   1888 TEST_F(ViewTest, FocusBlurPaints) {
   1889   TestView parent_view;
   1890   TestView* child_view1 = new TestView;  // Owned by |parent_view|.
   1891 
   1892   parent_view.SetBoundsRect(gfx::Rect(0, 0, 100, 100));
   1893 
   1894   child_view1->SetBoundsRect(gfx::Rect(0, 0, 20, 20));
   1895   parent_view.AddChildView(child_view1);
   1896 
   1897   parent_view.scheduled_paint_rects_.clear();
   1898   child_view1->scheduled_paint_rects_.clear();
   1899 
   1900   // Focus change shouldn't trigger paints.
   1901   child_view1->DoFocus();
   1902 
   1903   EXPECT_TRUE(parent_view.scheduled_paint_rects_.empty());
   1904   EXPECT_TRUE(child_view1->scheduled_paint_rects_.empty());
   1905 
   1906   child_view1->DoBlur();
   1907   EXPECT_TRUE(parent_view.scheduled_paint_rects_.empty());
   1908   EXPECT_TRUE(child_view1->scheduled_paint_rects_.empty());
   1909 }
   1910 
   1911 // Verifies SetBounds(same bounds) doesn't trigger a SchedulePaint().
   1912 TEST_F(ViewTest, SetBoundsSameBoundsDoesntSchedulePaint) {
   1913   TestView view;
   1914 
   1915   view.SetBoundsRect(gfx::Rect(0, 0, 100, 100));
   1916   view.InvalidateLayout();
   1917   view.scheduled_paint_rects_.clear();
   1918   view.SetBoundsRect(gfx::Rect(0, 0, 100, 100));
   1919   EXPECT_TRUE(view.scheduled_paint_rects_.empty());
   1920 }
   1921 
   1922 // Verifies AddChildView() and RemoveChildView() schedule appropriate paints.
   1923 TEST_F(ViewTest, AddAndRemoveSchedulePaints) {
   1924   gfx::Rect viewport_bounds(0, 0, 100, 100);
   1925 
   1926   // We have to put the View hierarchy into a Widget or no paints will be
   1927   // scheduled.
   1928   scoped_ptr<Widget> widget(new Widget);
   1929   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
   1930   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
   1931   params.bounds = viewport_bounds;
   1932   widget->Init(params);
   1933   widget->GetRootView()->SetBoundsRect(viewport_bounds);
   1934 
   1935   TestView* parent_view = new TestView;
   1936   widget->SetContentsView(parent_view);
   1937   parent_view->SetBoundsRect(viewport_bounds);
   1938   parent_view->scheduled_paint_rects_.clear();
   1939 
   1940   View* child_view = new View;
   1941   child_view->SetBoundsRect(gfx::Rect(0, 0, 20, 20));
   1942   parent_view->AddChildView(child_view);
   1943   ASSERT_EQ(1U, parent_view->scheduled_paint_rects_.size());
   1944   EXPECT_EQ(child_view->bounds(), parent_view->scheduled_paint_rects_.front());
   1945 
   1946   parent_view->scheduled_paint_rects_.clear();
   1947   parent_view->RemoveChildView(child_view);
   1948   scoped_ptr<View> child_deleter(child_view);
   1949   ASSERT_EQ(1U, parent_view->scheduled_paint_rects_.size());
   1950   EXPECT_EQ(child_view->bounds(), parent_view->scheduled_paint_rects_.front());
   1951 
   1952   widget->CloseNow();
   1953 }
   1954 
   1955 // Tests conversion methods with a transform.
   1956 TEST_F(ViewTest, ConversionsWithTransform) {
   1957   TestView top_view;
   1958 
   1959   // View hierarchy used to test scale transforms.
   1960   TestView* child = new TestView;
   1961   TestView* child_child = new TestView;
   1962 
   1963   // View used to test a rotation transform.
   1964   TestView* child_2 = new TestView;
   1965 
   1966   top_view.AddChildView(child);
   1967   child->AddChildView(child_child);
   1968 
   1969   top_view.SetBoundsRect(gfx::Rect(0, 0, 1000, 1000));
   1970 
   1971   child->SetBoundsRect(gfx::Rect(7, 19, 500, 500));
   1972   gfx::Transform transform;
   1973   transform.Scale(3.0, 4.0);
   1974   child->SetTransform(transform);
   1975 
   1976   child_child->SetBoundsRect(gfx::Rect(17, 13, 100, 100));
   1977   transform.MakeIdentity();
   1978   transform.Scale(5.0, 7.0);
   1979   child_child->SetTransform(transform);
   1980 
   1981   top_view.AddChildView(child_2);
   1982   child_2->SetBoundsRect(gfx::Rect(700, 725, 100, 100));
   1983   transform.MakeIdentity();
   1984   RotateClockwise(&transform);
   1985   child_2->SetTransform(transform);
   1986 
   1987   // Sanity check to make sure basic transforms act as expected.
   1988   {
   1989     gfx::Transform transform;
   1990     transform.Translate(110.0, -110.0);
   1991     transform.Scale(100.0, 55.0);
   1992     transform.Translate(1.0, 1.0);
   1993 
   1994     // convert to a 3x3 matrix.
   1995     const SkMatrix& matrix = transform.matrix();
   1996 
   1997     EXPECT_EQ(210, matrix.getTranslateX());
   1998     EXPECT_EQ(-55, matrix.getTranslateY());
   1999     EXPECT_EQ(100, matrix.getScaleX());
   2000     EXPECT_EQ(55, matrix.getScaleY());
   2001     EXPECT_EQ(0, matrix.getSkewX());
   2002     EXPECT_EQ(0, matrix.getSkewY());
   2003   }
   2004 
   2005   {
   2006     gfx::Transform transform;
   2007     transform.Translate(1.0, 1.0);
   2008     gfx::Transform t2;
   2009     t2.Scale(100.0, 55.0);
   2010     gfx::Transform t3;
   2011     t3.Translate(110.0, -110.0);
   2012     transform.ConcatTransform(t2);
   2013     transform.ConcatTransform(t3);
   2014 
   2015     // convert to a 3x3 matrix
   2016     const SkMatrix& matrix = transform.matrix();
   2017 
   2018     EXPECT_EQ(210, matrix.getTranslateX());
   2019     EXPECT_EQ(-55, matrix.getTranslateY());
   2020     EXPECT_EQ(100, matrix.getScaleX());
   2021     EXPECT_EQ(55, matrix.getScaleY());
   2022     EXPECT_EQ(0, matrix.getSkewX());
   2023     EXPECT_EQ(0, matrix.getSkewY());
   2024   }
   2025 
   2026   // Conversions from child->top and top->child.
   2027   {
   2028     gfx::Point point(5, 5);
   2029     View::ConvertPointToTarget(child, &top_view, &point);
   2030     EXPECT_EQ(22, point.x());
   2031     EXPECT_EQ(39, point.y());
   2032 
   2033     gfx::RectF rect(5.0f, 5.0f, 10.0f, 20.0f);
   2034     View::ConvertRectToTarget(child, &top_view, &rect);
   2035     EXPECT_FLOAT_EQ(22.0f, rect.x());
   2036     EXPECT_FLOAT_EQ(39.0f, rect.y());
   2037     EXPECT_FLOAT_EQ(30.0f, rect.width());
   2038     EXPECT_FLOAT_EQ(80.0f, rect.height());
   2039 
   2040     point.SetPoint(22, 39);
   2041     View::ConvertPointToTarget(&top_view, child, &point);
   2042     EXPECT_EQ(5, point.x());
   2043     EXPECT_EQ(5, point.y());
   2044 
   2045     rect.SetRect(22.0f, 39.0f, 30.0f, 80.0f);
   2046     View::ConvertRectToTarget(&top_view, child, &rect);
   2047     EXPECT_FLOAT_EQ(5.0f, rect.x());
   2048     EXPECT_FLOAT_EQ(5.0f, rect.y());
   2049     EXPECT_FLOAT_EQ(10.0f, rect.width());
   2050     EXPECT_FLOAT_EQ(20.0f, rect.height());
   2051   }
   2052 
   2053   // Conversions from child_child->top and top->child_child.
   2054   {
   2055     gfx::Point point(5, 5);
   2056     View::ConvertPointToTarget(child_child, &top_view, &point);
   2057     EXPECT_EQ(133, point.x());
   2058     EXPECT_EQ(211, point.y());
   2059 
   2060     gfx::RectF rect(5.0f, 5.0f, 10.0f, 20.0f);
   2061     View::ConvertRectToTarget(child_child, &top_view, &rect);
   2062     EXPECT_FLOAT_EQ(133.0f, rect.x());
   2063     EXPECT_FLOAT_EQ(211.0f, rect.y());
   2064     EXPECT_FLOAT_EQ(150.0f, rect.width());
   2065     EXPECT_FLOAT_EQ(560.0f, rect.height());
   2066 
   2067     point.SetPoint(133, 211);
   2068     View::ConvertPointToTarget(&top_view, child_child, &point);
   2069     EXPECT_EQ(5, point.x());
   2070     EXPECT_EQ(5, point.y());
   2071 
   2072     rect.SetRect(133.0f, 211.0f, 150.0f, 560.0f);
   2073     View::ConvertRectToTarget(&top_view, child_child, &rect);
   2074     EXPECT_FLOAT_EQ(5.0f, rect.x());
   2075     EXPECT_FLOAT_EQ(5.0f, rect.y());
   2076     EXPECT_FLOAT_EQ(10.0f, rect.width());
   2077     EXPECT_FLOAT_EQ(20.0f, rect.height());
   2078   }
   2079 
   2080   // Conversions from child_child->child and child->child_child
   2081   {
   2082     gfx::Point point(5, 5);
   2083     View::ConvertPointToTarget(child_child, child, &point);
   2084     EXPECT_EQ(42, point.x());
   2085     EXPECT_EQ(48, point.y());
   2086 
   2087     gfx::RectF rect(5.0f, 5.0f, 10.0f, 20.0f);
   2088     View::ConvertRectToTarget(child_child, child, &rect);
   2089     EXPECT_FLOAT_EQ(42.0f, rect.x());
   2090     EXPECT_FLOAT_EQ(48.0f, rect.y());
   2091     EXPECT_FLOAT_EQ(50.0f, rect.width());
   2092     EXPECT_FLOAT_EQ(140.0f, rect.height());
   2093 
   2094     point.SetPoint(42, 48);
   2095     View::ConvertPointToTarget(child, child_child, &point);
   2096     EXPECT_EQ(5, point.x());
   2097     EXPECT_EQ(5, point.y());
   2098 
   2099     rect.SetRect(42.0f, 48.0f, 50.0f, 140.0f);
   2100     View::ConvertRectToTarget(child, child_child, &rect);
   2101     EXPECT_FLOAT_EQ(5.0f, rect.x());
   2102     EXPECT_FLOAT_EQ(5.0f, rect.y());
   2103     EXPECT_FLOAT_EQ(10.0f, rect.width());
   2104     EXPECT_FLOAT_EQ(20.0f, rect.height());
   2105   }
   2106 
   2107   // Conversions from top_view to child with a value that should be negative.
   2108   // This ensures we don't round up with negative numbers.
   2109   {
   2110     gfx::Point point(6, 18);
   2111     View::ConvertPointToTarget(&top_view, child, &point);
   2112     EXPECT_EQ(-1, point.x());
   2113     EXPECT_EQ(-1, point.y());
   2114 
   2115     float error = 0.01f;
   2116     gfx::RectF rect(6.0f, 18.0f, 10.0f, 39.0f);
   2117     View::ConvertRectToTarget(&top_view, child, &rect);
   2118     EXPECT_NEAR(-0.33f, rect.x(), error);
   2119     EXPECT_NEAR(-0.25f, rect.y(), error);
   2120     EXPECT_NEAR(3.33f, rect.width(), error);
   2121     EXPECT_NEAR(9.75f, rect.height(), error);
   2122   }
   2123 
   2124   // Rect conversions from top_view->child_2 and child_2->top_view.
   2125   {
   2126     gfx::RectF rect(50.0f, 55.0f, 20.0f, 30.0f);
   2127     View::ConvertRectToTarget(child_2, &top_view, &rect);
   2128     EXPECT_FLOAT_EQ(615.0f, rect.x());
   2129     EXPECT_FLOAT_EQ(775.0f, rect.y());
   2130     EXPECT_FLOAT_EQ(30.0f, rect.width());
   2131     EXPECT_FLOAT_EQ(20.0f, rect.height());
   2132 
   2133     rect.SetRect(615.0f, 775.0f, 30.0f, 20.0f);
   2134     View::ConvertRectToTarget(&top_view, child_2, &rect);
   2135     EXPECT_FLOAT_EQ(50.0f, rect.x());
   2136     EXPECT_FLOAT_EQ(55.0f, rect.y());
   2137     EXPECT_FLOAT_EQ(20.0f, rect.width());
   2138     EXPECT_FLOAT_EQ(30.0f, rect.height());
   2139   }
   2140 }
   2141 
   2142 // Tests conversion methods to and from screen coordinates.
   2143 TEST_F(ViewTest, ConversionsToFromScreen) {
   2144   scoped_ptr<Widget> widget(new Widget);
   2145   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
   2146   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
   2147   params.bounds = gfx::Rect(50, 50, 650, 650);
   2148   widget->Init(params);
   2149 
   2150   View* child = new View;
   2151   widget->GetRootView()->AddChildView(child);
   2152   child->SetBounds(10, 10, 100, 200);
   2153   gfx::Transform t;
   2154   t.Scale(0.5, 0.5);
   2155   child->SetTransform(t);
   2156 
   2157   gfx::Point point_in_screen(100, 90);
   2158   gfx::Point point_in_child(80, 60);
   2159 
   2160   gfx::Point point = point_in_screen;
   2161   View::ConvertPointFromScreen(child, &point);
   2162   EXPECT_EQ(point_in_child.ToString(), point.ToString());
   2163 
   2164   View::ConvertPointToScreen(child, &point);
   2165   EXPECT_EQ(point_in_screen.ToString(), point.ToString());
   2166 }
   2167 
   2168 // Tests conversion methods for rectangles.
   2169 TEST_F(ViewTest, ConvertRectWithTransform) {
   2170   scoped_ptr<Widget> widget(new Widget);
   2171   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
   2172   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
   2173   params.bounds = gfx::Rect(50, 50, 650, 650);
   2174   widget->Init(params);
   2175   View* root = widget->GetRootView();
   2176 
   2177   TestView* v1 = new TestView;
   2178   TestView* v2 = new TestView;
   2179   root->AddChildView(v1);
   2180   v1->AddChildView(v2);
   2181 
   2182   v1->SetBoundsRect(gfx::Rect(10, 10, 500, 500));
   2183   v2->SetBoundsRect(gfx::Rect(20, 20, 100, 200));
   2184 
   2185   // |v2| now occupies (30, 30) to (130, 230) in |widget|
   2186   gfx::Rect rect(5, 5, 15, 40);
   2187   EXPECT_EQ(gfx::Rect(25, 25, 15, 40), v2->ConvertRectToParent(rect));
   2188   EXPECT_EQ(gfx::Rect(35, 35, 15, 40), v2->ConvertRectToWidget(rect));
   2189 
   2190   // Rotate |v2|
   2191   gfx::Transform t2;
   2192   RotateCounterclockwise(&t2);
   2193   t2.matrix().set(1, 3, 100.f);
   2194   v2->SetTransform(t2);
   2195 
   2196   // |v2| now occupies (30, 30) to (230, 130) in |widget|
   2197   EXPECT_EQ(gfx::Rect(25, 100, 40, 15), v2->ConvertRectToParent(rect));
   2198   EXPECT_EQ(gfx::Rect(35, 110, 40, 15), v2->ConvertRectToWidget(rect));
   2199 
   2200   // Scale down |v1|
   2201   gfx::Transform t1;
   2202   t1.Scale(0.5, 0.5);
   2203   v1->SetTransform(t1);
   2204 
   2205   // The rectangle should remain the same for |v1|.
   2206   EXPECT_EQ(gfx::Rect(25, 100, 40, 15), v2->ConvertRectToParent(rect));
   2207 
   2208   // |v2| now occupies (20, 20) to (120, 70) in |widget|
   2209   EXPECT_EQ(gfx::Rect(22, 60, 21, 8).ToString(),
   2210             v2->ConvertRectToWidget(rect).ToString());
   2211 
   2212   widget->CloseNow();
   2213 }
   2214 
   2215 class ObserverView : public View {
   2216  public:
   2217   ObserverView();
   2218   virtual ~ObserverView();
   2219 
   2220   void ResetTestState();
   2221 
   2222   bool has_add_details() const { return has_add_details_; }
   2223   bool has_remove_details() const { return has_remove_details_; }
   2224 
   2225   const ViewHierarchyChangedDetails& add_details() const {
   2226     return add_details_;
   2227   }
   2228 
   2229   const ViewHierarchyChangedDetails& remove_details() const {
   2230     return remove_details_;
   2231   }
   2232 
   2233  private:
   2234   // View:
   2235   virtual void ViewHierarchyChanged(
   2236       const ViewHierarchyChangedDetails& details) OVERRIDE;
   2237 
   2238   bool has_add_details_;
   2239   bool has_remove_details_;
   2240   ViewHierarchyChangedDetails add_details_;
   2241   ViewHierarchyChangedDetails remove_details_;
   2242 
   2243   DISALLOW_COPY_AND_ASSIGN(ObserverView);
   2244 };
   2245 
   2246 ObserverView::ObserverView()
   2247     : has_add_details_(false),
   2248       has_remove_details_(false) {
   2249 }
   2250 
   2251 ObserverView::~ObserverView() {}
   2252 
   2253 void ObserverView::ResetTestState() {
   2254   has_add_details_ = false;
   2255   has_remove_details_ = false;
   2256   add_details_ = ViewHierarchyChangedDetails();
   2257   remove_details_ = ViewHierarchyChangedDetails();
   2258 }
   2259 
   2260 void ObserverView::ViewHierarchyChanged(
   2261     const ViewHierarchyChangedDetails& details) {
   2262   if (details.is_add) {
   2263     has_add_details_ = true;
   2264     add_details_ = details;
   2265   } else {
   2266     has_remove_details_ = true;
   2267     remove_details_ = details;
   2268   }
   2269 }
   2270 
   2271 // Verifies that the ViewHierarchyChanged() notification is sent correctly when
   2272 // a child view is added or removed to all the views in the hierarchy (up and
   2273 // down).
   2274 // The tree looks like this:
   2275 // v1
   2276 // +-- v2
   2277 //     +-- v3
   2278 //     +-- v4 (starts here, then get reparented to v1)
   2279 TEST_F(ViewTest, ViewHierarchyChanged) {
   2280   ObserverView v1;
   2281 
   2282   ObserverView* v3 = new ObserverView();
   2283 
   2284   // Add |v3| to |v2|.
   2285   scoped_ptr<ObserverView> v2(new ObserverView());
   2286   v2->AddChildView(v3);
   2287 
   2288   // Make sure both |v2| and |v3| receive the ViewHierarchyChanged()
   2289   // notification.
   2290   EXPECT_TRUE(v2->has_add_details());
   2291   EXPECT_FALSE(v2->has_remove_details());
   2292   EXPECT_EQ(v2.get(), v2->add_details().parent);
   2293   EXPECT_EQ(v3, v2->add_details().child);
   2294   EXPECT_EQ(NULL, v2->add_details().move_view);
   2295 
   2296   EXPECT_TRUE(v3->has_add_details());
   2297   EXPECT_FALSE(v3->has_remove_details());
   2298   EXPECT_EQ(v2.get(), v3->add_details().parent);
   2299   EXPECT_EQ(v3, v3->add_details().child);
   2300   EXPECT_EQ(NULL, v3->add_details().move_view);
   2301 
   2302   // Reset everything to the initial state.
   2303   v2->ResetTestState();
   2304   v3->ResetTestState();
   2305 
   2306   // Add |v2| to v1.
   2307   v1.AddChildView(v2.get());
   2308 
   2309   // Verifies that |v2| is the child view *added* and the parent view is |v1|.
   2310   // Make sure all the views (v1, v2, v3) received _that_ information.
   2311   EXPECT_TRUE(v1.has_add_details());
   2312   EXPECT_FALSE(v1.has_remove_details());
   2313   EXPECT_EQ(&v1, v1.add_details().parent);
   2314   EXPECT_EQ(v2.get(), v1.add_details().child);
   2315   EXPECT_EQ(NULL, v1.add_details().move_view);
   2316 
   2317   EXPECT_TRUE(v2->has_add_details());
   2318   EXPECT_FALSE(v2->has_remove_details());
   2319   EXPECT_EQ(&v1, v2->add_details().parent);
   2320   EXPECT_EQ(v2.get(), v2->add_details().child);
   2321   EXPECT_EQ(NULL, v2->add_details().move_view);
   2322 
   2323   EXPECT_TRUE(v3->has_add_details());
   2324   EXPECT_FALSE(v3->has_remove_details());
   2325   EXPECT_EQ(&v1, v3->add_details().parent);
   2326   EXPECT_EQ(v2.get(), v3->add_details().child);
   2327   EXPECT_EQ(NULL, v3->add_details().move_view);
   2328 
   2329   // Reset everything to the initial state.
   2330   v1.ResetTestState();
   2331   v2->ResetTestState();
   2332   v3->ResetTestState();
   2333 
   2334   // Remove |v2| from |v1|.
   2335   v1.RemoveChildView(v2.get());
   2336 
   2337   // Verifies that |v2| is the child view *removed* and the parent view is |v1|.
   2338   // Make sure all the views (v1, v2, v3) received _that_ information.
   2339   EXPECT_FALSE(v1.has_add_details());
   2340   EXPECT_TRUE(v1.has_remove_details());
   2341   EXPECT_EQ(&v1, v1.remove_details().parent);
   2342   EXPECT_EQ(v2.get(), v1.remove_details().child);
   2343   EXPECT_EQ(NULL, v1.remove_details().move_view);
   2344 
   2345   EXPECT_FALSE(v2->has_add_details());
   2346   EXPECT_TRUE(v2->has_remove_details());
   2347   EXPECT_EQ(&v1, v2->remove_details().parent);
   2348   EXPECT_EQ(v2.get(), v2->remove_details().child);
   2349   EXPECT_EQ(NULL, v2->remove_details().move_view);
   2350 
   2351   EXPECT_FALSE(v3->has_add_details());
   2352   EXPECT_TRUE(v3->has_remove_details());
   2353   EXPECT_EQ(&v1, v3->remove_details().parent);
   2354   EXPECT_EQ(v3, v3->remove_details().child);
   2355   EXPECT_EQ(NULL, v3->remove_details().move_view);
   2356 
   2357   // Verifies notifications when reparenting a view.
   2358   ObserverView* v4 = new ObserverView();
   2359   // Add |v4| to |v2|.
   2360   v2->AddChildView(v4);
   2361 
   2362   // Reset everything to the initial state.
   2363   v1.ResetTestState();
   2364   v2->ResetTestState();
   2365   v3->ResetTestState();
   2366   v4->ResetTestState();
   2367 
   2368   // Reparent |v4| to |v1|.
   2369   v1.AddChildView(v4);
   2370 
   2371   // Verifies that all views receive the correct information for all the child,
   2372   // parent and move views.
   2373 
   2374   // |v1| is the new parent, |v4| is the child for add, |v2| is the old parent.
   2375   EXPECT_TRUE(v1.has_add_details());
   2376   EXPECT_FALSE(v1.has_remove_details());
   2377   EXPECT_EQ(&v1, v1.add_details().parent);
   2378   EXPECT_EQ(v4, v1.add_details().child);
   2379   EXPECT_EQ(v2.get(), v1.add_details().move_view);
   2380 
   2381   // |v2| is the old parent, |v4| is the child for remove, |v1| is the new
   2382   // parent.
   2383   EXPECT_FALSE(v2->has_add_details());
   2384   EXPECT_TRUE(v2->has_remove_details());
   2385   EXPECT_EQ(v2.get(), v2->remove_details().parent);
   2386   EXPECT_EQ(v4, v2->remove_details().child);
   2387   EXPECT_EQ(&v1, v2->remove_details().move_view);
   2388 
   2389   // |v3| is not impacted by this operation, and hence receives no notification.
   2390   EXPECT_FALSE(v3->has_add_details());
   2391   EXPECT_FALSE(v3->has_remove_details());
   2392 
   2393   // |v4| is the reparented child, so it receives notifications for the remove
   2394   // and then the add.  |v2| is its old parent, |v1| is its new parent.
   2395   EXPECT_TRUE(v4->has_remove_details());
   2396   EXPECT_TRUE(v4->has_add_details());
   2397   EXPECT_EQ(v2.get(), v4->remove_details().parent);
   2398   EXPECT_EQ(&v1, v4->add_details().parent);
   2399   EXPECT_EQ(v4, v4->add_details().child);
   2400   EXPECT_EQ(v4, v4->remove_details().child);
   2401   EXPECT_EQ(&v1, v4->remove_details().move_view);
   2402   EXPECT_EQ(v2.get(), v4->add_details().move_view);
   2403 }
   2404 
   2405 // Verifies if the child views added under the root are all deleted when calling
   2406 // RemoveAllChildViews.
   2407 // The tree looks like this:
   2408 // root
   2409 // +-- child1
   2410 //     +-- foo
   2411 //         +-- bar0
   2412 //         +-- bar1
   2413 //         +-- bar2
   2414 // +-- child2
   2415 // +-- child3
   2416 TEST_F(ViewTest, RemoveAllChildViews) {
   2417   View root;
   2418 
   2419   View* child1 = new View;
   2420   root.AddChildView(child1);
   2421 
   2422   for (int i = 0; i < 2; ++i)
   2423     root.AddChildView(new View);
   2424 
   2425   View* foo = new View;
   2426   child1->AddChildView(foo);
   2427 
   2428   // Add some nodes to |foo|.
   2429   for (int i = 0; i < 3; ++i)
   2430     foo->AddChildView(new View);
   2431 
   2432   EXPECT_EQ(3, root.child_count());
   2433   EXPECT_EQ(1, child1->child_count());
   2434   EXPECT_EQ(3, foo->child_count());
   2435 
   2436   // Now remove all child views from root.
   2437   root.RemoveAllChildViews(true);
   2438 
   2439   EXPECT_EQ(0, root.child_count());
   2440   EXPECT_FALSE(root.has_children());
   2441 }
   2442 
   2443 TEST_F(ViewTest, Contains) {
   2444   View v1;
   2445   View* v2 = new View;
   2446   View* v3 = new View;
   2447 
   2448   v1.AddChildView(v2);
   2449   v2->AddChildView(v3);
   2450 
   2451   EXPECT_FALSE(v1.Contains(NULL));
   2452   EXPECT_TRUE(v1.Contains(&v1));
   2453   EXPECT_TRUE(v1.Contains(v2));
   2454   EXPECT_TRUE(v1.Contains(v3));
   2455 
   2456   EXPECT_FALSE(v2->Contains(NULL));
   2457   EXPECT_TRUE(v2->Contains(v2));
   2458   EXPECT_FALSE(v2->Contains(&v1));
   2459   EXPECT_TRUE(v2->Contains(v3));
   2460 
   2461   EXPECT_FALSE(v3->Contains(NULL));
   2462   EXPECT_TRUE(v3->Contains(v3));
   2463   EXPECT_FALSE(v3->Contains(&v1));
   2464   EXPECT_FALSE(v3->Contains(v2));
   2465 }
   2466 
   2467 // Verifies if GetIndexOf() returns the correct index for the specified child
   2468 // view.
   2469 // The tree looks like this:
   2470 // root
   2471 // +-- child1
   2472 //     +-- foo1
   2473 // +-- child2
   2474 TEST_F(ViewTest, GetIndexOf) {
   2475   View root;
   2476 
   2477   View* child1 = new View;
   2478   root.AddChildView(child1);
   2479 
   2480   View* child2 = new View;
   2481   root.AddChildView(child2);
   2482 
   2483   View* foo1 = new View;
   2484   child1->AddChildView(foo1);
   2485 
   2486   EXPECT_EQ(-1, root.GetIndexOf(NULL));
   2487   EXPECT_EQ(-1, root.GetIndexOf(&root));
   2488   EXPECT_EQ(0, root.GetIndexOf(child1));
   2489   EXPECT_EQ(1, root.GetIndexOf(child2));
   2490   EXPECT_EQ(-1, root.GetIndexOf(foo1));
   2491 
   2492   EXPECT_EQ(-1, child1->GetIndexOf(NULL));
   2493   EXPECT_EQ(-1, child1->GetIndexOf(&root));
   2494   EXPECT_EQ(-1, child1->GetIndexOf(child1));
   2495   EXPECT_EQ(-1, child1->GetIndexOf(child2));
   2496   EXPECT_EQ(0, child1->GetIndexOf(foo1));
   2497 
   2498   EXPECT_EQ(-1, child2->GetIndexOf(NULL));
   2499   EXPECT_EQ(-1, child2->GetIndexOf(&root));
   2500   EXPECT_EQ(-1, child2->GetIndexOf(child2));
   2501   EXPECT_EQ(-1, child2->GetIndexOf(child1));
   2502   EXPECT_EQ(-1, child2->GetIndexOf(foo1));
   2503 }
   2504 
   2505 // Verifies that the child views can be reordered correctly.
   2506 TEST_F(ViewTest, ReorderChildren) {
   2507   View root;
   2508 
   2509   View* child = new View();
   2510   root.AddChildView(child);
   2511 
   2512   View* foo1 = new View();
   2513   child->AddChildView(foo1);
   2514   View* foo2 = new View();
   2515   child->AddChildView(foo2);
   2516   View* foo3 = new View();
   2517   child->AddChildView(foo3);
   2518   foo1->SetFocusable(true);
   2519   foo2->SetFocusable(true);
   2520   foo3->SetFocusable(true);
   2521 
   2522   ASSERT_EQ(0, child->GetIndexOf(foo1));
   2523   ASSERT_EQ(1, child->GetIndexOf(foo2));
   2524   ASSERT_EQ(2, child->GetIndexOf(foo3));
   2525   ASSERT_EQ(foo2, foo1->GetNextFocusableView());
   2526   ASSERT_EQ(foo3, foo2->GetNextFocusableView());
   2527   ASSERT_EQ(NULL, foo3->GetNextFocusableView());
   2528 
   2529   // Move |foo2| at the end.
   2530   child->ReorderChildView(foo2, -1);
   2531   ASSERT_EQ(0, child->GetIndexOf(foo1));
   2532   ASSERT_EQ(1, child->GetIndexOf(foo3));
   2533   ASSERT_EQ(2, child->GetIndexOf(foo2));
   2534   ASSERT_EQ(foo3, foo1->GetNextFocusableView());
   2535   ASSERT_EQ(foo2, foo3->GetNextFocusableView());
   2536   ASSERT_EQ(NULL, foo2->GetNextFocusableView());
   2537 
   2538   // Move |foo1| at the end.
   2539   child->ReorderChildView(foo1, -1);
   2540   ASSERT_EQ(0, child->GetIndexOf(foo3));
   2541   ASSERT_EQ(1, child->GetIndexOf(foo2));
   2542   ASSERT_EQ(2, child->GetIndexOf(foo1));
   2543   ASSERT_EQ(NULL, foo1->GetNextFocusableView());
   2544   ASSERT_EQ(foo2, foo1->GetPreviousFocusableView());
   2545   ASSERT_EQ(foo2, foo3->GetNextFocusableView());
   2546   ASSERT_EQ(foo1, foo2->GetNextFocusableView());
   2547 
   2548   // Move |foo2| to the front.
   2549   child->ReorderChildView(foo2, 0);
   2550   ASSERT_EQ(0, child->GetIndexOf(foo2));
   2551   ASSERT_EQ(1, child->GetIndexOf(foo3));
   2552   ASSERT_EQ(2, child->GetIndexOf(foo1));
   2553   ASSERT_EQ(NULL, foo1->GetNextFocusableView());
   2554   ASSERT_EQ(foo3, foo1->GetPreviousFocusableView());
   2555   ASSERT_EQ(foo3, foo2->GetNextFocusableView());
   2556   ASSERT_EQ(foo1, foo3->GetNextFocusableView());
   2557 }
   2558 
   2559 // Verifies that GetViewByID returns the correctly child view from the specified
   2560 // ID.
   2561 // The tree looks like this:
   2562 // v1
   2563 // +-- v2
   2564 //     +-- v3
   2565 //     +-- v4
   2566 TEST_F(ViewTest, GetViewByID) {
   2567   View v1;
   2568   const int kV1ID = 1;
   2569   v1.set_id(kV1ID);
   2570 
   2571   View v2;
   2572   const int kV2ID = 2;
   2573   v2.set_id(kV2ID);
   2574 
   2575   View v3;
   2576   const int kV3ID = 3;
   2577   v3.set_id(kV3ID);
   2578 
   2579   View v4;
   2580   const int kV4ID = 4;
   2581   v4.set_id(kV4ID);
   2582 
   2583   const int kV5ID = 5;
   2584 
   2585   v1.AddChildView(&v2);
   2586   v2.AddChildView(&v3);
   2587   v2.AddChildView(&v4);
   2588 
   2589   EXPECT_EQ(&v1, v1.GetViewByID(kV1ID));
   2590   EXPECT_EQ(&v2, v1.GetViewByID(kV2ID));
   2591   EXPECT_EQ(&v4, v1.GetViewByID(kV4ID));
   2592 
   2593   EXPECT_EQ(NULL, v1.GetViewByID(kV5ID));  // No V5 exists.
   2594   EXPECT_EQ(NULL, v2.GetViewByID(kV1ID));  // It can get only from child views.
   2595 
   2596   const int kGroup = 1;
   2597   v3.SetGroup(kGroup);
   2598   v4.SetGroup(kGroup);
   2599 
   2600   View::Views views;
   2601   v1.GetViewsInGroup(kGroup, &views);
   2602   EXPECT_EQ(2U, views.size());
   2603 
   2604   View::Views::const_iterator i(std::find(views.begin(), views.end(), &v3));
   2605   EXPECT_NE(views.end(), i);
   2606 
   2607   i = std::find(views.begin(), views.end(), &v4);
   2608   EXPECT_NE(views.end(), i);
   2609 }
   2610 
   2611 TEST_F(ViewTest, AddExistingChild) {
   2612   View v1, v2, v3;
   2613 
   2614   v1.AddChildView(&v2);
   2615   v1.AddChildView(&v3);
   2616   EXPECT_EQ(0, v1.GetIndexOf(&v2));
   2617   EXPECT_EQ(1, v1.GetIndexOf(&v3));
   2618 
   2619   // Check that there's no change in order when adding at same index.
   2620   v1.AddChildViewAt(&v2, 0);
   2621   EXPECT_EQ(0, v1.GetIndexOf(&v2));
   2622   EXPECT_EQ(1, v1.GetIndexOf(&v3));
   2623   v1.AddChildViewAt(&v3, 1);
   2624   EXPECT_EQ(0, v1.GetIndexOf(&v2));
   2625   EXPECT_EQ(1, v1.GetIndexOf(&v3));
   2626 
   2627   // Add it at a different index and check for change in order.
   2628   v1.AddChildViewAt(&v2, 1);
   2629   EXPECT_EQ(1, v1.GetIndexOf(&v2));
   2630   EXPECT_EQ(0, v1.GetIndexOf(&v3));
   2631   v1.AddChildViewAt(&v2, 0);
   2632   EXPECT_EQ(0, v1.GetIndexOf(&v2));
   2633   EXPECT_EQ(1, v1.GetIndexOf(&v3));
   2634 
   2635   // Check that calling |AddChildView()| does not change the order.
   2636   v1.AddChildView(&v2);
   2637   EXPECT_EQ(0, v1.GetIndexOf(&v2));
   2638   EXPECT_EQ(1, v1.GetIndexOf(&v3));
   2639   v1.AddChildView(&v3);
   2640   EXPECT_EQ(0, v1.GetIndexOf(&v2));
   2641   EXPECT_EQ(1, v1.GetIndexOf(&v3));
   2642 }
   2643 
   2644 ////////////////////////////////////////////////////////////////////////////////
   2645 // FocusManager
   2646 ////////////////////////////////////////////////////////////////////////////////
   2647 
   2648 // A widget that always claims to be active, regardless of its real activation
   2649 // status.
   2650 class ActiveWidget : public Widget {
   2651  public:
   2652   ActiveWidget() {}
   2653   virtual ~ActiveWidget() {}
   2654 
   2655   virtual bool IsActive() const OVERRIDE {
   2656     return true;
   2657   }
   2658 
   2659  private:
   2660   DISALLOW_COPY_AND_ASSIGN(ActiveWidget);
   2661 };
   2662 
   2663 TEST_F(ViewTest, AdvanceFocusIfNecessaryForUnfocusableView) {
   2664   // Create a widget with two views and give the first one focus.
   2665   ActiveWidget widget;
   2666   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
   2667   params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
   2668   widget.Init(params);
   2669 
   2670   View* view1 = new View();
   2671   view1->SetFocusable(true);
   2672   widget.GetRootView()->AddChildView(view1);
   2673   View* view2 = new View();
   2674   view2->SetFocusable(true);
   2675   widget.GetRootView()->AddChildView(view2);
   2676 
   2677   FocusManager* focus_manager = widget.GetFocusManager();
   2678   ASSERT_TRUE(focus_manager);
   2679 
   2680   focus_manager->SetFocusedView(view1);
   2681   EXPECT_EQ(view1, focus_manager->GetFocusedView());
   2682 
   2683   // Disable the focused view and check if the next view gets focused.
   2684   view1->SetEnabled(false);
   2685   EXPECT_EQ(view2, focus_manager->GetFocusedView());
   2686 
   2687   // Re-enable and re-focus.
   2688   view1->SetEnabled(true);
   2689   focus_manager->SetFocusedView(view1);
   2690   EXPECT_EQ(view1, focus_manager->GetFocusedView());
   2691 
   2692   // Hide the focused view and check it the next view gets focused.
   2693   view1->SetVisible(false);
   2694   EXPECT_EQ(view2, focus_manager->GetFocusedView());
   2695 
   2696   // Re-show and re-focus.
   2697   view1->SetVisible(true);
   2698   focus_manager->SetFocusedView(view1);
   2699   EXPECT_EQ(view1, focus_manager->GetFocusedView());
   2700 
   2701   // Set the focused view as not focusable and check if the next view gets
   2702   // focused.
   2703   view1->SetFocusable(false);
   2704   EXPECT_EQ(view2, focus_manager->GetFocusedView());
   2705 }
   2706 
   2707 ////////////////////////////////////////////////////////////////////////////////
   2708 // Layers
   2709 ////////////////////////////////////////////////////////////////////////////////
   2710 
   2711 namespace {
   2712 
   2713 // Test implementation of LayerAnimator.
   2714 class TestLayerAnimator : public ui::LayerAnimator {
   2715  public:
   2716   TestLayerAnimator();
   2717 
   2718   const gfx::Rect& last_bounds() const { return last_bounds_; }
   2719 
   2720   // LayerAnimator.
   2721   virtual void SetBounds(const gfx::Rect& bounds) OVERRIDE;
   2722 
   2723  protected:
   2724   virtual ~TestLayerAnimator() { }
   2725 
   2726  private:
   2727   gfx::Rect last_bounds_;
   2728 
   2729   DISALLOW_COPY_AND_ASSIGN(TestLayerAnimator);
   2730 };
   2731 
   2732 TestLayerAnimator::TestLayerAnimator()
   2733     : ui::LayerAnimator(base::TimeDelta::FromMilliseconds(0)) {
   2734 }
   2735 
   2736 void TestLayerAnimator::SetBounds(const gfx::Rect& bounds) {
   2737   last_bounds_ = bounds;
   2738 }
   2739 
   2740 }  // namespace
   2741 
   2742 class ViewLayerTest : public ViewsTestBase {
   2743  public:
   2744   ViewLayerTest() : widget_(NULL) {}
   2745 
   2746   virtual ~ViewLayerTest() {
   2747   }
   2748 
   2749   // Returns the Layer used by the RootView.
   2750   ui::Layer* GetRootLayer() {
   2751     return widget()->GetLayer();
   2752   }
   2753 
   2754   virtual void SetUp() OVERRIDE {
   2755     ViewTest::SetUp();
   2756     widget_ = new Widget;
   2757     Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
   2758     params.bounds = gfx::Rect(50, 50, 200, 200);
   2759     widget_->Init(params);
   2760     widget_->Show();
   2761     widget_->GetRootView()->SetBounds(0, 0, 200, 200);
   2762   }
   2763 
   2764   virtual void TearDown() OVERRIDE {
   2765     widget_->CloseNow();
   2766     ViewsTestBase::TearDown();
   2767   }
   2768 
   2769   Widget* widget() { return widget_; }
   2770 
   2771  private:
   2772   Widget* widget_;
   2773 };
   2774 
   2775 
   2776 TEST_F(ViewLayerTest, LayerToggling) {
   2777   // Because we lazily create textures the calls to DrawTree are necessary to
   2778   // ensure we trigger creation of textures.
   2779   ui::Layer* root_layer = widget()->GetLayer();
   2780   View* content_view = new View;
   2781   widget()->SetContentsView(content_view);
   2782 
   2783   // Create v1, give it a bounds and verify everything is set up correctly.
   2784   View* v1 = new View;
   2785   v1->SetPaintToLayer(true);
   2786   EXPECT_TRUE(v1->layer() != NULL);
   2787   v1->SetBoundsRect(gfx::Rect(20, 30, 140, 150));
   2788   content_view->AddChildView(v1);
   2789   ASSERT_TRUE(v1->layer() != NULL);
   2790   EXPECT_EQ(root_layer, v1->layer()->parent());
   2791   EXPECT_EQ(gfx::Rect(20, 30, 140, 150), v1->layer()->bounds());
   2792 
   2793   // Create v2 as a child of v1 and do basic assertion testing.
   2794   View* v2 = new View;
   2795   v1->AddChildView(v2);
   2796   EXPECT_TRUE(v2->layer() == NULL);
   2797   v2->SetBoundsRect(gfx::Rect(10, 20, 30, 40));
   2798   v2->SetPaintToLayer(true);
   2799   ASSERT_TRUE(v2->layer() != NULL);
   2800   EXPECT_EQ(v1->layer(), v2->layer()->parent());
   2801   EXPECT_EQ(gfx::Rect(10, 20, 30, 40), v2->layer()->bounds());
   2802 
   2803   // Turn off v1s layer. v2 should still have a layer but its parent should have
   2804   // changed.
   2805   v1->SetPaintToLayer(false);
   2806   EXPECT_TRUE(v1->layer() == NULL);
   2807   EXPECT_TRUE(v2->layer() != NULL);
   2808   EXPECT_EQ(root_layer, v2->layer()->parent());
   2809   ASSERT_EQ(1u, root_layer->children().size());
   2810   EXPECT_EQ(root_layer->children()[0], v2->layer());
   2811   // The bounds of the layer should have changed to be relative to the root view
   2812   // now.
   2813   EXPECT_EQ(gfx::Rect(30, 50, 30, 40), v2->layer()->bounds());
   2814 
   2815   // Make v1 have a layer again and verify v2s layer is wired up correctly.
   2816   gfx::Transform transform;
   2817   transform.Scale(2.0, 2.0);
   2818   v1->SetTransform(transform);
   2819   EXPECT_TRUE(v1->layer() != NULL);
   2820   EXPECT_TRUE(v2->layer() != NULL);
   2821   EXPECT_EQ(root_layer, v1->layer()->parent());
   2822   EXPECT_EQ(v1->layer(), v2->layer()->parent());
   2823   ASSERT_EQ(1u, root_layer->children().size());
   2824   EXPECT_EQ(root_layer->children()[0], v1->layer());
   2825   ASSERT_EQ(1u, v1->layer()->children().size());
   2826   EXPECT_EQ(v1->layer()->children()[0], v2->layer());
   2827   EXPECT_EQ(gfx::Rect(10, 20, 30, 40), v2->layer()->bounds());
   2828 }
   2829 
   2830 // Verifies turning on a layer wires up children correctly.
   2831 TEST_F(ViewLayerTest, NestedLayerToggling) {
   2832   View* content_view = new View;
   2833   widget()->SetContentsView(content_view);
   2834 
   2835   // Create v1, give it a bounds and verify everything is set up correctly.
   2836   View* v1 = new View;
   2837   content_view->AddChildView(v1);
   2838   v1->SetBoundsRect(gfx::Rect(20, 30, 140, 150));
   2839 
   2840   View* v2 = new View;
   2841   v1->AddChildView(v2);
   2842 
   2843   View* v3 = new View;
   2844   v3->SetPaintToLayer(true);
   2845   v2->AddChildView(v3);
   2846   ASSERT_TRUE(v3->layer() != NULL);
   2847 
   2848   // At this point we have v1-v2-v3. v3 has a layer, v1 and v2 don't.
   2849 
   2850   v1->SetPaintToLayer(true);
   2851   EXPECT_EQ(v1->layer(), v3->layer()->parent());
   2852 }
   2853 
   2854 TEST_F(ViewLayerTest, LayerAnimator) {
   2855   View* content_view = new View;
   2856   widget()->SetContentsView(content_view);
   2857 
   2858   View* v1 = new View;
   2859   content_view->AddChildView(v1);
   2860   v1->SetPaintToLayer(true);
   2861   EXPECT_TRUE(v1->layer() != NULL);
   2862 
   2863   TestLayerAnimator* animator = new TestLayerAnimator();
   2864   v1->layer()->SetAnimator(animator);
   2865 
   2866   gfx::Rect bounds(1, 2, 3, 4);
   2867   v1->SetBoundsRect(bounds);
   2868   EXPECT_EQ(bounds, animator->last_bounds());
   2869   // TestLayerAnimator doesn't update the layer.
   2870   EXPECT_NE(bounds, v1->layer()->bounds());
   2871 }
   2872 
   2873 // Verifies the bounds of a layer are updated if the bounds of ancestor that
   2874 // doesn't have a layer change.
   2875 TEST_F(ViewLayerTest, BoundsChangeWithLayer) {
   2876   View* content_view = new View;
   2877   widget()->SetContentsView(content_view);
   2878 
   2879   View* v1 = new View;
   2880   content_view->AddChildView(v1);
   2881   v1->SetBoundsRect(gfx::Rect(20, 30, 140, 150));
   2882 
   2883   View* v2 = new View;
   2884   v2->SetBoundsRect(gfx::Rect(10, 11, 40, 50));
   2885   v1->AddChildView(v2);
   2886   v2->SetPaintToLayer(true);
   2887   ASSERT_TRUE(v2->layer() != NULL);
   2888   EXPECT_EQ(gfx::Rect(30, 41, 40, 50), v2->layer()->bounds());
   2889 
   2890   v1->SetPosition(gfx::Point(25, 36));
   2891   EXPECT_EQ(gfx::Rect(35, 47, 40, 50), v2->layer()->bounds());
   2892 
   2893   v2->SetPosition(gfx::Point(11, 12));
   2894   EXPECT_EQ(gfx::Rect(36, 48, 40, 50), v2->layer()->bounds());
   2895 
   2896   // Bounds of the layer should change even if the view is not invisible.
   2897   v1->SetVisible(false);
   2898   v1->SetPosition(gfx::Point(20, 30));
   2899   EXPECT_EQ(gfx::Rect(31, 42, 40, 50), v2->layer()->bounds());
   2900 
   2901   v2->SetVisible(false);
   2902   v2->SetBoundsRect(gfx::Rect(10, 11, 20, 30));
   2903   EXPECT_EQ(gfx::Rect(30, 41, 20, 30), v2->layer()->bounds());
   2904 }
   2905 
   2906 // Make sure layers are positioned correctly in RTL.
   2907 TEST_F(ViewLayerTest, BoundInRTL) {
   2908   std::string locale = l10n_util::GetApplicationLocale(std::string());
   2909   base::i18n::SetICUDefaultLocale("he");
   2910 
   2911   View* view = new View;
   2912   widget()->SetContentsView(view);
   2913 
   2914   int content_width = view->width();
   2915 
   2916   // |v1| is initially not attached to anything. So its layer will have the same
   2917   // bounds as the view.
   2918   View* v1 = new View;
   2919   v1->SetPaintToLayer(true);
   2920   v1->SetBounds(10, 10, 20, 10);
   2921   EXPECT_EQ(gfx::Rect(10, 10, 20, 10),
   2922             v1->layer()->bounds());
   2923 
   2924   // Once |v1| is attached to the widget, its layer will get RTL-appropriate
   2925   // bounds.
   2926   view->AddChildView(v1);
   2927   EXPECT_EQ(gfx::Rect(content_width - 30, 10, 20, 10),
   2928             v1->layer()->bounds());
   2929   gfx::Rect l1bounds = v1->layer()->bounds();
   2930 
   2931   // Now attach a View to the widget first, then create a layer for it. Make
   2932   // sure the bounds are correct.
   2933   View* v2 = new View;
   2934   v2->SetBounds(50, 10, 30, 10);
   2935   EXPECT_FALSE(v2->layer());
   2936   view->AddChildView(v2);
   2937   v2->SetPaintToLayer(true);
   2938   EXPECT_EQ(gfx::Rect(content_width - 80, 10, 30, 10),
   2939             v2->layer()->bounds());
   2940   gfx::Rect l2bounds = v2->layer()->bounds();
   2941 
   2942   view->SetPaintToLayer(true);
   2943   EXPECT_EQ(l1bounds, v1->layer()->bounds());
   2944   EXPECT_EQ(l2bounds, v2->layer()->bounds());
   2945 
   2946   // Move one of the views. Make sure the layer is positioned correctly
   2947   // afterwards.
   2948   v1->SetBounds(v1->x() - 5, v1->y(), v1->width(), v1->height());
   2949   l1bounds.set_x(l1bounds.x() + 5);
   2950   EXPECT_EQ(l1bounds, v1->layer()->bounds());
   2951 
   2952   view->SetPaintToLayer(false);
   2953   EXPECT_EQ(l1bounds, v1->layer()->bounds());
   2954   EXPECT_EQ(l2bounds, v2->layer()->bounds());
   2955 
   2956   // Move a view again.
   2957   v2->SetBounds(v2->x() + 5, v2->y(), v2->width(), v2->height());
   2958   l2bounds.set_x(l2bounds.x() - 5);
   2959   EXPECT_EQ(l2bounds, v2->layer()->bounds());
   2960 
   2961   // Reset locale.
   2962   base::i18n::SetICUDefaultLocale(locale);
   2963 }
   2964 
   2965 // Makes sure a transform persists after toggling the visibility.
   2966 TEST_F(ViewLayerTest, ToggleVisibilityWithTransform) {
   2967   View* view = new View;
   2968   gfx::Transform transform;
   2969   transform.Scale(2.0, 2.0);
   2970   view->SetTransform(transform);
   2971   widget()->SetContentsView(view);
   2972   EXPECT_EQ(2.0f, view->GetTransform().matrix().get(0, 0));
   2973 
   2974   view->SetVisible(false);
   2975   EXPECT_EQ(2.0f, view->GetTransform().matrix().get(0, 0));
   2976 
   2977   view->SetVisible(true);
   2978   EXPECT_EQ(2.0f, view->GetTransform().matrix().get(0, 0));
   2979 }
   2980 
   2981 // Verifies a transform persists after removing/adding a view with a transform.
   2982 TEST_F(ViewLayerTest, ResetTransformOnLayerAfterAdd) {
   2983   View* view = new View;
   2984   gfx::Transform transform;
   2985   transform.Scale(2.0, 2.0);
   2986   view->SetTransform(transform);
   2987   widget()->SetContentsView(view);
   2988   EXPECT_EQ(2.0f, view->GetTransform().matrix().get(0, 0));
   2989   ASSERT_TRUE(view->layer() != NULL);
   2990   EXPECT_EQ(2.0f, view->layer()->transform().matrix().get(0, 0));
   2991 
   2992   View* parent = view->parent();
   2993   parent->RemoveChildView(view);
   2994   parent->AddChildView(view);
   2995 
   2996   EXPECT_EQ(2.0f, view->GetTransform().matrix().get(0, 0));
   2997   ASSERT_TRUE(view->layer() != NULL);
   2998   EXPECT_EQ(2.0f, view->layer()->transform().matrix().get(0, 0));
   2999 }
   3000 
   3001 // Makes sure that layer visibility is correct after toggling View visibility.
   3002 TEST_F(ViewLayerTest, ToggleVisibilityWithLayer) {
   3003   View* content_view = new View;
   3004   widget()->SetContentsView(content_view);
   3005 
   3006   // The view isn't attached to a widget or a parent view yet. But it should
   3007   // still have a layer, but the layer should not be attached to the root
   3008   // layer.
   3009   View* v1 = new View;
   3010   v1->SetPaintToLayer(true);
   3011   EXPECT_TRUE(v1->layer());
   3012   EXPECT_FALSE(LayerIsAncestor(widget()->GetCompositor()->root_layer(),
   3013                                v1->layer()));
   3014 
   3015   // Once the view is attached to a widget, its layer should be attached to the
   3016   // root layer and visible.
   3017   content_view->AddChildView(v1);
   3018   EXPECT_TRUE(LayerIsAncestor(widget()->GetCompositor()->root_layer(),
   3019                               v1->layer()));
   3020   EXPECT_TRUE(v1->layer()->IsDrawn());
   3021 
   3022   v1->SetVisible(false);
   3023   EXPECT_FALSE(v1->layer()->IsDrawn());
   3024 
   3025   v1->SetVisible(true);
   3026   EXPECT_TRUE(v1->layer()->IsDrawn());
   3027 
   3028   widget()->Hide();
   3029   EXPECT_FALSE(v1->layer()->IsDrawn());
   3030 
   3031   widget()->Show();
   3032   EXPECT_TRUE(v1->layer()->IsDrawn());
   3033 }
   3034 
   3035 // Tests that the layers in the subtree are orphaned after a View is removed
   3036 // from the parent.
   3037 TEST_F(ViewLayerTest, OrphanLayerAfterViewRemove) {
   3038   View* content_view = new View;
   3039   widget()->SetContentsView(content_view);
   3040 
   3041   View* v1 = new View;
   3042   content_view->AddChildView(v1);
   3043 
   3044   View* v2 = new View;
   3045   v1->AddChildView(v2);
   3046   v2->SetPaintToLayer(true);
   3047   EXPECT_TRUE(LayerIsAncestor(widget()->GetCompositor()->root_layer(),
   3048                               v2->layer()));
   3049   EXPECT_TRUE(v2->layer()->IsDrawn());
   3050 
   3051   content_view->RemoveChildView(v1);
   3052 
   3053   EXPECT_FALSE(LayerIsAncestor(widget()->GetCompositor()->root_layer(),
   3054                                v2->layer()));
   3055 
   3056   // Reparent |v2|.
   3057   content_view->AddChildView(v2);
   3058   delete v1;
   3059   v1 = NULL;
   3060   EXPECT_TRUE(LayerIsAncestor(widget()->GetCompositor()->root_layer(),
   3061                               v2->layer()));
   3062   EXPECT_TRUE(v2->layer()->IsDrawn());
   3063 }
   3064 
   3065 class PaintTrackingView : public View {
   3066  public:
   3067   PaintTrackingView() : painted_(false) {
   3068   }
   3069 
   3070   bool painted() const { return painted_; }
   3071   void set_painted(bool value) { painted_ = value; }
   3072 
   3073   virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
   3074     painted_ = true;
   3075   }
   3076 
   3077  private:
   3078   bool painted_;
   3079 
   3080   DISALLOW_COPY_AND_ASSIGN(PaintTrackingView);
   3081 };
   3082 
   3083 // Makes sure child views with layers aren't painted when paint starts at an
   3084 // ancestor.
   3085 TEST_F(ViewLayerTest, DontPaintChildrenWithLayers) {
   3086   PaintTrackingView* content_view = new PaintTrackingView;
   3087   widget()->SetContentsView(content_view);
   3088   content_view->SetPaintToLayer(true);
   3089   GetRootLayer()->GetCompositor()->ScheduleDraw();
   3090   ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
   3091   GetRootLayer()->SchedulePaint(gfx::Rect(0, 0, 10, 10));
   3092   content_view->set_painted(false);
   3093   // content_view no longer has a dirty rect. Paint from the root and make sure
   3094   // PaintTrackingView isn't painted.
   3095   GetRootLayer()->GetCompositor()->ScheduleDraw();
   3096   ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
   3097   EXPECT_FALSE(content_view->painted());
   3098 
   3099   // Make content_view have a dirty rect, paint the layers and make sure
   3100   // PaintTrackingView is painted.
   3101   content_view->layer()->SchedulePaint(gfx::Rect(0, 0, 10, 10));
   3102   GetRootLayer()->GetCompositor()->ScheduleDraw();
   3103   ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
   3104   EXPECT_TRUE(content_view->painted());
   3105 }
   3106 
   3107 // Tests that the visibility of child layers are updated correctly when a View's
   3108 // visibility changes.
   3109 TEST_F(ViewLayerTest, VisibilityChildLayers) {
   3110   View* v1 = new View;
   3111   v1->SetPaintToLayer(true);
   3112   widget()->SetContentsView(v1);
   3113 
   3114   View* v2 = new View;
   3115   v1->AddChildView(v2);
   3116 
   3117   View* v3 = new View;
   3118   v2->AddChildView(v3);
   3119   v3->SetVisible(false);
   3120 
   3121   View* v4 = new View;
   3122   v4->SetPaintToLayer(true);
   3123   v3->AddChildView(v4);
   3124 
   3125   EXPECT_TRUE(v1->layer()->IsDrawn());
   3126   EXPECT_FALSE(v4->layer()->IsDrawn());
   3127 
   3128   v2->SetVisible(false);
   3129   EXPECT_TRUE(v1->layer()->IsDrawn());
   3130   EXPECT_FALSE(v4->layer()->IsDrawn());
   3131 
   3132   v2->SetVisible(true);
   3133   EXPECT_TRUE(v1->layer()->IsDrawn());
   3134   EXPECT_FALSE(v4->layer()->IsDrawn());
   3135 
   3136   v2->SetVisible(false);
   3137   EXPECT_TRUE(v1->layer()->IsDrawn());
   3138   EXPECT_FALSE(v4->layer()->IsDrawn());
   3139   EXPECT_TRUE(ViewAndLayerTreeAreConsistent(v1, v1->layer()));
   3140 
   3141   v3->SetVisible(true);
   3142   EXPECT_TRUE(v1->layer()->IsDrawn());
   3143   EXPECT_FALSE(v4->layer()->IsDrawn());
   3144   EXPECT_TRUE(ViewAndLayerTreeAreConsistent(v1, v1->layer()));
   3145 
   3146   // Reparent |v3| to |v1|.
   3147   v1->AddChildView(v3);
   3148   EXPECT_TRUE(v1->layer()->IsDrawn());
   3149   EXPECT_TRUE(v4->layer()->IsDrawn());
   3150   EXPECT_TRUE(ViewAndLayerTreeAreConsistent(v1, v1->layer()));
   3151 }
   3152 
   3153 // This test creates a random View tree, and then randomly reorders child views,
   3154 // reparents views etc. Unrelated changes can appear to break this test. So
   3155 // marking this as FLAKY.
   3156 TEST_F(ViewLayerTest, DISABLED_ViewLayerTreesInSync) {
   3157   View* content = new View;
   3158   content->SetPaintToLayer(true);
   3159   widget()->SetContentsView(content);
   3160   widget()->Show();
   3161 
   3162   ConstructTree(content, 5);
   3163   EXPECT_TRUE(ViewAndLayerTreeAreConsistent(content, content->layer()));
   3164 
   3165   ScrambleTree(content);
   3166   EXPECT_TRUE(ViewAndLayerTreeAreConsistent(content, content->layer()));
   3167 
   3168   ScrambleTree(content);
   3169   EXPECT_TRUE(ViewAndLayerTreeAreConsistent(content, content->layer()));
   3170 
   3171   ScrambleTree(content);
   3172   EXPECT_TRUE(ViewAndLayerTreeAreConsistent(content, content->layer()));
   3173 }
   3174 
   3175 // Verifies when views are reordered the layer is also reordered. The widget is
   3176 // providing the parent layer.
   3177 TEST_F(ViewLayerTest, ReorderUnderWidget) {
   3178   View* content = new View;
   3179   widget()->SetContentsView(content);
   3180   View* c1 = new View;
   3181   c1->SetPaintToLayer(true);
   3182   content->AddChildView(c1);
   3183   View* c2 = new View;
   3184   c2->SetPaintToLayer(true);
   3185   content->AddChildView(c2);
   3186 
   3187   ui::Layer* parent_layer = c1->layer()->parent();
   3188   ASSERT_TRUE(parent_layer);
   3189   ASSERT_EQ(2u, parent_layer->children().size());
   3190   EXPECT_EQ(c1->layer(), parent_layer->children()[0]);
   3191   EXPECT_EQ(c2->layer(), parent_layer->children()[1]);
   3192 
   3193   // Move c1 to the front. The layers should have moved too.
   3194   content->ReorderChildView(c1, -1);
   3195   EXPECT_EQ(c1->layer(), parent_layer->children()[1]);
   3196   EXPECT_EQ(c2->layer(), parent_layer->children()[0]);
   3197 }
   3198 
   3199 // Verifies that the layer of a view can be acquired properly.
   3200 TEST_F(ViewLayerTest, AcquireLayer) {
   3201   View* content = new View;
   3202   widget()->SetContentsView(content);
   3203   scoped_ptr<View> c1(new View);
   3204   c1->SetPaintToLayer(true);
   3205   EXPECT_TRUE(c1->layer());
   3206   content->AddChildView(c1.get());
   3207 
   3208   scoped_ptr<ui::Layer> layer(c1->AcquireLayer());
   3209   EXPECT_EQ(layer.get(), c1->layer());
   3210 
   3211   scoped_ptr<ui::Layer> layer2(c1->RecreateLayer());
   3212   EXPECT_NE(c1->layer(), layer2.get());
   3213 
   3214   // Destroy view before destroying layer.
   3215   c1.reset();
   3216 }
   3217 
   3218 // Verify the z-order of the layers as a result of calling RecreateLayer().
   3219 TEST_F(ViewLayerTest, RecreateLayerZOrder) {
   3220   scoped_ptr<View> v(new View());
   3221   v->SetPaintToLayer(true);
   3222 
   3223   View* v1 = new View();
   3224   v1->SetPaintToLayer(true);
   3225   v->AddChildView(v1);
   3226   View* v2 = new View();
   3227   v2->SetPaintToLayer(true);
   3228   v->AddChildView(v2);
   3229 
   3230   // Test the initial z-order.
   3231   const std::vector<ui::Layer*>& child_layers_pre = v->layer()->children();
   3232   ASSERT_EQ(2u, child_layers_pre.size());
   3233   EXPECT_EQ(v1->layer(), child_layers_pre[0]);
   3234   EXPECT_EQ(v2->layer(), child_layers_pre[1]);
   3235 
   3236   scoped_ptr<ui::Layer> v1_old_layer(v1->RecreateLayer());
   3237 
   3238   // Test the new layer order. We expect: |v1| |v1_old_layer| |v2|.
   3239   // for |v1| and |v2|.
   3240   const std::vector<ui::Layer*>& child_layers_post = v->layer()->children();
   3241   ASSERT_EQ(3u, child_layers_post.size());
   3242   EXPECT_EQ(v1->layer(), child_layers_post[0]);
   3243   EXPECT_EQ(v1_old_layer, child_layers_post[1]);
   3244   EXPECT_EQ(v2->layer(), child_layers_post[2]);
   3245 }
   3246 
   3247 // Verify the z-order of the layers as a result of calling RecreateLayer when
   3248 // the widget is the parent with the layer.
   3249 TEST_F(ViewLayerTest, RecreateLayerZOrderWidgetParent) {
   3250   View* v = new View();
   3251   widget()->SetContentsView(v);
   3252 
   3253   View* v1 = new View();
   3254   v1->SetPaintToLayer(true);
   3255   v->AddChildView(v1);
   3256   View* v2 = new View();
   3257   v2->SetPaintToLayer(true);
   3258   v->AddChildView(v2);
   3259 
   3260   ui::Layer* root_layer = GetRootLayer();
   3261 
   3262   // Test the initial z-order.
   3263   const std::vector<ui::Layer*>& child_layers_pre = root_layer->children();
   3264   ASSERT_EQ(2u, child_layers_pre.size());
   3265   EXPECT_EQ(v1->layer(), child_layers_pre[0]);
   3266   EXPECT_EQ(v2->layer(), child_layers_pre[1]);
   3267 
   3268   scoped_ptr<ui::Layer> v1_old_layer(v1->RecreateLayer());
   3269 
   3270   // Test the new layer order. We expect: |v1| |v1_old_layer| |v2|.
   3271   const std::vector<ui::Layer*>& child_layers_post = root_layer->children();
   3272   ASSERT_EQ(3u, child_layers_post.size());
   3273   EXPECT_EQ(v1->layer(), child_layers_post[0]);
   3274   EXPECT_EQ(v1_old_layer, child_layers_post[1]);
   3275   EXPECT_EQ(v2->layer(), child_layers_post[2]);
   3276 }
   3277 
   3278 // Verifies RecreateLayer() moves all Layers over, even those that don't have
   3279 // a View.
   3280 TEST_F(ViewLayerTest, RecreateLayerMovesNonViewChildren) {
   3281   View v;
   3282   v.SetPaintToLayer(true);
   3283   View child;
   3284   child.SetPaintToLayer(true);
   3285   v.AddChildView(&child);
   3286   ASSERT_TRUE(v.layer() != NULL);
   3287   ASSERT_EQ(1u, v.layer()->children().size());
   3288   EXPECT_EQ(v.layer()->children()[0], child.layer());
   3289 
   3290   ui::Layer layer(ui::LAYER_NOT_DRAWN);
   3291   v.layer()->Add(&layer);
   3292   v.layer()->StackAtBottom(&layer);
   3293 
   3294   scoped_ptr<ui::Layer> old_layer(v.RecreateLayer());
   3295 
   3296   // All children should be moved from old layer to new layer.
   3297   ASSERT_TRUE(old_layer.get() != NULL);
   3298   EXPECT_TRUE(old_layer->children().empty());
   3299 
   3300   // And new layer should have the two children.
   3301   ASSERT_TRUE(v.layer() != NULL);
   3302   ASSERT_EQ(2u, v.layer()->children().size());
   3303   EXPECT_EQ(v.layer()->children()[0], &layer);
   3304   EXPECT_EQ(v.layer()->children()[1], child.layer());
   3305 }
   3306 
   3307 class BoundsTreeTestView : public View {
   3308  public:
   3309   BoundsTreeTestView() {}
   3310 
   3311   virtual void PaintChildren(gfx::Canvas* canvas,
   3312                              const CullSet& cull_set) OVERRIDE {
   3313     // Save out a copy of the cull_set before calling the base implementation.
   3314     last_cull_set_.clear();
   3315     if (cull_set.cull_set_) {
   3316       for (base::hash_set<intptr_t>::iterator it = cull_set.cull_set_->begin();
   3317            it != cull_set.cull_set_->end();
   3318            ++it) {
   3319         last_cull_set_.insert(reinterpret_cast<View*>(*it));
   3320       }
   3321     }
   3322     View::PaintChildren(canvas, cull_set);
   3323   }
   3324 
   3325   std::set<View*> last_cull_set_;
   3326 };
   3327 
   3328 TEST_F(ViewLayerTest, BoundsTreePaintUpdatesCullSet) {
   3329   BoundsTreeTestView* test_view = new BoundsTreeTestView;
   3330   widget()->SetContentsView(test_view);
   3331 
   3332   View* v1 = new View();
   3333   v1->SetBoundsRect(gfx::Rect(10, 15, 150, 151));
   3334   test_view->AddChildView(v1);
   3335 
   3336   View* v2 = new View();
   3337   v2->SetBoundsRect(gfx::Rect(20, 33, 40, 50));
   3338   v1->AddChildView(v2);
   3339 
   3340   // Schedule a full-view paint to get everyone's rectangles updated.
   3341   test_view->SchedulePaintInRect(test_view->bounds());
   3342   GetRootLayer()->GetCompositor()->ScheduleDraw();
   3343   ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
   3344 
   3345   // Now we have test_view - v1 - v2. Damage to only test_view should only
   3346   // return root_view and test_view.
   3347   test_view->SchedulePaintInRect(gfx::Rect(0, 0, 1, 1));
   3348   GetRootLayer()->GetCompositor()->ScheduleDraw();
   3349   ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
   3350   EXPECT_EQ(2U, test_view->last_cull_set_.size());
   3351   EXPECT_EQ(1U, test_view->last_cull_set_.count(widget()->GetRootView()));
   3352   EXPECT_EQ(1U, test_view->last_cull_set_.count(test_view));
   3353 
   3354   // Damage to v1 only should only return root_view, test_view, and v1.
   3355   test_view->SchedulePaintInRect(gfx::Rect(11, 16, 1, 1));
   3356   GetRootLayer()->GetCompositor()->ScheduleDraw();
   3357   ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
   3358   EXPECT_EQ(3U, test_view->last_cull_set_.size());
   3359   EXPECT_EQ(1U, test_view->last_cull_set_.count(widget()->GetRootView()));
   3360   EXPECT_EQ(1U, test_view->last_cull_set_.count(test_view));
   3361   EXPECT_EQ(1U, test_view->last_cull_set_.count(v1));
   3362 
   3363   // A Damage rect inside v2 should get all 3 views back in the |last_cull_set_|
   3364   // on call to TestView::Paint(), along with the widget root view.
   3365   test_view->SchedulePaintInRect(gfx::Rect(31, 49, 1, 1));
   3366   GetRootLayer()->GetCompositor()->ScheduleDraw();
   3367   ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
   3368   EXPECT_EQ(4U, test_view->last_cull_set_.size());
   3369   EXPECT_EQ(1U, test_view->last_cull_set_.count(widget()->GetRootView()));
   3370   EXPECT_EQ(1U, test_view->last_cull_set_.count(test_view));
   3371   EXPECT_EQ(1U, test_view->last_cull_set_.count(v1));
   3372   EXPECT_EQ(1U, test_view->last_cull_set_.count(v2));
   3373 }
   3374 
   3375 TEST_F(ViewLayerTest, BoundsTreeWithRTL) {
   3376   std::string locale = l10n_util::GetApplicationLocale(std::string());
   3377   base::i18n::SetICUDefaultLocale("ar");
   3378 
   3379   BoundsTreeTestView* test_view = new BoundsTreeTestView;
   3380   widget()->SetContentsView(test_view);
   3381 
   3382   // Add child views, which should be in RTL coordinate space of parent view.
   3383   View* v1 = new View;
   3384   v1->SetBoundsRect(gfx::Rect(10, 12, 25, 26));
   3385   test_view->AddChildView(v1);
   3386 
   3387   View* v2 = new View;
   3388   v2->SetBoundsRect(gfx::Rect(5, 6, 7, 8));
   3389   v1->AddChildView(v2);
   3390 
   3391   // Schedule a full-view paint to get everyone's rectangles updated.
   3392   test_view->SchedulePaintInRect(test_view->bounds());
   3393   GetRootLayer()->GetCompositor()->ScheduleDraw();
   3394   ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
   3395 
   3396   // Damage to the right side of the parent view should touch both child views.
   3397   gfx::Rect rtl_damage(test_view->bounds().width() - 16, 18, 1, 1);
   3398   test_view->SchedulePaintInRect(rtl_damage);
   3399   GetRootLayer()->GetCompositor()->ScheduleDraw();
   3400   ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
   3401   EXPECT_EQ(4U, test_view->last_cull_set_.size());
   3402   EXPECT_EQ(1U, test_view->last_cull_set_.count(widget()->GetRootView()));
   3403   EXPECT_EQ(1U, test_view->last_cull_set_.count(test_view));
   3404   EXPECT_EQ(1U, test_view->last_cull_set_.count(v1));
   3405   EXPECT_EQ(1U, test_view->last_cull_set_.count(v2));
   3406 
   3407   // Damage to the left side of the parent view should only touch the
   3408   // container views.
   3409   gfx::Rect ltr_damage(16, 18, 1, 1);
   3410   test_view->SchedulePaintInRect(ltr_damage);
   3411   GetRootLayer()->GetCompositor()->ScheduleDraw();
   3412   ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
   3413   EXPECT_EQ(2U, test_view->last_cull_set_.size());
   3414   EXPECT_EQ(1U, test_view->last_cull_set_.count(widget()->GetRootView()));
   3415   EXPECT_EQ(1U, test_view->last_cull_set_.count(test_view));
   3416 
   3417   // Reset locale.
   3418   base::i18n::SetICUDefaultLocale(locale);
   3419 }
   3420 
   3421 TEST_F(ViewLayerTest, BoundsTreeSetBoundsChangesCullSet) {
   3422   BoundsTreeTestView* test_view = new BoundsTreeTestView;
   3423   widget()->SetContentsView(test_view);
   3424 
   3425   View* v1 = new View;
   3426   v1->SetBoundsRect(gfx::Rect(5, 6, 100, 101));
   3427   test_view->AddChildView(v1);
   3428 
   3429   View* v2 = new View;
   3430   v2->SetBoundsRect(gfx::Rect(20, 33, 40, 50));
   3431   v1->AddChildView(v2);
   3432 
   3433   // Schedule a full-view paint to get everyone's rectangles updated.
   3434   test_view->SchedulePaintInRect(test_view->bounds());
   3435   GetRootLayer()->GetCompositor()->ScheduleDraw();
   3436   ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
   3437 
   3438   // Move v1 to a new origin out of the way of our next query.
   3439   v1->SetBoundsRect(gfx::Rect(50, 60, 100, 101));
   3440   // The move will force a repaint.
   3441   GetRootLayer()->GetCompositor()->ScheduleDraw();
   3442   ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
   3443 
   3444   // Schedule a paint with damage rect where v1 used to be.
   3445   test_view->SchedulePaintInRect(gfx::Rect(5, 6, 10, 11));
   3446   GetRootLayer()->GetCompositor()->ScheduleDraw();
   3447   ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
   3448 
   3449   // Should only have picked up root_view and test_view.
   3450   EXPECT_EQ(2U, test_view->last_cull_set_.size());
   3451   EXPECT_EQ(1U, test_view->last_cull_set_.count(widget()->GetRootView()));
   3452   EXPECT_EQ(1U, test_view->last_cull_set_.count(test_view));
   3453 }
   3454 
   3455 TEST_F(ViewLayerTest, BoundsTreeLayerChangeMakesNewTree) {
   3456   BoundsTreeTestView* test_view = new BoundsTreeTestView;
   3457   widget()->SetContentsView(test_view);
   3458 
   3459   View* v1 = new View;
   3460   v1->SetBoundsRect(gfx::Rect(5, 10, 15, 20));
   3461   test_view->AddChildView(v1);
   3462 
   3463   View* v2 = new View;
   3464   v2->SetBoundsRect(gfx::Rect(1, 2, 3, 4));
   3465   v1->AddChildView(v2);
   3466 
   3467   // Schedule a full-view paint to get everyone's rectangles updated.
   3468   test_view->SchedulePaintInRect(test_view->bounds());
   3469   GetRootLayer()->GetCompositor()->ScheduleDraw();
   3470   ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
   3471 
   3472   // Set v1 to paint to its own layer, it should remove itself from the
   3473   // test_view heiarchy and no longer intersect with damage rects in that cull
   3474   // set.
   3475   v1->SetPaintToLayer(true);
   3476 
   3477   // Schedule another full-view paint.
   3478   test_view->SchedulePaintInRect(test_view->bounds());
   3479   GetRootLayer()->GetCompositor()->ScheduleDraw();
   3480   ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
   3481   // v1 and v2 should no longer be present in the test_view cull_set.
   3482   EXPECT_EQ(2U, test_view->last_cull_set_.size());
   3483   EXPECT_EQ(0U, test_view->last_cull_set_.count(v1));
   3484   EXPECT_EQ(0U, test_view->last_cull_set_.count(v2));
   3485 
   3486   // Now set v1 back to not painting to a layer.
   3487   v1->SetPaintToLayer(false);
   3488   // Schedule another full-view paint.
   3489   test_view->SchedulePaintInRect(test_view->bounds());
   3490   GetRootLayer()->GetCompositor()->ScheduleDraw();
   3491   ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
   3492   // We should be back to the full cull set including v1 and v2.
   3493   EXPECT_EQ(4U, test_view->last_cull_set_.size());
   3494   EXPECT_EQ(1U, test_view->last_cull_set_.count(widget()->GetRootView()));
   3495   EXPECT_EQ(1U, test_view->last_cull_set_.count(test_view));
   3496   EXPECT_EQ(1U, test_view->last_cull_set_.count(v1));
   3497   EXPECT_EQ(1U, test_view->last_cull_set_.count(v2));
   3498 }
   3499 
   3500 TEST_F(ViewLayerTest, BoundsTreeRemoveChildRemovesBounds) {
   3501   BoundsTreeTestView* test_view = new BoundsTreeTestView;
   3502   widget()->SetContentsView(test_view);
   3503 
   3504   View* v1 = new View;
   3505   v1->SetBoundsRect(gfx::Rect(5, 10, 15, 20));
   3506   test_view->AddChildView(v1);
   3507 
   3508   View* v2 = new View;
   3509   v2->SetBoundsRect(gfx::Rect(1, 2, 3, 4));
   3510   v1->AddChildView(v2);
   3511 
   3512   // Schedule a full-view paint to get everyone's rectangles updated.
   3513   test_view->SchedulePaintInRect(test_view->bounds());
   3514   GetRootLayer()->GetCompositor()->ScheduleDraw();
   3515   ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
   3516 
   3517   // Now remove v1 from the root view.
   3518   test_view->RemoveChildView(v1);
   3519 
   3520   // Schedule another full-view paint.
   3521   test_view->SchedulePaintInRect(test_view->bounds());
   3522   GetRootLayer()->GetCompositor()->ScheduleDraw();
   3523   ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
   3524   // v1 and v2 should no longer be present in the test_view cull_set.
   3525   EXPECT_EQ(2U, test_view->last_cull_set_.size());
   3526   EXPECT_EQ(0U, test_view->last_cull_set_.count(v1));
   3527   EXPECT_EQ(0U, test_view->last_cull_set_.count(v2));
   3528 
   3529   // View v1 and v2 are no longer part of view hierarchy and therefore won't be
   3530   // deleted with that hierarchy.
   3531   delete v1;
   3532 }
   3533 
   3534 TEST_F(ViewLayerTest, BoundsTreeMoveViewMovesBounds) {
   3535   BoundsTreeTestView* test_view = new BoundsTreeTestView;
   3536   widget()->SetContentsView(test_view);
   3537 
   3538   // Build hierarchy v1 - v2 - v3.
   3539   View* v1 = new View;
   3540   v1->SetBoundsRect(gfx::Rect(20, 30, 150, 160));
   3541   test_view->AddChildView(v1);
   3542 
   3543   View* v2 = new View;
   3544   v2->SetBoundsRect(gfx::Rect(5, 10, 40, 50));
   3545   v1->AddChildView(v2);
   3546 
   3547   View* v3 = new View;
   3548   v3->SetBoundsRect(gfx::Rect(1, 2, 3, 4));
   3549   v2->AddChildView(v3);
   3550 
   3551   // Schedule a full-view paint and ensure all views are present in the cull.
   3552   test_view->SchedulePaintInRect(test_view->bounds());
   3553   GetRootLayer()->GetCompositor()->ScheduleDraw();
   3554   ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
   3555   EXPECT_EQ(5U, test_view->last_cull_set_.size());
   3556   EXPECT_EQ(1U, test_view->last_cull_set_.count(widget()->GetRootView()));
   3557   EXPECT_EQ(1U, test_view->last_cull_set_.count(test_view));
   3558   EXPECT_EQ(1U, test_view->last_cull_set_.count(v1));
   3559   EXPECT_EQ(1U, test_view->last_cull_set_.count(v2));
   3560   EXPECT_EQ(1U, test_view->last_cull_set_.count(v3));
   3561 
   3562   // Build an unrelated view hierarchy and move v2 in to it.
   3563   scoped_ptr<Widget> test_widget(new Widget);
   3564   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
   3565   params.bounds = gfx::Rect(10, 10, 500, 500);
   3566   params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
   3567   test_widget->Init(params);
   3568   test_widget->Show();
   3569   BoundsTreeTestView* widget_view = new BoundsTreeTestView;
   3570   test_widget->SetContentsView(widget_view);
   3571   widget_view->AddChildView(v2);
   3572 
   3573   // Now schedule full-view paints in both widgets.
   3574   test_view->SchedulePaintInRect(test_view->bounds());
   3575   widget_view->SchedulePaintInRect(widget_view->bounds());
   3576   GetRootLayer()->GetCompositor()->ScheduleDraw();
   3577   ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
   3578 
   3579   // Only v1 should be present in the first cull set.
   3580   EXPECT_EQ(3U, test_view->last_cull_set_.size());
   3581   EXPECT_EQ(1U, test_view->last_cull_set_.count(widget()->GetRootView()));
   3582   EXPECT_EQ(1U, test_view->last_cull_set_.count(test_view));
   3583   EXPECT_EQ(1U, test_view->last_cull_set_.count(v1));
   3584 
   3585   // We should find v2 and v3 in the widget_view cull_set.
   3586   EXPECT_EQ(4U, widget_view->last_cull_set_.size());
   3587   EXPECT_EQ(1U, widget_view->last_cull_set_.count(test_widget->GetRootView()));
   3588   EXPECT_EQ(1U, widget_view->last_cull_set_.count(widget_view));
   3589   EXPECT_EQ(1U, widget_view->last_cull_set_.count(v2));
   3590   EXPECT_EQ(1U, widget_view->last_cull_set_.count(v3));
   3591 }
   3592 
   3593 namespace {
   3594 
   3595 std::string ToString(const gfx::Vector2dF& vector) {
   3596   return base::StringPrintf("%.2f %0.2f", vector.x(), vector.y());
   3597 }
   3598 
   3599 }  // namespace
   3600 
   3601 TEST_F(ViewLayerTest, SnapLayerToPixel) {
   3602   View* v1 = new View;
   3603 
   3604   View* v11 = new View;
   3605   v1->AddChildView(v11);
   3606 
   3607   widget()->SetContentsView(v1);
   3608 
   3609   const gfx::Size& size = GetRootLayer()->GetCompositor()->size();
   3610   GetRootLayer()->GetCompositor()->SetScaleAndSize(1.25f, size);
   3611 
   3612   v11->SetBoundsRect(gfx::Rect(1, 1, 10, 10));
   3613   v1->SetBoundsRect(gfx::Rect(1, 1, 10, 10));
   3614   v11->SetPaintToLayer(true);
   3615 
   3616   EXPECT_EQ("0.40 0.40", ToString(v11->layer()->subpixel_position_offset()));
   3617 
   3618   // Creating a layer in parent should update the child view's layer offset.
   3619   v1->SetPaintToLayer(true);
   3620   EXPECT_EQ("-0.20 -0.20", ToString(v1->layer()->subpixel_position_offset()));
   3621   EXPECT_EQ("-0.20 -0.20", ToString(v11->layer()->subpixel_position_offset()));
   3622 
   3623   // DSF change should get propagated and update offsets.
   3624   GetRootLayer()->GetCompositor()->SetScaleAndSize(1.5f, size);
   3625   EXPECT_EQ("0.33 0.33", ToString(v1->layer()->subpixel_position_offset()));
   3626   EXPECT_EQ("0.33 0.33", ToString(v11->layer()->subpixel_position_offset()));
   3627 
   3628   // Deleting parent's layer should update the child view's layer's offset.
   3629   v1->SetPaintToLayer(false);
   3630   EXPECT_EQ("0.00 0.00", ToString(v11->layer()->subpixel_position_offset()));
   3631 
   3632   // Setting parent view should update the child view's layer's offset.
   3633   v1->SetBoundsRect(gfx::Rect(2, 2, 10, 10));
   3634   EXPECT_EQ("0.33 0.33", ToString(v11->layer()->subpixel_position_offset()));
   3635 
   3636   // Setting integral DSF should reset the offset.
   3637   GetRootLayer()->GetCompositor()->SetScaleAndSize(2.0f, size);
   3638   EXPECT_EQ("0.00 0.00", ToString(v11->layer()->subpixel_position_offset()));
   3639 }
   3640 
   3641 TEST_F(ViewTest, FocusableAssertions) {
   3642   // View subclasses may change insets based on whether they are focusable,
   3643   // which effects the preferred size. To avoid preferred size changing around
   3644   // these Views need to key off the last value set to SetFocusable(), not
   3645   // whether the View is focusable right now. For this reason it's important
   3646   // that focusable() return the last value passed to SetFocusable and not
   3647   // whether the View is focusable right now.
   3648   TestView view;
   3649   view.SetFocusable(true);
   3650   EXPECT_TRUE(view.focusable());
   3651   view.SetEnabled(false);
   3652   EXPECT_TRUE(view.focusable());
   3653   view.SetFocusable(false);
   3654   EXPECT_FALSE(view.focusable());
   3655 }
   3656 
   3657 // Verifies when a view is deleted it is removed from ViewStorage.
   3658 TEST_F(ViewTest, UpdateViewStorageOnDelete) {
   3659   ViewStorage* view_storage = ViewStorage::GetInstance();
   3660   const int storage_id = view_storage->CreateStorageID();
   3661   {
   3662     View view;
   3663     view_storage->StoreView(storage_id, &view);
   3664   }
   3665   EXPECT_TRUE(view_storage->RetrieveView(storage_id) == NULL);
   3666 }
   3667 
   3668 ////////////////////////////////////////////////////////////////////////////////
   3669 // NativeTheme
   3670 ////////////////////////////////////////////////////////////////////////////////
   3671 
   3672 void TestView::OnNativeThemeChanged(const ui::NativeTheme* native_theme) {
   3673   native_theme_ = native_theme;
   3674 }
   3675 
   3676 TEST_F(ViewTest, OnNativeThemeChanged) {
   3677   TestView* test_view = new TestView();
   3678   EXPECT_FALSE(test_view->native_theme_);
   3679   TestView* test_view_child = new TestView();
   3680   EXPECT_FALSE(test_view_child->native_theme_);
   3681 
   3682   // Child view added before the widget hierarchy exists should get the
   3683   // new native theme notification.
   3684   test_view->AddChildView(test_view_child);
   3685 
   3686   scoped_ptr<Widget> widget(new Widget);
   3687   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
   3688   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
   3689   widget->Init(params);
   3690 
   3691   widget->GetRootView()->AddChildView(test_view);
   3692   EXPECT_TRUE(test_view->native_theme_);
   3693   EXPECT_EQ(widget->GetNativeTheme(), test_view->native_theme_);
   3694   EXPECT_TRUE(test_view_child->native_theme_);
   3695   EXPECT_EQ(widget->GetNativeTheme(), test_view_child->native_theme_);
   3696 
   3697   // Child view added after the widget hierarchy exists should also get the
   3698   // notification.
   3699   TestView* test_view_child_2 = new TestView();
   3700   test_view->AddChildView(test_view_child_2);
   3701   EXPECT_TRUE(test_view_child_2->native_theme_);
   3702   EXPECT_EQ(widget->GetNativeTheme(), test_view_child_2->native_theme_);
   3703 
   3704   widget->CloseNow();
   3705 }
   3706 
   3707 }  // namespace views
   3708