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 3 // found in the LICENSE file. 4 5 #include "ash/first_run/desktop_cleaner.h" 6 7 #include "ash/shell.h" 8 #include "ash/shell_window_ids.h" 9 #include "ui/aura/window_event_dispatcher.h" 10 #include "ui/aura/window_observer.h" 11 #include "ui/compositor/layer_animation_observer.h" 12 #include "ui/compositor/scoped_layer_animation_settings.h" 13 #include "ui/message_center/message_center.h" 14 #include "ui/message_center/notification_blocker.h" 15 16 namespace ash { 17 namespace { 18 19 const int kContainerIdsToHide[] = { 20 kShellWindowId_DefaultContainer, 21 kShellWindowId_AlwaysOnTopContainer, 22 kShellWindowId_PanelContainer, 23 // TODO(dzhioev): uncomment this when issue with BrowserView::CanActivate 24 // will be fixed. 25 // kShellWindowId_SystemModalContainer 26 }; 27 28 } // namespace 29 30 class ContainerHider : public aura::WindowObserver, 31 public ui::ImplicitAnimationObserver { 32 public: ContainerHider(aura::Window * container)33 explicit ContainerHider(aura::Window* container) 34 : container_was_hidden_(!container->IsVisible()), 35 container_(container) { 36 if (container_was_hidden_) 37 return; 38 ui::Layer* layer = container_->layer(); 39 ui::ScopedLayerAnimationSettings animation_settings(layer->GetAnimator()); 40 animation_settings.AddObserver(this); 41 layer->SetOpacity(0.0); 42 } 43 ~ContainerHider()44 virtual ~ContainerHider() { 45 if (container_was_hidden_ || !container_) 46 return; 47 if (!WasAnimationCompletedForProperty(ui::LayerAnimationElement::OPACITY)) { 48 // We are in the middle of animation. 49 StopObservingImplicitAnimations(); 50 } else { 51 container_->Show(); 52 } 53 ui::Layer* layer = container_->layer(); 54 ui::ScopedLayerAnimationSettings animation_settings(layer->GetAnimator()); 55 layer->SetOpacity(1.0); 56 } 57 58 private: 59 // Overriden from ui::ImplicitAnimationObserver. OnImplicitAnimationsCompleted()60 virtual void OnImplicitAnimationsCompleted() OVERRIDE { 61 container_->Hide(); 62 } 63 64 // Overriden from aura::WindowObserver. OnWindowDestroying(aura::Window * window)65 virtual void OnWindowDestroying(aura::Window* window) OVERRIDE { 66 DCHECK(window == container_); 67 container_ = NULL; 68 } 69 70 const bool container_was_hidden_; 71 aura::Window* container_; 72 73 DISALLOW_COPY_AND_ASSIGN(ContainerHider); 74 }; 75 76 class NotificationBlocker : public message_center::NotificationBlocker { 77 public: NotificationBlocker()78 NotificationBlocker() 79 : message_center::NotificationBlocker( 80 message_center::MessageCenter::Get()) { 81 NotifyBlockingStateChanged(); 82 } 83 ~NotificationBlocker()84 virtual ~NotificationBlocker() {}; 85 86 private: 87 // Overriden from message_center::NotificationBlocker. ShouldShowNotificationAsPopup(const message_center::NotifierId & notifier_id) const88 virtual bool ShouldShowNotificationAsPopup( 89 const message_center::NotifierId& notifier_id) const OVERRIDE { 90 return false; 91 } 92 93 DISALLOW_COPY_AND_ASSIGN(NotificationBlocker); 94 }; 95 DesktopCleaner()96DesktopCleaner::DesktopCleaner() { 97 // TODO(dzhioev): Add support for secondary displays. 98 aura::Window* root_window = Shell::GetInstance()->GetPrimaryRootWindow(); 99 for (size_t i = 0; i < arraysize(kContainerIdsToHide); ++i) { 100 aura::Window* container = 101 Shell::GetContainer(root_window, kContainerIdsToHide[i]); 102 container_hiders_.push_back(make_linked_ptr(new ContainerHider(container))); 103 } 104 notification_blocker_.reset(new NotificationBlocker()); 105 } 106 ~DesktopCleaner()107DesktopCleaner::~DesktopCleaner() {} 108 109 // static GetContainersToHideForTest()110std::vector<int> DesktopCleaner::GetContainersToHideForTest() { 111 return std::vector<int>(kContainerIdsToHide, 112 kContainerIdsToHide + arraysize(kContainerIdsToHide)); 113 } 114 115 } // namespace ash 116 117