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

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

Issue 2772863002: Delete MenuController Nested Message Loop (Closed)
Patch Set: remove another async flag Created 3 years, 9 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
« no previous file with comments | « ui/views/controls/menu/menu_controller.cc ('k') | ui/views/controls/menu/menu_message_loop.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/views/controls/menu/menu_controller.h" 5 #include "ui/views/controls/menu/menu_controller.h"
6 6
7 #include "base/callback.h" 7 #include "base/callback.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/macros.h" 9 #include "base/macros.h"
10 #include "base/run_loop.h"
10 #include "base/single_thread_task_runner.h" 11 #include "base/single_thread_task_runner.h"
11 #include "base/strings/utf_string_conversions.h" 12 #include "base/strings/utf_string_conversions.h"
12 #include "base/threading/thread_task_runner_handle.h" 13 #include "base/threading/thread_task_runner_handle.h"
13 #include "build/build_config.h" 14 #include "build/build_config.h"
14 #include "ui/aura/scoped_window_targeter.h" 15 #include "ui/aura/scoped_window_targeter.h"
15 #include "ui/aura/window.h" 16 #include "ui/aura/window.h"
16 #include "ui/events/event.h" 17 #include "ui/events/event.h"
17 #include "ui/events/event_constants.h" 18 #include "ui/events/event_constants.h"
18 #include "ui/events/event_handler.h" 19 #include "ui/events/event_handler.h"
19 #include "ui/events/event_utils.h" 20 #include "ui/events/event_utils.h"
20 #include "ui/events/null_event_targeter.h" 21 #include "ui/events/null_event_targeter.h"
21 #include "ui/events/test/event_generator.h" 22 #include "ui/events/test/event_generator.h"
22 #include "ui/gfx/geometry/point.h" 23 #include "ui/gfx/geometry/point.h"
23 #include "ui/gfx/geometry/rect.h" 24 #include "ui/gfx/geometry/rect.h"
24 #include "ui/views/controls/menu/menu_controller_delegate.h" 25 #include "ui/views/controls/menu/menu_controller_delegate.h"
25 #include "ui/views/controls/menu/menu_delegate.h" 26 #include "ui/views/controls/menu/menu_delegate.h"
26 #include "ui/views/controls/menu/menu_host.h" 27 #include "ui/views/controls/menu/menu_host.h"
27 #include "ui/views/controls/menu/menu_host_root_view.h" 28 #include "ui/views/controls/menu/menu_host_root_view.h"
28 #include "ui/views/controls/menu/menu_item_view.h" 29 #include "ui/views/controls/menu/menu_item_view.h"
29 #include "ui/views/controls/menu/menu_message_loop.h"
30 #include "ui/views/controls/menu/menu_scroll_view_container.h" 30 #include "ui/views/controls/menu/menu_scroll_view_container.h"
31 #include "ui/views/controls/menu/submenu_view.h" 31 #include "ui/views/controls/menu/submenu_view.h"
32 #include "ui/views/test/menu_test_utils.h" 32 #include "ui/views/test/menu_test_utils.h"
33 #include "ui/views/test/test_views_delegate.h" 33 #include "ui/views/test/test_views_delegate.h"
34 #include "ui/views/test/views_test_base.h" 34 #include "ui/views/test/views_test_base.h"
35 #include "ui/views/widget/root_view.h" 35 #include "ui/views/widget/root_view.h"
36 36
37 #if defined(USE_AURA) 37 #if defined(USE_AURA)
38 #include "ui/aura/client/drag_drop_client.h" 38 #include "ui/aura/client/drag_drop_client.h"
39 #include "ui/aura/scoped_window_targeter.h" 39 #include "ui/aura/scoped_window_targeter.h"
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 } 146 }
147 } 147 }
148 148
149 int outstanding_touches() const { return outstanding_touches_; } 149 int outstanding_touches() const { return outstanding_touches_; }
150 150
151 private: 151 private:
152 int outstanding_touches_; 152 int outstanding_touches_;
153 DISALLOW_COPY_AND_ASSIGN(TestEventHandler); 153 DISALLOW_COPY_AND_ASSIGN(TestEventHandler);
154 }; 154 };
155 155
156 // A wrapper around MenuMessageLoop that can be used to track whether a message
157 // loop is running or not.
158 class TestMenuMessageLoop : public MenuMessageLoop {
159 public:
160 explicit TestMenuMessageLoop(std::unique_ptr<MenuMessageLoop> original);
161 ~TestMenuMessageLoop() override;
162
163 bool is_running() const { return is_running_; }
164
165 // MenuMessageLoop:
166 void QuitNow() override;
167
168 private:
169 // MenuMessageLoop:
170 void Run() override;
171
172 std::unique_ptr<MenuMessageLoop> original_;
173 bool is_running_;
174
175 DISALLOW_COPY_AND_ASSIGN(TestMenuMessageLoop);
176 };
177
178 TestMenuMessageLoop::TestMenuMessageLoop(
179 std::unique_ptr<MenuMessageLoop> original)
180 : original_(std::move(original)) {
181 DCHECK(original_);
182 }
183
184 TestMenuMessageLoop::~TestMenuMessageLoop() {}
185
186 void TestMenuMessageLoop::Run() {
187 is_running_ = true;
188 original_->Run();
189 }
190
191 void TestMenuMessageLoop::QuitNow() {
192 is_running_ = false;
193 original_->QuitNow();
194 }
195
196 #if defined(USE_AURA) 156 #if defined(USE_AURA)
197 // A DragDropClient which does not trigger a nested message loop. Instead a 157 // A DragDropClient which does not trigger a nested message loop. Instead a
198 // callback is triggered during StartDragAndDrop in order to allow testing. 158 // callback is triggered during StartDragAndDrop in order to allow testing.
199 class TestDragDropClient : public aura::client::DragDropClient { 159 class TestDragDropClient : public aura::client::DragDropClient {
200 public: 160 public:
201 explicit TestDragDropClient(const base::Closure& callback) 161 explicit TestDragDropClient(const base::Closure& callback)
202 : start_drag_and_drop_callback_(callback), drag_in_progress_(false) {} 162 : start_drag_and_drop_callback_(callback), drag_in_progress_(false) {}
203 ~TestDragDropClient() override {} 163 ~TestDragDropClient() override {}
204 164
205 // aura::client::DragDropClient: 165 // aura::client::DragDropClient:
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 269
310 void ReleaseTouchId(int id) { 270 void ReleaseTouchId(int id) {
311 event_generator_->ReleaseTouchId(id); 271 event_generator_->ReleaseTouchId(id);
312 } 272 }
313 273
314 void PressKey(ui::KeyboardCode key_code) { 274 void PressKey(ui::KeyboardCode key_code) {
315 event_generator_->PressKey(key_code, 0); 275 event_generator_->PressKey(key_code, 0);
316 } 276 }
317 277
318 #if defined(OS_LINUX) && defined(USE_X11) 278 #if defined(OS_LINUX) && defined(USE_X11)
319 void TestEventTargeter() {
320 {
321 // With the |ui::NullEventTargeter| instantiated and assigned we expect
322 // the menu to not handle the key event.
323 aura::ScopedWindowTargeter scoped_targeter(
324 owner()->GetNativeWindow()->GetRootWindow(),
325 std::unique_ptr<ui::EventTargeter>(new ui::NullEventTargeter));
326 event_generator_->PressKey(ui::VKEY_ESCAPE, 0);
327 EXPECT_EQ(MenuController::EXIT_NONE, menu_exit_type());
328 }
329 // Now that the targeter has been destroyed, expect to exit the menu
330 // normally when hitting escape.
331 event_generator_->PressKey(ui::VKEY_ESCAPE, 0);
332 EXPECT_EQ(MenuController::EXIT_ALL, menu_exit_type());
333 }
334
335 // Verifies that a non-nested menu fully closes when receiving an escape key. 279 // Verifies that a non-nested menu fully closes when receiving an escape key.
336 void TestAsyncEscapeKey() { 280 void TestAsyncEscapeKey() {
337 ui::KeyEvent event(ui::EventType::ET_KEY_PRESSED, ui::VKEY_ESCAPE, 0); 281 ui::KeyEvent event(ui::EventType::ET_KEY_PRESSED, ui::VKEY_ESCAPE, 0);
338 menu_controller_->OnWillDispatchKeyEvent(&event); 282 menu_controller_->OnWillDispatchKeyEvent(&event);
339 EXPECT_EQ(MenuController::EXIT_ALL, menu_exit_type()); 283 EXPECT_EQ(MenuController::EXIT_ALL, menu_exit_type());
340 } 284 }
341
342 #endif // defined(OS_LINUX) && defined(USE_X11) 285 #endif // defined(OS_LINUX) && defined(USE_X11)
343 286
344 #if defined(USE_AURA) 287 #if defined(USE_AURA)
345 // Verifies that an open menu receives a cancel event, and closes. 288 // Verifies that an open menu receives a cancel event, and closes.
346 void TestCancelEvent() { 289 void TestCancelEvent() {
347 EXPECT_EQ(MenuController::EXIT_NONE, menu_controller_->exit_type()); 290 EXPECT_EQ(MenuController::EXIT_NONE, menu_controller_->exit_type());
348 ui::CancelModeEvent cancel_event; 291 ui::CancelModeEvent cancel_event;
349 event_generator_->Dispatch(&cancel_event); 292 event_generator_->Dispatch(&cancel_event);
350 EXPECT_EQ(MenuController::EXIT_ALL, menu_controller_->exit_type()); 293 EXPECT_EQ(MenuController::EXIT_ALL, menu_controller_->exit_type());
351 } 294 }
352 #endif // defined(USE_AURA) 295 #endif // defined(USE_AURA)
353 296
354 // Verifies the state of the |menu_controller_| before destroying it. 297 // Verifies the state of the |menu_controller_| before destroying it.
355 void VerifyDragCompleteThenDestroy() { 298 void VerifyDragCompleteThenDestroy() {
356 EXPECT_FALSE(menu_controller()->drag_in_progress()); 299 EXPECT_FALSE(menu_controller()->drag_in_progress());
357 EXPECT_EQ(MenuController::EXIT_ALL, menu_controller()->exit_type()); 300 EXPECT_EQ(MenuController::EXIT_ALL, menu_controller()->exit_type());
358 DestroyMenuController(); 301 DestroyMenuController();
359 } 302 }
360 303
361 // Setups |menu_controller_delegate_| to be destroyed when OnMenuClosed is 304 // Setups |menu_controller_delegate_| to be destroyed when OnMenuClosed is
362 // called. 305 // called.
363 void TestDragCompleteThenDestroyOnMenuClosed() { 306 void TestDragCompleteThenDestroyOnMenuClosed() {
364 menu_controller_delegate_->set_on_menu_closed_callback( 307 menu_controller_delegate_->set_on_menu_closed_callback(
365 base::Bind(&MenuControllerTest::VerifyDragCompleteThenDestroy, 308 base::Bind(&MenuControllerTest::VerifyDragCompleteThenDestroy,
366 base::Unretained(this))); 309 base::Unretained(this)));
367 } 310 }
368 311
369 void TestAsynchronousNestedExitAll() { 312 void TestAsynchronousNestedExitAll() {
370 ASSERT_TRUE(test_message_loop_->is_running());
371
372 std::unique_ptr<TestMenuControllerDelegate> nested_delegate( 313 std::unique_ptr<TestMenuControllerDelegate> nested_delegate(
373 new TestMenuControllerDelegate()); 314 new TestMenuControllerDelegate());
374 315
375 menu_controller()->AddNestedDelegate(nested_delegate.get()); 316 menu_controller()->AddNestedDelegate(nested_delegate.get());
376 menu_controller()->SetAsyncRun(true);
377 317
378 int mouse_event_flags = 0; 318 int mouse_event_flags = 0;
379 MenuItemView* run_result = menu_controller()->Run( 319 MenuItemView* run_result = menu_controller()->Run(
380 owner(), nullptr, menu_item(), gfx::Rect(), MENU_ANCHOR_TOPLEFT, false, 320 owner(), nullptr, menu_item(), gfx::Rect(), MENU_ANCHOR_TOPLEFT, false,
381 false, &mouse_event_flags); 321 false, &mouse_event_flags);
382 EXPECT_EQ(run_result, nullptr); 322 EXPECT_EQ(run_result, nullptr);
383 323
384 // Exit all menus and check that the parent menu's message loop is 324 // Exit all menus and check that the parent menu's message loop is
385 // terminated. 325 // terminated.
386 menu_controller()->Cancel(MenuController::EXIT_ALL); 326 menu_controller()->Cancel(MenuController::EXIT_ALL);
387 EXPECT_EQ(MenuController::EXIT_ALL, menu_controller()->exit_type()); 327 EXPECT_EQ(MenuController::EXIT_ALL, menu_controller()->exit_type());
388 EXPECT_FALSE(test_message_loop_->is_running());
389 } 328 }
390 329
391 void TestAsynchronousNestedExitOutermost() { 330 void TestAsynchronousNestedExitOutermost() {
392 ASSERT_TRUE(test_message_loop_->is_running());
393
394 std::unique_ptr<TestMenuControllerDelegate> nested_delegate( 331 std::unique_ptr<TestMenuControllerDelegate> nested_delegate(
395 new TestMenuControllerDelegate()); 332 new TestMenuControllerDelegate());
396 333
397 menu_controller()->AddNestedDelegate(nested_delegate.get()); 334 menu_controller()->AddNestedDelegate(nested_delegate.get());
398 menu_controller()->SetAsyncRun(true);
399 335
400 int mouse_event_flags = 0; 336 int mouse_event_flags = 0;
401 MenuItemView* run_result = menu_controller()->Run( 337 MenuItemView* run_result = menu_controller()->Run(
402 owner(), nullptr, menu_item(), gfx::Rect(), MENU_ANCHOR_TOPLEFT, false, 338 owner(), nullptr, menu_item(), gfx::Rect(), MENU_ANCHOR_TOPLEFT, false,
403 false, &mouse_event_flags); 339 false, &mouse_event_flags);
404 EXPECT_EQ(run_result, nullptr); 340 EXPECT_EQ(run_result, nullptr);
405 341
406 // Exit the nested menu and check that the parent menu's message loop is 342 // Exit the nested menu and check that the parent menu's message loop is
407 // still running. 343 // still running.
408 menu_controller()->Cancel(MenuController::EXIT_OUTERMOST); 344 menu_controller()->Cancel(MenuController::EXIT_OUTERMOST);
409 EXPECT_EQ(MenuController::EXIT_NONE, menu_controller()->exit_type()); 345 EXPECT_EQ(MenuController::EXIT_NONE, menu_controller()->exit_type());
410 EXPECT_TRUE(test_message_loop_->is_running());
411 346
412 // Now, exit the parent menu and check that its message loop is terminated. 347 // Now, exit the parent menu and check that its message loop is terminated.
413 menu_controller()->Cancel(MenuController::EXIT_OUTERMOST); 348 menu_controller()->Cancel(MenuController::EXIT_OUTERMOST);
414 EXPECT_EQ(MenuController::EXIT_OUTERMOST, menu_controller()->exit_type()); 349 EXPECT_EQ(MenuController::EXIT_OUTERMOST, menu_controller()->exit_type());
415 EXPECT_FALSE(test_message_loop_->is_running());
416 } 350 }
417 351
418 // This nested an asynchronous delegate onto a menu with a nested message 352 // This nested an asynchronous delegate onto a menu with a nested message
419 // loop, then kills the loop. Simulates the loop being killed not by 353 // loop, then kills the loop. Simulates the loop being killed not by
420 // MenuController. 354 // MenuController.
421 void TestNestedMessageLoopKillsItself( 355 void TestNestedMessageLoopKillsItself(
422 TestMenuControllerDelegate* nested_delegate) { 356 TestMenuControllerDelegate* nested_delegate) {
423 menu_controller_->AddNestedDelegate(nested_delegate); 357 menu_controller_->AddNestedDelegate(nested_delegate);
424 menu_controller_->SetAsyncRun(true);
425
426 test_message_loop_->QuitNow();
427 } 358 }
428 359
429 // Tests destroying the active |menu_controller_| and replacing it with a new 360 // Tests destroying the active |menu_controller_| and replacing it with a new
430 // active instance. 361 // active instance.
431 void TestMenuControllerReplacementDuringDrag() { 362 void TestMenuControllerReplacementDuringDrag() {
432 DestroyMenuController(); 363 DestroyMenuController();
433 menu_item()->GetSubmenu()->Close(); 364 menu_item()->GetSubmenu()->Close();
434 menu_controller_ = 365 menu_controller_ =
435 new MenuController(true, menu_controller_delegate_.get()); 366 new MenuController(true, menu_controller_delegate_.get());
436 menu_controller_->owner_ = owner_.get(); 367 menu_controller_->owner_ = owner_.get();
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 MenuItemView* FindPreviousSelectableMenuItem(MenuItemView* parent, 434 MenuItemView* FindPreviousSelectableMenuItem(MenuItemView* parent,
504 int index) { 435 int index) {
505 return menu_controller_->FindNextSelectableMenuItem( 436 return menu_controller_->FindNextSelectableMenuItem(
506 parent, index, MenuController::INCREMENT_SELECTION_UP); 437 parent, index, MenuController::INCREMENT_SELECTION_UP);
507 } 438 }
508 439
509 internal::MenuControllerDelegate* GetCurrentDelegate() { 440 internal::MenuControllerDelegate* GetCurrentDelegate() {
510 return menu_controller_->delegate_; 441 return menu_controller_->delegate_;
511 } 442 }
512 443
513 bool IsAsyncRun() { return menu_controller_->async_run_; }
514
515 bool IsShowing() { return menu_controller_->showing_; } 444 bool IsShowing() { return menu_controller_->showing_; }
516 445
517 MenuHost* GetMenuHost(SubmenuView* submenu) { return submenu->host_; } 446 MenuHost* GetMenuHost(SubmenuView* submenu) { return submenu->host_; }
518 447
519 MenuHostRootView* CreateMenuHostRootView(MenuHost* host) { 448 MenuHostRootView* CreateMenuHostRootView(MenuHost* host) {
520 return static_cast<MenuHostRootView*>(host->CreateRootView()); 449 return static_cast<MenuHostRootView*>(host->CreateRootView());
521 } 450 }
522 451
523 void MenuHostOnDragWillStart(MenuHost* host) { host->OnDragWillStart(); } 452 void MenuHostOnDragWillStart(MenuHost* host) { host->OnDragWillStart(); }
524 453
(...skipping 16 matching lines...) Expand all
541 const ui::LocatedEvent* event) { 470 const ui::LocatedEvent* event) {
542 menu_controller_->SetSelectionOnPointerDown(source, event); 471 menu_controller_->SetSelectionOnPointerDown(source, event);
543 } 472 }
544 473
545 // Note that coordinates of events passed to MenuController must be in that of 474 // Note that coordinates of events passed to MenuController must be in that of
546 // the MenuScrollViewContainer. 475 // the MenuScrollViewContainer.
547 void ProcessMouseMoved(SubmenuView* source, const ui::MouseEvent& event) { 476 void ProcessMouseMoved(SubmenuView* source, const ui::MouseEvent& event) {
548 menu_controller_->OnMouseMoved(source, event); 477 menu_controller_->OnMouseMoved(source, event);
549 } 478 }
550 479
551 void RunMenu() {
552 #if defined(USE_AURA)
553 std::unique_ptr<MenuPreTargetHandler> menu_pre_target_handler(
554 new MenuPreTargetHandler(menu_controller_, owner_.get()));
555 #endif
556
557 menu_controller_->message_loop_depth_++;
558 menu_controller_->RunMessageLoop();
559 menu_controller_->message_loop_depth_--;
560 }
561
562 void Accept(MenuItemView* item, int event_flags) { 480 void Accept(MenuItemView* item, int event_flags) {
563 menu_controller_->Accept(item, event_flags); 481 menu_controller_->Accept(item, event_flags);
564 } 482 }
565 483
566 void InstallTestMenuMessageLoop() {
567 test_message_loop_ =
568 new TestMenuMessageLoop(std::move(menu_controller_->message_loop_));
569 menu_controller_->message_loop_.reset(test_message_loop_);
570 }
571
572 // Causes the |menu_controller_| to begin dragging. Use TestDragDropClient to 484 // Causes the |menu_controller_| to begin dragging. Use TestDragDropClient to
573 // avoid nesting message loops. 485 // avoid nesting message loops.
574 void StartDrag() { 486 void StartDrag() {
575 const gfx::Point location; 487 const gfx::Point location;
576 menu_controller_->state_.item = menu_item()->GetSubmenu()->GetMenuItemAt(0); 488 menu_controller_->state_.item = menu_item()->GetSubmenu()->GetMenuItemAt(0);
577 menu_controller_->StartDrag( 489 menu_controller_->StartDrag(
578 menu_item()->GetSubmenu()->GetMenuItemAt(0)->CreateSubmenu(), location); 490 menu_item()->GetSubmenu()->GetMenuItemAt(0)->CreateSubmenu(), location);
579 } 491 }
580 492
581 Widget* owner() { return owner_.get(); } 493 Widget* owner() { return owner_.get(); }
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
670 582
671 // Not owned. 583 // Not owned.
672 DestructingTestViewsDelegate* test_views_delegate_; 584 DestructingTestViewsDelegate* test_views_delegate_;
673 585
674 std::unique_ptr<Widget> owner_; 586 std::unique_ptr<Widget> owner_;
675 std::unique_ptr<ui::test::EventGenerator> event_generator_; 587 std::unique_ptr<ui::test::EventGenerator> event_generator_;
676 std::unique_ptr<TestMenuItemViewShown> menu_item_; 588 std::unique_ptr<TestMenuItemViewShown> menu_item_;
677 std::unique_ptr<TestMenuControllerDelegate> menu_controller_delegate_; 589 std::unique_ptr<TestMenuControllerDelegate> menu_controller_delegate_;
678 std::unique_ptr<MenuDelegate> menu_delegate_; 590 std::unique_ptr<MenuDelegate> menu_delegate_;
679 MenuController* menu_controller_; 591 MenuController* menu_controller_;
680 TestMenuMessageLoop* test_message_loop_;
681 592
682 DISALLOW_COPY_AND_ASSIGN(MenuControllerTest); 593 DISALLOW_COPY_AND_ASSIGN(MenuControllerTest);
683 }; 594 };
684 595
685 #if defined(OS_LINUX) && defined(USE_X11) 596 #if defined(OS_LINUX) && defined(USE_X11)
686 // Tests that an event targeter which blocks events will be honored by the menu 597 // Tests that an event targeter which blocks events will be honored by the menu
687 // event dispatcher. 598 // event dispatcher.
688 TEST_F(MenuControllerTest, EventTargeter) { 599 TEST_F(MenuControllerTest, EventTargeter) {
689 base::ThreadTaskRunnerHandle::Get()->PostTask( 600 {
690 FROM_HERE, base::Bind(&MenuControllerTest::TestEventTargeter, 601 // With the |ui::NullEventTargeter| instantiated and assigned we expect
691 base::Unretained(this))); 602 // the menu to not handle the key event.
692 RunMenu(); 603 aura::ScopedWindowTargeter scoped_targeter(
693 } 604 owner()->GetNativeWindow()->GetRootWindow(),
694 605 std::unique_ptr<ui::EventTargeter>(new ui::NullEventTargeter));
695 // Tests that an non-nested menu receiving an escape key will fully shut. This 606 PressKey(ui::VKEY_ESCAPE);
696 // should not crash by attempting to retarget the key to an inner menu. 607 base::RunLoop().RunUntilIdle();
697 TEST_F(MenuControllerTest, AsyncEscapeKey) { 608 EXPECT_EQ(MenuController::EXIT_NONE, menu_exit_type());
698 menu_controller()->SetAsyncRun(true); 609 }
610 // Now that the targeter has been destroyed, expect to exit the menu
611 // normally when hitting escape.
699 TestAsyncEscapeKey(); 612 TestAsyncEscapeKey();
700 } 613 }
701 614
702 #endif // defined(OS_LINUX) && defined(USE_X11) 615 #endif // defined(OS_LINUX) && defined(USE_X11)
703 616
704 #if defined(USE_X11) 617 #if defined(USE_X11)
705 // Tests that touch event ids are released correctly. See crbug.com/439051 for 618 // Tests that touch event ids are released correctly. See crbug.com/439051 for
706 // details. When the ids aren't managed correctly, we get stuck down touches. 619 // details. When the ids aren't managed correctly, we get stuck down touches.
707 TEST_F(MenuControllerTest, TouchIdsReleasedCorrectly) { 620 TEST_F(MenuControllerTest, TouchIdsReleasedCorrectly) {
708 TestEventHandler test_event_handler; 621 TestEventHandler test_event_handler;
709 owner()->GetNativeWindow()->GetRootWindow()->AddPreTargetHandler( 622 owner()->GetNativeWindow()->GetRootWindow()->AddPreTargetHandler(
710 &test_event_handler); 623 &test_event_handler);
711 624
712 std::vector<int> devices; 625 std::vector<int> devices;
713 devices.push_back(1); 626 devices.push_back(1);
714 ui::SetUpTouchDevicesForTest(devices); 627 ui::SetUpTouchDevicesForTest(devices);
715 628
716 event_generator()->PressTouchId(0); 629 event_generator()->PressTouchId(0);
717 event_generator()->PressTouchId(1); 630 event_generator()->PressTouchId(1);
718 event_generator()->ReleaseTouchId(0); 631 event_generator()->ReleaseTouchId(0);
719 632
720 base::ThreadTaskRunnerHandle::Get()->PostTask( 633 int mouse_event_flags = 0;
721 FROM_HERE, base::Bind(&MenuControllerTest::ReleaseTouchId, 634 MenuItemView* run_result = menu_controller()->Run(
722 base::Unretained(this), 1)); 635 owner(), nullptr, menu_item(), gfx::Rect(), MENU_ANCHOR_TOPLEFT, false,
636 false, &mouse_event_flags);
637 EXPECT_EQ(run_result, nullptr);
723 638
724 base::ThreadTaskRunnerHandle::Get()->PostTask( 639 MenuControllerTest::ReleaseTouchId(1);
725 FROM_HERE, base::Bind(&MenuControllerTest::PressKey, 640 TestAsyncEscapeKey();
726 base::Unretained(this), ui::VKEY_ESCAPE));
727
728 RunMenu();
729 641
730 EXPECT_EQ(MenuController::EXIT_ALL, menu_exit_type()); 642 EXPECT_EQ(MenuController::EXIT_ALL, menu_exit_type());
731 EXPECT_EQ(0, test_event_handler.outstanding_touches()); 643 EXPECT_EQ(0, test_event_handler.outstanding_touches());
732 644
733 owner()->GetNativeWindow()->GetRootWindow()->RemovePreTargetHandler( 645 owner()->GetNativeWindow()->GetRootWindow()->RemovePreTargetHandler(
734 &test_event_handler); 646 &test_event_handler);
735 } 647 }
736 #endif // defined(USE_X11) 648 #endif // defined(USE_X11)
737 649
738 // Tests that initial selected menu items are correct when items are enabled or 650 // Tests that initial selected menu items are correct when items are enabled or
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
1026 // Increment twice to move selection to |button2|. 938 // Increment twice to move selection to |button2|.
1027 IncrementSelection(); 939 IncrementSelection();
1028 IncrementSelection(); 940 IncrementSelection();
1029 EXPECT_EQ(5, pending_state_item()->GetCommand()); 941 EXPECT_EQ(5, pending_state_item()->GetCommand());
1030 EXPECT_FALSE(button1->IsHotTracked()); 942 EXPECT_FALSE(button1->IsHotTracked());
1031 EXPECT_TRUE(button2->IsHotTracked()); 943 EXPECT_TRUE(button2->IsHotTracked());
1032 EXPECT_FALSE(button3->IsHotTracked()); 944 EXPECT_FALSE(button3->IsHotTracked());
1033 EXPECT_EQ(button2, GetHotButton()); 945 EXPECT_EQ(button2, GetHotButton());
1034 946
1035 MenuController* controller = menu_controller(); 947 MenuController* controller = menu_controller();
1036 controller->SetAsyncRun(true);
1037 int mouse_event_flags = 0; 948 int mouse_event_flags = 0;
1038 MenuItemView* run_result = 949 MenuItemView* run_result =
1039 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), 950 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(),
1040 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); 951 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags);
1041 EXPECT_EQ(run_result, nullptr); 952 EXPECT_EQ(run_result, nullptr);
1042 953
1043 // |button2| should stay in hot-tracked state but menu controller should not 954 // |button2| should stay in hot-tracked state but menu controller should not
1044 // track it anymore (preventing resetting hot-tracked state when changing 955 // track it anymore (preventing resetting hot-tracked state when changing
1045 // selection while a nested run is active). 956 // selection while a nested run is active).
1046 EXPECT_TRUE(button2->IsHotTracked()); 957 EXPECT_TRUE(button2->IsHotTracked());
1047 EXPECT_EQ(nullptr, GetHotButton()); 958 EXPECT_EQ(nullptr, GetHotButton());
1048 959
1049 // Setting hot-tracked button while nested should get reverted when nested 960 // Setting hot-tracked button while nested should get reverted when nested
1050 // menu run ends. 961 // menu run ends.
1051 SetHotTrackedButton(button1); 962 SetHotTrackedButton(button1);
1052 EXPECT_TRUE(button1->IsHotTracked()); 963 EXPECT_TRUE(button1->IsHotTracked());
1053 EXPECT_EQ(button1, GetHotButton()); 964 EXPECT_EQ(button1, GetHotButton());
1054 965
1055 ExitMenuRun(); 966 ExitMenuRun();
1056 EXPECT_FALSE(button1->IsHotTracked()); 967 EXPECT_FALSE(button1->IsHotTracked());
1057 EXPECT_TRUE(button2->IsHotTracked()); 968 EXPECT_TRUE(button2->IsHotTracked());
1058 EXPECT_EQ(button2, GetHotButton()); 969 EXPECT_EQ(button2, GetHotButton());
1059 } 970 }
1060 971
1061 // Tests that a menu opened asynchronously, will notify its 972 // Tests that a menu opened asynchronously, will notify its
1062 // MenuControllerDelegate when Accept is called. 973 // MenuControllerDelegate when Accept is called.
1063 TEST_F(MenuControllerTest, AsynchronousAccept) { 974 TEST_F(MenuControllerTest, AsynchronousAccept) {
1064 MenuController* controller = menu_controller(); 975 MenuController* controller = menu_controller();
1065 controller->SetAsyncRun(true);
1066 976
1067 int mouse_event_flags = 0; 977 int mouse_event_flags = 0;
1068 MenuItemView* run_result = 978 MenuItemView* run_result =
1069 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), 979 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(),
1070 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); 980 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags);
1071 EXPECT_EQ(run_result, nullptr); 981 EXPECT_EQ(run_result, nullptr);
1072 TestMenuControllerDelegate* delegate = menu_controller_delegate(); 982 TestMenuControllerDelegate* delegate = menu_controller_delegate();
1073 EXPECT_EQ(0, delegate->on_menu_closed_called()); 983 EXPECT_EQ(0, delegate->on_menu_closed_called());
1074 984
1075 MenuItemView* accepted = menu_item()->GetSubmenu()->GetMenuItemAt(0); 985 MenuItemView* accepted = menu_item()->GetSubmenu()->GetMenuItemAt(0);
1076 const int kEventFlags = 42; 986 const int kEventFlags = 42;
1077 Accept(accepted, kEventFlags); 987 Accept(accepted, kEventFlags);
1078 988
1079 EXPECT_EQ(1, delegate->on_menu_closed_called()); 989 EXPECT_EQ(1, delegate->on_menu_closed_called());
1080 EXPECT_EQ(accepted, delegate->on_menu_closed_menu()); 990 EXPECT_EQ(accepted, delegate->on_menu_closed_menu());
1081 EXPECT_EQ(kEventFlags, delegate->on_menu_closed_mouse_event_flags()); 991 EXPECT_EQ(kEventFlags, delegate->on_menu_closed_mouse_event_flags());
1082 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, 992 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE,
1083 delegate->on_menu_closed_notify_type()); 993 delegate->on_menu_closed_notify_type());
1084 } 994 }
1085 995
1086 // Tests that a menu opened asynchronously, will notify its 996 // Tests that a menu opened asynchronously, will notify its
1087 // MenuControllerDelegate when CancelAll is called. 997 // MenuControllerDelegate when CancelAll is called.
1088 TEST_F(MenuControllerTest, AsynchronousCancelAll) { 998 TEST_F(MenuControllerTest, AsynchronousCancelAll) {
1089 MenuController* controller = menu_controller(); 999 MenuController* controller = menu_controller();
1090 controller->SetAsyncRun(true);
1091 1000
1092 int mouse_event_flags = 0; 1001 int mouse_event_flags = 0;
1093 MenuItemView* run_result = 1002 MenuItemView* run_result =
1094 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), 1003 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(),
1095 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); 1004 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags);
1096 EXPECT_EQ(run_result, nullptr); 1005 EXPECT_EQ(run_result, nullptr);
1097 TestMenuControllerDelegate* delegate = menu_controller_delegate(); 1006 TestMenuControllerDelegate* delegate = menu_controller_delegate();
1098 EXPECT_EQ(0, delegate->on_menu_closed_called()); 1007 EXPECT_EQ(0, delegate->on_menu_closed_called());
1099 1008
1100 controller->CancelAll(); 1009 controller->CancelAll();
1101 EXPECT_EQ(1, delegate->on_menu_closed_called()); 1010 EXPECT_EQ(1, delegate->on_menu_closed_called());
1102 EXPECT_EQ(nullptr, delegate->on_menu_closed_menu()); 1011 EXPECT_EQ(nullptr, delegate->on_menu_closed_menu());
1103 EXPECT_EQ(0, delegate->on_menu_closed_mouse_event_flags()); 1012 EXPECT_EQ(0, delegate->on_menu_closed_mouse_event_flags());
1104 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, 1013 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE,
1105 delegate->on_menu_closed_notify_type()); 1014 delegate->on_menu_closed_notify_type());
1106 EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type()); 1015 EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type());
1107 } 1016 }
1108 1017
1109 // Tests that an asynchrnous menu nested within a synchronous menu restores the 1018 // Tests that canceling a nested menu restores the previous
1110 // previous MenuControllerDelegate and synchronous settings. 1019 // MenuControllerDelegate, and notifies each delegate.
1111 TEST_F(MenuControllerTest, AsynchronousNestedDelegate) { 1020 TEST_F(MenuControllerTest, AsynchronousNestedDelegate) {
1112 MenuController* controller = menu_controller(); 1021 MenuController* controller = menu_controller();
1113 TestMenuControllerDelegate* delegate = menu_controller_delegate(); 1022 TestMenuControllerDelegate* delegate = menu_controller_delegate();
1114 std::unique_ptr<TestMenuControllerDelegate> nested_delegate( 1023 std::unique_ptr<TestMenuControllerDelegate> nested_delegate(
1115 new TestMenuControllerDelegate()); 1024 new TestMenuControllerDelegate());
1116 1025
1117 ASSERT_FALSE(IsAsyncRun());
1118 controller->AddNestedDelegate(nested_delegate.get()); 1026 controller->AddNestedDelegate(nested_delegate.get());
1119 controller->SetAsyncRun(true);
1120
1121 EXPECT_TRUE(IsAsyncRun());
1122 EXPECT_EQ(nested_delegate.get(), GetCurrentDelegate()); 1027 EXPECT_EQ(nested_delegate.get(), GetCurrentDelegate());
1123 1028
1124 int mouse_event_flags = 0; 1029 int mouse_event_flags = 0;
1125 MenuItemView* run_result = 1030 MenuItemView* run_result =
1126 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), 1031 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(),
1127 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); 1032 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags);
1128 EXPECT_EQ(run_result, nullptr); 1033 EXPECT_EQ(run_result, nullptr);
1129 1034
1130 controller->CancelAll(); 1035 controller->CancelAll();
1131 EXPECT_FALSE(IsAsyncRun());
1132 EXPECT_EQ(delegate, GetCurrentDelegate()); 1036 EXPECT_EQ(delegate, GetCurrentDelegate());
1133 EXPECT_EQ(0, delegate->on_menu_closed_called()); 1037 EXPECT_EQ(1, delegate->on_menu_closed_called());
1134 EXPECT_EQ(1, nested_delegate->on_menu_closed_called()); 1038 EXPECT_EQ(1, nested_delegate->on_menu_closed_called());
1135 EXPECT_EQ(nullptr, nested_delegate->on_menu_closed_menu()); 1039 EXPECT_EQ(nullptr, nested_delegate->on_menu_closed_menu());
1136 EXPECT_EQ(0, nested_delegate->on_menu_closed_mouse_event_flags()); 1040 EXPECT_EQ(0, nested_delegate->on_menu_closed_mouse_event_flags());
1137 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, 1041 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE,
1138 nested_delegate->on_menu_closed_notify_type()); 1042 nested_delegate->on_menu_closed_notify_type());
1139 EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type()); 1043 EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type());
1140 } 1044 }
1141 1045
1142 // Tests that dropping within an asynchronous menu stops the menu from showing 1046 // Tests that dropping within an asynchronous menu stops the menu from showing
1143 // and does not notify the controller. 1047 // and does not notify the controller.
1144 TEST_F(MenuControllerTest, AsynchronousPerformDrop) { 1048 TEST_F(MenuControllerTest, AsynchronousPerformDrop) {
1145 MenuController* controller = menu_controller(); 1049 MenuController* controller = menu_controller();
1146 controller->SetAsyncRun(true);
1147 SubmenuView* source = menu_item()->GetSubmenu(); 1050 SubmenuView* source = menu_item()->GetSubmenu();
1148 MenuItemView* target = source->GetMenuItemAt(0); 1051 MenuItemView* target = source->GetMenuItemAt(0);
1149 1052
1150 SetDropMenuItem(target, MenuDelegate::DropPosition::DROP_AFTER); 1053 SetDropMenuItem(target, MenuDelegate::DropPosition::DROP_AFTER);
1151 1054
1152 ui::OSExchangeData drop_data; 1055 ui::OSExchangeData drop_data;
1153 gfx::Rect bounds(target->bounds()); 1056 gfx::Rect bounds(target->bounds());
1154 gfx::Point location(bounds.x(), bounds.y()); 1057 gfx::Point location(bounds.x(), bounds.y());
1155 ui::DropTargetEvent target_event(drop_data, location, location, 1058 ui::DropTargetEvent target_event(drop_data, location, location,
1156 ui::DragDropTypes::DRAG_MOVE); 1059 ui::DragDropTypes::DRAG_MOVE);
1157 controller->OnPerformDrop(source, target_event); 1060 controller->OnPerformDrop(source, target_event);
1158 1061
1159 TestMenuDelegate* menu_delegate = 1062 TestMenuDelegate* menu_delegate =
1160 static_cast<TestMenuDelegate*>(target->GetDelegate()); 1063 static_cast<TestMenuDelegate*>(target->GetDelegate());
1161 TestMenuControllerDelegate* controller_delegate = menu_controller_delegate(); 1064 TestMenuControllerDelegate* controller_delegate = menu_controller_delegate();
1162 EXPECT_TRUE(menu_delegate->on_perform_drop_called()); 1065 EXPECT_TRUE(menu_delegate->on_perform_drop_called());
1163 EXPECT_FALSE(IsShowing()); 1066 EXPECT_FALSE(IsShowing());
1164 EXPECT_EQ(0, controller_delegate->on_menu_closed_called()); 1067 EXPECT_EQ(0, controller_delegate->on_menu_closed_called());
1165 } 1068 }
1166 1069
1167 // Tests that dragging within an asynchronous menu notifies the 1070 // Tests that dragging within an asynchronous menu notifies the
1168 // MenuControllerDelegate for shutdown. 1071 // MenuControllerDelegate for shutdown.
1169 TEST_F(MenuControllerTest, AsynchronousDragComplete) { 1072 TEST_F(MenuControllerTest, AsynchronousDragComplete) {
1170 MenuController* controller = menu_controller(); 1073 MenuController* controller = menu_controller();
1171 controller->SetAsyncRun(true);
1172 TestDragCompleteThenDestroyOnMenuClosed(); 1074 TestDragCompleteThenDestroyOnMenuClosed();
1173 1075
1174 controller->OnDragWillStart(); 1076 controller->OnDragWillStart();
1175 controller->OnDragComplete(true); 1077 controller->OnDragComplete(true);
1176 1078
1177 TestMenuControllerDelegate* controller_delegate = menu_controller_delegate(); 1079 TestMenuControllerDelegate* controller_delegate = menu_controller_delegate();
1178 EXPECT_EQ(1, controller_delegate->on_menu_closed_called()); 1080 EXPECT_EQ(1, controller_delegate->on_menu_closed_called());
1179 EXPECT_EQ(nullptr, controller_delegate->on_menu_closed_menu()); 1081 EXPECT_EQ(nullptr, controller_delegate->on_menu_closed_menu());
1180 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, 1082 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE,
1181 controller_delegate->on_menu_closed_notify_type()); 1083 controller_delegate->on_menu_closed_notify_type());
1182 } 1084 }
1183 1085
1184 // Tests that if Cancel is called during a drag, that OnMenuClosed is still 1086 // Tests that if Cancel is called during a drag, that OnMenuClosed is still
1185 // notified when the drag completes. 1087 // notified when the drag completes.
1186 TEST_F(MenuControllerTest, AsynchronousCancelDuringDrag) { 1088 TEST_F(MenuControllerTest, AsynchronousCancelDuringDrag) {
1187 MenuController* controller = menu_controller(); 1089 MenuController* controller = menu_controller();
1188 controller->SetAsyncRun(true);
1189 TestDragCompleteThenDestroyOnMenuClosed(); 1090 TestDragCompleteThenDestroyOnMenuClosed();
1190 1091
1191 controller->OnDragWillStart(); 1092 controller->OnDragWillStart();
1192 controller->CancelAll(); 1093 controller->CancelAll();
1193 controller->OnDragComplete(true); 1094 controller->OnDragComplete(true);
1194 1095
1195 TestMenuControllerDelegate* controller_delegate = menu_controller_delegate(); 1096 TestMenuControllerDelegate* controller_delegate = menu_controller_delegate();
1196 EXPECT_EQ(1, controller_delegate->on_menu_closed_called()); 1097 EXPECT_EQ(1, controller_delegate->on_menu_closed_called());
1197 EXPECT_EQ(nullptr, controller_delegate->on_menu_closed_menu()); 1098 EXPECT_EQ(nullptr, controller_delegate->on_menu_closed_menu());
1198 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, 1099 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE,
1199 controller_delegate->on_menu_closed_notify_type()); 1100 controller_delegate->on_menu_closed_notify_type());
1200 } 1101 }
1201 1102
1202 // Tests that if a menu is destroyed while drag operations are occuring, that 1103 // Tests that if a menu is destroyed while drag operations are occuring, that
1203 // the MenuHost does not crash as the drag completes. 1104 // the MenuHost does not crash as the drag completes.
1204 TEST_F(MenuControllerTest, AsynchronousDragHostDeleted) { 1105 TEST_F(MenuControllerTest, AsynchronousDragHostDeleted) {
1205 MenuController* controller = menu_controller();
1206 controller->SetAsyncRun(true);
1207
1208 SubmenuView* submenu = menu_item()->GetSubmenu(); 1106 SubmenuView* submenu = menu_item()->GetSubmenu();
1209 submenu->ShowAt(owner(), menu_item()->bounds(), false); 1107 submenu->ShowAt(owner(), menu_item()->bounds(), false);
1210 MenuHost* host = GetMenuHost(submenu); 1108 MenuHost* host = GetMenuHost(submenu);
1211 MenuHostOnDragWillStart(host); 1109 MenuHostOnDragWillStart(host);
1212 submenu->Close(); 1110 submenu->Close();
1213 DestroyMenuItem(); 1111 DestroyMenuItem();
1214 MenuHostOnDragComplete(host); 1112 MenuHostOnDragComplete(host);
1215 } 1113 }
1216 1114
1217 // Widget destruction and cleanup occurs on the MessageLoop after the 1115 // Widget destruction and cleanup occurs on the MessageLoop after the
1218 // MenuController has been destroyed. A MenuHostRootView should not attempt to 1116 // MenuController has been destroyed. A MenuHostRootView should not attempt to
1219 // access a destroyed MenuController. This test should not cause a crash. 1117 // access a destroyed MenuController. This test should not cause a crash.
1220 TEST_F(MenuControllerTest, HostReceivesInputBeforeDestruction) { 1118 TEST_F(MenuControllerTest, HostReceivesInputBeforeDestruction) {
1221 MenuController* controller = menu_controller();
1222 controller->SetAsyncRun(true);
1223
1224 SubmenuView* submenu = menu_item()->GetSubmenu(); 1119 SubmenuView* submenu = menu_item()->GetSubmenu();
1225 submenu->ShowAt(owner(), menu_item()->bounds(), false); 1120 submenu->ShowAt(owner(), menu_item()->bounds(), false);
1226 gfx::Point location(submenu->bounds().bottom_right()); 1121 gfx::Point location(submenu->bounds().bottom_right());
1227 location.Offset(1, 1); 1122 location.Offset(1, 1);
1228 1123
1229 MenuHost* host = GetMenuHost(submenu); 1124 MenuHost* host = GetMenuHost(submenu);
1230 // Normally created as the full Widget is brought up. Explicitly created here 1125 // Normally created as the full Widget is brought up. Explicitly created here
1231 // for testing. 1126 // for testing.
1232 std::unique_ptr<MenuHostRootView> root_view(CreateMenuHostRootView(host)); 1127 std::unique_ptr<MenuHostRootView> root_view(CreateMenuHostRootView(host));
1233 DestroyMenuController(); 1128 DestroyMenuController();
1234 1129
1235 ui::MouseEvent event(ui::ET_MOUSE_MOVED, location, location, 1130 ui::MouseEvent event(ui::ET_MOUSE_MOVED, location, location,
1236 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 0); 1131 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 0);
1237 1132
1238 // This should not attempt to access the destroyed MenuController and should 1133 // This should not attempt to access the destroyed MenuController and should
1239 // not crash. 1134 // not crash.
1240 root_view->OnMouseMoved(event); 1135 root_view->OnMouseMoved(event);
1241 } 1136 }
1242 1137
1243 // Tets that an asynchronous menu nested within an asynchronous menu closes both 1138 // Tets that an asynchronous menu nested within an asynchronous menu closes both
1244 // menus, and notifies both delegates. 1139 // menus, and notifies both delegates.
1245 TEST_F(MenuControllerTest, DoubleAsynchronousNested) { 1140 TEST_F(MenuControllerTest, DoubleAsynchronousNested) {
1246 MenuController* controller = menu_controller(); 1141 MenuController* controller = menu_controller();
1247 TestMenuControllerDelegate* delegate = menu_controller_delegate(); 1142 TestMenuControllerDelegate* delegate = menu_controller_delegate();
1248 std::unique_ptr<TestMenuControllerDelegate> nested_delegate( 1143 std::unique_ptr<TestMenuControllerDelegate> nested_delegate(
1249 new TestMenuControllerDelegate()); 1144 new TestMenuControllerDelegate());
1250 1145
1251 ASSERT_FALSE(IsAsyncRun());
1252 // Sets the run created in SetUp
1253 controller->SetAsyncRun(true);
1254
1255 // Nested run 1146 // Nested run
1256 controller->AddNestedDelegate(nested_delegate.get()); 1147 controller->AddNestedDelegate(nested_delegate.get());
1257 controller->SetAsyncRun(true);
1258 int mouse_event_flags = 0; 1148 int mouse_event_flags = 0;
1259 MenuItemView* run_result = 1149 MenuItemView* run_result =
1260 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), 1150 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(),
1261 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); 1151 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags);
1262 EXPECT_EQ(run_result, nullptr); 1152 EXPECT_EQ(run_result, nullptr);
1263 1153
1264 controller->CancelAll(); 1154 controller->CancelAll();
1265 EXPECT_EQ(1, delegate->on_menu_closed_called()); 1155 EXPECT_EQ(1, delegate->on_menu_closed_called());
1266 EXPECT_EQ(1, nested_delegate->on_menu_closed_called()); 1156 EXPECT_EQ(1, nested_delegate->on_menu_closed_called());
1267 } 1157 }
1268 1158
1269 // Tests that an asynchronous menu nested within a synchronous menu does not 1159 // Tests that a nested menu does not crash when trying to repost events that
1270 // crash when trying to repost events that occur outside of the bounds of the 1160 // occur outside of the bounds of the menu. Instead a proper shutdown should
1271 // menu. Instead a proper shutdown should occur. 1161 // occur.
1272 TEST_F(MenuControllerTest, AsynchronousRepostEvent) { 1162 TEST_F(MenuControllerTest, AsynchronousRepostEvent) {
1273 MenuController* controller = menu_controller(); 1163 MenuController* controller = menu_controller();
1274 TestMenuControllerDelegate* delegate = menu_controller_delegate(); 1164 TestMenuControllerDelegate* delegate = menu_controller_delegate();
1275 std::unique_ptr<TestMenuControllerDelegate> nested_delegate( 1165 std::unique_ptr<TestMenuControllerDelegate> nested_delegate(
1276 new TestMenuControllerDelegate()); 1166 new TestMenuControllerDelegate());
1277 1167
1278 ASSERT_FALSE(IsAsyncRun());
1279
1280 controller->AddNestedDelegate(nested_delegate.get()); 1168 controller->AddNestedDelegate(nested_delegate.get());
1281 controller->SetAsyncRun(true);
1282
1283 EXPECT_TRUE(IsAsyncRun());
1284 EXPECT_EQ(nested_delegate.get(), GetCurrentDelegate()); 1169 EXPECT_EQ(nested_delegate.get(), GetCurrentDelegate());
1285 1170
1286 MenuItemView* item = menu_item(); 1171 MenuItemView* item = menu_item();
1287 int mouse_event_flags = 0; 1172 int mouse_event_flags = 0;
1288 MenuItemView* run_result = 1173 MenuItemView* run_result =
1289 controller->Run(owner(), nullptr, item, gfx::Rect(), MENU_ANCHOR_TOPLEFT, 1174 controller->Run(owner(), nullptr, item, gfx::Rect(), MENU_ANCHOR_TOPLEFT,
1290 false, false, &mouse_event_flags); 1175 false, false, &mouse_event_flags);
1291 EXPECT_EQ(run_result, nullptr); 1176 EXPECT_EQ(run_result, nullptr);
1292 1177
1293 // Show a sub menu to target with a pointer selection. However have the event 1178 // Show a sub menu to target with a pointer selection. However have the event
1294 // occur outside of the bounds of the entire menu. 1179 // occur outside of the bounds of the entire menu.
1295 SubmenuView* sub_menu = item->GetSubmenu(); 1180 SubmenuView* sub_menu = item->GetSubmenu();
1296 sub_menu->ShowAt(owner(), item->bounds(), false); 1181 sub_menu->ShowAt(owner(), item->bounds(), false);
1297 gfx::Point location(sub_menu->bounds().bottom_right()); 1182 gfx::Point location(sub_menu->bounds().bottom_right());
1298 location.Offset(1, 1); 1183 location.Offset(1, 1);
1299 ui::MouseEvent event(ui::ET_MOUSE_PRESSED, location, location, 1184 ui::MouseEvent event(ui::ET_MOUSE_PRESSED, location, location,
1300 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 0); 1185 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 0);
1301 1186
1302 // When attempting to select outside of all menus this should lead to a 1187 // When attempting to select outside of all menus this should lead to a
1303 // shutdown. This should not crash while attempting to repost the event. 1188 // shutdown. This should not crash while attempting to repost the event.
1304 SetSelectionOnPointerDown(sub_menu, &event); 1189 SetSelectionOnPointerDown(sub_menu, &event);
1305 1190
1306 EXPECT_FALSE(IsAsyncRun());
1307 EXPECT_EQ(delegate, GetCurrentDelegate()); 1191 EXPECT_EQ(delegate, GetCurrentDelegate());
1308 EXPECT_EQ(0, delegate->on_menu_closed_called()); 1192 EXPECT_EQ(1, delegate->on_menu_closed_called());
1309 EXPECT_EQ(1, nested_delegate->on_menu_closed_called()); 1193 EXPECT_EQ(1, nested_delegate->on_menu_closed_called());
1310 EXPECT_EQ(nullptr, nested_delegate->on_menu_closed_menu()); 1194 EXPECT_EQ(nullptr, nested_delegate->on_menu_closed_menu());
1311 EXPECT_EQ(0, nested_delegate->on_menu_closed_mouse_event_flags()); 1195 EXPECT_EQ(0, nested_delegate->on_menu_closed_mouse_event_flags());
1312 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, 1196 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE,
1313 nested_delegate->on_menu_closed_notify_type()); 1197 nested_delegate->on_menu_closed_notify_type());
1314 EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type()); 1198 EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type());
1315 } 1199 }
1316 1200
1317 // Tests that an asynchronous menu reposts touch events that occur outside of 1201 // Tests that an asynchronous menu reposts touch events that occur outside of
1318 // the bounds of the menu, and that the menu closes. 1202 // the bounds of the menu, and that the menu closes.
1319 TEST_F(MenuControllerTest, AsynchronousTouchEventRepostEvent) { 1203 TEST_F(MenuControllerTest, AsynchronousTouchEventRepostEvent) {
1320 MenuController* controller = menu_controller(); 1204 MenuController* controller = menu_controller();
1321 TestMenuControllerDelegate* delegate = menu_controller_delegate(); 1205 TestMenuControllerDelegate* delegate = menu_controller_delegate();
1322 controller->SetAsyncRun(true);
1323 1206
1324 // Show a sub menu to target with a touch event. However have the event occur 1207 // Show a sub menu to target with a touch event. However have the event occur
1325 // outside of the bounds of the entire menu. 1208 // outside of the bounds of the entire menu.
1326 MenuItemView* item = menu_item(); 1209 MenuItemView* item = menu_item();
1327 SubmenuView* sub_menu = item->GetSubmenu(); 1210 SubmenuView* sub_menu = item->GetSubmenu();
1328 sub_menu->ShowAt(owner(), item->bounds(), false); 1211 sub_menu->ShowAt(owner(), item->bounds(), false);
1329 gfx::Point location(sub_menu->bounds().bottom_right()); 1212 gfx::Point location(sub_menu->bounds().bottom_right());
1330 location.Offset(1, 1); 1213 location.Offset(1, 1);
1331 ui::TouchEvent event( 1214 ui::TouchEvent event(
1332 ui::ET_TOUCH_PRESSED, location, ui::EventTimeForNow(), 1215 ui::ET_TOUCH_PRESSED, location, ui::EventTimeForNow(),
1333 ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0)); 1216 ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
1334 controller->OnTouchEvent(sub_menu, &event); 1217 controller->OnTouchEvent(sub_menu, &event);
1335 1218
1336 EXPECT_FALSE(IsShowing()); 1219 EXPECT_FALSE(IsShowing());
1337 EXPECT_EQ(1, delegate->on_menu_closed_called()); 1220 EXPECT_EQ(1, delegate->on_menu_closed_called());
1338 EXPECT_EQ(nullptr, delegate->on_menu_closed_menu()); 1221 EXPECT_EQ(nullptr, delegate->on_menu_closed_menu());
1339 EXPECT_EQ(0, delegate->on_menu_closed_mouse_event_flags()); 1222 EXPECT_EQ(0, delegate->on_menu_closed_mouse_event_flags());
1340 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, 1223 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE,
1341 delegate->on_menu_closed_notify_type()); 1224 delegate->on_menu_closed_notify_type());
1342 EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type()); 1225 EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type());
1343 } 1226 }
1344 1227
1345 // Tests that if you exit all menus when an asynchrnous menu is nested within a
1346 // synchronous menu, the message loop for the parent menu finishes running.
1347 TEST_F(MenuControllerTest, AsynchronousNestedExitAll) {
1348 InstallTestMenuMessageLoop();
1349
1350 base::ThreadTaskRunnerHandle::Get()->PostTask(
1351 FROM_HERE, base::Bind(&MenuControllerTest::TestAsynchronousNestedExitAll,
1352 base::Unretained(this)));
1353
1354 RunMenu();
1355 }
1356
1357 // Tests that if you exit the nested menu when an asynchrnous menu is nested
1358 // within a synchronous menu, the message loop for the parent menu remains
1359 // running.
1360 TEST_F(MenuControllerTest, AsynchronousNestedExitOutermost) {
1361 InstallTestMenuMessageLoop();
1362
1363 base::ThreadTaskRunnerHandle::Get()->PostTask(
1364 FROM_HERE,
1365 base::Bind(&MenuControllerTest::TestAsynchronousNestedExitOutermost,
1366 base::Unretained(this)));
1367
1368 RunMenu();
1369 }
1370
1371 // Tests that having the MenuController deleted during RepostEvent does not 1228 // Tests that having the MenuController deleted during RepostEvent does not
1372 // cause a crash. ASAN bots should not detect use-after-free in MenuController. 1229 // cause a crash. ASAN bots should not detect use-after-free in MenuController.
1373 TEST_F(MenuControllerTest, AsynchronousRepostEventDeletesController) { 1230 TEST_F(MenuControllerTest, AsynchronousRepostEventDeletesController) {
1374 MenuController* controller = menu_controller(); 1231 MenuController* controller = menu_controller();
1375 std::unique_ptr<TestMenuControllerDelegate> nested_delegate( 1232 std::unique_ptr<TestMenuControllerDelegate> nested_delegate(
1376 new TestMenuControllerDelegate()); 1233 new TestMenuControllerDelegate());
1377 1234
1378 ASSERT_FALSE(IsAsyncRun());
1379
1380 controller->AddNestedDelegate(nested_delegate.get()); 1235 controller->AddNestedDelegate(nested_delegate.get());
1381 controller->SetAsyncRun(true);
1382
1383 EXPECT_TRUE(IsAsyncRun());
1384 EXPECT_EQ(nested_delegate.get(), GetCurrentDelegate()); 1236 EXPECT_EQ(nested_delegate.get(), GetCurrentDelegate());
1385 1237
1386 MenuItemView* item = menu_item(); 1238 MenuItemView* item = menu_item();
1387 int mouse_event_flags = 0; 1239 int mouse_event_flags = 0;
1388 MenuItemView* run_result = 1240 MenuItemView* run_result =
1389 controller->Run(owner(), nullptr, item, gfx::Rect(), MENU_ANCHOR_TOPLEFT, 1241 controller->Run(owner(), nullptr, item, gfx::Rect(), MENU_ANCHOR_TOPLEFT,
1390 false, false, &mouse_event_flags); 1242 false, false, &mouse_event_flags);
1391 EXPECT_EQ(run_result, nullptr); 1243 EXPECT_EQ(run_result, nullptr);
1392 1244
1393 // Show a sub menu to target with a pointer selection. However have the event 1245 // Show a sub menu to target with a pointer selection. However have the event
(...skipping 16 matching lines...) Expand all
1410 sub_menu->Close(); 1262 sub_menu->Close();
1411 EXPECT_EQ(1, nested_delegate->on_menu_closed_called()); 1263 EXPECT_EQ(1, nested_delegate->on_menu_closed_called());
1412 } 1264 }
1413 1265
1414 // Tests that having the MenuController deleted during OnGestureEvent does not 1266 // Tests that having the MenuController deleted during OnGestureEvent does not
1415 // cause a crash. ASAN bots should not detect use-after-free in MenuController. 1267 // cause a crash. ASAN bots should not detect use-after-free in MenuController.
1416 TEST_F(MenuControllerTest, AsynchronousGestureDeletesController) { 1268 TEST_F(MenuControllerTest, AsynchronousGestureDeletesController) {
1417 MenuController* controller = menu_controller(); 1269 MenuController* controller = menu_controller();
1418 std::unique_ptr<TestMenuControllerDelegate> nested_delegate( 1270 std::unique_ptr<TestMenuControllerDelegate> nested_delegate(
1419 new TestMenuControllerDelegate()); 1271 new TestMenuControllerDelegate());
1420 ASSERT_FALSE(IsAsyncRun());
1421 1272
1422 controller->AddNestedDelegate(nested_delegate.get()); 1273 controller->AddNestedDelegate(nested_delegate.get());
1423 controller->SetAsyncRun(true);
1424
1425 EXPECT_TRUE(IsAsyncRun());
1426 EXPECT_EQ(nested_delegate.get(), GetCurrentDelegate()); 1274 EXPECT_EQ(nested_delegate.get(), GetCurrentDelegate());
1427 1275
1428 MenuItemView* item = menu_item(); 1276 MenuItemView* item = menu_item();
1429 int mouse_event_flags = 0; 1277 int mouse_event_flags = 0;
1430 MenuItemView* run_result = 1278 MenuItemView* run_result =
1431 controller->Run(owner(), nullptr, item, gfx::Rect(), MENU_ANCHOR_TOPLEFT, 1279 controller->Run(owner(), nullptr, item, gfx::Rect(), MENU_ANCHOR_TOPLEFT,
1432 false, false, &mouse_event_flags); 1280 false, false, &mouse_event_flags);
1433 EXPECT_EQ(run_result, nullptr); 1281 EXPECT_EQ(run_result, nullptr);
1434 1282
1435 // Show a sub menu to target with a tap event. 1283 // Show a sub menu to target with a tap event.
1436 SubmenuView* sub_menu = item->GetSubmenu(); 1284 SubmenuView* sub_menu = item->GetSubmenu();
1437 sub_menu->ShowAt(owner(), gfx::Rect(0, 0, 100, 100), true); 1285 sub_menu->ShowAt(owner(), gfx::Rect(0, 0, 100, 100), true);
1438 1286
1439 gfx::Point location(sub_menu->bounds().CenterPoint()); 1287 gfx::Point location(sub_menu->bounds().CenterPoint());
1440 ui::GestureEvent event(location.x(), location.y(), 0, ui::EventTimeForNow(), 1288 ui::GestureEvent event(location.x(), location.y(), 0, ui::EventTimeForNow(),
1441 ui::GestureEventDetails(ui::ET_GESTURE_TAP)); 1289 ui::GestureEventDetails(ui::ET_GESTURE_TAP));
1442 1290
1443 // This will lead to MenuController being deleted during the processing of the 1291 // This will lead to MenuController being deleted during the processing of the
1444 // gesture event. The remainder of this test, and TearDown should not crash. 1292 // gesture event. The remainder of this test, and TearDown should not crash.
1445 DestroyMenuControllerOnMenuClosed(nested_delegate.get()); 1293 DestroyMenuControllerOnMenuClosed(nested_delegate.get());
1446 controller->OnGestureEvent(sub_menu, &event); 1294 controller->OnGestureEvent(sub_menu, &event);
1447 1295
1448 // Close to remove observers before test TearDown 1296 // Close to remove observers before test TearDown
1449 sub_menu->Close(); 1297 sub_menu->Close();
1450 EXPECT_EQ(1, nested_delegate->on_menu_closed_called()); 1298 EXPECT_EQ(1, nested_delegate->on_menu_closed_called());
1451 } 1299 }
1452 1300
1453 // Tests that when an asynchronous menu is nested, and the nested message loop
1454 // is kill not by the MenuController, that the nested menu is notified of
1455 // destruction.
1456 TEST_F(MenuControllerTest, NestedMessageLoopDiesWithNestedMenu) {
1457 menu_controller()->CancelAll();
1458 InstallTestMenuMessageLoop();
1459 std::unique_ptr<TestMenuControllerDelegate> nested_delegate(
1460 new TestMenuControllerDelegate());
1461 // This will nest an asynchronous menu, and then kill the nested message loop.
1462 base::ThreadTaskRunnerHandle::Get()->PostTask(
1463 FROM_HERE,
1464 base::Bind(&MenuControllerTest::TestNestedMessageLoopKillsItself,
1465 base::Unretained(this), nested_delegate.get()));
1466
1467 int result_event_flags = 0;
1468 // This creates a nested message loop.
1469 EXPECT_EQ(nullptr, menu_controller()->Run(owner(), nullptr, menu_item(),
1470 gfx::Rect(), MENU_ANCHOR_TOPLEFT,
1471 false, false, &result_event_flags));
1472 EXPECT_FALSE(menu_controller_delegate()->on_menu_closed_called());
1473 EXPECT_TRUE(nested_delegate->on_menu_closed_called());
1474 }
1475
1476 #if defined(USE_AURA) 1301 #if defined(USE_AURA)
1477 // Tests that when a synchronous menu receives a cancel event, that it closes.
1478 TEST_F(MenuControllerTest, SynchronousCancelEvent) {
1479 ExitMenuRun();
1480 // Post actual test to run once the menu has created a nested message loop.
1481 base::ThreadTaskRunnerHandle::Get()->PostTask(
1482 FROM_HERE,
1483 base::Bind(&MenuControllerTest::TestCancelEvent, base::Unretained(this)));
1484 int mouse_event_flags = 0;
1485 MenuItemView* run_result = menu_controller()->Run(
1486 owner(), nullptr, menu_item(), gfx::Rect(), MENU_ANCHOR_TOPLEFT, false,
1487 false, &mouse_event_flags);
1488 EXPECT_EQ(run_result, nullptr);
1489 }
1490
1491 // Tests that when an asynchronous menu receives a cancel event, that it closes. 1302 // Tests that when an asynchronous menu receives a cancel event, that it closes.
1492 TEST_F(MenuControllerTest, AsynchronousCancelEvent) { 1303 TEST_F(MenuControllerTest, AsynchronousCancelEvent) {
1493 ExitMenuRun(); 1304 ExitMenuRun();
1494 MenuController* controller = menu_controller(); 1305 MenuController* controller = menu_controller();
1495 controller->SetAsyncRun(true);
1496 1306
1497 int mouse_event_flags = 0; 1307 int mouse_event_flags = 0;
1498 MenuItemView* run_result = 1308 MenuItemView* run_result =
1499 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), 1309 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(),
1500 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); 1310 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags);
1501 EXPECT_EQ(run_result, nullptr); 1311 EXPECT_EQ(run_result, nullptr);
1502 TestCancelEvent(); 1312 TestCancelEvent();
1503 } 1313 }
1504 1314
1505 // Tests that if a menu is ran without a widget, that MenuPreTargetHandler does 1315 // Tests that if a menu is ran without a widget, that MenuPreTargetHandler does
1506 // not cause a crash. 1316 // not cause a crash.
1507 TEST_F(MenuControllerTest, RunWithoutWidgetDoesntCrash) { 1317 TEST_F(MenuControllerTest, RunWithoutWidgetDoesntCrash) {
1508 ExitMenuRun(); 1318 ExitMenuRun();
1509 MenuController* controller = menu_controller(); 1319 MenuController* controller = menu_controller();
1510 controller->SetAsyncRun(true);
1511 int mouse_event_flags = 0; 1320 int mouse_event_flags = 0;
1512 MenuItemView* run_result = 1321 MenuItemView* run_result =
1513 controller->Run(nullptr, nullptr, menu_item(), gfx::Rect(), 1322 controller->Run(nullptr, nullptr, menu_item(), gfx::Rect(),
1514 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); 1323 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags);
1515 EXPECT_EQ(run_result, nullptr); 1324 EXPECT_EQ(run_result, nullptr);
1516 } 1325 }
1517 1326
1518 // Tests that if a MenuController is destroying during drag/drop, and another 1327 // Tests that if a MenuController is destroying during drag/drop, and another
1519 // MenuController becomes active, that the exiting of drag does not cause a 1328 // MenuController becomes active, that the exiting of drag does not cause a
1520 // crash. 1329 // crash.
(...skipping 10 matching lines...) Expand all
1531 ->GetNativeWindow() 1340 ->GetNativeWindow()
1532 ->GetRootWindow(), 1341 ->GetRootWindow(),
1533 &drag_drop_client); 1342 &drag_drop_client);
1534 StartDrag(); 1343 StartDrag();
1535 } 1344 }
1536 1345
1537 // Tests that if a CancelAll is called during drag-and-drop that it does not 1346 // Tests that if a CancelAll is called during drag-and-drop that it does not
1538 // destroy the MenuController. On Windows and Linux this destruction also 1347 // destroy the MenuController. On Windows and Linux this destruction also
1539 // destroys the Widget used for drag-and-drop, thereby ending the drag. 1348 // destroys the Widget used for drag-and-drop, thereby ending the drag.
1540 TEST_F(MenuControllerTest, CancelAllDuringDrag) { 1349 TEST_F(MenuControllerTest, CancelAllDuringDrag) {
1541 MenuController* controller = menu_controller();
1542 controller->SetAsyncRun(true);
1543
1544 // Build the menu so that the appropriate root window is available to set the 1350 // Build the menu so that the appropriate root window is available to set the
1545 // drag drop client on. 1351 // drag drop client on.
1546 AddButtonMenuItems(); 1352 AddButtonMenuItems();
1547 TestDragDropClient drag_drop_client(base::Bind( 1353 TestDragDropClient drag_drop_client(base::Bind(
1548 &MenuControllerTest::TestCancelAllDuringDrag, base::Unretained(this))); 1354 &MenuControllerTest::TestCancelAllDuringDrag, base::Unretained(this)));
1549 aura::client::SetDragDropClient(menu_item() 1355 aura::client::SetDragDropClient(menu_item()
1550 ->GetSubmenu() 1356 ->GetSubmenu()
1551 ->GetWidget() 1357 ->GetWidget()
1552 ->GetNativeWindow() 1358 ->GetNativeWindow()
1553 ->GetRootWindow(), 1359 ->GetRootWindow(),
1554 &drag_drop_client); 1360 &drag_drop_client);
1555 StartDrag(); 1361 StartDrag();
1556 } 1362 }
1557 1363
1558 // Tests that when releasing the ref on ViewsDelegate and MenuController is 1364 // Tests that when releasing the ref on ViewsDelegate and MenuController is
1559 // deleted, that shutdown occurs without crashing. 1365 // deleted, that shutdown occurs without crashing.
1560 TEST_F(MenuControllerTest, DestroyedDuringViewsRelease) { 1366 TEST_F(MenuControllerTest, DestroyedDuringViewsRelease) {
1561 ExitMenuRun(); 1367 ExitMenuRun();
1562 MenuController* controller = menu_controller(); 1368 MenuController* controller = menu_controller();
1563 controller->SetAsyncRun(true);
1564 1369
1565 int mouse_event_flags = 0; 1370 int mouse_event_flags = 0;
1566 MenuItemView* run_result = 1371 MenuItemView* run_result =
1567 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), 1372 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(),
1568 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); 1373 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags);
1569 EXPECT_EQ(run_result, nullptr); 1374 EXPECT_EQ(run_result, nullptr);
1570 TestDestroyedDuringViewsRelease(); 1375 TestDestroyedDuringViewsRelease();
1571 } 1376 }
1572 1377
1573 #endif // defined(USE_AURA) 1378 #endif // defined(USE_AURA)
1574 1379
1575 } // namespace test 1380 } // namespace test
1576 } // namespace views 1381 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/controls/menu/menu_controller.cc ('k') | ui/views/controls/menu/menu_message_loop.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698