Chromium Code Reviews| 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 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 OnWindowDestroyed(window->first); | 200 OnWindowDestroyed(window->first); |
| 201 window = window_to_entry_.begin(); | 201 window = window_to_entry_.begin(); |
| 202 } | 202 } |
| 203 | 203 |
| 204 if (ash::WmShell::HasInstance()) { | 204 if (user_manager::UserManager::IsInitialized()) |
| 205 ash::WmShell::Get()->GetSessionStateDelegate()->RemoveSessionStateObserver( | 205 user_manager::UserManager::Get()->RemoveSessionStateObserver(this); |
| 206 this); | |
| 207 } | |
| 208 | 206 |
| 209 // Remove all app observers. | 207 // Remove all app observers. |
| 210 ProfileManager* profile_manager = g_browser_process->profile_manager(); | 208 ProfileManager* profile_manager = g_browser_process->profile_manager(); |
| 211 // might be nullptr in unit tests. | 209 // might be nullptr in unit tests. |
| 212 if (!profile_manager) | 210 if (!profile_manager) |
| 213 return; | 211 return; |
| 214 | 212 |
| 215 std::vector<Profile*> profiles = profile_manager->GetLoadedProfiles(); | 213 std::vector<Profile*> profiles = profile_manager->GetLoadedProfiles(); |
| 216 for (auto it = profiles.begin(); it != profiles.end(); ++it) { | 214 for (auto it = profiles.begin(); it != profiles.end(); ++it) { |
| 217 const AccountId account_id = multi_user_util::GetAccountIdFromProfile(*it); | 215 const AccountId account_id = multi_user_util::GetAccountIdFromProfile(*it); |
| 218 AccountIdToAppWindowObserver::iterator app_observer_iterator = | 216 AccountIdToAppWindowObserver::iterator app_observer_iterator = |
| 219 account_id_to_app_observer_.find(account_id); | 217 account_id_to_app_observer_.find(account_id); |
| 220 if (app_observer_iterator != account_id_to_app_observer_.end()) { | 218 if (app_observer_iterator != account_id_to_app_observer_.end()) { |
| 221 extensions::AppWindowRegistry::Get(*it)->RemoveObserver( | 219 extensions::AppWindowRegistry::Get(*it)->RemoveObserver( |
| 222 app_observer_iterator->second); | 220 app_observer_iterator->second); |
| 223 delete app_observer_iterator->second; | 221 delete app_observer_iterator->second; |
| 224 account_id_to_app_observer_.erase(app_observer_iterator); | 222 account_id_to_app_observer_.erase(app_observer_iterator); |
| 225 } | 223 } |
| 226 } | 224 } |
| 227 } | 225 } |
| 228 | 226 |
| 229 void MultiUserWindowManagerChromeOS::Init() { | 227 void MultiUserWindowManagerChromeOS::Init() { |
| 230 // Since we are setting the SessionStateObserver and adding the user, this | 228 // Since we are setting the SessionStateObserver and adding the user, this |
| 231 // function should get called only once. | 229 // function should get called only once. |
| 232 DCHECK(account_id_to_app_observer_.find(current_account_id_) == | 230 DCHECK(account_id_to_app_observer_.find(current_account_id_) == |
| 233 account_id_to_app_observer_.end()); | 231 account_id_to_app_observer_.end()); |
| 234 | 232 |
| 235 // Add a session state observer to be able to monitor session changes. | 233 // Add a session state observer to be able to monitor session changes. |
| 236 if (ash::WmShell::HasInstance()) { | 234 if (user_manager::UserManager::IsInitialized()) |
| 237 ash::WmShell::Get()->GetSessionStateDelegate()->AddSessionStateObserver( | 235 user_manager::UserManager::Get()->AddSessionStateObserver(this); |
| 238 this); | |
| 239 } | |
| 240 | 236 |
| 241 // The BrowserListObserver would have been better to use then the old | 237 // The BrowserListObserver would have been better to use then the old |
| 242 // notification system, but that observer fires before the window got created. | 238 // notification system, but that observer fires before the window got created. |
| 243 registrar_.Add(this, NOTIFICATION_BROWSER_WINDOW_READY, | 239 registrar_.Add(this, NOTIFICATION_BROWSER_WINDOW_READY, |
| 244 content::NotificationService::AllSources()); | 240 content::NotificationService::AllSources()); |
| 245 | 241 |
| 246 // Add an app window observer & all already running apps. | 242 // Add an app window observer & all already running apps. |
| 247 Profile* profile = | 243 Profile* profile = |
| 248 multi_user_util::GetProfileFromAccountId(current_account_id_); | 244 multi_user_util::GetProfileFromAccountId(current_account_id_); |
| 249 if (profile) | 245 if (profile) |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 297 const AccountId previous_owner(GetUserPresentingWindow(window)); | 293 const AccountId previous_owner(GetUserPresentingWindow(window)); |
| 298 if (!ShowWindowForUserIntern(window, account_id)) | 294 if (!ShowWindowForUserIntern(window, account_id)) |
| 299 return; | 295 return; |
| 300 // The window switched to a new desktop and we have to switch to that desktop, | 296 // 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 | 297 // but only when it was on the visible desktop and the the target is not the |
| 302 // visible desktop. | 298 // visible desktop. |
| 303 if (account_id == current_account_id_ || | 299 if (account_id == current_account_id_ || |
| 304 previous_owner != current_account_id_) | 300 previous_owner != current_account_id_) |
| 305 return; | 301 return; |
| 306 | 302 |
| 307 ash::WmShell::Get()->GetSessionStateDelegate()->SwitchActiveUser(account_id); | 303 SessionControllerClient::DoSwitchActiveUser(account_id); |
| 308 } | 304 } |
| 309 | 305 |
| 310 bool MultiUserWindowManagerChromeOS::AreWindowsSharedAmongUsers() const { | 306 bool MultiUserWindowManagerChromeOS::AreWindowsSharedAmongUsers() const { |
| 311 WindowToEntryMap::const_iterator it = window_to_entry_.begin(); | 307 WindowToEntryMap::const_iterator it = window_to_entry_.begin(); |
| 312 for (; it != window_to_entry_.end(); ++it) { | 308 for (; it != window_to_entry_.end(); ++it) { |
| 313 if (it->second->owner() != it->second->show_for_user()) | 309 if (it->second->owner() != it->second->show_for_user()) |
| 314 return true; | 310 return true; |
| 315 } | 311 } |
| 316 return false; | 312 return false; |
| 317 } | 313 } |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 376 | 372 |
| 377 void MultiUserWindowManagerChromeOS::AddObserver(Observer* observer) { | 373 void MultiUserWindowManagerChromeOS::AddObserver(Observer* observer) { |
| 378 observers_.AddObserver(observer); | 374 observers_.AddObserver(observer); |
| 379 } | 375 } |
| 380 | 376 |
| 381 void MultiUserWindowManagerChromeOS::RemoveObserver(Observer* observer) { | 377 void MultiUserWindowManagerChromeOS::RemoveObserver(Observer* observer) { |
| 382 observers_.RemoveObserver(observer); | 378 observers_.RemoveObserver(observer); |
| 383 } | 379 } |
| 384 | 380 |
| 385 void MultiUserWindowManagerChromeOS::ActiveUserChanged( | 381 void MultiUserWindowManagerChromeOS::ActiveUserChanged( |
| 386 const AccountId& account_id) { | 382 const user_manager::User* active_user) { |
| 387 // This needs to be set before the animation starts. | 383 // This needs to be set before the animation starts. |
| 388 current_account_id_ = account_id; | 384 current_account_id_ = active_user->GetAccountId(); |
| 389 | 385 |
| 390 // Here to avoid a very nasty race condition, we must destruct any previously | 386 // Here to avoid a very nasty race condition, we must destruct any previously |
| 391 // created animation before creating a new one. Otherwise, the newly | 387 // 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 | 388 // 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. | 389 // animation only to be reshown again by the destructor of the old animation. |
| 394 animation_.reset(); | 390 animation_.reset(); |
| 395 animation_.reset(new UserSwitchAnimatorChromeOS( | 391 animation_.reset(new UserSwitchAnimatorChromeOS( |
| 396 this, account_id, GetAdjustedAnimationTimeInMS(kUserFadeTimeMS))); | 392 this, current_account_id_, |
| 393 GetAdjustedAnimationTimeInMS(kUserFadeTimeMS))); | |
| 397 // Call notifier here instead of observing ActiveUserChanged because | 394 // Call notifier here instead of observing ActiveUserChanged because |
| 398 // this must happen after MultiUserWindowManagerChromeOS is notified. | 395 // this must happen after MultiUserWindowManagerChromeOS is notified. |
| 399 ash::WmShell::Get()->media_controller()->RequestCaptureState(); | 396 ash::WmShell::Get()->media_controller()->RequestCaptureState(); |
| 400 } | 397 } |
| 401 | 398 |
| 402 void MultiUserWindowManagerChromeOS::OnWindowDestroyed(aura::Window* window) { | 399 void MultiUserWindowManagerChromeOS::OnWindowDestroyed(aura::Window* window) { |
| 403 if (GetWindowOwner(window).empty()) { | 400 if (GetWindowOwner(window).empty()) { |
| 404 // This must be a window in the transient chain - remove it and its | 401 // This must be a window in the transient chain - remove it and its |
| 405 // children from the owner. | 402 // children from the owner. |
| 406 RemoveTransientOwnerRecursive(window); | 403 RemoveTransientOwnerRecursive(window); |
| 407 return; | 404 return; |
| 408 } | 405 } |
| 406 | |
| 407 window->RemoveObserver(this); | |
|
Mr4D (OOO till 08-26)
2017/02/28 04:56:56
This is odd. Why wasn't this needed before?
xiyuan
2017/02/28 18:35:50
Got the CHECK failure in WindowObserver dtor [1] w
| |
| 409 wm::TransientWindowManager::Get(window)->RemoveObserver(this); | 408 wm::TransientWindowManager::Get(window)->RemoveObserver(this); |
| 410 // Remove the window from the owners list. | 409 // Remove the window from the owners list. |
| 411 delete window_to_entry_[window]; | 410 delete window_to_entry_[window]; |
| 412 window_to_entry_.erase(window); | 411 window_to_entry_.erase(window); |
| 413 | 412 |
| 414 // Notify entry change. | 413 // Notify entry change. |
| 415 for (Observer& observer : observers_) | 414 for (Observer& observer : observers_) |
| 416 observer.OnOwnerEntryRemoved(window); | 415 observer.OnOwnerEntryRemoved(window); |
| 417 } | 416 } |
| 418 | 417 |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 562 if (HasSystemModalTransientChildWindow(window)) { | 561 if (HasSystemModalTransientChildWindow(window)) { |
| 563 // The window is system modal and we need to find the parent which owns | 562 // 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. | 563 // it so that we can switch to the desktop accordingly. |
| 565 AccountId account_id = GetUserPresentingWindow(window); | 564 AccountId account_id = GetUserPresentingWindow(window); |
| 566 if (!account_id.is_valid()) { | 565 if (!account_id.is_valid()) { |
| 567 aura::Window* owning_window = GetOwningWindowInTransientChain(window); | 566 aura::Window* owning_window = GetOwningWindowInTransientChain(window); |
| 568 DCHECK(owning_window); | 567 DCHECK(owning_window); |
| 569 account_id = GetUserPresentingWindow(owning_window); | 568 account_id = GetUserPresentingWindow(owning_window); |
| 570 DCHECK(account_id.is_valid()); | 569 DCHECK(account_id.is_valid()); |
| 571 } | 570 } |
| 572 ash::WmShell::Get()->GetSessionStateDelegate()->SwitchActiveUser( | 571 SessionControllerClient::DoSwitchActiveUser(account_id); |
| 573 account_id); | |
| 574 return; | 572 return; |
| 575 } | 573 } |
| 576 } | 574 } |
| 577 | 575 |
| 578 // To avoid that these commands are recorded as any other commands, we are | 576 // To avoid that these commands are recorded as any other commands, we are |
| 579 // suppressing any window entry changes while this is going on. | 577 // suppressing any window entry changes while this is going on. |
| 580 base::AutoReset<bool> suppressor(&suppress_visibility_changes_, true); | 578 base::AutoReset<bool> suppressor(&suppress_visibility_changes_, true); |
| 581 | 579 |
| 582 if (visible) | 580 if (visible) |
| 583 ShowWithTransientChildrenRecursive(window, animation_time_in_ms); | 581 ShowWithTransientChildrenRecursive(window, animation_time_in_ms); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 707 window->Hide(); | 705 window->Hide(); |
| 708 } | 706 } |
| 709 | 707 |
| 710 int MultiUserWindowManagerChromeOS::GetAdjustedAnimationTimeInMS( | 708 int MultiUserWindowManagerChromeOS::GetAdjustedAnimationTimeInMS( |
| 711 int default_time_in_ms) const { | 709 int default_time_in_ms) const { |
| 712 return animation_speed_ == ANIMATION_SPEED_NORMAL ? default_time_in_ms : | 710 return animation_speed_ == ANIMATION_SPEED_NORMAL ? default_time_in_ms : |
| 713 (animation_speed_ == ANIMATION_SPEED_FAST ? 10 : 0); | 711 (animation_speed_ == ANIMATION_SPEED_FAST ? 10 : 0); |
| 714 } | 712 } |
| 715 | 713 |
| 716 } // namespace chrome | 714 } // namespace chrome |
| OLD | NEW |