OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 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 #import "chrome/browser/ui/cocoa/notifications/notification_builder_mac.h" | 5 #import "chrome/browser/ui/cocoa/notifications/notification_builder_mac.h" |
6 | 6 |
7 #import <AppKit/AppKit.h> | 7 #import <AppKit/AppKit.h> |
8 | 8 |
9 #include "base/mac/mac_util.h" | 9 #include "base/mac/mac_util.h" |
10 #include "base/mac/scoped_nsobject.h" | 10 #include "base/mac/scoped_nsobject.h" |
11 | 11 |
12 #include "chrome/browser/ui/cocoa/notifications/notification_constants_mac.h" | 12 #include "chrome/browser/ui/cocoa/notifications/notification_constants_mac.h" |
13 | 13 |
14 namespace { | 14 namespace { |
15 | 15 |
16 // Internal builder constants representing the different notification fields | 16 // Internal builder constants representing the different notification fields |
17 // They don't need to be exposed outside the builder. | 17 // They don't need to be exposed outside the builder. |
18 | 18 |
19 NSString* const kNotificationTitle = @"title"; | 19 NSString* const kNotificationTitle = @"title"; |
20 NSString* const kNotificationSubTitle = @"subtitle"; | 20 NSString* const kNotificationSubTitle = @"subtitle"; |
21 NSString* const kNotificationInformativeText = @"informativeText"; | 21 NSString* const kNotificationInformativeText = @"informativeText"; |
22 NSString* const kNotificationImage = @"icon"; | 22 NSString* const kNotificationImage = @"icon"; |
23 NSString* const kNotificationButtonOne = @"buttonOne"; | 23 NSString* const kNotificationButtonOne = @"buttonOne"; |
24 NSString* const kNotificationButtonTwo = @"buttonTwo"; | 24 NSString* const kNotificationButtonTwo = @"buttonTwo"; |
25 NSString* const kNotificationTag = @"tag"; | 25 NSString* const kNotificationTag = @"tag"; |
26 NSString* const kNotificationCloseButtonTag = @"closeButton"; | 26 NSString* const kNotificationCloseButtonTag = @"closeButton"; |
27 NSString* const kNotificationOptionsButtonTag = @"optionsButton"; | 27 NSString* const kNotificationOptionsButtonTag = @"optionsButton"; |
28 NSString* const kNotificationSettingsButtonTag = @"settingsButton"; | 28 NSString* const kNotificationSettingsButtonTag = @"settingsButton"; |
29 | |
29 } // namespace | 30 } // namespace |
30 | 31 |
31 @implementation NotificationBuilder { | 32 @implementation NotificationBuilder { |
32 base::scoped_nsobject<NSMutableDictionary> notificationData_; | 33 base::scoped_nsobject<NSMutableDictionary> notificationData_; |
33 } | 34 } |
34 | 35 |
35 - (instancetype)initWithCloseLabel:(NSString*)closeLabel | 36 - (instancetype)initWithCloseLabel:(NSString*)closeLabel |
36 optionsLabel:(NSString*)optionsLabel | 37 optionsLabel:(NSString*)optionsLabel |
37 settingsLabel:(NSString*)settingsLabel { | 38 settingsLabel:(NSString*)settingsLabel { |
38 if ((self = [super init])) { | 39 if ((self = [super init])) { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
115 - (void)setIncognito:(BOOL)incognito { | 116 - (void)setIncognito:(BOOL)incognito { |
116 [notificationData_ setObject:[NSNumber numberWithBool:incognito] | 117 [notificationData_ setObject:[NSNumber numberWithBool:incognito] |
117 forKey:notification_constants::kNotificationIncognito]; | 118 forKey:notification_constants::kNotificationIncognito]; |
118 } | 119 } |
119 | 120 |
120 - (void)setNotificationType:(NSNumber*)notificationType { | 121 - (void)setNotificationType:(NSNumber*)notificationType { |
121 [notificationData_ setObject:notificationType | 122 [notificationData_ setObject:notificationType |
122 forKey:notification_constants::kNotificationType]; | 123 forKey:notification_constants::kNotificationType]; |
123 } | 124 } |
124 | 125 |
126 - (void)setShowSettingsButton:(BOOL)showSettingsButton { | |
127 [notificationData_ | |
128 setObject:[NSNumber numberWithBool:showSettingsButton] | |
129 forKey:notification_constants::kNotificationHasSettingsButton]; | |
130 } | |
131 | |
125 - (NSUserNotification*)buildUserNotification { | 132 - (NSUserNotification*)buildUserNotification { |
126 base::scoped_nsobject<NSUserNotification> toast( | 133 base::scoped_nsobject<NSUserNotification> toast( |
127 [[NSUserNotification alloc] init]); | 134 [[NSUserNotification alloc] init]); |
128 [toast setTitle:[notificationData_ objectForKey:kNotificationTitle]]; | 135 [toast setTitle:[notificationData_ objectForKey:kNotificationTitle]]; |
129 [toast setSubtitle:[notificationData_ objectForKey:kNotificationSubTitle]]; | 136 [toast setSubtitle:[notificationData_ objectForKey:kNotificationSubTitle]]; |
130 [toast setInformativeText:[notificationData_ | 137 [toast setInformativeText:[notificationData_ |
131 objectForKey:kNotificationInformativeText]]; | 138 objectForKey:kNotificationInformativeText]]; |
132 | 139 |
133 // Icon | 140 // Icon |
134 if ([notificationData_ objectForKey:kNotificationImage]) { | 141 if ([notificationData_ objectForKey:kNotificationImage]) { |
135 if ([[NSImage class] conformsToProtocol:@protocol(NSSecureCoding)]) { | 142 if ([[NSImage class] conformsToProtocol:@protocol(NSSecureCoding)]) { |
136 NSImage* image = [notificationData_ objectForKey:kNotificationImage]; | 143 NSImage* image = [notificationData_ objectForKey:kNotificationImage]; |
137 [toast setContentImage:image]; | 144 [toast setContentImage:image]; |
138 } else { // NSImage only conforms to NSSecureCoding from 10.10 onwards. | 145 } else { // NSImage only conforms to NSSecureCoding from 10.10 onwards. |
139 base::scoped_nsobject<NSImage> image([[NSImage alloc] | 146 base::scoped_nsobject<NSImage> image([[NSImage alloc] |
140 initWithData:[notificationData_ objectForKey:kNotificationImage]]); | 147 initWithData:[notificationData_ objectForKey:kNotificationImage]]); |
141 [toast setContentImage:image]; | 148 [toast setContentImage:image]; |
142 } | 149 } |
143 } | 150 } |
144 | 151 |
152 // Type (needed to define the buttons) | |
153 NSNumber* type = [notificationData_ | |
154 objectForKey:notification_constants::kNotificationType]; | |
Peter Beverloo
2017/04/07 16:19:05
Move back to line 219 w/o the comment now that |ty
| |
155 | |
156 // Extensions don't have a settings button. | |
Peter Beverloo
2017/04/07 16:19:05
nit: this layer doesn't care, I'd just generalize
| |
157 NSNumber* showSettingsButton = [notificationData_ | |
158 objectForKey:notification_constants::kNotificationHasSettingsButton]; | |
159 | |
145 // Buttons | 160 // Buttons |
146 if ([toast respondsToSelector:@selector(_showsButtons)]) { | 161 if ([toast respondsToSelector:@selector(_showsButtons)]) { |
147 DCHECK([notificationData_ objectForKey:kNotificationCloseButtonTag]); | 162 DCHECK([notificationData_ objectForKey:kNotificationCloseButtonTag]); |
148 DCHECK([notificationData_ objectForKey:kNotificationSettingsButtonTag]); | 163 DCHECK([notificationData_ objectForKey:kNotificationSettingsButtonTag]); |
149 DCHECK([notificationData_ objectForKey:kNotificationOptionsButtonTag]); | 164 DCHECK([notificationData_ objectForKey:kNotificationOptionsButtonTag]); |
165 DCHECK([notificationData_ | |
166 objectForKey:notification_constants::kNotificationHasSettingsButton]); | |
167 | |
168 BOOL settingsButton = [showSettingsButton boolValue]; | |
150 | 169 |
151 [toast setValue:@YES forKey:@"_showsButtons"]; | 170 [toast setValue:@YES forKey:@"_showsButtons"]; |
152 // A default close button label is provided by the platform but we | 171 // A default close button label is provided by the platform but we |
153 // explicitly override it in case the user decides to not | 172 // explicitly override it in case the user decides to not |
154 // use the OS language in Chrome. | 173 // use the OS language in Chrome. |
155 [toast setOtherButtonTitle:[notificationData_ | 174 [toast setOtherButtonTitle:[notificationData_ |
156 objectForKey:kNotificationCloseButtonTag]]; | 175 objectForKey:kNotificationCloseButtonTag]]; |
157 | 176 |
158 // Display the Settings button as the action button if there are either no | 177 // Display the Settings button as the action button if there are either no |
159 // developer-provided action buttons, or the alternate action menu is not | 178 // developer-provided action buttons, or the alternate action menu is not |
160 // available on this Mac version. This avoids needlessly showing the menu. | 179 // available on this Mac version. This avoids needlessly showing the menu. |
161 // TODO(miguelg): Extensions should not have a settings button. | |
162 if (![notificationData_ objectForKey:kNotificationButtonOne] || | 180 if (![notificationData_ objectForKey:kNotificationButtonOne] || |
163 ![toast respondsToSelector:@selector(_alwaysShowAlternateActionMenu)]) { | 181 ![toast respondsToSelector:@selector(_alwaysShowAlternateActionMenu)]) { |
164 [toast | 182 if (settingsButton) { |
165 setActionButtonTitle: | 183 [toast setActionButtonTitle: |
166 [notificationData_ objectForKey:kNotificationSettingsButtonTag]]; | 184 [notificationData_ |
185 objectForKey:kNotificationSettingsButtonTag]]; | |
186 } else { | |
187 [toast setHasActionButton:NO]; | |
Peter Beverloo
2017/04/07 16:19:05
Is this necessary? Surely that's the default?
| |
188 } | |
189 | |
167 } else { | 190 } else { |
168 // Otherwise show the alternate menu, then show the developer actions and | 191 // Otherwise show the alternate menu, then show the developer actions and |
169 // finally the settings one. | 192 // finally the settings one if needed. |
170 DCHECK( | 193 DCHECK( |
171 [toast respondsToSelector:@selector(_alwaysShowAlternateActionMenu)]); | 194 [toast respondsToSelector:@selector(_alwaysShowAlternateActionMenu)]); |
172 DCHECK( | 195 DCHECK( |
173 [toast respondsToSelector:@selector(_alternateActionButtonTitles)]); | 196 [toast respondsToSelector:@selector(_alternateActionButtonTitles)]); |
174 [toast | 197 [toast |
175 setActionButtonTitle:[notificationData_ | 198 setActionButtonTitle:[notificationData_ |
176 objectForKey:kNotificationOptionsButtonTag]]; | 199 objectForKey:kNotificationOptionsButtonTag]]; |
177 [toast setValue:@YES forKey:@"_alwaysShowAlternateActionMenu"]; | 200 [toast setValue:@YES forKey:@"_alwaysShowAlternateActionMenu"]; |
178 | 201 |
179 NSMutableArray* buttons = [NSMutableArray arrayWithCapacity:3]; | 202 NSMutableArray* buttons = [NSMutableArray arrayWithCapacity:3]; |
180 [buttons | 203 [buttons |
181 addObject:[notificationData_ objectForKey:kNotificationButtonOne]]; | 204 addObject:[notificationData_ objectForKey:kNotificationButtonOne]]; |
182 if ([notificationData_ objectForKey:kNotificationButtonTwo]) { | 205 if ([notificationData_ objectForKey:kNotificationButtonTwo]) { |
183 [buttons | 206 [buttons |
184 addObject:[notificationData_ objectForKey:kNotificationButtonTwo]]; | 207 addObject:[notificationData_ objectForKey:kNotificationButtonTwo]]; |
185 } | 208 } |
186 [buttons addObject:[notificationData_ | 209 if (settingsButton) { |
187 objectForKey:kNotificationSettingsButtonTag]]; | 210 [buttons addObject:[notificationData_ |
211 objectForKey:kNotificationSettingsButtonTag]]; | |
212 } | |
213 | |
188 [toast setValue:buttons forKey:@"_alternateActionButtonTitles"]; | 214 [toast setValue:buttons forKey:@"_alternateActionButtonTitles"]; |
189 } | 215 } |
190 } | 216 } |
191 | 217 |
192 // Tag | 218 // Tag |
193 if ([toast respondsToSelector:@selector(setIdentifier:)] && | 219 if ([toast respondsToSelector:@selector(setIdentifier:)] && |
194 [notificationData_ objectForKey:kNotificationTag]) { | 220 [notificationData_ objectForKey:kNotificationTag]) { |
195 [toast setValue:[notificationData_ objectForKey:kNotificationTag] | 221 [toast setValue:[notificationData_ objectForKey:kNotificationTag] |
196 forKey:@"identifier"]; | 222 forKey:@"identifier"]; |
197 } | 223 } |
(...skipping 11 matching lines...) Expand all Loading... | |
209 | 235 |
210 DCHECK([notificationData_ | 236 DCHECK([notificationData_ |
211 objectForKey:notification_constants::kNotificationProfileId]); | 237 objectForKey:notification_constants::kNotificationProfileId]); |
212 NSString* profileId = [notificationData_ | 238 NSString* profileId = [notificationData_ |
213 objectForKey:notification_constants::kNotificationProfileId]; | 239 objectForKey:notification_constants::kNotificationProfileId]; |
214 | 240 |
215 DCHECK([notificationData_ | 241 DCHECK([notificationData_ |
216 objectForKey:notification_constants::kNotificationIncognito]); | 242 objectForKey:notification_constants::kNotificationIncognito]); |
217 NSNumber* incognito = [notificationData_ | 243 NSNumber* incognito = [notificationData_ |
218 objectForKey:notification_constants::kNotificationIncognito]; | 244 objectForKey:notification_constants::kNotificationIncognito]; |
219 NSNumber* type = [notificationData_ | |
220 objectForKey:notification_constants::kNotificationType]; | |
221 | 245 |
222 toast.get().userInfo = @{ | 246 toast.get().userInfo = @{ |
223 notification_constants::kNotificationOrigin : origin, | 247 notification_constants::kNotificationOrigin : origin, |
224 notification_constants::kNotificationId : notificationId, | 248 notification_constants::kNotificationId : notificationId, |
225 notification_constants::kNotificationProfileId : profileId, | 249 notification_constants::kNotificationProfileId : profileId, |
226 notification_constants::kNotificationIncognito : incognito, | 250 notification_constants::kNotificationIncognito : incognito, |
227 notification_constants::kNotificationType : type, | 251 notification_constants::kNotificationType : type, |
252 notification_constants::kNotificationHasSettingsButton : showSettingsButton, | |
228 }; | 253 }; |
229 | 254 |
230 return toast.autorelease(); | 255 return toast.autorelease(); |
231 } | 256 } |
232 | 257 |
233 - (NSDictionary*)buildDictionary { | 258 - (NSDictionary*)buildDictionary { |
234 return [[notificationData_ copy] autorelease]; | 259 return [[notificationData_ copy] autorelease]; |
235 } | 260 } |
236 | 261 |
237 @end | 262 @end |
OLD | NEW |