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/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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |