File: notification_builder_mac.mm

package info (click to toggle)
chromium-browser 57.0.2987.98-1~deb8u1
  • links: PTS, VCS
  • area: main
  • in suites: jessie
  • size: 2,637,852 kB
  • ctags: 2,544,394
  • sloc: cpp: 12,815,961; ansic: 3,676,222; python: 1,147,112; asm: 526,608; java: 523,212; xml: 286,794; perl: 92,654; sh: 86,408; objc: 73,271; makefile: 27,698; cs: 18,487; yacc: 13,031; tcl: 12,957; pascal: 4,875; ml: 4,716; lex: 3,904; sql: 3,862; ruby: 1,982; lisp: 1,508; php: 1,368; exp: 404; awk: 325; csh: 117; jsp: 39; sed: 37
file content (226 lines) | stat: -rw-r--r-- 8,658 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import "chrome/browser/ui/cocoa/notifications/notification_builder_mac.h"

#import <AppKit/AppKit.h>

#include "base/mac/scoped_nsobject.h"
#include "chrome/browser/ui/cocoa/notifications/notification_constants_mac.h"

namespace {

// Internal builder constants representing the different notification fields
// They don't need to be exposed outside the builder.

NSString* const kNotificationTitle = @"title";
NSString* const kNotificationSubTitle = @"subtitle";
NSString* const kNotificationInformativeText = @"informativeText";
NSString* const kNotificationImage = @"icon";
NSString* const kNotificationButtonOne = @"buttonOne";
NSString* const kNotificationButtonTwo = @"buttonTwo";
NSString* const kNotificationTag = @"tag";
NSString* const kNotificationCloseButtonTag = @"closeButton";
NSString* const kNotificationOptionsButtonTag = @"optionsButton";
NSString* const kNotificationSettingsButtonTag = @"settingsButton";
}  // namespace

@implementation NotificationBuilder {
  base::scoped_nsobject<NSMutableDictionary> notificationData_;
}

- (instancetype)initWithCloseLabel:(NSString*)closeLabel
                      optionsLabel:(NSString*)optionsLabel
                     settingsLabel:(NSString*)settingsLabel {
  if ((self = [super init])) {
    notificationData_.reset([[NSMutableDictionary alloc] init]);
    [notificationData_ setObject:closeLabel forKey:kNotificationCloseButtonTag];
    [notificationData_ setObject:optionsLabel
                          forKey:kNotificationOptionsButtonTag];
    [notificationData_ setObject:settingsLabel
                          forKey:kNotificationSettingsButtonTag];
  }
  return self;
}

- (instancetype)initWithDictionary:(NSDictionary*)data {
  if ((self = [super init])) {
    notificationData_.reset([data copy]);
  }
  return self;
}

- (void)setTitle:(NSString*)title {
  if (title.length)
    [notificationData_ setObject:title forKey:kNotificationTitle];
}

- (void)setSubTitle:(NSString*)subTitle {
  if (subTitle.length)
    [notificationData_ setObject:subTitle forKey:kNotificationSubTitle];
}

- (void)setContextMessage:(NSString*)contextMessage {
  if (contextMessage.length)
    [notificationData_ setObject:contextMessage
                          forKey:kNotificationInformativeText];
}

- (void)setIcon:(NSImage*)icon {
  if (icon)
    [notificationData_ setObject:icon forKey:kNotificationImage];
}

- (void)setButtons:(NSString*)primaryButton
    secondaryButton:(NSString*)secondaryButton {
  DCHECK(primaryButton.length);
  [notificationData_ setObject:primaryButton forKey:kNotificationButtonOne];
  if (secondaryButton.length) {
    [notificationData_ setObject:secondaryButton forKey:kNotificationButtonTwo];
  }
}

- (void)setTag:(NSString*)tag {
  if (tag.length)
    [notificationData_ setObject:tag forKey:kNotificationTag];
}

- (void)setOrigin:(NSString*)origin {
  if (origin.length)
    [notificationData_ setObject:origin
                          forKey:notification_constants::kNotificationOrigin];
}

- (void)setNotificationId:(NSString*)notificationId {
  DCHECK(notificationId.length);
  [notificationData_ setObject:notificationId
                        forKey:notification_constants::kNotificationId];
}

- (void)setProfileId:(NSString*)profileId {
  DCHECK(profileId.length);
  [notificationData_ setObject:profileId
                        forKey:notification_constants::kNotificationProfileId];
}

- (void)setIncognito:(BOOL)incognito {
  [notificationData_ setObject:[NSNumber numberWithBool:incognito]
                        forKey:notification_constants::kNotificationIncognito];
}

- (void)setNotificationType:(NSNumber*)notificationType {
  [notificationData_ setObject:notificationType
                        forKey:notification_constants::kNotificationType];
}

- (NSUserNotification*)buildUserNotification {
  base::scoped_nsobject<NSUserNotification> toast(
      [[NSUserNotification alloc] init]);
  [toast setTitle:[notificationData_ objectForKey:kNotificationTitle]];
  [toast setSubtitle:[notificationData_ objectForKey:kNotificationSubTitle]];
  [toast setInformativeText:[notificationData_
                                objectForKey:kNotificationInformativeText]];

  // Icon
  if ([notificationData_ objectForKey:kNotificationImage]) {
    if ([toast respondsToSelector:@selector(_identityImage)]) {
      NSImage* image = [notificationData_ objectForKey:kNotificationImage];
      [toast setValue:image forKey:@"_identityImage"];
      [toast setValue:@NO forKey:@"_identityImageHasBorder"];
    }
  }

  // Buttons
  if ([toast respondsToSelector:@selector(_showsButtons)]) {
    DCHECK([notificationData_ objectForKey:kNotificationCloseButtonTag]);
    DCHECK([notificationData_ objectForKey:kNotificationSettingsButtonTag]);
    DCHECK([notificationData_ objectForKey:kNotificationOptionsButtonTag]);

    [toast setValue:@YES forKey:@"_showsButtons"];
    // A default close button label is provided by the platform but we
    // explicitly override it in case the user decides to not
    // use the OS language in Chrome.
    [toast setOtherButtonTitle:[notificationData_
                                   objectForKey:kNotificationCloseButtonTag]];

    // Display the Settings button as the action button if there are either no
    // developer-provided action buttons, or the alternate action menu is not
    // available on this Mac version. This avoids needlessly showing the menu.
    // TODO(miguelg): Extensions should not have a settings button.
    if (![notificationData_ objectForKey:kNotificationButtonOne] ||
        ![toast respondsToSelector:@selector(_alwaysShowAlternateActionMenu)]) {
      [toast
          setActionButtonTitle:
              [notificationData_ objectForKey:kNotificationSettingsButtonTag]];
    } else {
      // Otherwise show the alternate menu, then show the developer actions and
      // finally the settings one.
      DCHECK(
          [toast respondsToSelector:@selector(_alwaysShowAlternateActionMenu)]);
      DCHECK(
          [toast respondsToSelector:@selector(_alternateActionButtonTitles)]);
      [toast
          setActionButtonTitle:[notificationData_
                                   objectForKey:kNotificationOptionsButtonTag]];
      [toast setValue:@YES forKey:@"_alwaysShowAlternateActionMenu"];

      NSMutableArray* buttons = [NSMutableArray arrayWithCapacity:3];
      [buttons
          addObject:[notificationData_ objectForKey:kNotificationButtonOne]];
      if ([notificationData_ objectForKey:kNotificationButtonTwo]) {
        [buttons
            addObject:[notificationData_ objectForKey:kNotificationButtonTwo]];
      }
      [buttons addObject:[notificationData_
                             objectForKey:kNotificationSettingsButtonTag]];
      [toast setValue:buttons forKey:@"_alternateActionButtonTitles"];
    }
  }

  // Tag
  if ([toast respondsToSelector:@selector(setIdentifier:)] &&
      [notificationData_ objectForKey:kNotificationTag]) {
    [toast setValue:[notificationData_ objectForKey:kNotificationTag]
             forKey:@"identifier"];
  }

  NSString* origin =
      [notificationData_
          objectForKey:notification_constants::kNotificationOrigin]
          ? [notificationData_
                objectForKey:notification_constants::kNotificationOrigin]
          : @"";
  DCHECK(
      [notificationData_ objectForKey:notification_constants::kNotificationId]);
  NSString* notificationId =
      [notificationData_ objectForKey:notification_constants::kNotificationId];

  DCHECK([notificationData_
      objectForKey:notification_constants::kNotificationProfileId]);
  NSString* profileId = [notificationData_
      objectForKey:notification_constants::kNotificationProfileId];

  DCHECK([notificationData_
      objectForKey:notification_constants::kNotificationIncognito]);
  NSNumber* incognito = [notificationData_
      objectForKey:notification_constants::kNotificationIncognito];
  NSNumber* type = [notificationData_
      objectForKey:notification_constants::kNotificationType];

  toast.get().userInfo = @{
    notification_constants::kNotificationOrigin : origin,
    notification_constants::kNotificationId : notificationId,
    notification_constants::kNotificationProfileId : profileId,
    notification_constants::kNotificationIncognito : incognito,
    notification_constants::kNotificationType : type,
  };

  return toast.autorelease();
}

- (NSDictionary*)buildDictionary {
  return [[notificationData_ copy] autorelease];
}

@end