Popular sites on the NTP: check that experiment group StartsWith (rather than IS...
[chromium-blink-merge.git] / chrome / browser / ui / cocoa / notifications / message_center_tray_bridge.mm
blobcf7ab98be114ec149a3c7838a8460cf0ce977686
1 // Copyright (c) 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.
5 #include "chrome/browser/ui/cocoa/notifications/message_center_tray_bridge.h"
7 #include "base/bind.h"
8 #include "base/i18n/number_formatting.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/profiler/scoped_tracker.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/common/pref_names.h"
14 #include "chrome/grit/chromium_strings.h"
15 #include "chrome/grit/generated_resources.h"
16 #include "ui/base/l10n/l10n_util.h"
17 #import "ui/base/l10n/l10n_util_mac.h"
18 #import "ui/message_center/cocoa/popup_collection.h"
19 #import "ui/message_center/cocoa/status_item_view.h"
20 #import "ui/message_center/cocoa/tray_controller.h"
21 #import "ui/message_center/cocoa/tray_view_controller.h"
22 #include "ui/message_center/message_center.h"
23 #include "ui/message_center/message_center_tray.h"
25 namespace message_center {
27 MessageCenterTrayDelegate* CreateMessageCenterTray() {
28   return new MessageCenterTrayBridge(g_browser_process->message_center());
31 }  // namespace message_center
33 MessageCenterTrayBridge::MessageCenterTrayBridge(
34     message_center::MessageCenter* message_center)
35     : message_center_(message_center),
36       tray_(new message_center::MessageCenterTray(this, message_center)),
37       status_item_update_pending_(false),
38       weak_ptr_factory_(this) {
39   show_status_item_.Init(
40       prefs::kMessageCenterShowIcon,
41       g_browser_process->local_state(),
42       base::Bind(&MessageCenterTrayBridge::OnShowStatusItemChanged,
43                  weak_ptr_factory_.GetWeakPtr()));
46 MessageCenterTrayBridge::~MessageCenterTrayBridge() {
47   [status_item_view_ removeItem];
50 void MessageCenterTrayBridge::OnMessageCenterTrayChanged() {
51   // Update the status item on the next run of the message loop so that if a
52   // popup is displayed, the item doesn't flash the unread count.
53   if (!status_item_update_pending_) {
54     status_item_update_pending_ = true;
55     base::MessageLoop::current()->PostTask(
56         FROM_HERE,
57         base::Bind(&MessageCenterTrayBridge::HandleMessageCenterTrayChanged,
58                    weak_ptr_factory_.GetWeakPtr()));
59   }
61   [tray_controller_ onMessageCenterTrayChanged];
64 bool MessageCenterTrayBridge::ShowPopups() {
65   popup_collection_.reset(
66       [[MCPopupCollection alloc] initWithMessageCenter:message_center_]);
67   return true;
70 void MessageCenterTrayBridge::HidePopups() {
71   popup_collection_.reset();
74 bool MessageCenterTrayBridge::ShowMessageCenter() {
75   if (tray_controller_)
76     return false;
78   OpenTrayWindow();
79   return true;
82 void MessageCenterTrayBridge::HideMessageCenter() {
83   [status_item_view_ setHighlight:NO];
84   [tray_controller_ close];
85   tray_controller_.autorelease();
86   UpdateStatusItem();
89 bool MessageCenterTrayBridge::ShowNotifierSettings() {
90   // This method needs to be implemented when the context menu of each
91   // notification is ready and it contains 'settings' menu item.
92   return false;
95 bool MessageCenterTrayBridge::IsContextMenuEnabled() const {
96   // Cocoa message center doesn't support context menu yet.
97   return false;
100 message_center::MessageCenterTray*
101 MessageCenterTrayBridge::GetMessageCenterTray() {
102   return tray_.get();
105 void MessageCenterTrayBridge::UpdateStatusItem() {
106   // We want a static message center icon while it's visible.
107   if (!status_item_view_ || message_center()->IsMessageCenterVisible())
108     return;
110   size_t unread_count = message_center_->UnreadNotificationCount();
111   bool quiet_mode = message_center_->IsQuietMode();
112   [status_item_view_ setUnreadCount:unread_count withQuietMode:quiet_mode];
114   if (unread_count > 0) {
115     base::string16 unread_count_string = base::FormatNumber(unread_count);
116     [status_item_view_ setToolTip:
117         l10n_util::GetNSStringF(IDS_MESSAGE_CENTER_TOOLTIP_UNREAD,
118             unread_count_string)];
119   } else {
120     [status_item_view_ setToolTip:
121         l10n_util::GetNSString(IDS_MESSAGE_CENTER_TOOLTIP)];
122   }
125 void MessageCenterTrayBridge::OpenTrayWindow() {
126   DCHECK(!tray_controller_);
127   tray_controller_.reset(
128       [[MCTrayController alloc] initWithMessageCenterTray:tray_.get()]);
129   [[tray_controller_ viewController] setTrayTitle:
130       l10n_util::GetNSStringF(IDS_MESSAGE_CENTER_FOOTER_WITH_PRODUCT_TITLE,
131           l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME))];
133   UpdateStatusItem();
135   DCHECK(status_item_view_);
136   [status_item_view_ setHighlight:YES];
137   NSRect frame = [[status_item_view_ window] frame];
138   [tray_controller_ showTrayAtRightOf:NSMakePoint(NSMinX(frame),
139                                                   NSMinY(frame))
140                              atLeftOf:NSMakePoint(NSMaxX(frame),
141                                                   NSMinY(frame))];
144 bool MessageCenterTrayBridge::CanShowStatusItem() const {
145   return g_browser_process->local_state()->GetBoolean(
146       prefs::kMessageCenterShowIcon);
149 bool MessageCenterTrayBridge::NeedsStatusItem() const {
150   return status_item_view_ || message_center_->NotificationCount() > 0;
153 void MessageCenterTrayBridge::ShowStatusItem() {
154   if (status_item_view_)
155     return;
156   status_item_view_.reset([[MCStatusItemView alloc] init]);
157   [status_item_view_ setCallback:^{
158       tray_->ToggleMessageCenterBubble();
159   }];
162 void MessageCenterTrayBridge::HideStatusItem() {
163   [status_item_view_ removeItem];
164   status_item_view_.reset();
167 void MessageCenterTrayBridge::HandleMessageCenterTrayChanged() {
168   // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465858
169   // is fixed.
170   tracked_objects::ScopedTracker tracking_profile1(
171       FROM_HERE_WITH_EXPLICIT_FUNCTION(
172           "465858 "
173           "MessageCenterTrayBridge::HandleMessageCenterTrayChanged::Start"));
174   status_item_update_pending_ = false;
175   if (CanShowStatusItem() && NeedsStatusItem()) {
176     // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465858
177     // is fixed.
178     tracked_objects::ScopedTracker tracking_profile2(
179         FROM_HERE_WITH_EXPLICIT_FUNCTION(
180             "465858 "
181             "MessageCenterTrayBridge::HandleMessageCenterTrayChanged::"
182             "ShowStatusItem"));
183     ShowStatusItem();
185     // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465858
186     // is fixed.
187     tracked_objects::ScopedTracker tracking_profile3(
188         FROM_HERE_WITH_EXPLICIT_FUNCTION(
189             "465858 "
190             "MessageCenterTrayBridge::HandleMessageCenterTrayChanged::"
191             "UpdateStatusItem"));
192     UpdateStatusItem();
193   } else {
194     // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465858
195     // is fixed.
196     tracked_objects::ScopedTracker tracking_profile4(
197         FROM_HERE_WITH_EXPLICIT_FUNCTION(
198             "465858 "
199             "MessageCenterTrayBridge::HandleMessageCenterTrayChanged::"
200             "HideStatusItem"));
201     HideStatusItem();
202   }
205 void MessageCenterTrayBridge::OnShowStatusItemChanged() {
206   if (CanShowStatusItem()) {
207     ShowStatusItem();
208     UpdateStatusItem();
209   } else {
210     HideStatusItem();
211   }