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

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

Issue 130983007: Creating multi profile animations for switching users and teleporting of windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed Created 6 years, 10 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/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/desktop_background/user_wallpaper_delegate.h"
10 #include "ash/multi_profile_uma.h" 11 #include "ash/multi_profile_uma.h"
12 #include "ash/root_window_controller.h"
11 #include "ash/session_state_delegate.h" 13 #include "ash/session_state_delegate.h"
14 #include "ash/shelf/shelf.h"
15 #include "ash/shelf/shelf_layout_manager.h"
12 #include "ash/shell.h" 16 #include "ash/shell.h"
13 #include "ash/shell_delegate.h" 17 #include "ash/shell_delegate.h"
14 #include "ash/shell_window_ids.h" 18 #include "ash/shell_window_ids.h"
15 #include "ash/wm/mru_window_tracker.h" 19 #include "ash/wm/mru_window_tracker.h"
16 #include "ash/wm/window_positioner.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/browser.h" 34 #include "chrome/browser/ui/browser.h"
29 #include "chrome/browser/ui/browser_finder.h" 35 #include "chrome/browser/ui/browser_finder.h"
30 #include "chrome/browser/ui/browser_list.h" 36 #include "chrome/browser/ui/browser_list.h"
31 #include "chrome/browser/ui/browser_window.h" 37 #include "chrome/browser/ui/browser_window.h"
32 #include "content/public/browser/notification_service.h" 38 #include "content/public/browser/notification_service.h"
33 #include "google_apis/gaia/gaia_auth_util.h" 39 #include "google_apis/gaia/gaia_auth_util.h"
34 #include "ui/aura/client/activation_client.h" 40 #include "ui/aura/client/activation_client.h"
35 #include "ui/aura/client/aura_constants.h" 41 #include "ui/aura/client/aura_constants.h"
36 #include "ui/aura/root_window.h" 42 #include "ui/aura/root_window.h"
37 #include "ui/aura/window.h" 43 #include "ui/aura/window.h"
38 #include "ui/base/ui_base_types.h" 44 #include "ui/base/ui_base_types.h"
39 #include "ui/events/event.h" 45 #include "ui/events/event.h"
40 #include "ui/message_center/message_center.h" 46 #include "ui/message_center/message_center.h"
41 #include "ui/views/corewm/transient_window_manager.h" 47 #include "ui/views/corewm/transient_window_manager.h"
48 #include "ui/views/corewm/window_animations.h"
42 #include "ui/views/corewm/window_util.h" 49 #include "ui/views/corewm/window_util.h"
43 50
44 namespace { 51 namespace {
45 52
53 // The animation time in milliseconds for a single window which is fading
54 // in / out.
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;
60
61 // The animation time in ms for a window which get teleported to another screen.
62 static int kTeleportAnimationTimeMS = 300;
63
46 // Checks if a given event is a user event. 64 // Checks if a given event is a user event.
47 bool IsUserEvent(ui::Event* e) { 65 bool IsUserEvent(ui::Event* e) {
48 if (e) { 66 if (e) {
49 ui::EventType type = e->type(); 67 ui::EventType type = e->type();
50 if (type != ui::ET_CANCEL_MODE && 68 if (type != ui::ET_CANCEL_MODE &&
51 type != ui::ET_UMA_DATA && 69 type != ui::ET_UMA_DATA &&
52 type != ui::ET_UNKNOWN) 70 type != ui::ET_UNKNOWN)
53 return true; 71 return true;
54 } 72 }
55 return false; 73 return false;
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 } 143 }
126 } 144 }
127 } 145 }
128 ash::MultiProfileUMA::RecordTeleportWindowType(window_type); 146 ash::MultiProfileUMA::RecordTeleportWindowType(window_type);
129 } 147 }
130 148
131 } // namespace 149 } // namespace
132 150
133 namespace chrome { 151 namespace chrome {
134 152
153 // A class to temporarily change the animation properties for a window.
154 class AnimationSetter {
155 public:
156 AnimationSetter(aura::Window* window, int animation_time_in_ms)
157 : window_(window),
158 previous_animation_type_(
159 views::corewm::GetWindowVisibilityAnimationType(window_)),
160 previous_animation_time_(
161 views::corewm::GetWindowVisibilityAnimationDuration(*window_)) {
162 views::corewm::SetWindowVisibilityAnimationType(
163 window_,
164 views::corewm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE);
165 views::corewm::SetWindowVisibilityAnimationDuration(
166 window_,
167 base::TimeDelta::FromMilliseconds(animation_time_in_ms));
168 }
169
170 ~AnimationSetter() {
171 views::corewm::SetWindowVisibilityAnimationType(window_,
172 previous_animation_type_);
173 views::corewm::SetWindowVisibilityAnimationDuration(
174 window_,
175 previous_animation_time_);
176 }
177
178 private:
179 // The window which gets used.
180 aura::Window* window_;
181
182 // Previous animation type.
183 const int previous_animation_type_;
184
185 // Previous animation time.
186 const base::TimeDelta previous_animation_time_;
187
188 DISALLOW_COPY_AND_ASSIGN(AnimationSetter);
189 };
190
135 // logic while the user gets switched. 191 // logic while the user gets switched.
136 class UserChangeActionDisabler { 192 class UserChangeActionDisabler {
137 public: 193 public:
138 UserChangeActionDisabler() { 194 UserChangeActionDisabler() {
139 ash::WindowPositioner::DisableAutoPositioning(true); 195 ash::WindowPositioner::DisableAutoPositioning(true);
140 ash::Shell::GetInstance()->mru_window_tracker()->SetIgnoreActivations(true); 196 ash::Shell::GetInstance()->mru_window_tracker()->SetIgnoreActivations(true);
141 } 197 }
142 198
143 ~UserChangeActionDisabler() { 199 ~UserChangeActionDisabler() {
144 ash::WindowPositioner::DisableAutoPositioning(false); 200 ash::WindowPositioner::DisableAutoPositioning(false);
(...skipping 30 matching lines...) Expand all
175 std::string user_id_; 231 std::string user_id_;
176 232
177 DISALLOW_COPY_AND_ASSIGN(AppObserver); 233 DISALLOW_COPY_AND_ASSIGN(AppObserver);
178 }; 234 };
179 235
180 MultiUserWindowManagerChromeOS::MultiUserWindowManagerChromeOS( 236 MultiUserWindowManagerChromeOS::MultiUserWindowManagerChromeOS(
181 const std::string& current_user_id) 237 const std::string& current_user_id)
182 : current_user_id_(current_user_id), 238 : current_user_id_(current_user_id),
183 notification_blocker_(new MultiUserNotificationBlockerChromeOS( 239 notification_blocker_(new MultiUserNotificationBlockerChromeOS(
184 message_center::MessageCenter::Get(), this)), 240 message_center::MessageCenter::Get(), this)),
185 suppress_visibility_changes_(false) { 241 suppress_visibility_changes_(false),
242 animations_disabled_(false) {
186 // Add a session state observer to be able to monitor session changes. 243 // Add a session state observer to be able to monitor session changes.
187 if (ash::Shell::HasInstance()) 244 if (ash::Shell::HasInstance())
188 ash::Shell::GetInstance()->session_state_delegate()-> 245 ash::Shell::GetInstance()->session_state_delegate()->
189 AddSessionStateObserver(this); 246 AddSessionStateObserver(this);
190 247
191 // The BrowserListObserver would have been better to use then the old 248 // The BrowserListObserver would have been better to use then the old
192 // notification system, but that observer fires before the window got created. 249 // notification system, but that observer fires before the window got created.
193 registrar_.Add(this, NOTIFICATION_BROWSER_WINDOW_READY, 250 registrar_.Add(this, NOTIFICATION_BROWSER_WINDOW_READY,
194 content::NotificationService::AllSources()); 251 content::NotificationService::AllSources());
195 252
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 // Add all transient children to our set of windows. Note that the function 310 // Add all transient children to our set of windows. Note that the function
254 // will add the children but not the owner to the transient children map. 311 // will add the children but not the owner to the transient children map.
255 AddTransientOwnerRecursive(window, window); 312 AddTransientOwnerRecursive(window, window);
256 313
257 // Right now only |notification_blocker_| needs to know when the list of 314 // Right now only |notification_blocker_| needs to know when the list of
258 // owners may change. 315 // owners may change.
259 // TODO(skuhne): replace this by observer when another one needs this event. 316 // TODO(skuhne): replace this by observer when another one needs this event.
260 notification_blocker_->UpdateWindowOwners(); 317 notification_blocker_->UpdateWindowOwners();
261 318
262 if (!IsWindowOnDesktopOfUser(window, current_user_id_)) 319 if (!IsWindowOnDesktopOfUser(window, current_user_id_))
263 SetWindowVisibility(window, false); 320 SetWindowVisibility(window, false, 0);
264 } 321 }
265 322
266 const std::string& MultiUserWindowManagerChromeOS::GetWindowOwner( 323 const std::string& MultiUserWindowManagerChromeOS::GetWindowOwner(
267 aura::Window* window) { 324 aura::Window* window) {
268 WindowToEntryMap::iterator it = window_to_entry_.find(window); 325 WindowToEntryMap::iterator it = window_to_entry_.find(window);
269 return it != window_to_entry_.end() ? it->second->owner() 326 return it != window_to_entry_.end() ? it->second->owner()
270 : base::EmptyString(); 327 : base::EmptyString();
271 } 328 }
272 329
273 void MultiUserWindowManagerChromeOS::ShowWindowForUser( 330 void MultiUserWindowManagerChromeOS::ShowWindowForUser(
(...skipping 21 matching lines...) Expand all
295 RecordUMAForTransferredWindowType(window); 352 RecordUMAForTransferredWindowType(window);
296 } 353 }
297 354
298 WindowToEntryMap::iterator it = window_to_entry_.find(window); 355 WindowToEntryMap::iterator it = window_to_entry_.find(window);
299 it->second->set_show_for_user(user_id); 356 it->second->set_show_for_user(user_id);
300 357
301 // Show the window if the added user is the current one. 358 // Show the window if the added user is the current one.
302 if (user_id == current_user_id_) { 359 if (user_id == current_user_id_) {
303 // Only show the window if it should be shown according to its state. 360 // Only show the window if it should be shown according to its state.
304 if (it->second->show()) 361 if (it->second->show())
305 SetWindowVisibility(window, true); 362 SetWindowVisibility(window, true, kTeleportAnimationTimeMS);
306 } else { 363 } else {
307 SetWindowVisibility(window, false); 364 SetWindowVisibility(window, false, kTeleportAnimationTimeMS);
308 } 365 }
309 366
310 // TODO(skuhne): replace this by observer when another one needs this event. 367 // TODO(skuhne): replace this by observer when another one needs this event.
311 notification_blocker_->UpdateWindowOwners(); 368 notification_blocker_->UpdateWindowOwners();
312 } 369 }
313 370
314 bool MultiUserWindowManagerChromeOS::AreWindowsSharedAmongUsers() { 371 bool MultiUserWindowManagerChromeOS::AreWindowsSharedAmongUsers() {
315 WindowToEntryMap::iterator it = window_to_entry_.begin(); 372 WindowToEntryMap::iterator it = window_to_entry_.begin();
316 for (; it != window_to_entry_.end(); ++it) { 373 for (; it != window_to_entry_.end(); ++it) {
317 if (it->second->owner() != it->second->show_for_user()) 374 if (it->second->owner() != it->second->show_for_user())
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 BrowserList::const_iterator browser_it = browser_list->begin(); 426 BrowserList::const_iterator browser_it = browser_list->begin();
370 for (; browser_it != browser_list->end(); ++browser_it) { 427 for (; browser_it != browser_list->end(); ++browser_it) {
371 if ((*browser_it)->profile()->GetOriginalProfile() == profile) 428 if ((*browser_it)->profile()->GetOriginalProfile() == profile)
372 AddBrowserWindow(*browser_it); 429 AddBrowserWindow(*browser_it);
373 } 430 }
374 } 431 }
375 432
376 void MultiUserWindowManagerChromeOS::ActiveUserChanged( 433 void MultiUserWindowManagerChromeOS::ActiveUserChanged(
377 const std::string& user_id) { 434 const std::string& user_id) {
378 DCHECK(user_id != current_user_id_); 435 DCHECK(user_id != current_user_id_);
379 std::string old_user = current_user_id_;
380 current_user_id_ = user_id; 436 current_user_id_ = user_id;
381 // Disable the window position manager and the MRU window tracker temporarily. 437 // If there is an animation in progress finish the pending switch which also
382 scoped_ptr<UserChangeActionDisabler> disabler(new UserChangeActionDisabler); 438 // kills the timer (if there is one).
439 if (user_changed_animation_timer_.get())
440 TransitionUser(SHOW_NEW_USER);
383 441
384 // We need to show/hide the windows in the same order as they were created in 442 // Start the animation by hiding the old user.
385 // their parent window(s) to keep the layer / window hierarchy in sync. To 443 TransitionUser(HIDE_OLD_USER);
386 // achieve that we first collect all parent windows and then enumerate all
387 // windows in those parent windows and show or hide them accordingly.
388 444
389 // Create a list of all parent windows we have to check and their parents. 445 // If animations are disabled we immediately switch to the new user, otherwise
390 std::set<aura::Window*> parent_list; 446 // we create a timer which will fade in the new user once the other user has
391 for (WindowToEntryMap::iterator it = window_to_entry_.begin(); 447 // been faded away.
392 it != window_to_entry_.end(); ++it) { 448 if (animations_disabled_) {
393 aura::Window* parent = it->first->parent(); 449 TransitionUser(SHOW_NEW_USER);
394 if (parent_list.find(parent) == parent_list.end()) 450 } else {
395 parent_list.insert(parent); 451 user_changed_animation_timer_.reset(new base::Timer(
452 FROM_HERE,
453 base::TimeDelta::FromMilliseconds(kUserFadeTimeMS),
454 base::Bind(&MultiUserWindowManagerChromeOS::TransitionUser,
455 base::Unretained(this),
456 SHOW_NEW_USER),
457 false));
458 user_changed_animation_timer_->Reset();
396 } 459 }
397
398 // Traverse the found parent windows to handle their child windows in order of
399 // their appearance.
400 for (std::set<aura::Window*>::iterator it_parents = parent_list.begin();
401 it_parents != parent_list.end(); ++it_parents) {
402 const aura::Window::Windows window_list = (*it_parents)->children();
403 for (aura::Window::Windows::const_iterator it_window = window_list.begin();
404 it_window != window_list.end(); ++it_window) {
405 aura::Window* window = *it_window;
406 WindowToEntryMap::iterator it_map = window_to_entry_.find(window);
407 if (it_map != window_to_entry_.end()) {
408 bool should_be_visible = it_map->second->show_for_user() == user_id &&
409 it_map->second->show();
410 bool is_visible = window->IsVisible();
411 if (should_be_visible != is_visible)
412 SetWindowVisibility(window, should_be_visible);
413 }
414 }
415 }
416
417 // Finally we need to restore the previously active window.
418 ash::MruWindowTracker::WindowList mru_list =
419 ash::Shell::GetInstance()->mru_window_tracker()->BuildMruWindowList();
420 if (mru_list.size()) {
421 aura::Window* window = mru_list[0];
422 ash::wm::WindowState* window_state = ash::wm::GetWindowState(window);
423 if (IsWindowOnDesktopOfUser(window, user_id) &&
424 !window_state->IsMinimized()) {
425 aura::client::ActivationClient* client =
426 aura::client::GetActivationClient(window->GetRootWindow());
427 // Several unit tests come here without an activation client.
428 if (client)
429 client->ActivateWindow(window);
430 }
431 }
432
433 // This is called directly here to make sure notification_blocker will see the
434 // new window status.
435 notification_blocker_->ActiveUserChanged(user_id);
436 } 460 }
437 461
438 void MultiUserWindowManagerChromeOS::OnWindowDestroyed(aura::Window* window) { 462 void MultiUserWindowManagerChromeOS::OnWindowDestroyed(aura::Window* window) {
439 if (GetWindowOwner(window).empty()) { 463 if (GetWindowOwner(window).empty()) {
440 // This must be a window in the transient chain - remove it and its 464 // This must be a window in the transient chain - remove it and its
441 // children from the owner. 465 // children from the owner.
442 RemoveTransientOwnerRecursive(window); 466 RemoveTransientOwnerRecursive(window);
443 return; 467 return;
444 } 468 }
445 ash::wm::GetWindowState(window)->RemoveObserver(this); 469 ash::wm::GetWindowState(window)->RemoveObserver(this);
(...skipping 29 matching lines...) Expand all
475 } 499 }
476 } 500 }
477 501
478 void MultiUserWindowManagerChromeOS::OnWindowVisibilityChanged( 502 void MultiUserWindowManagerChromeOS::OnWindowVisibilityChanged(
479 aura::Window* window, bool visible) { 503 aura::Window* window, bool visible) {
480 if (suppress_visibility_changes_) 504 if (suppress_visibility_changes_)
481 return; 505 return;
482 506
483 // Don't allow to make the window visible if it shouldn't be. 507 // Don't allow to make the window visible if it shouldn't be.
484 if (visible && !IsWindowOnDesktopOfUser(window, current_user_id_)) { 508 if (visible && !IsWindowOnDesktopOfUser(window, current_user_id_)) {
485 SetWindowVisibility(window, false); 509 SetWindowVisibility(window, false, 0);
486 return; 510 return;
487 } 511 }
488 aura::Window* owned_parent = GetOwningWindowInTransientChain(window); 512 aura::Window* owned_parent = GetOwningWindowInTransientChain(window);
489 if (owned_parent && owned_parent != window && visible && 513 if (owned_parent && owned_parent != window && visible &&
490 !IsWindowOnDesktopOfUser(owned_parent, current_user_id_)) 514 !IsWindowOnDesktopOfUser(owned_parent, current_user_id_))
491 SetWindowVisibility(window, false); 515 SetWindowVisibility(window, false, 0);
492 } 516 }
493 517
494 void MultiUserWindowManagerChromeOS::OnTransientChildAdded( 518 void MultiUserWindowManagerChromeOS::OnTransientChildAdded(
495 aura::Window* window, 519 aura::Window* window,
496 aura::Window* transient_window) { 520 aura::Window* transient_window) {
497 if (!GetWindowOwner(window).empty()) { 521 if (!GetWindowOwner(window).empty()) {
498 AddTransientOwnerRecursive(transient_window, window); 522 AddTransientOwnerRecursive(transient_window, window);
499 return; 523 return;
500 } 524 }
501 aura::Window* owned_parent = 525 aura::Window* owned_parent =
(...skipping 28 matching lines...) Expand all
530 } 554 }
531 555
532 void MultiUserWindowManagerChromeOS::Observe( 556 void MultiUserWindowManagerChromeOS::Observe(
533 int type, 557 int type,
534 const content::NotificationSource& source, 558 const content::NotificationSource& source,
535 const content::NotificationDetails& details) { 559 const content::NotificationDetails& details) {
536 if (type == NOTIFICATION_BROWSER_WINDOW_READY) 560 if (type == NOTIFICATION_BROWSER_WINDOW_READY)
537 AddBrowserWindow(content::Source<Browser>(source).ptr()); 561 AddBrowserWindow(content::Source<Browser>(source).ptr());
538 } 562 }
539 563
564 void MultiUserWindowManagerChromeOS::SetAnimationsForTest(bool disable) {
565 animations_disabled_ = disable;
566 }
567
568 bool MultiUserWindowManagerChromeOS::IsAnimationRunningForTest() {
569 return user_changed_animation_timer_.get() != NULL;
570 }
571
572 void MultiUserWindowManagerChromeOS::TransitionUser(
573 MultiUserWindowManagerChromeOS::AnimationStep animation_step) {
574 TransitionWallpaper(animation_step);
575 TransitionUserShelf(animation_step);
576
577 // Disable the window position manager and the MRU window tracker temporarily.
578 scoped_ptr<UserChangeActionDisabler> disabler(new UserChangeActionDisabler);
579
580 // We need to show/hide the windows in the same order as they were created in
581 // their parent window(s) to keep the layer / window hierarchy in sync. To
582 // achieve that we first collect all parent windows and then enumerate all
583 // windows in those parent windows and show or hide them accordingly.
584
585 // Create a list of all parent windows we have to check and their parents.
586 std::set<aura::Window*> parent_list;
587 for (WindowToEntryMap::iterator it = window_to_entry_.begin();
588 it != window_to_entry_.end(); ++it) {
589 aura::Window* parent = it->first->parent();
590 if (parent_list.find(parent) == parent_list.end())
591 parent_list.insert(parent);
592 }
593
594 // Traverse the found parent windows to handle their child windows in order of
595 // their appearance.
596 for (std::set<aura::Window*>::iterator it_parents = parent_list.begin();
597 it_parents != parent_list.end(); ++it_parents) {
598 const aura::Window::Windows window_list = (*it_parents)->children();
599 for (aura::Window::Windows::const_iterator it_window = window_list.begin();
600 it_window != window_list.end(); ++it_window) {
601 aura::Window* window = *it_window;
602 WindowToEntryMap::iterator it_map = window_to_entry_.find(window);
603 if (it_map != window_to_entry_.end()) {
604 bool should_be_visible =
605 it_map->second->show_for_user() == current_user_id_ &&
606 it_map->second->show();
607 bool is_visible = window->IsVisible();
608 if (should_be_visible != is_visible &&
609 should_be_visible == (animation_step == SHOW_NEW_USER))
610 SetWindowVisibility(window, should_be_visible, kUserFadeTimeMS);
611 }
612 }
613 }
614
615 // Activation and real switch are happening after the other user gets shown.
616 if (animation_step == SHOW_NEW_USER) {
617 // Finally we need to restore the previously active window.
618 ash::MruWindowTracker::WindowList mru_list =
619 ash::Shell::GetInstance()->mru_window_tracker()->BuildMruWindowList();
620 if (mru_list.size()) {
621 aura::Window* window = mru_list[0];
622 ash::wm::WindowState* window_state = ash::wm::GetWindowState(window);
623 if (IsWindowOnDesktopOfUser(window, current_user_id_) &&
624 !window_state->IsMinimized()) {
625 aura::client::ActivationClient* client =
626 aura::client::GetActivationClient(window->GetRootWindow());
627 // Several unit tests come here without an activation client.
628 if (client)
629 client->ActivateWindow(window);
630 }
631 }
632
633 // This is called directly here to make sure notification_blocker will see
634 // the new window status.
635 notification_blocker_->ActiveUserChanged(current_user_id_);
636
637 // We can reset the timer at this point.
638 // Note: The timer can be destroyed while it is performing its task.
639 user_changed_animation_timer_.reset();
640 }
641 }
642
643 void MultiUserWindowManagerChromeOS::TransitionWallpaper(
644 MultiUserWindowManagerChromeOS::AnimationStep animation_step) {
645 // Handle the wallpaper switch.
646 if (chromeos::WallpaperManager::Get()) {
647 ash::UserWallpaperDelegate* wallpaper_delegate =
648 ash::Shell::GetInstance()->user_wallpaper_delegate();
649 if (animation_step == HIDE_OLD_USER) {
650 // Set the wallpaper cross dissolve animation duration to our complete
651 // animation cycle for a fade in and fade out.
652 wallpaper_delegate->SetAnimationDurationOverride(2 * kUserFadeTimeMS);
653 chromeos::WallpaperManager::Get()->SetUserWallpaperDelayed(
654 current_user_id_);
655 } else {
656 // Revert the wallpaper cross dissolve animation duration back to the
657 // default.
658 wallpaper_delegate->SetAnimationDurationOverride(0);
659 }
660 }
661 }
662
663 void MultiUserWindowManagerChromeOS::TransitionUserShelf(
664 MultiUserWindowManagerChromeOS::AnimationStep animation_step) {
665 // The shelf animation duration override.
666 int duration_override = kUserFadeTimeMS;
667 // Handle the shelf order of items. This is done once the old user is hidden.
668 if (animation_step == SHOW_NEW_USER) {
669 // Some unit tests have no ChromeLauncherController.
670 if (ChromeLauncherController::instance())
671 ChromeLauncherController::instance()->ActiveUserChanged(current_user_id_);
672 // We kicked off the shelf animation in the command above. As such we can
673 // disable the override now again.
674 duration_override = 0;
675 }
676
677 if (animations_disabled_)
678 return;
679
680 ash::Shell::RootWindowControllerList controller =
681 ash::Shell::GetInstance()->GetAllRootWindowControllers();
682 for (ash::Shell::RootWindowControllerList::iterator it1 = controller.begin();
683 it1 != controller.end(); ++it1) {
684 (*it1)->GetShelfLayoutManager()->SetAnimationDurationOverride(
685 duration_override);
686 }
687
688 // For each root window hide the shelf.
689 if (animation_step == HIDE_OLD_USER) {
690 aura::Window::Windows root_windows = ash::Shell::GetAllRootWindows();
691 for (aura::Window::Windows::const_iterator iter = root_windows.begin();
692 iter != root_windows.end(); ++iter) {
693 ash::Shell::GetInstance()->SetShelfAutoHideBehavior(
694 ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN, *iter);
695 }
696 }
697 }
698
540 void MultiUserWindowManagerChromeOS::AddBrowserWindow(Browser* browser) { 699 void MultiUserWindowManagerChromeOS::AddBrowserWindow(Browser* browser) {
541 // A unit test (e.g. CrashRestoreComplexTest.RestoreSessionForThreeUsers) can 700 // A unit test (e.g. CrashRestoreComplexTest.RestoreSessionForThreeUsers) can
542 // come here with no valid window. 701 // come here with no valid window.
543 if (!browser->window() || !browser->window()->GetNativeWindow()) 702 if (!browser->window() || !browser->window()->GetNativeWindow())
544 return; 703 return;
545 SetWindowOwner(browser->window()->GetNativeWindow(), 704 SetWindowOwner(browser->window()->GetNativeWindow(),
546 multi_user_util::GetUserIDFromProfile(browser->profile())); 705 multi_user_util::GetUserIDFromProfile(browser->profile()));
547 } 706 }
548 707
549 void MultiUserWindowManagerChromeOS::SetWindowVisibility( 708 void MultiUserWindowManagerChromeOS::SetWindowVisibility(
550 aura::Window* window, bool visible) { 709 aura::Window* window, bool visible, int animation_time_in_ms) {
551 if (window->IsVisible() == visible) 710 if (window->IsVisible() == visible)
552 return; 711 return;
553 712
554 // Hiding a system modal dialog should not be allowed. Instead we switch to 713 // Hiding a system modal dialog should not be allowed. Instead we switch to
555 // the user which is showing the system modal window. 714 // the user which is showing the system modal window.
556 // Note that in some cases (e.g. unit test) windows might not have a root 715 // Note that in some cases (e.g. unit test) windows might not have a root
557 // window. 716 // window.
558 if (!visible && window->GetRootWindow()) { 717 if (!visible && window->GetRootWindow()) {
559 // Get the system modal container for the window's root window. 718 // Get the system modal container for the window's root window.
560 aura::Window* system_modal_container = 719 aura::Window* system_modal_container =
(...skipping 13 matching lines...) Expand all
574 user_id); 733 user_id);
575 return; 734 return;
576 } 735 }
577 } 736 }
578 737
579 // To avoid that these commands are recorded as any other commands, we are 738 // To avoid that these commands are recorded as any other commands, we are
580 // suppressing any window entry changes while this is going on. 739 // suppressing any window entry changes while this is going on.
581 base::AutoReset<bool> suppressor(&suppress_visibility_changes_, true); 740 base::AutoReset<bool> suppressor(&suppress_visibility_changes_, true);
582 741
583 if (visible) { 742 if (visible) {
584 ShowWithTransientChildrenRecursive(window); 743 ShowWithTransientChildrenRecursive(window, animation_time_in_ms);
585 } else { 744 } else {
586 if (window->HasFocus()) 745 if (window->HasFocus())
587 window->Blur(); 746 window->Blur();
588 window->Hide(); 747 SetWindowVisible(window, false, animation_time_in_ms);
589 } 748 }
590 } 749 }
591 750
592 void MultiUserWindowManagerChromeOS::ShowWithTransientChildrenRecursive( 751 void MultiUserWindowManagerChromeOS::ShowWithTransientChildrenRecursive(
593 aura::Window* window) { 752 aura::Window* window, int animation_time_in_ms) {
594 aura::Window::Windows::const_iterator it = 753 aura::Window::Windows::const_iterator it =
595 views::corewm::GetTransientChildren(window).begin(); 754 views::corewm::GetTransientChildren(window).begin();
596 for (; it != views::corewm::GetTransientChildren(window).end(); ++it) 755 for (; it != views::corewm::GetTransientChildren(window).end(); ++it)
597 ShowWithTransientChildrenRecursive(*it); 756 ShowWithTransientChildrenRecursive(*it, animation_time_in_ms);
598 757
599 // We show all children which were not explicitly hidden. 758 // We show all children which were not explicitly hidden.
600 TransientWindowToVisibility::iterator it2 = 759 TransientWindowToVisibility::iterator it2 =
601 transient_window_to_visibility_.find(window); 760 transient_window_to_visibility_.find(window);
602 if (it2 == transient_window_to_visibility_.end() || it2->second) 761 if (it2 == transient_window_to_visibility_.end() || it2->second)
603 window->Show(); 762 SetWindowVisible(window, true, animation_time_in_ms);
604 } 763 }
605 764
606 aura::Window* MultiUserWindowManagerChromeOS::GetOwningWindowInTransientChain( 765 aura::Window* MultiUserWindowManagerChromeOS::GetOwningWindowInTransientChain(
607 aura::Window* window) { 766 aura::Window* window) {
608 if (!GetWindowOwner(window).empty()) 767 if (!GetWindowOwner(window).empty())
609 return NULL; 768 return NULL;
610 aura::Window* parent = views::corewm::GetTransientParent(window); 769 aura::Window* parent = views::corewm::GetTransientParent(window);
611 while (parent) { 770 while (parent) {
612 if (!GetWindowOwner(parent).empty()) 771 if (!GetWindowOwner(parent).empty())
613 return parent; 772 return parent;
(...skipping 21 matching lines...) Expand all
635 transient_window_to_visibility_[window] = window->IsVisible(); 794 transient_window_to_visibility_[window] = window->IsVisible();
636 795
637 // Add observers to track state changes. 796 // Add observers to track state changes.
638 window->AddObserver(this); 797 window->AddObserver(this);
639 views::corewm::TransientWindowManager::Get(window)->AddObserver(this); 798 views::corewm::TransientWindowManager::Get(window)->AddObserver(this);
640 799
641 // Hide the window if it should not be shown. Note that this hide operation 800 // Hide the window if it should not be shown. Note that this hide operation
642 // will hide recursively this and all children - but we have already collected 801 // will hide recursively this and all children - but we have already collected
643 // their initial view state. 802 // their initial view state.
644 if (!IsWindowOnDesktopOfUser(owned_parent, current_user_id_)) 803 if (!IsWindowOnDesktopOfUser(owned_parent, current_user_id_))
645 SetWindowVisibility(window, false); 804 SetWindowVisibility(window, false, kAnimationTimeMS);
646 } 805 }
647 806
648 void MultiUserWindowManagerChromeOS::RemoveTransientOwnerRecursive( 807 void MultiUserWindowManagerChromeOS::RemoveTransientOwnerRecursive(
649 aura::Window* window) { 808 aura::Window* window) {
650 // First remove all child windows. 809 // First remove all child windows.
651 aura::Window::Windows::const_iterator it = 810 aura::Window::Windows::const_iterator it =
652 views::corewm::GetTransientChildren(window).begin(); 811 views::corewm::GetTransientChildren(window).begin();
653 for (; it != views::corewm::GetTransientChildren(window).end(); ++it) 812 for (; it != views::corewm::GetTransientChildren(window).end(); ++it)
654 RemoveTransientOwnerRecursive(*it); 813 RemoveTransientOwnerRecursive(*it);
655 814
(...skipping 11 matching lines...) Expand all
667 if (unowned_view_state && !window->IsVisible()) { 826 if (unowned_view_state && !window->IsVisible()) {
668 // To prevent these commands from being recorded as any other commands, we 827 // To prevent these commands from being recorded as any other commands, we
669 // are suppressing any window entry changes while this is going on. 828 // are suppressing any window entry changes while this is going on.
670 // Instead of calling SetWindowVisible, only show gets called here since all 829 // Instead of calling SetWindowVisible, only show gets called here since all
671 // dependents have been shown previously already. 830 // dependents have been shown previously already.
672 base::AutoReset<bool> suppressor(&suppress_visibility_changes_, true); 831 base::AutoReset<bool> suppressor(&suppress_visibility_changes_, true);
673 window->Show(); 832 window->Show();
674 } 833 }
675 } 834 }
676 835
836 void MultiUserWindowManagerChromeOS::SetWindowVisible(
837 aura::Window* window,
838 bool visible,
839 int animation_time_in_ms) {
840 AnimationSetter animation_setter(
841 window,
842 animations_disabled_ ? 0 : animation_time_in_ms);
843
844 if (visible)
845 window->Show();
846 else
847 window->Hide();
848
849 // Make sure that animations have no influence on the window state after the
850 // call.
851 DCHECK_EQ(visible, window->IsVisible());
852 }
853
677 } // namespace chrome 854 } // namespace chrome
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698