blob: 3a206ab627419c0bc60ab07219ee15d25c73cfbc [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/views/frame/immersive_mode_controller_ash.h"
#include "ash/test/ash_test_base.h"
#include "chrome/browser/ui/immersive_fullscreen_configuration.h"
#include "ui/aura/client/cursor_client.h"
#include "ui/aura/root_window.h"
#include "ui/aura/test/event_generator.h"
#include "ui/aura/window.h"
#include "ui/views/bubble/bubble_delegate.h"
// For now, immersive fullscreen is Chrome OS only.
#if defined(OS_CHROMEOS)
/////////////////////////////////////////////////////////////////////////////
class MockImmersiveModeControllerDelegate
: public ImmersiveModeController::Delegate {
public:
MockImmersiveModeControllerDelegate() : immersive_style_(false) {}
virtual ~MockImmersiveModeControllerDelegate() {}
bool immersive_style() const { return immersive_style_; }
// ImmersiveModeController::Delegate overrides:
virtual BookmarkBarView* GetBookmarkBar() OVERRIDE { return NULL; }
virtual FullscreenController* GetFullscreenController() OVERRIDE {
return NULL;
}
virtual void FullscreenStateChanged() OVERRIDE {}
virtual void SetImmersiveStyle(bool immersive) OVERRIDE {
immersive_style_ = immersive;
}
virtual content::WebContents* GetWebContents() OVERRIDE {
return NULL;
}
private:
bool immersive_style_;
DISALLOW_COPY_AND_ASSIGN(MockImmersiveModeControllerDelegate);
};
/////////////////////////////////////////////////////////////////////////////
class ImmersiveModeControllerAshTest : public ash::test::AshTestBase {
public:
enum Modality {
MODALITY_MOUSE,
MODALITY_TOUCH,
MODALITY_GESTURE
};
ImmersiveModeControllerAshTest() : widget_(NULL), top_container_(NULL) {}
virtual ~ImmersiveModeControllerAshTest() {}
ImmersiveModeControllerAsh* controller() { return controller_.get(); }
views::View* top_container() { return top_container_; }
MockImmersiveModeControllerDelegate* delegate() { return delegate_.get(); }
aura::test::EventGenerator* event_generator() {
return event_generator_.get();
}
// Access to private data from the controller.
bool top_edge_hover_timer_running() const {
return controller_->top_edge_hover_timer_.IsRunning();
}
int mouse_x_when_hit_top() const {
return controller_->mouse_x_when_hit_top_;
}
// ash::test::AshTestBase overrides:
virtual void SetUp() OVERRIDE {
ash::test::AshTestBase::SetUp();
ImmersiveFullscreenConfiguration::EnableImmersiveFullscreenForTest();
ASSERT_TRUE(ImmersiveFullscreenConfiguration::UseImmersiveFullscreen());
controller_.reset(new ImmersiveModeControllerAsh);
delegate_.reset(new MockImmersiveModeControllerDelegate);
event_generator_.reset(new aura::test::EventGenerator(CurrentContext()));
widget_ = new views::Widget();
views::Widget::InitParams params;
params.context = CurrentContext();
params.bounds = gfx::Rect(0, 0, 500, 500);
widget_->Init(params);
widget_->Show();
top_container_ = new views::View();
top_container_->SetBounds(0, 0, 500, 100);
top_container_->set_focusable(true);
widget_->GetContentsView()->AddChildView(top_container_);
controller_->Init(delegate_.get(), widget_, top_container_);
controller_->DisableAnimationsForTest();
}
// Attempt to reveal the top-of-window views via |modality|.
// The top-of-window views can only be revealed via mouse hover or a gesture.
void AttemptReveal(Modality modality) {
ASSERT_NE(modality, MODALITY_TOUCH);
AttemptRevealStateChange(true, modality);
}
// Attempt to unreveal the top-of-window views via |modality|. The
// top-of-window views can be unrevealed via any modality.
void AttemptUnreveal(Modality modality) {
AttemptRevealStateChange(false, modality);
}
// Sets whether the mouse is hovered above |top_container_|.
// SetHovered(true) moves the mouse over the |top_container_| but does not
// move it to the top of the screen so will not initiate a reveal.
void SetHovered(bool is_mouse_hovered) {
MoveMouse(0, is_mouse_hovered ? 1 : top_container_->height() + 100);
}
// Move the mouse to the given coordinates. The coordinates should be in
// |top_container_| coordinates.
void MoveMouse(int x, int y) {
// Luckily, |top_container_| is at the top left of the root window so the
// provided coordinates are already in the coordinates of the root window.
event_generator_->MoveMouseTo(x, y);
// If the top edge timer started running as a result of the mouse move, run
// the task which occurs after the timer delay. This reveals the
// top-of-window views synchronously if the mouse is hovered at the top of
// the screen.
if (controller()->top_edge_hover_timer_.IsRunning()) {
controller()->top_edge_hover_timer_.user_task().Run();
controller()->top_edge_hover_timer_.Stop();
}
}
private:
// Attempt to change the revealed state to |revealed| via |modality|.
void AttemptRevealStateChange(bool revealed, Modality modality) {
// Compute the event position in |top_container_| coordinates.
gfx::Point event_position(0, revealed ? 0 : top_container_->height() + 100);
switch (modality) {
case MODALITY_MOUSE: {
MoveMouse(event_position.x(), event_position.y());
break;
}
case MODALITY_TOUCH: {
// Luckily, |top_container_| is at the top left of the root window so
// |event_position| is already in the coordinates of the root window.
event_generator_->MoveTouch(event_position);
event_generator_->PressTouch();
event_generator_->ReleaseTouch();
break;
}
case MODALITY_GESTURE: {
aura::client::GetCursorClient(CurrentContext())->DisableMouseEvents();
ImmersiveModeControllerAsh::SwipeType swipe_type = revealed ?
ImmersiveModeControllerAsh::SWIPE_OPEN :
ImmersiveModeControllerAsh::SWIPE_CLOSE;
controller_->UpdateRevealedLocksForSwipe(swipe_type);
break;
}
}
}
scoped_ptr<ImmersiveModeControllerAsh> controller_;
scoped_ptr<MockImmersiveModeControllerDelegate> delegate_;
views::Widget* widget_; // Owned by the native widget.
views::View* top_container_; // Owned by |root_view_|.
scoped_ptr<aura::test::EventGenerator> event_generator_;
DISALLOW_COPY_AND_ASSIGN(ImmersiveModeControllerAshTest);
};
// Test of initial state and basic functionality.
TEST_F(ImmersiveModeControllerAshTest, ImmersiveModeControllerAsh) {
// Initial state.
EXPECT_FALSE(controller()->IsEnabled());
EXPECT_FALSE(controller()->ShouldHideTopViews());
EXPECT_FALSE(controller()->IsRevealed());
EXPECT_FALSE(delegate()->immersive_style());
// Enabling hides the top views.
controller()->SetEnabled(true);
EXPECT_TRUE(controller()->IsEnabled());
EXPECT_FALSE(controller()->IsRevealed());
EXPECT_TRUE(controller()->ShouldHideTopViews());
EXPECT_FALSE(controller()->ShouldHideTabIndicators());
EXPECT_TRUE(delegate()->immersive_style());
// Revealing shows the top views.
AttemptReveal(MODALITY_MOUSE);
EXPECT_TRUE(controller()->IsRevealed());
EXPECT_FALSE(controller()->ShouldHideTopViews());
// Tabs are painting in the normal style during a reveal.
EXPECT_FALSE(delegate()->immersive_style());
}
// Test mouse event processing for top-of-screen reveal triggering.
TEST_F(ImmersiveModeControllerAshTest, OnMouseEvent) {
// Set up initial state.
controller()->SetEnabled(true);
ASSERT_TRUE(controller()->IsEnabled());
ASSERT_FALSE(controller()->IsRevealed());
// Mouse wheel event does nothing.
ui::MouseEvent wheel(
ui::ET_MOUSEWHEEL, gfx::Point(), gfx::Point(), ui::EF_NONE);
event_generator()->Dispatch(&wheel);
EXPECT_FALSE(top_edge_hover_timer_running());
// Move to top edge of screen starts hover timer running. We cannot use
// MoveMouse() because MoveMouse() stops the timer if it started running.
event_generator()->MoveMouseTo(100, 0);
EXPECT_TRUE(top_edge_hover_timer_running());
EXPECT_EQ(100, mouse_x_when_hit_top());
// Moving off the top edge stops it.
event_generator()->MoveMouseTo(100, 1);
EXPECT_FALSE(top_edge_hover_timer_running());
// Moving back to the top starts the timer again.
event_generator()->MoveMouseTo(100, 0);
EXPECT_TRUE(top_edge_hover_timer_running());
EXPECT_EQ(100, mouse_x_when_hit_top());
// Slight move to the right keeps the timer running for the same hit point.
event_generator()->MoveMouseTo(101, 0);
EXPECT_TRUE(top_edge_hover_timer_running());
EXPECT_EQ(100, mouse_x_when_hit_top());
// Moving back to the left also keeps the timer running.
event_generator()->MoveMouseTo(100, 0);
EXPECT_TRUE(top_edge_hover_timer_running());
EXPECT_EQ(100, mouse_x_when_hit_top());
// Large move right restarts the timer (so it is still running) and considers
// this a new hit at the top.
event_generator()->MoveMouseTo(499, 0);
EXPECT_TRUE(top_edge_hover_timer_running());
EXPECT_EQ(499, mouse_x_when_hit_top());
// Moving off the top edge horizontally stops the timer.
EXPECT_GT(CurrentContext()->bounds().width(), top_container()->width());
EXPECT_EQ(500, top_container()->width());
event_generator()->MoveMouseTo(500, 0);
EXPECT_FALSE(top_edge_hover_timer_running());
// Once revealed, a move just a little below the top container doesn't end a
// reveal.
AttemptReveal(MODALITY_MOUSE);
event_generator()->MoveMouseTo(0, top_container()->height() + 1);
EXPECT_TRUE(controller()->IsRevealed());
// Once revealed, clicking just below the top container ends the reveal.
event_generator()->ClickLeftButton();
EXPECT_FALSE(controller()->IsRevealed());
// Moving a lot below the top container ends a reveal.
AttemptReveal(MODALITY_MOUSE);
EXPECT_TRUE(controller()->IsRevealed());
event_generator()->MoveMouseTo(0, top_container()->height() + 50);
EXPECT_FALSE(controller()->IsRevealed());
// The mouse position cannot cause a reveal when TopContainerView's widget
// has capture.
views::Widget* widget = top_container()->GetWidget();
widget->SetCapture(top_container());
AttemptReveal(MODALITY_MOUSE);
EXPECT_FALSE(controller()->IsRevealed());
widget->ReleaseCapture();
// The mouse position cannot end the reveal while TopContainerView's widget
// has capture.
AttemptReveal(MODALITY_MOUSE);
EXPECT_TRUE(controller()->IsRevealed());
widget->SetCapture(top_container());
event_generator()->MoveMouseTo(0, top_container()->height() + 51);
EXPECT_TRUE(controller()->IsRevealed());
// Releasing capture should end the reveal.
widget->ReleaseCapture();
EXPECT_FALSE(controller()->IsRevealed());
}
// Test that hovering the mouse over the find bar does not end a reveal.
TEST_F(ImmersiveModeControllerAshTest, FindBar) {
// Set up initial state.
controller()->SetEnabled(true);
ASSERT_TRUE(controller()->IsEnabled());
ASSERT_FALSE(controller()->IsRevealed());
// Compute the find bar bounds relative to TopContainerView. The find
// bar is aligned with the bottom right of the TopContainerView.
gfx::Rect find_bar_bounds(top_container()->bounds().right() - 100,
top_container()->bounds().bottom(),
100,
50);
gfx::Point find_bar_position_in_screen = find_bar_bounds.origin();
views::View::ConvertPointToScreen(top_container(),
&find_bar_position_in_screen);
gfx::Rect find_bar_bounds_in_screen(find_bar_position_in_screen,
find_bar_bounds.size());
controller()->OnFindBarVisibleBoundsChanged(find_bar_bounds_in_screen);
// Moving the mouse over the find bar does not end the reveal.
gfx::Point over_find_bar(find_bar_bounds.x() + 25, find_bar_bounds.y() + 25);
AttemptReveal(MODALITY_MOUSE);
EXPECT_TRUE(controller()->IsRevealed());
MoveMouse(over_find_bar.x(), over_find_bar.y());
EXPECT_TRUE(controller()->IsRevealed());
// Moving the mouse off of the find bar horizontally ends the reveal.
MoveMouse(find_bar_bounds.x() - 25, find_bar_bounds.y() + 25);
EXPECT_FALSE(controller()->IsRevealed());
// Moving the mouse off of the find bar vertically ends the reveal.
AttemptReveal(MODALITY_MOUSE);
EXPECT_TRUE(controller()->IsRevealed());
MoveMouse(find_bar_bounds.x() + 25, find_bar_bounds.bottom() + 25);
// Similar to the TopContainerView, moving the mouse slightly off vertically
// of the find bar does not end the reveal.
AttemptReveal(MODALITY_MOUSE);
MoveMouse(find_bar_bounds.x() + 25, find_bar_bounds.bottom() + 1);
EXPECT_TRUE(controller()->IsRevealed());
// Similar to the TopContainerView, clicking the mouse even slightly off of
// the find bar ends the reveal.
event_generator()->ClickLeftButton();
EXPECT_FALSE(controller()->IsRevealed());
// Set the find bar bounds to empty. Hovering over the position previously
// occupied by the find bar, |over_find_bar|, should end the reveal.
controller()->OnFindBarVisibleBoundsChanged(gfx::Rect());
AttemptReveal(MODALITY_MOUSE);
MoveMouse(over_find_bar.x(), over_find_bar.y());
EXPECT_FALSE(controller()->IsRevealed());
}
// Test revealing the top-of-window views using one modality and ending
// the reveal via another. For instance, initiating the reveal via a SWIPE_OPEN
// edge gesture, switching to using the mouse and ending the reveal by moving
// the mouse off of the top-of-window views.
TEST_F(ImmersiveModeControllerAshTest, DifferentModalityEnterExit) {
controller()->SetEnabled(true);
EXPECT_TRUE(controller()->IsEnabled());
EXPECT_FALSE(controller()->IsRevealed());
// Initiate reveal via gesture, end reveal via mouse.
AttemptReveal(MODALITY_GESTURE);
EXPECT_TRUE(controller()->IsRevealed());
MoveMouse(1, 1);
EXPECT_TRUE(controller()->IsRevealed());
AttemptUnreveal(MODALITY_MOUSE);
EXPECT_FALSE(controller()->IsRevealed());
// Initiate reveal via gesture, end reveal via touch.
AttemptReveal(MODALITY_GESTURE);
EXPECT_TRUE(controller()->IsRevealed());
AttemptUnreveal(MODALITY_TOUCH);
EXPECT_FALSE(controller()->IsRevealed());
// Initiate reveal via mouse, end reveal via gesture.
AttemptReveal(MODALITY_MOUSE);
EXPECT_TRUE(controller()->IsRevealed());
AttemptUnreveal(MODALITY_GESTURE);
EXPECT_FALSE(controller()->IsRevealed());
// Initiate reveal via mouse, end reveal via touch.
AttemptReveal(MODALITY_MOUSE);
EXPECT_TRUE(controller()->IsRevealed());
AttemptUnreveal(MODALITY_TOUCH);
EXPECT_FALSE(controller()->IsRevealed());
}
// Test when the SWIPE_CLOSE edge gesture closes the top-of-window views.
TEST_F(ImmersiveModeControllerAshTest, EndRevealViaGesture) {
controller()->SetEnabled(true);
EXPECT_TRUE(controller()->IsEnabled());
EXPECT_FALSE(controller()->IsRevealed());
// A gesture should be able to close the top-of-window views when
// top-of-window views have focus.
AttemptReveal(MODALITY_MOUSE);
top_container()->RequestFocus();
EXPECT_TRUE(controller()->IsRevealed());
AttemptUnreveal(MODALITY_GESTURE);
EXPECT_FALSE(controller()->IsRevealed());
top_container()->GetFocusManager()->ClearFocus();
// If some other code is holding onto a lock, a gesture should not be able to
// end the reveal.
AttemptReveal(MODALITY_MOUSE);
scoped_ptr<ImmersiveRevealedLock> lock(controller()->GetRevealedLock(
ImmersiveModeController::ANIMATE_REVEAL_NO));
EXPECT_TRUE(controller()->IsRevealed());
AttemptUnreveal(MODALITY_GESTURE);
EXPECT_TRUE(controller()->IsRevealed());
lock.reset();
EXPECT_FALSE(controller()->IsRevealed());
}
// Do not test under windows because focus testing is not reliable on
// Windows. (crbug.com/79493)
#if !defined(OS_WIN)
// Test how focus and activation affects whether the top-of-window views are
// revealed.
TEST_F(ImmersiveModeControllerAshTest, Focus) {
// Add views to the view hierarchy which we will focus and unfocus during the
// test.
views::View* child_view = new views::View();
child_view->SetBounds(0, 0, 10, 10);
child_view->set_focusable(true);
top_container()->AddChildView(child_view);
views::View* unrelated_view = new views::View();
unrelated_view->SetBounds(0, 100, 10, 10);
unrelated_view->set_focusable(true);
top_container()->parent()->AddChildView(unrelated_view);
views::FocusManager* focus_manager =
top_container()->GetWidget()->GetFocusManager();
controller()->SetEnabled(true);
// 1) Test that the top-of-window views stay revealed as long as either a
// |child_view| has focus or the mouse is hovered above the top-of-window
// views.
AttemptReveal(MODALITY_MOUSE);
child_view->RequestFocus();
focus_manager->ClearFocus();
EXPECT_TRUE(controller()->IsRevealed());
child_view->RequestFocus();
SetHovered(false);
EXPECT_TRUE(controller()->IsRevealed());
focus_manager->ClearFocus();
EXPECT_FALSE(controller()->IsRevealed());
// 2) Test that focusing |unrelated_view| hides the top-of-window views.
// Note: In this test we can cheat and trigger a reveal via focus because
// the top container does not hide when the top-of-window views are not
// revealed.
child_view->RequestFocus();
EXPECT_TRUE(controller()->IsRevealed());
unrelated_view->RequestFocus();
EXPECT_FALSE(controller()->IsRevealed());
// 3) Test that a loss of focus of |child_view| to |unrelated_view|
// while immersive mode is disabled is properly registered.
child_view->RequestFocus();
EXPECT_TRUE(controller()->IsRevealed());
controller()->SetEnabled(false);
EXPECT_FALSE(controller()->IsRevealed());
unrelated_view->RequestFocus();
controller()->SetEnabled(true);
EXPECT_FALSE(controller()->IsRevealed());
// Repeat test but with a revealed lock acquired when immersive mode is
// disabled because the code path is different.
child_view->RequestFocus();
EXPECT_TRUE(controller()->IsRevealed());
controller()->SetEnabled(false);
scoped_ptr<ImmersiveRevealedLock> lock(controller()->GetRevealedLock(
ImmersiveModeController::ANIMATE_REVEAL_NO));
EXPECT_FALSE(controller()->IsRevealed());
unrelated_view->RequestFocus();
controller()->SetEnabled(true);
EXPECT_TRUE(controller()->IsRevealed());
lock.reset();
EXPECT_FALSE(controller()->IsRevealed());
}
// Test how activation affects whether the top-of-window views are revealed.
// The behavior when a bubble is activated is tested in
// ImmersiveModeControllerAshTest.Bubbles.
TEST_F(ImmersiveModeControllerAshTest, Activation) {
views::Widget* top_container_widget = top_container()->GetWidget();
controller()->SetEnabled(true);
ASSERT_FALSE(controller()->IsRevealed());
// 1) Test that a transient window which is not a bubble does not trigger a
// reveal but does keep the top-of-window views revealed if they are already
// revealed.
views::Widget::InitParams transient_params;
transient_params.ownership =
views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
transient_params.parent = top_container_widget->GetNativeView();
transient_params.bounds = gfx::Rect(0, 0, 100, 100);
scoped_ptr<views::Widget> transient_widget(new views::Widget());
transient_widget->Init(transient_params);
transient_widget->Show();
EXPECT_FALSE(controller()->IsRevealed());
top_container_widget->Activate();
AttemptReveal(MODALITY_MOUSE);
EXPECT_TRUE(controller()->IsRevealed());
transient_widget->Activate();
SetHovered(false);
EXPECT_TRUE(controller()->IsRevealed());
transient_widget.reset();
EXPECT_FALSE(controller()->IsRevealed());
// 2) Test that activating a non-transient window ends the reveal if any.
views::Widget::InitParams non_transient_params;
non_transient_params.ownership =
views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
non_transient_params.context = top_container_widget->GetNativeView();
non_transient_params.bounds = gfx::Rect(0, 0, 100, 100);
scoped_ptr<views::Widget> non_transient_widget(new views::Widget());
non_transient_widget->Init(non_transient_params);
non_transient_widget->Show();
EXPECT_FALSE(controller()->IsRevealed());
top_container_widget->Activate();
AttemptReveal(MODALITY_MOUSE);
EXPECT_TRUE(controller()->IsRevealed());
non_transient_widget->Activate();
EXPECT_FALSE(controller()->IsRevealed());
}
// Test how bubbles affect whether the top-of-window views are revealed.
TEST_F(ImmersiveModeControllerAshTest, Bubbles) {
scoped_ptr<ImmersiveRevealedLock> revealed_lock;
views::Widget* top_container_widget = top_container()->GetWidget();
// Add views to the view hierarchy to which we will anchor bubbles.
views::View* child_view = new views::View();
child_view->SetBounds(0, 0, 10, 10);
top_container()->AddChildView(child_view);
views::View* unrelated_view = new views::View();
unrelated_view->SetBounds(0, 100, 10, 10);
top_container()->parent()->AddChildView(unrelated_view);
controller()->SetEnabled(true);
ASSERT_FALSE(controller()->IsRevealed());
// 1) Test that a bubble anchored to a child of the top container triggers
// a reveal and keeps the top-of-window views revealed for the duration of
// its visibility.
views::Widget* bubble_widget1(views::BubbleDelegateView::CreateBubble(
new views::BubbleDelegateView(child_view, views::BubbleBorder::NONE)));
bubble_widget1->Show();
EXPECT_TRUE(controller()->IsRevealed());
// Activating |top_container_widget| will close |bubble_widget1|.
top_container_widget->Activate();
AttemptReveal(MODALITY_MOUSE);
revealed_lock.reset(controller()->GetRevealedLock(
ImmersiveModeController::ANIMATE_REVEAL_NO));
EXPECT_TRUE(controller()->IsRevealed());
views::Widget* bubble_widget2 = views::BubbleDelegateView::CreateBubble(
new views::BubbleDelegateView(child_view, views::BubbleBorder::NONE));
bubble_widget2->Show();
EXPECT_TRUE(controller()->IsRevealed());
revealed_lock.reset();
SetHovered(false);
EXPECT_TRUE(controller()->IsRevealed());
bubble_widget2->Close();
EXPECT_FALSE(controller()->IsRevealed());
// 2) Test that the top-of-window views stay revealed as long as at least one
// bubble anchored to a child of the top container is visible.
views::BubbleDelegateView* bubble_delegate3(new views::BubbleDelegateView(
child_view, views::BubbleBorder::NONE));
bubble_delegate3->set_use_focusless(true);
views::Widget* bubble_widget3(views::BubbleDelegateView::CreateBubble(
bubble_delegate3));
bubble_widget3->Show();
views::BubbleDelegateView* bubble_delegate4(new views::BubbleDelegateView(
child_view, views::BubbleBorder::NONE));
bubble_delegate4->set_use_focusless(true);
views::Widget* bubble_widget4(views::BubbleDelegateView::CreateBubble(
bubble_delegate4));
bubble_widget4->Show();
EXPECT_TRUE(controller()->IsRevealed());
bubble_widget3->Hide();
EXPECT_TRUE(controller()->IsRevealed());
bubble_widget4->Hide();
EXPECT_FALSE(controller()->IsRevealed());
bubble_widget4->Show();
EXPECT_TRUE(controller()->IsRevealed());
// 3) Test that visibility changes which occur while immersive fullscreen is
// disabled are handled upon reenabling immersive fullscreen.
controller()->SetEnabled(false);
bubble_widget4->Hide();
controller()->SetEnabled(true);
EXPECT_FALSE(controller()->IsRevealed());
// We do not need |bubble_widget3| or |bubble_widget4| anymore, close them.
bubble_widget3->Close();
bubble_widget4->Close();
// 4) Test that a bubble added while immersive fullscreen is disabled is
// handled upon reenabling immersive fullscreen.
controller()->SetEnabled(false);
views::Widget* bubble_widget5 = views::BubbleDelegateView::CreateBubble(
new views::BubbleDelegateView(child_view, views::BubbleBorder::NONE));
bubble_widget5->Show();
controller()->SetEnabled(true);
EXPECT_TRUE(controller()->IsRevealed());
bubble_widget5->Close();
// 5) Test that a bubble which is not anchored to a child of the
// TopContainerView does not trigger a reveal or keep the
// top-of-window views revealed if they are already revealed.
views::Widget* bubble_widget6 = views::BubbleDelegateView::CreateBubble(
new views::BubbleDelegateView(unrelated_view, views::BubbleBorder::NONE));
bubble_widget6->Show();
EXPECT_FALSE(controller()->IsRevealed());
// Activating |top_container_widget| will close |bubble_widget6|.
top_container_widget->Activate();
AttemptReveal(MODALITY_MOUSE);
EXPECT_TRUE(controller()->IsRevealed());
views::Widget* bubble_widget7 = views::BubbleDelegateView::CreateBubble(
new views::BubbleDelegateView(unrelated_view, views::BubbleBorder::NONE));
bubble_widget7->Show();
SetHovered(false);
EXPECT_FALSE(controller()->IsRevealed());
bubble_widget7->Close();
}
#endif // defined(OS_WIN)
#endif // defined(OS_CHROMEOS)