OLD | NEW |
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_platform_bridge_mac.h" | 5 #include "chrome/browser/notifications/notification_platform_bridge_mac.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 // A Cocoa class that represents the delegate of NSUserNotificationCenter and | 120 // A Cocoa class that represents the delegate of NSUserNotificationCenter and |
121 // can forward commands to C++. | 121 // can forward commands to C++. |
122 @interface NotificationCenterDelegate | 122 @interface NotificationCenterDelegate |
123 : NSObject<NSUserNotificationCenterDelegate> { | 123 : NSObject<NSUserNotificationCenterDelegate> { |
124 } | 124 } |
125 @end | 125 @end |
126 | 126 |
127 // Interface to communicate with the Alert XPC service. | 127 // Interface to communicate with the Alert XPC service. |
128 @interface AlertDispatcherImpl : NSObject<AlertDispatcher> | 128 @interface AlertDispatcherImpl : NSObject<AlertDispatcher> |
129 | 129 |
130 // Deliver a notification to the XPC service to be displayed as an alert. | |
131 - (void)dispatchNotification:(NSDictionary*)data; | |
132 | |
133 // Close a notification for a given |notificationId| and |profileId|. | |
134 - (void)closeNotificationWithId:(NSString*)notificationId | |
135 withProfileId:(NSString*)profileId; | |
136 | |
137 // Close all notifications. | |
138 - (void)closeAllNotifications; | |
139 | |
140 @end | 130 @end |
141 | 131 |
142 // ///////////////////////////////////////////////////////////////////////////// | 132 // ///////////////////////////////////////////////////////////////////////////// |
143 NotificationPlatformBridgeMac::NotificationPlatformBridgeMac( | 133 NotificationPlatformBridgeMac::NotificationPlatformBridgeMac( |
144 NSUserNotificationCenter* notification_center, | 134 NSUserNotificationCenter* notification_center, |
145 id<AlertDispatcher> alert_dispatcher) | 135 id<AlertDispatcher> alert_dispatcher) |
146 : delegate_([NotificationCenterDelegate alloc]), | 136 : delegate_([NotificationCenterDelegate alloc]), |
147 notification_center_([notification_center retain]), | 137 notification_center_([notification_center retain]), |
148 alert_dispatcher_([alert_dispatcher retain]) { | 138 alert_dispatcher_([alert_dispatcher retain]) { |
149 [notification_center_ setDelegate:delegate_.get()]; | 139 [notification_center_ setDelegate:delegate_.get()]; |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 if (!notification_removed) { | 276 if (!notification_removed) { |
287 [alert_dispatcher_ closeNotificationWithId:candidate_id | 277 [alert_dispatcher_ closeNotificationWithId:candidate_id |
288 withProfileId:current_profile_id]; | 278 withProfileId:current_profile_id]; |
289 } | 279 } |
290 #endif // ENABLE_XPC_NOTIFICATIONS | 280 #endif // ENABLE_XPC_NOTIFICATIONS |
291 } | 281 } |
292 | 282 |
293 void NotificationPlatformBridgeMac::GetDisplayed( | 283 void NotificationPlatformBridgeMac::GetDisplayed( |
294 const std::string& profile_id, | 284 const std::string& profile_id, |
295 bool incognito, | 285 bool incognito, |
296 const DisplayedNotificationsCallback& callback) const { | 286 const GetDisplayedNotificationsCallback& callback) const { |
| 287 #if BUILDFLAG(ENABLE_XPC_NOTIFICATIONS) |
| 288 [alert_dispatcher_ |
| 289 getDisplayedAlertsForProfileId:base::SysUTF8ToNSString(profile_id) |
| 290 incognito:incognito |
| 291 notificationCenter:notification_center_ |
| 292 callback:callback]; |
| 293 |
| 294 #else |
| 295 |
297 auto displayed_notifications = base::MakeUnique<std::set<std::string>>(); | 296 auto displayed_notifications = base::MakeUnique<std::set<std::string>>(); |
298 NSString* current_profile_id = base::SysUTF8ToNSString(profile_id); | 297 NSString* current_profile_id = base::SysUTF8ToNSString(profile_id); |
299 for (NSUserNotification* toast in | 298 for (NSUserNotification* toast in |
300 [notification_center_ deliveredNotifications]) { | 299 [notification_center_ deliveredNotifications]) { |
301 NSString* toast_profile_id = [toast.userInfo | 300 NSString* toast_profile_id = [toast.userInfo |
302 objectForKey:notification_constants::kNotificationProfileId]; | 301 objectForKey:notification_constants::kNotificationProfileId]; |
303 if ([toast_profile_id isEqualToString:current_profile_id]) { | 302 BOOL incognito_notification = [[toast.userInfo |
| 303 objectForKey:notification_constants::kNotificationIncognito] boolValue]; |
| 304 if ([toast_profile_id isEqualToString:current_profile_id] && |
| 305 incognito == incognito_notification) { |
304 displayed_notifications->insert(base::SysNSStringToUTF8([toast.userInfo | 306 displayed_notifications->insert(base::SysNSStringToUTF8([toast.userInfo |
305 objectForKey:notification_constants::kNotificationId])); | 307 objectForKey:notification_constants::kNotificationId])); |
306 } | 308 } |
307 } | 309 } |
308 content::BrowserThread::PostTask( | 310 content::BrowserThread::PostTask( |
309 content::BrowserThread::UI, FROM_HERE, | 311 content::BrowserThread::UI, FROM_HERE, |
310 base::Bind(callback, base::Passed(&displayed_notifications), | 312 base::Bind(callback, base::Passed(&displayed_notifications), |
311 true /* supports_synchronization */)); | 313 true /* supports_synchronization */)); |
| 314 |
| 315 #endif // ENABLE_XPC_NOTIFICATIONS |
312 } | 316 } |
313 | 317 |
314 // static | 318 // static |
315 void NotificationPlatformBridgeMac::ProcessNotificationResponse( | 319 void NotificationPlatformBridgeMac::ProcessNotificationResponse( |
316 NSDictionary* response) { | 320 NSDictionary* response) { |
317 if (!NotificationPlatformBridgeMac::VerifyNotificationData(response)) | 321 if (!NotificationPlatformBridgeMac::VerifyNotificationData(response)) |
318 return; | 322 return; |
319 | 323 |
320 NSNumber* button_index = | 324 NSNumber* button_index = |
321 [response objectForKey:notification_constants::kNotificationButtonIndex]; | 325 [response objectForKey:notification_constants::kNotificationButtonIndex]; |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
483 | 487 |
484 xpcConnection_.get().exportedInterface = | 488 xpcConnection_.get().exportedInterface = |
485 [NSXPCInterface interfaceWithProtocol:@protocol(NotificationReply)]; | 489 [NSXPCInterface interfaceWithProtocol:@protocol(NotificationReply)]; |
486 xpcConnection_.get().exportedObject = self; | 490 xpcConnection_.get().exportedObject = self; |
487 [xpcConnection_ resume]; | 491 [xpcConnection_ resume]; |
488 } | 492 } |
489 | 493 |
490 return self; | 494 return self; |
491 } | 495 } |
492 | 496 |
| 497 // AlertDispatcher: |
493 - (void)dispatchNotification:(NSDictionary*)data { | 498 - (void)dispatchNotification:(NSDictionary*)data { |
494 [[self serviceProxy] deliverNotification:data]; | 499 [[self serviceProxy] deliverNotification:data]; |
495 } | 500 } |
496 | 501 |
497 - (void)closeNotificationWithId:(NSString*)notificationId | 502 - (void)closeNotificationWithId:(NSString*)notificationId |
498 withProfileId:(NSString*)profileId { | 503 withProfileId:(NSString*)profileId { |
499 [[self serviceProxy] closeNotificationWithId:notificationId | 504 [[self serviceProxy] closeNotificationWithId:notificationId |
500 withProfileId:profileId]; | 505 withProfileId:profileId]; |
501 } | 506 } |
502 | 507 |
503 - (void)closeAllNotifications { | 508 - (void)closeAllNotifications { |
504 [[self serviceProxy] closeAllNotifications]; | 509 [[self serviceProxy] closeAllNotifications]; |
505 } | 510 } |
506 | 511 |
| 512 - (void) |
| 513 getDisplayedAlertsForProfileId:(NSString*)profileId |
| 514 incognito:(BOOL)incognito |
| 515 notificationCenter:(NSUserNotificationCenter*)notificationCenter |
| 516 callback:(GetDisplayedNotificationsCallback)callback { |
| 517 auto reply = ^(NSArray* alerts) { |
| 518 std::unique_ptr<std::set<std::string>> displayedNotifications = |
| 519 base::MakeUnique<std::set<std::string>>(); |
| 520 |
| 521 for (NSUserNotification* toast in |
| 522 [notificationCenter deliveredNotifications]) { |
| 523 NSString* toastProfileId = [toast.userInfo |
| 524 objectForKey:notification_constants::kNotificationProfileId]; |
| 525 BOOL incognitoNotification = [[toast.userInfo |
| 526 objectForKey:notification_constants::kNotificationIncognito] |
| 527 boolValue]; |
| 528 if ([toastProfileId isEqualToString:profileId] && |
| 529 incognito == incognitoNotification) { |
| 530 displayedNotifications->insert(base::SysNSStringToUTF8([toast.userInfo |
| 531 objectForKey:notification_constants::kNotificationId])); |
| 532 } |
| 533 } |
| 534 |
| 535 for (NSString* alert in alerts) |
| 536 displayedNotifications->insert(base::SysNSStringToUTF8(alert)); |
| 537 |
| 538 content::BrowserThread::PostTask( |
| 539 content::BrowserThread::UI, FROM_HERE, |
| 540 base::Bind(callback, base::Passed(&displayedNotifications), |
| 541 true /* supports_synchronization */)); |
| 542 }; |
| 543 |
| 544 [[self serviceProxy] getDisplayedAlertsForProfileId:profileId |
| 545 andIncognito:incognito |
| 546 withReply:reply]; |
| 547 } |
| 548 |
507 // NotificationReply: | 549 // NotificationReply: |
508 - (void)notificationClick:(NSDictionary*)notificationResponseData { | 550 - (void)notificationClick:(NSDictionary*)notificationResponseData { |
509 NotificationPlatformBridgeMac::ProcessNotificationResponse( | 551 NotificationPlatformBridgeMac::ProcessNotificationResponse( |
510 notificationResponseData); | 552 notificationResponseData); |
511 } | 553 } |
512 | 554 |
513 // Private methods: | 555 // Private methods: |
514 | 556 |
515 // Retrieves the connection's remoteObjectProxy. Always use this as opposed | 557 // Retrieves the connection's remoteObjectProxy. Always use this as opposed |
516 // to going directly through the connection, since this will ensure that the | 558 // to going directly through the connection, since this will ensure that the |
517 // service has its exception port configured for crash reporting. | 559 // service has its exception port configured for crash reporting. |
518 - (id<NotificationDelivery>)serviceProxy { | 560 - (id<NotificationDelivery>)serviceProxy { |
519 id<NotificationDelivery> proxy = [xpcConnection_ remoteObjectProxy]; | 561 id<NotificationDelivery> proxy = [xpcConnection_ remoteObjectProxy]; |
520 | 562 |
521 if (!setExceptionPort_) { | 563 if (!setExceptionPort_) { |
522 base::mac::ScopedMachSendRight exceptionPort( | 564 base::mac::ScopedMachSendRight exceptionPort( |
523 crash_reporter::GetCrashpadClient().GetHandlerMachPort()); | 565 crash_reporter::GetCrashpadClient().GetHandlerMachPort()); |
524 base::scoped_nsobject<CrXPCMachPort> xpcPort( | 566 base::scoped_nsobject<CrXPCMachPort> xpcPort( |
525 [[CrXPCMachPort alloc] initWithMachSendRight:std::move(exceptionPort)]); | 567 [[CrXPCMachPort alloc] initWithMachSendRight:std::move(exceptionPort)]); |
526 [proxy setMachExceptionPort:xpcPort]; | 568 [proxy setMachExceptionPort:xpcPort]; |
527 setExceptionPort_ = YES; | 569 setExceptionPort_ = YES; |
528 } | 570 } |
529 | 571 |
530 return proxy; | 572 return proxy; |
531 } | 573 } |
532 | 574 |
533 @end | 575 @end |
OLD | NEW |