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

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

Issue 2093953002: Introduce a new API to handle native notification clicks (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: initial review Created 4 years, 5 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/mac/foundation_util.h" 9 #include "base/mac/foundation_util.h"
10 #include "base/mac/mac_util.h" 10 #include "base/mac/mac_util.h"
11 #include "base/strings/string_number_conversions.h" 11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/sys_string_conversions.h" 12 #include "base/strings/sys_string_conversions.h"
13 #include "chrome/browser/browser_process.h" 13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/notifications/native_notification_display_service.h"
14 #include "chrome/browser/notifications/notification.h" 15 #include "chrome/browser/notifications/notification.h"
15 #include "chrome/browser/notifications/notification_common.h" 16 #include "chrome/browser/notifications/notification_common.h"
16 #include "chrome/browser/notifications/notification_display_service_factory.h" 17 #include "chrome/browser/notifications/notification_display_service_factory.h"
17 #include "chrome/browser/notifications/persistent_notification_delegate.h" 18 #include "chrome/browser/notifications/persistent_notification_delegate.h"
18 #include "chrome/browser/notifications/platform_notification_service_impl.h" 19 #include "chrome/browser/notifications/platform_notification_service_impl.h"
19 #include "chrome/browser/profiles/profile.h" 20 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/browser/profiles/profile_manager.h" 21 #include "chrome/browser/profiles/profile_manager.h"
21 #include "chrome/browser/ui/cocoa/notifications/notification_builder_mac.h" 22 #include "chrome/browser/ui/cocoa/notifications/notification_builder_mac.h"
22 #include "chrome/browser/ui/cocoa/notifications/notification_constants_mac.h" 23 #include "chrome/browser/ui/cocoa/notifications/notification_constants_mac.h"
23 #import "chrome/browser/ui/cocoa/notifications/notification_response_builder_mac .h" 24 #import "chrome/browser/ui/cocoa/notifications/notification_response_builder_mac .h"
(...skipping 16 matching lines...) Expand all
40 // notification#icon in NSUserNotification.contentImage (10.9) 41 // notification#icon in NSUserNotification.contentImage (10.9)
41 // Site settings button is implemented as NSUserNotification's action button 42 // Site settings button is implemented as NSUserNotification's action button
42 // Not possible to implement: 43 // Not possible to implement:
43 // -notification.requireInteraction 44 // -notification.requireInteraction
44 // -The event associated to the close button 45 // -The event associated to the close button
45 46
46 // TODO(miguelg) implement the following features 47 // TODO(miguelg) implement the following features
47 // - Sound names can be implemented by setting soundName in NSUserNotification 48 // - Sound names can be implemented by setting soundName in NSUserNotification
48 // NSUserNotificationDefaultSoundName gives you the platform default. 49 // NSUserNotificationDefaultSoundName gives you the platform default.
49 50
51 namespace {
52 // Callback to run once the profile has been loaded in order to perform a
Peter Beverloo 2016/07/05 14:25:35 micro nit: blank line above here
Miguel Garcia 2016/07/05 17:12:53 Done.
53 // given |operation| in a notification.
54 void ProfileLoadedCallback(NotificationCommon::Operation operation,
55 NotificationCommon::Type notification_type,
56 const std::string& origin,
57 const std::string& notification_id,
58 int action_index,
59 Profile* profile) {
60 if (!profile) {
61 // TODO(miguelg): Add UMA for this condition.
62 // Perhaps propagate this through PersistentNotificationStatus.
63 LOG(WARNING) << "Profile not loaded correctly";
64 return;
65 }
66
67 NotificationDisplayService* display_service =
68 NotificationDisplayServiceFactory::GetForProfile(profile);
69
70 static_cast<NativeNotificationDisplayService*>(display_service)
71 ->ProcessNotificationOperation(operation, notification_type, origin,
72 notification_id, action_index);
73 }
74
75 } // namespace
50 76
51 // static 77 // static
52 NotificationPlatformBridge* NotificationPlatformBridge::Create() { 78 NotificationPlatformBridge* NotificationPlatformBridge::Create() {
53 return new NotificationPlatformBridgeMac( 79 return new NotificationPlatformBridgeMac(
54 [NSUserNotificationCenter defaultUserNotificationCenter]); 80 [NSUserNotificationCenter defaultUserNotificationCenter]);
55 } 81 }
56 82
57 // A Cocoa class that represents the delegate of NSUserNotificationCenter and 83 // A Cocoa class that represents the delegate of NSUserNotificationCenter and
58 // can forward commands to C++. 84 // can forward commands to C++.
59 @interface NotificationCenterDelegate 85 @interface NotificationCenterDelegate
(...skipping 10 matching lines...) Expand all
70 [notification_center_ setDelegate:delegate_.get()]; 96 [notification_center_ setDelegate:delegate_.get()];
71 } 97 }
72 98
73 NotificationPlatformBridgeMac::~NotificationPlatformBridgeMac() { 99 NotificationPlatformBridgeMac::~NotificationPlatformBridgeMac() {
74 [notification_center_ setDelegate:nil]; 100 [notification_center_ setDelegate:nil];
75 101
76 // TODO(miguelg) lift this restriction if possible. 102 // TODO(miguelg) lift this restriction if possible.
77 [notification_center_ removeAllDeliveredNotifications]; 103 [notification_center_ removeAllDeliveredNotifications];
78 } 104 }
79 105
80 void NotificationPlatformBridgeMac::Display(const std::string& notification_id, 106 void NotificationPlatformBridgeMac::Display(
81 const std::string& profile_id, 107 NotificationCommon::Type notification_type,
82 bool incognito, 108 const std::string& notification_id,
83 const Notification& notification) { 109 const std::string& profile_id,
110 bool incognito,
111 const Notification& notification) {
84 base::scoped_nsobject<NotificationBuilder> builder( 112 base::scoped_nsobject<NotificationBuilder> builder(
85 [[NotificationBuilder alloc] init]); 113 [[NotificationBuilder alloc] init]);
86 114
87 [builder setTitle:base::SysUTF16ToNSString(notification.title())]; 115 [builder setTitle:base::SysUTF16ToNSString(notification.title())];
88 [builder setContextMessage:base::SysUTF16ToNSString(notification.message())]; 116 [builder setContextMessage:base::SysUTF16ToNSString(notification.message())];
89 117
90 base::string16 subtitle = 118 base::string16 subtitle =
91 notification.context_message().empty() 119 notification.context_message().empty()
92 ? url_formatter::FormatOriginForSecurityDisplay( 120 ? url_formatter::FormatOriginForSecurityDisplay(
93 url::Origin(notification.origin_url()), 121 url::Origin(notification.origin_url()),
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 break; 158 break;
131 } 159 }
132 } 160 }
133 } 161 }
134 } 162 }
135 163
136 [builder setOrigin:base::SysUTF8ToNSString(notification.origin_url().spec())]; 164 [builder setOrigin:base::SysUTF8ToNSString(notification.origin_url().spec())];
137 [builder setNotificationId:base::SysUTF8ToNSString(notification_id)]; 165 [builder setNotificationId:base::SysUTF8ToNSString(notification_id)];
138 [builder setProfileId:base::SysUTF8ToNSString(profile_id)]; 166 [builder setProfileId:base::SysUTF8ToNSString(profile_id)];
139 [builder setIncognito:incognito]; 167 [builder setIncognito:incognito];
168 [builder setNotificationType:[NSNumber numberWithInteger:notification_type]];
140 169
141 NSUserNotification* toast = [builder buildUserNotification]; 170 NSUserNotification* toast = [builder buildUserNotification];
142 [notification_center_ deliverNotification:toast]; 171 [notification_center_ deliverNotification:toast];
143 } 172 }
144 173
145 void NotificationPlatformBridgeMac::Close(const std::string& profile_id, 174 void NotificationPlatformBridgeMac::Close(const std::string& profile_id,
146 const std::string& notification_id) { 175 const std::string& notification_id) {
147 NSString* candidate_id = base::SysUTF8ToNSString(notification_id); 176 NSString* candidate_id = base::SysUTF8ToNSString(notification_id);
148 177
149 NSString* current_profile_id = base::SysUTF8ToNSString(profile_id); 178 NSString* current_profile_id = base::SysUTF8ToNSString(profile_id);
150 for (NSUserNotification* toast in 179 for (NSUserNotification* toast in
151 [notification_center_ deliveredNotifications]) { 180 [notification_center_ deliveredNotifications]) {
152 NSString* toast_id = 181 NSString* toast_id =
153 [toast.userInfo objectForKey:notification_constants::kNotificationId]; 182 [toast.userInfo objectForKey:notification_constants::kNotificationId];
154 183
155 NSString* persistent_profile_id = [toast.userInfo 184 NSString* persistent_profile_id = [toast.userInfo
156 objectForKey:notification_constants::kNotificationProfileId]; 185 objectForKey:notification_constants::kNotificationProfileId];
186
157 if ([toast_id isEqualToString:candidate_id] && 187 if ([toast_id isEqualToString:candidate_id] &&
158 [persistent_profile_id isEqualToString:current_profile_id]) { 188 [persistent_profile_id isEqualToString:current_profile_id]) {
159 [notification_center_ removeDeliveredNotification:toast]; 189 [notification_center_ removeDeliveredNotification:toast];
160 } 190 }
161 } 191 }
162 } 192 }
163 193
164 bool NotificationPlatformBridgeMac::GetDisplayed( 194 bool NotificationPlatformBridgeMac::GetDisplayed(
165 const std::string& profile_id, 195 const std::string& profile_id,
166 bool incognito, 196 bool incognito,
(...skipping 18 matching lines...) Expand all
185 } 215 }
186 216
187 // static 217 // static
188 bool NotificationPlatformBridgeMac::VerifyNotificationData( 218 bool NotificationPlatformBridgeMac::VerifyNotificationData(
189 NSDictionary* response) { 219 NSDictionary* response) {
190 if (![response 220 if (![response
191 objectForKey:notification_constants::kNotificationButtonIndex] || 221 objectForKey:notification_constants::kNotificationButtonIndex] ||
192 ![response objectForKey:notification_constants::kNotificationOperation] || 222 ![response objectForKey:notification_constants::kNotificationOperation] ||
193 ![response objectForKey:notification_constants::kNotificationId] || 223 ![response objectForKey:notification_constants::kNotificationId] ||
194 ![response objectForKey:notification_constants::kNotificationProfileId] || 224 ![response objectForKey:notification_constants::kNotificationProfileId] ||
195 ![response objectForKey:notification_constants::kNotificationIncognito]) { 225 ![response objectForKey:notification_constants::kNotificationIncognito] ||
226 ![response objectForKey:notification_constants::kNotificationType]) {
196 LOG(ERROR) << "Missing required key"; 227 LOG(ERROR) << "Missing required key";
197 return false; 228 return false;
198 } 229 }
199 230
200 NSNumber* button_index = 231 NSNumber* button_index =
201 [response objectForKey:notification_constants::kNotificationButtonIndex]; 232 [response objectForKey:notification_constants::kNotificationButtonIndex];
202 NSNumber* operation = 233 NSNumber* operation =
203 [response objectForKey:notification_constants::kNotificationOperation]; 234 [response objectForKey:notification_constants::kNotificationOperation];
204 NSString* notification_id = 235 NSString* notification_id =
205 [response objectForKey:notification_constants::kNotificationId]; 236 [response objectForKey:notification_constants::kNotificationId];
206 NSString* profile_id = 237 NSString* profile_id =
207 [response objectForKey:notification_constants::kNotificationProfileId]; 238 [response objectForKey:notification_constants::kNotificationProfileId];
239 NSNumber* notification_type =
240 [response objectForKey:notification_constants::kNotificationType];
208 241
209 if (button_index.intValue < -1 || 242 if (button_index.intValue < -1 ||
210 button_index.intValue >= 243 button_index.intValue >=
211 static_cast<int>(blink::kWebNotificationMaxActions)) { 244 static_cast<int>(blink::kWebNotificationMaxActions)) {
212 LOG(ERROR) << "Invalid number of buttons supplied " 245 LOG(ERROR) << "Invalid number of buttons supplied "
213 << button_index.intValue; 246 << button_index.intValue;
214 return false; 247 return false;
215 } 248 }
216 249
217 if (operation.unsignedIntValue > NotificationCommon::OPERATION_MAX) { 250 if (operation.unsignedIntValue > NotificationCommon::OPERATION_MAX) {
218 LOG(ERROR) << operation.unsignedIntValue 251 LOG(ERROR) << operation.unsignedIntValue
219 << " does not correspond to a valid operation."; 252 << " does not correspond to a valid operation.";
220 return false; 253 return false;
221 } 254 }
222 255
223 if (notification_id.length <= 0) { 256 if (notification_id.length <= 0) {
224 LOG(ERROR) << "Notification Id is empty"; 257 LOG(ERROR) << "Notification Id is empty";
225 return false; 258 return false;
226 } 259 }
227 260
228 if (profile_id.length <= 0) { 261 if (profile_id.length <= 0) {
229 LOG(ERROR) << "Profile Id is empty"; 262 LOG(ERROR) << "ProfileId not provided";
Peter Beverloo 2016/07/05 14:25:35 Bad merge?
Miguel Garcia 2016/07/05 17:12:53 Yeah sorry.
230 return false; 263 return false;
231 } 264 }
232 265
266 if (notification_type.unsignedIntValue > NotificationCommon::TYPE_MAX) {
267 LOG(ERROR) << notification_type.unsignedIntValue
268 << " Does not correspond to a valid operation.";
269 return false;
270 }
271
233 // Origin is not actually required but if it's there it should be a valid one. 272 // Origin is not actually required but if it's there it should be a valid one.
234 NSString* origin = 273 NSString* origin =
235 [response objectForKey:notification_constants::kNotificationOrigin]; 274 [response objectForKey:notification_constants::kNotificationOrigin];
236 if (origin) { 275 if (origin) {
237 std::string notificationOrigin = base::SysNSStringToUTF8(origin); 276 std::string notificationOrigin = base::SysNSStringToUTF8(origin);
238 GURL url(notificationOrigin); 277 GURL url(notificationOrigin);
239 if (!url.is_valid()) 278 if (!url.is_valid())
240 return false; 279 return false;
241 } 280 }
242 281
(...skipping 14 matching lines...) Expand all
257 [response objectForKey:notification_constants::kNotificationButtonIndex]; 296 [response objectForKey:notification_constants::kNotificationButtonIndex];
258 NSNumber* operation = 297 NSNumber* operation =
259 [response objectForKey:notification_constants::kNotificationOperation]; 298 [response objectForKey:notification_constants::kNotificationOperation];
260 299
261 std::string notificationOrigin = base::SysNSStringToUTF8( 300 std::string notificationOrigin = base::SysNSStringToUTF8(
262 [response objectForKey:notification_constants::kNotificationOrigin]); 301 [response objectForKey:notification_constants::kNotificationOrigin]);
263 NSString* notificationId = 302 NSString* notificationId =
264 [response objectForKey:notification_constants::kNotificationId]; 303 [response objectForKey:notification_constants::kNotificationId];
265 std::string persistentNotificationId = 304 std::string persistentNotificationId =
266 base::SysNSStringToUTF8(notificationId); 305 base::SysNSStringToUTF8(notificationId);
267 int64_t persistentId;
268 if (!base::StringToInt64(persistentNotificationId, &persistentId)) {
269 LOG(ERROR) << "Unable to convert notification ID: "
270 << persistentNotificationId << " to integer.";
271 return;
272 }
273 std::string profileId = base::SysNSStringToUTF8( 306 std::string profileId = base::SysNSStringToUTF8(
274 [response objectForKey:notification_constants::kNotificationProfileId]); 307 [response objectForKey:notification_constants::kNotificationProfileId]);
275 NSNumber* isIncognito = 308 NSNumber* isIncognito =
276 [response objectForKey:notification_constants::kNotificationIncognito]; 309 [response objectForKey:notification_constants::kNotificationIncognito];
310 NSNumber* notificationType =
311 [response objectForKey:notification_constants::kNotificationType];
277 312
278 GURL origin(notificationOrigin); 313 ProfileManager* profileManager = g_browser_process->profile_manager();
314 DCHECK(profileManager);
279 315
280 PlatformNotificationServiceImpl::GetInstance() 316 profileManager->LoadProfile(
281 ->ProcessPersistentNotificationOperation( 317 profileId, [isIncognito boolValue],
282 static_cast<NotificationCommon::Operation>(operation.intValue), 318 base::Bind(
283 profileId, [isIncognito boolValue], origin, persistentId, 319 &ProfileLoadedCallback, static_cast<NotificationCommon::Operation>(
284 buttonIndex.intValue); 320 operation.unsignedIntValue),
321 static_cast<NotificationCommon::Type>(
322 notificationType.unsignedIntValue),
323 notificationOrigin, persistentNotificationId, buttonIndex.intValue));
285 } 324 }
286 325
287 - (BOOL)userNotificationCenter:(NSUserNotificationCenter*)center 326 - (BOOL)userNotificationCenter:(NSUserNotificationCenter*)center
288 shouldPresentNotification:(NSUserNotification*)nsNotification { 327 shouldPresentNotification:(NSUserNotification*)nsNotification {
289 // Always display notifications, regardless of whether the app is foreground. 328 // Always display notifications, regardless of whether the app is foreground.
290 return YES; 329 return YES;
291 } 330 }
292 331
293 @end 332 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698