diff options
36 files changed, 836 insertions, 468 deletions
diff --git a/ash/ash.gyp b/ash/ash.gyp index 3ece44a..baa8015 100644 --- a/ash/ash.gyp +++ b/ash/ash.gyp @@ -622,6 +622,8 @@ 'test/launcher_view_test_api.h', 'test/display_manager_test_api.cc', 'test/display_manager_test_api.h', + 'test/launcher_item_delegate_manager_test_api.cc', + 'test/launcher_item_delegate_manager_test_api.h', 'test/mirror_window_test_api.cc', 'test/mirror_window_test_api.h', 'test/shell_test_api.cc', @@ -632,10 +634,12 @@ 'test/test_user_wallpaper_delegate.h', 'test/test_launcher_delegate.cc', 'test/test_launcher_delegate.h', + 'test/test_launcher_item_delegate.cc', + 'test/test_launcher_item_delegate.h', 'test/test_screenshot_delegate.cc', 'test/test_screenshot_delegate.cc', 'test/test_session_state_delegate.cc', - 'test/test_session_state_delegate.cc', + 'test/test_session_state_delegate.h', 'test/test_shell_delegate.cc', 'test/test_shell_delegate.h', 'test/test_suite.cc', @@ -748,14 +752,21 @@ 'shell/context_menu.cc', 'shell/context_menu.h', 'shell/launcher_delegate_impl.cc', + 'shell/launcher_delegate_impl.h', 'shell/lock_view.cc', 'shell/panel_window.cc', + 'shell/panel_window.h', 'shell/shell_delegate_impl.cc', 'shell/shell_delegate_impl.h', 'shell/toplevel_window.cc', + 'shell/toplevel_window.h', 'shell/widgets.cc', 'shell/window_type_launcher.cc', + 'shell/window_type_launcher.h', 'shell/window_watcher.cc', + 'shell/window_watcher.h', + 'shell/window_watcher_launcher_item_delegate.cc', + 'shell/window_watcher_launcher_item_delegate.h', 'shell/window_watcher_unittest.cc', 'shell_unittest.cc', 'system/chromeos/managed/tray_locally_managed_user_unittest.cc', @@ -914,6 +925,8 @@ 'shell/window_type_launcher.h', 'shell/window_watcher.cc', 'shell/window_watcher.h', + 'shell/window_watcher_launcher_item_delegate.cc', + 'shell/window_watcher_launcher_item_delegate.h', '../content/app/startup_helper_win.cc', '../ui/views/test/test_views_delegate.cc', ], diff --git a/ash/launcher/launcher.cc b/ash/launcher/launcher.cc index b1e819d..ae16485 100644 --- a/ash/launcher/launcher.cc +++ b/ash/launcher/launcher.cc @@ -108,8 +108,10 @@ void Launcher::ActivateLauncherItem(int index) { false); const ash::LauncherItem& item = launcher_view_->model()->items()[index]; - Shell::GetInstance()->launcher_item_delegate_manager()-> - GetLauncherItemDelegate(item.type)->ItemSelected(item, event); + ash::LauncherItemDelegate* item_delegate = + Shell::GetInstance()->launcher_item_delegate_manager()-> + GetLauncherItemDelegate(item.id); + item_delegate->ItemSelected(event); } void Launcher::CycleWindowLinear(CycleDirection direction) { diff --git a/ash/launcher/launcher_delegate.h b/ash/launcher/launcher_delegate.h index 41d0c29..3766ca3 100644 --- a/ash/launcher/launcher_delegate.h +++ b/ash/launcher/launcher_delegate.h @@ -25,6 +25,7 @@ class ASH_EXPORT LauncherDelegate { // there isn't one. // Note: Windows of tabbed browsers will return the |LauncherID| of the // currently active tab or selected tab. + // TODO(simon.hong81): Remove this and handle in LauncherItemDelegateManager. virtual LauncherID GetIDByWindow(aura::Window* window) = 0; // Callback used to allow delegate to perform initialization actions that diff --git a/ash/launcher/launcher_item_delegate.h b/ash/launcher/launcher_item_delegate.h index e1d940d..a72b6e6 100644 --- a/ash/launcher/launcher_item_delegate.h +++ b/ash/launcher/launcher_item_delegate.h @@ -35,7 +35,6 @@ class ASH_EXPORT LauncherMenuModel : public ui::SimpleMenuModel { }; // Delegate for the LauncherItem. -// TODO(simon.hong81): Remove LauncherItem from abstract function parameters. class ASH_EXPORT LauncherItemDelegate { public: virtual ~LauncherItemDelegate() {} @@ -46,17 +45,15 @@ class ASH_EXPORT LauncherItemDelegate { // but not |aura::Window|. If the |event| is of type KeyEvent, it is assumed // that this was triggered by keyboard action (Alt+<number>) and special // handling might happen. - virtual void ItemSelected(const LauncherItem& item, - const ui::Event& event) = 0; + virtual void ItemSelected(const ui::Event& event) = 0; - // Returns the title to display for the specified launcher item. - virtual base::string16 GetTitle(const LauncherItem& item) = 0; + // Returns the title to display. + virtual base::string16 GetTitle() = 0; // Returns the context menumodel for the specified item on // |root_window|. Return NULL if there should be no context // menu. The caller takes ownership of the returned model. - virtual ui::MenuModel* CreateContextMenu(const LauncherItem& item, - aura::RootWindow* root_window) = 0; + virtual ui::MenuModel* CreateContextMenu(aura::RootWindow* root_window) = 0; // Returns the application menu model for the specified item. There are three // possible return values: @@ -67,15 +64,13 @@ class ASH_EXPORT LauncherItemDelegate { // - A list containing the title and the active list of items. // The caller takes ownership of the returned model. // |event_flags| specifies the flags of the event which triggered this menu. - virtual LauncherMenuModel* CreateApplicationMenu( - const LauncherItem& item, - int event_flags) = 0; + virtual ash::LauncherMenuModel* CreateApplicationMenu(int event_flags) = 0; - // Whether the given launcher item is draggable. - virtual bool IsDraggable(const LauncherItem& item) = 0; + // Whether the launcher item is draggable. + virtual bool IsDraggable() = 0; - // Returns true if a tooltip should be shown for the item. - virtual bool ShouldShowTooltip(const LauncherItem& item) = 0; + // Returns true if a tooltip should be shown. + virtual bool ShouldShowTooltip() = 0; }; } // namespace ash diff --git a/ash/launcher/launcher_item_delegate_manager.cc b/ash/launcher/launcher_item_delegate_manager.cc index 1708fe6..e401b76 100644 --- a/ash/launcher/launcher_item_delegate_manager.cc +++ b/ash/launcher/launcher_item_delegate_manager.cc @@ -4,28 +4,72 @@ #include "ash/launcher/launcher_item_delegate_manager.h" +#include "ash/launcher/launcher_item_delegate.h" +#include "ash/launcher/launcher_model.h" +#include "ash/shell.h" #include "base/logging.h" +#include "base/stl_util.h" namespace ash { -LauncherItemDelegateManager::LauncherItemDelegateManager() { +LauncherItemDelegateManager::LauncherItemDelegateManager( + ash::LauncherModel* model) : model_(model) { + DCHECK(model_); + model_->AddObserver(this); } LauncherItemDelegateManager::~LauncherItemDelegateManager() { + model_->RemoveObserver(this); + STLDeleteContainerPairSecondPointers(id_to_item_delegate_map_.begin(), + id_to_item_delegate_map_.end()); } -void LauncherItemDelegateManager::RegisterLauncherItemDelegate( - ash::LauncherItemType type, LauncherItemDelegate* item_delegate) { - // When a new |item_delegate| is registered with an exsiting |type|, it will - // get overwritten. - item_type_to_item_delegate_map_[type] = item_delegate; +void LauncherItemDelegateManager::SetLauncherItemDelegate( + ash::LauncherID id, + scoped_ptr<LauncherItemDelegate> item_delegate) { + // If another LauncherItemDelegate is already registered for |id|, we assume + // that this request is replacing LauncherItemDelegate for |id| with + // |item_delegate|. + RemoveLauncherItemDelegate(id); + id_to_item_delegate_map_[id] = item_delegate.release(); } LauncherItemDelegate* LauncherItemDelegateManager::GetLauncherItemDelegate( - ash::LauncherItemType item_type) { - DCHECK(item_type_to_item_delegate_map_.find(item_type) != - item_type_to_item_delegate_map_.end()); - return item_type_to_item_delegate_map_[item_type]; + ash::LauncherID id) { + if (model_->ItemIndexByID(id) != -1) { + // Each LauncherItem has to have a LauncherItemDelegate. + DCHECK(id_to_item_delegate_map_.find(id) != id_to_item_delegate_map_.end()); + return id_to_item_delegate_map_[id]; + } + return NULL; +} + +void LauncherItemDelegateManager::LauncherItemAdded(int index) { +} + +void LauncherItemDelegateManager::LauncherItemRemoved(int index, + ash::LauncherID id) { + RemoveLauncherItemDelegate(id); +} + +void LauncherItemDelegateManager::LauncherItemMoved(int start_index, + int target_index) { +} + +void LauncherItemDelegateManager::LauncherItemChanged( + int index, + const LauncherItem& old_item) { +} + +void LauncherItemDelegateManager::LauncherStatusChanged() { +} + +void LauncherItemDelegateManager::RemoveLauncherItemDelegate( + ash::LauncherID id) { + if (id_to_item_delegate_map_.find(id) != id_to_item_delegate_map_.end()) { + delete id_to_item_delegate_map_[id]; + id_to_item_delegate_map_.erase(id); + } } } // namespace ash diff --git a/ash/launcher/launcher_item_delegate_manager.h b/ash/launcher/launcher_item_delegate_manager.h index f7c52f5..168a094 100644 --- a/ash/launcher/launcher_item_delegate_manager.h +++ b/ash/launcher/launcher_item_delegate_manager.h @@ -8,39 +8,61 @@ #include <map> #include "ash/ash_export.h" +#include "ash/launcher/launcher_model_observer.h" #include "ash/launcher/launcher_types.h" #include "base/compiler_specific.h" +#include "base/memory/scoped_ptr.h" namespace ash { class LauncherItemDelegate; +class LauncherModel; -// LauncherItemDelegateManager helps Launcher/LauncherView to choose right -// LauncherItemDelegate based on LauncherItemType. -// When new LauncherItemDelegate is created, it must be registered by -// RegisterLauncherItemDelegate(). If not, Launcher/LauncherView can't get -// LauncherItem's LauncherItemDelegate. -// TODO(simon.hong81): This class should own all LauncherItemDelegate. -class ASH_EXPORT LauncherItemDelegateManager { +namespace test { +class LauncherItemDelegateManagerTestAPI; +} + +// LauncherItemDelegateManager manages the set of LauncherItemDelegates for the +// launcher. LauncherItemDelegateManager does not create LauncherItemDelegates, +// rather it is expected that someone else invokes SetLauncherItemDelegate +// appropriately. On the other hand, LauncherItemDelegateManager destroys +// LauncherItemDelegates when the corresponding item from the model is removed. +class ASH_EXPORT LauncherItemDelegateManager + : public ash::LauncherModelObserver { public: - LauncherItemDelegateManager(); + explicit LauncherItemDelegateManager(ash::LauncherModel* model); virtual ~LauncherItemDelegateManager(); - // Returns LauncherItemDelegate for |item_type|. - // This class doesn't own each LauncherItemDelegate for now. - LauncherItemDelegate* GetLauncherItemDelegate( - ash::LauncherItemType item_type); + // Set |item_delegate| for |id| and take an ownership. + void SetLauncherItemDelegate( + ash::LauncherID id, + scoped_ptr<ash::LauncherItemDelegate> item_delegate); + + // Returns LauncherItemDelegate for |item_type|. Always returns non-NULL. + LauncherItemDelegate* GetLauncherItemDelegate(ash::LauncherID id); - // Register |item_delegate| for |type|. - // For now, This class doesn't own |item_delegate|. - // TODO(simon.hong81): Register LauncherItemDelegate with LauncherID. - void RegisterLauncherItemDelegate( - ash::LauncherItemType type, LauncherItemDelegate* item_delegate); + // ash::LauncherModelObserver overrides: + virtual void LauncherItemAdded(int model_index) OVERRIDE; + virtual void LauncherItemRemoved(int index, ash::LauncherID id) OVERRIDE; + virtual void LauncherItemMoved(int start_index, int targetindex) OVERRIDE; + virtual void LauncherItemChanged( + int index, + const ash::LauncherItem& old_item) OVERRIDE; + virtual void LauncherStatusChanged() OVERRIDE; private: - typedef std::map<ash::LauncherItemType, LauncherItemDelegate*> - LauncherItemTypeToItemDelegateMap; + friend class ash::test::LauncherItemDelegateManagerTestAPI; + + typedef std::map<ash::LauncherID, LauncherItemDelegate*> + LauncherIDToItemDelegateMap; + + // Remove and destroy LauncherItemDelegate for |id|. + void RemoveLauncherItemDelegate(ash::LauncherID id); + + // Clear all exsiting LauncherItemDelegate for test. + // Not owned by LauncherItemDelegate. + ash::LauncherModel* model_; - LauncherItemTypeToItemDelegateMap item_type_to_item_delegate_map_; + LauncherIDToItemDelegateMap id_to_item_delegate_map_; DISALLOW_COPY_AND_ASSIGN(LauncherItemDelegateManager); }; diff --git a/ash/launcher/launcher_unittest.cc b/ash/launcher/launcher_unittest.cc index c1ea47b..0778c33 100644 --- a/ash/launcher/launcher_unittest.cc +++ b/ash/launcher/launcher_unittest.cc @@ -4,14 +4,15 @@ #include "ash/launcher/launcher.h" #include "ash/launcher/launcher_button.h" +#include "ash/launcher/launcher_item_delegate_manager.h" #include "ash/launcher/launcher_model.h" #include "ash/launcher/launcher_view.h" - #include "ash/shelf/shelf_widget.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" #include "ash/test/launcher_test_api.h" #include "ash/test/launcher_view_test_api.h" +#include "ash/test/test_launcher_item_delegate.h" #include "ash/wm/window_util.h" #include "ui/aura/root_window.h" #include "ui/gfx/display.h" @@ -34,7 +35,8 @@ class LauncherTest : public ash::test::AshTestBase { public: LauncherTest() : launcher_(NULL), launcher_view_(NULL), - launcher_model_(NULL) { + launcher_model_(NULL), + item_delegate_manager_(NULL) { } virtual ~LauncherTest() {} @@ -48,6 +50,8 @@ class LauncherTest : public ash::test::AshTestBase { ash::test::LauncherTestAPI test(launcher_); launcher_view_ = test.launcher_view(); launcher_model_ = launcher_view_->model(); + item_delegate_manager_ = + Shell::GetInstance()->launcher_item_delegate_manager(); test_.reset(new ash::test::LauncherViewTestAPI(launcher_view_)); } @@ -68,6 +72,10 @@ class LauncherTest : public ash::test::AshTestBase { return launcher_model_; } + LauncherItemDelegateManager* item_manager() { + return item_delegate_manager_; + } + ash::test::LauncherViewTestAPI* test_api() { return test_.get(); } @@ -76,6 +84,7 @@ class LauncherTest : public ash::test::AshTestBase { Launcher* launcher_; LauncherView* launcher_view_; LauncherModel* launcher_model_; + LauncherItemDelegateManager* item_delegate_manager_; scoped_ptr<ash::test::LauncherViewTestAPI> test_; DISALLOW_COPY_AND_ASSIGN(LauncherTest); @@ -111,6 +120,12 @@ TEST_F(LauncherTest, checkHoverAfterMenu) { item.type = TYPE_PLATFORM_APP; item.status = STATUS_RUNNING; int index = launcher_model()->Add(item); + + scoped_ptr<LauncherItemDelegate> delegate( + new ash::test::TestLauncherItemDelegate(NULL)); + item_manager()->SetLauncherItemDelegate(launcher_model()->items()[index].id, + delegate.Pass()); + ASSERT_EQ(++button_count, test_api()->GetButtonCount()); LauncherButton* button = test_api()->GetButton(index); button->AddState(LauncherButton::STATE_HOVERED); diff --git a/ash/launcher/launcher_view.cc b/ash/launcher/launcher_view.cc index 136aeb4..70be9bb 100644 --- a/ash/launcher/launcher_view.cc +++ b/ash/launcher/launcher_view.cc @@ -997,8 +997,8 @@ void LauncherView::PrepareForDrag(Pointer pointer, // If the item is no longer draggable, bail out. LauncherItemDelegate* item_delegate = item_manager_->GetLauncherItemDelegate( - model_->items()[start_drag_index_].type); - if (!item_delegate->IsDraggable(model_->items()[start_drag_index_])) { + model_->items()[start_drag_index_].id); + if (!item_delegate->IsDraggable()) { CancelDrag(-1); return; } @@ -1015,8 +1015,8 @@ void LauncherView::ContinueDrag(const ui::LocatedEvent& event) { DCHECK_NE(-1, current_index); LauncherItemDelegate* item_delegate = item_manager_->GetLauncherItemDelegate( - model_->items()[current_index].type); - if (!item_delegate->IsDraggable(model_->items()[current_index])) { + model_->items()[current_index].id); + if (!item_delegate->IsDraggable()) { CancelDrag(-1); return; } @@ -1549,9 +1549,8 @@ void LauncherView::PointerPressedOnButton(views::View* view, return; LauncherItemDelegate* item_delegate = item_manager_->GetLauncherItemDelegate( - model_->items()[index].type); - if (view_model_->view_size() <= 1 || - !item_delegate->IsDraggable(model_->items()[index])) + model_->items()[index].id); + if (view_model_->view_size() <= 1 || !item_delegate->IsDraggable()) return; // View is being deleted or not draggable, ignore request. ShelfLayoutManager* shelf = tooltip_->shelf_layout_manager(); @@ -1621,8 +1620,8 @@ base::string16 LauncherView::GetAccessibleName(const views::View* view) { return base::string16(); LauncherItemDelegate* item_delegate = item_manager_->GetLauncherItemDelegate( - model_->items()[view_index].type); - return item_delegate->GetTitle(model_->items()[view_index]); + model_->items()[view_index].id); + return item_delegate->GetTitle(); } void LauncherView::ButtonPressed(views::Button* sender, @@ -1681,8 +1680,8 @@ void LauncherView::ButtonPressed(views::Button* sender, LauncherItemDelegate* item_delegate = item_manager_->GetLauncherItemDelegate( - model_->items()[view_index].type); - item_delegate->ItemSelected(model_->items()[view_index], event); + model_->items()[view_index].id); + item_delegate->ItemSelected(event); ShowListMenuForView(model_->items()[view_index], sender, event); } @@ -1693,8 +1692,8 @@ bool LauncherView::ShowListMenuForView(const LauncherItem& item, const ui::Event& event) { scoped_ptr<ash::LauncherMenuModel> menu_model; LauncherItemDelegate* item_delegate = - item_manager_->GetLauncherItemDelegate(item.type); - menu_model.reset(item_delegate->CreateApplicationMenu(item, event.flags())); + item_manager_->GetLauncherItemDelegate(item.id); + menu_model.reset(item_delegate->CreateApplicationMenu(event.flags())); // Make sure we have a menu and it has at least two items in addition to the // application title and the 3 spacing separators. @@ -1727,9 +1726,8 @@ void LauncherView::ShowContextMenuForView(views::View* source, } scoped_ptr<ui::MenuModel> menu_model; LauncherItemDelegate* item_delegate = item_manager_->GetLauncherItemDelegate( - model_->items()[view_index].type); + model_->items()[view_index].id); menu_model.reset(item_delegate->CreateContextMenu( - model_->items()[view_index], source->GetWidget()->GetNativeView()->GetRootWindow())); if (!menu_model) return; @@ -1890,8 +1888,8 @@ bool LauncherView::ShouldShowTooltipForView(const views::View* view) const { if (!item) return true; LauncherItemDelegate* item_delegate = - item_manager_->GetLauncherItemDelegate(item->type); - return item_delegate->ShouldShowTooltip(*item); + item_manager_->GetLauncherItemDelegate(item->id); + return item_delegate->ShouldShowTooltip(); } int LauncherView::CalculateShelfDistance(const gfx::Point& coordinate) const { diff --git a/ash/launcher/launcher_view_unittest.cc b/ash/launcher/launcher_view_unittest.cc index deab2f2..220fd64 100644 --- a/ash/launcher/launcher_view_unittest.cc +++ b/ash/launcher/launcher_view_unittest.cc @@ -11,6 +11,7 @@ #include "ash/launcher/launcher.h" #include "ash/launcher/launcher_button.h" #include "ash/launcher/launcher_icon_observer.h" +#include "ash/launcher/launcher_item_delegate_manager.h" #include "ash/launcher/launcher_model.h" #include "ash/launcher/launcher_types.h" #include "ash/root_window_controller.h" @@ -24,6 +25,7 @@ #include "ash/test/launcher_view_test_api.h" #include "ash/test/shell_test_api.h" #include "ash/test/test_launcher_delegate.h" +#include "ash/test/test_launcher_item_delegate.h" #include "base/basictypes.h" #include "base/command_line.h" #include "base/compiler_specific.h" @@ -213,6 +215,10 @@ class LauncherViewTest : public AshTestBase { test_api_.reset(new LauncherViewTestAPI(launcher_view_)); test_api_->SetAnimationDuration(1); // Speeds up animation for test. + item_manager_ = + ash::Shell::GetInstance()->launcher_item_delegate_manager(); + DCHECK(item_manager_); + // Add browser shortcut launcher item at index 0 for test. AddBrowserShortcut(); } @@ -223,12 +229,19 @@ class LauncherViewTest : public AshTestBase { } protected: + void CreateAndSetLauncherItemDelegateForID(LauncherID id) { + scoped_ptr<LauncherItemDelegate> delegate( + new ash::test::TestLauncherItemDelegate(NULL)); + item_manager_->SetLauncherItemDelegate(id, delegate.Pass()); + } + LauncherID AddBrowserShortcut() { LauncherItem browser_shortcut; browser_shortcut.type = TYPE_BROWSER_SHORTCUT; LauncherID id = model_->next_id(); model_->AddAt(browser_index_, browser_shortcut); + CreateAndSetLauncherItemDelegateForID(id); test_api_->RunMessageLoopUntilAnimationsDone(); return id; } @@ -240,6 +253,7 @@ class LauncherViewTest : public AshTestBase { LauncherID id = model_->next_id(); model_->Add(item); + CreateAndSetLauncherItemDelegateForID(id); test_api_->RunMessageLoopUntilAnimationsDone(); return id; } @@ -257,6 +271,7 @@ class LauncherViewTest : public AshTestBase { LauncherID id = model_->next_id(); model_->Add(item); + CreateAndSetLauncherItemDelegateForID(id); return id; } @@ -267,6 +282,7 @@ class LauncherViewTest : public AshTestBase { LauncherID id = model_->next_id(); model_->Add(item); + CreateAndSetLauncherItemDelegateForID(id); return id; } @@ -387,6 +403,7 @@ class LauncherViewTest : public AshTestBase { LauncherModel* model_; internal::LauncherView* launcher_view_; int browser_index_; + LauncherItemDelegateManager* item_manager_; scoped_ptr<LauncherViewTestAPI> test_api_; diff --git a/ash/shelf/app_list_shelf_item_delegate.cc b/ash/shelf/app_list_shelf_item_delegate.cc index 615a381..231f68d 100644 --- a/ash/shelf/app_list_shelf_item_delegate.cc +++ b/ash/shelf/app_list_shelf_item_delegate.cc @@ -4,10 +4,8 @@ #include "ash/shelf/app_list_shelf_item_delegate.h" -#include "ash/launcher/launcher_item_delegate_manager.h" #include "ash/launcher/launcher_model.h" #include "ash/shell.h" -#include "ash/shell_delegate.h" #include "grit/ash_strings.h" #include "ui/base/l10n/l10n_util.h" @@ -18,23 +16,18 @@ AppListShelfItemDelegate::AppListShelfItemDelegate() { LauncherItem app_list; app_list.type = TYPE_APP_LIST; Shell::GetInstance()->launcher_model()->Add(app_list); - - ash::Shell::GetInstance()->launcher_item_delegate_manager()-> - RegisterLauncherItemDelegate(ash::TYPE_APP_LIST, this); } AppListShelfItemDelegate::~AppListShelfItemDelegate() { - // Don't unregister this from LauncherItemDelegateManager. - // LauncherItemDelegateManager is already destroyed. + // LauncherItemDelegateManager owns and destroys this class. } -void AppListShelfItemDelegate::ItemSelected(const LauncherItem& item, - const ui::Event& event) { +void AppListShelfItemDelegate::ItemSelected(const ui::Event& event) { // Pass NULL here to show the app list in the currently active RootWindow. Shell::GetInstance()->ToggleAppList(NULL); } -base::string16 AppListShelfItemDelegate::GetTitle(const LauncherItem& item) { +base::string16 AppListShelfItemDelegate::GetTitle() { LauncherModel* model = Shell::GetInstance()->launcher_model(); DCHECK(model); return model->status() == LauncherModel::STATUS_LOADING ? @@ -43,23 +36,21 @@ base::string16 AppListShelfItemDelegate::GetTitle(const LauncherItem& item) { } ui::MenuModel* AppListShelfItemDelegate::CreateContextMenu( - const LauncherItem& item, aura::RootWindow* root_window) { return NULL; } LauncherMenuModel* AppListShelfItemDelegate::CreateApplicationMenu( - const LauncherItem& item, int event_flags) { // AppList does not show an application menu. return NULL; } -bool AppListShelfItemDelegate::IsDraggable(const LauncherItem& item) { +bool AppListShelfItemDelegate::IsDraggable() { return false; } -bool AppListShelfItemDelegate::ShouldShowTooltip(const LauncherItem& item) { +bool AppListShelfItemDelegate::ShouldShowTooltip() { return true; } diff --git a/ash/shelf/app_list_shelf_item_delegate.h b/ash/shelf/app_list_shelf_item_delegate.h index fe3c94e..2827599 100644 --- a/ash/shelf/app_list_shelf_item_delegate.h +++ b/ash/shelf/app_list_shelf_item_delegate.h @@ -20,17 +20,13 @@ class AppListShelfItemDelegate : public LauncherItemDelegate { virtual ~AppListShelfItemDelegate(); // ash::LauncherItemDelegate overrides: - virtual void ItemSelected(const LauncherItem& item, - const ui::Event& event) OVERRIDE; - virtual base::string16 GetTitle(const LauncherItem& item) OVERRIDE; + virtual void ItemSelected(const ui::Event& event) OVERRIDE; + virtual base::string16 GetTitle() OVERRIDE; virtual ui::MenuModel* CreateContextMenu( - const LauncherItem& item, aura::RootWindow* root_window) OVERRIDE; - virtual LauncherMenuModel* CreateApplicationMenu( - const LauncherItem& item, - int event_flags) OVERRIDE; - virtual bool IsDraggable(const LauncherItem& item) OVERRIDE; - virtual bool ShouldShowTooltip(const LauncherItem& item) OVERRIDE; + virtual LauncherMenuModel* CreateApplicationMenu(int event_flags) OVERRIDE; + virtual bool IsDraggable() OVERRIDE; + virtual bool ShouldShowTooltip() OVERRIDE; private: DISALLOW_COPY_AND_ASSIGN(AppListShelfItemDelegate); diff --git a/ash/shell.cc b/ash/shell.cc index 6c14d66..5ad43a2 100644 --- a/ash/shell.cc +++ b/ash/shell.cc @@ -39,6 +39,7 @@ #include "ash/session_state_delegate.h" #include "ash/shelf/app_list_shelf_item_delegate.h" #include "ash/shelf/shelf_layout_manager.h" +#include "ash/shelf/shelf_util.h" #include "ash/shelf/shelf_widget.h" #include "ash/shell_delegate.h" #include "ash/shell_factory.h" @@ -485,13 +486,30 @@ SystemTray* Shell::GetPrimarySystemTray() { LauncherDelegate* Shell::GetLauncherDelegate() { if (!launcher_delegate_) { - // Creates LauncherItemDelegateManager before LauncherDelegate. - launcher_item_delegate_manager_.reset(new LauncherItemDelegateManager); launcher_model_.reset(new LauncherModel); + // Creates LauncherItemDelegateManager before LauncherDelegate. + launcher_item_delegate_manager_.reset( + new LauncherItemDelegateManager(launcher_model_.get())); + launcher_delegate_.reset( delegate_->CreateLauncherDelegate(launcher_model_.get())); - app_list_shelf_item_delegate_.reset( + scoped_ptr<LauncherItemDelegate> controller( new internal::AppListShelfItemDelegate); + + ash::LauncherID app_list_id = 0; + // TODO(simon.hong81): Make function for this in shelf_util.h + // Finding the launcher model's location of the app list and setting its + // LauncherItemDelegate. + for (size_t i = 0; i < launcher_model_->items().size(); ++i) { + if (launcher_model_->items()[i].type == ash::TYPE_APP_LIST) { + app_list_id = launcher_model_->items()[i].id; + break; + } + } + DCHECK(app_list_id); + launcher_item_delegate_manager_->SetLauncherItemDelegate( + app_list_id, + controller.Pass()); } return launcher_delegate_.get(); } @@ -645,6 +663,9 @@ Shell::~Shell() { user_action_client_.reset(); visibility_controller_.reset(); launcher_delegate_.reset(); + // |launcher_item_delegate_manager_| observes |launcher_model_|. It must be + // destroyed before |launcher_model_| is destroyed. + launcher_item_delegate_manager_.reset(); launcher_model_.reset(); video_detector_.reset(); diff --git a/ash/shell.h b/ash/shell.h index d665add..34b31eb 100644 --- a/ash/shell.h +++ b/ash/shell.h @@ -81,6 +81,7 @@ class DisplayController; class HighContrastController; class Launcher; class LauncherDelegate; +class LauncherItemDelegate; class LauncherItemDelegateManager; class LauncherModel; class MagnificationController; @@ -108,7 +109,6 @@ class WindowSelectorController; namespace internal { class AcceleratorFilter; class AppListController; -class AppListShelfItemDelegate; class CaptureController; class DisplayChangeObserver; class DisplayErrorObserver; @@ -568,8 +568,6 @@ class ASH_EXPORT Shell scoped_ptr<SessionStateDelegate> session_state_delegate_; scoped_ptr<LauncherDelegate> launcher_delegate_; scoped_ptr<LauncherItemDelegateManager> launcher_item_delegate_manager_; - scoped_ptr<internal::AppListShelfItemDelegate> - app_list_shelf_item_delegate_; scoped_ptr<LauncherModel> launcher_model_; scoped_ptr<ash::WindowPositioner> window_positioner_; diff --git a/ash/shell/launcher_delegate_impl.cc b/ash/shell/launcher_delegate_impl.cc index 882431c..4ec47ae 100644 --- a/ash/shell/launcher_delegate_impl.cc +++ b/ash/shell/launcher_delegate_impl.cc @@ -4,67 +4,27 @@ #include "ash/shell/launcher_delegate_impl.h" -#include "ash/launcher/launcher_item_delegate_manager.h" -#include "ash/shelf/shelf_util.h" #include "ash/shell.h" #include "ash/shell/toplevel_window.h" #include "ash/shell/window_watcher.h" #include "ash/wm/window_util.h" #include "base/strings/string_util.h" #include "grit/ash_resources.h" -#include "ui/aura/window.h" namespace ash { namespace shell { LauncherDelegateImpl::LauncherDelegateImpl(WindowWatcher* watcher) : watcher_(watcher) { - ash::LauncherItemDelegateManager* manager = - ash::Shell::GetInstance()->launcher_item_delegate_manager(); - manager->RegisterLauncherItemDelegate(ash::TYPE_APP_PANEL, this); - manager->RegisterLauncherItemDelegate(ash::TYPE_PLATFORM_APP, this); } LauncherDelegateImpl::~LauncherDelegateImpl() { } -void LauncherDelegateImpl::ItemSelected(const ash::LauncherItem& item, - const ui::Event& event) { - aura::Window* window = watcher_->GetWindowByID(item.id); - if (window->type() == aura::client::WINDOW_TYPE_PANEL) - ash::wm::MoveWindowToEventRoot(window, event); - window->Show(); - ash::wm::ActivateWindow(window); -} - -base::string16 LauncherDelegateImpl::GetTitle(const ash::LauncherItem& item) { - return watcher_->GetWindowByID(item.id)->title(); -} - -ui::MenuModel* LauncherDelegateImpl::CreateContextMenu( - const ash::LauncherItem& item, - aura::RootWindow* root_window) { - return NULL; -} - -ash::LauncherMenuModel* LauncherDelegateImpl::CreateApplicationMenu( - const ash::LauncherItem& item, - int event_flags) { - return NULL; -} - ash::LauncherID LauncherDelegateImpl::GetIDByWindow(aura::Window* window) { return watcher_ ? watcher_->GetIDByWindow(window) : 0; } -bool LauncherDelegateImpl::IsDraggable(const ash::LauncherItem& item) { - return true; -} - -bool LauncherDelegateImpl::ShouldShowTooltip(const ash::LauncherItem& item) { - return true; -} - void LauncherDelegateImpl::OnLauncherCreated(Launcher* launcher) { } diff --git a/ash/shell/launcher_delegate_impl.h b/ash/shell/launcher_delegate_impl.h index b6f7658..71c943d 100644 --- a/ash/shell/launcher_delegate_impl.h +++ b/ash/shell/launcher_delegate_impl.h @@ -6,7 +6,6 @@ #define ASH_SHELL_LAUNCHER_DELEGATE_IMPL_H_ #include "ash/launcher/launcher_delegate.h" -#include "ash/launcher/launcher_item_delegate.h" #include "base/compiler_specific.h" namespace aura { @@ -18,8 +17,7 @@ namespace shell { class WindowWatcher; -class LauncherDelegateImpl : public ash::LauncherDelegate, - public ash::LauncherItemDelegate { +class LauncherDelegateImpl : public ash::LauncherDelegate { public: explicit LauncherDelegateImpl(WindowWatcher* watcher); virtual ~LauncherDelegateImpl(); @@ -37,19 +35,6 @@ class LauncherDelegateImpl : public ash::LauncherDelegate, virtual bool CanPin() const OVERRIDE; virtual void UnpinAppWithID(const std::string& app_id) OVERRIDE; - // LauncherItemDelegate overrides: - virtual void ItemSelected(const ash::LauncherItem& item, - const ui::Event& event) OVERRIDE; - virtual base::string16 GetTitle(const ash::LauncherItem& item) OVERRIDE; - virtual ui::MenuModel* CreateContextMenu( - const ash::LauncherItem& item, - aura::RootWindow* root) OVERRIDE; - virtual ash::LauncherMenuModel* CreateApplicationMenu( - const ash::LauncherItem&, - int event_flags) OVERRIDE; - virtual bool IsDraggable(const ash::LauncherItem& item) OVERRIDE; - virtual bool ShouldShowTooltip(const LauncherItem& item) OVERRIDE; - private: // Used to update Launcher. Owned by main. WindowWatcher* watcher_; diff --git a/ash/shell/window_watcher.cc b/ash/shell/window_watcher.cc index f076483..7c72e27 100644 --- a/ash/shell/window_watcher.cc +++ b/ash/shell/window_watcher.cc @@ -6,9 +6,11 @@ #include "ash/display/display_controller.h" #include "ash/launcher/launcher.h" +#include "ash/launcher/launcher_item_delegate_manager.h" #include "ash/launcher/launcher_model.h" #include "ash/shelf/shelf_widget.h" #include "ash/shell.h" +#include "ash/shell/window_watcher_launcher_item_delegate.h" #include "ash/shell_window_ids.h" #include "ui/aura/root_window.h" #include "ui/aura/window.h" @@ -108,7 +110,8 @@ void WindowWatcher::OnWindowAdded(aura::Window* new_window) { ash::LauncherItem item; item.type = new_window->type() == aura::client::WINDOW_TYPE_PANEL ? ash::TYPE_APP_PANEL : ash::TYPE_PLATFORM_APP; - id_to_window_[model->next_id()] = new_window; + ash::LauncherID id = model->next_id(); + id_to_window_[id] = new_window; SkBitmap icon_bitmap; icon_bitmap.setConfig(SkBitmap::kARGB_8888_Config, 16, 16); @@ -121,6 +124,12 @@ void WindowWatcher::OnWindowAdded(aura::Window* new_window) { item.image = gfx::ImageSkia(gfx::ImageSkiaRep(icon_bitmap, 1.0f)); model->Add(item); + + ash::LauncherItemDelegateManager* manager = + ash::Shell::GetInstance()->launcher_item_delegate_manager(); + scoped_ptr<LauncherItemDelegate> delegate( + new WindowWatcherLauncherItemDelegate(id, this)); + manager->SetLauncherItemDelegate(id, delegate.Pass()); } void WindowWatcher::OnWillRemoveWindow(aura::Window* window) { diff --git a/ash/shell/window_watcher_launcher_item_delegate.cc b/ash/shell/window_watcher_launcher_item_delegate.cc new file mode 100644 index 0000000..553b9fc --- /dev/null +++ b/ash/shell/window_watcher_launcher_item_delegate.cc @@ -0,0 +1,58 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/shell/window_watcher_launcher_item_delegate.h" + +#include "ash/shell/window_watcher.h" +#include "ash/wm/window_util.h" +#include "ui/aura/window.h" + +namespace ash { +namespace shell { + +WindowWatcherLauncherItemDelegate::WindowWatcherLauncherItemDelegate( + ash::LauncherID id, + ash::shell::WindowWatcher* watcher) + : id_(id), + watcher_(watcher) { + DCHECK_GT(id_, 0); + DCHECK(watcher_); +} + +WindowWatcherLauncherItemDelegate::~WindowWatcherLauncherItemDelegate() { +} + +void WindowWatcherLauncherItemDelegate::ItemSelected(const ui::Event& event) { + aura::Window* window = watcher_->GetWindowByID(id_); + if (window->type() == aura::client::WINDOW_TYPE_PANEL) + ash::wm::MoveWindowToEventRoot(window, event); + window->Show(); + ash::wm::ActivateWindow(window); +} + +base::string16 WindowWatcherLauncherItemDelegate::GetTitle() { + return watcher_->GetWindowByID(id_)->title(); +} + +ui::MenuModel* WindowWatcherLauncherItemDelegate::CreateContextMenu( + aura::RootWindow* root_window) { + return NULL; +} + +ash::LauncherMenuModel* +WindowWatcherLauncherItemDelegate::CreateApplicationMenu( + int event_flags) { + return NULL; +} + +bool WindowWatcherLauncherItemDelegate::IsDraggable() { + return true; +} + +bool WindowWatcherLauncherItemDelegate::ShouldShowTooltip() { + return true; +} + +} // namespace shell +} // namespace ash diff --git a/ash/shell/window_watcher_launcher_item_delegate.h b/ash/shell/window_watcher_launcher_item_delegate.h new file mode 100644 index 0000000..e7d0b22 --- /dev/null +++ b/ash/shell/window_watcher_launcher_item_delegate.h @@ -0,0 +1,44 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_SHELL_WINDOW_WATCHER_LAUNCHER_ITEM_DELEGATE_ +#define ASH_SHELL_WINDOW_WATCHER_LAUNCHER_ITEM_DELEGATE_ + +#include "ash/launcher/launcher_item_delegate.h" +#include "base/basictypes.h" +#include "base/compiler_specific.h" + +namespace ash { +namespace shell { + +class WindowWatcher; + +// LauncherItemDelegate implementation used by WindowWatcher. +class WindowWatcherLauncherItemDelegate : public ash::LauncherItemDelegate { + public: + WindowWatcherLauncherItemDelegate(ash::LauncherID id, + ash::shell::WindowWatcher* watcher); + virtual ~WindowWatcherLauncherItemDelegate(); + + // ash::LauncherItemDelegate overrides: + virtual void ItemSelected(const ui::Event& event) OVERRIDE; + virtual base::string16 GetTitle() OVERRIDE; + virtual ui::MenuModel* CreateContextMenu( + aura::RootWindow* root_window) OVERRIDE; + virtual ash::LauncherMenuModel* CreateApplicationMenu( + int event_flags) OVERRIDE; + virtual bool IsDraggable() OVERRIDE; + virtual bool ShouldShowTooltip() OVERRIDE; + + private: + ash::LauncherID id_; + ash::shell::WindowWatcher* watcher_; + + DISALLOW_COPY_AND_ASSIGN(WindowWatcherLauncherItemDelegate); +}; + +} // namespace shell +} // namespace ash + +#endif // ASH_SHELL_WINDOW_WATCHER_LAUNCHER_ITEM_DELEGATE_ diff --git a/ash/test/launcher_item_delegate_manager_test_api.cc b/ash/test/launcher_item_delegate_manager_test_api.cc new file mode 100644 index 0000000..159f7da --- /dev/null +++ b/ash/test/launcher_item_delegate_manager_test_api.cc @@ -0,0 +1,29 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/test/launcher_item_delegate_manager_test_api.h" + +#include "ash/launcher/launcher_item_delegate.h" +#include "ash/launcher/launcher_item_delegate_manager.h" +#include "base/stl_util.h" + +namespace ash { +namespace test { + +LauncherItemDelegateManagerTestAPI::LauncherItemDelegateManagerTestAPI( + LauncherItemDelegateManager* manager) + : manager_(manager) { + DCHECK(manager_); +} + +void +LauncherItemDelegateManagerTestAPI::RemoveAllLauncherItemDelegateForTest() { + STLDeleteContainerPairSecondPointers( + manager_->id_to_item_delegate_map_.begin(), + manager_->id_to_item_delegate_map_.end()); + manager_->id_to_item_delegate_map_.clear(); +} + +} // namespace test +} // namespace ash diff --git a/ash/test/launcher_item_delegate_manager_test_api.h b/ash/test/launcher_item_delegate_manager_test_api.h new file mode 100644 index 0000000..d916a055 --- /dev/null +++ b/ash/test/launcher_item_delegate_manager_test_api.h @@ -0,0 +1,34 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_TEST_LAUNCHER_ITEM_DELEGATE_MANAGER_TEST_API_H_ +#define ASH_TEST_LAUNCHER_ITEM_DELEGATE_MANAGER_TEST_API_H_ + +#include "base/basictypes.h" + +namespace ash { + +class LauncherItemDelegateManager; + +namespace test { + +// Accesses private methods from a LauncherItemDelegateManager for testing. +class LauncherItemDelegateManagerTestAPI { + public: + explicit LauncherItemDelegateManagerTestAPI( + LauncherItemDelegateManager* manager); + + // Clear all exsiting LauncherItemDelegate for test. + void RemoveAllLauncherItemDelegateForTest(); + + private: + LauncherItemDelegateManager* manager_; // Not owned. + + DISALLOW_COPY_AND_ASSIGN(LauncherItemDelegateManagerTestAPI); +}; + +} // namespace test +} // namespace ash + +#endif // ASH_TEST_LAUNCHER_ITEM_DELEGATE_MANAGER_TEST_API_H_ diff --git a/ash/test/test_launcher_delegate.cc b/ash/test/test_launcher_delegate.cc index 508947e..98f1db0 100644 --- a/ash/test/test_launcher_delegate.cc +++ b/ash/test/test_launcher_delegate.cc @@ -8,7 +8,7 @@ #include "ash/launcher/launcher_model.h" #include "ash/shelf/shelf_util.h" #include "ash/shell.h" -#include "ash/wm/window_util.h" +#include "ash/test/test_launcher_item_delegate.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "grit/ash_resources.h" @@ -23,14 +23,6 @@ TestLauncherDelegate::TestLauncherDelegate(LauncherModel* model) : model_(model) { CHECK(!instance_); instance_ = this; - - ash::LauncherItemDelegateManager* manager = - ash::Shell::GetInstance()->launcher_item_delegate_manager(); - manager->RegisterLauncherItemDelegate(ash::TYPE_APP_PANEL, this); - manager->RegisterLauncherItemDelegate(ash::TYPE_APP_SHORTCUT, this); - manager->RegisterLauncherItemDelegate(ash::TYPE_BROWSER_SHORTCUT, this); - manager->RegisterLauncherItemDelegate(ash::TYPE_PLATFORM_APP, this); - manager->RegisterLauncherItemDelegate(ash::TYPE_WINDOWED_APP, this); } TestLauncherDelegate::~TestLauncherDelegate() { @@ -54,6 +46,13 @@ void TestLauncherDelegate::AddLauncherItem( item.status = status; model_->Add(item); window->AddObserver(this); + + ash::LauncherItemDelegateManager* manager = + ash::Shell::GetInstance()->launcher_item_delegate_manager(); + // |manager| owns TestLauncherItemDelegate. + scoped_ptr<LauncherItemDelegate> delegate( + new TestLauncherItemDelegate(window)); + manager->SetLauncherItemDelegate(window_to_id_[window], delegate.Pass()); } void TestLauncherDelegate::RemoveLauncherItemForWindow(aura::Window* window) { @@ -80,32 +79,6 @@ void TestLauncherDelegate::OnWindowHierarchyChanging( RemoveLauncherItemForWindow(params.target); } -void TestLauncherDelegate::ItemSelected(const ash::LauncherItem& item, - const ui::Event& event) { - aura::Window* window = GetWindowByID(item.id); - if (window->type() == aura::client::WINDOW_TYPE_PANEL) - ash::wm::MoveWindowToEventRoot(window, event); - window->Show(); - ash::wm::ActivateWindow(window); -} - -base::string16 TestLauncherDelegate::GetTitle(const ash::LauncherItem& item) { - aura::Window* window = GetWindowByID(item.id); - return window ? window->title() : base::string16(); -} - -ui::MenuModel* TestLauncherDelegate::CreateContextMenu( - const ash::LauncherItem& item, - aura::RootWindow* root) { - return NULL; -} - -ash::LauncherMenuModel* TestLauncherDelegate::CreateApplicationMenu( - const ash::LauncherItem& item, - int event_flags) { - return NULL; -} - ash::LauncherID TestLauncherDelegate::GetIDByWindow(aura::Window* window) { WindowToID::const_iterator found = window_to_id_.find(window); if (found == window_to_id_.end()) @@ -113,24 +86,6 @@ ash::LauncherID TestLauncherDelegate::GetIDByWindow(aura::Window* window) { return found->second; } -aura::Window* TestLauncherDelegate::GetWindowByID(ash::LauncherID id) { - for (WindowToID::const_iterator it = window_to_id_.begin(); - it != window_to_id_.end(); - it++) { - if (it->second == id) - return it->first; - } - return NULL; -} - -bool TestLauncherDelegate::IsDraggable(const ash::LauncherItem& item) { - return true; -} - -bool TestLauncherDelegate::ShouldShowTooltip(const ash::LauncherItem& item) { - return true; -} - void TestLauncherDelegate::OnLauncherCreated(Launcher* launcher) { } diff --git a/ash/test/test_launcher_delegate.h b/ash/test/test_launcher_delegate.h index 60e6d4f..4198665 100644 --- a/ash/test/test_launcher_delegate.h +++ b/ash/test/test_launcher_delegate.h @@ -9,7 +9,6 @@ #include <set> #include "ash/launcher/launcher_delegate.h" -#include "ash/launcher/launcher_item_delegate.h" #include "base/compiler_specific.h" #include "ui/aura/window_observer.h" @@ -22,7 +21,6 @@ namespace test { // Test implementation of LauncherDelegate. // Tests may create icons for windows by calling AddLauncherItem class TestLauncherDelegate : public LauncherDelegate, - public LauncherItemDelegate, public aura::WindowObserver { public: explicit TestLauncherDelegate(LauncherModel* model); @@ -50,26 +48,12 @@ class TestLauncherDelegate : public LauncherDelegate, virtual bool IsAppPinned(const std::string& app_id) OVERRIDE; virtual void UnpinAppWithID(const std::string& app_id) OVERRIDE; - // LauncherItemDelegate implementation. - virtual void ItemSelected(const LauncherItem& item, - const ui::Event& event) OVERRIDE; - virtual base::string16 GetTitle(const LauncherItem& item) OVERRIDE; - virtual ui::MenuModel* CreateContextMenu(const LauncherItem& item, - aura::RootWindow* root) OVERRIDE; - virtual ash::LauncherMenuModel* CreateApplicationMenu( - const LauncherItem& item, - int event_flags) OVERRIDE; - virtual bool IsDraggable(const ash::LauncherItem& item) OVERRIDE; - virtual bool ShouldShowTooltip(const LauncherItem& item) OVERRIDE; - private: typedef std::map<aura::Window*, ash::LauncherID> WindowToID; typedef std::set<aura::Window*> ObservedWindows; static TestLauncherDelegate* instance_; - aura::Window* GetWindowByID(ash::LauncherID id); - LauncherModel* model_; // Maps from window to the id we gave it. diff --git a/ash/test/test_launcher_item_delegate.cc b/ash/test/test_launcher_item_delegate.cc new file mode 100644 index 0000000..9cb56bb --- /dev/null +++ b/ash/test/test_launcher_item_delegate.cc @@ -0,0 +1,52 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/test/test_launcher_item_delegate.h" + +#include "ash/wm/window_util.h" +#include "ui/aura/window.h" + +namespace ash { +namespace test { + +TestLauncherItemDelegate::TestLauncherItemDelegate(aura::Window* window) + : window_(window) { +} + +TestLauncherItemDelegate::~TestLauncherItemDelegate() { +} + +void TestLauncherItemDelegate::ItemSelected(const ui::Event& event) { + if (window_) { + if (window_->type() == aura::client::WINDOW_TYPE_PANEL) + ash::wm::MoveWindowToEventRoot(window_, event); + window_->Show(); + ash::wm::ActivateWindow(window_); + } +} + +base::string16 TestLauncherItemDelegate::GetTitle() { + return window_ ? window_->title() : base::string16(); +} + +ui::MenuModel* TestLauncherItemDelegate::CreateContextMenu( + aura::RootWindow* root_window) { + return NULL; +} + +ash::LauncherMenuModel* TestLauncherItemDelegate::CreateApplicationMenu( + int event_flags) { + return NULL; +} + +bool TestLauncherItemDelegate::IsDraggable() { + return true; +} + +bool TestLauncherItemDelegate::ShouldShowTooltip() { + return true; +} + +} // namespace test +} // namespace ash diff --git a/ash/test/test_launcher_item_delegate.h b/ash/test/test_launcher_item_delegate.h new file mode 100644 index 0000000..138a772 --- /dev/null +++ b/ash/test/test_launcher_item_delegate.h @@ -0,0 +1,44 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_TEST_TEST_LAUNCHER_ITEM_DELEGATE_ +#define ASH_TEST_TEST_LAUNCHER_ITEM_DELEGATE_ + +#include "ash/launcher/launcher_item_delegate.h" +#include "base/basictypes.h" +#include "base/compiler_specific.h" + +namespace aura { +class Window; +} + +namespace ash { +namespace test { + +// Test implementation of ash::LauncherItemDelegate. +class TestLauncherItemDelegate : public ash::LauncherItemDelegate { + public: + explicit TestLauncherItemDelegate(aura::Window* window); + virtual ~TestLauncherItemDelegate(); + + // ash::LauncherItemDelegate overrides: + virtual void ItemSelected(const ui::Event& event) OVERRIDE; + virtual base::string16 GetTitle() OVERRIDE; + virtual ui::MenuModel* CreateContextMenu( + aura::RootWindow* root_window) OVERRIDE; + virtual ash::LauncherMenuModel* CreateApplicationMenu( + int event_flags) OVERRIDE; + virtual bool IsDraggable() OVERRIDE; + virtual bool ShouldShowTooltip() OVERRIDE; + + private: + aura::Window* window_; + + DISALLOW_COPY_AND_ASSIGN(TestLauncherItemDelegate); +}; + +} // namespace test +} // namespace ash + +#endif // ASH_TEST_TEST_LAUNCHER_ITEM_DELEGATE_ diff --git a/chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.cc b/chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.cc index 97f62bd..a05ff2e 100644 --- a/chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.cc +++ b/chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.cc @@ -5,6 +5,8 @@ #include "chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.h" #include "apps/native_app_window.h" +#include "ash/launcher/launcher_model.h" +#include "ash/shell.h" #include "ash/wm/window_util.h" #include "chrome/browser/extensions/extension_process_manager.h" #include "chrome/browser/extensions/extension_system.h" @@ -12,6 +14,8 @@ #include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item_tab.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" +#include "chrome/browser/ui/ash/launcher/launcher_application_menu_item_model.h" +#include "chrome/browser/ui/ash/launcher/launcher_context_menu.h" #include "chrome/browser/ui/ash/launcher/launcher_item_controller.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" @@ -25,6 +29,10 @@ #include "ui/events/event.h" #include "ui/views/corewm/window_animations.h" +#if defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/login/default_pinned_apps_field_trial.h" +#endif + using extensions::Extension; namespace { @@ -56,10 +64,6 @@ AppShortcutLauncherItemController::AppShortcutLauncherItemController( AppShortcutLauncherItemController::~AppShortcutLauncherItemController() { } -string16 AppShortcutLauncherItemController::GetTitle() { - return GetAppTitle(); -} - bool AppShortcutLauncherItemController::IsCurrentlyShownInWindow( aura::Window* window) const { Browser* browser = chrome::FindBrowserWithWindow(window); @@ -131,21 +135,6 @@ void AppShortcutLauncherItemController::Close() { } } -void AppShortcutLauncherItemController::Clicked(const ui::Event& event) { - // In case of a keyboard event, we were called by a hotkey. In that case we - // activate the next item in line if an item of our list is already active. - if (event.type() == ui::ET_KEY_RELEASED) { - if (AdvanceToNextApp()) - return; - } - Activate(ash::LAUNCH_FROM_UNKNOWN); -} - -void AppShortcutLauncherItemController::OnRemoved() { - // AppShortcutLauncherItemController is unowned; delete on removal. - delete this; -} - ChromeLauncherAppMenuItems AppShortcutLauncherItemController::GetApplicationList(int event_flags) { ChromeLauncherAppMenuItems items; @@ -199,6 +188,44 @@ AppShortcutLauncherItemController::GetRunningApplications() { return items; } +void AppShortcutLauncherItemController::ItemSelected(const ui::Event& event) { +#if defined(OS_CHROMEOS) + if (!app_id().empty()) + chromeos::default_pinned_apps_field_trial::RecordShelfAppClick(app_id()); +#endif + // In case of a keyboard event, we were called by a hotkey. In that case we + // activate the next item in line if an item of our list is already active. + if (event.type() == ui::ET_KEY_RELEASED) { + if (AdvanceToNextApp()) + return; + } + Activate(ash::LAUNCH_FROM_UNKNOWN); +} + +base::string16 AppShortcutLauncherItemController::GetTitle() { + return GetAppTitle(); +} + +ui::MenuModel* AppShortcutLauncherItemController::CreateContextMenu( + aura::RootWindow* root_window) { + ash::LauncherItem item = + *(launcher_controller()->model()->ItemByID(launcher_id())); + return new LauncherContextMenu(launcher_controller(), &item, root_window); +} + +ash::LauncherMenuModel* +AppShortcutLauncherItemController::CreateApplicationMenu(int event_flags) { + return new LauncherApplicationMenuItemModel(GetApplicationList(event_flags)); +} + +bool AppShortcutLauncherItemController::IsDraggable() { + return true; +} + +bool AppShortcutLauncherItemController::ShouldShowTooltip() { + return true; +} + content::WebContents* AppShortcutLauncherItemController::GetLRUApplication() { URLPattern refocus_pattern(URLPattern::SCHEME_ALL); refocus_pattern.SetMatchAllURLs(true); diff --git a/chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.h b/chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.h index 2ba1c24..3dc6726 100644 --- a/chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.h +++ b/chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.h @@ -33,19 +33,25 @@ class AppShortcutLauncherItemController : public LauncherItemController { virtual ~AppShortcutLauncherItemController(); + std::vector<content::WebContents*> GetRunningApplications(); + // LauncherItemController overrides: - virtual string16 GetTitle() OVERRIDE; virtual bool IsCurrentlyShownInWindow(aura::Window* window) const OVERRIDE; virtual bool IsOpen() const OVERRIDE; virtual bool IsVisible() const OVERRIDE; virtual void Launch(ash::LaunchSource source, int event_flags) OVERRIDE; virtual void Activate(ash::LaunchSource source) OVERRIDE; virtual void Close() OVERRIDE; - virtual void Clicked(const ui::Event& event) OVERRIDE; - virtual void OnRemoved() OVERRIDE; virtual ChromeLauncherAppMenuItems GetApplicationList( int event_flags) OVERRIDE; - std::vector<content::WebContents*> GetRunningApplications(); + virtual void ItemSelected(const ui::Event& event) OVERRIDE; + virtual base::string16 GetTitle() OVERRIDE; + virtual ui::MenuModel* CreateContextMenu( + aura::RootWindow* root_window) OVERRIDE; + virtual ash::LauncherMenuModel* CreateApplicationMenu( + int event_flags) OVERRIDE; + virtual bool IsDraggable() OVERRIDE; + virtual bool ShouldShowTooltip() OVERRIDE; // Get the refocus url pattern, which can be used to identify this application // from a URL link. diff --git a/chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.cc b/chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.cc index 7c8df1e..8412877 100644 --- a/chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.cc +++ b/chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.cc @@ -16,6 +16,8 @@ #include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item_browser.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item_tab.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" +#include "chrome/browser/ui/ash/launcher/launcher_application_menu_item_model.h" +#include "chrome/browser/ui/ash/launcher/launcher_context_menu.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_list.h" @@ -96,10 +98,6 @@ void BrowserShortcutLauncherItemController::UpdateBrowserItemState() { } } -string16 BrowserShortcutLauncherItemController::GetTitle() { - return l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); -} - bool BrowserShortcutLauncherItemController::IsCurrentlyShownInWindow( aura::Window* window) const { const BrowserList* ash_browser_list = @@ -157,31 +155,6 @@ void BrowserShortcutLauncherItemController::Activate(ash::LaunchSource source) { void BrowserShortcutLauncherItemController::Close() { } -void BrowserShortcutLauncherItemController::Clicked(const ui::Event& event) { - #if defined(OS_CHROMEOS) - chromeos::default_pinned_apps_field_trial::RecordShelfClick( - chromeos::default_pinned_apps_field_trial::CHROME); - #endif - - if (event.flags() & ui::EF_CONTROL_DOWN) { - launcher_controller()->CreateNewWindow(); - return; - } - - // In case of a keyboard event, we were called by a hotkey. In that case we - // activate the next item in line if an item of our list is already active. - if (event.type() & ui::ET_KEY_RELEASED) { - ActivateOrAdvanceToNextBrowser(); - return; - } - - Activate(ash::LAUNCH_FROM_UNKNOWN); -} - -void BrowserShortcutLauncherItemController::OnRemoved() { - // BrowserShortcutLauncherItemController is owned by ChromeLauncherController. -} - ChromeLauncherAppMenuItems BrowserShortcutLauncherItemController::GetApplicationList(int event_flags) { ChromeLauncherAppMenuItems items; @@ -234,6 +207,52 @@ BrowserShortcutLauncherItemController::GetApplicationList(int event_flags) { return items.Pass(); } +void BrowserShortcutLauncherItemController::ItemSelected( + const ui::Event& event) { +#if defined(OS_CHROMEOS) + chromeos::default_pinned_apps_field_trial::RecordShelfClick( + chromeos::default_pinned_apps_field_trial::CHROME); +#endif + + if (event.flags() & ui::EF_CONTROL_DOWN) { + launcher_controller()->CreateNewWindow(); + return; + } + + // In case of a keyboard event, we were called by a hotkey. In that case we + // activate the next item in line if an item of our list is already active. + if (event.type() & ui::ET_KEY_RELEASED) { + ActivateOrAdvanceToNextBrowser(); + return; + } + + Activate(ash::LAUNCH_FROM_UNKNOWN); +} + +string16 BrowserShortcutLauncherItemController::GetTitle() { + return l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); +} + +ui::MenuModel* BrowserShortcutLauncherItemController::CreateContextMenu( + aura::RootWindow* root_window) { + ash::LauncherItem item = + *(launcher_controller()->model()->ItemByID(launcher_id())); + return new LauncherContextMenu(launcher_controller(), &item, root_window); +} + +ash::LauncherMenuModel* +BrowserShortcutLauncherItemController::CreateApplicationMenu(int event_flags) { + return new LauncherApplicationMenuItemModel(GetApplicationList(event_flags)); +} + +bool BrowserShortcutLauncherItemController::IsDraggable() { + return launcher_controller()->CanPin() ? true : false; +} + +bool BrowserShortcutLauncherItemController::ShouldShowTooltip() { + return true; +} + gfx::Image BrowserShortcutLauncherItemController::GetBrowserListIcon( content::WebContents* web_contents) const { ResourceBundle& rb = ResourceBundle::GetSharedInstance(); diff --git a/chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.h b/chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.h index 749e101..fbdfd97 100644 --- a/chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.h +++ b/chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.h @@ -30,17 +30,22 @@ class BrowserShortcutLauncherItemController : public LauncherItemController { void UpdateBrowserItemState(); // LauncherItemController overrides: - virtual string16 GetTitle() OVERRIDE; virtual bool IsCurrentlyShownInWindow(aura::Window* window) const OVERRIDE; virtual bool IsOpen() const OVERRIDE; virtual bool IsVisible() const OVERRIDE; virtual void Launch(ash::LaunchSource source, int event_flags) OVERRIDE; virtual void Activate(ash::LaunchSource source) OVERRIDE; virtual void Close() OVERRIDE; - virtual void Clicked(const ui::Event& event) OVERRIDE; - virtual void OnRemoved() OVERRIDE; virtual ChromeLauncherAppMenuItems GetApplicationList( int event_flags) OVERRIDE; + virtual void ItemSelected(const ui::Event& event) OVERRIDE; + virtual base::string16 GetTitle() OVERRIDE; + virtual ui::MenuModel* CreateContextMenu( + aura::RootWindow* root_window) OVERRIDE; + virtual ash::LauncherMenuModel* CreateApplicationMenu( + int event_flags) OVERRIDE; + virtual bool IsDraggable() OVERRIDE; + virtual bool ShouldShowTooltip() OVERRIDE; private: // Get the favicon for the browser list entry for |web_contents|. diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc index d95257f..4b7937b 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc @@ -43,8 +43,6 @@ #include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item_tab.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_types.h" #include "chrome/browser/ui/ash/launcher/launcher_app_tab_helper.h" -#include "chrome/browser/ui/ash/launcher/launcher_application_menu_item_model.h" -#include "chrome/browser/ui/ash/launcher/launcher_context_menu.h" #include "chrome/browser/ui/ash/launcher/launcher_item_controller.h" #include "chrome/browser/ui/ash/launcher/shell_window_launcher_controller.h" #include "chrome/browser/ui/ash/launcher/shell_window_launcher_item_controller.h" @@ -83,7 +81,6 @@ #include "ui/views/corewm/window_animations.h" #if defined(OS_CHROMEOS) -#include "chrome/browser/chromeos/login/default_pinned_apps_field_trial.h" #include "chrome/browser/chromeos/login/user_manager.h" #include "chrome/browser/chromeos/login/wallpaper_manager.h" #include "chrome/browser/ui/ash/chrome_shell_delegate.h" @@ -257,6 +254,7 @@ ChromeLauncherController::ChromeLauncherController( Profile* profile, ash::LauncherModel* model) : model_(model), + item_delegate_manager_(NULL), profile_(profile), app_sync_ui_state_(NULL), ignore_persist_pinned_state_change_(false) { @@ -277,8 +275,11 @@ ChromeLauncherController::ChromeLauncherController( model_->AddObserver(this); // Right now ash::Shell isn't created for tests. // TODO(mukai): Allows it to observe display change and write tests. - if (ash::Shell::HasInstance()) + if (ash::Shell::HasInstance()) { ash::Shell::GetInstance()->display_controller()->AddObserver(this); + item_delegate_manager_ = + ash::Shell::GetInstance()->launcher_item_delegate_manager(); + } // TODO(stevenjb): Find a better owner for shell_window_controller_? shell_window_controller_.reset(new ShellWindowLauncherController(this)); @@ -289,11 +290,6 @@ ChromeLauncherController::ChromeLauncherController( chrome::NOTIFICATION_EXTENSION_UNLOADED, content::Source<Profile>(profile_)); - // This check is needed for win7_aura. Without this, all tests in - // ChromeLauncherControllerTest will fail by win7_aura. - if (ash::Shell::HasInstance()) - RegisterLauncherItemDelegate(); - #if defined(OS_CHROMEOS) // On Chrome OS using multi profile we want to switch the content of the shelf // with a user change. Note that for unit tests the instance can be NULL. @@ -325,7 +321,6 @@ ChromeLauncherController::~ChromeLauncherController() { ash::Shell::GetInstance()->display_controller()->RemoveObserver(this); for (IDToItemControllerMap::iterator i = id_to_item_controller_map_.begin(); i != id_to_item_controller_map_.end(); ++i) { - i->second->OnRemoved(); int index = model_->ItemIndexByID(i->first); // A "browser proxy" is not known to the model and this removal does // therefore not need to be propagated to the model. @@ -416,9 +411,10 @@ void ChromeLauncherController::SetItemController( CHECK(controller); IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id); CHECK(iter != id_to_item_controller_map_.end()); - iter->second->OnRemoved(); - iter->second = controller; controller->set_launcher_id(id); + iter->second = controller; + // Existing controller is destroyed and replaced by registering again. + SetLauncherItemDelegate(id, controller); } void ChromeLauncherController::CloseLauncherItem(ash::LauncherID id) { @@ -429,9 +425,10 @@ void ChromeLauncherController::CloseLauncherItem(ash::LauncherID id) { CHECK(iter != id_to_item_controller_map_.end()); SetItemStatus(id, ash::STATUS_CLOSED); std::string app_id = iter->second->app_id(); - iter->second->OnRemoved(); iter->second = new AppShortcutLauncherItemController(app_id, this); iter->second->set_launcher_id(id); + // Existing controller is destroyed and replaced by registering again. + SetLauncherItemDelegate(id, iter->second); } else { LauncherItemClosed(id); } @@ -959,37 +956,6 @@ void ChromeLauncherController::ActivateWindowOrMinimizeIfActive( } } -void ChromeLauncherController::ItemSelected(const ash::LauncherItem& item, - const ui::Event& event) { - DCHECK(HasItemController(item.id)); - LauncherItemController* item_controller = id_to_item_controller_map_[item.id]; -#if defined(OS_CHROMEOS) - if (!item_controller->app_id().empty()) { - chromeos::default_pinned_apps_field_trial::RecordShelfAppClick( - item_controller->app_id()); - } -#endif - item_controller->Clicked(event); -} - -string16 ChromeLauncherController::GetTitle(const ash::LauncherItem& item) { - DCHECK(HasItemController(item.id)); - return id_to_item_controller_map_[item.id]->GetTitle(); -} - -ui::MenuModel* ChromeLauncherController::CreateContextMenu( - const ash::LauncherItem& item, - aura::RootWindow* root_window) { - return new LauncherContextMenu(this, &item, root_window); -} - -ash::LauncherMenuModel* ChromeLauncherController::CreateApplicationMenu( - const ash::LauncherItem& item, - int event_flags) { - return new LauncherApplicationMenuItemModel(GetApplicationList(item, - event_flags)); -} - ash::LauncherID ChromeLauncherController::GetIDByWindow(aura::Window* window) { int browser_index = ash::GetBrowserItemIndex(*model_); DCHECK_GE(browser_index, 0); @@ -1011,19 +977,6 @@ ash::LauncherID ChromeLauncherController::GetIDByWindow(aura::Window* window) { return 0; } -bool ChromeLauncherController::IsDraggable(const ash::LauncherItem& item) { - return (item.type == ash::TYPE_APP_SHORTCUT || - item.type == ash::TYPE_WINDOWED_APP) ? CanPin() : true; -} - -bool ChromeLauncherController::ShouldShowTooltip( - const ash::LauncherItem& item) { - if (item.type == ash::TYPE_APP_PANEL && - id_to_item_controller_map_[item.id]->IsVisible()) - return false; - return true; -} - void ChromeLauncherController::OnLauncherCreated(ash::Launcher* launcher) { launchers_.insert(launcher); launcher->shelf_widget()->shelf_layout_manager()->AddObserver(this); @@ -1303,6 +1256,11 @@ const std::string& ChromeLauncherController::GetAppIdFromLauncherIdForTest( return id_to_item_controller_map_[id]->app_id(); } +void ChromeLauncherController::SetLauncherItemDelegateManagerForTest( + ash::LauncherItemDelegateManager* manager) { + item_delegate_manager_ = manager; +} + ash::LauncherID ChromeLauncherController::CreateAppShortcutLauncherItemWithType( const std::string& app_id, int index, @@ -1314,6 +1272,13 @@ ash::LauncherID ChromeLauncherController::CreateAppShortcutLauncherItemWithType( return launcher_id; } +LauncherItemController* ChromeLauncherController::GetLauncherItemController( + const ash::LauncherID id) { + if (!HasItemController(id)) + return NULL; + return id_to_item_controller_map_[id]; +} + Profile* ChromeLauncherController::GetProfileForNewWindows() { return ProfileManager::GetDefaultProfileOrOffTheRecord(); } @@ -1323,7 +1288,6 @@ void ChromeLauncherController::LauncherItemClosed(ash::LauncherID id) { CHECK(iter != id_to_item_controller_map_.end()); CHECK(iter->second); app_icon_loader_->ClearImage(iter->second->app_id()); - iter->second->OnRemoved(); id_to_item_controller_map_.erase(iter); int index = model_->ItemIndexByID(id); // A "browser proxy" is not known to the model and this removal does @@ -1641,6 +1605,8 @@ ash::LauncherID ChromeLauncherController::InsertAppLauncherItem( app_icon_loader_->FetchImage(app_id); + SetLauncherItemDelegate(id, controller); + return id; } @@ -1683,10 +1649,11 @@ ash::LauncherID ChromeLauncherController::CreateBrowserShortcutLauncherItem() { ash::LauncherID id = model_->next_id(); size_t index = GetChromeIconIndexForCreation(); model_->AddAt(index, browser_shortcut); - browser_item_controller_.reset( - new BrowserShortcutLauncherItemController(this)); - id_to_item_controller_map_[id] = browser_item_controller_.get(); + id_to_item_controller_map_[id] = + new BrowserShortcutLauncherItemController(this); id_to_item_controller_map_[id]->set_launcher_id(id); + // LauncherItemDelegateManager owns BrowserShortcutLauncherItemController. + SetLauncherItemDelegate(id, id_to_item_controller_map_[id]); return id; } @@ -1861,16 +1828,14 @@ void ChromeLauncherController::CloseWindowedAppsFromRemovedExtension( } } -void ChromeLauncherController::RegisterLauncherItemDelegate() { - // TODO(simon.hong81): Register LauncherItemDelegate when LauncherItemDelegate - // is created. - ash::LauncherItemDelegateManager* manager = - ash::Shell::GetInstance()->launcher_item_delegate_manager(); - manager->RegisterLauncherItemDelegate(ash::TYPE_APP_PANEL, this); - manager->RegisterLauncherItemDelegate(ash::TYPE_APP_SHORTCUT, this); - manager->RegisterLauncherItemDelegate(ash::TYPE_BROWSER_SHORTCUT, this); - manager->RegisterLauncherItemDelegate(ash::TYPE_PLATFORM_APP, this); - manager->RegisterLauncherItemDelegate(ash::TYPE_WINDOWED_APP, this); +void ChromeLauncherController::SetLauncherItemDelegate( + ash::LauncherID id, + ash::LauncherItemDelegate* item_delegate) { + DCHECK_GT(id, 0); + DCHECK(item_delegate); + DCHECK(item_delegate_manager_); + item_delegate_manager_->SetLauncherItemDelegate(id, + scoped_ptr<ash::LauncherItemDelegate>(item_delegate).Pass()); } void ChromeLauncherController::AttachProfile(Profile* profile) { diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.h b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.h index 6583eff..8057626 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.h +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.h @@ -46,6 +46,7 @@ class ShellWindowLauncherController; class TabContents; namespace ash { +class LauncherItemDelegateManager; class LauncherModel; } @@ -85,10 +86,7 @@ class ChromeLauncherControllerUserSwitchObserver { // * App shell windows have ShellWindowLauncherItemController, owned by // ShellWindowLauncherController. // * Shortcuts have no LauncherItemController. -// TODO(simon.hong81): Move LauncherItemDelegate out from -// ChromeLauncherController and makes separate subclass with it. class ChromeLauncherController : public ash::LauncherDelegate, - public ash::LauncherItemDelegate, public ash::LauncherModelObserver, public ash::ShellObserver, public ash::DisplayController::Observer, @@ -296,18 +294,6 @@ class ChromeLauncherController : public ash::LauncherDelegate, virtual bool CanPin() const OVERRIDE; virtual void UnpinAppWithID(const std::string& app_id) OVERRIDE; - // ash::LauncherItemDelegate overrides: - virtual void ItemSelected(const ash::LauncherItem& item, - const ui::Event& event) OVERRIDE; - virtual string16 GetTitle(const ash::LauncherItem& item) OVERRIDE; - virtual ui::MenuModel* CreateContextMenu( - const ash::LauncherItem& item, aura::RootWindow* root) OVERRIDE; - virtual ash::LauncherMenuModel* CreateApplicationMenu( - const ash::LauncherItem& item, - int event_flags) OVERRIDE; - virtual bool IsDraggable(const ash::LauncherItem& item) OVERRIDE; - virtual bool ShouldShowTooltip(const ash::LauncherItem& item) OVERRIDE; - // ash::LauncherModelObserver overrides: virtual void LauncherItemAdded(int index) OVERRIDE; virtual void LauncherItemRemoved(int index, ash::LauncherID id) OVERRIDE; @@ -385,6 +371,8 @@ class ChromeLauncherController : public ash::LauncherDelegate, BrowserShortcutLauncherItemController* GetBrowserShortcutLauncherItemController(); + LauncherItemController* GetLauncherItemController(const ash::LauncherID id); + protected: // Creates a new app shortcut item and controller on the launcher at |index|. // Use kInsertItemAtEnd to add a shortcut as the last item. @@ -397,6 +385,11 @@ class ChromeLauncherController : public ash::LauncherDelegate, void SetAppIconLoaderForTest(extensions::AppIconLoader* loader); const std::string& GetAppIdFromLauncherIdForTest(ash::LauncherID id); + // Sets the ash::LauncherItemDelegateManager only for unittests and doesn't + // take an ownership of it. + void SetLauncherItemDelegateManagerForTest( + ash::LauncherItemDelegateManager* manager); + private: friend class ChromeLauncherControllerTest; friend class LauncherAppBrowserTest; @@ -508,8 +501,10 @@ class ChromeLauncherController : public ash::LauncherDelegate, // deleted. void CloseWindowedAppsFromRemovedExtension(const std::string& app_id); - // Register LauncherItemDelegate. - void RegisterLauncherItemDelegate(); + // Set LauncherItemDelegate |item_delegate| for |id| and take an ownership. + // TODO(simon.hong81): Make this take a scoped_ptr of |item_delegate|. + void SetLauncherItemDelegate(ash::LauncherID id, + ash::LauncherItemDelegate* item_delegate); // Attach to a specific profile. void AttachProfile(Profile* proifile); @@ -521,6 +516,8 @@ class ChromeLauncherController : public ash::LauncherDelegate, ash::LauncherModel* model_; + ash::LauncherItemDelegateManager* item_delegate_manager_; + // Profile used for prefs and loading extensions. This is NOT necessarily the // profile new windows are created with. Profile* profile_; @@ -553,9 +550,6 @@ class ChromeLauncherController : public ash::LauncherDelegate, // Launchers that are currently being observed. std::set<ash::Launcher*> launchers_; - // The owned browser shortcut item. - scoped_ptr<BrowserShortcutLauncherItemController> browser_item_controller_; - // The owned browser status monitor. scoped_ptr<BrowserStatusMonitor> browser_status_monitor_; diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc index 3addbf6..baab616 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc @@ -34,6 +34,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/app_list/app_list_service.h" #include "chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.h" +#include "chrome/browser/ui/ash/launcher/launcher_application_menu_item_model.h" #include "chrome/browser/ui/ash/launcher/launcher_item_controller.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" @@ -151,7 +152,8 @@ class LauncherPlatformAppBrowserTest int GetNumApplicationMenuItems(const ash::LauncherItem& item) { const int event_flags = 0; scoped_ptr<ash::LauncherMenuModel> menu( - controller_->CreateApplicationMenu(item, event_flags)); + new LauncherApplicationMenuItemModel( + controller_->GetApplicationList(item, event_flags))); int num_items = 0; for (int i = 0; i < menu->GetItemCount(); ++i) { if (menu->GetTypeAt(i) != ui::MenuModel::TYPE_SEPARATOR) @@ -658,7 +660,7 @@ IN_PROC_BROWSER_TEST_F(LauncherAppBrowserNoMinimizeOnClick, EXPECT_EQ(LauncherItemController::TYPE_APP, item1_controller->type()); // Clicking the item should have no effect. TestEvent click_event(ui::ET_MOUSE_PRESSED); - item1_controller->Clicked(click_event); + item1_controller->ItemSelected(click_event); EXPECT_TRUE(window1->GetNativeWindow()->IsVisible()); EXPECT_TRUE(window1->GetBaseWindow()->IsActive()); // Minimize the window and confirm that the controller item is updated. @@ -667,14 +669,14 @@ IN_PROC_BROWSER_TEST_F(LauncherAppBrowserNoMinimizeOnClick, EXPECT_FALSE(window1->GetBaseWindow()->IsActive()); EXPECT_EQ(ash::STATUS_RUNNING, item1.status); // Clicking the item should activate the window. - item1_controller->Clicked(click_event); + item1_controller->ItemSelected(click_event); EXPECT_TRUE(window1->GetNativeWindow()->IsVisible()); EXPECT_TRUE(window1->GetBaseWindow()->IsActive()); EXPECT_EQ(ash::STATUS_ACTIVE, item1.status); // Maximizing a window should preserve state after minimize + click. window1->GetBaseWindow()->Maximize(); window1->GetBaseWindow()->Minimize(); - item1_controller->Clicked(click_event); + item1_controller->ItemSelected(click_event); EXPECT_TRUE(window1->GetNativeWindow()->IsVisible()); EXPECT_TRUE(window1->GetBaseWindow()->IsActive()); EXPECT_TRUE(window1->GetBaseWindow()->IsMaximized()); @@ -697,20 +699,20 @@ IN_PROC_BROWSER_TEST_F(LauncherAppBrowserMinimizeOnClick, EXPECT_EQ(LauncherItemController::TYPE_APP, item1_controller->type()); // Since it is already active, clicking it should minimize. TestEvent click_event(ui::ET_MOUSE_PRESSED); - item1_controller->Clicked(click_event); + item1_controller->ItemSelected(click_event); EXPECT_FALSE(window1->GetNativeWindow()->IsVisible()); EXPECT_FALSE(window1->GetBaseWindow()->IsActive()); EXPECT_TRUE(window1->GetBaseWindow()->IsMinimized()); EXPECT_EQ(ash::STATUS_RUNNING, item1.status); // Clicking the item again should activate the window again. - item1_controller->Clicked(click_event); + item1_controller->ItemSelected(click_event); EXPECT_TRUE(window1->GetNativeWindow()->IsVisible()); EXPECT_TRUE(window1->GetBaseWindow()->IsActive()); EXPECT_EQ(ash::STATUS_ACTIVE, item1.status); // Maximizing a window should preserve state after minimize + click. window1->GetBaseWindow()->Maximize(); window1->GetBaseWindow()->Minimize(); - item1_controller->Clicked(click_event); + item1_controller->ItemSelected(click_event); EXPECT_TRUE(window1->GetNativeWindow()->IsVisible()); EXPECT_TRUE(window1->GetBaseWindow()->IsActive()); EXPECT_TRUE(window1->GetBaseWindow()->IsMaximized()); @@ -725,13 +727,13 @@ IN_PROC_BROWSER_TEST_F(LauncherAppBrowserMinimizeOnClick, EXPECT_TRUE(window1a->GetNativeWindow()->IsVisible()); EXPECT_TRUE(window1a->GetBaseWindow()->IsActive()); // The first click does nothing. - item1_controller->Clicked(click_event); + item1_controller->ItemSelected(click_event); EXPECT_TRUE(window1->GetNativeWindow()->IsVisible()); EXPECT_TRUE(window1a->GetNativeWindow()->IsVisible()); EXPECT_TRUE(window1->GetBaseWindow()->IsActive()); EXPECT_FALSE(window1a->GetBaseWindow()->IsActive()); // The second neither. - item1_controller->Clicked(click_event); + item1_controller->ItemSelected(click_event); EXPECT_TRUE(window1->GetNativeWindow()->IsVisible()); EXPECT_TRUE(window1a->GetNativeWindow()->IsVisible()); EXPECT_TRUE(window1->GetBaseWindow()->IsActive()); @@ -760,15 +762,15 @@ IN_PROC_BROWSER_TEST_F(LauncherPlatformAppBrowserTest, AppPanelClickBehavior) { EXPECT_EQ(LauncherItemController::TYPE_APP_PANEL, item1_controller->type()); // Click the item and confirm that the panel is activated. TestEvent click_event(ui::ET_MOUSE_PRESSED); - item1_controller->Clicked(click_event); + item1_controller->ItemSelected(click_event); EXPECT_TRUE(panel->GetBaseWindow()->IsActive()); EXPECT_EQ(ash::STATUS_ACTIVE, item1.status); // Click the item again and confirm that the panel is minimized. - item1_controller->Clicked(click_event); + item1_controller->ItemSelected(click_event); EXPECT_TRUE(panel->GetBaseWindow()->IsMinimized()); EXPECT_EQ(ash::STATUS_RUNNING, item1.status); // Click the item again and confirm that the panel is activated. - item1_controller->Clicked(click_event); + item1_controller->ItemSelected(click_event); EXPECT_TRUE(panel->GetNativeWindow()->IsVisible()); EXPECT_TRUE(panel->GetBaseWindow()->IsActive()); EXPECT_EQ(ash::STATUS_ACTIVE, item1.status); @@ -1418,7 +1420,7 @@ IN_PROC_BROWSER_TEST_F(LauncherPlatformAppBrowserTest, WindowAttentionStatus) { // Click the item and confirm that the panel is activated. TestEvent click_event(ui::ET_MOUSE_PRESSED); - item_controller->Clicked(click_event); + item_controller->ItemSelected(click_event); EXPECT_TRUE(panel->GetBaseWindow()->IsActive()); EXPECT_EQ(ash::STATUS_ACTIVE, item.status); @@ -1524,8 +1526,9 @@ IN_PROC_BROWSER_TEST_F(LauncherAppBrowserTest, ActivateAfterSessionRestore) { EXPECT_EQ(it, ash_browser_list->end_last_active()); // Now request to either activate an existing app or create a new one. - controller_->ItemSelected(*model_->ItemByID(shortcut_id), - ui::KeyEvent(ui::ET_KEY_RELEASED, + LauncherItemController* item_controller = + controller_->GetLauncherItemController(shortcut_id); + item_controller->ItemSelected(ui::KeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_RETURN, 0, false)); diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc index 77b9d5e..45e281a 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc @@ -9,9 +9,11 @@ #include <vector> #include "ash/ash_switches.h" +#include "ash/launcher/launcher_item_delegate_manager.h" #include "ash/launcher/launcher_model.h" #include "ash/launcher/launcher_model_observer.h" #include "ash/shell.h" +#include "ash/test/launcher_item_delegate_manager_test_api.h" #include "base/command_line.h" #include "base/compiler_specific.h" #include "base/files/file_path.h" @@ -22,6 +24,7 @@ #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/test_extension_system.h" #include "chrome/browser/ui/ash/chrome_launcher_prefs.h" +#include "chrome/browser/ui/ash/launcher/launcher_application_menu_item_model.h" #include "chrome/browser/ui/ash/launcher/launcher_item_controller.h" #include "chrome/browser/ui/ash/launcher/shell_window_launcher_item_controller.h" #include "chrome/browser/ui/browser.h" @@ -194,7 +197,6 @@ class TestV2AppLauncherItemController : public LauncherItemController { virtual ~TestV2AppLauncherItemController() {} // Override for LauncherItemController: - virtual string16 GetTitle() OVERRIDE { return string16(); } virtual bool IsCurrentlyShownInWindow(aura::Window* window) const OVERRIDE { return true; } @@ -203,8 +205,8 @@ class TestV2AppLauncherItemController : public LauncherItemController { virtual void Launch(ash::LaunchSource source, int event_flags) OVERRIDE {} virtual void Activate(ash::LaunchSource source) OVERRIDE {} virtual void Close() OVERRIDE {} - virtual void Clicked(const ui::Event& event) OVERRIDE {} - virtual void OnRemoved() OVERRIDE {} + virtual void ItemSelected(const ui::Event& event) OVERRIDE {} + virtual string16 GetTitle() OVERRIDE { return string16(); } virtual ChromeLauncherAppMenuItems GetApplicationList( int event_flags) OVERRIDE { ChromeLauncherAppMenuItems items; @@ -212,6 +214,12 @@ class TestV2AppLauncherItemController : public LauncherItemController { items.push_back(new ChromeLauncherAppMenuItem(string16(), NULL, false)); return items.Pass(); } + virtual ui::MenuModel* CreateContextMenu( + aura::RootWindow* root_window) OVERRIDE { return NULL; } + virtual ash::LauncherMenuModel* CreateApplicationMenu( + int event_flags) OVERRIDE { return NULL; } + virtual bool IsDraggable() OVERRIDE { return false; } + virtual bool ShouldShowTooltip() OVERRIDE { return false; } private: @@ -222,7 +230,8 @@ class TestV2AppLauncherItemController : public LauncherItemController { class ChromeLauncherControllerTest : public BrowserWithTestWindowTest { protected: - ChromeLauncherControllerTest() : extension_service_(NULL) { + ChromeLauncherControllerTest() : test_controller_(NULL), + extension_service_(NULL) { SetHostDesktopType(chrome::HOST_DESKTOP_TYPE_ASH); } @@ -236,6 +245,14 @@ class ChromeLauncherControllerTest : public BrowserWithTestWindowTest { model_observer_.reset(new TestLauncherModelObserver); model_->AddObserver(model_observer_.get()); + if (ash::Shell::HasInstance()) { + item_delegate_manager_ = + ash::Shell::GetInstance()->launcher_item_delegate_manager(); + } else { + item_delegate_manager_ = + new ash::LauncherItemDelegateManager(model_.get()); + } + DictionaryValue manifest; manifest.SetString(extensions::manifest_keys::kName, "launcher controller test extension"); @@ -309,7 +326,7 @@ class ChromeLauncherControllerTest : public BrowserWithTestWindowTest { // Creates a running V2 app (not pinned) of type |app_id|. virtual void CreateRunningV2App(const std::string& app_id) { - DCHECK(!test_controller_.get()); + DCHECK(!test_controller_); ash::LauncherID id = launcher_controller_->CreateAppShortcutLauncherItemWithType( app_id, @@ -317,9 +334,9 @@ class ChromeLauncherControllerTest : public BrowserWithTestWindowTest { ash::TYPE_PLATFORM_APP); DCHECK(id); // Change the created launcher controller into a V2 app controller. - test_controller_.reset(new TestV2AppLauncherItemController(app_id, - launcher_controller_.get())); - launcher_controller_->SetItemController(id, test_controller_.get()); + test_controller_ = new TestV2AppLauncherItemController(app_id, + launcher_controller_.get()); + launcher_controller_->SetItemController(id, test_controller_); } // Sets the stage for a multi user test. @@ -361,13 +378,14 @@ class ChromeLauncherControllerTest : public BrowserWithTestWindowTest { } virtual void TearDown() OVERRIDE { + if (!ash::Shell::HasInstance()) + delete item_delegate_manager_; model_->RemoveObserver(model_observer_.get()); model_observer_.reset(); launcher_controller_.reset(); model_.reset(); BrowserWithTestWindowTest::TearDown(); - test_controller_.reset(); } void AddAppListLauncherItem() { @@ -380,6 +398,8 @@ class ChromeLauncherControllerTest : public BrowserWithTestWindowTest { AddAppListLauncherItem(); launcher_controller_.reset( new ChromeLauncherController(profile(), model_.get())); + if (!ash::Shell::HasInstance()) + SetLauncherItemDelegateManager(item_delegate_manager_); launcher_controller_->Init(); } @@ -397,6 +417,11 @@ class ChromeLauncherControllerTest : public BrowserWithTestWindowTest { launcher_controller_->SetAppTabHelperForTest(helper); } + void SetLauncherItemDelegateManager( + ash::LauncherItemDelegateManager* manager) { + launcher_controller_->SetLauncherItemDelegateManagerForTest(manager); + } + void InsertPrefValue(base::ListValue* pref_value, int index, const std::string& extension_id) { @@ -537,10 +562,14 @@ class ChromeLauncherControllerTest : public BrowserWithTestWindowTest { scoped_ptr<ChromeLauncherController> launcher_controller_; scoped_ptr<TestLauncherModelObserver> model_observer_; scoped_ptr<ash::LauncherModel> model_; - scoped_ptr<TestV2AppLauncherItemController> test_controller_; + + // |item_delegate_manager_| owns |test_controller_|. + LauncherItemController* test_controller_; ExtensionService* extension_service_; + ash::LauncherItemDelegateManager* item_delegate_manager_; + DISALLOW_COPY_AND_ASSIGN(ChromeLauncherControllerTest); }; @@ -1503,7 +1532,8 @@ bool CheckMenuCreation(ChromeLauncherController* controller, } scoped_ptr<ash::LauncherMenuModel> menu( - controller->CreateApplicationMenu(item, 0)); + new LauncherApplicationMenuItemModel( + controller->GetApplicationList(item, 0))); // The first element in the menu is a spacing separator. On some systems // (e.g. Windows) such things do not exist. As such we check the existence // and adjust dynamically. @@ -1667,7 +1697,8 @@ TEST_F(ChromeLauncherControllerTest, V1AppMenuExecution) { // item is per definition already the active tab). { scoped_ptr<ash::LauncherMenuModel> menu( - launcher_controller_->CreateApplicationMenu(item_gmail, 0)); + new LauncherApplicationMenuItemModel( + launcher_controller_->GetApplicationList(item_gmail, 0))); // The first element in the menu is a spacing separator. On some systems // (e.g. Windows) such things do not exist. As such we check the existence // and adjust dynamically. @@ -1680,7 +1711,8 @@ TEST_F(ChromeLauncherControllerTest, V1AppMenuExecution) { // Execute the first item. { scoped_ptr<ash::LauncherMenuModel> menu( - launcher_controller_->CreateApplicationMenu(item_gmail, 0)); + new LauncherApplicationMenuItemModel( + launcher_controller_->GetApplicationList(item_gmail, 0))); int first_item = (menu->GetTypeAt(0) == ui::MenuModel::TYPE_SEPARATOR) ? 1 : 0; menu->ActivatedAt(first_item + 2); @@ -1741,11 +1773,14 @@ TEST_F(ChromeLauncherControllerTest, AppPanels) { // Test adding an app panel std::string app_id = extension1_->id(); - ShellWindowLauncherItemController app_panel_controller( - LauncherItemController::TYPE_APP_PANEL, "id", app_id, - launcher_controller_.get()); + ShellWindowLauncherItemController* app_panel_controller = + new ShellWindowLauncherItemController( + LauncherItemController::TYPE_APP_PANEL, + "id", + app_id, + launcher_controller_.get()); ash::LauncherID launcher_id1 = launcher_controller_->CreateAppLauncherItem( - &app_panel_controller, app_id, ash::STATUS_RUNNING); + app_panel_controller, app_id, ash::STATUS_RUNNING); int panel_index = model_observer_->last_index(); EXPECT_EQ(3, model_observer_->added()); EXPECT_EQ(0, model_observer_->changed()); @@ -1756,7 +1791,7 @@ TEST_F(ChromeLauncherControllerTest, AppPanels) { EXPECT_EQ(0, launcher_controller_->GetLauncherIDForAppID(app_id)); // Setting the app image image should not change the panel if it set its icon - app_panel_controller.set_image_set_by_controller(true); + app_panel_controller->set_image_set_by_controller(true); gfx::ImageSkia image; launcher_controller_->SetAppImage(app_id, image); EXPECT_EQ(0, model_observer_->changed()); @@ -1764,8 +1799,15 @@ TEST_F(ChromeLauncherControllerTest, AppPanels) { // Add a second app panel and verify that it get the same index as the first // one had, being added to the left of the existing panel. + ShellWindowLauncherItemController* app_panel_controller2 = + new ShellWindowLauncherItemController( + LauncherItemController::TYPE_APP_PANEL, + "id", + app_id, + launcher_controller_.get()); + ash::LauncherID launcher_id2 = launcher_controller_->CreateAppLauncherItem( - &app_panel_controller, app_id, ash::STATUS_RUNNING); + app_panel_controller2, app_id, ash::STATUS_RUNNING); EXPECT_EQ(panel_index, model_observer_->last_index()); EXPECT_EQ(1, model_observer_->added()); model_observer_->clear_counts(); @@ -1869,14 +1911,27 @@ TEST_F(ChromeLauncherControllerTest, PersistLauncherItemPositions) { EXPECT_EQ(ash::TYPE_BROWSER_SHORTCUT, model_->items()[3].type); launcher_controller_.reset(); + if (!ash::Shell::HasInstance()) { + delete item_delegate_manager_; + } else { + // Clear already registered LauncherItemDelegate. + ash::test::LauncherItemDelegateManagerTestAPI test(item_delegate_manager_); + test.RemoveAllLauncherItemDelegateForTest(); + } model_.reset(new ash::LauncherModel); + + AddAppListLauncherItem(); launcher_controller_.reset( ChromeLauncherController::CreateInstance(profile(), model_.get())); app_tab_helper = new TestAppTabHelperImpl; app_tab_helper->SetAppID(tab_strip_model->GetWebContentsAt(0), "1"); app_tab_helper->SetAppID(tab_strip_model->GetWebContentsAt(1), "2"); SetAppTabHelper(app_tab_helper); - AddAppListLauncherItem(); + if (!ash::Shell::HasInstance()) { + item_delegate_manager_ = + new ash::LauncherItemDelegateManager(model_.get()); + SetLauncherItemDelegateManager(item_delegate_manager_); + } launcher_controller_->Init(); // Check LauncherItems are restored after resetting ChromeLauncherController. @@ -1912,7 +1967,15 @@ TEST_F(ChromeLauncherControllerTest, PersistPinned) { EXPECT_EQ(initial_size + 1, model_->items().size()); launcher_controller_.reset(); + if (!ash::Shell::HasInstance()) { + delete item_delegate_manager_; + } else { + // Clear already registered LauncherItemDelegate. + ash::test::LauncherItemDelegateManagerTestAPI test(item_delegate_manager_); + test.RemoveAllLauncherItemDelegateForTest(); + } model_.reset(new ash::LauncherModel); + AddAppListLauncherItem(); launcher_controller_.reset( ChromeLauncherController::CreateInstance(profile(), model_.get())); @@ -1921,6 +1984,11 @@ TEST_F(ChromeLauncherControllerTest, PersistPinned) { SetAppTabHelper(app_tab_helper); app_icon_loader = new TestAppIconLoaderImpl; SetAppIconLoader(app_icon_loader); + if (!ash::Shell::HasInstance()) { + item_delegate_manager_ = + new ash::LauncherItemDelegateManager(model_.get()); + SetLauncherItemDelegateManager(item_delegate_manager_); + } launcher_controller_->Init(); EXPECT_EQ(1, app_icon_loader->fetch_count()); diff --git a/chrome/browser/ui/ash/launcher/launcher_item_controller.h b/chrome/browser/ui/ash/launcher/launcher_item_controller.h index df14b78..6398e97 100644 --- a/chrome/browser/ui/ash/launcher/launcher_item_controller.h +++ b/chrome/browser/ui/ash/launcher/launcher_item_controller.h @@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_UI_ASH_LAUNCHER_LAUNCHER_ITEM_CONTROLLER_H_ #define CHROME_BROWSER_UI_ASH_LAUNCHER_LAUNCHER_ITEM_CONTROLLER_H_ +#include "ash/launcher/launcher_item_delegate.h" #include "ash/launcher/launcher_types.h" #include "base/basictypes.h" #include "base/compiler_specific.h" @@ -28,7 +29,7 @@ class WebContents; // LauncherItemController is used by ChromeLauncherController to track one // or more windows associated with a launcher item. -class LauncherItemController { +class LauncherItemController : public ash::LauncherItemDelegate { public: enum Type { TYPE_APP, @@ -63,9 +64,6 @@ class LauncherItemController { image_set_by_controller_ = image_set_by_controller; } - // Returns the title for this item. - virtual string16 GetTitle() = 0; - // Returns true if this item controls |window|. // When this |window| has multiple applications/tabs, it only returns true // it controls the currently visible app/tab. @@ -87,17 +85,6 @@ class LauncherItemController { // Closes all windows associated with this item. virtual void Close() = 0; - // Called when the item is clicked. The behavior varies by the number of - // windows associated with the item: - // * One window: toggles the minimize state. - // * Multiple windows: cycles the active window. - // The |event| is dispatched by a view, therefore the type of the - // event's target is |views::View|. - virtual void Clicked(const ui::Event& event) = 0; - - // Called when the controlled item is removed from the launcher. - virtual void OnRemoved() = 0; - // Called to retrieve the list of running applications. virtual ChromeLauncherAppMenuItems GetApplicationList(int event_flags) = 0; diff --git a/chrome/browser/ui/ash/launcher/shell_window_launcher_controller.cc b/chrome/browser/ui/ash/launcher/shell_window_launcher_controller.cc index 70f78a9..cf31464 100644 --- a/chrome/browser/ui/ash/launcher/shell_window_launcher_controller.cc +++ b/chrome/browser/ui/ash/launcher/shell_window_launcher_controller.cc @@ -7,7 +7,6 @@ #include "apps/shell_window.h" #include "ash/shell.h" #include "ash/wm/window_util.h" -#include "base/stl_util.h" #include "base/strings/stringprintf.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" @@ -42,7 +41,6 @@ ShellWindowLauncherController::ShellWindowLauncherController( } } - ShellWindowLauncherController::~ShellWindowLauncherController() { registry_->RemoveObserver(this); if (activation_client_) @@ -52,8 +50,6 @@ ShellWindowLauncherController::~ShellWindowLauncherController() { iter != window_to_app_launcher_id_map_.end(); ++iter) { iter->first->RemoveObserver(this); } - STLDeleteContainerPairSecondPointers( - app_controller_map_.begin(), app_controller_map_.end()); } void ShellWindowLauncherController::OnShellWindowAdded( @@ -138,7 +134,6 @@ void ShellWindowLauncherController::OnWindowDestroying(aura::Window* window) { ash::LauncherID launcher_id = controller->launcher_id(); owner_->CloseLauncherItem(launcher_id); app_controller_map_.erase(iter2); - delete controller; } } diff --git a/chrome/browser/ui/ash/launcher/shell_window_launcher_item_controller.cc b/chrome/browser/ui/ash/launcher/shell_window_launcher_item_controller.cc index e05d503..c383007 100644 --- a/chrome/browser/ui/ash/launcher/shell_window_launcher_item_controller.cc +++ b/chrome/browser/ui/ash/launcher/shell_window_launcher_item_controller.cc @@ -6,11 +6,14 @@ #include "apps/native_app_window.h" #include "apps/shell_window.h" +#include "ash/launcher/launcher_model.h" #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item_v2app.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" +#include "chrome/browser/ui/ash/launcher/launcher_application_menu_item_model.h" +#include "chrome/browser/ui/ash/launcher/launcher_context_menu.h" #include "chrome/browser/ui/ash/launcher/launcher_item_controller.h" #include "content/public/browser/web_contents.h" #include "ui/aura/client/aura_constants.h" @@ -81,20 +84,6 @@ void ShellWindowLauncherItemController::SetActiveWindow(aura::Window* window) { last_active_shell_window_ = *iter; } -string16 ShellWindowLauncherItemController::GetTitle() { - // For panels return the title of the contents if set. - // Otherwise return the title of the app. - if (type() == TYPE_APP_PANEL && !shell_windows_.empty()) { - ShellWindow* shell_window = shell_windows_.front(); - if (shell_window->web_contents()) { - string16 title = shell_window->web_contents()->GetTitle(); - if (!title.empty()) - return title; - } - } - return GetAppTitle(); -} - bool ShellWindowLauncherItemController::IsCurrentlyShownInWindow( aura::Window* window) const { ShellWindowList::const_iterator iter = @@ -140,7 +129,36 @@ void ShellWindowLauncherItemController::Close() { } } -void ShellWindowLauncherItemController::Clicked(const ui::Event& event) { +void ShellWindowLauncherItemController::ActivateIndexedApp(size_t index) { + if (index >= shell_windows_.size()) + return; + ShellWindowList::iterator it = shell_windows_.begin(); + std::advance(it, index); + ShowAndActivateOrMinimize(*it); +} + +ChromeLauncherAppMenuItems +ShellWindowLauncherItemController::GetApplicationList(int event_flags) { + ChromeLauncherAppMenuItems items; + items.push_back(new ChromeLauncherAppMenuItem(GetTitle(), NULL, false)); + int index = 0; + for (ShellWindowList::iterator iter = shell_windows_.begin(); + iter != shell_windows_.end(); ++iter) { + ShellWindow* shell_window = *iter; + scoped_ptr<gfx::Image> image(shell_window->GetAppListIcon()); + items.push_back(new ChromeLauncherAppMenuItemV2App( + shell_window->GetTitle(), + image.get(), // Will be copied + app_id(), + launcher_controller(), + index, + index == 0 /* has_leading_separator */)); + ++index; + } + return items.Pass(); +} + +void ShellWindowLauncherItemController::ItemSelected(const ui::Event& event) { if (shell_windows_.empty()) return; if (type() == TYPE_APP_PANEL) { @@ -171,33 +189,42 @@ void ShellWindowLauncherItemController::Clicked(const ui::Event& event) { } } -void ShellWindowLauncherItemController::ActivateIndexedApp(size_t index) { - if (index >= shell_windows_.size()) - return; - ShellWindowList::iterator it = shell_windows_.begin(); - std::advance(it, index); - ShowAndActivateOrMinimize(*it); +base::string16 ShellWindowLauncherItemController::GetTitle() { + // For panels return the title of the contents if set. + // Otherwise return the title of the app. + if (type() == TYPE_APP_PANEL && !shell_windows_.empty()) { + ShellWindow* shell_window = shell_windows_.front(); + if (shell_window->web_contents()) { + string16 title = shell_window->web_contents()->GetTitle(); + if (!title.empty()) + return title; + } + } + return GetAppTitle(); } -ChromeLauncherAppMenuItems -ShellWindowLauncherItemController::GetApplicationList(int event_flags) { - ChromeLauncherAppMenuItems items; - items.push_back(new ChromeLauncherAppMenuItem(GetTitle(), NULL, false)); - int index = 0; - for (ShellWindowList::iterator iter = shell_windows_.begin(); - iter != shell_windows_.end(); ++iter) { - ShellWindow* shell_window = *iter; - scoped_ptr<gfx::Image> image(shell_window->GetAppListIcon()); - items.push_back(new ChromeLauncherAppMenuItemV2App( - shell_window->GetTitle(), - image.get(), // Will be copied - app_id(), - launcher_controller(), - index, - index == 0 /* has_leading_separator */)); - ++index; - } - return items.Pass(); +ui::MenuModel* ShellWindowLauncherItemController::CreateContextMenu( + aura::RootWindow* root_window) { + ash::LauncherItem item = + *(launcher_controller()->model()->ItemByID(launcher_id())); + return new LauncherContextMenu(launcher_controller(), &item, root_window); +} + +ash::LauncherMenuModel* +ShellWindowLauncherItemController::CreateApplicationMenu(int event_flags) { + return new LauncherApplicationMenuItemModel(GetApplicationList(event_flags)); +} + +bool ShellWindowLauncherItemController::IsDraggable() { + if (type() == TYPE_APP_PANEL) + return true; + return launcher_controller()->CanPin() ? true : false; +} + +bool ShellWindowLauncherItemController::ShouldShowTooltip() { + if (type() == TYPE_APP_PANEL && IsVisible()) + return false; + return true; } void ShellWindowLauncherItemController::OnWindowPropertyChanged( diff --git a/chrome/browser/ui/ash/launcher/shell_window_launcher_item_controller.h b/chrome/browser/ui/ash/launcher/shell_window_launcher_item_controller.h index 63c1408..ea2226c 100644 --- a/chrome/browser/ui/ash/launcher/shell_window_launcher_item_controller.h +++ b/chrome/browser/ui/ash/launcher/shell_window_launcher_item_controller.h @@ -31,7 +31,7 @@ class ChromeLauncherController; // instance per app, per launcher id. // For apps with multiple windows, each item controller keeps track of all // windows associated with the app and their activation order. -// Instances are owned by ShellWindowLauncherController. +// Instances are owned by ash::LauncherItemDelegateManager. // // Tests are in chrome_launcher_controller_browsertest.cc @@ -54,20 +54,25 @@ class ShellWindowLauncherItemController : public LauncherItemController, const std::string& app_launcher_id() const { return app_launcher_id_; } - // LauncherItemController - virtual string16 GetTitle() OVERRIDE; + // LauncherItemController overrides: virtual bool IsCurrentlyShownInWindow(aura::Window* window) const OVERRIDE; virtual bool IsOpen() const OVERRIDE; virtual bool IsVisible() const OVERRIDE; virtual void Launch(ash::LaunchSource source, int event_flags) OVERRIDE; virtual void Activate(ash::LaunchSource source) OVERRIDE; virtual void Close() OVERRIDE; - virtual void Clicked(const ui::Event& event) OVERRIDE; - virtual void OnRemoved() OVERRIDE {} virtual ChromeLauncherAppMenuItems GetApplicationList( int event_flags) OVERRIDE; + virtual void ItemSelected(const ui::Event& eent) OVERRIDE; + virtual base::string16 GetTitle() OVERRIDE; + virtual ui::MenuModel* CreateContextMenu( + aura::RootWindow* root_window) OVERRIDE; + virtual ash::LauncherMenuModel* CreateApplicationMenu( + int event_flags) OVERRIDE; + virtual bool IsDraggable() OVERRIDE; + virtual bool ShouldShowTooltip() OVERRIDE; - // aura::WindowObserver + // aura::WindowObserver overrides: virtual void OnWindowPropertyChanged(aura::Window* window, const void* key, intptr_t old) OVERRIDE; |