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