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 |