| 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 |