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