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

Side by Side Diff: chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.cc

Issue 227243002: Revert of Improving the user transition to add special cases for maximized windows and make the transition "m… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 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 | Annotate | Revision Log
OLDNEW
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/app_window.h" 7 #include "apps/app_window.h"
8 #include "apps/app_window_registry.h" 8 #include "apps/app_window_registry.h"
9 #include "ash/ash_switches.h" 9 #include "ash/ash_switches.h"
10 #include "ash/desktop_background/user_wallpaper_delegate.h"
10 #include "ash/multi_profile_uma.h" 11 #include "ash/multi_profile_uma.h"
11 #include "ash/root_window_controller.h" 12 #include "ash/root_window_controller.h"
12 #include "ash/session_state_delegate.h" 13 #include "ash/session_state_delegate.h"
13 #include "ash/shelf/shelf.h" 14 #include "ash/shelf/shelf.h"
15 #include "ash/shelf/shelf_layout_manager.h"
14 #include "ash/shell.h" 16 #include "ash/shell.h"
15 #include "ash/shell_delegate.h" 17 #include "ash/shell_delegate.h"
16 #include "ash/shell_window_ids.h" 18 #include "ash/shell_window_ids.h"
19 #include "ash/wm/mru_window_tracker.h"
20 #include "ash/wm/window_positioner.h"
17 #include "ash/wm/window_state.h" 21 #include "ash/wm/window_state.h"
18 #include "base/auto_reset.h" 22 #include "base/auto_reset.h"
19 #include "base/message_loop/message_loop.h" 23 #include "base/message_loop/message_loop.h"
20 #include "base/strings/string_util.h" 24 #include "base/strings/string_util.h"
21 #include "chrome/browser/browser_process.h" 25 #include "chrome/browser/browser_process.h"
22 #include "chrome/browser/chrome_notification_types.h" 26 #include "chrome/browser/chrome_notification_types.h"
23 #include "chrome/browser/chromeos/login/user_manager.h" 27 #include "chrome/browser/chromeos/login/user_manager.h"
28 #include "chrome/browser/chromeos/login/wallpaper_manager.h"
24 #include "chrome/browser/profiles/profile.h" 29 #include "chrome/browser/profiles/profile.h"
25 #include "chrome/browser/profiles/profile_manager.h" 30 #include "chrome/browser/profiles/profile_manager.h"
31 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
26 #include "chrome/browser/ui/ash/multi_user/multi_user_notification_blocker_chrom eos.h" 32 #include "chrome/browser/ui/ash/multi_user/multi_user_notification_blocker_chrom eos.h"
27 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h" 33 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
28 #include "chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.h"
29 #include "chrome/browser/ui/browser.h" 34 #include "chrome/browser/ui/browser.h"
30 #include "chrome/browser/ui/browser_finder.h" 35 #include "chrome/browser/ui/browser_finder.h"
31 #include "chrome/browser/ui/browser_list.h" 36 #include "chrome/browser/ui/browser_list.h"
32 #include "chrome/browser/ui/browser_window.h" 37 #include "chrome/browser/ui/browser_window.h"
33 #include "content/public/browser/notification_service.h" 38 #include "content/public/browser/notification_service.h"
34 #include "google_apis/gaia/gaia_auth_util.h" 39 #include "google_apis/gaia/gaia_auth_util.h"
35 #include "ui/aura/client/aura_constants.h" 40 #include "ui/aura/client/aura_constants.h"
36 #include "ui/aura/window.h" 41 #include "ui/aura/window.h"
37 #include "ui/aura/window_event_dispatcher.h" 42 #include "ui/aura/window_event_dispatcher.h"
38 #include "ui/base/ui_base_types.h" 43 #include "ui/base/ui_base_types.h"
39 #include "ui/events/event.h" 44 #include "ui/events/event.h"
40 #include "ui/message_center/message_center.h" 45 #include "ui/message_center/message_center.h"
41 #include "ui/wm/core/transient_window_manager.h" 46 #include "ui/wm/core/transient_window_manager.h"
42 #include "ui/wm/core/window_animations.h" 47 #include "ui/wm/core/window_animations.h"
43 #include "ui/wm/core/window_util.h" 48 #include "ui/wm/core/window_util.h"
49 #include "ui/wm/public/activation_client.h"
44 50
45 namespace { 51 namespace {
46 52
47 // The animation time in milliseconds for a single window which is fading 53 // The animation time in milliseconds for a single window which is fading
48 // in / out. 54 // in / out.
49 const int kAnimationTimeMS = 100; 55 static int kAnimationTimeMS = 100;
56
57 // The animation time in millseconds for the fade in and / or out when switching
58 // users.
59 static int kUserFadeTimeMS = 110;
50 60
51 // The animation time in ms for a window which get teleported to another screen. 61 // The animation time in ms for a window which get teleported to another screen.
52 const int kTeleportAnimationTimeMS = 300; 62 static int kTeleportAnimationTimeMS = 300;
53 63
54 // Checks if a given event is a user event. 64 // Checks if a given event is a user event.
55 bool IsUserEvent(const ui::Event* e) { 65 bool IsUserEvent(ui::Event* e) {
56 if (e) { 66 if (e) {
57 ui::EventType type = e->type(); 67 ui::EventType type = e->type();
58 if (type != ui::ET_CANCEL_MODE && 68 if (type != ui::ET_CANCEL_MODE &&
59 type != ui::ET_UMA_DATA && 69 type != ui::ET_UMA_DATA &&
60 type != ui::ET_UNKNOWN) 70 type != ui::ET_UNKNOWN)
61 return true; 71 return true;
62 } 72 }
63 return false; 73 return false;
64 } 74 }
65 75
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 180
171 // Previous animation type. 181 // Previous animation type.
172 const int previous_animation_type_; 182 const int previous_animation_type_;
173 183
174 // Previous animation time. 184 // Previous animation time.
175 const base::TimeDelta previous_animation_time_; 185 const base::TimeDelta previous_animation_time_;
176 186
177 DISALLOW_COPY_AND_ASSIGN(AnimationSetter); 187 DISALLOW_COPY_AND_ASSIGN(AnimationSetter);
178 }; 188 };
179 189
190 // logic while the user gets switched.
191 class UserChangeActionDisabler {
192 public:
193 UserChangeActionDisabler() {
194 ash::WindowPositioner::DisableAutoPositioning(true);
195 ash::Shell::GetInstance()->mru_window_tracker()->SetIgnoreActivations(true);
196 }
197
198 ~UserChangeActionDisabler() {
199 ash::WindowPositioner::DisableAutoPositioning(false);
200 ash::Shell::GetInstance()->mru_window_tracker()->SetIgnoreActivations(
201 false);
202 }
203 private:
204
205 DISALLOW_COPY_AND_ASSIGN(UserChangeActionDisabler);
206 };
207
180 // This class keeps track of all applications which were started for a user. 208 // This class keeps track of all applications which were started for a user.
181 // When an app gets created, the window will be tagged for that user. Note 209 // When an app gets created, the window will be tagged for that user. Note
182 // that the destruction does not need to be tracked here since the universal 210 // that the destruction does not need to be tracked here since the universal
183 // window observer will take care of that. 211 // window observer will take care of that.
184 class AppObserver : public apps::AppWindowRegistry::Observer { 212 class AppObserver : public apps::AppWindowRegistry::Observer {
185 public: 213 public:
186 explicit AppObserver(const std::string& user_id) : user_id_(user_id) {} 214 explicit AppObserver(const std::string& user_id) : user_id_(user_id) {}
187 virtual ~AppObserver() {} 215 virtual ~AppObserver() {}
188 216
189 // AppWindowRegistry::Observer overrides: 217 // AppWindowRegistry::Observer overrides:
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 observers_.AddObserver(observer); 404 observers_.AddObserver(observer);
377 } 405 }
378 406
379 void MultiUserWindowManagerChromeOS::RemoveObserver(Observer* observer) { 407 void MultiUserWindowManagerChromeOS::RemoveObserver(Observer* observer) {
380 observers_.RemoveObserver(observer); 408 observers_.RemoveObserver(observer);
381 } 409 }
382 410
383 void MultiUserWindowManagerChromeOS::ActiveUserChanged( 411 void MultiUserWindowManagerChromeOS::ActiveUserChanged(
384 const std::string& user_id) { 412 const std::string& user_id) {
385 DCHECK(user_id != current_user_id_); 413 DCHECK(user_id != current_user_id_);
386 // This needs to be set before the animation starts.
387 current_user_id_ = user_id; 414 current_user_id_ = user_id;
415 // If there is an animation in progress finish the pending switch which also
416 // kills the timer (if there is one).
417 if (user_changed_animation_timer_.get())
418 TransitionUser(SHOW_NEW_USER);
388 419
389 animation_.reset( 420 // Start the animation by hiding the old user.
390 new UserSwichAnimatorChromeOS(this, user_id, animations_disabled_)); 421 TransitionUser(HIDE_OLD_USER);
422
423 // If animations are disabled we immediately switch to the new user, otherwise
424 // we create a timer which will fade in the new user once the other user has
425 // been faded away.
426 if (animations_disabled_) {
427 TransitionUser(SHOW_NEW_USER);
428 } else {
429 user_changed_animation_timer_.reset(new base::Timer(
430 FROM_HERE,
431 base::TimeDelta::FromMilliseconds(kUserFadeTimeMS),
432 base::Bind(&MultiUserWindowManagerChromeOS::TransitionUser,
433 base::Unretained(this),
434 SHOW_NEW_USER),
435 false));
436 user_changed_animation_timer_->Reset();
437 }
391 } 438 }
392 439
393 void MultiUserWindowManagerChromeOS::OnWindowDestroyed(aura::Window* window) { 440 void MultiUserWindowManagerChromeOS::OnWindowDestroyed(aura::Window* window) {
394 if (GetWindowOwner(window).empty()) { 441 if (GetWindowOwner(window).empty()) {
395 // This must be a window in the transient chain - remove it and its 442 // This must be a window in the transient chain - remove it and its
396 // children from the owner. 443 // children from the owner.
397 RemoveTransientOwnerRecursive(window); 444 RemoveTransientOwnerRecursive(window);
398 return; 445 return;
399 } 446 }
400 wm::TransientWindowManager::Get(window)->RemoveObserver(this); 447 wm::TransientWindowManager::Get(window)->RemoveObserver(this);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 const content::NotificationDetails& details) { 524 const content::NotificationDetails& details) {
478 if (type == NOTIFICATION_BROWSER_WINDOW_READY) 525 if (type == NOTIFICATION_BROWSER_WINDOW_READY)
479 AddBrowserWindow(content::Source<Browser>(source).ptr()); 526 AddBrowserWindow(content::Source<Browser>(source).ptr());
480 } 527 }
481 528
482 void MultiUserWindowManagerChromeOS::SetAnimationsForTest(bool disable) { 529 void MultiUserWindowManagerChromeOS::SetAnimationsForTest(bool disable) {
483 animations_disabled_ = disable; 530 animations_disabled_ = disable;
484 } 531 }
485 532
486 bool MultiUserWindowManagerChromeOS::IsAnimationRunningForTest() { 533 bool MultiUserWindowManagerChromeOS::IsAnimationRunningForTest() {
487 return animation_.get() != NULL && !animation_->IsAnimationFinished(); 534 return user_changed_animation_timer_.get() != NULL;
488 } 535 }
489 536
490 const std::string& MultiUserWindowManagerChromeOS::GetCurrentUserForTest() { 537 const std::string& MultiUserWindowManagerChromeOS::GetCurrentUserForTest() {
491 return current_user_id_; 538 return current_user_id_;
492 } 539 }
493 540
494 bool MultiUserWindowManagerChromeOS::ShowWindowForUserIntern( 541 bool MultiUserWindowManagerChromeOS::ShowWindowForUserIntern(
495 aura::Window* window, 542 aura::Window* window,
496 const std::string& user_id) { 543 const std::string& user_id) {
497 // If there is either no owner, or the owner is the current user, no action 544 // If there is either no owner, or the owner is the current user, no action
(...skipping 28 matching lines...) Expand all
526 SetWindowVisibility(window, true, kTeleportAnimationTimeMS); 573 SetWindowVisibility(window, true, kTeleportAnimationTimeMS);
527 } else { 574 } else {
528 SetWindowVisibility(window, false, kTeleportAnimationTimeMS); 575 SetWindowVisibility(window, false, kTeleportAnimationTimeMS);
529 } 576 }
530 577
531 // Notify entry change. 578 // Notify entry change.
532 FOR_EACH_OBSERVER(Observer, observers_, OnOwnerEntryChanged(window)); 579 FOR_EACH_OBSERVER(Observer, observers_, OnOwnerEntryChanged(window));
533 return true; 580 return true;
534 } 581 }
535 582
583 void MultiUserWindowManagerChromeOS::TransitionUser(
584 MultiUserWindowManagerChromeOS::AnimationStep animation_step) {
585 TransitionWallpaper(animation_step);
586 TransitionUserShelf(animation_step);
587
588 // Disable the window position manager and the MRU window tracker temporarily.
589 scoped_ptr<UserChangeActionDisabler> disabler(new UserChangeActionDisabler);
590
591 // We need to show/hide the windows in the same order as they were created in
592 // their parent window(s) to keep the layer / window hierarchy in sync. To
593 // achieve that we first collect all parent windows and then enumerate all
594 // windows in those parent windows and show or hide them accordingly.
595
596 // Create a list of all parent windows we have to check and their parents.
597 std::set<aura::Window*> parent_list;
598 for (WindowToEntryMap::iterator it = window_to_entry_.begin();
599 it != window_to_entry_.end(); ++it) {
600 aura::Window* parent = it->first->parent();
601 if (parent_list.find(parent) == parent_list.end())
602 parent_list.insert(parent);
603 }
604
605 // Traverse the found parent windows to handle their child windows in order of
606 // their appearance.
607 for (std::set<aura::Window*>::iterator it_parents = parent_list.begin();
608 it_parents != parent_list.end(); ++it_parents) {
609 const aura::Window::Windows window_list = (*it_parents)->children();
610 for (aura::Window::Windows::const_iterator it_window = window_list.begin();
611 it_window != window_list.end(); ++it_window) {
612 aura::Window* window = *it_window;
613 WindowToEntryMap::iterator it_map = window_to_entry_.find(window);
614 if (it_map != window_to_entry_.end()) {
615 bool should_be_visible =
616 it_map->second->show_for_user() == current_user_id_ &&
617 it_map->second->show();
618 bool is_visible = window->IsVisible();
619 ash::wm::WindowState* window_state = ash::wm::GetWindowState(window);
620 if (animation_step == SHOW_NEW_USER &&
621 it_map->second->owner() == current_user_id_ &&
622 it_map->second->show_for_user() != current_user_id_ &&
623 window_state->IsMinimized()) {
624 // Pull back minimized visiting windows to the owners desktop.
625 ShowWindowForUserIntern(window, current_user_id_);
626 window_state->Unminimize();
627 } else if (should_be_visible != is_visible &&
628 should_be_visible == (animation_step == SHOW_NEW_USER)) {
629 SetWindowVisibility(window, should_be_visible, kUserFadeTimeMS);
630 }
631 }
632 }
633 }
634
635 // Activation and real switch are happening after the other user gets shown.
636 if (animation_step == SHOW_NEW_USER) {
637 // Finally we need to restore the previously active window.
638 ash::MruWindowTracker::WindowList mru_list =
639 ash::Shell::GetInstance()->mru_window_tracker()->BuildMruWindowList();
640 if (mru_list.size()) {
641 aura::Window* window = mru_list[0];
642 ash::wm::WindowState* window_state = ash::wm::GetWindowState(window);
643 if (IsWindowOnDesktopOfUser(window, current_user_id_) &&
644 !window_state->IsMinimized()) {
645 aura::client::ActivationClient* client =
646 aura::client::GetActivationClient(window->GetRootWindow());
647 // Several unit tests come here without an activation client.
648 if (client)
649 client->ActivateWindow(window);
650 }
651 }
652
653 // This is called directly here to make sure notification_blocker will see
654 // the new window status.
655 notification_blocker_->ActiveUserChanged(current_user_id_);
656
657 // We can reset the timer at this point.
658 // Note: The timer can be destroyed while it is performing its task.
659 user_changed_animation_timer_.reset();
660 }
661 }
662
663 void MultiUserWindowManagerChromeOS::TransitionWallpaper(
664 MultiUserWindowManagerChromeOS::AnimationStep animation_step) {
665 // Handle the wallpaper switch.
666 ash::UserWallpaperDelegate* wallpaper_delegate =
667 ash::Shell::GetInstance()->user_wallpaper_delegate();
668 if (animation_step == HIDE_OLD_USER) {
669 // Set the wallpaper cross dissolve animation duration to our complete
670 // animation cycle for a fade in and fade out.
671 wallpaper_delegate->SetAnimationDurationOverride(2 * kUserFadeTimeMS);
672 chromeos::WallpaperManager::Get()->SetUserWallpaperDelayed(
673 current_user_id_);
674 } else {
675 // Revert the wallpaper cross dissolve animation duration back to the
676 // default.
677 wallpaper_delegate->SetAnimationDurationOverride(0);
678 }
679 }
680
681 void MultiUserWindowManagerChromeOS::TransitionUserShelf(
682 MultiUserWindowManagerChromeOS::AnimationStep animation_step) {
683 // The shelf animation duration override.
684 int duration_override = kUserFadeTimeMS;
685 // Handle the shelf order of items. This is done once the old user is hidden.
686 if (animation_step == SHOW_NEW_USER) {
687 // Some unit tests have no ChromeLauncherController.
688 if (ChromeLauncherController::instance())
689 ChromeLauncherController::instance()->ActiveUserChanged(current_user_id_);
690 // We kicked off the shelf animation in the command above. As such we can
691 // disable the override now again.
692 duration_override = 0;
693 }
694
695 if (animations_disabled_)
696 return;
697
698 ash::Shell::RootWindowControllerList controller =
699 ash::Shell::GetInstance()->GetAllRootWindowControllers();
700 for (ash::Shell::RootWindowControllerList::iterator it1 = controller.begin();
701 it1 != controller.end(); ++it1) {
702 (*it1)->GetShelfLayoutManager()->SetAnimationDurationOverride(
703 duration_override);
704 }
705
706 // For each root window hide the shelf.
707 if (animation_step == HIDE_OLD_USER) {
708 aura::Window::Windows root_windows = ash::Shell::GetAllRootWindows();
709 for (aura::Window::Windows::const_iterator iter = root_windows.begin();
710 iter != root_windows.end(); ++iter) {
711 ash::Shell::GetInstance()->SetShelfAutoHideBehavior(
712 ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN, *iter);
713 }
714 }
715 }
716
717 void MultiUserWindowManagerChromeOS::AddBrowserWindow(Browser* browser) {
718 // A unit test (e.g. CrashRestoreComplexTest.RestoreSessionForThreeUsers) can
719 // come here with no valid window.
720 if (!browser->window() || !browser->window()->GetNativeWindow())
721 return;
722 SetWindowOwner(browser->window()->GetNativeWindow(),
723 multi_user_util::GetUserIDFromProfile(browser->profile()));
724 }
725
536 void MultiUserWindowManagerChromeOS::SetWindowVisibility( 726 void MultiUserWindowManagerChromeOS::SetWindowVisibility(
537 aura::Window* window, bool visible, int animation_time_in_ms) { 727 aura::Window* window, bool visible, int animation_time_in_ms) {
538 if (window->IsVisible() == visible) 728 if (window->IsVisible() == visible)
539 return; 729 return;
540 730
541 // Hiding a system modal dialog should not be allowed. Instead we switch to 731 // Hiding a system modal dialog should not be allowed. Instead we switch to
542 // the user which is showing the system modal window. 732 // the user which is showing the system modal window.
543 // Note that in some cases (e.g. unit test) windows might not have a root 733 // Note that in some cases (e.g. unit test) windows might not have a root
544 // window. 734 // window.
545 if (!visible && window->GetRootWindow()) { 735 if (!visible && window->GetRootWindow()) {
(...skipping 23 matching lines...) Expand all
569 759
570 if (visible) { 760 if (visible) {
571 ShowWithTransientChildrenRecursive(window, animation_time_in_ms); 761 ShowWithTransientChildrenRecursive(window, animation_time_in_ms);
572 } else { 762 } else {
573 if (window->HasFocus()) 763 if (window->HasFocus())
574 window->Blur(); 764 window->Blur();
575 SetWindowVisible(window, false, animation_time_in_ms); 765 SetWindowVisible(window, false, animation_time_in_ms);
576 } 766 }
577 } 767 }
578 768
579 void MultiUserWindowManagerChromeOS::AddBrowserWindow(Browser* browser) {
580 // A unit test (e.g. CrashRestoreComplexTest.RestoreSessionForThreeUsers) can
581 // come here with no valid window.
582 if (!browser->window() || !browser->window()->GetNativeWindow())
583 return;
584 SetWindowOwner(browser->window()->GetNativeWindow(),
585 multi_user_util::GetUserIDFromProfile(browser->profile()));
586 }
587
588 void MultiUserWindowManagerChromeOS::ShowWithTransientChildrenRecursive( 769 void MultiUserWindowManagerChromeOS::ShowWithTransientChildrenRecursive(
589 aura::Window* window, int animation_time_in_ms) { 770 aura::Window* window, int animation_time_in_ms) {
590 aura::Window::Windows::const_iterator it = 771 aura::Window::Windows::const_iterator it =
591 wm::GetTransientChildren(window).begin(); 772 wm::GetTransientChildren(window).begin();
592 for (; it != wm::GetTransientChildren(window).end(); ++it) 773 for (; it != wm::GetTransientChildren(window).end(); ++it)
593 ShowWithTransientChildrenRecursive(*it, animation_time_in_ms); 774 ShowWithTransientChildrenRecursive(*it, animation_time_in_ms);
594 775
595 // We show all children which were not explicitly hidden. 776 // We show all children which were not explicitly hidden.
596 TransientWindowToVisibility::iterator it2 = 777 TransientWindowToVisibility::iterator it2 =
597 transient_window_to_visibility_.find(window); 778 transient_window_to_visibility_.find(window);
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
682 window->Show(); 863 window->Show();
683 else 864 else
684 window->Hide(); 865 window->Hide();
685 866
686 // Make sure that animations have no influence on the window state after the 867 // Make sure that animations have no influence on the window state after the
687 // call. 868 // call.
688 DCHECK_EQ(visible, window->IsVisible()); 869 DCHECK_EQ(visible, window->IsVisible());
689 } 870 }
690 871
691 } // namespace chrome 872 } // namespace chrome
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698