Commit 02b68439 authored by Qiang Xu's avatar Qiang Xu Committed by Commit Bot

cros: introduce callback for GetContextMenu in ash::ShelfItemDelegate

Changes:
Introduce callback for GetContextMenu in ash::ShelfItemDelegate so that
chrome's implementation could pass this callback further to wait
asynchronous getting menu items, such as getting menu items from
Android.
For ARC++ app shortcuts project, we could bind GetAppShortcutItems
callback and run this introduced callback when android runs
GetAppShortcutItems callback.

AppListItem side change: crrev.com/c/1023064.

Bug: 803291
Test: covered by tests.
Change-Id: I4d1e25ff8dfcf6572bb483fe4be3bd3eddba367e
Reviewed-on: https://chromium-review.googlesource.com/1023161
Commit-Queue: Qiang Xu <warx@google.com>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#552847}
parent ca095304
...@@ -8,12 +8,13 @@ ...@@ -8,12 +8,13 @@
#include <utility> #include <utility>
#include "ash/public/cpp/menu_utils.h" #include "ash/public/cpp/menu_utils.h"
#include "base/bind.h"
#include "ui/base/models/menu_model.h" #include "ui/base/models/menu_model.h"
namespace ash { namespace ash {
ShelfItemDelegate::ShelfItemDelegate(const ShelfID& shelf_id) ShelfItemDelegate::ShelfItemDelegate(const ShelfID& shelf_id)
: shelf_id_(shelf_id), binding_(this), image_set_by_controller_(false) {} : shelf_id_(shelf_id), binding_(this), weak_ptr_factory_(this) {}
ShelfItemDelegate::~ShelfItemDelegate() = default; ShelfItemDelegate::~ShelfItemDelegate() = default;
...@@ -27,10 +28,10 @@ MenuItemList ShelfItemDelegate::GetAppMenuItems(int event_flags) { ...@@ -27,10 +28,10 @@ MenuItemList ShelfItemDelegate::GetAppMenuItems(int event_flags) {
return MenuItemList(); return MenuItemList();
} }
std::unique_ptr<ui::MenuModel> ShelfItemDelegate::GetContextMenu( void ShelfItemDelegate::GetContextMenu(int64_t display_id,
int64_t display_id) { GetMenuModelCallback callback) {
// Shelf items do not have any custom context menu entries by default. // Shelf items do not have any custom context menu entries by default.
return nullptr; std::move(callback).Run(nullptr);
} }
AppWindowLauncherItemController* AppWindowLauncherItemController*
...@@ -54,7 +55,16 @@ bool ShelfItemDelegate::ExecuteContextMenuCommand(int64_t command_id, ...@@ -54,7 +55,16 @@ bool ShelfItemDelegate::ExecuteContextMenuCommand(int64_t command_id,
void ShelfItemDelegate::GetContextMenuItems( void ShelfItemDelegate::GetContextMenuItems(
int64_t display_id, int64_t display_id,
GetContextMenuItemsCallback callback) { GetContextMenuItemsCallback callback) {
context_menu_ = GetContextMenu(display_id); GetContextMenu(
display_id,
base::BindOnce(&ShelfItemDelegate::OnGetContextMenu,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}
void ShelfItemDelegate::OnGetContextMenu(
GetContextMenuItemsCallback callback,
std::unique_ptr<ui::MenuModel> menu_model) {
context_menu_ = std::move(menu_model);
std::move(callback).Run( std::move(callback).Run(
menu_utils::GetMojoMenuItemsFromModel(context_menu_.get())); menu_utils::GetMojoMenuItemsFromModel(context_menu_.get()));
} }
......
...@@ -5,13 +5,16 @@ ...@@ -5,13 +5,16 @@
#ifndef ASH_PUBLIC_CPP_SHELF_ITEM_DELEGATE_H_ #ifndef ASH_PUBLIC_CPP_SHELF_ITEM_DELEGATE_H_
#define ASH_PUBLIC_CPP_SHELF_ITEM_DELEGATE_H_ #define ASH_PUBLIC_CPP_SHELF_ITEM_DELEGATE_H_
#include <memory>
#include <string> #include <string>
#include "ash/public/cpp/ash_public_export.h" #include "ash/public/cpp/ash_public_export.h"
#include "ash/public/cpp/shelf_types.h" #include "ash/public/cpp/shelf_types.h"
#include "ash/public/interfaces/shelf.mojom.h" #include "ash/public/interfaces/shelf.mojom.h"
#include "base/callback.h"
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding.h"
#include "ui/events/event.h" #include "ui/events/event.h"
...@@ -49,7 +52,10 @@ class ASH_PUBLIC_EXPORT ShelfItemDelegate : public mojom::ShelfItemDelegate { ...@@ -49,7 +52,10 @@ class ASH_PUBLIC_EXPORT ShelfItemDelegate : public mojom::ShelfItemDelegate {
virtual MenuItemList GetAppMenuItems(int event_flags); virtual MenuItemList GetAppMenuItems(int event_flags);
// Returns the context menu model; used to show ShelfItem context menus. // Returns the context menu model; used to show ShelfItem context menus.
virtual std::unique_ptr<ui::MenuModel> GetContextMenu(int64_t display_id); using GetMenuModelCallback =
base::OnceCallback<void(std::unique_ptr<ui::MenuModel>)>;
virtual void GetContextMenu(int64_t display_id,
GetMenuModelCallback callback);
// Returns nullptr if class is not AppWindowLauncherItemController. // Returns nullptr if class is not AppWindowLauncherItemController.
virtual AppWindowLauncherItemController* AsAppWindowLauncherItemController(); virtual AppWindowLauncherItemController* AsAppWindowLauncherItemController();
...@@ -62,6 +68,10 @@ class ASH_PUBLIC_EXPORT ShelfItemDelegate : public mojom::ShelfItemDelegate { ...@@ -62,6 +68,10 @@ class ASH_PUBLIC_EXPORT ShelfItemDelegate : public mojom::ShelfItemDelegate {
GetContextMenuItemsCallback callback) override; GetContextMenuItemsCallback callback) override;
private: private:
// Bound by GetContextMenu().
void OnGetContextMenu(GetContextMenuItemsCallback callback,
std::unique_ptr<ui::MenuModel> menu_model);
// The shelf id; empty if there is no app associated with the item. // The shelf id; empty if there is no app associated with the item.
// Besides the application id, ShelfID also contains a launch id, which is an // Besides the application id, ShelfID also contains a launch id, which is an
// id that can be passed to an app when launched in order to support multiple // id that can be passed to an app when launched in order to support multiple
...@@ -73,11 +83,13 @@ class ASH_PUBLIC_EXPORT ShelfItemDelegate : public mojom::ShelfItemDelegate { ...@@ -73,11 +83,13 @@ class ASH_PUBLIC_EXPORT ShelfItemDelegate : public mojom::ShelfItemDelegate {
mojo::Binding<mojom::ShelfItemDelegate> binding_; mojo::Binding<mojom::ShelfItemDelegate> binding_;
// Set to true if the launcher item image has been set by the controller. // Set to true if the launcher item image has been set by the controller.
bool image_set_by_controller_; bool image_set_by_controller_ = false;
// The context menu model that was last shown for the associated shelf item. // The context menu model that was last shown for the associated shelf item.
std::unique_ptr<ui::MenuModel> context_menu_; std::unique_ptr<ui::MenuModel> context_menu_;
base::WeakPtrFactory<ShelfItemDelegate> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(ShelfItemDelegate); DISALLOW_COPY_AND_ASSIGN(ShelfItemDelegate);
}; };
......
...@@ -126,11 +126,13 @@ ash::MenuItemList AppShortcutLauncherItemController::GetAppMenuItems( ...@@ -126,11 +126,13 @@ ash::MenuItemList AppShortcutLauncherItemController::GetAppMenuItems(
return items; return items;
} }
std::unique_ptr<ui::MenuModel> void AppShortcutLauncherItemController::GetContextMenu(
AppShortcutLauncherItemController::GetContextMenu(int64_t display_id) { int64_t display_id,
GetMenuModelCallback callback) {
ChromeLauncherController* controller = ChromeLauncherController::instance(); ChromeLauncherController* controller = ChromeLauncherController::instance();
const ash::ShelfItem* item = controller->GetItem(shelf_id()); const ash::ShelfItem* item = controller->GetItem(shelf_id());
return LauncherContextMenu::Create(controller, item, display_id); std::move(callback).Run(
LauncherContextMenu::Create(controller, item, display_id));
} }
void AppShortcutLauncherItemController::ExecuteCommand(bool from_context_menu, void AppShortcutLauncherItemController::ExecuteCommand(bool from_context_menu,
......
...@@ -47,7 +47,8 @@ class AppShortcutLauncherItemController : public ash::ShelfItemDelegate { ...@@ -47,7 +47,8 @@ class AppShortcutLauncherItemController : public ash::ShelfItemDelegate {
ash::ShelfLaunchSource source, ash::ShelfLaunchSource source,
ItemSelectedCallback callback) override; ItemSelectedCallback callback) override;
ash::MenuItemList GetAppMenuItems(int event_flags) override; ash::MenuItemList GetAppMenuItems(int event_flags) override;
std::unique_ptr<ui::MenuModel> GetContextMenu(int64_t display_id) override; void GetContextMenu(int64_t display_id,
GetMenuModelCallback callback) override;
void ExecuteCommand(bool from_context_menu, void ExecuteCommand(bool from_context_menu,
int64_t command_id, int64_t command_id,
int32_t event_flags, int32_t event_flags,
......
...@@ -101,11 +101,13 @@ void AppWindowLauncherItemController::ItemSelected( ...@@ -101,11 +101,13 @@ void AppWindowLauncherItemController::ItemSelected(
action, GetAppMenuItems(event ? event->flags() : ui::EF_NONE)); action, GetAppMenuItems(event ? event->flags() : ui::EF_NONE));
} }
std::unique_ptr<ui::MenuModel> AppWindowLauncherItemController::GetContextMenu( void AppWindowLauncherItemController::GetContextMenu(
int64_t display_id) { int64_t display_id,
GetMenuModelCallback callback) {
ChromeLauncherController* controller = ChromeLauncherController::instance(); ChromeLauncherController* controller = ChromeLauncherController::instance();
const ash::ShelfItem* item = controller->GetItem(shelf_id()); const ash::ShelfItem* item = controller->GetItem(shelf_id());
return LauncherContextMenu::Create(controller, item, display_id); std::move(callback).Run(
LauncherContextMenu::Create(controller, item, display_id));
} }
void AppWindowLauncherItemController::Close() { void AppWindowLauncherItemController::Close() {
......
...@@ -52,7 +52,8 @@ class AppWindowLauncherItemController : public ash::ShelfItemDelegate, ...@@ -52,7 +52,8 @@ class AppWindowLauncherItemController : public ash::ShelfItemDelegate,
int64_t command_id, int64_t command_id,
int32_t event_flags, int32_t event_flags,
int64_t display_id) override; int64_t display_id) override;
std::unique_ptr<ui::MenuModel> GetContextMenu(int64_t display_id) override; void GetContextMenu(int64_t display_id,
GetMenuModelCallback callback) override;
void Close() override; void Close() override;
// aura::WindowObserver overrides: // aura::WindowObserver overrides:
......
...@@ -54,11 +54,13 @@ void ArcAppDeferredLauncherItemController::ExecuteCommand( ...@@ -54,11 +54,13 @@ void ArcAppDeferredLauncherItemController::ExecuteCommand(
NOTIMPLEMENTED(); NOTIMPLEMENTED();
} }
std::unique_ptr<ui::MenuModel> void ArcAppDeferredLauncherItemController::GetContextMenu(
ArcAppDeferredLauncherItemController::GetContextMenu(int64_t display_id) { int64_t display_id,
GetMenuModelCallback callback) {
ChromeLauncherController* controller = ChromeLauncherController::instance(); ChromeLauncherController* controller = ChromeLauncherController::instance();
const ash::ShelfItem* item = controller->GetItem(shelf_id()); const ash::ShelfItem* item = controller->GetItem(shelf_id());
return LauncherContextMenu::Create(controller, item, display_id); std::move(callback).Run(
LauncherContextMenu::Create(controller, item, display_id));
} }
void ArcAppDeferredLauncherItemController::Close() { void ArcAppDeferredLauncherItemController::Close() {
......
...@@ -43,7 +43,8 @@ class ArcAppDeferredLauncherItemController : public ash::ShelfItemDelegate { ...@@ -43,7 +43,8 @@ class ArcAppDeferredLauncherItemController : public ash::ShelfItemDelegate {
int64_t command_id, int64_t command_id,
int32_t event_flags, int32_t event_flags,
int64_t display_id) override; int64_t display_id) override;
std::unique_ptr<ui::MenuModel> GetContextMenu(int64_t display_id) override; void GetContextMenu(int64_t display_id,
GetMenuModelCallback callback) override;
void Close() override; void Close() override;
private: private:
......
...@@ -243,11 +243,13 @@ ash::MenuItemList BrowserShortcutLauncherItemController::GetAppMenuItems( ...@@ -243,11 +243,13 @@ ash::MenuItemList BrowserShortcutLauncherItemController::GetAppMenuItems(
return items; return items;
} }
std::unique_ptr<ui::MenuModel> void BrowserShortcutLauncherItemController::GetContextMenu(
BrowserShortcutLauncherItemController::GetContextMenu(int64_t display_id) { int64_t display_id,
GetMenuModelCallback callback) {
ChromeLauncherController* controller = ChromeLauncherController::instance(); ChromeLauncherController* controller = ChromeLauncherController::instance();
const ash::ShelfItem* item = controller->GetItem(shelf_id()); const ash::ShelfItem* item = controller->GetItem(shelf_id());
return LauncherContextMenu::Create(controller, item, display_id); std::move(callback).Run(
LauncherContextMenu::Create(controller, item, display_id));
} }
void BrowserShortcutLauncherItemController::ExecuteCommand( void BrowserShortcutLauncherItemController::ExecuteCommand(
......
...@@ -44,7 +44,8 @@ class BrowserShortcutLauncherItemController : public ash::ShelfItemDelegate, ...@@ -44,7 +44,8 @@ class BrowserShortcutLauncherItemController : public ash::ShelfItemDelegate,
ash::ShelfLaunchSource source, ash::ShelfLaunchSource source,
ItemSelectedCallback callback) override; ItemSelectedCallback callback) override;
ash::MenuItemList GetAppMenuItems(int event_flags) override; ash::MenuItemList GetAppMenuItems(int event_flags) override;
std::unique_ptr<ui::MenuModel> GetContextMenu(int64_t display_id) override; void GetContextMenu(int64_t display_id,
GetMenuModelCallback callback) override;
void ExecuteCommand(bool from_context_menu, void ExecuteCommand(bool from_context_menu,
int64_t command_id, int64_t command_id,
int32_t event_flags, int32_t event_flags,
......
...@@ -10,8 +10,10 @@ ...@@ -10,8 +10,10 @@
#include "ash/public/cpp/shelf_model.h" #include "ash/public/cpp/shelf_model.h"
#include "ash/test/ash_test_base.h" #include "ash/test/ash_test_base.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/test/bind_test_util.h"
#include "chrome/app/chrome_command_ids.h" #include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/prefs/incognito_mode_prefs.h" #include "chrome/browser/prefs/incognito_mode_prefs.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
...@@ -93,6 +95,21 @@ class LauncherContextMenuTest : public ash::AshTestBase { ...@@ -93,6 +95,21 @@ class LauncherContextMenuTest : public ash::AshTestBase {
return widget; return widget;
} }
std::unique_ptr<ui::MenuModel> GetContextMenu(
ash::ShelfItemDelegate* item_delegate,
int64_t display_id) {
base::RunLoop run_loop;
std::unique_ptr<ui::MenuModel> menu;
item_delegate->GetContextMenu(
display_id, base::BindLambdaForTesting(
[&](std::unique_ptr<ui::MenuModel> created_menu) {
menu = std::move(created_menu);
run_loop.Quit();
}));
run_loop.Run();
return menu;
}
void TearDown() override { void TearDown() override {
launcher_controller_.reset(); launcher_controller_.reset();
ash::AshTestBase::TearDown(); ash::AshTestBase::TearDown();
...@@ -197,7 +214,7 @@ TEST_F(LauncherContextMenuTest, ArcLauncherMenusCheck) { ...@@ -197,7 +214,7 @@ TEST_F(LauncherContextMenuTest, ArcLauncherMenusCheck) {
const int64_t display_id = GetPrimaryDisplay().id(); const int64_t display_id = GetPrimaryDisplay().id();
std::unique_ptr<ui::MenuModel> menu = std::unique_ptr<ui::MenuModel> menu =
item_delegate->GetContextMenu(display_id); GetContextMenu(item_delegate, display_id);
ASSERT_TRUE(menu); ASSERT_TRUE(menu);
// ARC app is pinned but not running. // ARC app is pinned but not running.
...@@ -220,7 +237,7 @@ TEST_F(LauncherContextMenuTest, ArcLauncherMenusCheck) { ...@@ -220,7 +237,7 @@ TEST_F(LauncherContextMenuTest, ArcLauncherMenusCheck) {
ASSERT_EQ(1U, menu_list.size()); ASSERT_EQ(1U, menu_list.size());
EXPECT_EQ(base::UTF8ToUTF16(app_name), menu_list[0]->label); EXPECT_EQ(base::UTF8ToUTF16(app_name), menu_list[0]->label);
menu = item_delegate->GetContextMenu(display_id); menu = GetContextMenu(item_delegate, display_id);
ASSERT_TRUE(menu); ASSERT_TRUE(menu);
EXPECT_FALSE( EXPECT_FALSE(
...@@ -247,7 +264,7 @@ TEST_F(LauncherContextMenuTest, ArcLauncherMenusCheck) { ...@@ -247,7 +264,7 @@ TEST_F(LauncherContextMenuTest, ArcLauncherMenusCheck) {
ASSERT_EQ(1U, menu_list.size()); ASSERT_EQ(1U, menu_list.size());
EXPECT_EQ(base::UTF8ToUTF16(app_name2), menu_list[0]->label); EXPECT_EQ(base::UTF8ToUTF16(app_name2), menu_list[0]->label);
menu = item_delegate2->GetContextMenu(display_id); menu = GetContextMenu(item_delegate2, display_id);
ASSERT_TRUE(menu); ASSERT_TRUE(menu);
EXPECT_FALSE( EXPECT_FALSE(
...@@ -289,7 +306,7 @@ TEST_F(LauncherContextMenuTest, ArcLauncherMenusCheck) { ...@@ -289,7 +306,7 @@ TEST_F(LauncherContextMenuTest, ArcLauncherMenusCheck) {
model()->GetShelfItemDelegate(shelf_id3); model()->GetShelfItemDelegate(shelf_id3);
ASSERT_TRUE(item_delegate3); ASSERT_TRUE(item_delegate3);
menu = item_delegate3->GetContextMenu(display_id); menu = GetContextMenu(item_delegate3, display_id);
ASSERT_TRUE(menu); ASSERT_TRUE(menu);
EXPECT_FALSE( EXPECT_FALSE(
...@@ -339,7 +356,7 @@ TEST_F(LauncherContextMenuTest, ArcDeferredLauncherContextMenuItemCheck) { ...@@ -339,7 +356,7 @@ TEST_F(LauncherContextMenuTest, ArcDeferredLauncherContextMenuItemCheck) {
model()->GetShelfItemDelegate(shelf_id1); model()->GetShelfItemDelegate(shelf_id1);
ASSERT_TRUE(item_delegate); ASSERT_TRUE(item_delegate);
std::unique_ptr<ui::MenuModel> menu = std::unique_ptr<ui::MenuModel> menu =
item_delegate->GetContextMenu(0 /* display_id */); GetContextMenu(item_delegate, 0 /* display_id */);
ASSERT_TRUE(menu); ASSERT_TRUE(menu);
EXPECT_FALSE( EXPECT_FALSE(
...@@ -349,7 +366,7 @@ TEST_F(LauncherContextMenuTest, ArcDeferredLauncherContextMenuItemCheck) { ...@@ -349,7 +366,7 @@ TEST_F(LauncherContextMenuTest, ArcDeferredLauncherContextMenuItemCheck) {
item_delegate = model()->GetShelfItemDelegate(shelf_id2); item_delegate = model()->GetShelfItemDelegate(shelf_id2);
ASSERT_TRUE(item_delegate); ASSERT_TRUE(item_delegate);
menu = item_delegate->GetContextMenu(0 /* display_id */); menu = GetContextMenu(item_delegate, 0 /* display_id */);
ASSERT_TRUE(menu); ASSERT_TRUE(menu);
EXPECT_FALSE( EXPECT_FALSE(
......
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