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 16namespace ash { 17namespace { 18 19const 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 30class ContainerHider : public aura::WindowObserver, 31 public ui::ImplicitAnimationObserver { 32 public: 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 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. 60 virtual void OnImplicitAnimationsCompleted() OVERRIDE { 61 container_->Hide(); 62 } 63 64 // Overriden from aura::WindowObserver. 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 76class NotificationBlocker : public message_center::NotificationBlocker { 77 public: 78 NotificationBlocker() 79 : message_center::NotificationBlocker( 80 message_center::MessageCenter::Get()) { 81 NotifyBlockingStateChanged(); 82 } 83 84 virtual ~NotificationBlocker() {}; 85 86 private: 87 // Overriden from message_center::NotificationBlocker. 88 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 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 107DesktopCleaner::~DesktopCleaner() {} 108 109// static 110std::vector<int> DesktopCleaner::GetContainersToHideForTest() { 111 return std::vector<int>(kContainerIdsToHide, 112 kContainerIdsToHide + arraysize(kContainerIdsToHide)); 113} 114 115} // namespace ash 116 117