| Index: chrome/browser/notifications/notification_ui_manager_mac.mm
|
| diff --git a/chrome/browser/notifications/notification_ui_manager_mac.mm b/chrome/browser/notifications/notification_ui_manager_mac.mm
|
| deleted file mode 100644
|
| index d0b783c1fdf51b9fbf47a72ce9e5dcbaff261d03..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/notifications/notification_ui_manager_mac.mm
|
| +++ /dev/null
|
| @@ -1,346 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "chrome/browser/notifications/notification_ui_manager_mac.h"
|
| -
|
| -#include "base/mac/cocoa_protocols.h"
|
| -#include "base/mac/mac_util.h"
|
| -#include "base/memory/scoped_ptr.h"
|
| -#include "base/strings/sys_string_conversions.h"
|
| -#include "chrome/browser/browser_process.h"
|
| -#include "chrome/browser/notifications/notification.h"
|
| -#include "chrome/browser/notifications/balloon_notification_ui_manager.h"
|
| -#include "chrome/browser/notifications/message_center_notification_manager.h"
|
| -#include "chrome/browser/notifications/message_center_settings_controller.h"
|
| -#include "chrome/browser/profiles/profile.h"
|
| -#include "chrome/browser/profiles/profile_info_cache.h"
|
| -#include "chrome/browser/profiles/profile_manager.h"
|
| -#include "ui/message_center/message_center_util.h"
|
| -
|
| -@class NSUserNotificationCenter;
|
| -
|
| -// Since NSUserNotification and NSUserNotificationCenter are new classes in
|
| -// 10.8, they cannot simply be declared with an @interface. An @implementation
|
| -// is needed to link, but providing one would cause a runtime conflict when
|
| -// running on 10.8. Instead, provide the interface defined as a protocol and
|
| -// use that instead, because sizeof(id<Protocol>) == sizeof(Class*). In order to
|
| -// instantiate, use NSClassFromString and simply assign the alloc/init'd result
|
| -// to an instance of the proper protocol. This way the compiler, linker, and
|
| -// loader are all happy. And the code isn't full of objc_msgSend.
|
| -@protocol CrUserNotification <NSObject>
|
| -@property(copy) NSString* title;
|
| -@property(copy) NSString* subtitle;
|
| -@property(copy) NSString* informativeText;
|
| -@property(copy) NSString* actionButtonTitle;
|
| -@property(copy) NSDictionary* userInfo;
|
| -@property(copy) NSDate* deliveryDate;
|
| -@property(copy) NSTimeZone* deliveryTimeZone;
|
| -@property(copy) NSDateComponents* deliveryRepeatInterval;
|
| -@property(readonly) NSDate* actualDeliveryDate;
|
| -@property(readonly, getter=isPresented) BOOL presented;
|
| -@property(readonly, getter=isRemote) BOOL remote;
|
| -@property(copy) NSString* soundName;
|
| -@property BOOL hasActionButton;
|
| -@end
|
| -
|
| -@protocol CrUserNotificationCenter
|
| -+ (NSUserNotificationCenter*)defaultUserNotificationCenter;
|
| -@property(assign) id<NSUserNotificationCenterDelegate> delegate;
|
| -@property(copy) NSArray* scheduledNotifications;
|
| -- (void)scheduleNotification:(id<CrUserNotification>)notification;
|
| -- (void)removeScheduledNotification:(id<CrUserNotification>)notification;
|
| -@property(readonly) NSArray* deliveredNotifications;
|
| -- (void)deliverNotification:(id<CrUserNotification>)notification;
|
| -- (void)removeDeliveredNotification:(id<CrUserNotification>)notification;
|
| -- (void)removeAllDeliveredNotifications;
|
| -@end
|
| -
|
| -////////////////////////////////////////////////////////////////////////////////
|
| -
|
| -namespace {
|
| -
|
| -// A "fun" way of saying:
|
| -// +[NSUserNotificationCenter defaultUserNotificationCenter].
|
| -id<CrUserNotificationCenter> GetNotificationCenter() {
|
| - return [NSClassFromString(@"NSUserNotificationCenter")
|
| - performSelector:@selector(defaultUserNotificationCenter)];
|
| -}
|
| -
|
| -// The key in NSUserNotification.userInfo that stores the C++ notification_id.
|
| -NSString* const kNotificationIDKey = @"notification_id";
|
| -
|
| -} // namespace
|
| -
|
| -// A Cocoa class that can be the delegate of NSUserNotificationCenter that
|
| -// forwards commands to C++.
|
| -@interface NotificationCenterDelegate : NSObject
|
| - <NSUserNotificationCenterDelegate> {
|
| - @private
|
| - NotificationUIManagerMac* manager_; // Weak, owns self.
|
| -}
|
| -- (id)initWithManager:(NotificationUIManagerMac*)manager;
|
| -@end
|
| -
|
| -////////////////////////////////////////////////////////////////////////////////
|
| -
|
| -NotificationUIManagerMac::ControllerNotification::ControllerNotification(
|
| - Profile* a_profile,
|
| - id<CrUserNotification> a_view,
|
| - Notification* a_model)
|
| - : profile(a_profile),
|
| - view(a_view),
|
| - model(a_model) {
|
| -}
|
| -
|
| -NotificationUIManagerMac::ControllerNotification::~ControllerNotification() {
|
| - [view release];
|
| - delete model;
|
| -}
|
| -
|
| -////////////////////////////////////////////////////////////////////////////////
|
| -
|
| -// static
|
| -NotificationUIManager* NotificationUIManager::Create(PrefService* local_state) {
|
| - // TODO(rsesek): Remove this function and merge it with the one in
|
| - // notification_ui_manager.cc.
|
| - if (DelegatesToMessageCenter()) {
|
| - ProfileInfoCache* profile_info_cache =
|
| - &g_browser_process->profile_manager()->GetProfileInfoCache();
|
| - scoped_ptr<message_center::NotifierSettingsProvider> settings_provider(
|
| - new MessageCenterSettingsController(profile_info_cache));
|
| - return new MessageCenterNotificationManager(
|
| - g_browser_process->message_center(),
|
| - local_state,
|
| - settings_provider.Pass());
|
| - }
|
| -
|
| - BalloonNotificationUIManager* balloon_manager = NULL;
|
| - if (base::mac::IsOSMountainLionOrLater())
|
| - balloon_manager = new NotificationUIManagerMac(local_state);
|
| - else
|
| - balloon_manager = new BalloonNotificationUIManager(local_state);
|
| - balloon_manager->SetBalloonCollection(BalloonCollection::Create());
|
| - return balloon_manager;
|
| -}
|
| -
|
| -NotificationUIManagerMac::NotificationUIManagerMac(PrefService* local_state)
|
| - : BalloonNotificationUIManager(local_state),
|
| - delegate_([[NotificationCenterDelegate alloc] initWithManager:this]) {
|
| - DCHECK(!GetNotificationCenter().delegate);
|
| - GetNotificationCenter().delegate = delegate_.get();
|
| -}
|
| -
|
| -NotificationUIManagerMac::~NotificationUIManagerMac() {
|
| - CancelAll();
|
| -}
|
| -
|
| -void NotificationUIManagerMac::Add(const Notification& notification,
|
| - Profile* profile) {
|
| - if (notification.is_html()) {
|
| - BalloonNotificationUIManager::Add(notification, profile);
|
| - } else {
|
| - if (!notification.replace_id().empty()) {
|
| - id<CrUserNotification> replacee = FindNotificationWithReplacementId(
|
| - notification.replace_id());
|
| - if (replacee)
|
| - RemoveNotification(replacee);
|
| - }
|
| -
|
| - // Owned by ControllerNotification.
|
| - id<CrUserNotification> ns_notification =
|
| - [[NSClassFromString(@"NSUserNotification") alloc] init];
|
| -
|
| - ns_notification.title = base::SysUTF16ToNSString(notification.title());
|
| - ns_notification.subtitle =
|
| - base::SysUTF16ToNSString(notification.display_source());
|
| - ns_notification.informativeText =
|
| - base::SysUTF16ToNSString(notification.message());
|
| - ns_notification.userInfo =
|
| - [NSDictionary dictionaryWithObject:base::SysUTF8ToNSString(
|
| - notification.notification_id())
|
| - forKey:kNotificationIDKey];
|
| - ns_notification.hasActionButton = NO;
|
| -
|
| - notification_map_.insert(std::make_pair(
|
| - notification.notification_id(),
|
| - new ControllerNotification(profile,
|
| - ns_notification,
|
| - new Notification(notification))));
|
| -
|
| - [GetNotificationCenter() deliverNotification:ns_notification];
|
| - }
|
| -}
|
| -
|
| -std::set<std::string>
|
| -NotificationUIManagerMac::GetAllIdsByProfileAndSourceOrigin(
|
| - Profile* profile, const GURL& source_origin) {
|
| - std::set<std::string> notification_ids =
|
| - BalloonNotificationUIManager::GetAllIdsByProfileAndSourceOrigin(
|
| - profile, source_origin);
|
| -
|
| - for (NotificationMap::iterator it = notification_map_.begin();
|
| - it != notification_map_.end(); ++it) {
|
| - ControllerNotification* controller_notification = it->second;
|
| - Notification* model = controller_notification->model;
|
| - if (model->origin_url() == source_origin &&
|
| - profile->IsSameProfile(controller_notification->profile)) {
|
| - notification_ids.insert(model->notification_id());
|
| - }
|
| - }
|
| - return notification_ids;
|
| -}
|
| -
|
| -bool NotificationUIManagerMac::CancelById(const std::string& notification_id) {
|
| - NotificationMap::iterator it = notification_map_.find(notification_id);
|
| - if (it == notification_map_.end())
|
| - return BalloonNotificationUIManager::CancelById(notification_id);
|
| -
|
| - return RemoveNotification(it->second->view);
|
| -}
|
| -
|
| -bool NotificationUIManagerMac::CancelAllBySourceOrigin(
|
| - const GURL& source_origin) {
|
| - bool success =
|
| - BalloonNotificationUIManager::CancelAllBySourceOrigin(source_origin);
|
| -
|
| - for (NotificationMap::iterator it = notification_map_.begin();
|
| - it != notification_map_.end();) {
|
| - if (it->second->model->origin_url() == source_origin) {
|
| - // RemoveNotification will erase from the map, invalidating iterator
|
| - // references to the removed element.
|
| - success |= RemoveNotification((it++)->second->view);
|
| - } else {
|
| - ++it;
|
| - }
|
| - }
|
| -
|
| - return success;
|
| -}
|
| -
|
| -bool NotificationUIManagerMac::CancelAllByProfile(Profile* profile) {
|
| - bool success = BalloonNotificationUIManager::CancelAllByProfile(profile);
|
| -
|
| - for (NotificationMap::iterator it = notification_map_.begin();
|
| - it != notification_map_.end();) {
|
| - if (it->second->profile == profile) {
|
| - // RemoveNotification will erase from the map, invalidating iterator
|
| - // references to the removed element.
|
| - success |= RemoveNotification((it++)->second->view);
|
| - } else {
|
| - ++it;
|
| - }
|
| - }
|
| -
|
| - return success;
|
| -}
|
| -
|
| -void NotificationUIManagerMac::CancelAll() {
|
| - id<CrUserNotificationCenter> center = GetNotificationCenter();
|
| -
|
| - // Calling RemoveNotification would loop many times over, so just replicate
|
| - // a small bit of its logic here.
|
| - for (NotificationMap::iterator it = notification_map_.begin();
|
| - it != notification_map_.end();
|
| - ++it) {
|
| - it->second->model->Close(false);
|
| - delete it->second;
|
| - }
|
| - notification_map_.clear();
|
| -
|
| - // Clean up any lingering ones in the system tray.
|
| - [center removeAllDeliveredNotifications];
|
| -
|
| - BalloonNotificationUIManager::CancelAll();
|
| -}
|
| -
|
| -const Notification*
|
| -NotificationUIManagerMac::FindNotificationWithCocoaNotification(
|
| - id<CrUserNotification> notification) const {
|
| - std::string notification_id = base::SysNSStringToUTF8(
|
| - [notification.userInfo objectForKey:kNotificationIDKey]);
|
| -
|
| - NotificationMap::const_iterator it = notification_map_.find(notification_id);
|
| - if (it == notification_map_.end())
|
| - return NULL;
|
| -
|
| - return it->second->model;
|
| -}
|
| -
|
| -bool NotificationUIManagerMac::RemoveNotification(
|
| - id<CrUserNotification> notification) {
|
| - std::string notification_id = base::SysNSStringToUTF8(
|
| - [notification.userInfo objectForKey:kNotificationIDKey]);
|
| - id<CrUserNotificationCenter> center = GetNotificationCenter();
|
| -
|
| - // First remove all Cocoa notifications from the center that match the
|
| - // notification. Notifications in the system tray do not share pointer
|
| - // equality with the balloons or any other message delievered to the
|
| - // delegate, so this loop must be run through every time to clean up stale
|
| - // notifications.
|
| - NSArray* delivered_notifications = center.deliveredNotifications;
|
| - for (id<CrUserNotification> delivered in delivered_notifications) {
|
| - if ([delivered isEqual:notification]) {
|
| - [center removeDeliveredNotification:delivered];
|
| - }
|
| - }
|
| -
|
| - // Then clean up the C++ model side.
|
| - NotificationMap::iterator it = notification_map_.find(notification_id);
|
| - if (it == notification_map_.end())
|
| - return false;
|
| -
|
| - it->second->model->Close(false);
|
| - delete it->second;
|
| - notification_map_.erase(it);
|
| -
|
| - return true;
|
| -}
|
| -
|
| -id<CrUserNotification>
|
| -NotificationUIManagerMac::FindNotificationWithReplacementId(
|
| - const string16& replacement_id) const {
|
| - for (NotificationMap::const_iterator it = notification_map_.begin();
|
| - it != notification_map_.end();
|
| - ++it) {
|
| - if (it->second->model->replace_id() == replacement_id)
|
| - return it->second->view;
|
| - }
|
| - return nil;
|
| -}
|
| -
|
| -////////////////////////////////////////////////////////////////////////////////
|
| -
|
| -@implementation NotificationCenterDelegate
|
| -
|
| -- (id)initWithManager:(NotificationUIManagerMac*)manager {
|
| - if ((self = [super init])) {
|
| - CHECK(manager);
|
| - manager_ = manager;
|
| - }
|
| - return self;
|
| -}
|
| -
|
| -- (void)userNotificationCenter:(NSUserNotificationCenter*)center
|
| - didDeliverNotification:(id<CrUserNotification>)nsNotification {
|
| - const Notification* notification =
|
| - manager_->FindNotificationWithCocoaNotification(nsNotification);
|
| - if (notification)
|
| - notification->Display();
|
| -}
|
| -
|
| -- (void)userNotificationCenter:(NSUserNotificationCenter*)center
|
| - didActivateNotification:(id<CrUserNotification>)nsNotification {
|
| - const Notification* notification =
|
| - manager_->FindNotificationWithCocoaNotification(nsNotification);
|
| - if (notification)
|
| - notification->Click();
|
| -}
|
| -
|
| -- (BOOL)userNotificationCenter:(NSUserNotificationCenter*)center
|
| - shouldPresentNotification:(id<CrUserNotification>)nsNotification {
|
| - // Always display notifications, regardless of whether the app is foreground.
|
| - return YES;
|
| -}
|
| -
|
| -@end
|
|
|