Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(204)

Side by Side Diff: chrome/browser/notifications/notification_ui_manager_mac.mm

Issue 1814923002: Nuke NotificationUIManager from PlatformNotificationServiceImpl (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@profile_manager_load
Patch Set: Rebase Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/notifications/notification_ui_manager_mac.h" 5 #include "chrome/browser/notifications/notification_ui_manager_mac.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/mac/foundation_util.h" 10 #include "base/mac/foundation_util.h"
11 #include "base/mac/mac_util.h" 11 #include "base/mac/mac_util.h"
12 #include "base/strings/string_number_conversions.h" 12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/sys_string_conversions.h" 13 #include "base/strings/sys_string_conversions.h"
14 #include "chrome/browser/notifications/message_center_notification_display_servi ce.h"
14 #include "chrome/browser/notifications/notification.h" 15 #include "chrome/browser/notifications/notification.h"
15 #include "chrome/browser/notifications/persistent_notification_delegate.h" 16 #include "chrome/browser/notifications/persistent_notification_delegate.h"
16 #include "chrome/browser/notifications/platform_notification_service_impl.h" 17 #include "chrome/browser/notifications/platform_notification_service_impl.h"
17 #include "chrome/browser/profiles/profile.h" 18 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/profiles/profile_manager.h" 19 #include "chrome/browser/profiles/profile_manager.h"
19 #include "chrome/common/chrome_switches.h" 20 #include "chrome/common/chrome_switches.h"
20 #include "chrome/grit/generated_resources.h" 21 #include "chrome/grit/generated_resources.h"
21 #include "ui/base/l10n/l10n_util_mac.h" 22 #include "ui/base/l10n/l10n_util_mac.h"
22 #include "url/gurl.h" 23 #include "url/gurl.h"
23 24
(...skipping 15 matching lines...) Expand all
39 // TODO(miguelg) implement the following features 40 // TODO(miguelg) implement the following features
40 // - Sound names can be implemented by setting soundName in NSUserNotification 41 // - Sound names can be implemented by setting soundName in NSUserNotification
41 // NSUserNotificationDefaultSoundName gives you the platform default. 42 // NSUserNotificationDefaultSoundName gives you the platform default.
42 43
43 namespace { 44 namespace {
44 45
45 // Keys in NSUserNotification.userInfo to map chrome notifications to 46 // Keys in NSUserNotification.userInfo to map chrome notifications to
46 // native ones. 47 // native ones.
47 NSString* const kNotificationOriginKey = @"notification_origin"; 48 NSString* const kNotificationOriginKey = @"notification_origin";
48 NSString* const kNotificationPersistentIdKey = @"notification_persistent_id"; 49 NSString* const kNotificationPersistentIdKey = @"notification_persistent_id";
49 NSString* const kNotificationDelegateIdKey = @"notification_delegate_id";
50 50
51 // TODO(miguelg) get rid of this key once ProfileID has been ported
52 // from the void* it is today to the stable identifier provided
53 // in kNotificationProfilePersistentIdKey.
54 NSString* const kNotificationProfileIdKey = @"notification_profile_id";
55 NSString* const kNotificationProfilePersistentIdKey = 51 NSString* const kNotificationProfilePersistentIdKey =
56 @"notification_profile_persistent_id"; 52 @"notification_profile_persistent_id";
57 NSString* const kNotificationIncognitoKey = @"notification_incognito"; 53 NSString* const kNotificationIncognitoKey = @"notification_incognito";
58 54
59 } // namespace 55 } // namespace
60 56
61 // Only use native notifications for web, behind a flag and on 10.8+ 57 #if defined(OS_MACOSX)
Peter Beverloo 2016/03/21 15:57:04 When is this ever not true?
58 // Only use native notifications for web, behind a flag
62 // static 59 // static
63 NotificationUIManager* 60 NotificationDisplayService* NotificationDisplayService::Create(
64 NotificationUIManager::CreateNativeNotificationManager() { 61 Profile* profile) {
65 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 62 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
66 switches::kEnableNativeNotifications) && 63 switches::kEnableNativeNotifications)) {
67 base::mac::IsOSMountainLionOrLater()) { 64 return new NotificationUIManagerMac(
68 return new NotificationUIManagerMac(); 65 profile, [NSUserNotificationCenter defaultUserNotificationCenter]);
69 } 66 }
70 return nullptr; 67
68 // Fall back to the MessageCenter backed Display Service.
69 return new MessageCenterNotificationDisplayService(profile);
71 } 70 }
71 #endif
72 72
73 // A Cocoa class that represents the delegate of NSUserNotificationCenter and 73 // A Cocoa class that represents the delegate of NSUserNotificationCenter and
74 // can forward commands to C++. 74 // can forward commands to C++.
75 @interface NotificationCenterDelegate 75 @interface NotificationCenterDelegate
76 : NSObject<NSUserNotificationCenterDelegate> { 76 : NSObject<NSUserNotificationCenterDelegate> {
77 @private 77 @private
78 NotificationUIManagerMac* manager_; // Weak, owns self. 78 NotificationUIManagerMac* manager_; // Weak, owns self.
79 } 79 }
80 - (id)initWithManager:(NotificationUIManagerMac*)manager; 80 - (id)initWithManager:(NotificationUIManagerMac*)manager;
81 @end 81 @end
82 82
83 // ///////////////////////////////////////////////////////////////////////////// 83 // /////////////////////////////////////////////////////////////////////////////
84 84
85 NotificationUIManagerMac::NotificationUIManagerMac() 85 NotificationUIManagerMac::NotificationUIManagerMac(
86 : delegate_([[NotificationCenterDelegate alloc] initWithManager:this]) { 86 Profile* profile,
87 [[NSUserNotificationCenter defaultUserNotificationCenter] 87 NSUserNotificationCenter* notification_center)
88 setDelegate:delegate_.get()]; 88 : NotificationDisplayService(profile),
89 delegate_([[NotificationCenterDelegate alloc] initWithManager:this]),
90 notification_center_(notification_center) {
91 [notification_center_ setDelegate:delegate_.get()];
89 } 92 }
90 93
91 NotificationUIManagerMac::~NotificationUIManagerMac() { 94 NotificationUIManagerMac::~NotificationUIManagerMac() {
92 [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:nil]; 95 [notification_center_ setDelegate:nil];
93 CancelAll(); 96 [notification_center_ removeAllDeliveredNotifications];
94 } 97 }
95 98
96 void NotificationUIManagerMac::Add(const Notification& notification, 99 void NotificationUIManagerMac::Display(const Notification& notification) {
97 Profile* profile) {
98 // The Mac notification UI manager only supports Web Notifications, which 100 // The Mac notification UI manager only supports Web Notifications, which
99 // have a PersistentNotificationDelegate. The persistent id of the 101 // have a PersistentNotificationDelegate. The persistent id of the
100 // notification is exposed through it's interface. 102 // notification is exposed through it's interface.
101 PersistentNotificationDelegate* delegate = 103 PersistentNotificationDelegate* delegate =
102 static_cast<PersistentNotificationDelegate*>(notification.delegate()); 104 static_cast<PersistentNotificationDelegate*>(notification.delegate());
103 DCHECK(delegate); 105 DCHECK(delegate);
104 106
105 base::scoped_nsobject<NSUserNotification> toast( 107 base::scoped_nsobject<NSUserNotification> toast(
106 [[NSUserNotification alloc] init]); 108 [[NSUserNotification alloc] init]);
107 [toast setTitle:base::SysUTF16ToNSString(notification.title())]; 109 [toast setTitle:base::SysUTF16ToNSString(notification.title())];
108 [toast setSubtitle:base::SysUTF16ToNSString(notification.message())]; 110 [toast setSubtitle:base::SysUTF16ToNSString(notification.message())];
109 111
110 // TODO(miguelg): try to elide the origin perhaps See NSString 112 // TODO(miguelg): try to elide the origin perhaps See NSString
111 // stringWithFormat. It seems that the informativeText font is constant. 113 // stringWithFormat. It seems that the informativeText font is constant.
112 NSString* informativeText = 114 NSString* informative_text =
113 notification.context_message().empty() 115 notification.context_message().empty()
114 ? base::SysUTF8ToNSString(notification.origin_url().spec()) 116 ? base::SysUTF8ToNSString(notification.origin_url().spec())
115 : base::SysUTF16ToNSString(notification.context_message()); 117 : base::SysUTF16ToNSString(notification.context_message());
116 [toast setInformativeText:informativeText]; 118 [toast setInformativeText:informative_text];
117 119
118 // Some functionality is only available in 10.9+ or requires private APIs 120 // Some functionality requires private APIs
119 // Icon 121 // Icon
120 if ([toast respondsToSelector:@selector(_identityImage)] && 122 if ([toast respondsToSelector:@selector(_identityImage)] &&
121 !notification.icon().IsEmpty()) { 123 !notification.icon().IsEmpty()) {
122 [toast setValue:notification.icon().ToNSImage() forKey:@"_identityImage"]; 124 [toast setValue:notification.icon().ToNSImage() forKey:@"_identityImage"];
123 [toast setValue:@NO forKey:@"_identityImageHasBorder"]; 125 [toast setValue:@NO forKey:@"_identityImageHasBorder"];
124 } 126 }
125 127
126 // Buttons 128 // Buttons
127 if ([toast respondsToSelector:@selector(_showsButtons)]) { 129 if ([toast respondsToSelector:@selector(_showsButtons)]) {
128 [toast setValue:@YES forKey:@"_showsButtons"]; 130 [toast setValue:@YES forKey:@"_showsButtons"];
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 [existing_notification valueForKey:@"identifier"]; 181 [existing_notification valueForKey:@"identifier"];
180 if ([identifier isEqual:base::SysUTF8ToNSString(notification.tag())]) { 182 if ([identifier isEqual:base::SysUTF8ToNSString(notification.tag())]) {
181 [notification_center 183 [notification_center
182 removeDeliveredNotification:existing_notification]; 184 removeDeliveredNotification:existing_notification];
183 break; 185 break;
184 } 186 }
185 } 187 }
186 } 188 }
187 } 189 }
188 190
189 int64_t persistent_notification_id = delegate->persistent_notification_id(); 191 std::string persistent_notification_id =
190 int64_t profile_id = reinterpret_cast<int64_t>(GetProfileID(profile)); 192 base::Int64ToString(delegate->persistent_notification_id());
191 193
192 toast.get().userInfo = @{ 194 toast.get().userInfo = @{
193 kNotificationOriginKey : 195 kNotificationOriginKey :
194 base::SysUTF8ToNSString(notification.origin_url().spec()), 196 base::SysUTF8ToNSString(notification.origin_url().spec()),
195 kNotificationPersistentIdKey : 197 kNotificationPersistentIdKey :
196 [NSNumber numberWithLongLong:persistent_notification_id], 198 base::SysUTF8ToNSString(persistent_notification_id),
197 kNotificationDelegateIdKey :
198 base::SysUTF8ToNSString(notification.delegate_id()),
199 kNotificationProfileIdKey : [NSNumber numberWithLongLong:profile_id],
200 kNotificationProfilePersistentIdKey : 199 kNotificationProfilePersistentIdKey :
201 base::SysUTF8ToNSString(profile->GetPath().BaseName().value()), 200 base::SysUTF8ToNSString(profile_->GetPath().BaseName().value()),
202 kNotificationIncognitoKey : 201 kNotificationIncognitoKey :
203 [NSNumber numberWithBool:profile->IsOffTheRecord()] 202 [NSNumber numberWithBool:profile_->IsOffTheRecord()]
204 }; 203 };
205 204
206 [[NSUserNotificationCenter defaultUserNotificationCenter] 205 [notification_center_ deliverNotification:toast];
207 deliverNotification:toast];
208 } 206 }
209 207
210 bool NotificationUIManagerMac::Update(const Notification& notification, 208 bool NotificationUIManagerMac::Close(
211 Profile* profile) { 209 const std::string& persistent_notification_id) {
212 NOTREACHED(); 210 NSString* candidate_id = base::SysUTF8ToNSString(persistent_notification_id);
213 return false;
214 }
215 211
216 const Notification* NotificationUIManagerMac::FindById( 212 NSString* current_profile_id =
217 const std::string& delegate_id, 213 base::SysUTF8ToNSString(profile_->GetPath().BaseName().value());
218 ProfileID profile_id) const { 214 for (NSUserNotification* toast in
219 NOTREACHED(); 215 [notification_center_ deliveredNotifications]) {
220 return nil; 216 NSString* toast_id =
221 } 217 [toast.userInfo objectForKey:kNotificationPersistentIdKey];
222 218
223 bool NotificationUIManagerMac::CancelById(const std::string& delegate_id, 219 NSString* persistent_profile_id =
224 ProfileID profile_id) { 220 [toast.userInfo objectForKey:kNotificationProfilePersistentIdKey];
225 int64_t persistent_notification_id = 0;
226 // TODO(peter): Use the |delegate_id| directly when notification ids are being
227 // generated by content/ instead of us.
228 if (!base::StringToInt64(delegate_id, &persistent_notification_id))
229 return false;
230 221
231 NSUserNotificationCenter* notificationCenter = 222 if (toast_id == candidate_id &&
232 [NSUserNotificationCenter defaultUserNotificationCenter]; 223 persistent_profile_id == current_profile_id) {
233 for (NSUserNotification* toast in 224 [notification_center_ removeDeliveredNotification:toast];
234 [notificationCenter deliveredNotifications]) {
235 NSNumber* toast_id =
236 [toast.userInfo objectForKey:kNotificationPersistentIdKey];
237 if (toast_id.longLongValue == persistent_notification_id) {
238 [notificationCenter removeDeliveredNotification:toast];
239 return true; 225 return true;
240 } 226 }
241 } 227 }
242 228
243 return false; 229 return false;
244 } 230 }
245 231
246 std::set<std::string> 232 std::set<std::string> NotificationUIManagerMac::GetDisplayed() const {
247 NotificationUIManagerMac::GetAllIdsByProfileAndSourceOrigin( 233 // For now, when chrome quits we cancel all pending notifications.
248 ProfileID profile_id, 234 std::set<std::string> notification_ids;
249 const GURL& source) { 235 NSString* current_profile_id =
250 NOTREACHED(); 236 base::SysUTF8ToNSString(profile_->GetPath().BaseName().value());
251 return std::set<std::string>(); 237 for (NSUserNotification* toast in
238 [notification_center_ deliveredNotifications]) {
239 NSString* toast_profile_id =
240 [toast.userInfo objectForKey:kNotificationProfilePersistentIdKey];
241 if (toast_profile_id == current_profile_id) {
242 notification_ids.insert(base::SysNSStringToUTF8(
243 [toast.userInfo objectForKey:kNotificationPersistentIdKey]));
244 }
245 }
246 return notification_ids;
252 } 247 }
253 248
254 std::set<std::string> NotificationUIManagerMac::GetAllIdsByProfile( 249 bool NotificationUIManagerMac::SupportsNotificationCenter() const {
255 ProfileID profile_id) { 250 return true;
256 // ProfileID in mac is not safe to use across browser restarts
257 // Therefore because when chrome quits we cancel all pending notifications.
258 // TODO(miguelg) get rid of ProfileID as a void* for native notifications.
259 std::set<std::string> delegate_ids;
260 NSUserNotificationCenter* notificationCenter =
261 [NSUserNotificationCenter defaultUserNotificationCenter];
262 for (NSUserNotification* toast in
263 [notificationCenter deliveredNotifications]) {
264 NSNumber* toast_profile_id =
265 [toast.userInfo objectForKey:kNotificationProfileIdKey];
266 if (toast_profile_id.longLongValue ==
267 reinterpret_cast<int64_t>(profile_id)) {
268 delegate_ids.insert(base::SysNSStringToUTF8(
269 [toast.userInfo objectForKey:kNotificationDelegateIdKey]));
270 }
271 }
272 return delegate_ids;
273 }
274
275 bool NotificationUIManagerMac::CancelAllBySourceOrigin(
276 const GURL& source_origin) {
277 NOTREACHED();
278 return false;
279 }
280
281 bool NotificationUIManagerMac::CancelAllByProfile(ProfileID profile_id) {
282 NOTREACHED();
283 return false;
284 }
285
286 void NotificationUIManagerMac::CancelAll() {
287 [[NSUserNotificationCenter defaultUserNotificationCenter]
288 removeAllDeliveredNotifications];
289 } 251 }
290 252
291 // ///////////////////////////////////////////////////////////////////////////// 253 // /////////////////////////////////////////////////////////////////////////////
292 254
293 @implementation NotificationCenterDelegate 255 @implementation NotificationCenterDelegate
294 256
295 - (id)initWithManager:(NotificationUIManagerMac*)manager { 257 - (id)initWithManager:(NotificationUIManagerMac*)manager {
296 if ((self = [super init])) { 258 if ((self = [super init])) {
297 DCHECK(manager); 259 DCHECK(manager);
298 manager_ = manager; 260 manager_ = manager;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 persistentNotificationId.longLongValue, buttonIndex); 322 persistentNotificationId.longLongValue, buttonIndex);
361 } 323 }
362 324
363 - (BOOL)userNotificationCenter:(NSUserNotificationCenter*)center 325 - (BOOL)userNotificationCenter:(NSUserNotificationCenter*)center
364 shouldPresentNotification:(NSUserNotification*)nsNotification { 326 shouldPresentNotification:(NSUserNotification*)nsNotification {
365 // Always display notifications, regardless of whether the app is foreground. 327 // Always display notifications, regardless of whether the app is foreground.
366 return YES; 328 return YES;
367 } 329 }
368 330
369 @end 331 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698