| 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 |