1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file.
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/wm/immersive_fullscreen_controller.h"
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/display/display_manager.h"
8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ash/display/mouse_cursor_event_filter.h"
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/root_window_controller.h"
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/shelf/shelf_layout_manager.h"
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/shelf/shelf_types.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/shell.h"
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/test/ash_test_base.h"
1446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ash/wm/window_state.h"
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/aura/client/aura_constants.h"
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/aura/client/cursor_client.h"
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/aura/env.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/aura/test/test_window_delegate.h"
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/aura/window.h"
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h"
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/events/event_utils.h"
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/events/test/event_generator.h"
2323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ui/events/test/test_event_handler.h"
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/gfx/animation/slide_animation.h"
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/views/bubble/bubble_delegate.h"
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/views/controls/native/native_view_host.h"
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/views/view.h"
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/views/widget/widget.h"
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace ash {
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace {
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class MockImmersiveFullscreenControllerDelegate
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    : public ImmersiveFullscreenController::Delegate {
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  MockImmersiveFullscreenControllerDelegate(views::View* top_container_view)
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      : top_container_view_(top_container_view),
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        enabled_(false),
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        visible_fraction_(1) {
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~MockImmersiveFullscreenControllerDelegate() {}
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // ImmersiveFullscreenController::Delegate overrides:
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void OnImmersiveRevealStarted() OVERRIDE {
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    enabled_ = true;
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    visible_fraction_ = 0;
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void OnImmersiveRevealEnded() OVERRIDE {
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    visible_fraction_ = 0;
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void OnImmersiveFullscreenExited() OVERRIDE {
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    enabled_ = false;
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    visible_fraction_ = 1;
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void SetVisibleFraction(double visible_fraction) OVERRIDE {
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    visible_fraction_ = visible_fraction;
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual std::vector<gfx::Rect> GetVisibleBoundsInScreen() const OVERRIDE {
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    std::vector<gfx::Rect> bounds_in_screen;
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bounds_in_screen.push_back(top_container_view_->GetBoundsInScreen());
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return bounds_in_screen;
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool is_enabled() const {
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return enabled_;
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  double visible_fraction() const {
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return visible_fraction_;
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private:
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  views::View* top_container_view_;
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool enabled_;
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  double visible_fraction_;
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MockImmersiveFullscreenControllerDelegate);
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
8123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)class ConsumeEventHandler : public ui::test::TestEventHandler {
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ConsumeEventHandler() {}
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~ConsumeEventHandler() {}
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void OnEvent(ui::Event* event) OVERRIDE {
8823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    ui::test::TestEventHandler::OnEvent(event);
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (event->cancelable())
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      event->SetHandled();
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ConsumeEventHandler);
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/////////////////////////////////////////////////////////////////////////////
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class ImmersiveFullscreenControllerTest : public ash::test::AshTestBase {
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  enum Modality {
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    MODALITY_MOUSE,
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MODALITY_GESTURE_TAP,
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MODALITY_GESTURE_SCROLL
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  };
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ImmersiveFullscreenControllerTest()
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : widget_(NULL),
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        top_container_(NULL),
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        content_view_(NULL) {}
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~ImmersiveFullscreenControllerTest() {}
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ImmersiveFullscreenController* controller() {
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return controller_.get();
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  views::NativeViewHost* content_view() {
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return content_view_;
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  views::View* top_container() {
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return top_container_;
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  views::Widget* widget() { return widget_; }
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  aura::Window* window() {
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return widget_->GetNativeWindow();
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  MockImmersiveFullscreenControllerDelegate* delegate() {
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return delegate_.get();
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Access to private data from the controller.
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool top_edge_hover_timer_running() const {
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return controller_->top_edge_hover_timer_.IsRunning();
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int mouse_x_when_hit_top() const {
141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return controller_->mouse_x_when_hit_top_in_screen_;
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // ash::test::AshTestBase overrides:
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ash::test::AshTestBase::SetUp();
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    widget_ = new views::Widget();
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    views::Widget::InitParams params;
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    params.context = CurrentContext();
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    widget_->Init(params);
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    widget_->Show();
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    window()->SetProperty(aura::client::kShowStateKey,
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          ui::SHOW_STATE_FULLSCREEN);
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    gfx::Size window_size = widget_->GetWindowBoundsInScreen().size();
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    content_view_ = new views::NativeViewHost();
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    content_view_->SetBounds(0, 0, window_size.width(), window_size.height());
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    widget_->GetContentsView()->AddChildView(content_view_);
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    top_container_ = new views::View();
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    top_container_->SetBounds(
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        0, 0, window_size.width(), 100);
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    top_container_->SetFocusable(true);
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    widget_->GetContentsView()->AddChildView(top_container_);
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    delegate_.reset(
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new MockImmersiveFullscreenControllerDelegate(top_container_));
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    controller_.reset(new ImmersiveFullscreenController);
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    controller_->Init(delegate_.get(), widget_, top_container_);
172a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    controller_->SetupForTest();
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // The mouse is moved so that it is not over |top_container_| by
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // AshTestBase.
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Enables / disables immersive fullscreen.
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void SetEnabled(bool enabled) {
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    controller_->SetEnabled(ImmersiveFullscreenController::WINDOW_TYPE_OTHER,
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            enabled);
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Attempt to reveal the top-of-window views via |modality|.
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The top-of-window views can only be revealed via mouse hover or a gesture.
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void AttemptReveal(Modality modality) {
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_NE(modality, MODALITY_GESTURE_TAP);
188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    AttemptRevealStateChange(true, modality);
189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Attempt to unreveal the top-of-window views via |modality|. The
192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // top-of-window views can be unrevealed via any modality.
193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void AttemptUnreveal(Modality modality) {
194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    AttemptRevealStateChange(false, modality);
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Sets whether the mouse is hovered above |top_container_|.
198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // SetHovered(true) moves the mouse over the |top_container_| but does not
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // move it to the top of the screen so will not initiate a reveal.
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void SetHovered(bool is_mouse_hovered) {
201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    MoveMouse(0, is_mouse_hovered ? 10 : top_container_->height() + 100);
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Move the mouse to the given coordinates. The coordinates should be in
205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // |top_container_| coordinates.
206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void MoveMouse(int x, int y) {
207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    gfx::Point screen_position(x, y);
208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    views::View::ConvertPointToScreen(top_container_, &screen_position);
209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    GetEventGenerator().MoveMouseTo(screen_position.x(), screen_position.y());
210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // If the top edge timer started running as a result of the mouse move, run
212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // the task which occurs after the timer delay. This reveals the
213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // top-of-window views synchronously if the mouse is hovered at the top of
214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // the screen.
215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (controller()->top_edge_hover_timer_.IsRunning()) {
216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      controller()->top_edge_hover_timer_.user_task().Run();
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      controller()->top_edge_hover_timer_.Stop();
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private:
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Attempt to change the revealed state to |revealed| via |modality|.
223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void AttemptRevealStateChange(bool revealed, Modality modality) {
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Compute the event position in |top_container_| coordinates.
225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    gfx::Point event_position(0, revealed ? 0 : top_container_->height() + 100);
226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    switch (modality) {
227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      case MODALITY_MOUSE: {
228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        MoveMouse(event_position.x(), event_position.y());
229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        break;
230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      }
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case MODALITY_GESTURE_TAP: {
232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        gfx::Point screen_position = event_position;
233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        views::View::ConvertPointToScreen(top_container_, &screen_position);
2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        ui::test::EventGenerator& event_generator(GetEventGenerator());
235f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        event_generator.MoveTouch(event_position);
236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        event_generator.PressTouch();
237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        event_generator.ReleaseTouch();
238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        break;
239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      }
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case MODALITY_GESTURE_SCROLL: {
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        gfx::Point start(0, revealed ? 0 : top_container_->height() - 2);
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        gfx::Vector2d scroll_delta(0, 40);
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        gfx::Point end = revealed ? start + scroll_delta : start - scroll_delta;
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        views::View::ConvertPointToScreen(top_container_, &start);
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        views::View::ConvertPointToScreen(top_container_, &end);
2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        ui::test::EventGenerator& event_generator(GetEventGenerator());
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        event_generator.GestureScrollSequence(
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            start, end,
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            base::TimeDelta::FromMilliseconds(30), 1);
250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        break;
251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      }
252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<ImmersiveFullscreenController> controller_;
256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<MockImmersiveFullscreenControllerDelegate> delegate_;
257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  views::Widget* widget_;  // Owned by the native widget.
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  views::View* top_container_;  // Owned by |widget_|'s root-view.
2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  views::NativeViewHost* content_view_;  // Owned by |widget_|'s root-view.
260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ImmersiveFullscreenControllerTest);
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Test the initial state and that the delegate gets notified of the
265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// top-of-window views getting hidden and revealed.
266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(ImmersiveFullscreenControllerTest, Delegate) {
267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Initial state.
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsEnabled());
269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(delegate()->is_enabled());
271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Enabling initially hides the top views.
2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(true);
274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsEnabled());
275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(delegate()->is_enabled());
277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(0, delegate()->visible_fraction());
278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Revealing shows the top views.
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AttemptReveal(MODALITY_MOUSE);
281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsEnabled());
282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(delegate()->is_enabled());
284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(1, delegate()->visible_fraction());
285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Disabling ends the immersive reveal.
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(false);
288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsEnabled());
289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(delegate()->is_enabled());
291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// GetRevealedLock() specific tests.
294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(ImmersiveFullscreenControllerTest, RevealedLock) {
295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<ImmersiveRevealedLock> lock1;
296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<ImmersiveRevealedLock> lock2;
297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Immersive fullscreen is not on by default.
299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsEnabled());
300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // 1) Test acquiring and releasing a revealed state lock while immersive
302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // fullscreen is disabled. Acquiring or releasing the lock should have no
303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // effect till immersive fullscreen is enabled.
304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  lock1.reset(controller()->GetRevealedLock(
305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      ImmersiveFullscreenController::ANIMATE_REVEAL_NO));
306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsEnabled());
307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Immersive fullscreen should start in the revealed state due to the lock.
3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(true);
311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsEnabled());
312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(false);
315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsEnabled());
316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  lock1.reset();
319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsEnabled());
320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
322f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Immersive fullscreen should start in the closed state because the lock is
323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // no longer held.
3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(true);
325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsEnabled());
326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // 2) Test that acquiring a lock reveals the top-of-window views if they are
329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // hidden.
330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  lock1.reset(controller()->GetRevealedLock(
331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      ImmersiveFullscreenController::ANIMATE_REVEAL_NO));
332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // 3) Test that the top-of-window views are only hidden when all of the locks
335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // are released.
336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  lock2.reset(controller()->GetRevealedLock(
337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      ImmersiveFullscreenController::ANIMATE_REVEAL_NO));
338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  lock1.reset();
339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  lock2.reset();
342f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
343f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Test mouse event processing for top-of-screen reveal triggering.
346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(ImmersiveFullscreenControllerTest, OnMouseEvent) {
347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Set up initial state.
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(true);
349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(controller()->IsEnabled());
350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_FALSE(controller()->IsRevealed());
351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::test::EventGenerator& event_generator(GetEventGenerator());
353f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  gfx::Rect top_container_bounds_in_screen =
355f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      top_container()->GetBoundsInScreen();
356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // A position along the top edge of TopContainerView in screen coordinates.
357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  gfx::Point top_edge_pos(top_container_bounds_in_screen.x() + 100,
358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          top_container_bounds_in_screen.y());
359f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
360f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Mouse wheel event does nothing.
361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ui::MouseEvent wheel(
3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ui::ET_MOUSEWHEEL, top_edge_pos, top_edge_pos, ui::EF_NONE, ui::EF_NONE);
363f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  event_generator.Dispatch(&wheel);
364f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(top_edge_hover_timer_running());
365f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
366f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Move to top edge of screen starts hover timer running. We cannot use
367f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // MoveMouse() because MoveMouse() stops the timer if it started running.
368f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  event_generator.MoveMouseTo(top_edge_pos);
369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(top_edge_hover_timer_running());
370f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(top_edge_pos.x(), mouse_x_when_hit_top());
371f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
372f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Moving |ImmersiveFullscreenControllerTest::kMouseRevealBoundsHeight| down
373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // from the top edge stops it.
374a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  event_generator.MoveMouseBy(0,
375a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      ImmersiveFullscreenController::kMouseRevealBoundsHeight);
376f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(top_edge_hover_timer_running());
377f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
378f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Moving back to the top starts the timer again.
379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  event_generator.MoveMouseTo(top_edge_pos);
380f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(top_edge_hover_timer_running());
381f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(top_edge_pos.x(), mouse_x_when_hit_top());
382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
383f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Slight move to the right keeps the timer running for the same hit point.
384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  event_generator.MoveMouseBy(1, 0);
385f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(top_edge_hover_timer_running());
386f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(top_edge_pos.x(), mouse_x_when_hit_top());
387f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
388f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Moving back to the left also keeps the timer running.
389f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  event_generator.MoveMouseBy(-1, 0);
390f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(top_edge_hover_timer_running());
391f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(top_edge_pos.x(), mouse_x_when_hit_top());
392f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
393f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Large move right restarts the timer (so it is still running) and considers
394f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // this a new hit at the top.
395f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  event_generator.MoveMouseTo(top_edge_pos.x() + 100, top_edge_pos.y());
396f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(top_edge_hover_timer_running());
397f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(top_edge_pos.x() + 100, mouse_x_when_hit_top());
398f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Moving off the top edge horizontally stops the timer.
400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  event_generator.MoveMouseTo(top_container_bounds_in_screen.right() + 1,
401f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              top_container_bounds_in_screen.y());
402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(top_edge_hover_timer_running());
403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Once revealed, a move just a little below the top container doesn't end a
405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // reveal.
406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AttemptReveal(MODALITY_MOUSE);
407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  event_generator.MoveMouseTo(top_container_bounds_in_screen.x(),
408f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              top_container_bounds_in_screen.bottom() + 1);
409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Once revealed, clicking just below the top container ends the reveal.
412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  event_generator.ClickLeftButton();
413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Moving a lot below the top container ends a reveal.
416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AttemptReveal(MODALITY_MOUSE);
417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  event_generator.MoveMouseTo(top_container_bounds_in_screen.x(),
419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              top_container_bounds_in_screen.bottom() + 50);
420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
422a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // The mouse position cannot cause a reveal when the top container's widget
423f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // has capture.
424f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  views::Widget* widget = top_container()->GetWidget();
425f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  widget->SetCapture(top_container());
426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AttemptReveal(MODALITY_MOUSE);
427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
428f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  widget->ReleaseCapture();
429f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
430a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // The mouse position cannot end the reveal while the top container's widget
431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // has capture.
432f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AttemptReveal(MODALITY_MOUSE);
433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
434f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  widget->SetCapture(top_container());
435f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  event_generator.MoveMouseTo(top_container_bounds_in_screen.x(),
436f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              top_container_bounds_in_screen.bottom() + 51);
437f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
438f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
439f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Releasing capture should end the reveal.
440f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  widget->ReleaseCapture();
441f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
442f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
443f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
444a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Test mouse event processing for top-of-screen reveal triggering when the
445a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// top container's widget is inactive.
446a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(ImmersiveFullscreenControllerTest, Inactive) {
447a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Set up initial state.
448a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  views::Widget* popup_widget = views::Widget::CreateWindowWithContextAndBounds(
449a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      NULL,
450a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      CurrentContext(),
451a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gfx::Rect(0, 0, 200, 200));
452a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  popup_widget->Show();
453a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_FALSE(top_container()->GetWidget()->IsActive());
454a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(true);
456a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(controller()->IsEnabled());
457a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_FALSE(controller()->IsRevealed());
458a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
459a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  gfx::Rect top_container_bounds_in_screen =
460a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      top_container()->GetBoundsInScreen();
461a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  gfx::Rect popup_bounds_in_screen = popup_widget->GetWindowBoundsInScreen();
462a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(top_container_bounds_in_screen.origin().ToString(),
463a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            popup_bounds_in_screen.origin().ToString());
464a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_GT(top_container_bounds_in_screen.right(),
465a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            popup_bounds_in_screen.right());
466a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
467a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // The top-of-window views should stay hidden if the cursor is at the top edge
468a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // but above an obscured portion of the top-of-window views.
469a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MoveMouse(popup_bounds_in_screen.x(),
470a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            top_container_bounds_in_screen.y());
471a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
472a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
473a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // The top-of-window views should reveal if the cursor is at the top edge and
474a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // above an unobscured portion of the top-of-window views.
475a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MoveMouse(top_container_bounds_in_screen.right() - 1,
476a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            top_container_bounds_in_screen.y());
477a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
478a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
479a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // The top-of-window views should stay revealed if the cursor is moved off
480a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // of the top edge.
481a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MoveMouse(top_container_bounds_in_screen.right() - 1,
482a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            top_container_bounds_in_screen.bottom() - 1);
483a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
484a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
485a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Moving way off of the top-of-window views should end the immersive reveal.
486a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MoveMouse(top_container_bounds_in_screen.right() - 1,
487a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            top_container_bounds_in_screen.bottom() + 50);
488a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
489a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
490a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Moving way off of the top-of-window views in a region where the
491a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // top-of-window views are obscured should also end the immersive reveal.
492a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Ideally, the immersive reveal would end immediately when the cursor moves
493a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // to an obscured portion of the top-of-window views.
494a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MoveMouse(top_container_bounds_in_screen.right() - 1,
495a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            top_container_bounds_in_screen.y());
496a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
497a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MoveMouse(top_container_bounds_in_screen.x(),
498a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            top_container_bounds_in_screen.bottom() + 50);
499a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
500a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
501a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
502f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Test mouse event processing for top-of-screen reveal triggering when the user
503f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// has a vertical display layout (primary display above/below secondary display)
504f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// and the immersive fullscreen window is on the bottom display.
505f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(ImmersiveFullscreenControllerTest, MouseEventsVerticalDisplayLayout) {
506f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!SupportsMultipleDisplays())
507f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
508f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
509f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Set up initial state.
510f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  UpdateDisplay("800x600,800x600");
511f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ash::DisplayLayout display_layout(ash::DisplayLayout::TOP, 0);
512f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ash::Shell::GetInstance()->display_manager()->SetLayoutForCurrentDisplays(
513f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      display_layout);
514f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(true);
516f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(controller()->IsEnabled());
517f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_FALSE(controller()->IsRevealed());
518f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
519f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  aura::Window::Windows root_windows = ash::Shell::GetAllRootWindows();
520f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(root_windows[0],
521f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            top_container()->GetWidget()->GetNativeWindow()->GetRootWindow());
522f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
523f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  gfx::Rect primary_root_window_bounds_in_screen =
524f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      root_windows[0]->GetBoundsInScreen();
525f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Do not set |x| to the root window's x position because the display's
526f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // corners have special behavior.
527f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int x = primary_root_window_bounds_in_screen.x() + 10;
528f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The y position of the top edge of the primary display.
529f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int y_top_edge = primary_root_window_bounds_in_screen.y();
530f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::test::EventGenerator& event_generator(GetEventGenerator());
532f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
533f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Moving right below the top edge starts the hover timer running. We
534f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // cannot use MoveMouse() because MoveMouse() stops the timer if it started
535f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // running.
536f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  event_generator.MoveMouseTo(x, y_top_edge + 1);
537f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(top_edge_hover_timer_running());
538f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(y_top_edge + 1,
539f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            aura::Env::GetInstance()->last_mouse_location().y());
540f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
541f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The timer should continue running if the user moves the mouse to the top
542f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // edge even though the mouse is warped to the secondary display.
543f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  event_generator.MoveMouseTo(x, y_top_edge);
544f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(top_edge_hover_timer_running());
545cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
546f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The timer should continue running if the user overshoots the top edge
547f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // a bit.
548f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  event_generator.MoveMouseTo(x, y_top_edge - 2);
549f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(top_edge_hover_timer_running());
550f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
551f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The timer should stop running if the user overshoots the top edge by
552f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // a lot.
553f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  event_generator.MoveMouseTo(x, y_top_edge - 20);
554f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(top_edge_hover_timer_running());
555f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
556f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The timer should not start if the user moves the mouse to the bottom of the
557f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // secondary display without crossing the top edge first.
558f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  event_generator.MoveMouseTo(x, y_top_edge - 2);
559f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
560f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Reveal the top-of-window views by overshooting the top edge slightly.
561f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  event_generator.MoveMouseTo(x, y_top_edge + 1);
562f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // MoveMouse() runs the timer task.
563f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  MoveMouse(x, y_top_edge - 2);
564f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
565f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
566f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The top-of-window views should stay revealed if the user moves the mouse
567f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // around in the bottom region of the secondary display.
568f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  event_generator.MoveMouseTo(x + 10, y_top_edge - 3);
569f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
570f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
571f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The top-of-window views should hide if the user moves the mouse away from
572f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // the bottom region of the secondary display.
573f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  event_generator.MoveMouseTo(x, y_top_edge - 20);
574f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
575a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
576a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Test that it is possible to reveal the top-of-window views by overshooting
577a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // the top edge slightly when the top container's widget is not active.
578a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  views::Widget* popup_widget = views::Widget::CreateWindowWithContextAndBounds(
579a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      NULL,
580a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      CurrentContext(),
581a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gfx::Rect(0, 200, 100, 100));
582a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  popup_widget->Show();
583a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_FALSE(top_container()->GetWidget()->IsActive());
584a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_FALSE(top_container()->GetBoundsInScreen().Intersects(
585a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      popup_widget->GetWindowBoundsInScreen()));
586a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  event_generator.MoveMouseTo(x, y_top_edge + 1);
587a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MoveMouse(x, y_top_edge - 2);
588a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
589f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
590f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
591f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Test behavior when the mouse becomes hovered without moving.
592f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(ImmersiveFullscreenControllerTest, MouseHoveredWithoutMoving) {
5935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(true);
594f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<ImmersiveRevealedLock> lock;
595f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
596f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // 1) Test that if the mouse becomes hovered without the mouse moving due to a
597f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // lock causing the top-of-window views to be revealed (and the mouse
598f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // happening to be near the top of the screen), the top-of-window views do not
599f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // hide till the mouse moves off of the top-of-window views.
600f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SetHovered(true);
601f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
602f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  lock.reset(controller()->GetRevealedLock(
603f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      ImmersiveFullscreenController::ANIMATE_REVEAL_NO));
604f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
605f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  lock.reset();
606f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
607f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SetHovered(false);
608f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
609f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
610f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // 2) Test that if the mouse becomes hovered without moving because of a
611a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // reveal in ImmersiveFullscreenController::SetEnabled(true) and there are no
612a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // locks keeping the top-of-window views revealed, that mouse hover does not
613a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // prevent the top-of-window views from closing.
6145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(false);
615f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SetHovered(true);
616f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
6175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(true);
618f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
619f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
620f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // 3) Test that if the mouse becomes hovered without moving because of a
621a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // reveal in ImmersiveFullscreenController::SetEnabled(true) and there is a
622a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // lock keeping the top-of-window views revealed, that the top-of-window views
623a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // do not hide till the mouse moves off of the top-of-window views.
6245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(false);
625f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SetHovered(true);
626f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  lock.reset(controller()->GetRevealedLock(
627f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      ImmersiveFullscreenController::ANIMATE_REVEAL_NO));
628f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
6295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(true);
630f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
631f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  lock.reset();
632f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
633f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SetHovered(false);
634f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
635f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
636f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
637f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Test revealing the top-of-window views using one modality and ending
638f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// the reveal via another. For instance, initiating the reveal via a SWIPE_OPEN
639f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// edge gesture, switching to using the mouse and ending the reveal by moving
640f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// the mouse off of the top-of-window views.
641f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(ImmersiveFullscreenControllerTest, DifferentModalityEnterExit) {
6425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(true);
643f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsEnabled());
644f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
645f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
646f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Initiate reveal via gesture, end reveal via mouse.
6475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AttemptReveal(MODALITY_GESTURE_SCROLL);
648f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
649f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  MoveMouse(1, 1);
650f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
651f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AttemptUnreveal(MODALITY_MOUSE);
652f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
653f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
654f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Initiate reveal via gesture, end reveal via touch.
6555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AttemptReveal(MODALITY_GESTURE_SCROLL);
656f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
6575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AttemptUnreveal(MODALITY_GESTURE_TAP);
658f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
659f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
660f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Initiate reveal via mouse, end reveal via gesture.
661f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AttemptReveal(MODALITY_MOUSE);
662f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
6635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AttemptUnreveal(MODALITY_GESTURE_SCROLL);
664f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
665f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
666f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Initiate reveal via mouse, end reveal via touch.
667f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AttemptReveal(MODALITY_MOUSE);
668f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
6695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AttemptUnreveal(MODALITY_GESTURE_TAP);
670f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
671f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
672f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
673f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Test when the SWIPE_CLOSE edge gesture closes the top-of-window views.
674a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#if defined(OS_WIN)
675a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// On Windows, touch events do not result in mouse events being disabled.  As
676a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// a result, the last part of this test which ends the reveal via a gesture will
677a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// not work correctly.  See crbug.com/332430, and the function
678a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// ShouldHideCursorOnTouch() in compound_event_filter.cc.
679a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#define MAYBE_EndRevealViaGesture DISABLED_EndRevealViaGesture
680a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#else
681a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#define MAYBE_EndRevealViaGesture EndRevealViaGesture
682a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#endif
683a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochTEST_F(ImmersiveFullscreenControllerTest, MAYBE_EndRevealViaGesture) {
6845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(true);
685f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsEnabled());
686f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
687f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
688f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // A gesture should be able to close the top-of-window views when
689f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // top-of-window views have focus.
690f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AttemptReveal(MODALITY_MOUSE);
691f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  top_container()->RequestFocus();
692f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
6935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AttemptUnreveal(MODALITY_GESTURE_SCROLL);
694f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
695a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
696a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // The top-of-window views should no longer have focus. Clearing focus is
697a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // important because it closes focus-related popup windows like the touch
698a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // selection handles.
699a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(top_container()->HasFocus());
700f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
701f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // If some other code is holding onto a lock, a gesture should not be able to
702f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // end the reveal.
703f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AttemptReveal(MODALITY_MOUSE);
704f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<ImmersiveRevealedLock> lock(controller()->GetRevealedLock(
705f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      ImmersiveFullscreenController::ANIMATE_REVEAL_NO));
706f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
7075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AttemptUnreveal(MODALITY_GESTURE_SCROLL);
708f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
709f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  lock.reset();
710f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
711f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
712f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Tests that touch-gesture can be used to reveal the top-of-window views when
7145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// the child window consumes all events.
7155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(ImmersiveFullscreenControllerTest, RevealViaGestureChildConsumesEvents) {
7165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Enabling initially hides the top views.
7175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(true);
7185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(controller()->IsEnabled());
7195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
7205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  aura::test::TestWindowDelegate child_delegate;
7225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<aura::Window> child(
7235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      CreateTestWindowInShellWithDelegateAndType(&child_delegate,
7245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                 ui::wm::WINDOW_TYPE_CONTROL,
7255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                 1234,
7265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                 gfx::Rect()));
7275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  content_view()->Attach(child.get());
7285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  child->Show();
7295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ConsumeEventHandler handler;
7315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  child->AddPreTargetHandler(&handler);
7325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Reveal the top views using a touch-scroll gesture. The child window should
7345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // not receive the touch events.
7355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AttemptReveal(MODALITY_GESTURE_SCROLL);
7365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
7375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0, handler.num_touch_events());
7385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AttemptUnreveal(MODALITY_GESTURE_TAP);
7405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
7415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_GT(handler.num_touch_events(), 0);
7425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  child->RemovePreTargetHandler(&handler);
7435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
7445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Make sure touch events towards the top of the window do not leak through to
7465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// windows underneath.
7475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(ImmersiveFullscreenControllerTest, EventsDoNotLeakToWindowUnderneath) {
7485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Rect window_bounds = window()->GetBoundsInScreen();
7495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  aura::test::TestWindowDelegate child_delegate;
7505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<aura::Window> behind(CreateTestWindowInShellWithDelegate(
7515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      &child_delegate, 1234, window_bounds));
7525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  behind->Show();
7535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  behind->SetBounds(window_bounds);
7545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  widget()->StackAbove(behind.get());
7555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Make sure the windows are aligned on top.
7575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(behind->GetBoundsInScreen().y(), window()->GetBoundsInScreen().y());
7585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int top = behind->GetBoundsInScreen().y();
7595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui::TouchEvent touch(ui::ET_TOUCH_MOVED, gfx::Point(10, top), 0,
7615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       ui::EventTimeForNow());
7625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui::EventTarget* root = window()->GetRootWindow();
7635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui::EventTargeter* targeter = root->GetEventTargeter();
7645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(window(), targeter->FindTargetForEvent(root, &touch));
7655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(true);
7675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
7685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Make sure the windows are still aligned on top.
7695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(behind->GetBoundsInScreen().y(), window()->GetBoundsInScreen().y());
7705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  top = behind->GetBoundsInScreen().y();
7715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui::TouchEvent touch2(ui::ET_TOUCH_MOVED, gfx::Point(10, top), 0,
7725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        ui::EventTimeForNow());
7735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The event should still be targeted to window().
7745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(window(), targeter->FindTargetForEvent(root, &touch2));
7755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
7765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
77746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Check that the window state gets properly marked for immersive fullscreen.
77846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(ImmersiveFullscreenControllerTest, WindowStateImmersiveFullscreen) {
77946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ash::wm::WindowState* window_state = ash::wm::GetWindowState(window());
78046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
78146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_FALSE(window_state->in_immersive_fullscreen());
78246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  SetEnabled(true);
78346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_TRUE(controller()->IsEnabled());
78446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(window_state->in_immersive_fullscreen());
78546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
78646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  SetEnabled(false);
78746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_FALSE(controller()->IsEnabled());
78846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_FALSE(window_state->in_immersive_fullscreen());
78946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
79046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
791f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Do not test under windows because focus testing is not reliable on
792f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Windows. (crbug.com/79493)
793f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if !defined(OS_WIN)
794f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
795f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Test how focus and activation affects whether the top-of-window views are
796f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// revealed.
797f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(ImmersiveFullscreenControllerTest, Focus) {
798f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Add views to the view hierarchy which we will focus and unfocus during the
799f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // test.
800f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  views::View* child_view = new views::View();
801f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  child_view->SetBounds(0, 0, 10, 10);
8025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  child_view->SetFocusable(true);
803f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  top_container()->AddChildView(child_view);
804f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  views::View* unrelated_view = new views::View();
805f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  unrelated_view->SetBounds(0, 100, 10, 10);
8065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  unrelated_view->SetFocusable(true);
807f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  top_container()->parent()->AddChildView(unrelated_view);
808f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  views::FocusManager* focus_manager =
809f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      top_container()->GetWidget()->GetFocusManager();
810f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
8115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(true);
812f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
813f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // 1) Test that the top-of-window views stay revealed as long as either a
814f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // |child_view| has focus or the mouse is hovered above the top-of-window
815f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // views.
816f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AttemptReveal(MODALITY_MOUSE);
817f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  child_view->RequestFocus();
818f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  focus_manager->ClearFocus();
819f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
820f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  child_view->RequestFocus();
821f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SetHovered(false);
822f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
823f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  focus_manager->ClearFocus();
824f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
825f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
826f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // 2) Test that focusing |unrelated_view| hides the top-of-window views.
827f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Note: In this test we can cheat and trigger a reveal via focus because
828f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // the top container does not hide when the top-of-window views are not
829f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // revealed.
830f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  child_view->RequestFocus();
831f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
832f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  unrelated_view->RequestFocus();
833f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
834f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
835f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // 3) Test that a loss of focus of |child_view| to |unrelated_view|
836f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // while immersive mode is disabled is properly registered.
837f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  child_view->RequestFocus();
838f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
8395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(false);
840f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
841f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  unrelated_view->RequestFocus();
8425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(true);
843f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
844f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
845f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Repeat test but with a revealed lock acquired when immersive mode is
846f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // disabled because the code path is different.
847f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  child_view->RequestFocus();
848f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
8495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(false);
850f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<ImmersiveRevealedLock> lock(controller()->GetRevealedLock(
851f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      ImmersiveFullscreenController::ANIMATE_REVEAL_NO));
852f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
853f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  unrelated_view->RequestFocus();
8545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(true);
855f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
856f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  lock.reset();
857f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
858f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
859f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
860a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Test how transient windows affect whether the top-of-window views are
861a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// revealed.
862a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(ImmersiveFullscreenControllerTest, Transient) {
863f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  views::Widget* top_container_widget = top_container()->GetWidget();
864f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
8655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(true);
866f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_FALSE(controller()->IsRevealed());
867f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
868f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // 1) Test that a transient window which is not a bubble does not trigger a
869f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // reveal but does keep the top-of-window views revealed if they are already
870f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // revealed.
871f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  views::Widget::InitParams transient_params;
872f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  transient_params.ownership =
873f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
874f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  transient_params.parent = top_container_widget->GetNativeView();
875a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  transient_params.bounds = gfx::Rect(0, 100, 100, 100);
876f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<views::Widget> transient_widget(new views::Widget());
877f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  transient_widget->Init(transient_params);
878f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
879f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
880f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AttemptReveal(MODALITY_MOUSE);
881f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
882a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  transient_widget->Show();
883f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SetHovered(false);
884f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
885f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  transient_widget.reset();
886f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
887f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
888a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // 2) Test that activating a non-transient window does not keep the
889a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // top-of-window views revealed.
890f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  views::Widget::InitParams non_transient_params;
891f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  non_transient_params.ownership =
892f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
893f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  non_transient_params.context = top_container_widget->GetNativeView();
894a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  non_transient_params.bounds = gfx::Rect(0, 100, 100, 100);
895f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<views::Widget> non_transient_widget(new views::Widget());
896f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  non_transient_widget->Init(non_transient_params);
897f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
898f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
899f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AttemptReveal(MODALITY_MOUSE);
900f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
901a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  non_transient_widget->Show();
902a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SetHovered(false);
903f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
904f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
905f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
906f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Test how bubbles affect whether the top-of-window views are revealed.
907f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(ImmersiveFullscreenControllerTest, Bubbles) {
908f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<ImmersiveRevealedLock> revealed_lock;
909f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  views::Widget* top_container_widget = top_container()->GetWidget();
910f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
911f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Add views to the view hierarchy to which we will anchor bubbles.
912f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  views::View* child_view = new views::View();
913f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  child_view->SetBounds(0, 0, 10, 10);
914f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  top_container()->AddChildView(child_view);
915f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  views::View* unrelated_view = new views::View();
916f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  unrelated_view->SetBounds(0, 100, 10, 10);
917f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  top_container()->parent()->AddChildView(unrelated_view);
918f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
9195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(true);
920f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_FALSE(controller()->IsRevealed());
921f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
922f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // 1) Test that a bubble anchored to a child of the top container triggers
923f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // a reveal and keeps the top-of-window views revealed for the duration of
924f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // its visibility.
925f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  views::Widget* bubble_widget1(views::BubbleDelegateView::CreateBubble(
926f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new views::BubbleDelegateView(child_view, views::BubbleBorder::NONE)));
927f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bubble_widget1->Show();
928f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
929f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
930f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Activating |top_container_widget| will close |bubble_widget1|.
931f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  top_container_widget->Activate();
932f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AttemptReveal(MODALITY_MOUSE);
933f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  revealed_lock.reset(controller()->GetRevealedLock(
934f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      ImmersiveFullscreenController::ANIMATE_REVEAL_NO));
935f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
936f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
937f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  views::Widget* bubble_widget2 = views::BubbleDelegateView::CreateBubble(
938f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new views::BubbleDelegateView(child_view, views::BubbleBorder::NONE));
939f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bubble_widget2->Show();
940f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
941f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  revealed_lock.reset();
942f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SetHovered(false);
943f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
944f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bubble_widget2->Close();
945f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
946f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
947f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // 2) Test that transitioning from keeping the top-of-window views revealed
948f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // because of a bubble to keeping the top-of-window views revealed because of
949f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // mouse hover by activating |top_container_widget| works.
950f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  views::Widget* bubble_widget3 = views::BubbleDelegateView::CreateBubble(
951f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new views::BubbleDelegateView(child_view, views::BubbleBorder::NONE));
952f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bubble_widget3->Show();
953f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SetHovered(true);
954f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
955f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  top_container_widget->Activate();
956f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
957f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
958f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // 3) Test that the top-of-window views stay revealed as long as at least one
959f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // bubble anchored to a child of the top container is visible.
960f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SetHovered(false);
961f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
962f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
963f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  views::BubbleDelegateView* bubble_delegate4(new views::BubbleDelegateView(
964f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      child_view, views::BubbleBorder::NONE));
9655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bubble_delegate4->set_can_activate(false);
966f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  views::Widget* bubble_widget4(views::BubbleDelegateView::CreateBubble(
967f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      bubble_delegate4));
968f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bubble_widget4->Show();
969f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
970f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  views::BubbleDelegateView* bubble_delegate5(new views::BubbleDelegateView(
971f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      child_view, views::BubbleBorder::NONE));
9725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bubble_delegate5->set_can_activate(false);
973f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  views::Widget* bubble_widget5(views::BubbleDelegateView::CreateBubble(
974f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      bubble_delegate5));
975f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bubble_widget5->Show();
976f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
977f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
978f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bubble_widget4->Hide();
979f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
980f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bubble_widget5->Hide();
981f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
982f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bubble_widget5->Show();
983f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
984f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
985f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // 4) Test that visibility changes which occur while immersive fullscreen is
986f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // disabled are handled upon reenabling immersive fullscreen.
9875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(false);
988f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bubble_widget5->Hide();
9895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(true);
990f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
991f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
992f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // We do not need |bubble_widget4| or |bubble_widget5| anymore, close them.
993f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bubble_widget4->Close();
994f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bubble_widget5->Close();
995f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
996f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // 5) Test that a bubble added while immersive fullscreen is disabled is
997f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // handled upon reenabling immersive fullscreen.
9985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(false);
999f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1000f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  views::Widget* bubble_widget6 = views::BubbleDelegateView::CreateBubble(
1001f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new views::BubbleDelegateView(child_view, views::BubbleBorder::NONE));
1002f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bubble_widget6->Show();
1003f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
10045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(true);
1005f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
1006f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1007f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bubble_widget6->Close();
1008f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1009f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // 6) Test that a bubble which is not anchored to a child of the
1010f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // TopContainerView does not trigger a reveal or keep the
1011f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // top-of-window views revealed if they are already revealed.
1012f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  views::Widget* bubble_widget7 = views::BubbleDelegateView::CreateBubble(
1013f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new views::BubbleDelegateView(unrelated_view, views::BubbleBorder::NONE));
1014f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bubble_widget7->Show();
1015f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
1016f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1017f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Activating |top_container_widget| will close |bubble_widget6|.
1018f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  top_container_widget->Activate();
1019f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AttemptReveal(MODALITY_MOUSE);
1020f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller()->IsRevealed());
1021f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1022f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  views::Widget* bubble_widget8 = views::BubbleDelegateView::CreateBubble(
1023f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new views::BubbleDelegateView(unrelated_view, views::BubbleBorder::NONE));
1024f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bubble_widget8->Show();
1025f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SetHovered(false);
1026f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(controller()->IsRevealed());
1027f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bubble_widget8->Close();
1028f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
1029f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1030f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif  // defined(OS_WIN)
1031f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1032f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Test that the shelf is set to auto hide as long as the window is in
1033f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// immersive fullscreen and that the shelf's state before entering immersive
1034f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// fullscreen is restored upon exiting immersive fullscreen.
1035f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(ImmersiveFullscreenControllerTest, Shelf) {
1036c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ash::ShelfLayoutManager* shelf =
1037f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      ash::Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager();
1038f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1039f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Shelf is visible by default.
1040f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  window()->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
1041f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_FALSE(controller()->IsEnabled());
1042f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(ash::SHELF_VISIBLE, shelf->visibility_state());
1043f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1044f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Entering immersive fullscreen sets the shelf to auto hide.
1045f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  window()->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
10465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(true);
1047f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(ash::SHELF_AUTO_HIDE, shelf->visibility_state());
1048f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1049f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Disabling immersive fullscreen puts it back.
10505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(false);
1051f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  window()->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
1052f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_FALSE(controller()->IsEnabled());
1053f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(ash::SHELF_VISIBLE, shelf->visibility_state());
1054f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1055f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The user could toggle the shelf auto-hide behavior.
1056f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  shelf->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1057f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(ash::SHELF_AUTO_HIDE, shelf->visibility_state());
1058f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1059f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Entering immersive fullscreen keeps auto-hide.
1060f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  window()->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
10615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(true);
1062f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(ash::SHELF_AUTO_HIDE, shelf->visibility_state());
1063f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1064f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Disabling immersive fullscreen maintains the user's auto-hide selection.
10655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetEnabled(false);
1066f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  window()->SetProperty(aura::client::kShowStateKey,
1067f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        ui::SHOW_STATE_NORMAL);
1068f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(ash::SHELF_AUTO_HIDE, shelf->visibility_state());
1069f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
1070f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1071f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespase ash
1072