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 "chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h" | 5 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h" |
6 | 6 |
7 #include "apps/shell_window.h" | 7 #include "apps/shell_window.h" |
8 #include "apps/shell_window_registry.h" | 8 #include "apps/shell_window_registry.h" |
9 #include "ash/ash_switches.h" | 9 #include "ash/ash_switches.h" |
10 #include "ash/multi_profile_uma.h" | 10 #include "ash/multi_profile_uma.h" |
11 #include "ash/session_state_delegate.h" | 11 #include "ash/session_state_delegate.h" |
12 #include "ash/shell.h" | 12 #include "ash/shell.h" |
13 #include "ash/shell_delegate.h" | 13 #include "ash/shell_delegate.h" |
14 #include "ash/shell_window_ids.h" | 14 #include "ash/shell_window_ids.h" |
15 #include "ash/wm/mru_window_tracker.h" | 15 #include "ash/wm/mru_window_tracker.h" |
16 #include "ash/wm/window_positioner.h" | 16 #include "ash/wm/window_positioner.h" |
17 #include "ash/wm/window_state.h" | 17 #include "ash/wm/window_state.h" |
18 #include "base/auto_reset.h" | 18 #include "base/auto_reset.h" |
19 #include "base/message_loop/message_loop.h" | 19 #include "base/message_loop/message_loop.h" |
20 #include "base/strings/string_util.h" | 20 #include "base/strings/string_util.h" |
21 #include "chrome/browser/browser_process.h" | 21 #include "chrome/browser/browser_process.h" |
22 #include "chrome/browser/chrome_notification_types.h" | 22 #include "chrome/browser/chrome_notification_types.h" |
23 #include "chrome/browser/chromeos/login/user_manager.h" | 23 #include "chrome/browser/chromeos/login/user_manager.h" |
24 #include "chrome/browser/profiles/profile.h" | 24 #include "chrome/browser/profiles/profile.h" |
25 #include "chrome/browser/profiles/profile_manager.h" | 25 #include "chrome/browser/profiles/profile_manager.h" |
| 26 #include "chrome/browser/ui/ash/multi_user/multi_user_notification_blocker_chrom
eos.h" |
26 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h" | 27 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h" |
27 #include "chrome/browser/ui/browser.h" | 28 #include "chrome/browser/ui/browser.h" |
28 #include "chrome/browser/ui/browser_finder.h" | 29 #include "chrome/browser/ui/browser_finder.h" |
29 #include "chrome/browser/ui/browser_list.h" | 30 #include "chrome/browser/ui/browser_list.h" |
30 #include "chrome/browser/ui/browser_window.h" | 31 #include "chrome/browser/ui/browser_window.h" |
31 #include "content/public/browser/notification_service.h" | 32 #include "content/public/browser/notification_service.h" |
32 #include "google_apis/gaia/gaia_auth_util.h" | 33 #include "google_apis/gaia/gaia_auth_util.h" |
33 #include "ui/aura/client/activation_client.h" | 34 #include "ui/aura/client/activation_client.h" |
34 #include "ui/aura/client/aura_constants.h" | 35 #include "ui/aura/client/aura_constants.h" |
35 #include "ui/aura/root_window.h" | 36 #include "ui/aura/root_window.h" |
36 #include "ui/aura/window.h" | 37 #include "ui/aura/window.h" |
37 #include "ui/base/ui_base_types.h" | 38 #include "ui/base/ui_base_types.h" |
38 #include "ui/events/event.h" | 39 #include "ui/events/event.h" |
| 40 #include "ui/message_center/message_center.h" |
39 #include "ui/views/corewm/window_util.h" | 41 #include "ui/views/corewm/window_util.h" |
40 | 42 |
41 namespace { | 43 namespace { |
42 | 44 |
43 // Checks if a given event is a user event. | 45 // Checks if a given event is a user event. |
44 bool IsUserEvent(ui::Event* e) { | 46 bool IsUserEvent(ui::Event* e) { |
45 if (e) { | 47 if (e) { |
46 ui::EventType type = e->type(); | 48 ui::EventType type = e->type(); |
47 if (type != ui::ET_CANCEL_MODE && | 49 if (type != ui::ET_CANCEL_MODE && |
48 type != ui::ET_UMA_DATA && | 50 type != ui::ET_UMA_DATA && |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 | 172 |
171 private: | 173 private: |
172 std::string user_id_; | 174 std::string user_id_; |
173 | 175 |
174 DISALLOW_COPY_AND_ASSIGN(AppObserver); | 176 DISALLOW_COPY_AND_ASSIGN(AppObserver); |
175 }; | 177 }; |
176 | 178 |
177 MultiUserWindowManagerChromeOS::MultiUserWindowManagerChromeOS( | 179 MultiUserWindowManagerChromeOS::MultiUserWindowManagerChromeOS( |
178 const std::string& current_user_id) | 180 const std::string& current_user_id) |
179 : current_user_id_(current_user_id), | 181 : current_user_id_(current_user_id), |
| 182 notification_blocker_(new MultiUserNotificationBlockerChromeOS( |
| 183 message_center::MessageCenter::Get(), this)), |
180 suppress_visibility_changes_(false) { | 184 suppress_visibility_changes_(false) { |
181 // Add a session state observer to be able to monitor session changes. | 185 // Add a session state observer to be able to monitor session changes. |
182 if (ash::Shell::HasInstance()) | 186 if (ash::Shell::HasInstance()) |
183 ash::Shell::GetInstance()->session_state_delegate()-> | 187 ash::Shell::GetInstance()->session_state_delegate()-> |
184 AddSessionStateObserver(this); | 188 AddSessionStateObserver(this); |
185 | 189 |
186 // The BrowserListObserver would have been better to use then the old | 190 // The BrowserListObserver would have been better to use then the old |
187 // notification system, but that observer fires before the window got created. | 191 // notification system, but that observer fires before the window got created. |
188 registrar_.Add(this, NOTIFICATION_BROWSER_WINDOW_READY, | 192 registrar_.Add(this, NOTIFICATION_BROWSER_WINDOW_READY, |
189 content::NotificationService::AllSources()); | 193 content::NotificationService::AllSources()); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 | 245 |
242 // Check if this window was created due to a user interaction. If it was, | 246 // Check if this window was created due to a user interaction. If it was, |
243 // transfer it to the current user. | 247 // transfer it to the current user. |
244 if (IsProcessingUserEvent()) | 248 if (IsProcessingUserEvent()) |
245 window_to_entry_[window]->set_show_for_user(current_user_id_); | 249 window_to_entry_[window]->set_show_for_user(current_user_id_); |
246 | 250 |
247 // Add all transient children to our set of windows. Note that the function | 251 // Add all transient children to our set of windows. Note that the function |
248 // will add the children but not the owner to the transient children map. | 252 // will add the children but not the owner to the transient children map. |
249 AddTransientOwnerRecursive(window, window); | 253 AddTransientOwnerRecursive(window, window); |
250 | 254 |
| 255 // Right now only |notification_blocker_| needs to know when the list of |
| 256 // owners may change. |
| 257 // TODO(skuhne): replace this by observer when another one needs this event. |
| 258 notification_blocker_->UpdateWindowOwners(); |
| 259 |
251 if (!IsWindowOnDesktopOfUser(window, current_user_id_)) | 260 if (!IsWindowOnDesktopOfUser(window, current_user_id_)) |
252 SetWindowVisibility(window, false); | 261 SetWindowVisibility(window, false); |
253 } | 262 } |
254 | 263 |
255 const std::string& MultiUserWindowManagerChromeOS::GetWindowOwner( | 264 const std::string& MultiUserWindowManagerChromeOS::GetWindowOwner( |
256 aura::Window* window) { | 265 aura::Window* window) { |
257 WindowToEntryMap::iterator it = window_to_entry_.find(window); | 266 WindowToEntryMap::iterator it = window_to_entry_.find(window); |
258 return it != window_to_entry_.end() ? it->second->owner() | 267 return it != window_to_entry_.end() ? it->second->owner() |
259 : base::EmptyString(); | 268 : base::EmptyString(); |
260 } | 269 } |
(...skipping 27 matching lines...) Expand all Loading... |
288 it->second->set_show_for_user(user_id); | 297 it->second->set_show_for_user(user_id); |
289 | 298 |
290 // Show the window if the added user is the current one. | 299 // Show the window if the added user is the current one. |
291 if (user_id == current_user_id_) { | 300 if (user_id == current_user_id_) { |
292 // Only show the window if it should be shown according to its state. | 301 // Only show the window if it should be shown according to its state. |
293 if (it->second->show()) | 302 if (it->second->show()) |
294 SetWindowVisibility(window, true); | 303 SetWindowVisibility(window, true); |
295 } else { | 304 } else { |
296 SetWindowVisibility(window, false); | 305 SetWindowVisibility(window, false); |
297 } | 306 } |
| 307 |
| 308 // TODO(skuhne): replace this by observer when another one needs this event. |
| 309 notification_blocker_->UpdateWindowOwners(); |
298 } | 310 } |
299 | 311 |
300 bool MultiUserWindowManagerChromeOS::AreWindowsSharedAmongUsers() { | 312 bool MultiUserWindowManagerChromeOS::AreWindowsSharedAmongUsers() { |
301 WindowToEntryMap::iterator it = window_to_entry_.begin(); | 313 WindowToEntryMap::iterator it = window_to_entry_.begin(); |
302 for (; it != window_to_entry_.end(); ++it) { | 314 for (; it != window_to_entry_.end(); ++it) { |
303 if (it->second->owner() != it->second->show_for_user()) | 315 if (it->second->owner() != it->second->show_for_user()) |
304 return true; | 316 return true; |
305 } | 317 } |
306 return false; | 318 return false; |
307 } | 319 } |
308 | 320 |
| 321 void MultiUserWindowManagerChromeOS::GetOwnersOfVisibleWindows( |
| 322 std::set<std::string>* user_ids) { |
| 323 for (WindowToEntryMap::iterator it = window_to_entry_.begin(); |
| 324 it != window_to_entry_.end(); ++it) { |
| 325 if (it->first->IsVisible()) |
| 326 user_ids->insert(it->second->owner()); |
| 327 } |
| 328 } |
| 329 |
309 bool MultiUserWindowManagerChromeOS::IsWindowOnDesktopOfUser( | 330 bool MultiUserWindowManagerChromeOS::IsWindowOnDesktopOfUser( |
310 aura::Window* window, | 331 aura::Window* window, |
311 const std::string& user_id) { | 332 const std::string& user_id) { |
312 const std::string& presenting_user = GetUserPresentingWindow(window); | 333 const std::string& presenting_user = GetUserPresentingWindow(window); |
313 return presenting_user.empty() || presenting_user == user_id; | 334 return presenting_user.empty() || presenting_user == user_id; |
314 } | 335 } |
315 | 336 |
316 const std::string& MultiUserWindowManagerChromeOS::GetUserPresentingWindow( | 337 const std::string& MultiUserWindowManagerChromeOS::GetUserPresentingWindow( |
317 aura::Window* window) { | 338 aura::Window* window) { |
318 WindowToEntryMap::iterator it = window_to_entry_.find(window); | 339 WindowToEntryMap::iterator it = window_to_entry_.find(window); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
399 ash::wm::WindowState* window_state = ash::wm::GetWindowState(window); | 420 ash::wm::WindowState* window_state = ash::wm::GetWindowState(window); |
400 if (IsWindowOnDesktopOfUser(window, user_id) && | 421 if (IsWindowOnDesktopOfUser(window, user_id) && |
401 !window_state->IsMinimized()) { | 422 !window_state->IsMinimized()) { |
402 aura::client::ActivationClient* client = | 423 aura::client::ActivationClient* client = |
403 aura::client::GetActivationClient(window->GetRootWindow()); | 424 aura::client::GetActivationClient(window->GetRootWindow()); |
404 // Several unit tests come here without an activation client. | 425 // Several unit tests come here without an activation client. |
405 if (client) | 426 if (client) |
406 client->ActivateWindow(window); | 427 client->ActivateWindow(window); |
407 } | 428 } |
408 } | 429 } |
| 430 |
| 431 // This is called directly here to make sure notification_blocker will see the |
| 432 // new window status. |
| 433 notification_blocker_->ActiveUserChanged(user_id); |
409 } | 434 } |
410 | 435 |
411 void MultiUserWindowManagerChromeOS::OnWindowDestroyed(aura::Window* window) { | 436 void MultiUserWindowManagerChromeOS::OnWindowDestroyed(aura::Window* window) { |
412 if (GetWindowOwner(window).empty()) { | 437 if (GetWindowOwner(window).empty()) { |
413 // This must be a window in the transient chain - remove it and its | 438 // This must be a window in the transient chain - remove it and its |
414 // children from the owner. | 439 // children from the owner. |
415 RemoveTransientOwnerRecursive(window); | 440 RemoveTransientOwnerRecursive(window); |
416 return; | 441 return; |
417 } | 442 } |
418 // Remove the state and the window observer. | 443 // Remove the state and the window observer. |
419 ash::wm::GetWindowState(window)->RemoveObserver(this); | 444 ash::wm::GetWindowState(window)->RemoveObserver(this); |
420 // Remove the window from the owners list. | 445 // Remove the window from the owners list. |
421 delete window_to_entry_[window]; | 446 delete window_to_entry_[window]; |
422 window_to_entry_.erase(window); | 447 window_to_entry_.erase(window); |
| 448 // TODO(skuhne): replace this by observer when another one needs this event. |
| 449 notification_blocker_->UpdateWindowOwners(); |
423 } | 450 } |
424 | 451 |
425 void MultiUserWindowManagerChromeOS::OnWindowVisibilityChanging( | 452 void MultiUserWindowManagerChromeOS::OnWindowVisibilityChanging( |
426 aura::Window* window, bool visible) { | 453 aura::Window* window, bool visible) { |
427 // This command gets called first and immediately when show or hide gets | 454 // This command gets called first and immediately when show or hide gets |
428 // called. We remember here the desired state for restoration IF we were | 455 // called. We remember here the desired state for restoration IF we were |
429 // not ourselves issuing the call. | 456 // not ourselves issuing the call. |
430 // Note also that using the OnWindowVisibilityChanged callback cannot be | 457 // Note also that using the OnWindowVisibilityChanged callback cannot be |
431 // used for this. | 458 // used for this. |
432 if (suppress_visibility_changes_) | 459 if (suppress_visibility_changes_) |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
638 // To prevent these commands from being recorded as any other commands, we | 665 // To prevent these commands from being recorded as any other commands, we |
639 // are suppressing any window entry changes while this is going on. | 666 // are suppressing any window entry changes while this is going on. |
640 // Instead of calling SetWindowVisible, only show gets called here since all | 667 // Instead of calling SetWindowVisible, only show gets called here since all |
641 // dependents have been shown previously already. | 668 // dependents have been shown previously already. |
642 base::AutoReset<bool> suppressor(&suppress_visibility_changes_, true); | 669 base::AutoReset<bool> suppressor(&suppress_visibility_changes_, true); |
643 window->Show(); | 670 window->Show(); |
644 } | 671 } |
645 } | 672 } |
646 | 673 |
647 } // namespace chrome | 674 } // namespace chrome |
OLD | NEW |