| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ash/test/test_shelf_delegate.h" | 5 #include "ash/test/test_shelf_delegate.h" |
| 6 | 6 |
| 7 #include <utility> | |
| 8 | |
| 9 #include "ash/root_window_controller.h" | |
| 10 #include "ash/shelf/shelf_model.h" | 7 #include "ash/shelf/shelf_model.h" |
| 11 #include "ash/shelf/wm_shelf.h" | |
| 12 #include "ash/shell.h" | 8 #include "ash/shell.h" |
| 13 #include "ash/shell_observer.h" | 9 #include "base/strings/string_util.h" |
| 14 #include "ash/test/test_shelf_item_delegate.h" | |
| 15 #include "ash/wm/window_properties.h" | |
| 16 #include "ash/wm_window.h" | |
| 17 #include "base/memory/ptr_util.h" | |
| 18 #include "ui/aura/window.h" | |
| 19 | 10 |
| 20 namespace ash { | 11 namespace ash { |
| 21 namespace test { | 12 namespace test { |
| 22 | 13 |
| 23 namespace { | |
| 24 | |
| 25 // Set the |type| of the item with the given |shelf_id|, if the item exists. | |
| 26 void SetItemType(ShelfID shelf_id, ShelfItemType type) { | |
| 27 ShelfModel* model = Shell::Get()->shelf_model(); | |
| 28 ash::ShelfItems::const_iterator item = model->ItemByID(shelf_id); | |
| 29 if (item != model->items().end()) { | |
| 30 ShelfItem pinned_item = *item; | |
| 31 pinned_item.type = type; | |
| 32 model->Set(item - model->items().begin(), pinned_item); | |
| 33 } | |
| 34 } | |
| 35 | |
| 36 } // namespace | |
| 37 | |
| 38 TestShelfDelegate* TestShelfDelegate::instance_ = nullptr; | 14 TestShelfDelegate* TestShelfDelegate::instance_ = nullptr; |
| 39 | 15 |
| 40 // A ShellObserver that sets the shelf alignment and auto hide behavior when the | 16 TestShelfDelegate::TestShelfDelegate() { |
| 41 // shelf is created, to simulate ChromeLauncherController's behavior. | |
| 42 class ShelfInitializer : public ShellObserver { | |
| 43 public: | |
| 44 ShelfInitializer() { Shell::Get()->AddShellObserver(this); } | |
| 45 ~ShelfInitializer() override { Shell::Get()->RemoveShellObserver(this); } | |
| 46 | |
| 47 // ShellObserver: | |
| 48 void OnShelfCreatedForRootWindow(WmWindow* root_window) override { | |
| 49 WmShelf* shelf = root_window->GetRootWindowController()->GetShelf(); | |
| 50 // Do not override the custom initialization performed by some unit tests. | |
| 51 if (shelf->alignment() == SHELF_ALIGNMENT_BOTTOM_LOCKED && | |
| 52 shelf->auto_hide_behavior() == SHELF_AUTO_HIDE_ALWAYS_HIDDEN) { | |
| 53 shelf->SetAlignment(SHELF_ALIGNMENT_BOTTOM); | |
| 54 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); | |
| 55 shelf->UpdateVisibilityState(); | |
| 56 } | |
| 57 } | |
| 58 | |
| 59 private: | |
| 60 DISALLOW_COPY_AND_ASSIGN(ShelfInitializer); | |
| 61 }; | |
| 62 | |
| 63 TestShelfDelegate::TestShelfDelegate() | |
| 64 : shelf_initializer_(base::MakeUnique<ShelfInitializer>()) { | |
| 65 CHECK(!instance_); | 17 CHECK(!instance_); |
| 66 instance_ = this; | 18 instance_ = this; |
| 67 } | 19 } |
| 68 | 20 |
| 69 TestShelfDelegate::~TestShelfDelegate() { | 21 TestShelfDelegate::~TestShelfDelegate() { |
| 70 instance_ = nullptr; | 22 instance_ = nullptr; |
| 71 } | 23 } |
| 72 | 24 |
| 73 void TestShelfDelegate::AddShelfItem(WmWindow* window) { | |
| 74 AddShelfItem(window, std::string()); | |
| 75 } | |
| 76 | |
| 77 void TestShelfDelegate::AddShelfItem(WmWindow* window, | |
| 78 const std::string& app_id) { | |
| 79 ShelfItem item; | |
| 80 if (!app_id.empty()) | |
| 81 item.app_launch_id = AppLaunchId(app_id); | |
| 82 if (window->GetType() == ui::wm::WINDOW_TYPE_PANEL) | |
| 83 item.type = TYPE_APP_PANEL; | |
| 84 else | |
| 85 item.type = TYPE_APP; | |
| 86 ShelfModel* model = Shell::Get()->shelf_model(); | |
| 87 ShelfID id = model->next_id(); | |
| 88 item.status = STATUS_CLOSED; | |
| 89 model->Add(item); | |
| 90 window->aura_window()->AddObserver(this); | |
| 91 | |
| 92 model->SetShelfItemDelegate(id, | |
| 93 base::MakeUnique<TestShelfItemDelegate>(window)); | |
| 94 window->aura_window()->SetProperty(kShelfIDKey, id); | |
| 95 } | |
| 96 | |
| 97 void TestShelfDelegate::RemoveShelfItemForWindow(WmWindow* window) { | |
| 98 ShelfID shelf_id = window->aura_window()->GetProperty(kShelfIDKey); | |
| 99 if (shelf_id == 0) | |
| 100 return; | |
| 101 ShelfModel* model = Shell::Get()->shelf_model(); | |
| 102 int index = model->ItemIndexByID(shelf_id); | |
| 103 DCHECK_NE(-1, index); | |
| 104 model->RemoveItemAt(index); | |
| 105 window->aura_window()->RemoveObserver(this); | |
| 106 const std::string& app_id = GetAppIDForShelfID(shelf_id); | |
| 107 if (IsAppPinned(app_id)) | |
| 108 UnpinAppWithID(app_id); | |
| 109 } | |
| 110 | |
| 111 void TestShelfDelegate::OnWindowDestroying(aura::Window* window) { | |
| 112 RemoveShelfItemForWindow(WmWindow::Get(window)); | |
| 113 } | |
| 114 | |
| 115 void TestShelfDelegate::OnWindowHierarchyChanging( | |
| 116 const HierarchyChangeParams& params) { | |
| 117 // The window may be legitimately reparented while staying open if it moves | |
| 118 // to another display or container. If the window does not have a new parent | |
| 119 // then remove the shelf item. | |
| 120 if (!params.new_parent) | |
| 121 RemoveShelfItemForWindow(WmWindow::Get(params.target)); | |
| 122 } | |
| 123 | |
| 124 ShelfID TestShelfDelegate::GetShelfIDForAppID(const std::string& app_id) { | 25 ShelfID TestShelfDelegate::GetShelfIDForAppID(const std::string& app_id) { |
| 125 // Get shelf id for |app_id| and an empty |launch_id|. | 26 // Get shelf id for |app_id| and an empty |launch_id|. |
| 126 return GetShelfIDForAppIDAndLaunchID(app_id, std::string()); | 27 return GetShelfIDForAppIDAndLaunchID(app_id, std::string()); |
| 127 } | 28 } |
| 128 | 29 |
| 129 ShelfID TestShelfDelegate::GetShelfIDForAppIDAndLaunchID( | 30 ShelfID TestShelfDelegate::GetShelfIDForAppIDAndLaunchID( |
| 130 const std::string& app_id, | 31 const std::string& app_id, |
| 131 const std::string& launch_id) { | 32 const std::string& launch_id) { |
| 132 for (const ShelfItem& item : Shell::Get()->shelf_model()->items()) { | 33 for (const ShelfItem& item : Shell::Get()->shelf_model()->items()) { |
| 133 // Ash's ShelfWindowWatcher handles app panel windows separately. | 34 // Ash's ShelfWindowWatcher handles app panel windows separately. |
| 134 if (item.type != TYPE_APP_PANEL && item.app_launch_id.app_id() == app_id && | 35 if (item.type != TYPE_APP_PANEL && item.app_launch_id.app_id() == app_id && |
| 135 item.app_launch_id.launch_id() == launch_id) { | 36 item.app_launch_id.launch_id() == launch_id) { |
| 136 return item.id; | 37 return item.id; |
| 137 } | 38 } |
| 138 } | 39 } |
| 139 return kInvalidShelfID; | 40 return kInvalidShelfID; |
| 140 } | 41 } |
| 141 | 42 |
| 142 const std::string& TestShelfDelegate::GetAppIDForShelfID(ShelfID id) { | 43 const std::string& TestShelfDelegate::GetAppIDForShelfID(ShelfID id) { |
| 143 ShelfModel* model = Shell::Get()->shelf_model(); | 44 ShelfModel* model = Shell::Get()->shelf_model(); |
| 144 ash::ShelfItems::const_iterator item = model->ItemByID(id); | 45 ShelfItems::const_iterator item = model->ItemByID(id); |
| 145 return item != model->items().end() ? item->app_launch_id.app_id() | 46 return item != model->items().end() ? item->app_launch_id.app_id() |
| 146 : base::EmptyString(); | 47 : base::EmptyString(); |
| 147 } | 48 } |
| 148 | 49 |
| 149 void TestShelfDelegate::PinAppWithID(const std::string& app_id) { | 50 void TestShelfDelegate::PinAppWithID(const std::string& app_id) { |
| 150 SetItemType(GetShelfIDForAppID(app_id), TYPE_PINNED_APP); | 51 // If the app is already pinned, do nothing and return. |
| 151 pinned_apps_.insert(app_id); | 52 if (IsAppPinned(app_id)) |
| 53 return; |
| 54 |
| 55 // Convert an existing item to be pinned, or create a new pinned item. |
| 56 ShelfModel* model = Shell::Get()->shelf_model(); |
| 57 const int index = model->ItemIndexByID(GetShelfIDForAppID(app_id)); |
| 58 if (index >= 0) { |
| 59 ShelfItem item = model->items()[index]; |
| 60 DCHECK_EQ(item.type, TYPE_APP); |
| 61 DCHECK(!item.pinned_by_policy); |
| 62 item.type = TYPE_PINNED_APP; |
| 63 model->Set(index, item); |
| 64 } else if (!app_id.empty()) { |
| 65 ShelfItem item; |
| 66 item.type = TYPE_PINNED_APP; |
| 67 item.app_launch_id = AppLaunchId(app_id); |
| 68 model->Add(item); |
| 69 } |
| 152 } | 70 } |
| 153 | 71 |
| 154 bool TestShelfDelegate::IsAppPinned(const std::string& app_id) { | 72 bool TestShelfDelegate::IsAppPinned(const std::string& app_id) { |
| 155 return pinned_apps_.find(app_id) != pinned_apps_.end(); | 73 ShelfID shelf_id = GetShelfIDForAppID(app_id); |
| 74 ShelfModel* model = Shell::Get()->shelf_model(); |
| 75 ShelfItems::const_iterator item = model->ItemByID(shelf_id); |
| 76 return item != model->items().end() && item->type == TYPE_PINNED_APP; |
| 156 } | 77 } |
| 157 | 78 |
| 158 void TestShelfDelegate::UnpinAppWithID(const std::string& app_id) { | 79 void TestShelfDelegate::UnpinAppWithID(const std::string& app_id) { |
| 159 SetItemType(GetShelfIDForAppID(app_id), TYPE_APP); | 80 // If the app is already not pinned, do nothing and return. |
| 160 pinned_apps_.erase(app_id); | 81 if (!IsAppPinned(app_id)) |
| 82 return; |
| 83 |
| 84 // Remove the item if it is closed, or mark it as unpinned. |
| 85 ShelfModel* model = Shell::Get()->shelf_model(); |
| 86 const int index = model->ItemIndexByID(GetShelfIDForAppID(app_id)); |
| 87 ShelfItem item = model->items()[index]; |
| 88 DCHECK_EQ(item.type, TYPE_PINNED_APP); |
| 89 DCHECK(!item.pinned_by_policy); |
| 90 if (item.status == STATUS_CLOSED) { |
| 91 model->RemoveItemAt(index); |
| 92 } else { |
| 93 item.type = TYPE_APP; |
| 94 model->Set(index, item); |
| 95 } |
| 161 } | 96 } |
| 162 | 97 |
| 163 } // namespace test | 98 } // namespace test |
| 164 } // namespace ash | 99 } // namespace ash |
| OLD | NEW |