OLD | NEW |
1 // Copyright 2014 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/app_window_launcher_controller.h" | 5 #include "chrome/browser/ui/ash/launcher/extension_app_window_launcher_controlle
r.h" |
6 | 6 |
7 #include "ash/shelf/shelf_util.h" | 7 #include "ash/shelf/shelf_util.h" |
8 #include "ash/shell.h" | 8 #include "ash/shell.h" |
9 #include "ash/wm/window_util.h" | 9 #include "ash/wm/window_util.h" |
10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
11 #include "chrome/browser/profiles/profile.h" | 11 #include "chrome/browser/profiles/profile.h" |
12 #include "chrome/browser/ui/ash/launcher/app_window_launcher_item_controller.h" | |
13 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" | 12 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" |
| 13 #include "chrome/browser/ui/ash/launcher/extension_app_window_launcher_item_cont
roller.h" |
14 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h" | 14 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h" |
15 #include "extensions/browser/app_window/app_window.h" | 15 #include "extensions/browser/app_window/app_window.h" |
| 16 #include "extensions/browser/app_window/native_app_window.h" |
16 #include "extensions/common/extension.h" | 17 #include "extensions/common/extension.h" |
17 #include "ui/aura/window_event_dispatcher.h" | 18 #include "ui/aura/window_event_dispatcher.h" |
18 #include "ui/wm/public/activation_client.h" | |
19 | 19 |
20 using extensions::AppWindow; | 20 using extensions::AppWindow; |
21 using extensions::AppWindowRegistry; | 21 using extensions::AppWindowRegistry; |
22 | 22 |
23 namespace { | 23 namespace { |
24 | 24 |
25 std::string GetAppShelfId(AppWindow* app_window) { | 25 std::string GetAppShelfId(AppWindow* app_window) { |
26 if (app_window->window_type_is_panel()) | 26 if (app_window->window_type_is_panel()) |
27 return base::StringPrintf("panel:%d", app_window->session_id().id()); | 27 return base::StringPrintf("panel:%d", app_window->session_id().id()); |
28 return app_window->extension_id(); | 28 return app_window->extension_id(); |
29 } | 29 } |
30 | 30 |
31 } // namespace | 31 } // namespace |
32 | 32 |
33 AppWindowLauncherController::AppWindowLauncherController( | 33 ExtensionAppWindowLauncherController::ExtensionAppWindowLauncherController( |
34 ChromeLauncherController* owner) | 34 ChromeLauncherController* owner) |
35 : owner_(owner), activation_client_(NULL) { | 35 : AppWindowLauncherController(owner) { |
36 AppWindowRegistry* registry = AppWindowRegistry::Get(owner->profile()); | 36 AppWindowRegistry* registry = AppWindowRegistry::Get(owner->profile()); |
37 registry_.insert(registry); | 37 registry_.insert(registry); |
38 registry->AddObserver(this); | 38 registry->AddObserver(this); |
39 if (ash::Shell::HasInstance()) { | |
40 if (ash::Shell::GetInstance()->GetPrimaryRootWindow()) { | |
41 activation_client_ = aura::client::GetActivationClient( | |
42 ash::Shell::GetInstance()->GetPrimaryRootWindow()); | |
43 if (activation_client_) | |
44 activation_client_->AddObserver(this); | |
45 } | |
46 } | |
47 } | 39 } |
48 | 40 |
49 AppWindowLauncherController::~AppWindowLauncherController() { | 41 ExtensionAppWindowLauncherController::~ExtensionAppWindowLauncherController() { |
50 for (std::set<AppWindowRegistry*>::iterator it = registry_.begin(); | 42 for (std::set<AppWindowRegistry*>::iterator it = registry_.begin(); |
51 it != registry_.end(); | 43 it != registry_.end(); ++it) |
52 ++it) | |
53 (*it)->RemoveObserver(this); | 44 (*it)->RemoveObserver(this); |
54 | 45 |
55 if (activation_client_) | |
56 activation_client_->RemoveObserver(this); | |
57 for (WindowToAppShelfIdMap::iterator iter = | 46 for (WindowToAppShelfIdMap::iterator iter = |
58 window_to_app_shelf_id_map_.begin(); | 47 window_to_app_shelf_id_map_.begin(); |
59 iter != window_to_app_shelf_id_map_.end(); | 48 iter != window_to_app_shelf_id_map_.end(); ++iter) { |
60 ++iter) { | |
61 iter->first->RemoveObserver(this); | 49 iter->first->RemoveObserver(this); |
62 } | 50 } |
63 } | 51 } |
64 | 52 |
65 void AppWindowLauncherController::AdditionalUserAddedToSession( | 53 void ExtensionAppWindowLauncherController::AdditionalUserAddedToSession( |
66 Profile* profile) { | 54 Profile* profile) { |
67 // TODO(skuhne): This was added for the legacy side by side mode in M32. If | 55 // TODO(skuhne): This was added for the legacy side by side mode in M32. If |
68 // this mode gets no longer pursued this special case can be removed. | 56 // this mode gets no longer pursued this special case can be removed. |
69 if (chrome::MultiUserWindowManager::GetMultiProfileMode() != | 57 if (chrome::MultiUserWindowManager::GetMultiProfileMode() != |
70 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_MIXED) | 58 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_MIXED) |
71 return; | 59 return; |
72 | 60 |
73 AppWindowRegistry* registry = AppWindowRegistry::Get(profile); | 61 AppWindowRegistry* registry = AppWindowRegistry::Get(profile); |
74 if (registry_.find(registry) != registry_.end()) | 62 if (registry_.find(registry) != registry_.end()) |
75 return; | 63 return; |
76 | 64 |
77 registry->AddObserver(this); | 65 registry->AddObserver(this); |
78 registry_.insert(registry); | 66 registry_.insert(registry); |
79 } | 67 } |
80 | 68 |
81 void AppWindowLauncherController::OnAppWindowIconChanged( | 69 void ExtensionAppWindowLauncherController::OnAppWindowIconChanged( |
82 AppWindow* app_window) { | 70 AppWindow* app_window) { |
83 const std::string app_shelf_id = GetAppShelfId(app_window); | 71 const std::string app_shelf_id = GetAppShelfId(app_window); |
84 AppControllerMap::iterator iter = app_controller_map_.find(app_shelf_id); | 72 AppControllerMap::iterator iter = app_controller_map_.find(app_shelf_id); |
85 if (iter == app_controller_map_.end()) | 73 if (iter == app_controller_map_.end()) |
86 return; | 74 return; |
87 AppWindowLauncherItemController* controller = iter->second; | 75 ExtensionAppWindowLauncherItemController* controller = iter->second; |
88 controller->set_image_set_by_controller(true); | 76 controller->set_image_set_by_controller(true); |
89 owner_->SetLauncherItemImage(controller->shelf_id(), | 77 owner()->SetLauncherItemImage(controller->shelf_id(), |
90 app_window->app_icon().AsImageSkia()); | 78 app_window->app_icon().AsImageSkia()); |
91 } | 79 } |
92 | 80 |
93 void AppWindowLauncherController::OnAppWindowShown(AppWindow* app_window, | 81 void ExtensionAppWindowLauncherController::OnAppWindowShown( |
94 bool was_hidden) { | 82 AppWindow* app_window, |
| 83 bool was_hidden) { |
95 aura::Window* window = app_window->GetNativeWindow(); | 84 aura::Window* window = app_window->GetNativeWindow(); |
96 if (!IsRegisteredApp(window)) | 85 if (!IsRegisteredApp(window)) |
97 RegisterApp(app_window); | 86 RegisterApp(app_window); |
98 } | 87 } |
99 | 88 |
100 void AppWindowLauncherController::OnAppWindowHidden(AppWindow* app_window) { | 89 void ExtensionAppWindowLauncherController::OnAppWindowHidden( |
| 90 AppWindow* app_window) { |
101 aura::Window* window = app_window->GetNativeWindow(); | 91 aura::Window* window = app_window->GetNativeWindow(); |
102 if (IsRegisteredApp(window)) | 92 if (IsRegisteredApp(window)) |
103 UnregisterApp(window); | 93 UnregisterApp(window); |
104 } | 94 } |
105 | 95 |
106 // Called from aura::Window::~Window(), before delegate_->OnWindowDestroyed() | 96 // Called from aura::Window::~Window(), before delegate_->OnWindowDestroyed() |
107 // which destroys AppWindow, so both |window| and the associated AppWindow | 97 // which destroys AppWindow, so both |window| and the associated AppWindow |
108 // are valid here. | 98 // are valid here. |
109 void AppWindowLauncherController::OnWindowDestroying(aura::Window* window) { | 99 void ExtensionAppWindowLauncherController::OnWindowDestroying( |
| 100 aura::Window* window) { |
110 UnregisterApp(window); | 101 UnregisterApp(window); |
111 } | 102 } |
112 | 103 |
113 void AppWindowLauncherController::OnWindowActivated( | 104 void ExtensionAppWindowLauncherController::RegisterApp(AppWindow* app_window) { |
114 aura::client::ActivationChangeObserver::ActivationReason reason, | |
115 aura::Window* new_active, | |
116 aura::Window* old_active) { | |
117 // Make the newly active window the active (first) entry in the controller. | |
118 AppWindowLauncherItemController* new_controller = | |
119 ControllerForWindow(new_active); | |
120 if (new_controller) { | |
121 new_controller->SetActiveWindow(new_active); | |
122 owner_->SetItemStatus(new_controller->shelf_id(), ash::STATUS_ACTIVE); | |
123 } | |
124 | |
125 // Mark the old active window's launcher item as running (if different). | |
126 AppWindowLauncherItemController* old_controller = | |
127 ControllerForWindow(old_active); | |
128 if (old_controller && old_controller != new_controller) | |
129 owner_->SetItemStatus(old_controller->shelf_id(), ash::STATUS_RUNNING); | |
130 } | |
131 | |
132 void AppWindowLauncherController::RegisterApp(AppWindow* app_window) { | |
133 // Windows created by IME extension should be treated the same way as the | 105 // Windows created by IME extension should be treated the same way as the |
134 // virtual keyboard window, which does not register itself in launcher. | 106 // virtual keyboard window, which does not register itself in launcher. |
135 if (app_window->is_ime_window()) | 107 if (app_window->is_ime_window()) |
136 return; | 108 return; |
137 | 109 |
138 aura::Window* window = app_window->GetNativeWindow(); | 110 aura::Window* window = app_window->GetNativeWindow(); |
139 // Get the app's shelf identifier and add an entry to the map. | 111 // Get the app's shelf identifier and add an entry to the map. |
140 DCHECK(window_to_app_shelf_id_map_.find(window) == | 112 DCHECK(window_to_app_shelf_id_map_.find(window) == |
141 window_to_app_shelf_id_map_.end()); | 113 window_to_app_shelf_id_map_.end()); |
142 const std::string app_shelf_id = GetAppShelfId(app_window); | 114 const std::string app_shelf_id = GetAppShelfId(app_window); |
143 window_to_app_shelf_id_map_[window] = app_shelf_id; | 115 window_to_app_shelf_id_map_[window] = app_shelf_id; |
144 window->AddObserver(this); | 116 window->AddObserver(this); |
145 | 117 |
146 // Find or create an item controller and launcher item. | 118 // Find or create an item controller and launcher item. |
147 std::string app_id = app_window->extension_id(); | 119 std::string app_id = app_window->extension_id(); |
148 ash::ShelfItemStatus status = ash::wm::IsActiveWindow(window) | 120 ash::ShelfItemStatus status = ash::wm::IsActiveWindow(window) |
149 ? ash::STATUS_ACTIVE | 121 ? ash::STATUS_ACTIVE |
150 : ash::STATUS_RUNNING; | 122 : ash::STATUS_RUNNING; |
151 AppControllerMap::iterator iter = app_controller_map_.find(app_shelf_id); | 123 AppControllerMap::iterator iter = app_controller_map_.find(app_shelf_id); |
152 ash::ShelfID shelf_id = 0; | 124 ash::ShelfID shelf_id = 0; |
153 if (iter != app_controller_map_.end()) { | 125 if (iter != app_controller_map_.end()) { |
154 AppWindowLauncherItemController* controller = iter->second; | 126 ExtensionAppWindowLauncherItemController* controller = iter->second; |
155 DCHECK(controller->app_id() == app_id); | 127 DCHECK(controller->app_id() == app_id); |
156 shelf_id = controller->shelf_id(); | 128 shelf_id = controller->shelf_id(); |
157 controller->AddAppWindow(app_window, status); | 129 controller->AddAppWindow(app_window); |
158 } else { | 130 } else { |
159 LauncherItemController::Type type = | 131 LauncherItemController::Type type = |
160 app_window->window_type_is_panel() | 132 app_window->window_type_is_panel() |
161 ? LauncherItemController::TYPE_APP_PANEL | 133 ? LauncherItemController::TYPE_APP_PANEL |
162 : LauncherItemController::TYPE_APP; | 134 : LauncherItemController::TYPE_APP; |
163 AppWindowLauncherItemController* controller = | 135 ExtensionAppWindowLauncherItemController* controller = |
164 new AppWindowLauncherItemController(type, app_shelf_id, app_id, owner_); | 136 new ExtensionAppWindowLauncherItemController(type, app_shelf_id, app_id, |
165 controller->AddAppWindow(app_window, status); | 137 owner()); |
| 138 controller->AddAppWindow(app_window); |
166 // If the app shelf id is not unique, and there is already a shelf | 139 // If the app shelf id is not unique, and there is already a shelf |
167 // item for this app id (e.g. pinned), use that shelf item. | 140 // item for this app id (e.g. pinned), use that shelf item. |
168 if (app_shelf_id == app_id) | 141 if (app_shelf_id == app_id) |
169 shelf_id = owner_->GetShelfIDForAppID(app_id); | 142 shelf_id = owner()->GetShelfIDForAppID(app_id); |
170 if (shelf_id == 0) { | 143 if (shelf_id == 0) { |
171 shelf_id = owner_->CreateAppLauncherItem(controller, app_id, status); | 144 shelf_id = owner()->CreateAppLauncherItem(controller, app_id, status); |
172 // Restore any existing app icon and flag as set. | 145 // Restore any existing app icon and flag as set. |
173 const gfx::Image& app_icon = app_window->app_icon(); | 146 const gfx::Image& app_icon = app_window->app_icon(); |
174 if (!app_icon.IsEmpty()) { | 147 if (!app_icon.IsEmpty()) { |
175 owner_->SetLauncherItemImage(shelf_id, app_icon.AsImageSkia()); | 148 owner()->SetLauncherItemImage(shelf_id, app_icon.AsImageSkia()); |
176 controller->set_image_set_by_controller(true); | 149 controller->set_image_set_by_controller(true); |
177 } | 150 } |
178 } else { | 151 } else { |
179 owner_->SetItemController(shelf_id, controller); | 152 owner()->SetItemController(shelf_id, controller); |
180 } | 153 } |
181 const std::string app_shelf_id = GetAppShelfId(app_window); | 154 const std::string app_shelf_id = GetAppShelfId(app_window); |
182 app_controller_map_[app_shelf_id] = controller; | 155 app_controller_map_[app_shelf_id] = controller; |
183 } | 156 } |
184 owner_->SetItemStatus(shelf_id, status); | 157 owner()->SetItemStatus(shelf_id, status); |
185 ash::SetShelfIDForWindow(shelf_id, window); | 158 ash::SetShelfIDForWindow(shelf_id, window); |
186 } | 159 } |
187 | 160 |
188 void AppWindowLauncherController::UnregisterApp(aura::Window* window) { | 161 void ExtensionAppWindowLauncherController::UnregisterApp(aura::Window* window) { |
189 WindowToAppShelfIdMap::iterator iter1 = | 162 WindowToAppShelfIdMap::iterator iter1 = |
190 window_to_app_shelf_id_map_.find(window); | 163 window_to_app_shelf_id_map_.find(window); |
191 DCHECK(iter1 != window_to_app_shelf_id_map_.end()); | 164 DCHECK(iter1 != window_to_app_shelf_id_map_.end()); |
192 std::string app_shelf_id = iter1->second; | 165 std::string app_shelf_id = iter1->second; |
193 window_to_app_shelf_id_map_.erase(iter1); | 166 window_to_app_shelf_id_map_.erase(iter1); |
194 window->RemoveObserver(this); | 167 window->RemoveObserver(this); |
195 | 168 |
196 AppControllerMap::iterator iter2 = app_controller_map_.find(app_shelf_id); | 169 AppControllerMap::iterator iter2 = app_controller_map_.find(app_shelf_id); |
197 DCHECK(iter2 != app_controller_map_.end()); | 170 DCHECK(iter2 != app_controller_map_.end()); |
198 AppWindowLauncherItemController* controller = iter2->second; | 171 ExtensionAppWindowLauncherItemController* controller = iter2->second; |
199 controller->RemoveAppWindowForWindow(window); | 172 controller->RemoveWindowForNativeWindow(window); |
200 if (controller->app_window_count() == 0) { | 173 if (controller->window_count() == 0) { |
201 // If this is the last window associated with the app shelf id, close the | 174 // If this is the last window associated with the app shelf id, close the |
202 // shelf item. | 175 // shelf item. |
203 ash::ShelfID shelf_id = controller->shelf_id(); | 176 ash::ShelfID shelf_id = controller->shelf_id(); |
204 owner_->CloseLauncherItem(shelf_id); | 177 owner()->CloseLauncherItem(shelf_id); |
205 app_controller_map_.erase(iter2); | 178 app_controller_map_.erase(iter2); |
206 } | 179 } |
207 } | 180 } |
208 | 181 |
209 bool AppWindowLauncherController::IsRegisteredApp(aura::Window* window) { | 182 bool ExtensionAppWindowLauncherController::IsRegisteredApp( |
| 183 aura::Window* window) { |
210 return window_to_app_shelf_id_map_.find(window) != | 184 return window_to_app_shelf_id_map_.find(window) != |
211 window_to_app_shelf_id_map_.end(); | 185 window_to_app_shelf_id_map_.end(); |
212 } | 186 } |
213 | 187 |
214 // Private Methods | 188 // Private Methods |
215 | 189 |
216 AppWindowLauncherItemController* | 190 AppWindowLauncherItemController* |
217 AppWindowLauncherController::ControllerForWindow(aura::Window* window) { | 191 ExtensionAppWindowLauncherController::ControllerForWindow( |
| 192 aura::Window* window) { |
218 WindowToAppShelfIdMap::iterator iter1 = | 193 WindowToAppShelfIdMap::iterator iter1 = |
219 window_to_app_shelf_id_map_.find(window); | 194 window_to_app_shelf_id_map_.find(window); |
220 if (iter1 == window_to_app_shelf_id_map_.end()) | 195 if (iter1 == window_to_app_shelf_id_map_.end()) |
221 return NULL; | 196 return nullptr; |
222 std::string app_shelf_id = iter1->second; | 197 std::string app_shelf_id = iter1->second; |
223 AppControllerMap::iterator iter2 = app_controller_map_.find(app_shelf_id); | 198 AppControllerMap::iterator iter2 = app_controller_map_.find(app_shelf_id); |
224 if (iter2 == app_controller_map_.end()) | 199 if (iter2 == app_controller_map_.end()) |
225 return NULL; | 200 return nullptr; |
226 return iter2->second; | 201 return iter2->second; |
227 } | 202 } |
OLD | NEW |