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

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

Issue 2402303002: Implement the ability to close alerts programatically (Closed)
Patch Set: 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
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)closeNotification:(NSString*)notificationId
122 withProfile:(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_ closeNotification:candidate_id
254 withProfile:current_profile_id];
255 return;
256 }
257 #endif // ENABLE_XPC_NOTIFICATIONS
234 258
235 NSString* current_profile_id = base::SysUTF8ToNSString(profile_id);
236 for (NSUserNotification* toast in 259 for (NSUserNotification* toast in
237 [notification_center_ deliveredNotifications]) { 260 [notification_center_ deliveredNotifications]) {
238 NSString* toast_id = 261 NSString* toast_id =
239 [toast.userInfo objectForKey:notification_constants::kNotificationId]; 262 [toast.userInfo objectForKey:notification_constants::kNotificationId];
240 263
241 NSString* persistent_profile_id = [toast.userInfo 264 NSString* persistent_profile_id = [toast.userInfo
242 objectForKey:notification_constants::kNotificationProfileId]; 265 objectForKey:notification_constants::kNotificationProfileId];
243 266
244 if ([toast_id isEqualToString:candidate_id] && 267 if ([toast_id isEqualToString:candidate_id] &&
245 [persistent_profile_id isEqualToString:current_profile_id]) { 268 [persistent_profile_id isEqualToString:current_profile_id]) {
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 shouldPresentNotification:(NSUserNotification*)nsNotification { 419 shouldPresentNotification:(NSUserNotification*)nsNotification {
397 // Always display notifications, regardless of whether the app is foreground. 420 // Always display notifications, regardless of whether the app is foreground.
398 return YES; 421 return YES;
399 } 422 }
400 423
401 @end 424 @end
402 425
403 @implementation NotificationRemoteDispatcher { 426 @implementation NotificationRemoteDispatcher {
404 // The connection to the XPC server in charge of delivering alerts. 427 // The connection to the XPC server in charge of delivering alerts.
405 base::scoped_nsobject<NSXPCConnection> xpcConnection_; 428 base::scoped_nsobject<NSXPCConnection> xpcConnection_;
429 base::scoped_nsobject<NSMutableSet> alertsDisplayed_;
406 } 430 }
407 431
408 - (instancetype)init { 432 - (instancetype)init {
409 if ((self = [super init])) { 433 if ((self = [super init])) {
434 alertsDisplayed_.reset([[NSMutableSet alloc] init]);
Robert Sesek 2016/10/10 18:22:47 What is the purpose of this set? It looks like thi
Miguel Garcia 2016/10/11 11:55:41 It is consulted through isAlertDisplayed which is
Robert Sesek 2016/10/11 15:28:41 Sorry, missed that due to a find-in-page bug on Ma
410 xpcConnection_.reset([[NSXPCConnection alloc] 435 xpcConnection_.reset([[NSXPCConnection alloc]
411 initWithServiceName: 436 initWithServiceName:
412 [NSString 437 [NSString
413 stringWithFormat:notification_constants::kAlertXPCServiceName, 438 stringWithFormat:notification_constants::kAlertXPCServiceName,
414 [base::mac::OuterBundle() bundleIdentifier]]]); 439 [base::mac::OuterBundle() bundleIdentifier]]]);
415 xpcConnection_.get().remoteObjectInterface = 440 xpcConnection_.get().remoteObjectInterface =
416 [NSXPCInterface interfaceWithProtocol:@protocol(NotificationDelivery)]; 441 [NSXPCInterface interfaceWithProtocol:@protocol(NotificationDelivery)];
417 442
418 xpcConnection_.get().interruptionHandler = ^{ 443 xpcConnection_.get().interruptionHandler = ^{
419 LOG(WARNING) << "connection interrupted: interruptionHandler: "; 444 LOG(WARNING) << "connection interrupted: interruptionHandler: ";
(...skipping 11 matching lines...) Expand all
431 xpcConnection_.get().exportedInterface = 456 xpcConnection_.get().exportedInterface =
432 [NSXPCInterface interfaceWithProtocol:@protocol(NotificationReply)]; 457 [NSXPCInterface interfaceWithProtocol:@protocol(NotificationReply)];
433 xpcConnection_.get().exportedObject = self; 458 xpcConnection_.get().exportedObject = self;
434 [xpcConnection_ resume]; 459 [xpcConnection_ resume];
435 } 460 }
436 461
437 return self; 462 return self;
438 } 463 }
439 464
440 - (void)dispatchNotification:(NSDictionary*)data { 465 - (void)dispatchNotification:(NSDictionary*)data {
466 NSString* notificationId =
467 [data objectForKey:notification_constants::kNotificationId];
468 NSString* profileId =
469 [data objectForKey:notification_constants::kNotificationProfileId];
470 NSString* alertKey = [self _createAlertKeyWithNotification:notificationId
471 withProfile:profileId];
472 [alertsDisplayed_ addObject:alertKey];
441 [[xpcConnection_ remoteObjectProxy] deliverNotification:data]; 473 [[xpcConnection_ remoteObjectProxy] deliverNotification:data];
442 } 474 }
443 475
476 - (void)closeNotification:(NSString*)notificationId
477 withProfile:(NSString*)profileId {
478 NSString* alertKey = [self _createAlertKeyWithNotification:notificationId
479 withProfile:profileId];
480 [alertsDisplayed_ removeObject:alertKey];
481 [[xpcConnection_ remoteObjectProxy] closeNotification:notificationId
482 withProfile:profileId];
483 }
484
485 - (void)closeAllNotifications {
486 [alertsDisplayed_ removeAllObjects];
487 [[xpcConnection_ remoteObjectProxy] closeAllNotifications];
488 }
489
490 - (BOOL)isAlertDisplayed:(NSString*)notificationId
491 withProfile:(NSString*)profileId {
492 NSString* alertKey = [self _createAlertKeyWithNotification:notificationId
493 withProfile:profileId];
494 return [alertsDisplayed_ containsObject:alertKey];
495 }
496
497 // Creates a unique identifier for the notification. Only used for internal
498 // tracking.
499 - (NSString*)_createAlertKeyWithNotification:(NSString*)notificationId
Robert Sesek 2016/10/10 18:22:47 We don't name private methods with _.
Miguel Garcia 2016/10/11 11:55:41 Done.
500 withProfile:(NSString*)profileId {
501 return [NSString stringWithFormat:@"%@:%@", notificationId, profileId];
502 }
503
444 // NotificationReply implementation 504 // NotificationReply implementation
445 - (void)notificationClick:(NSDictionary*)notificationResponseData { 505 - (void)notificationClick:(NSDictionary*)notificationResponseData {
446 NotificationPlatformBridgeMac::ProcessNotificationResponse( 506 NotificationPlatformBridgeMac::ProcessNotificationResponse(
447 notificationResponseData); 507 notificationResponseData);
448 } 508 }
449 509
450 @end 510 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698