Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(734)

Side by Side Diff: chrome/browser/ui/ash/launcher/app_window_launcher_controller.cc

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

Powered by Google App Engine
This is Rietveld 408576698