| 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 "ash/common/media_controller.h" | 7 #include "ash/common/media_controller.h" |
| 8 #include "ash/common/multi_profile_uma.h" | 8 #include "ash/common/multi_profile_uma.h" |
| 9 #include "ash/common/session/session_state_delegate.h" | |
| 10 #include "ash/common/wm/maximize_mode/maximize_mode_controller.h" | 9 #include "ash/common/wm/maximize_mode/maximize_mode_controller.h" |
| 11 #include "ash/common/wm/window_state.h" | 10 #include "ash/common/wm/window_state.h" |
| 12 #include "ash/common/wm_shell.h" | 11 #include "ash/common/wm_shell.h" |
| 13 #include "ash/common/wm_window.h" | 12 #include "ash/common/wm_window.h" |
| 14 #include "ash/public/cpp/shell_window_ids.h" | 13 #include "ash/public/cpp/shell_window_ids.h" |
| 15 #include "ash/shell.h" | 14 #include "ash/shell.h" |
| 16 #include "ash/wm/window_state_aura.h" | 15 #include "ash/wm/window_state_aura.h" |
| 17 #include "base/auto_reset.h" | 16 #include "base/auto_reset.h" |
| 18 #include "base/macros.h" | 17 #include "base/macros.h" |
| 19 #include "base/message_loop/message_loop.h" | 18 #include "base/message_loop/message_loop.h" |
| 20 #include "base/strings/string_util.h" | 19 #include "base/strings/string_util.h" |
| 21 #include "chrome/browser/browser_process.h" | 20 #include "chrome/browser/browser_process.h" |
| 22 #include "chrome/browser/chrome_notification_types.h" | 21 #include "chrome/browser/chrome_notification_types.h" |
| 23 #include "chrome/browser/profiles/profile.h" | 22 #include "chrome/browser/profiles/profile.h" |
| 24 #include "chrome/browser/profiles/profile_manager.h" | 23 #include "chrome/browser/profiles/profile_manager.h" |
| 25 #include "chrome/browser/ui/ash/multi_user/multi_user_notification_blocker_chrom
eos.h" | 24 #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" | 25 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h" |
| 27 #include "chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.h" | 26 #include "chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.h" |
| 27 #include "chrome/browser/ui/ash/session_controller_client.h" |
| 28 #include "chrome/browser/ui/browser.h" | 28 #include "chrome/browser/ui/browser.h" |
| 29 #include "chrome/browser/ui/browser_finder.h" | 29 #include "chrome/browser/ui/browser_finder.h" |
| 30 #include "chrome/browser/ui/browser_list.h" | 30 #include "chrome/browser/ui/browser_list.h" |
| 31 #include "chrome/browser/ui/browser_window.h" | 31 #include "chrome/browser/ui/browser_window.h" |
| 32 #include "content/public/browser/notification_service.h" | 32 #include "content/public/browser/notification_service.h" |
| 33 #include "extensions/browser/app_window/app_window.h" | 33 #include "extensions/browser/app_window/app_window.h" |
| 34 #include "extensions/browser/app_window/app_window_registry.h" | 34 #include "extensions/browser/app_window/app_window_registry.h" |
| 35 #include "ui/aura/client/aura_constants.h" | 35 #include "ui/aura/client/aura_constants.h" |
| 36 #include "ui/aura/window.h" | 36 #include "ui/aura/window.h" |
| 37 #include "ui/aura/window_event_dispatcher.h" | 37 #include "ui/aura/window_event_dispatcher.h" |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 MultiUserWindowManagerChromeOS::~MultiUserWindowManagerChromeOS() { | 190 MultiUserWindowManagerChromeOS::~MultiUserWindowManagerChromeOS() { |
| 191 // When the MultiUserWindowManager gets destroyed, ash::Shell is mostly gone. | 191 // When the MultiUserWindowManager gets destroyed, ash::Shell is mostly gone. |
| 192 // As such we should not try to finalize any outstanding user animations. | 192 // As such we should not try to finalize any outstanding user animations. |
| 193 // Note that the destruction of the object can be done later. | 193 // Note that the destruction of the object can be done later. |
| 194 if (animation_.get()) | 194 if (animation_.get()) |
| 195 animation_->CancelAnimation(); | 195 animation_->CancelAnimation(); |
| 196 | 196 |
| 197 // Remove all window observers. | 197 // Remove all window observers. |
| 198 WindowToEntryMap::iterator window = window_to_entry_.begin(); | 198 WindowToEntryMap::iterator window = window_to_entry_.begin(); |
| 199 while (window != window_to_entry_.end()) { | 199 while (window != window_to_entry_.end()) { |
| 200 // Explicitly remove this from window observer list since OnWindowDestroyed |
| 201 // no longer does that. |
| 202 window->first->RemoveObserver(this); |
| 200 OnWindowDestroyed(window->first); | 203 OnWindowDestroyed(window->first); |
| 201 window = window_to_entry_.begin(); | 204 window = window_to_entry_.begin(); |
| 202 } | 205 } |
| 203 | 206 |
| 204 if (ash::WmShell::HasInstance()) { | 207 if (user_manager::UserManager::IsInitialized()) |
| 205 ash::WmShell::Get()->GetSessionStateDelegate()->RemoveSessionStateObserver( | 208 user_manager::UserManager::Get()->RemoveSessionStateObserver(this); |
| 206 this); | |
| 207 } | |
| 208 | 209 |
| 209 // Remove all app observers. | 210 // Remove all app observers. |
| 210 ProfileManager* profile_manager = g_browser_process->profile_manager(); | 211 ProfileManager* profile_manager = g_browser_process->profile_manager(); |
| 211 // might be nullptr in unit tests. | 212 // might be nullptr in unit tests. |
| 212 if (!profile_manager) | 213 if (!profile_manager) |
| 213 return; | 214 return; |
| 214 | 215 |
| 215 std::vector<Profile*> profiles = profile_manager->GetLoadedProfiles(); | 216 std::vector<Profile*> profiles = profile_manager->GetLoadedProfiles(); |
| 216 for (auto it = profiles.begin(); it != profiles.end(); ++it) { | 217 for (auto it = profiles.begin(); it != profiles.end(); ++it) { |
| 217 const AccountId account_id = multi_user_util::GetAccountIdFromProfile(*it); | 218 const AccountId account_id = multi_user_util::GetAccountIdFromProfile(*it); |
| 218 AccountIdToAppWindowObserver::iterator app_observer_iterator = | 219 AccountIdToAppWindowObserver::iterator app_observer_iterator = |
| 219 account_id_to_app_observer_.find(account_id); | 220 account_id_to_app_observer_.find(account_id); |
| 220 if (app_observer_iterator != account_id_to_app_observer_.end()) { | 221 if (app_observer_iterator != account_id_to_app_observer_.end()) { |
| 221 extensions::AppWindowRegistry::Get(*it)->RemoveObserver( | 222 extensions::AppWindowRegistry::Get(*it)->RemoveObserver( |
| 222 app_observer_iterator->second); | 223 app_observer_iterator->second); |
| 223 delete app_observer_iterator->second; | 224 delete app_observer_iterator->second; |
| 224 account_id_to_app_observer_.erase(app_observer_iterator); | 225 account_id_to_app_observer_.erase(app_observer_iterator); |
| 225 } | 226 } |
| 226 } | 227 } |
| 227 } | 228 } |
| 228 | 229 |
| 229 void MultiUserWindowManagerChromeOS::Init() { | 230 void MultiUserWindowManagerChromeOS::Init() { |
| 230 // Since we are setting the SessionStateObserver and adding the user, this | 231 // Since we are setting the SessionStateObserver and adding the user, this |
| 231 // function should get called only once. | 232 // function should get called only once. |
| 232 DCHECK(account_id_to_app_observer_.find(current_account_id_) == | 233 DCHECK(account_id_to_app_observer_.find(current_account_id_) == |
| 233 account_id_to_app_observer_.end()); | 234 account_id_to_app_observer_.end()); |
| 234 | 235 |
| 235 // Add a session state observer to be able to monitor session changes. | 236 // Add a session state observer to be able to monitor session changes. |
| 236 if (ash::WmShell::HasInstance()) { | 237 if (user_manager::UserManager::IsInitialized()) |
| 237 ash::WmShell::Get()->GetSessionStateDelegate()->AddSessionStateObserver( | 238 user_manager::UserManager::Get()->AddSessionStateObserver(this); |
| 238 this); | |
| 239 } | |
| 240 | 239 |
| 241 // The BrowserListObserver would have been better to use then the old | 240 // The BrowserListObserver would have been better to use then the old |
| 242 // notification system, but that observer fires before the window got created. | 241 // notification system, but that observer fires before the window got created. |
| 243 registrar_.Add(this, NOTIFICATION_BROWSER_WINDOW_READY, | 242 registrar_.Add(this, NOTIFICATION_BROWSER_WINDOW_READY, |
| 244 content::NotificationService::AllSources()); | 243 content::NotificationService::AllSources()); |
| 245 | 244 |
| 246 // Add an app window observer & all already running apps. | 245 // Add an app window observer & all already running apps. |
| 247 Profile* profile = | 246 Profile* profile = |
| 248 multi_user_util::GetProfileFromAccountId(current_account_id_); | 247 multi_user_util::GetProfileFromAccountId(current_account_id_); |
| 249 if (profile) | 248 if (profile) |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 const AccountId previous_owner(GetUserPresentingWindow(window)); | 296 const AccountId previous_owner(GetUserPresentingWindow(window)); |
| 298 if (!ShowWindowForUserIntern(window, account_id)) | 297 if (!ShowWindowForUserIntern(window, account_id)) |
| 299 return; | 298 return; |
| 300 // The window switched to a new desktop and we have to switch to that desktop, | 299 // The window switched to a new desktop and we have to switch to that desktop, |
| 301 // but only when it was on the visible desktop and the the target is not the | 300 // but only when it was on the visible desktop and the the target is not the |
| 302 // visible desktop. | 301 // visible desktop. |
| 303 if (account_id == current_account_id_ || | 302 if (account_id == current_account_id_ || |
| 304 previous_owner != current_account_id_) | 303 previous_owner != current_account_id_) |
| 305 return; | 304 return; |
| 306 | 305 |
| 307 ash::WmShell::Get()->GetSessionStateDelegate()->SwitchActiveUser(account_id); | 306 SessionControllerClient::DoSwitchActiveUser(account_id); |
| 308 } | 307 } |
| 309 | 308 |
| 310 bool MultiUserWindowManagerChromeOS::AreWindowsSharedAmongUsers() const { | 309 bool MultiUserWindowManagerChromeOS::AreWindowsSharedAmongUsers() const { |
| 311 WindowToEntryMap::const_iterator it = window_to_entry_.begin(); | 310 WindowToEntryMap::const_iterator it = window_to_entry_.begin(); |
| 312 for (; it != window_to_entry_.end(); ++it) { | 311 for (; it != window_to_entry_.end(); ++it) { |
| 313 if (it->second->owner() != it->second->show_for_user()) | 312 if (it->second->owner() != it->second->show_for_user()) |
| 314 return true; | 313 return true; |
| 315 } | 314 } |
| 316 return false; | 315 return false; |
| 317 } | 316 } |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 | 375 |
| 377 void MultiUserWindowManagerChromeOS::AddObserver(Observer* observer) { | 376 void MultiUserWindowManagerChromeOS::AddObserver(Observer* observer) { |
| 378 observers_.AddObserver(observer); | 377 observers_.AddObserver(observer); |
| 379 } | 378 } |
| 380 | 379 |
| 381 void MultiUserWindowManagerChromeOS::RemoveObserver(Observer* observer) { | 380 void MultiUserWindowManagerChromeOS::RemoveObserver(Observer* observer) { |
| 382 observers_.RemoveObserver(observer); | 381 observers_.RemoveObserver(observer); |
| 383 } | 382 } |
| 384 | 383 |
| 385 void MultiUserWindowManagerChromeOS::ActiveUserChanged( | 384 void MultiUserWindowManagerChromeOS::ActiveUserChanged( |
| 386 const AccountId& account_id) { | 385 const user_manager::User* active_user) { |
| 387 // This needs to be set before the animation starts. | 386 // This needs to be set before the animation starts. |
| 388 current_account_id_ = account_id; | 387 current_account_id_ = active_user->GetAccountId(); |
| 389 | 388 |
| 390 // Here to avoid a very nasty race condition, we must destruct any previously | 389 // Here to avoid a very nasty race condition, we must destruct any previously |
| 391 // created animation before creating a new one. Otherwise, the newly | 390 // created animation before creating a new one. Otherwise, the newly |
| 392 // constructed will hide all windows of the old user in the first step of the | 391 // constructed will hide all windows of the old user in the first step of the |
| 393 // animation only to be reshown again by the destructor of the old animation. | 392 // animation only to be reshown again by the destructor of the old animation. |
| 394 animation_.reset(); | 393 animation_.reset(); |
| 395 animation_.reset(new UserSwitchAnimatorChromeOS( | 394 animation_.reset(new UserSwitchAnimatorChromeOS( |
| 396 this, account_id, GetAdjustedAnimationTimeInMS(kUserFadeTimeMS))); | 395 this, current_account_id_, |
| 396 GetAdjustedAnimationTimeInMS(kUserFadeTimeMS))); |
| 397 // Call notifier here instead of observing ActiveUserChanged because | 397 // Call notifier here instead of observing ActiveUserChanged because |
| 398 // this must happen after MultiUserWindowManagerChromeOS is notified. | 398 // this must happen after MultiUserWindowManagerChromeOS is notified. |
| 399 ash::WmShell::Get()->media_controller()->RequestCaptureState(); | 399 ash::WmShell::Get()->media_controller()->RequestCaptureState(); |
| 400 } | 400 } |
| 401 | 401 |
| 402 void MultiUserWindowManagerChromeOS::OnWindowDestroyed(aura::Window* window) { | 402 void MultiUserWindowManagerChromeOS::OnWindowDestroyed(aura::Window* window) { |
| 403 if (GetWindowOwner(window).empty()) { | 403 if (GetWindowOwner(window).empty()) { |
| 404 // This must be a window in the transient chain - remove it and its | 404 // This must be a window in the transient chain - remove it and its |
| 405 // children from the owner. | 405 // children from the owner. |
| 406 RemoveTransientOwnerRecursive(window); | 406 RemoveTransientOwnerRecursive(window); |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 562 if (HasSystemModalTransientChildWindow(window)) { | 562 if (HasSystemModalTransientChildWindow(window)) { |
| 563 // The window is system modal and we need to find the parent which owns | 563 // The window is system modal and we need to find the parent which owns |
| 564 // it so that we can switch to the desktop accordingly. | 564 // it so that we can switch to the desktop accordingly. |
| 565 AccountId account_id = GetUserPresentingWindow(window); | 565 AccountId account_id = GetUserPresentingWindow(window); |
| 566 if (!account_id.is_valid()) { | 566 if (!account_id.is_valid()) { |
| 567 aura::Window* owning_window = GetOwningWindowInTransientChain(window); | 567 aura::Window* owning_window = GetOwningWindowInTransientChain(window); |
| 568 DCHECK(owning_window); | 568 DCHECK(owning_window); |
| 569 account_id = GetUserPresentingWindow(owning_window); | 569 account_id = GetUserPresentingWindow(owning_window); |
| 570 DCHECK(account_id.is_valid()); | 570 DCHECK(account_id.is_valid()); |
| 571 } | 571 } |
| 572 ash::WmShell::Get()->GetSessionStateDelegate()->SwitchActiveUser( | 572 SessionControllerClient::DoSwitchActiveUser(account_id); |
| 573 account_id); | |
| 574 return; | 573 return; |
| 575 } | 574 } |
| 576 } | 575 } |
| 577 | 576 |
| 578 // To avoid that these commands are recorded as any other commands, we are | 577 // To avoid that these commands are recorded as any other commands, we are |
| 579 // suppressing any window entry changes while this is going on. | 578 // suppressing any window entry changes while this is going on. |
| 580 base::AutoReset<bool> suppressor(&suppress_visibility_changes_, true); | 579 base::AutoReset<bool> suppressor(&suppress_visibility_changes_, true); |
| 581 | 580 |
| 582 if (visible) | 581 if (visible) |
| 583 ShowWithTransientChildrenRecursive(window, animation_time_in_ms); | 582 ShowWithTransientChildrenRecursive(window, animation_time_in_ms); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 707 window->Hide(); | 706 window->Hide(); |
| 708 } | 707 } |
| 709 | 708 |
| 710 int MultiUserWindowManagerChromeOS::GetAdjustedAnimationTimeInMS( | 709 int MultiUserWindowManagerChromeOS::GetAdjustedAnimationTimeInMS( |
| 711 int default_time_in_ms) const { | 710 int default_time_in_ms) const { |
| 712 return animation_speed_ == ANIMATION_SPEED_NORMAL ? default_time_in_ms : | 711 return animation_speed_ == ANIMATION_SPEED_NORMAL ? default_time_in_ms : |
| 713 (animation_speed_ == ANIMATION_SPEED_FAST ? 10 : 0); | 712 (animation_speed_ == ANIMATION_SPEED_FAST ? 10 : 0); |
| 714 } | 713 } |
| 715 | 714 |
| 716 } // namespace chrome | 715 } // namespace chrome |
| OLD | NEW |