| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 <map> | 5 #include <map> |
| 6 #include <string> | 6 #include <string> |
| 7 #include <unordered_set> | 7 #include <unordered_set> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| 11 #include "base/memory/scoped_vector.h" | 11 #include "base/memory/scoped_vector.h" |
| 12 | 12 |
| 13 #include "chrome/browser/extensions/extension_util.h" | 13 #include "chrome/browser/extensions/extension_util.h" |
| 14 #include "chrome/browser/extensions/menu_manager_factory.h" | 14 #include "chrome/browser/extensions/menu_manager_factory.h" |
| 15 #include "chrome/browser/ui/app_list/app_context_menu_delegate.h" | 15 #include "chrome/browser/ui/app_list/app_context_menu_delegate.h" |
| 16 #include "chrome/browser/ui/app_list/app_list_controller_delegate.h" | 16 #include "chrome/browser/ui/app_list/app_list_controller_delegate.h" |
| 17 #include "chrome/browser/ui/app_list/app_list_test_util.h" | 17 #include "chrome/browser/ui/app_list/app_list_test_util.h" |
| 18 #include "chrome/browser/ui/app_list/chrome_app_list_item.h" | 18 #include "chrome/browser/ui/app_list/chrome_app_list_item.h" |
| 19 #include "chrome/browser/ui/app_list/extension_app_context_menu.h" | 19 #include "chrome/browser/ui/app_list/extension_app_context_menu.h" |
| 20 #include "chrome/browser/ui/app_list/test/test_app_list_controller_delegate.h" | 20 #include "chrome/browser/ui/app_list/test/test_app_list_controller_delegate.h" |
| 21 #include "chrome/test/base/testing_profile.h" | 21 #include "chrome/test/base/testing_profile.h" |
| 22 #include "components/keyed_service/core/keyed_service.h" | 22 #include "components/keyed_service/core/keyed_service.h" |
| 23 #include "testing/gtest/include/gtest/gtest.h" | 23 #include "testing/gtest/include/gtest/gtest.h" |
| 24 | 24 |
| 25 #if defined(OS_CHROMEOS) | 25 #if defined(OS_CHROMEOS) |
| 26 #include "chrome/browser/ui/app_list/arc/arc_app_item.h" | 26 #include "chrome/browser/ui/app_list/arc/arc_app_item.h" |
| 27 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" |
| 27 #include "chrome/browser/ui/app_list/arc/arc_app_test.h" | 28 #include "chrome/browser/ui/app_list/arc/arc_app_test.h" |
| 28 #include "components/arc/test/fake_app_instance.h" | 29 #include "components/arc/test/fake_app_instance.h" |
| 29 #include "components/arc/test/fake_arc_bridge_service.h" | 30 #include "components/arc/test/fake_arc_bridge_service.h" |
| 30 #endif | 31 #endif |
| 31 | 32 |
| 32 namespace { | 33 namespace { |
| 33 | 34 |
| 34 class FakeAppContextMenuDelegate : public app_list::AppContextMenuDelegate { | 35 class FakeAppContextMenuDelegate : public app_list::AppContextMenuDelegate { |
| 35 public: | 36 public: |
| 36 FakeAppContextMenuDelegate() = default; | 37 FakeAppContextMenuDelegate() = default; |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 : command_id(command_id), | 143 : command_id(command_id), |
| 143 is_enabled(enabled), | 144 is_enabled(enabled), |
| 144 is_checked(checked) { | 145 is_checked(checked) { |
| 145 } | 146 } |
| 146 | 147 |
| 147 int command_id; | 148 int command_id; |
| 148 bool is_enabled; | 149 bool is_enabled; |
| 149 bool is_checked; | 150 bool is_checked; |
| 150 }; | 151 }; |
| 151 | 152 |
| 153 void ValidateItemState(const ui::MenuModel* menu_model, |
| 154 int index, |
| 155 const MenuState& state) { |
| 156 EXPECT_EQ(state.command_id, menu_model->GetCommandIdAt(index)); |
| 157 if (state.command_id == -1) |
| 158 return; // Don't check separator. |
| 159 EXPECT_EQ(state.is_enabled, menu_model->IsEnabledAt(index)); |
| 160 EXPECT_EQ(state.is_checked, menu_model->IsItemCheckedAt(index)); |
| 161 } |
| 162 |
| 152 void ValidateMenuState(const ui::MenuModel* menu_model, | 163 void ValidateMenuState(const ui::MenuModel* menu_model, |
| 153 const std::vector<MenuState>& states) { | 164 const std::vector<MenuState>& states) { |
| 154 ASSERT_NE(nullptr, menu_model); | 165 ASSERT_NE(nullptr, menu_model); |
| 155 size_t state_index = 0; | 166 size_t state_index = 0; |
| 156 for (int i = 0; i < menu_model->GetItemCount(); ++i) { | 167 for (int i = 0; i < menu_model->GetItemCount(); ++i) { |
| 157 ASSERT_LT(state_index, states.size()); | 168 ASSERT_LT(state_index, states.size()); |
| 158 const MenuState& state = states[state_index++]; | 169 ValidateItemState(menu_model, i, states[state_index++]); |
| 159 EXPECT_EQ(state.command_id, menu_model->GetCommandIdAt(i)); | |
| 160 if (state.command_id == -1) | |
| 161 continue; // Don't check separator. | |
| 162 EXPECT_EQ(state.is_enabled, menu_model->IsEnabledAt(i)); | |
| 163 EXPECT_EQ(state.is_checked, menu_model->IsItemCheckedAt(i)); | |
| 164 } | 170 } |
| 165 EXPECT_EQ(state_index, states.size()); | 171 EXPECT_EQ(state_index, states.size()); |
| 166 } | 172 } |
| 167 | 173 |
| 168 FakeAppListControllerDelegate* controller() { | 174 FakeAppListControllerDelegate* controller() { |
| 169 return controller_.get(); | 175 return controller_.get(); |
| 170 } | 176 } |
| 171 | 177 |
| 172 FakeAppContextMenuDelegate* menu_delegate() { | 178 FakeAppContextMenuDelegate* menu_delegate() { |
| 173 return menu_delegate_.get(); | 179 return menu_delegate_.get(); |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 controller()); | 347 controller()); |
| 342 ui::MenuModel* menu_model = menu.GetMenuModel(); | 348 ui::MenuModel* menu_model = menu.GetMenuModel(); |
| 343 EXPECT_EQ(nullptr, menu_model); | 349 EXPECT_EQ(nullptr, menu_model); |
| 344 } | 350 } |
| 345 | 351 |
| 346 #if defined(OS_CHROMEOS) | 352 #if defined(OS_CHROMEOS) |
| 347 TEST_F(AppContextMenuTest, ArcMenu) { | 353 TEST_F(AppContextMenuTest, ArcMenu) { |
| 348 ArcAppTest arc_test; | 354 ArcAppTest arc_test; |
| 349 arc_test.SetUp(profile()); | 355 arc_test.SetUp(profile()); |
| 350 | 356 |
| 351 const arc::mojom::AppInfo& app_info = arc_test.fake_apps()[0]; | 357 const arc::mojom::AppInfo& app_info = arc_test.fake_apps()[1]; |
| 352 const std::string app_id = ArcAppTest::GetAppId(app_info); | 358 const std::string app_id = ArcAppTest::GetAppId(app_info); |
| 353 controller()->SetAppPinnable(app_id, AppListControllerDelegate::PIN_EDITABLE); | 359 controller()->SetAppPinnable(app_id, AppListControllerDelegate::PIN_EDITABLE); |
| 354 | 360 |
| 355 arc_test.app_instance()->RefreshAppList(); | 361 arc_test.app_instance()->RefreshAppList(); |
| 356 arc_test.app_instance()->SendRefreshAppList(arc_test.fake_apps()); | 362 arc_test.app_instance()->SendRefreshAppList(arc_test.fake_apps()); |
| 357 | 363 |
| 358 ArcAppItem item(profile(), nullptr, app_id, std::string()); | 364 ArcAppItem item(profile(), nullptr, app_id, std::string()); |
| 359 | 365 |
| 360 ui::MenuModel* menu = item.GetContextMenuModel(); | 366 ui::MenuModel* menu = item.GetContextMenuModel(); |
| 361 ASSERT_NE(nullptr, menu); | 367 ASSERT_NE(nullptr, menu); |
| 362 | 368 |
| 363 ASSERT_EQ(4, menu->GetItemCount()); | 369 ASSERT_EQ(6, menu->GetItemCount()); |
| 364 EXPECT_EQ(app_list::AppContextMenu::LAUNCH_NEW, menu->GetCommandIdAt(0)); | 370 ValidateItemState(menu, 0, MenuState(app_list::AppContextMenu::LAUNCH_NEW)); |
| 365 EXPECT_TRUE(menu->IsEnabledAt(0)); | 371 ValidateItemState(menu, 1, MenuState()); // separator |
| 366 EXPECT_FALSE(menu->IsItemCheckedAt(0)); | 372 ValidateItemState(menu, 2, MenuState(app_list::AppContextMenu::TOGGLE_PIN)); |
| 367 EXPECT_EQ(-1, menu->GetCommandIdAt(1)); // separator | 373 ValidateItemState(menu, 3, MenuState()); // separator |
| 368 EXPECT_EQ(app_list::AppContextMenu::TOGGLE_PIN, menu->GetCommandIdAt(2)); | 374 ValidateItemState(menu, 4, MenuState(app_list::AppContextMenu::UNINSTALL)); |
| 369 EXPECT_TRUE(menu->IsEnabledAt(2)); | 375 ValidateItemState( |
| 370 EXPECT_FALSE(menu->IsItemCheckedAt(2)); | 376 menu, 5, MenuState(app_list::AppContextMenu::SHOW_APP_INFO)); |
| 371 EXPECT_EQ(app_list::AppContextMenu::SHOW_APP_INFO, menu->GetCommandIdAt(3)); | |
| 372 EXPECT_TRUE(menu->IsEnabledAt(3)); | |
| 373 EXPECT_FALSE(menu->IsItemCheckedAt(3)); | |
| 374 | 377 |
| 375 // Test activate request. | 378 // Test activate request. |
| 376 EXPECT_EQ(0u, arc_test.app_instance()->launch_requests().size()); | 379 EXPECT_EQ(0u, arc_test.app_instance()->launch_requests().size()); |
| 377 | 380 |
| 378 menu->ActivatedAt(0); | 381 menu->ActivatedAt(0); |
| 379 | 382 |
| 380 const ScopedVector<arc::FakeAppInstance::Request>& launch_requests = | 383 const ScopedVector<arc::FakeAppInstance::Request>& launch_requests = |
| 381 arc_test.app_instance()->launch_requests(); | 384 arc_test.app_instance()->launch_requests(); |
| 382 ASSERT_EQ(1u, launch_requests.size()); | 385 ASSERT_EQ(1u, launch_requests.size()); |
| 383 EXPECT_TRUE(launch_requests[0]->IsForApp(app_info)); | 386 EXPECT_TRUE(launch_requests[0]->IsForApp(app_info)); |
| 384 | 387 |
| 385 controller()->SetAppOpen(app_id, true); | 388 controller()->SetAppOpen(app_id, true); |
| 386 // It is not expected that menu model is unchanged on GetContextMenuModel. Arc | 389 // It is not expected that menu model is unchanged on GetContextMenuModel. Arc |
| 387 // app menu requires model to be recalculated. | 390 // app menu requires model to be recalculated. |
| 388 menu = item.GetContextMenuModel(); | 391 menu = item.GetContextMenuModel(); |
| 389 ASSERT_EQ(2, menu->GetItemCount()); | 392 ASSERT_EQ(4, menu->GetItemCount()); |
| 390 EXPECT_EQ(app_list::AppContextMenu::TOGGLE_PIN, menu->GetCommandIdAt(0)); | 393 ValidateItemState(menu, 0, MenuState(app_list::AppContextMenu::TOGGLE_PIN)); |
| 391 EXPECT_TRUE(menu->IsEnabledAt(0)); | 394 ValidateItemState(menu, 1, MenuState()); // separator |
| 392 EXPECT_FALSE(menu->IsItemCheckedAt(0)); | 395 ValidateItemState(menu, 2, MenuState(app_list::AppContextMenu::UNINSTALL)); |
| 393 EXPECT_EQ(app_list::AppContextMenu::SHOW_APP_INFO, menu->GetCommandIdAt(1)); | 396 ValidateItemState( |
| 394 EXPECT_TRUE(menu->IsEnabledAt(1)); | 397 menu, 3, MenuState(app_list::AppContextMenu::SHOW_APP_INFO)); |
| 395 EXPECT_FALSE(menu->IsItemCheckedAt(1)); | |
| 396 | 398 |
| 399 // This makes all apps non-ready. |
| 400 controller()->SetAppOpen(app_id, false); |
| 401 arc::InstanceHolder<arc::mojom::AppInstance>::Observer* instance_observer = |
| 402 arc_test.arc_app_list_prefs(); |
| 403 instance_observer->OnInstanceClosed(); |
| 404 |
| 405 menu = item.GetContextMenuModel(); |
| 406 ASSERT_EQ(6, menu->GetItemCount()); |
| 407 ValidateItemState(menu, 0, MenuState(app_list::AppContextMenu::LAUNCH_NEW)); |
| 408 ValidateItemState(menu, 1, MenuState()); // separator |
| 409 ValidateItemState(menu, 2, MenuState(app_list::AppContextMenu::TOGGLE_PIN)); |
| 410 ValidateItemState(menu, 3, MenuState()); // separator |
| 411 ValidateItemState( |
| 412 menu, 4, MenuState(app_list::AppContextMenu::UNINSTALL, false, false)); |
| 413 ValidateItemState( |
| 414 menu, 5, |
| 415 MenuState(app_list::AppContextMenu::SHOW_APP_INFO, false, false)); |
| 416 |
| 417 // Uninstall all apps. |
| 397 arc_test.app_instance()->RefreshAppList(); | 418 arc_test.app_instance()->RefreshAppList(); |
| 398 arc_test.app_instance()->SendRefreshAppList( | 419 arc_test.app_instance()->SendRefreshAppList( |
| 399 std::vector<arc::mojom::AppInfo>()); | 420 std::vector<arc::mojom::AppInfo>()); |
| 400 controller()->SetAppOpen(app_id, false); | 421 controller()->SetAppOpen(app_id, false); |
| 401 | 422 |
| 423 // No app available case. |
| 402 menu = item.GetContextMenuModel(); | 424 menu = item.GetContextMenuModel(); |
| 403 ASSERT_EQ(4, menu->GetItemCount()); | 425 EXPECT_EQ(0, menu->GetItemCount()); |
| 404 EXPECT_EQ(app_list::AppContextMenu::LAUNCH_NEW, menu->GetCommandIdAt(0)); | 426 } |
| 405 EXPECT_TRUE(menu->IsEnabledAt(0)); | 427 |
| 406 EXPECT_FALSE(menu->IsItemCheckedAt(0)); | 428 |
| 407 EXPECT_EQ(-1, menu->GetCommandIdAt(1)); // separator | 429 TEST_F(AppContextMenuTest, ArcMenuShortcut) { |
| 408 EXPECT_EQ(app_list::AppContextMenu::TOGGLE_PIN, menu->GetCommandIdAt(2)); | 430 ArcAppTest arc_test; |
| 409 EXPECT_TRUE(menu->IsEnabledAt(2)); | 431 arc_test.SetUp(profile()); |
| 410 EXPECT_FALSE(menu->IsItemCheckedAt(2)); | 432 |
| 411 EXPECT_EQ(app_list::AppContextMenu::SHOW_APP_INFO, menu->GetCommandIdAt(3)); | 433 const arc::mojom::ShortcutInfo& shortcut_info = arc_test.fake_shortcuts()[0]; |
| 412 EXPECT_TRUE(menu->IsEnabledAt(3)); | 434 const std::string app_id = ArcAppTest::GetAppId(shortcut_info); |
| 413 EXPECT_FALSE(menu->IsItemCheckedAt(3)); | 435 controller()->SetAppPinnable(app_id, AppListControllerDelegate::PIN_EDITABLE); |
| 436 |
| 437 arc_test.app_instance()->SendInstallShortcuts(arc_test.fake_shortcuts()); |
| 438 |
| 439 ArcAppItem item(profile(), nullptr, app_id, std::string()); |
| 440 |
| 441 ui::MenuModel* menu = item.GetContextMenuModel(); |
| 442 ASSERT_NE(nullptr, menu); |
| 443 |
| 444 ASSERT_EQ(6, menu->GetItemCount()); |
| 445 ValidateItemState(menu, 0, MenuState(app_list::AppContextMenu::LAUNCH_NEW)); |
| 446 ValidateItemState(menu, 1, MenuState()); // separator |
| 447 ValidateItemState(menu, 2, MenuState(app_list::AppContextMenu::TOGGLE_PIN)); |
| 448 ValidateItemState(menu, 3, MenuState()); // separator |
| 449 ValidateItemState(menu, 4, MenuState(app_list::AppContextMenu::UNINSTALL)); |
| 450 ValidateItemState( |
| 451 menu, 5, MenuState(app_list::AppContextMenu::SHOW_APP_INFO)); |
| 452 |
| 453 // This makes all apps non-ready. Shortcut is still uninstall-able. |
| 454 arc::InstanceHolder<arc::mojom::AppInstance>::Observer* instance_observer = |
| 455 arc_test.arc_app_list_prefs(); |
| 456 instance_observer->OnInstanceClosed(); |
| 457 |
| 458 menu = item.GetContextMenuModel(); |
| 459 ASSERT_EQ(6, menu->GetItemCount()); |
| 460 ValidateItemState(menu, 0, MenuState(app_list::AppContextMenu::LAUNCH_NEW)); |
| 461 ValidateItemState(menu, 1, MenuState()); // separator |
| 462 ValidateItemState(menu, 2, MenuState(app_list::AppContextMenu::TOGGLE_PIN)); |
| 463 ValidateItemState(menu, 3, MenuState()); // separator |
| 464 ValidateItemState(menu, 4, MenuState(app_list::AppContextMenu::UNINSTALL)); |
| 465 ValidateItemState( |
| 466 menu, 5, |
| 467 MenuState(app_list::AppContextMenu::SHOW_APP_INFO, false, false)); |
| 414 } | 468 } |
| 415 | 469 |
| 416 TEST_F(AppContextMenuTest, ArcMenuStickyItem) { | 470 TEST_F(AppContextMenuTest, ArcMenuStickyItem) { |
| 417 ArcAppTest arc_test; | 471 ArcAppTest arc_test; |
| 418 arc_test.SetUp(profile()); | 472 arc_test.SetUp(profile()); |
| 419 | 473 |
| 420 arc_test.app_instance()->RefreshAppList(); | 474 arc_test.app_instance()->RefreshAppList(); |
| 421 arc_test.app_instance()->SendRefreshAppList(arc_test.fake_apps()); | 475 arc_test.app_instance()->SendRefreshAppList(arc_test.fake_apps()); |
| 422 | 476 |
| 423 { | 477 { |
| 424 // Verify menu of store | 478 // Verify menu of store |
| 425 const arc::mojom::AppInfo& store_info = arc_test.fake_apps()[0]; | 479 const arc::mojom::AppInfo& store_info = arc_test.fake_apps()[0]; |
| 426 const std::string store_id = ArcAppTest::GetAppId(store_info); | 480 const std::string store_id = ArcAppTest::GetAppId(store_info); |
| 427 controller()->SetAppPinnable(store_id, | 481 controller()->SetAppPinnable(store_id, |
| 428 AppListControllerDelegate::PIN_EDITABLE); | 482 AppListControllerDelegate::PIN_EDITABLE); |
| 429 ArcAppItem item(profile(), nullptr, store_id, std::string()); | 483 ArcAppItem item(profile(), nullptr, store_id, std::string()); |
| 430 ui::MenuModel* menu = item.GetContextMenuModel(); | 484 ui::MenuModel* menu = item.GetContextMenuModel(); |
| 431 ASSERT_NE(nullptr, menu); | 485 ASSERT_NE(nullptr, menu); |
| 432 | 486 |
| 433 ASSERT_EQ(4, menu->GetItemCount()); | 487 ASSERT_EQ(5, menu->GetItemCount()); |
| 434 EXPECT_EQ(app_list::AppContextMenu::LAUNCH_NEW, menu->GetCommandIdAt(0)); | 488 ValidateItemState(menu, 0, MenuState(app_list::AppContextMenu::LAUNCH_NEW)); |
| 435 EXPECT_TRUE(menu->IsEnabledAt(0)); | 489 ValidateItemState(menu, 1, MenuState()); // separator |
| 436 EXPECT_FALSE(menu->IsItemCheckedAt(0)); | 490 ValidateItemState(menu, 2, MenuState(app_list::AppContextMenu::TOGGLE_PIN)); |
| 437 EXPECT_EQ(-1, menu->GetCommandIdAt(1)); // separator | 491 ValidateItemState(menu, 3, MenuState()); // separator |
| 438 EXPECT_EQ(app_list::AppContextMenu::TOGGLE_PIN, menu->GetCommandIdAt(2)); | 492 ValidateItemState( |
| 439 EXPECT_TRUE(menu->IsEnabledAt(2)); | 493 menu, 4, MenuState(app_list::AppContextMenu::SHOW_APP_INFO)); |
| 440 EXPECT_FALSE(menu->IsItemCheckedAt(2)); | |
| 441 EXPECT_EQ(app_list::AppContextMenu::SHOW_APP_INFO, menu->GetCommandIdAt(3)); | |
| 442 EXPECT_TRUE(menu->IsEnabledAt(3)); | |
| 443 EXPECT_FALSE(menu->IsItemCheckedAt(3)); | |
| 444 | |
| 445 // No "uninstall" entry. | |
| 446 } | |
| 447 | |
| 448 { | |
| 449 // Verify normal app menu | |
| 450 const arc::mojom::AppInfo& app_info = arc_test.fake_apps()[1]; | |
| 451 const std::string app_id = ArcAppTest::GetAppId(app_info); | |
| 452 controller()->SetAppPinnable(app_id, | |
| 453 AppListControllerDelegate::PIN_EDITABLE); | |
| 454 ArcAppItem item(profile(), nullptr, app_id, std::string()); | |
| 455 ui::MenuModel* menu = item.GetContextMenuModel(); | |
| 456 ASSERT_NE(nullptr, menu); | |
| 457 | |
| 458 ASSERT_EQ(6, menu->GetItemCount()); | |
| 459 EXPECT_EQ(app_list::AppContextMenu::LAUNCH_NEW, menu->GetCommandIdAt(0)); | |
| 460 EXPECT_TRUE(menu->IsEnabledAt(0)); | |
| 461 EXPECT_FALSE(menu->IsItemCheckedAt(0)); | |
| 462 EXPECT_EQ(-1, menu->GetCommandIdAt(1)); // separator | |
| 463 EXPECT_EQ(app_list::AppContextMenu::TOGGLE_PIN, menu->GetCommandIdAt(2)); | |
| 464 EXPECT_TRUE(menu->IsEnabledAt(2)); | |
| 465 EXPECT_FALSE(menu->IsItemCheckedAt(2)); | |
| 466 EXPECT_EQ(-1, menu->GetCommandIdAt(3)); // separator | |
| 467 EXPECT_EQ(app_list::AppContextMenu::UNINSTALL, menu->GetCommandIdAt(4)); | |
| 468 EXPECT_TRUE(menu->IsEnabledAt(4)); | |
| 469 EXPECT_FALSE(menu->IsItemCheckedAt(4)); | |
| 470 EXPECT_EQ(app_list::AppContextMenu::SHOW_APP_INFO, menu->GetCommandIdAt(5)); | |
| 471 EXPECT_TRUE(menu->IsEnabledAt(5)); | |
| 472 EXPECT_FALSE(menu->IsItemCheckedAt(5)); | |
| 473 } | 494 } |
| 474 } | 495 } |
| 496 |
| 475 #endif | 497 #endif |
| OLD | NEW |