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

Side by Side Diff: chrome/browser/ui/cocoa/notifications/notification_builder_mac.mm

Issue 2799343003: Add support for native extension notifications (Closed)
Patch Set: Remove dependent CL to land standalone Created 3 years, 8 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 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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698