Commit aa1da928 authored by mukai@chromium.org's avatar mukai@chromium.org

Fix the bug of multiple overlays.

- keyboard overlay and partial_screenshot overlay should do nothing
  if there are already overlays.
- overlay_event_filter should cancel the existing delegate if
  another delegate is trying to activate.

BUG=341958
R=jamescook@chromium.org
TEST=manually

Review URL: https://codereview.chromium.org/461093003

Cr-Commit-Position: refs/heads/master@{#289199}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@289199 0039d316-1c4b-4281-b951-d872f2087c98
parent e578cf31
...@@ -689,6 +689,8 @@ ...@@ -689,6 +689,8 @@
'test/test_activation_delegate.h', 'test/test_activation_delegate.h',
'test/test_lock_state_controller_delegate.cc', 'test/test_lock_state_controller_delegate.cc',
'test/test_lock_state_controller_delegate.h', 'test/test_lock_state_controller_delegate.h',
'test/test_overlay_delegate.cc',
'test/test_overlay_delegate.h',
'test/test_screenshot_delegate.cc', 'test/test_screenshot_delegate.cc',
'test/test_screenshot_delegate.h', 'test/test_screenshot_delegate.h',
'test/test_session_state_delegate.cc', 'test/test_session_state_delegate.cc',
...@@ -860,6 +862,7 @@ ...@@ -860,6 +862,7 @@
'wm/window_util_unittest.cc', 'wm/window_util_unittest.cc',
'wm/maximize_mode/workspace_backdrop_delegate.cc', 'wm/maximize_mode/workspace_backdrop_delegate.cc',
'wm/maximize_mode/workspace_backdrop_delegate.h', 'wm/maximize_mode/workspace_backdrop_delegate.h',
'wm/overlay_event_filter_unittest.cc',
'wm/workspace/magnetism_matcher_unittest.cc', 'wm/workspace/magnetism_matcher_unittest.cc',
'wm/workspace/multi_window_resize_controller_unittest.cc', 'wm/workspace/multi_window_resize_controller_unittest.cc',
'wm/workspace/workspace_event_handler_test_helper.cc', 'wm/workspace/workspace_event_handler_test_helper.cc',
......
...@@ -40,7 +40,7 @@ FirstRunHelperImpl::FirstRunHelperImpl() ...@@ -40,7 +40,7 @@ FirstRunHelperImpl::FirstRunHelperImpl()
} }
FirstRunHelperImpl::~FirstRunHelperImpl() { FirstRunHelperImpl::~FirstRunHelperImpl() {
Shell::GetInstance()->overlay_filter()->Deactivate(); Shell::GetInstance()->overlay_filter()->Deactivate(this);
if (IsTrayBubbleOpened()) if (IsTrayBubbleOpened())
CloseTrayBubble(); CloseTrayBubble();
widget_->Close(); widget_->Close();
......
...@@ -43,7 +43,7 @@ KeyboardOverlayView::~KeyboardOverlayView() { ...@@ -43,7 +43,7 @@ KeyboardOverlayView::~KeyboardOverlayView() {
} }
void KeyboardOverlayView::Cancel() { void KeyboardOverlayView::Cancel() {
Shell::GetInstance()->overlay_filter()->Deactivate(); Shell::GetInstance()->overlay_filter()->Deactivate(this);
views::Widget* widget = GetWidget(); views::Widget* widget = GetWidget();
if (widget) if (widget)
widget->Close(); widget->Close();
...@@ -66,10 +66,14 @@ aura::Window* KeyboardOverlayView::GetWindow() { ...@@ -66,10 +66,14 @@ aura::Window* KeyboardOverlayView::GetWindow() {
return GetWidget()->GetNativeWindow(); return GetWidget()->GetNativeWindow();
} }
// static
void KeyboardOverlayView::ShowDialog( void KeyboardOverlayView::ShowDialog(
content::BrowserContext* context, content::BrowserContext* context,
WebContentsHandler* handler, WebContentsHandler* handler,
const GURL& url) { const GURL& url) {
if (Shell::GetInstance()->overlay_filter()->IsActive())
return;
KeyboardOverlayDelegate* delegate = new KeyboardOverlayDelegate( KeyboardOverlayDelegate* delegate = new KeyboardOverlayDelegate(
l10n_util::GetStringUTF16(IDS_ASH_KEYBOARD_OVERLAY_TITLE), url); l10n_util::GetStringUTF16(IDS_ASH_KEYBOARD_OVERLAY_TITLE), url);
KeyboardOverlayView* view = KeyboardOverlayView* view =
......
// Copyright 2014 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 "ash/test/test_overlay_delegate.h"
namespace ash {
namespace test {
TestOverlayDelegate::TestOverlayDelegate()
: cancel_count_(0) {}
TestOverlayDelegate::~TestOverlayDelegate() {}
int TestOverlayDelegate::GetCancelCountAndReset() {
int count = cancel_count_;
cancel_count_ = 0;
return count;
}
void TestOverlayDelegate::Cancel() {
++cancel_count_;
}
bool TestOverlayDelegate::IsCancelingKeyEvent(ui::KeyEvent* event) {
return false;
}
aura::Window* TestOverlayDelegate::GetWindow() {
return NULL;
}
} // namespace test
} // namespace ash
// Copyright 2014 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.
#ifndef ASH_TEST_TEST_OVERLAY_DELEGATE_H_
#define ASH_TEST_TEST_OVERLAY_DELEGATE_H_
#include "ash/wm/overlay_event_filter.h"
namespace ash {
namespace test {
class TestOverlayDelegate : public OverlayEventFilter::Delegate {
public:
TestOverlayDelegate();
virtual ~TestOverlayDelegate();
int GetCancelCountAndReset();
private:
// Overridden from OverlayEventFilter::Delegate:
virtual void Cancel() OVERRIDE;
virtual bool IsCancelingKeyEvent(ui::KeyEvent* event) OVERRIDE;
virtual aura::Window* GetWindow() OVERRIDE;
int cancel_count_;
DISALLOW_COPY_AND_ASSIGN(TestOverlayDelegate);
};
} // namespace test
} // namespace ash
#endif // ASH_TEST_TEST_OVERLAY_DELEGATE_H_
...@@ -56,11 +56,14 @@ void OverlayEventFilter::OnLockStateChanged(bool locked) { ...@@ -56,11 +56,14 @@ void OverlayEventFilter::OnLockStateChanged(bool locked) {
} }
void OverlayEventFilter::Activate(Delegate* delegate) { void OverlayEventFilter::Activate(Delegate* delegate) {
if (delegate_)
delegate_->Cancel();
delegate_ = delegate; delegate_ = delegate;
} }
void OverlayEventFilter::Deactivate() { void OverlayEventFilter::Deactivate(Delegate* delegate) {
delegate_ = NULL; if (delegate_ == delegate)
delegate_ = NULL;
} }
void OverlayEventFilter::Cancel() { void OverlayEventFilter::Cancel() {
...@@ -68,4 +71,8 @@ void OverlayEventFilter::Cancel() { ...@@ -68,4 +71,8 @@ void OverlayEventFilter::Cancel() {
delegate_->Cancel(); delegate_->Cancel();
} }
bool OverlayEventFilter::IsActive() {
return delegate_ != NULL;
}
} // namespace ash } // namespace ash
...@@ -46,11 +46,14 @@ class ASH_EXPORT OverlayEventFilter : public ui::EventHandler, ...@@ -46,11 +46,14 @@ class ASH_EXPORT OverlayEventFilter : public ui::EventHandler,
void Activate(Delegate* delegate); void Activate(Delegate* delegate);
// Ends the filtering of events. // Ends the filtering of events.
void Deactivate(); void Deactivate(Delegate* delegate);
// Cancels the partial screenshot UI. Do nothing if it's not activated. // Cancels the partial screenshot UI. Do nothing if it's not activated.
void Cancel(); void Cancel();
// Returns true if it's currently active.
bool IsActive();
// ui::EventHandler overrides: // ui::EventHandler overrides:
virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE; virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE;
...@@ -60,6 +63,8 @@ class ASH_EXPORT OverlayEventFilter : public ui::EventHandler, ...@@ -60,6 +63,8 @@ class ASH_EXPORT OverlayEventFilter : public ui::EventHandler,
virtual void OnLockStateChanged(bool locked) OVERRIDE; virtual void OnLockStateChanged(bool locked) OVERRIDE;
private: private:
FRIEND_TEST_ALL_PREFIXES(PartialScreenshotViewTest, DontStartOverOverlay);
Delegate* delegate_; Delegate* delegate_;
DISALLOW_COPY_AND_ASSIGN(OverlayEventFilter); DISALLOW_COPY_AND_ASSIGN(OverlayEventFilter);
......
// Copyright 2014 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 "ash/wm/overlay_event_filter.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ash/test/test_overlay_delegate.h"
namespace ash {
namespace test {
typedef AshTestBase OverlayEventFilterTest;
// Tests of the multiple overlay delegates attempt to activate, in that case
// Cancel() of the existing delegate should be called.
// See http://crbug.com/341958
TEST_F(OverlayEventFilterTest, CancelAtActivating) {
TestOverlayDelegate d1;
TestOverlayDelegate d2;
Shell::GetInstance()->overlay_filter()->Activate(&d1);
EXPECT_EQ(0, d1.GetCancelCountAndReset());
EXPECT_EQ(0, d2.GetCancelCountAndReset());
Shell::GetInstance()->overlay_filter()->Activate(&d2);
EXPECT_EQ(1, d1.GetCancelCountAndReset());
EXPECT_EQ(0, d2.GetCancelCountAndReset());
Shell::GetInstance()->overlay_filter()->Cancel();
EXPECT_EQ(0, d1.GetCancelCountAndReset());
EXPECT_EQ(1, d2.GetCancelCountAndReset());
}
} // namespace test
} // namespace ash
...@@ -70,7 +70,7 @@ class PartialScreenshotView::OverlayDelegate ...@@ -70,7 +70,7 @@ class PartialScreenshotView::OverlayDelegate
private: private:
virtual ~OverlayDelegate() { virtual ~OverlayDelegate() {
Shell::GetInstance()->overlay_filter()->Deactivate(); Shell::GetInstance()->overlay_filter()->Deactivate(this);
} }
std::vector<views::Widget*> widgets_; std::vector<views::Widget*> widgets_;
...@@ -83,6 +83,10 @@ std::vector<PartialScreenshotView*> ...@@ -83,6 +83,10 @@ std::vector<PartialScreenshotView*>
PartialScreenshotView::StartPartialScreenshot( PartialScreenshotView::StartPartialScreenshot(
ScreenshotDelegate* screenshot_delegate) { ScreenshotDelegate* screenshot_delegate) {
std::vector<PartialScreenshotView*> views; std::vector<PartialScreenshotView*> views;
if (Shell::GetInstance()->overlay_filter()->IsActive())
return views;
OverlayDelegate* overlay_delegate = new OverlayDelegate(); OverlayDelegate* overlay_delegate = new OverlayDelegate();
aura::Window::Windows root_windows = Shell::GetAllRootWindows(); aura::Window::Windows root_windows = Shell::GetAllRootWindows();
for (aura::Window::Windows::iterator it = root_windows.begin(); for (aura::Window::Windows::iterator it = root_windows.begin();
......
...@@ -8,33 +8,51 @@ ...@@ -8,33 +8,51 @@
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/shell_window_ids.h" #include "ash/shell_window_ids.h"
#include "ash/test/ash_test_base.h" #include "ash/test/ash_test_base.h"
#include "ash/test/test_overlay_delegate.h"
#include "ash/test/test_screenshot_delegate.h" #include "ash/test/test_screenshot_delegate.h"
#include "ui/aura/window_event_dispatcher.h" #include "ui/aura/window_event_dispatcher.h"
#include "ui/events/test/event_generator.h" #include "ui/events/test/event_generator.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_observer.h"
namespace ash { namespace ash {
class PartialScreenshotViewTest : public test::AshTestBase { class PartialScreenshotViewTest : public test::AshTestBase,
public views::WidgetObserver {
public: public:
PartialScreenshotViewTest() : view_(NULL) {} PartialScreenshotViewTest() : view_(NULL) {}
virtual ~PartialScreenshotViewTest() {} virtual ~PartialScreenshotViewTest() {
if (view_)
view_->GetWidget()->RemoveObserver(this);
}
virtual void SetUp() OVERRIDE { void StartPartialScreenshot() {
test::AshTestBase::SetUp();
std::vector<PartialScreenshotView*> views = std::vector<PartialScreenshotView*> views =
PartialScreenshotView::StartPartialScreenshot(GetScreenshotDelegate()); PartialScreenshotView::StartPartialScreenshot(GetScreenshotDelegate());
ASSERT_EQ(1u, views.size()); if (!views.empty()) {
view_ = views[0]; view_ = views[0];
view_->GetWidget()->AddObserver(this);
}
} }
protected: protected:
PartialScreenshotView* view_; PartialScreenshotView* view_;
private: private:
// views::WidgetObserver:
virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE {
if (view_ && view_->GetWidget() == widget)
view_ = NULL;
widget->RemoveObserver(this);
}
DISALLOW_COPY_AND_ASSIGN(PartialScreenshotViewTest); DISALLOW_COPY_AND_ASSIGN(PartialScreenshotViewTest);
}; };
TEST_F(PartialScreenshotViewTest, BasicMouse) { TEST_F(PartialScreenshotViewTest, BasicMouse) {
StartPartialScreenshot();
ASSERT_TRUE(view_);
ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
generator.MoveMouseTo(100, 100); generator.MoveMouseTo(100, 100);
...@@ -53,6 +71,9 @@ TEST_F(PartialScreenshotViewTest, BasicMouse) { ...@@ -53,6 +71,9 @@ TEST_F(PartialScreenshotViewTest, BasicMouse) {
} }
TEST_F(PartialScreenshotViewTest, BasicTouch) { TEST_F(PartialScreenshotViewTest, BasicTouch) {
StartPartialScreenshot();
ASSERT_TRUE(view_);
ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
generator.set_current_location(gfx::Point(100,100)); generator.set_current_location(gfx::Point(100,100));
...@@ -74,4 +95,28 @@ TEST_F(PartialScreenshotViewTest, BasicTouch) { ...@@ -74,4 +95,28 @@ TEST_F(PartialScreenshotViewTest, BasicTouch) {
EXPECT_EQ("100,100 100x100", GetScreenshotDelegate()->last_rect().ToString()); EXPECT_EQ("100,100 100x100", GetScreenshotDelegate()->last_rect().ToString());
} }
// Partial screenshot session should not start when there is already another
// overlay. See: http://crbug.com/341958
TEST_F(PartialScreenshotViewTest, DontStartOverOverlay) {
OverlayEventFilter* overlay_filter = Shell::GetInstance()->overlay_filter();
test::TestOverlayDelegate delegate;
overlay_filter->Activate(&delegate);
EXPECT_EQ(&delegate, overlay_filter->delegate_);
StartPartialScreenshot();
EXPECT_TRUE(view_ == NULL);
EXPECT_EQ(&delegate, overlay_filter->delegate_);
overlay_filter->Deactivate(&delegate);
StartPartialScreenshot();
EXPECT_TRUE(view_ != NULL);
// Someone else attempts to activate the overlay session, which should cancel
// the current partial screenshot session.
overlay_filter->Activate(&delegate);
RunAllPendingInMessageLoop();
EXPECT_EQ(&delegate, overlay_filter->delegate_);
EXPECT_TRUE(view_ == NULL);
}
} // namespace ash } // namespace ash
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment