• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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 "chrome/browser/chromeos/notifications/balloon_collection_impl.h"
6 
7 #include <algorithm>
8 
9 #include "base/logging.h"
10 #include "chrome/browser/chromeos/notifications/balloon_view.h"
11 #include "chrome/browser/chromeos/notifications/notification_panel.h"
12 #include "chrome/browser/notifications/balloon.h"
13 #include "chrome/browser/notifications/notification.h"
14 #include "chrome/browser/ui/browser_list.h"
15 #include "chrome/browser/ui/window_sizer.h"
16 #include "content/common/notification_service.h"
17 #include "ui/gfx/rect.h"
18 #include "ui/gfx/size.h"
19 
20 namespace {
21 
22 // Margin from the edge of the work area
23 const int kVerticalEdgeMargin = 5;
24 const int kHorizontalEdgeMargin = 5;
25 
26 }  // namespace
27 
28 namespace chromeos {
29 
BalloonCollectionImpl()30 BalloonCollectionImpl::BalloonCollectionImpl()
31     : notification_ui_(new NotificationPanel()) {
32   registrar_.Add(this, NotificationType::BROWSER_CLOSED,
33                  NotificationService::AllSources());
34 }
35 
~BalloonCollectionImpl()36 BalloonCollectionImpl::~BalloonCollectionImpl() {
37   Shutdown();
38 }
39 
Add(const Notification & notification,Profile * profile)40 void BalloonCollectionImpl::Add(const Notification& notification,
41                                 Profile* profile) {
42   Balloon* new_balloon = MakeBalloon(notification, profile);
43   base_.Add(new_balloon);
44   new_balloon->Show();
45   notification_ui_->Add(new_balloon);
46 
47   // There may be no listener in a unit test.
48   if (space_change_listener_)
49     space_change_listener_->OnBalloonSpaceChanged();
50 }
51 
AddWebUIMessageCallback(const Notification & notification,const std::string & message,MessageCallback * callback)52 bool BalloonCollectionImpl::AddWebUIMessageCallback(
53     const Notification& notification,
54     const std::string& message,
55     MessageCallback* callback) {
56   Balloon* balloon = FindBalloon(notification);
57   if (!balloon) {
58     delete callback;
59     return false;
60   }
61   BalloonViewHost* host =
62       static_cast<BalloonViewHost*>(balloon->view()->GetHost());
63   return host->AddWebUIMessageCallback(message, callback);
64 }
65 
AddSystemNotification(const Notification & notification,Profile * profile,bool sticky,bool control)66 void BalloonCollectionImpl::AddSystemNotification(
67     const Notification& notification,
68     Profile* profile,
69     bool sticky,
70     bool control) {
71 
72   Balloon* new_balloon = new Balloon(notification, profile, this);
73   new_balloon->set_view(
74       new chromeos::BalloonViewImpl(sticky, control, true));
75   base_.Add(new_balloon);
76   new_balloon->Show();
77   notification_ui_->Add(new_balloon);
78 
79   // There may be no listener in a unit test.
80   if (space_change_listener_)
81     space_change_listener_->OnBalloonSpaceChanged();
82 }
83 
UpdateNotification(const Notification & notification)84 bool BalloonCollectionImpl::UpdateNotification(
85     const Notification& notification) {
86   Balloon* balloon = FindBalloon(notification);
87   if (!balloon)
88     return false;
89   balloon->Update(notification);
90   notification_ui_->Update(balloon);
91   return true;
92 }
93 
UpdateAndShowNotification(const Notification & notification)94 bool BalloonCollectionImpl::UpdateAndShowNotification(
95     const Notification& notification) {
96   Balloon* balloon = FindBalloon(notification);
97   if (!balloon)
98     return false;
99   balloon->Update(notification);
100   bool updated = notification_ui_->Update(balloon);
101   DCHECK(updated);
102   notification_ui_->Show(balloon);
103   return true;
104 }
105 
RemoveById(const std::string & id)106 bool BalloonCollectionImpl::RemoveById(const std::string& id) {
107   return base_.CloseById(id);
108 }
109 
RemoveBySourceOrigin(const GURL & origin)110 bool BalloonCollectionImpl::RemoveBySourceOrigin(const GURL& origin) {
111   return base_.CloseAllBySourceOrigin(origin);
112 }
113 
RemoveAll()114 void BalloonCollectionImpl::RemoveAll() {
115   base_.CloseAll();
116 }
117 
HasSpace() const118 bool BalloonCollectionImpl::HasSpace() const {
119   return true;
120 }
121 
ResizeBalloon(Balloon * balloon,const gfx::Size & size)122 void BalloonCollectionImpl::ResizeBalloon(Balloon* balloon,
123                                           const gfx::Size& size) {
124   notification_ui_->ResizeNotification(balloon, size);
125 }
126 
OnBalloonClosed(Balloon * source)127 void BalloonCollectionImpl::OnBalloonClosed(Balloon* source) {
128   notification_ui_->Remove(source);
129   base_.Remove(source);
130 
131   // There may be no listener in a unit test.
132   if (space_change_listener_)
133     space_change_listener_->OnBalloonSpaceChanged();
134 }
135 
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)136 void BalloonCollectionImpl::Observe(NotificationType type,
137                                     const NotificationSource& source,
138                                     const NotificationDetails& details) {
139   DCHECK(type == NotificationType::BROWSER_CLOSED);
140   bool app_closing = *Details<bool>(details).ptr();
141   // When exiting, we need to shutdown all renderers in
142   // BalloonViewImpl before IO thread gets deleted in the
143   // BrowserProcessImpl's destructor.  See http://crbug.com/40810
144   // for details.
145   if (app_closing)
146     RemoveAll();
147 }
148 
Shutdown()149 void BalloonCollectionImpl::Shutdown() {
150   // We need to remove the panel first because deleting
151   // views that are not owned by parent will not remove
152   // themselves from the parent.
153   DVLOG(1) << "Shutting down notification UI";
154   notification_ui_.reset();
155 }
156 
MakeBalloon(const Notification & notification,Profile * profile)157 Balloon* BalloonCollectionImpl::MakeBalloon(const Notification& notification,
158                                             Profile* profile) {
159   Balloon* new_balloon = new Balloon(notification, profile, this);
160   new_balloon->set_view(new chromeos::BalloonViewImpl(false, true, false));
161   return new_balloon;
162 }
163 
164 }  // namespace chromeos
165 
166 // static
Create()167 BalloonCollection* BalloonCollection::Create() {
168   return new chromeos::BalloonCollectionImpl();
169 }
170