Home | History | Annotate | Download | only in launcher
      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 "ash/launcher/launcher_tooltip_manager.h"
      6 
      7 #include "ash/root_window_controller.h"
      8 #include "ash/shelf/shelf_layout_manager.h"
      9 #include "ash/shelf/shelf_widget.h"
     10 #include "ash/shell.h"
     11 #include "ash/shell_window_ids.h"
     12 #include "ash/test/ash_test_base.h"
     13 #include "ash/wm/window_util.h"
     14 #include "base/strings/string16.h"
     15 #include "base/time/time.h"
     16 #include "ui/aura/root_window.h"
     17 #include "ui/base/events/event.h"
     18 #include "ui/base/events/event_constants.h"
     19 #include "ui/base/events/event_handler.h"
     20 #include "ui/base/keycodes/keyboard_codes.h"
     21 #include "ui/views/widget/widget.h"
     22 
     23 namespace {
     24 
     25 void SetEventTarget(ui::EventTarget* target,
     26                     ui::Event* event) {
     27   ui::Event::DispatcherApi dispatch_helper(event);
     28   dispatch_helper.set_target(target);
     29 }
     30 
     31 }
     32 
     33 namespace ash {
     34 namespace test {
     35 
     36 class LauncherTooltipManagerTest : public AshTestBase {
     37  public:
     38   LauncherTooltipManagerTest() {}
     39   virtual ~LauncherTooltipManagerTest() {}
     40 
     41   virtual void SetUp() OVERRIDE {
     42     AshTestBase::SetUp();
     43     internal::RootWindowController* controller =
     44         Shell::GetPrimaryRootWindowController();
     45     tooltip_manager_.reset(new internal::LauncherTooltipManager(
     46         controller->GetShelfLayoutManager(),
     47         controller->shelf()->launcher()->GetLauncherViewForTest()));
     48   }
     49 
     50   virtual void TearDown() OVERRIDE {
     51     tooltip_manager_.reset();
     52     AshTestBase::TearDown();
     53   }
     54 
     55   void ShowDelayed() {
     56     CreateWidget();
     57     tooltip_manager_->ShowDelayed(dummy_anchor_.get(), base::string16());
     58   }
     59 
     60   void ShowImmediately() {
     61     CreateWidget();
     62     tooltip_manager_->ShowImmediately(dummy_anchor_.get(), base::string16());
     63   }
     64 
     65   bool TooltipIsVisible() {
     66     return tooltip_manager_->IsVisible();
     67   }
     68 
     69   bool IsTimerRunning() {
     70     return tooltip_manager_->timer_.get() != NULL;
     71   }
     72 
     73   ui::EventHandler* GetEventHandler() {
     74     return tooltip_manager_.get();
     75   }
     76 
     77   views::Widget* GetTooltipWidget() {
     78     return tooltip_manager_->widget_;
     79   }
     80 
     81  protected:
     82   scoped_ptr<views::Widget> widget_;
     83   scoped_ptr<views::View> dummy_anchor_;
     84   scoped_ptr<internal::LauncherTooltipManager> tooltip_manager_;
     85 
     86  private:
     87   void CreateWidget() {
     88     dummy_anchor_.reset(new views::View);
     89 
     90     widget_.reset(new views::Widget);
     91     views::Widget::InitParams params(
     92         views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
     93     params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
     94     params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
     95     params.parent = Shell::GetContainer(
     96         Shell::GetPrimaryRootWindow(),
     97         ash::internal::kShellWindowId_ShelfContainer);
     98 
     99     widget_->Init(params);
    100     widget_->SetContentsView(dummy_anchor_.get());
    101   }
    102 
    103   DISALLOW_COPY_AND_ASSIGN(LauncherTooltipManagerTest);
    104 };
    105 
    106 TEST_F(LauncherTooltipManagerTest, ShowingBasics) {
    107   // ShowDelayed() should just start the timer instead of showing immediately.
    108   ShowDelayed();
    109   EXPECT_FALSE(TooltipIsVisible());
    110   EXPECT_TRUE(IsTimerRunning());
    111 
    112   ShowImmediately();
    113   EXPECT_TRUE(TooltipIsVisible());
    114   EXPECT_FALSE(IsTimerRunning());
    115 }
    116 
    117 TEST_F(LauncherTooltipManagerTest, HideWhenShelfIsHidden) {
    118   ShowImmediately();
    119   ASSERT_TRUE(TooltipIsVisible());
    120 
    121   // Create a full-screen window to hide the shelf.
    122   scoped_ptr<views::Widget> widget(new views::Widget);
    123   views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
    124   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
    125   params.context = CurrentContext();
    126   widget->Init(params);
    127   widget->SetFullscreen(true);
    128   widget->Show();
    129 
    130   // Once the shelf is hidden, the tooltip should be invisible.
    131   ASSERT_EQ(
    132       SHELF_HIDDEN,
    133       Shell::GetPrimaryRootWindowController()->
    134           GetShelfLayoutManager()->visibility_state());
    135   EXPECT_FALSE(TooltipIsVisible());
    136 
    137   // Do not show the view if the shelf is hidden.
    138   ShowImmediately();
    139   EXPECT_FALSE(TooltipIsVisible());
    140 
    141   // ShowDelayed() doesn't even start the timer for the hidden shelf.
    142   ShowDelayed();
    143   EXPECT_FALSE(IsTimerRunning());
    144 }
    145 
    146 TEST_F(LauncherTooltipManagerTest, HideWhenShelfIsAutoHide) {
    147   // Create a visible window so auto-hide behavior is enforced.
    148   views::Widget* dummy = new views::Widget;
    149   views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
    150   params.bounds = gfx::Rect(0, 0, 200, 200);
    151   params.context = CurrentContext();
    152   dummy->Init(params);
    153   dummy->Show();
    154 
    155   ShowImmediately();
    156   ASSERT_TRUE(TooltipIsVisible());
    157 
    158   internal::ShelfLayoutManager* shelf =
    159       Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager();
    160   shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
    161   shelf->UpdateAutoHideState();
    162   ASSERT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state());
    163 
    164   // Tooltip visibility change for auto hide may take time.
    165   EXPECT_TRUE(TooltipIsVisible());
    166   RunAllPendingInMessageLoop();
    167   EXPECT_FALSE(TooltipIsVisible());
    168 
    169   // Do not show the view if the shelf is hidden.
    170   ShowImmediately();
    171   EXPECT_FALSE(TooltipIsVisible());
    172 
    173   // ShowDelayed doesn't even run the timer for the hidden shelf.
    174   ShowDelayed();
    175   EXPECT_FALSE(IsTimerRunning());
    176 }
    177 
    178 TEST_F(LauncherTooltipManagerTest, ShouldHideForEvents) {
    179   ShowImmediately();
    180   ASSERT_TRUE(TooltipIsVisible());
    181 
    182   aura::RootWindow* root_window = Shell::GetInstance()->GetPrimaryRootWindow();
    183   ui::EventHandler* event_handler = GetEventHandler();
    184 
    185   // Should not hide for key events.
    186   ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::EF_NONE, false);
    187   SetEventTarget(root_window, &key_event);
    188   event_handler->OnKeyEvent(&key_event);
    189   EXPECT_FALSE(key_event.handled());
    190   EXPECT_TRUE(TooltipIsVisible());
    191 
    192   // Should hide for touch events.
    193   ui::TouchEvent touch_event(
    194       ui::ET_TOUCH_PRESSED, gfx::Point(), 0, base::TimeDelta());
    195   SetEventTarget(root_window, &touch_event);
    196   event_handler->OnTouchEvent(&touch_event);
    197   EXPECT_FALSE(touch_event.handled());
    198   EXPECT_FALSE(TooltipIsVisible());
    199 
    200   // Shouldn't hide if the touch happens on the tooltip.
    201   ShowImmediately();
    202   views::Widget* tooltip_widget = GetTooltipWidget();
    203   SetEventTarget(tooltip_widget->GetNativeWindow(), &touch_event);
    204   event_handler->OnTouchEvent(&touch_event);
    205   EXPECT_FALSE(touch_event.handled());
    206   EXPECT_TRUE(TooltipIsVisible());
    207 
    208   // Should hide for gesture events.
    209   ui::GestureEvent gesture_event(
    210       ui::ET_GESTURE_BEGIN, 0, 0, ui::EF_NONE,
    211       base::TimeDelta::FromMilliseconds(base::Time::Now().ToDoubleT() * 1000),
    212       ui::GestureEventDetails(ui::ET_GESTURE_BEGIN, 0.0f, 0.0f), 0);
    213   SetEventTarget(tooltip_widget->GetNativeWindow(), &gesture_event);
    214   event_handler->OnGestureEvent(&gesture_event);
    215   EXPECT_FALSE(gesture_event.handled());
    216   RunAllPendingInMessageLoop();
    217   EXPECT_FALSE(TooltipIsVisible());
    218 }
    219 
    220 TEST_F(LauncherTooltipManagerTest, HideForMouseEvent) {
    221   ShowImmediately();
    222   ASSERT_TRUE(TooltipIsVisible());
    223 
    224   aura::RootWindow* root_window = Shell::GetInstance()->GetPrimaryRootWindow();
    225   ui::EventHandler* event_handler = GetEventHandler();
    226 
    227   gfx::Rect tooltip_rect = GetTooltipWidget()->GetNativeWindow()->bounds();
    228   ASSERT_FALSE(tooltip_rect.IsEmpty());
    229 
    230   // Shouldn't hide if the mouse is in the tooltip.
    231   ui::MouseEvent mouse_event(ui::ET_MOUSE_MOVED, tooltip_rect.CenterPoint(),
    232                              tooltip_rect.CenterPoint(), ui::EF_NONE);
    233   ui::LocatedEvent::TestApi test_api(&mouse_event);
    234 
    235   SetEventTarget(root_window, &mouse_event);
    236   event_handler->OnMouseEvent(&mouse_event);
    237   EXPECT_FALSE(mouse_event.handled());
    238   EXPECT_TRUE(TooltipIsVisible());
    239 
    240   // Should hide if the mouse is out of the tooltip.
    241   test_api.set_location(tooltip_rect.origin() + gfx::Vector2d(-1, -1));
    242   event_handler->OnMouseEvent(&mouse_event);
    243   EXPECT_FALSE(mouse_event.handled());
    244   RunAllPendingInMessageLoop();
    245   EXPECT_FALSE(TooltipIsVisible());
    246 }
    247 
    248 }  // namespace test
    249 }  // namespace ash
    250