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

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

Issue 2402303002: Implement the ability to close alerts programatically (Closed)
Patch Set: review Created 4 years, 2 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
« no previous file with comments | « no previous file | chrome/browser/ui/cocoa/notifications/alert_notification_service.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_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 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 // A Cocoa class that represents the delegate of NSUserNotificationCenter and 107 // A Cocoa class that represents the delegate of NSUserNotificationCenter and
108 // can forward commands to C++. 108 // can forward commands to C++.
109 @interface NotificationCenterDelegate 109 @interface NotificationCenterDelegate
110 : NSObject<NSUserNotificationCenterDelegate> { 110 : NSObject<NSUserNotificationCenterDelegate> {
111 } 111 }
112 @end 112 @end
113 113
114 // Interface to communicate with the Alert XPC service. 114 // Interface to communicate with the Alert XPC service.
115 @interface NotificationRemoteDispatcher : NSObject 115 @interface NotificationRemoteDispatcher : NSObject
116 116
117 // Deliver a notification to the XPC service to be displayed as an alert.
117 - (void)dispatchNotification:(NSDictionary*)data; 118 - (void)dispatchNotification:(NSDictionary*)data;
118 119
120 // CLose a notification for a given |notificationId| and |profileId|.
121 - (void)closeNotificationWithId:(NSString*)notificationId
122 withProfileId:(NSString*)profileId;
123
124 // Close all notifications.
125 - (void)closeAllNotifications;
126
127 // Return true if an alert with the given |notificationId| and |profileId|
128 // is being displayed. This is based on cached results so it might not
129 // be totally accurate.
130 - (BOOL)isAlertDisplayed:(NSString*)notificationId
131 withProfile:(NSString*)profileId;
119 @end 132 @end
120 133
121 // ///////////////////////////////////////////////////////////////////////////// 134 // /////////////////////////////////////////////////////////////////////////////
122 135
123 NotificationPlatformBridgeMac::NotificationPlatformBridgeMac( 136 NotificationPlatformBridgeMac::NotificationPlatformBridgeMac(
124 NSUserNotificationCenter* notification_center) 137 NSUserNotificationCenter* notification_center)
125 : delegate_([NotificationCenterDelegate alloc]), 138 : delegate_([NotificationCenterDelegate alloc]),
126 notification_center_(notification_center), 139 notification_center_(notification_center),
127 #if BUILDFLAG(ENABLE_XPC_NOTIFICATIONS) 140 #if BUILDFLAG(ENABLE_XPC_NOTIFICATIONS)
128 notification_remote_dispatcher_( 141 notification_remote_dispatcher_(
129 [[NotificationRemoteDispatcher alloc] init]) 142 [[NotificationRemoteDispatcher alloc] init])
130 #else 143 #else
131 notification_remote_dispatcher_(nullptr) 144 notification_remote_dispatcher_(nullptr)
132 #endif // ENABLE_XPC_NOTIFICATIONS 145 #endif // ENABLE_XPC_NOTIFICATIONS
133 { 146 {
134 [notification_center_ setDelegate:delegate_.get()]; 147 [notification_center_ setDelegate:delegate_.get()];
135 } 148 }
136 149
137 NotificationPlatformBridgeMac::~NotificationPlatformBridgeMac() { 150 NotificationPlatformBridgeMac::~NotificationPlatformBridgeMac() {
138 [notification_center_ setDelegate:nil]; 151 [notification_center_ setDelegate:nil];
139 152
140 // TODO(miguelg) remove only alerts shown by the XPC service.
141 // TODO(miguelg) do not remove banners if possible. 153 // TODO(miguelg) do not remove banners if possible.
142 [notification_center_ removeAllDeliveredNotifications]; 154 [notification_center_ removeAllDeliveredNotifications];
155 #if BUILDFLAG(ENABLE_XPC_NOTIFICATIONS)
156 [notification_remote_dispatcher_ closeAllNotifications];
157 #endif // BUILDFLAG(ENABLE_XPC_NOTIFICATIONS)
143 } 158 }
144 159
145 void NotificationPlatformBridgeMac::Display( 160 void NotificationPlatformBridgeMac::Display(
146 NotificationCommon::Type notification_type, 161 NotificationCommon::Type notification_type,
147 const std::string& notification_id, 162 const std::string& notification_id,
148 const std::string& profile_id, 163 const std::string& profile_id,
149 bool incognito, 164 bool incognito,
150 const Notification& notification) { 165 const Notification& notification) {
151 base::scoped_nsobject<NotificationBuilder> builder( 166 base::scoped_nsobject<NotificationBuilder> builder(
152 [[NotificationBuilder alloc] 167 [[NotificationBuilder alloc]
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 } 239 }
225 #else 240 #else
226 NSUserNotification* toast = [builder buildUserNotification]; 241 NSUserNotification* toast = [builder buildUserNotification];
227 [notification_center_ deliverNotification:toast]; 242 [notification_center_ deliverNotification:toast];
228 #endif // ENABLE_XPC_NOTIFICATIONS 243 #endif // ENABLE_XPC_NOTIFICATIONS
229 } 244 }
230 245
231 void NotificationPlatformBridgeMac::Close(const std::string& profile_id, 246 void NotificationPlatformBridgeMac::Close(const std::string& profile_id,
232 const std::string& notification_id) { 247 const std::string& notification_id) {
233 NSString* candidate_id = base::SysUTF8ToNSString(notification_id); 248 NSString* candidate_id = base::SysUTF8ToNSString(notification_id);
249 NSString* current_profile_id = base::SysUTF8ToNSString(profile_id);
250 #if BUILDFLAG(ENABLE_XPC_NOTIFICATIONS)
251 if ([notification_remote_dispatcher_ isAlertDisplayed:candidate_id
252 withProfile:current_profile_id]) {
253 [notification_remote_dispatcher_
254 closeNotificationWithId:candidate_id
255 withProfileId:current_profile_id];
256 return;
257 }
258 #endif // ENABLE_XPC_NOTIFICATIONS
234 259
235 NSString* current_profile_id = base::SysUTF8ToNSString(profile_id);
236 for (NSUserNotification* toast in 260 for (NSUserNotification* toast in
237 [notification_center_ deliveredNotifications]) { 261 [notification_center_ deliveredNotifications]) {
238 NSString* toast_id = 262 NSString* toast_id =
239 [toast.userInfo objectForKey:notification_constants::kNotificationId]; 263 [toast.userInfo objectForKey:notification_constants::kNotificationId];
240 264
241 NSString* persistent_profile_id = [toast.userInfo 265 NSString* persistent_profile_id = [toast.userInfo
242 objectForKey:notification_constants::kNotificationProfileId]; 266 objectForKey:notification_constants::kNotificationProfileId];
243 267
244 if ([toast_id isEqualToString:candidate_id] && 268 if ([toast_id isEqualToString:candidate_id] &&
245 [persistent_profile_id isEqualToString:current_profile_id]) { 269 [persistent_profile_id isEqualToString:current_profile_id]) {
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 shouldPresentNotification:(NSUserNotification*)nsNotification { 420 shouldPresentNotification:(NSUserNotification*)nsNotification {
397 // Always display notifications, regardless of whether the app is foreground. 421 // Always display notifications, regardless of whether the app is foreground.
398 return YES; 422 return YES;
399 } 423 }
400 424
401 @end 425 @end
402 426
403 @implementation NotificationRemoteDispatcher { 427 @implementation NotificationRemoteDispatcher {
404 // The connection to the XPC server in charge of delivering alerts. 428 // The connection to the XPC server in charge of delivering alerts.
405 base::scoped_nsobject<NSXPCConnection> xpcConnection_; 429 base::scoped_nsobject<NSXPCConnection> xpcConnection_;
430 base::scoped_nsobject<NSMutableSet> alertsDisplayed_;
Peter Beverloo 2016/10/11 14:37:49 Instead of caching which alerts we still think are
Miguel Garcia 2016/10/12 11:30:21 Given you both had concerns on the cache approach
406 } 431 }
407 432
408 - (instancetype)init { 433 - (instancetype)init {
409 if ((self = [super init])) { 434 if ((self = [super init])) {
435 alertsDisplayed_.reset([[NSMutableSet alloc] init]);
410 xpcConnection_.reset([[NSXPCConnection alloc] 436 xpcConnection_.reset([[NSXPCConnection alloc]
411 initWithServiceName: 437 initWithServiceName:
412 [NSString 438 [NSString
413 stringWithFormat:notification_constants::kAlertXPCServiceName, 439 stringWithFormat:notification_constants::kAlertXPCServiceName,
414 [base::mac::OuterBundle() bundleIdentifier]]]); 440 [base::mac::OuterBundle() bundleIdentifier]]]);
415 xpcConnection_.get().remoteObjectInterface = 441 xpcConnection_.get().remoteObjectInterface =
416 [NSXPCInterface interfaceWithProtocol:@protocol(NotificationDelivery)]; 442 [NSXPCInterface interfaceWithProtocol:@protocol(NotificationDelivery)];
417 443
418 xpcConnection_.get().interruptionHandler = ^{ 444 xpcConnection_.get().interruptionHandler = ^{
419 LOG(WARNING) << "connection interrupted: interruptionHandler: "; 445 LOG(WARNING) << "connection interrupted: interruptionHandler: ";
(...skipping 11 matching lines...) Expand all
431 xpcConnection_.get().exportedInterface = 457 xpcConnection_.get().exportedInterface =
432 [NSXPCInterface interfaceWithProtocol:@protocol(NotificationReply)]; 458 [NSXPCInterface interfaceWithProtocol:@protocol(NotificationReply)];
433 xpcConnection_.get().exportedObject = self; 459 xpcConnection_.get().exportedObject = self;
434 [xpcConnection_ resume]; 460 [xpcConnection_ resume];
435 } 461 }
436 462
437 return self; 463 return self;
438 } 464 }
439 465
440 - (void)dispatchNotification:(NSDictionary*)data { 466 - (void)dispatchNotification:(NSDictionary*)data {
467 NSString* notificationId =
468 [data objectForKey:notification_constants::kNotificationId];
469 NSString* profileId =
470 [data objectForKey:notification_constants::kNotificationProfileId];
471 NSString* alertKey = [self createAlertKeyWithNotification:notificationId
472 withProfile:profileId];
473 [alertsDisplayed_ addObject:alertKey];
441 [[xpcConnection_ remoteObjectProxy] deliverNotification:data]; 474 [[xpcConnection_ remoteObjectProxy] deliverNotification:data];
442 } 475 }
443 476
477 - (void)closeNotificationWithId:(NSString*)notificationId
478 withProfileId:(NSString*)profileId {
479 NSString* alertKey = [self createAlertKeyWithNotification:notificationId
480 withProfile:profileId];
481 [alertsDisplayed_ removeObject:alertKey];
482 [[xpcConnection_ remoteObjectProxy] closeNotificationWithId:notificationId
483 withProfileId:profileId];
484 }
485
486 - (void)closeAllNotifications {
487 [alertsDisplayed_ removeAllObjects];
488 [[xpcConnection_ remoteObjectProxy] closeAllNotifications];
489 }
490
491 - (BOOL)isAlertDisplayed:(NSString*)notificationId
492 withProfile:(NSString*)profileId {
493 NSString* alertKey = [self createAlertKeyWithNotification:notificationId
494 withProfile:profileId];
495 return [alertsDisplayed_ containsObject:alertKey];
496 }
497
498 // Creates a unique identifier for the notification. Only used for internal
499 // tracking.
500 - (NSString*)createAlertKeyWithNotification:(NSString*)notificationId
501 withProfile:(NSString*)profileId {
502 return [NSString stringWithFormat:@"%@:%@", notificationId, profileId];
503 }
504
444 // NotificationReply implementation 505 // NotificationReply implementation
445 - (void)notificationClick:(NSDictionary*)notificationResponseData { 506 - (void)notificationClick:(NSDictionary*)notificationResponseData {
446 NotificationPlatformBridgeMac::ProcessNotificationResponse( 507 NotificationPlatformBridgeMac::ProcessNotificationResponse(
447 notificationResponseData); 508 notificationResponseData);
448 } 509 }
449 510
450 @end 511 @end
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/ui/cocoa/notifications/alert_notification_service.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698