Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(100)

Side by Side Diff: ui/views/controls/menu/menu_controller_unittest.cc

Issue 279073002: views: Terminate the nested message-loop correctly. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ui/views/controls/menu/menu_controller.h"
6
7 #include "base/run_loop.h"
8 #include "ui/aura/window.h"
9 #include "ui/events/platform/platform_event_source.h"
10 #include "ui/views/test/views_test_base.h"
11 #include "ui/wm/public/dispatcher_client.h"
12
13 #if defined(OS_WIN)
14 #include "base/message_loop/message_pump_dispatcher.h"
15 #elif defined(USE_X11)
16 #include <X11/Xlib.h>
17 #undef Bool
18 #undef None
19 #endif
20
21 namespace views {
22
23 namespace {
24
25 class TestPlatformEventSource : public ui::PlatformEventSource {
26 public:
27 TestPlatformEventSource() {}
28 virtual ~TestPlatformEventSource() {}
29
30 uint32_t Dispatch(const ui::PlatformEvent& event) {
31 return DispatchEvent(event);
32 }
33
34 private:
35 DISALLOW_COPY_AND_ASSIGN(TestPlatformEventSource);
36 };
37
38 class TestDispatcherClient : public aura::client::DispatcherClient {
39 public:
40 TestDispatcherClient() : dispatcher_(NULL) {}
41 virtual ~TestDispatcherClient() {}
42
43 base::MessagePumpDispatcher* dispatcher() {
44 return dispatcher_;
45 }
46
47 // aura::client::DispatcherClient:
48 virtual void RunWithDispatcher(
49 base::MessagePumpDispatcher* dispatcher) OVERRIDE {
50 base::AutoReset<base::MessagePumpDispatcher*> reset_dispatcher(&dispatcher_,
51 dispatcher);
52 base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
53 base::MessageLoop::ScopedNestableTaskAllower allow(loop);
54 base::RunLoop run_loop;
55 quit_callback_ = run_loop.QuitClosure();
56 run_loop.Run();
57 }
58
59 virtual void QuitNestedMessageLoop() OVERRIDE { quit_callback_.Run(); }
60
61 private:
62 base::MessagePumpDispatcher* dispatcher_;
63 base::Closure quit_callback_;
64
65 DISALLOW_COPY_AND_ASSIGN(TestDispatcherClient);
66 };
67
68 } // namespace
69
70 class MenuControllerTest : public ViewsTestBase {
71 public:
72 MenuControllerTest() : controller_(NULL) {}
73 virtual ~MenuControllerTest() {}
74
75 // Dispatches |count| number of items, each in a separate iteration of the
76 // message-loop, by posting a task.
77 void Step3_DispatchEvents(int count) {
78 base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
79 base::MessageLoop::ScopedNestableTaskAllower allow(loop);
80 controller_->exit_type_ = MenuController::EXIT_ALL;
81
82 #if defined(USE_X11)
83 XEvent xevent;
84 memset(&xevent, 0, sizeof(xevent));
85 event_source_.Dispatch(&xevent);
86 #else
87 MSG msg;
88 memset(&msg, 0, sizeof(MSG));
89 dispatcher_client_.dispatcher()->Dispatch(msg);
90 #endif
91
92 if (count) {
93 base::MessageLoop::current()->PostTask(
94 FROM_HERE,
95 base::Bind(&MenuControllerTest::Step3_DispatchEvents,
96 base::Unretained(this),
97 count - 1));
98 } else {
99 EXPECT_TRUE(run_loop_->running());
100 run_loop_->Quit();
101 }
102 }
103
104 // Runs a nested message-loop that does not involve the menu itself.
105 void Step2_RunNestedLoop() {
106 base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
107 base::MessageLoop::ScopedNestableTaskAllower allow(loop);
108 base::MessageLoop::current()->PostTask(
109 FROM_HERE,
110 base::Bind(&MenuControllerTest::Step3_DispatchEvents,
111 base::Unretained(this),
112 3));
113 run_loop_.reset(new base::RunLoop());
114 run_loop_->Run();
115 }
116
117 void Step1_RunMenu() {
118 Widget widget;
119 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
120 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
121 widget.Init(params);
122 widget.Show();
123
124 aura::client::SetDispatcherClient(widget.GetNativeWindow()->GetRootWindow(),
125 &dispatcher_client_);
126
127 controller_ = new MenuController(NULL, true, NULL);
128 controller_->owner_ = &widget;
129 base::MessageLoop::current()->PostTask(
130 FROM_HERE,
131 base::Bind(&MenuControllerTest::Step2_RunNestedLoop,
132 base::Unretained(this)));
133 controller_->RunMessageLoop(false);
134 }
135
136 private:
137 MenuController* controller_;
138 scoped_ptr<base::RunLoop> run_loop_;
139 TestPlatformEventSource event_source_;
140 TestDispatcherClient dispatcher_client_;
141
142 DISALLOW_COPY_AND_ASSIGN(MenuControllerTest);
143 };
144
145 TEST_F(MenuControllerTest, Basic) {
146 base::MessageLoop::ScopedNestableTaskAllower allow_nested(
147 base::MessageLoop::current());
148 message_loop()->PostTask(
149 FROM_HERE,
150 base::Bind(&MenuControllerTest::Step1_RunMenu, base::Unretained(this)));
151 }
152
153 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/controls/menu/menu_controller.cc ('k') | ui/views/controls/menu/menu_event_dispatcher_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698