OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/ash/launcher/extension_app_window_launcher_controlle
r.h" | 5 #include "chrome/browser/ui/ash/launcher/extension_app_window_launcher_controlle
r.h" |
6 | 6 |
| 7 #include "ash/public/cpp/shelf_types.h" |
| 8 #include "ash/public/cpp/window_properties.h" |
7 #include "ash/shelf/shelf_model.h" | 9 #include "ash/shelf/shelf_model.h" |
8 #include "ash/wm/window_properties.h" | |
9 #include "ash/wm/window_util.h" | 10 #include "ash/wm/window_util.h" |
10 #include "ash/wm_window.h" | 11 #include "ash/wm_window.h" |
11 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
12 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
13 #include "chrome/browser/profiles/profile.h" | 14 #include "chrome/browser/profiles/profile.h" |
14 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" | 15 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" |
15 #include "chrome/browser/ui/ash/launcher/extension_app_window_launcher_item_cont
roller.h" | 16 #include "chrome/browser/ui/ash/launcher/extension_app_window_launcher_item_cont
roller.h" |
16 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h" | 17 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h" |
17 #include "extensions/browser/app_window/app_window.h" | 18 #include "extensions/browser/app_window/app_window.h" |
18 #include "extensions/browser/app_window/native_app_window.h" | 19 #include "extensions/browser/app_window/native_app_window.h" |
19 #include "extensions/common/extension.h" | 20 #include "extensions/common/extension.h" |
20 #include "ui/aura/window.h" | 21 #include "ui/aura/window.h" |
21 #include "ui/aura/window_event_dispatcher.h" | 22 #include "ui/aura/window_event_dispatcher.h" |
22 | 23 |
23 using extensions::AppWindow; | 24 using extensions::AppWindow; |
24 using extensions::AppWindowRegistry; | 25 using extensions::AppWindowRegistry; |
25 | 26 |
26 namespace { | 27 namespace { |
27 | 28 |
28 std::string GetLaunchId(AppWindow* app_window) { | 29 // Get the ShelfID for a given |app_window|. |
| 30 ash::ShelfID GetShelfId(AppWindow* app_window) { |
29 // Set launch_id default value to an empty string. If showInShelf parameter | 31 // Set launch_id default value to an empty string. If showInShelf parameter |
30 // is true or the window type is panel and the window key is not empty, its | 32 // is true or the window type is panel and the window key is not empty, its |
31 // value is appended to the launch_id. Otherwise, if the window key is | 33 // value is appended to the launch_id. Otherwise, if the window key is |
32 // empty, the session_id is used. | 34 // empty, the session_id is used. |
33 std::string launch_id; | 35 std::string launch_id; |
34 if (app_window->show_in_shelf() || app_window->window_type_is_panel()) { | 36 if (app_window->show_in_shelf() || app_window->window_type_is_panel()) { |
35 if (!app_window->window_key().empty()) | 37 if (!app_window->window_key().empty()) |
36 launch_id = app_window->window_key(); | 38 launch_id = app_window->window_key(); |
37 else | 39 else |
38 launch_id = base::StringPrintf("%d", app_window->session_id().id()); | 40 launch_id = base::StringPrintf("%d", app_window->session_id().id()); |
39 } | 41 } |
40 return launch_id; | 42 return ash::ShelfID(app_window->extension_id(), launch_id); |
41 } | |
42 | |
43 std::string GetAppShelfId(AppWindow* app_window) { | |
44 // Set app_shelf_id value to app_id and then append launch_id. | |
45 std::string app_id = app_window->extension_id(); | |
46 std::string launch_id = GetLaunchId(app_window); | |
47 return app_id + launch_id; | |
48 } | 43 } |
49 | 44 |
50 } // namespace | 45 } // namespace |
51 | 46 |
52 ExtensionAppWindowLauncherController::ExtensionAppWindowLauncherController( | 47 ExtensionAppWindowLauncherController::ExtensionAppWindowLauncherController( |
53 ChromeLauncherController* owner) | 48 ChromeLauncherController* owner) |
54 : AppWindowLauncherController(owner) { | 49 : AppWindowLauncherController(owner) { |
55 AppWindowRegistry* registry = AppWindowRegistry::Get(owner->profile()); | 50 AppWindowRegistry* registry = AppWindowRegistry::Get(owner->profile()); |
56 registry_.insert(registry); | 51 registry_.insert(registry); |
57 registry->AddObserver(this); | 52 registry->AddObserver(this); |
58 } | 53 } |
59 | 54 |
60 ExtensionAppWindowLauncherController::~ExtensionAppWindowLauncherController() { | 55 ExtensionAppWindowLauncherController::~ExtensionAppWindowLauncherController() { |
61 for (std::set<AppWindowRegistry*>::iterator it = registry_.begin(); | 56 for (extensions::AppWindowRegistry* iter : registry_) |
62 it != registry_.end(); ++it) | 57 iter->RemoveObserver(this); |
63 (*it)->RemoveObserver(this); | |
64 | 58 |
65 for (WindowToAppShelfIdMap::iterator iter = | 59 for (const auto& iter : window_to_shelf_id_map_) |
66 window_to_app_shelf_id_map_.begin(); | 60 iter.first->RemoveObserver(this); |
67 iter != window_to_app_shelf_id_map_.end(); ++iter) { | |
68 iter->first->RemoveObserver(this); | |
69 } | |
70 } | 61 } |
71 | 62 |
72 void ExtensionAppWindowLauncherController::AdditionalUserAddedToSession( | 63 void ExtensionAppWindowLauncherController::AdditionalUserAddedToSession( |
73 Profile* profile) { | 64 Profile* profile) { |
74 // TODO(skuhne): This was added for the legacy side by side mode in M32. If | 65 // TODO(skuhne): This was added for the legacy side by side mode in M32. If |
75 // this mode gets no longer pursued this special case can be removed. | 66 // this mode gets no longer pursued this special case can be removed. |
76 if (chrome::MultiUserWindowManager::GetMultiProfileMode() != | 67 if (chrome::MultiUserWindowManager::GetMultiProfileMode() != |
77 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_MIXED) | 68 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_MIXED) |
78 return; | 69 return; |
79 | 70 |
80 AppWindowRegistry* registry = AppWindowRegistry::Get(profile); | 71 AppWindowRegistry* registry = AppWindowRegistry::Get(profile); |
81 if (registry_.find(registry) != registry_.end()) | 72 if (registry_.find(registry) != registry_.end()) |
82 return; | 73 return; |
83 | 74 |
84 registry->AddObserver(this); | 75 registry->AddObserver(this); |
85 registry_.insert(registry); | 76 registry_.insert(registry); |
86 } | 77 } |
87 | 78 |
88 void ExtensionAppWindowLauncherController::OnAppWindowIconChanged( | 79 void ExtensionAppWindowLauncherController::OnAppWindowIconChanged( |
89 AppWindow* app_window) { | 80 AppWindow* app_window) { |
90 const std::string app_shelf_id = GetAppShelfId(app_window); | 81 const ash::ShelfID shelf_id = GetShelfId(app_window); |
91 AppControllerMap::iterator iter = app_controller_map_.find(app_shelf_id); | 82 AppControllerMap::iterator iter = app_controller_map_.find(shelf_id); |
92 if (iter == app_controller_map_.end()) | 83 if (iter == app_controller_map_.end()) |
93 return; | 84 return; |
94 | 85 |
95 // Check if the window actually overrides its default icon. Otherwise use app | 86 // Check if the window actually overrides its default icon. Otherwise use app |
96 // icon loader provided by owner. | 87 // icon loader provided by owner. |
97 if (!app_window->HasCustomIcon() || app_window->app_icon().IsEmpty()) | 88 if (!app_window->HasCustomIcon() || app_window->app_icon().IsEmpty()) |
98 return; | 89 return; |
99 | 90 |
100 ExtensionAppWindowLauncherItemController* controller = iter->second; | 91 ExtensionAppWindowLauncherItemController* controller = iter->second; |
101 controller->set_image_set_by_controller(true); | 92 controller->set_image_set_by_controller(true); |
(...skipping 18 matching lines...) Expand all Loading... |
120 | 111 |
121 // Called from aura::Window::~Window(), before delegate_->OnWindowDestroyed() | 112 // Called from aura::Window::~Window(), before delegate_->OnWindowDestroyed() |
122 // which destroys AppWindow, so both |window| and the associated AppWindow | 113 // which destroys AppWindow, so both |window| and the associated AppWindow |
123 // are valid here. | 114 // are valid here. |
124 void ExtensionAppWindowLauncherController::OnWindowDestroying( | 115 void ExtensionAppWindowLauncherController::OnWindowDestroying( |
125 aura::Window* window) { | 116 aura::Window* window) { |
126 UnregisterApp(window); | 117 UnregisterApp(window); |
127 } | 118 } |
128 | 119 |
129 void ExtensionAppWindowLauncherController::RegisterApp(AppWindow* app_window) { | 120 void ExtensionAppWindowLauncherController::RegisterApp(AppWindow* app_window) { |
| 121 const ash::ShelfID shelf_id = GetShelfId(app_window); |
| 122 DCHECK(!shelf_id.IsNull()); |
| 123 aura::Window* window = app_window->GetNativeWindow(); |
| 124 window->SetProperty(ash::kShelfIDKey, new ash::ShelfID(shelf_id)); |
| 125 |
130 // Windows created by IME extension should be treated the same way as the | 126 // Windows created by IME extension should be treated the same way as the |
131 // virtual keyboard window, which does not register itself in launcher. | 127 // virtual keyboard window, which does not register itself in launcher. |
132 // Ash's ShelfWindowWatcher handles app panel windows separately. | 128 // Ash's ShelfWindowWatcher handles app panel windows separately. |
133 if (app_window->is_ime_window() || app_window->window_type_is_panel()) | 129 if (app_window->is_ime_window() || app_window->window_type_is_panel()) |
134 return; | 130 return; |
135 | 131 |
136 aura::Window* window = app_window->GetNativeWindow(); | |
137 // Get the app's shelf identifier and add an entry to the map. | 132 // Get the app's shelf identifier and add an entry to the map. |
138 DCHECK(window_to_app_shelf_id_map_.find(window) == | 133 DCHECK_EQ(window_to_shelf_id_map_.count(window), 0u); |
139 window_to_app_shelf_id_map_.end()); | 134 window_to_shelf_id_map_[window] = shelf_id; |
140 const std::string app_shelf_id = GetAppShelfId(app_window); | |
141 window_to_app_shelf_id_map_[window] = app_shelf_id; | |
142 window->AddObserver(this); | 135 window->AddObserver(this); |
143 | 136 |
144 // Find or create an item controller and launcher item. | 137 // Find or create an item controller and launcher item. |
145 std::string app_id = app_window->extension_id(); | |
146 ash::ShelfItemStatus status = ash::wm::IsActiveWindow(window) | 138 ash::ShelfItemStatus status = ash::wm::IsActiveWindow(window) |
147 ? ash::STATUS_ACTIVE | 139 ? ash::STATUS_ACTIVE |
148 : ash::STATUS_RUNNING; | 140 : ash::STATUS_RUNNING; |
149 AppControllerMap::iterator app_controller_iter = | 141 AppControllerMap::iterator app_controller_iter = |
150 app_controller_map_.find(app_shelf_id); | 142 app_controller_map_.find(shelf_id); |
151 ash::ShelfID shelf_id = 0; | |
152 | 143 |
153 if (app_controller_iter != app_controller_map_.end()) { | 144 if (app_controller_iter != app_controller_map_.end()) { |
154 ExtensionAppWindowLauncherItemController* controller = | 145 ExtensionAppWindowLauncherItemController* controller = |
155 app_controller_iter->second; | 146 app_controller_iter->second; |
156 DCHECK(controller->app_id() == app_id); | 147 DCHECK_EQ(controller->app_id(), shelf_id.app_id); |
157 shelf_id = controller->shelf_id(); | |
158 controller->AddAppWindow(app_window); | 148 controller->AddAppWindow(app_window); |
159 } else { | 149 } else { |
160 std::string launch_id = GetLaunchId(app_window); | |
161 std::unique_ptr<ExtensionAppWindowLauncherItemController> controller = | 150 std::unique_ptr<ExtensionAppWindowLauncherItemController> controller = |
162 base::MakeUnique<ExtensionAppWindowLauncherItemController>( | 151 base::MakeUnique<ExtensionAppWindowLauncherItemController>(shelf_id); |
163 ash::AppLaunchId(app_id, launch_id)); | 152 app_controller_map_[shelf_id] = controller.get(); |
164 ExtensionAppWindowLauncherItemController* item_controller = | 153 controller->AddAppWindow(app_window); |
165 controller.get(); | |
166 | 154 |
167 controller->AddAppWindow(app_window); | 155 // Check for any existing pinned shelf item with a matching |shelf_id|. |
168 // If there is already a shelf id mapped to this AppLaunchId (e.g. pinned), | 156 const int item_index = owner()->shelf_model()->ItemIndexByID(shelf_id); |
169 // use that shelf item. | 157 if (item_index < 0) { |
170 shelf_id = owner()->GetShelfIDForAppIDAndLaunchID(app_id, launch_id); | 158 owner()->CreateAppLauncherItem(std::move(controller), status); |
171 | |
172 if (shelf_id == 0) { | |
173 shelf_id = owner()->CreateAppLauncherItem(std::move(controller), status); | |
174 // Restore any existing app icon and flag as set. | 159 // Restore any existing app icon and flag as set. |
175 if (app_window->HasCustomIcon() && !app_window->app_icon().IsEmpty()) { | 160 if (app_window->HasCustomIcon() && !app_window->app_icon().IsEmpty()) { |
176 owner()->SetLauncherItemImage(shelf_id, | 161 owner()->SetLauncherItemImage(shelf_id, |
177 app_window->app_icon().AsImageSkia()); | 162 app_window->app_icon().AsImageSkia()); |
178 item_controller->set_image_set_by_controller(true); | 163 app_controller_map_[shelf_id]->set_image_set_by_controller(true); |
179 } | 164 } |
180 } else { | 165 } else { |
181 owner()->shelf_model()->SetShelfItemDelegate(shelf_id, | 166 owner()->shelf_model()->SetShelfItemDelegate(shelf_id, |
182 std::move(controller)); | 167 std::move(controller)); |
183 } | 168 } |
| 169 } |
184 | 170 |
185 // We need to change the controller associated with app_shelf_id. | |
186 app_controller_map_[app_shelf_id] = item_controller; | |
187 } | |
188 owner()->SetItemStatus(shelf_id, status); | 171 owner()->SetItemStatus(shelf_id, status); |
189 ash::WmWindow::Get(window)->aura_window()->SetProperty(ash::kShelfIDKey, | |
190 shelf_id); | |
191 } | 172 } |
192 | 173 |
193 void ExtensionAppWindowLauncherController::UnregisterApp(aura::Window* window) { | 174 void ExtensionAppWindowLauncherController::UnregisterApp(aura::Window* window) { |
194 WindowToAppShelfIdMap::iterator window_iter = | 175 const auto window_iter = window_to_shelf_id_map_.find(window); |
195 window_to_app_shelf_id_map_.find(window); | 176 DCHECK(window_iter != window_to_shelf_id_map_.end()); |
196 DCHECK(window_iter != window_to_app_shelf_id_map_.end()); | 177 ash::ShelfID shelf_id = window_iter->second; |
197 std::string app_shelf_id = window_iter->second; | 178 window_to_shelf_id_map_.erase(window_iter); |
198 window_to_app_shelf_id_map_.erase(window_iter); | |
199 window->RemoveObserver(this); | 179 window->RemoveObserver(this); |
200 | 180 |
201 AppControllerMap::iterator app_controller_iter = | 181 AppControllerMap::iterator app_controller_iter = |
202 app_controller_map_.find(app_shelf_id); | 182 app_controller_map_.find(shelf_id); |
203 DCHECK(app_controller_iter != app_controller_map_.end()); | 183 DCHECK(app_controller_iter != app_controller_map_.end()); |
204 ExtensionAppWindowLauncherItemController* controller; | 184 ExtensionAppWindowLauncherItemController* controller; |
205 controller = app_controller_iter->second; | 185 controller = app_controller_iter->second; |
206 | 186 |
207 controller->RemoveWindow(controller->GetAppWindow(window)); | 187 controller->RemoveWindow(controller->GetAppWindow(window)); |
208 if (controller->window_count() == 0) { | 188 if (controller->window_count() == 0) { |
209 // If this is the last window associated with the app window shelf id, | 189 // If this is the last window associated with the app window shelf id, |
210 // close the shelf item. | 190 // close the shelf item. |
211 ash::ShelfID shelf_id = controller->shelf_id(); | |
212 owner()->CloseLauncherItem(shelf_id); | 191 owner()->CloseLauncherItem(shelf_id); |
213 app_controller_map_.erase(app_controller_iter); | 192 app_controller_map_.erase(app_controller_iter); |
214 } | 193 } |
215 } | 194 } |
216 | 195 |
217 bool ExtensionAppWindowLauncherController::IsRegisteredApp( | 196 bool ExtensionAppWindowLauncherController::IsRegisteredApp( |
218 aura::Window* window) { | 197 aura::Window* window) { |
219 return window_to_app_shelf_id_map_.find(window) != | 198 return window_to_shelf_id_map_.find(window) != window_to_shelf_id_map_.end(); |
220 window_to_app_shelf_id_map_.end(); | |
221 } | 199 } |
222 | 200 |
223 // Private Methods | 201 // Private Methods |
224 | 202 |
225 AppWindowLauncherItemController* | 203 AppWindowLauncherItemController* |
226 ExtensionAppWindowLauncherController::ControllerForWindow( | 204 ExtensionAppWindowLauncherController::ControllerForWindow( |
227 aura::Window* window) { | 205 aura::Window* window) { |
228 WindowToAppShelfIdMap::iterator window_iter = | 206 const auto window_iter = window_to_shelf_id_map_.find(window); |
229 window_to_app_shelf_id_map_.find(window); | 207 if (window_iter == window_to_shelf_id_map_.end()) |
230 if (window_iter == window_to_app_shelf_id_map_.end()) | |
231 return nullptr; | 208 return nullptr; |
232 AppControllerMap::iterator app_controller_iter = | 209 const auto controller_iter = app_controller_map_.find(window_iter->second); |
233 app_controller_map_.find(window_iter->second); | 210 if (controller_iter == app_controller_map_.end()) |
234 if (app_controller_iter == app_controller_map_.end()) | |
235 return nullptr; | 211 return nullptr; |
236 return app_controller_iter->second; | 212 return controller_iter->second; |
237 } | 213 } |
OLD | NEW |