1c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// found in the LICENSE file. 4c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 5c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.h" 6c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 7c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ash/desktop_background/user_wallpaper_delegate.h" 8c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ash/root_window_controller.h" 9c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ash/shelf/shelf_layout_manager.h" 10c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ash/shell.h" 11c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ash/wm/mru_window_tracker.h" 12c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ash/wm/window_positioner.h" 13c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ash/wm/window_state.h" 14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h" 15c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" 16c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/ui/ash/multi_user/multi_user_notification_blocker_chromeos.h" 17c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h" 18c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ui/wm/public/activation_client.h" 19c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 20c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochnamespace chrome { 21c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 22c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochnamespace { 23c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 24c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// The minimal possible animation time for animations which should happen 25c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// "instantly". 26c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst int kMinimalAnimationTimeMS = 1; 27c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 28c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// logic while the user gets switched. 29c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochclass UserChangeActionDisabler { 30c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch public: 31c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch UserChangeActionDisabler() { 32c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ash::WindowPositioner::DisableAutoPositioning(true); 33c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ash::Shell::GetInstance()->mru_window_tracker()->SetIgnoreActivations(true); 34c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 35c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 36c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ~UserChangeActionDisabler() { 37c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ash::WindowPositioner::DisableAutoPositioning(false); 38c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ash::Shell::GetInstance()->mru_window_tracker()->SetIgnoreActivations( 39c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch false); 40c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 41c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch private: 42c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 43c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DISALLOW_COPY_AND_ASSIGN(UserChangeActionDisabler); 44c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}; 45c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 46c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} // namespace 47c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 48c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochUserSwichAnimatorChromeOS::UserSwichAnimatorChromeOS( 49c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch MultiUserWindowManagerChromeOS* owner, 50c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const std::string& new_user_id, 51a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch int animation_speed_ms) 52c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch : owner_(owner), 53c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch new_user_id_(new_user_id), 54a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch animation_speed_ms_(animation_speed_ms), 55c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch animation_step_(ANIMATION_STEP_HIDE_OLD_USER), 56c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch screen_cover_(GetScreenCover()) { 57c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch AdvanceUserTransitionAnimation(); 58c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 59a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!animation_speed_ms_) { 60c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch FinalizeAnimation(); 61c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } else { 62c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch user_changed_animation_timer_.reset(new base::Timer( 63c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch FROM_HERE, 64a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::TimeDelta::FromMilliseconds(animation_speed_ms_), 65c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::Bind( 66c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch &UserSwichAnimatorChromeOS::AdvanceUserTransitionAnimation, 67c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::Unretained(this)), 68c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch true)); 69c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch user_changed_animation_timer_->Reset(); 70c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 71c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 72c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 73c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochUserSwichAnimatorChromeOS::~UserSwichAnimatorChromeOS() { 74c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch FinalizeAnimation(); 75c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 76c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 77c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// static 78c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbool UserSwichAnimatorChromeOS::CoversScreen(aura::Window* window) { 79c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Full screen covers the screen naturally. Since a normal window can have the 80c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // same size as the work area, we only compare the bounds against the work 81c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // area. 82c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (ash::wm::GetWindowState(window)->IsFullscreen()) 83c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return true; 84c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect bounds = window->GetBoundsInRootWindow(); 85c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect work_area = gfx::Screen::GetScreenFor(window)-> 86c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GetDisplayNearestWindow(window).work_area(); 87c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch bounds.Intersect(work_area); 88c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return work_area == bounds; 89c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 90c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 91c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid UserSwichAnimatorChromeOS::AdvanceUserTransitionAnimation() { 92c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK_NE(animation_step_, ANIMATION_STEP_ENDED); 93c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 94c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch TransitionWallpaper(animation_step_); 95c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch TransitionUserShelf(animation_step_); 96c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch TransitionWindows(animation_step_); 97c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 98c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Advance to the next step. 99c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch switch (animation_step_) { 100c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch case ANIMATION_STEP_HIDE_OLD_USER: 101c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch animation_step_ = ANIMATION_STEP_SHOW_NEW_USER; 102c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch break; 103c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch case ANIMATION_STEP_SHOW_NEW_USER: 104c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch animation_step_ = ANIMATION_STEP_FINALIZE; 105c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch break; 106c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch case ANIMATION_STEP_FINALIZE: 107c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch user_changed_animation_timer_.reset(); 108c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch animation_step_ = ANIMATION_STEP_ENDED; 109c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch break; 110c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch case ANIMATION_STEP_ENDED: 111c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch NOTREACHED(); 112c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch break; 113c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 114c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 115c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 116c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid UserSwichAnimatorChromeOS::CancelAnimation() { 117c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch animation_step_ = ANIMATION_STEP_ENDED; 118c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 119c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 120c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid UserSwichAnimatorChromeOS::FinalizeAnimation() { 121c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch user_changed_animation_timer_.reset(); 122c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch while (ANIMATION_STEP_ENDED != animation_step_) 123c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch AdvanceUserTransitionAnimation(); 124c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 125c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 126c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid UserSwichAnimatorChromeOS::TransitionWallpaper( 127c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch AnimationStep animation_step) { 128c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Handle the wallpaper switch. 129c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ash::UserWallpaperDelegate* wallpaper_delegate = 130c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ash::Shell::GetInstance()->user_wallpaper_delegate(); 131c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (animation_step == ANIMATION_STEP_HIDE_OLD_USER) { 132c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Set the wallpaper cross dissolve animation duration to our complete 133c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // animation cycle for a fade in and fade out. 134a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch int duration = 135a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch NO_USER_COVERS_SCREEN == screen_cover_ ? (2 * animation_speed_ms_) : 0; 136c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch wallpaper_delegate->SetAnimationDurationOverride( 137a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch std::max(duration, kMinimalAnimationTimeMS)); 138c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (screen_cover_ != NEW_USER_COVERS_SCREEN) { 139c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch chromeos::WallpaperManager::Get()->SetUserWallpaperNow(new_user_id_); 140c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch wallpaper_user_id_ = 141c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch (NO_USER_COVERS_SCREEN == screen_cover_ ? "->" : "") + 142c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch new_user_id_; 143c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 144c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } else if (animation_step == ANIMATION_STEP_FINALIZE) { 145c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Revert the wallpaper cross dissolve animation duration back to the 146c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // default. 147c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (screen_cover_ == NEW_USER_COVERS_SCREEN) 148c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch chromeos::WallpaperManager::Get()->SetUserWallpaperNow(new_user_id_); 149c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 150c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Coming here the wallpaper user id is the final result. No matter how we 151c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // got here. 152c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch wallpaper_user_id_ = new_user_id_; 153c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch wallpaper_delegate->SetAnimationDurationOverride(0); 154c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 155c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 156c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 157c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid UserSwichAnimatorChromeOS::TransitionUserShelf( 158c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch AnimationStep animation_step) { 159c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // The shelf animation duration override. 160a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch int duration_override = animation_speed_ms_; 161c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Handle the shelf order of items. This is done once the old user is hidden. 162c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (animation_step == ANIMATION_STEP_SHOW_NEW_USER) { 163c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Some unit tests have no ChromeLauncherController. 164c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (ChromeLauncherController::instance()) 165c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ChromeLauncherController::instance()->ActiveUserChanged(new_user_id_); 166c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // We kicked off the shelf animation in the command above. As such we can 167c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // disable the override now again. 168c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch duration_override = 0; 169c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 170c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 171a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!animation_speed_ms_ || animation_step == ANIMATION_STEP_FINALIZE) 172c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 173c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 174c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ash::Shell::RootWindowControllerList controller = 175c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ash::Shell::GetInstance()->GetAllRootWindowControllers(); 176c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch for (ash::Shell::RootWindowControllerList::iterator iter = controller.begin(); 177c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch iter != controller.end(); ++iter) { 178c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch (*iter)->GetShelfLayoutManager()->SetAnimationDurationOverride( 179c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch duration_override); 180c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 181c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 182c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // For each root window hide the shelf. 183c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (animation_step == ANIMATION_STEP_HIDE_OLD_USER) { 184c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch aura::Window::Windows root_windows = ash::Shell::GetAllRootWindows(); 185c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch for (aura::Window::Windows::const_iterator iter = root_windows.begin(); 186c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch iter != root_windows.end(); ++iter) { 187c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // This shelf change is only part of the animation and will be updated by 188c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // ChromeLauncherController::ActiveUserChanged() to the new users value. 189c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Note that the user perference will not be changed. 190c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ash::Shell::GetInstance()->SetShelfAutoHideBehavior( 191c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN, *iter); 192c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 193c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 194c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 195c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 196c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid UserSwichAnimatorChromeOS::TransitionWindows( 197c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch AnimationStep animation_step) { 198c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Disable the window position manager and the MRU window tracker temporarily. 199c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch UserChangeActionDisabler disabler; 200c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 201c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (animation_step == ANIMATION_STEP_HIDE_OLD_USER || 202c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch (animation_step == ANIMATION_STEP_FINALIZE && 203c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch screen_cover_ == BOTH_USERS_COVER_SCREEN)) { 204c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // We need to show/hide the windows in the same order as they were created 205c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // in their parent window(s) to keep the layer / window hierarchy in sync. 206c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // To achieve that we first collect all parent windows and then enumerate 207c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // all windows in those parent windows and show or hide them accordingly. 208c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 209c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Create a list of all parent windows we have to check. 210c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch std::set<aura::Window*> parent_list; 211c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch for (MultiUserWindowManagerChromeOS::WindowToEntryMap::const_iterator it = 212c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch owner_->window_to_entry().begin(); 213c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch it != owner_->window_to_entry().end(); ++it) { 214c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch aura::Window* parent = it->first->parent(); 215c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (parent_list.find(parent) == parent_list.end()) 216c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch parent_list.insert(parent); 217c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 218c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 219c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch for (std::set<aura::Window*>::iterator it_parents = parent_list.begin(); 220c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch it_parents != parent_list.end(); ++it_parents) { 221c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const aura::Window::Windows window_list = (*it_parents)->children(); 222c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // In case of |BOTH_USERS_COVER_SCREEN| the desktop might shine through 223c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // if all windows fade (in or out). To avoid this we only fade the topmost 224c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // covering window (in / out) and make / keep all other covering windows 225c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // visible while animating. |foreground_window_found| will get set when 226c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // the top fading window was found. 227c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch bool foreground_window_found = false; 228c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Covering windows which follow the fade direction will also fade - all 229c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // others will get immediately shown / kept shown until the animation is 230c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // finished. 231c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch bool foreground_becomes_visible = false; 232c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch for (aura::Window::Windows::const_reverse_iterator it_window = 233c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch window_list.rbegin(); 234c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch it_window != window_list.rend(); ++it_window) { 235c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch aura::Window* window = *it_window; 236c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch MultiUserWindowManagerChromeOS::WindowToEntryMap::const_iterator 237c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch it_map = owner_->window_to_entry().find(window); 238c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (it_map != owner_->window_to_entry().end()) { 239c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch bool should_be_visible = 240c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch it_map->second->show_for_user() == new_user_id_ && 241c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch it_map->second->show(); 242c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch bool is_visible = window->IsVisible(); 243c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ash::wm::WindowState* window_state = ash::wm::GetWindowState(window); 244c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (it_map->second->owner() == new_user_id_ && 245c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch it_map->second->show_for_user() != new_user_id_ && 246c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch window_state->IsMinimized()) { 247c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Pull back minimized visiting windows to the owners desktop. 248c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch owner_->ShowWindowForUserIntern(window, new_user_id_); 249c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch window_state->Unminimize(); 250c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } else if (should_be_visible != is_visible) { 251c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch bool animate = true; 252c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int duration = animation_step == ANIMATION_STEP_FINALIZE ? 253a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 0 : (2 * animation_speed_ms_); 254a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch duration = std::max(kMinimalAnimationTimeMS, duration); 255c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (animation_step != ANIMATION_STEP_FINALIZE && 256c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch screen_cover_ == BOTH_USERS_COVER_SCREEN && 257c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch CoversScreen(window)) { 258c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!foreground_window_found) { 259c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch foreground_window_found = true; 260c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch foreground_becomes_visible = should_be_visible; 261c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } else if (should_be_visible != foreground_becomes_visible) { 262c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Covering windows behind the foreground window which are 263c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // inverting their visibility should immediately become visible 264c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // or stay visible until the animation is finished. 265c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch duration = kMinimalAnimationTimeMS; 266c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!should_be_visible) 267c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch animate = false; 268c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 269c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 270c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (animate) 271c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch owner_->SetWindowVisibility(window, should_be_visible, duration); 272c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 273c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 274c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 275c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 276c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 277c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 278c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Activation and real switch are happening after the other user gets shown. 279c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (animation_step == ANIMATION_STEP_SHOW_NEW_USER) { 280c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Finally we need to restore the previously active window. 281c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ash::MruWindowTracker::WindowList mru_list = 282c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ash::Shell::GetInstance()->mru_window_tracker()->BuildMruWindowList(); 283c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!mru_list.empty()) { 284c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch aura::Window* window = mru_list[0]; 285c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ash::wm::WindowState* window_state = ash::wm::GetWindowState(window); 286c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (owner_->IsWindowOnDesktopOfUser(window, new_user_id_) && 287c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch !window_state->IsMinimized()) { 288c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch aura::client::ActivationClient* client = 289c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch aura::client::GetActivationClient(window->GetRootWindow()); 290c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Several unit tests come here without an activation client. 291c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (client) 292c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch client->ActivateWindow(window); 293c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 294c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 295c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 296c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // This is called directly here to make sure notification_blocker will see 297c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // the new window status. 298c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch owner_->notification_blocker()->ActiveUserChanged(new_user_id_); 299c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 300c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 301c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 302c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochUserSwichAnimatorChromeOS::TransitioningScreenCover 303c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochUserSwichAnimatorChromeOS::GetScreenCover() { 304c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch TransitioningScreenCover cover = NO_USER_COVERS_SCREEN; 305c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch for (MultiUserWindowManagerChromeOS::WindowToEntryMap::const_iterator it_map = 306c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch owner_->window_to_entry().begin(); 307c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch it_map != owner_->window_to_entry().end(); 308c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ++it_map) { 309c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch aura::Window* window = it_map->first; 310c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (window->IsVisible() && CoversScreen(window)) { 311c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (cover == NEW_USER_COVERS_SCREEN) 312c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return BOTH_USERS_COVER_SCREEN; 313c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch else 314c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch cover = OLD_USER_COVERS_SCREEN; 315c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } else if (owner_->IsWindowOnDesktopOfUser(window, new_user_id_) && 316c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch CoversScreen(window)) { 317c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (cover == OLD_USER_COVERS_SCREEN) 318c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return BOTH_USERS_COVER_SCREEN; 319c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch else 320c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch cover = NEW_USER_COVERS_SCREEN; 321c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 322c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 323c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return cover; 324c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 325c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 326c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} // namespace chrome 327