| OLD | NEW |
| (Empty) |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #import "chrome/browser/ui/cocoa/notifications/notification_builder_mac.h" | |
| 6 | |
| 7 #import <AppKit/AppKit.h> | |
| 8 | |
| 9 #include "base/mac/mac_util.h" | |
| 10 #include "base/mac/scoped_nsobject.h" | |
| 11 #include "chrome/grit/generated_resources.h" | |
| 12 #include "ui/base/l10n/l10n_util_mac.h" | |
| 13 | |
| 14 namespace { | |
| 15 | |
| 16 // Internal builder constants representing the different notification fields | |
| 17 // They don't need to be exposed outside the builder. | |
| 18 | |
| 19 NSString* const kNotificationTitle = @"title"; | |
| 20 NSString* const kNotificationSubTitle = @"subtitle"; | |
| 21 NSString* const kNotificationInformativeText = @"informativeText"; | |
| 22 NSString* const kNotificationImage = @"icon"; | |
| 23 NSString* const kNotificationButtonOne = @"buttonOne"; | |
| 24 NSString* const kNotificationButtonTwo = @"buttonTwo"; | |
| 25 NSString* const kNotificationTag = @"tag"; | |
| 26 NSString* const kNotificationCloseButtonTag = @"closeButton"; | |
| 27 NSString* const kNotificationOptionsButtonTag = @"optionsButton"; | |
| 28 NSString* const kNotificationSettingsButtonTag = @"settingsButton"; | |
| 29 } // namespace | |
| 30 | |
| 31 namespace notification_builder { | |
| 32 | |
| 33 // Exposed constants to include user related data in the notification. | |
| 34 NSString* const kNotificationOrigin = @"notificationOrigin"; | |
| 35 NSString* const kNotificationId = @"notificationId"; | |
| 36 NSString* const kNotificationProfileId = @"notificationProfileId"; | |
| 37 NSString* const kNotificationIncognito = @"notificationIncognito"; | |
| 38 | |
| 39 } // namespace notification_builder | |
| 40 | |
| 41 @implementation NotificationBuilder { | |
| 42 base::scoped_nsobject<NSMutableDictionary> notificationData_; | |
| 43 } | |
| 44 | |
| 45 - (instancetype)init { | |
| 46 if ((self = [super init])) { | |
| 47 notificationData_.reset([[NSMutableDictionary alloc] init]); | |
| 48 [notificationData_ | |
| 49 setObject:l10n_util::GetNSString(IDS_NOTIFICATION_BUTTON_CLOSE) | |
| 50 forKey:kNotificationCloseButtonTag]; | |
| 51 [notificationData_ | |
| 52 setObject:l10n_util::GetNSString(IDS_NOTIFICATION_BUTTON_OPTIONS) | |
| 53 forKey:kNotificationOptionsButtonTag]; | |
| 54 [notificationData_ | |
| 55 setObject:l10n_util::GetNSString(IDS_NOTIFICATION_BUTTON_SETTINGS) | |
| 56 forKey:kNotificationSettingsButtonTag]; | |
| 57 } | |
| 58 return self; | |
| 59 } | |
| 60 | |
| 61 - (instancetype)initWithDictionary:(NSDictionary*)data { | |
| 62 if ((self = [super init])) { | |
| 63 notificationData_.reset([data copy]); | |
| 64 } | |
| 65 return self; | |
| 66 } | |
| 67 | |
| 68 - (void)setTitle:(NSString*)title { | |
| 69 if (title.length) | |
| 70 [notificationData_ setObject:title forKey:kNotificationTitle]; | |
| 71 } | |
| 72 | |
| 73 - (void)setSubTitle:(NSString*)subTitle { | |
| 74 if (subTitle.length) | |
| 75 [notificationData_ setObject:subTitle forKey:kNotificationSubTitle]; | |
| 76 } | |
| 77 | |
| 78 - (void)setContextMessage:(NSString*)contextMessage { | |
| 79 if (contextMessage.length) | |
| 80 [notificationData_ setObject:contextMessage | |
| 81 forKey:kNotificationInformativeText]; | |
| 82 } | |
| 83 | |
| 84 - (void)setIcon:(NSImage*)icon { | |
| 85 if (icon) | |
| 86 [notificationData_ setObject:icon forKey:kNotificationImage]; | |
| 87 } | |
| 88 | |
| 89 - (void)setButtons:(NSString*)primaryButton | |
| 90 secondaryButton:(NSString*)secondaryButton { | |
| 91 DCHECK(primaryButton.length); | |
| 92 [notificationData_ setObject:primaryButton forKey:kNotificationButtonOne]; | |
| 93 if (secondaryButton.length) { | |
| 94 [notificationData_ setObject:secondaryButton forKey:kNotificationButtonTwo]; | |
| 95 } | |
| 96 } | |
| 97 | |
| 98 - (void)setTag:(NSString*)tag { | |
| 99 if (tag.length) | |
| 100 [notificationData_ setObject:tag forKey:kNotificationTag]; | |
| 101 } | |
| 102 | |
| 103 - (void)setOrigin:(NSString*)origin { | |
| 104 if (origin.length) | |
| 105 [notificationData_ setObject:origin | |
| 106 forKey:notification_builder::kNotificationOrigin]; | |
| 107 } | |
| 108 | |
| 109 - (void)setNotificationId:(NSString*)notificationId { | |
| 110 DCHECK(notificationId.length); | |
| 111 [notificationData_ setObject:notificationId | |
| 112 forKey:notification_builder::kNotificationId]; | |
| 113 } | |
| 114 | |
| 115 - (void)setProfileId:(NSString*)profileId { | |
| 116 DCHECK(profileId.length); | |
| 117 [notificationData_ setObject:profileId | |
| 118 forKey:notification_builder::kNotificationProfileId]; | |
| 119 } | |
| 120 | |
| 121 - (void)setIncognito:(BOOL)incognito { | |
| 122 [notificationData_ setObject:[NSNumber numberWithBool:incognito] | |
| 123 forKey:notification_builder::kNotificationIncognito]; | |
| 124 } | |
| 125 | |
| 126 - (NSUserNotification*)buildUserNotification { | |
| 127 base::scoped_nsobject<NSUserNotification> toast( | |
| 128 [[NSUserNotification alloc] init]); | |
| 129 [toast setTitle:[notificationData_ objectForKey:kNotificationTitle]]; | |
| 130 [toast setSubtitle:[notificationData_ objectForKey:kNotificationSubTitle]]; | |
| 131 [toast setInformativeText:[notificationData_ | |
| 132 objectForKey:kNotificationInformativeText]]; | |
| 133 | |
| 134 // Icon | |
| 135 if ([notificationData_ objectForKey:kNotificationImage]) { | |
| 136 if ([toast respondsToSelector:@selector(_identityImage)]) { | |
| 137 NSImage* image = [notificationData_ objectForKey:kNotificationImage]; | |
| 138 [toast setValue:image forKey:@"_identityImage"]; | |
| 139 [toast setValue:@NO forKey:@"_identityImageHasBorder"]; | |
| 140 } | |
| 141 } | |
| 142 | |
| 143 // Buttons | |
| 144 if ([toast respondsToSelector:@selector(_showsButtons)]) { | |
| 145 DCHECK([notificationData_ objectForKey:kNotificationCloseButtonTag]); | |
| 146 DCHECK([notificationData_ objectForKey:kNotificationSettingsButtonTag]); | |
| 147 DCHECK([notificationData_ objectForKey:kNotificationOptionsButtonTag]); | |
| 148 | |
| 149 [toast setValue:@YES forKey:@"_showsButtons"]; | |
| 150 // A default close button label is provided by the platform but we | |
| 151 // explicitly override it in case the user decides to not | |
| 152 // use the OS language in Chrome. | |
| 153 [toast setOtherButtonTitle:[notificationData_ | |
| 154 objectForKey:kNotificationCloseButtonTag]]; | |
| 155 | |
| 156 // Display the Settings button as the action button if there are either no | |
| 157 // developer-provided action buttons, or the alternate action menu is not | |
| 158 // available on this Mac version. This avoids needlessly showing the menu. | |
| 159 // TODO(miguelg): Extensions should not have a settings button. | |
| 160 if (![notificationData_ objectForKey:kNotificationButtonOne] || | |
| 161 ![toast respondsToSelector:@selector(_alwaysShowAlternateActionMenu)]) { | |
| 162 [toast | |
| 163 setActionButtonTitle: | |
| 164 [notificationData_ objectForKey:kNotificationSettingsButtonTag]]; | |
| 165 } else { | |
| 166 // Otherwise show the alternate menu, then show the developer actions and | |
| 167 // finally the settings one. | |
| 168 DCHECK( | |
| 169 [toast respondsToSelector:@selector(_alwaysShowAlternateActionMenu)]); | |
| 170 DCHECK( | |
| 171 [toast respondsToSelector:@selector(_alternateActionButtonTitles)]); | |
| 172 [toast | |
| 173 setActionButtonTitle:[notificationData_ | |
| 174 objectForKey:kNotificationOptionsButtonTag]]; | |
| 175 [toast setValue:@YES forKey:@"_alwaysShowAlternateActionMenu"]; | |
| 176 | |
| 177 NSMutableArray* buttons = [NSMutableArray arrayWithCapacity:3]; | |
| 178 [buttons | |
| 179 addObject:[notificationData_ objectForKey:kNotificationButtonOne]]; | |
| 180 if ([notificationData_ objectForKey:kNotificationButtonTwo]) { | |
| 181 [buttons | |
| 182 addObject:[notificationData_ objectForKey:kNotificationButtonTwo]]; | |
| 183 } | |
| 184 [buttons addObject:[notificationData_ | |
| 185 objectForKey:kNotificationSettingsButtonTag]]; | |
| 186 [toast setValue:buttons forKey:@"_alternateActionButtonTitles"]; | |
| 187 } | |
| 188 } | |
| 189 | |
| 190 // Tag | |
| 191 if ([toast respondsToSelector:@selector(setIdentifier:)] && | |
| 192 [notificationData_ objectForKey:kNotificationTag]) { | |
| 193 [toast setValue:[notificationData_ objectForKey:kNotificationTag] | |
| 194 forKey:@"identifier"]; | |
| 195 } | |
| 196 | |
| 197 NSString* origin = | |
| 198 [notificationData_ objectForKey:notification_builder::kNotificationOrigin] | |
| 199 ? [notificationData_ | |
| 200 objectForKey:notification_builder::kNotificationOrigin] | |
| 201 : @""; | |
| 202 DCHECK( | |
| 203 [notificationData_ objectForKey:notification_builder::kNotificationId]); | |
| 204 NSString* notificationId = | |
| 205 [notificationData_ objectForKey:notification_builder::kNotificationId]; | |
| 206 | |
| 207 DCHECK([notificationData_ | |
| 208 objectForKey:notification_builder::kNotificationProfileId]); | |
| 209 NSString* profileId = [notificationData_ | |
| 210 objectForKey:notification_builder::kNotificationProfileId]; | |
| 211 | |
| 212 DCHECK([notificationData_ | |
| 213 objectForKey:notification_builder::kNotificationIncognito]); | |
| 214 NSNumber* incognito = [notificationData_ | |
| 215 objectForKey:notification_builder::kNotificationIncognito]; | |
| 216 | |
| 217 toast.get().userInfo = @{ | |
| 218 notification_builder::kNotificationOrigin : origin, | |
| 219 notification_builder::kNotificationId : notificationId, | |
| 220 notification_builder::kNotificationProfileId : profileId, | |
| 221 notification_builder::kNotificationIncognito : incognito, | |
| 222 }; | |
| 223 | |
| 224 return toast.autorelease(); | |
| 225 } | |
| 226 | |
| 227 - (NSDictionary*)buildDictionary { | |
| 228 return [[notificationData_ copy] autorelease]; | |
| 229 } | |
| 230 | |
| 231 @end | |
| OLD | NEW |