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

Side by Side Diff: chrome/browser/notifications/sync_notifier/chrome_notifier_service.cc

Issue 12717010: Widen Data Pipes and newer protobufs (Closed) Base URL: http://git.chromium.org/chromium/src.git@newProtobufs
Patch Set: Synced Notifications - newer protobufs and wider data paths 2 Created 7 years, 9 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 // The ChromeNotifierService works together with sync to maintain the state of 5 // The ChromeNotifierService works together with sync to maintain the state of
6 // user notifications, which can then be presented in the notification center, 6 // user notifications, which can then be presented in the notification center,
7 // via the Notification UI Manager. 7 // via the Notification UI Manager.
8 8
9 #include "chrome/browser/notifications/sync_notifier/chrome_notifier_service.h" 9 #include "chrome/browser/notifications/sync_notifier/chrome_notifier_service.h"
10 10
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 it != initial_sync_data.end(); ++it) { 54 it != initial_sync_data.end(); ++it) {
55 const syncer::SyncData& sync_data = *it; 55 const syncer::SyncData& sync_data = *it;
56 DCHECK_EQ(syncer::SYNCED_NOTIFICATIONS, sync_data.GetDataType()); 56 DCHECK_EQ(syncer::SYNCED_NOTIFICATIONS, sync_data.GetDataType());
57 57
58 // Build a local notification object from the sync data. 58 // Build a local notification object from the sync data.
59 scoped_ptr<SyncedNotification> incoming(CreateNotificationFromSyncData( 59 scoped_ptr<SyncedNotification> incoming(CreateNotificationFromSyncData(
60 sync_data)); 60 sync_data));
61 DCHECK(incoming.get()); 61 DCHECK(incoming.get());
62 62
63 // Process each incoming remote notification. 63 // Process each incoming remote notification.
64 const std::string& id = incoming->notification_id(); 64 const std::string& key = incoming->key();
65 DCHECK_GT(id.length(), 0U); 65 DCHECK_GT(key.length(), 0U);
66 SyncedNotification* found = FindNotificationById(id); 66 SyncedNotification* found = FindNotificationByKey(key);
67 67
68 if (NULL == found) { 68 if (NULL == found) {
69 // If there are no conflicts, copy in the data from remote. 69 // If there are no conflicts, copy in the data from remote.
70 Add(incoming.Pass()); 70 Add(incoming.Pass());
71 } else { 71 } else {
72 // If the incoming (remote) and stored (local) notifications match 72 // If the incoming (remote) and stored (local) notifications match
73 // in all fields, we don't need to do anything here. 73 // in all fields, we don't need to do anything here.
74 if (incoming->EqualsIgnoringReadState(*found)) { 74 if (incoming->EqualsIgnoringReadState(*found)) {
75 75
76 if (incoming->read_state() == found->read_state()) { 76 if (incoming->read_state() == found->read_state()) {
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 return error; 168 return error;
169 } 169 }
170 170
171 // Support functions for data type conversion. 171 // Support functions for data type conversion.
172 172
173 // Static method. Get to the sync data in our internal format. 173 // Static method. Get to the sync data in our internal format.
174 syncer::SyncData ChromeNotifierService::CreateSyncDataFromNotification( 174 syncer::SyncData ChromeNotifierService::CreateSyncDataFromNotification(
175 const SyncedNotification& notification) { 175 const SyncedNotification& notification) {
176 // Construct the sync_data using the specifics from the notification. 176 // Construct the sync_data using the specifics from the notification.
177 return syncer::SyncData::CreateLocalData( 177 return syncer::SyncData::CreateLocalData(
178 notification.notification_id(), notification.notification_id(), 178 notification.key(), notification.key(),
179 notification.GetEntitySpecifics()); 179 notification.GetEntitySpecifics());
180 } 180 }
181 181
182 // Static Method. Convert from SyncData to our internal format. 182 // Static Method. Convert from SyncData to our internal format.
183 scoped_ptr<SyncedNotification> 183 scoped_ptr<SyncedNotification>
184 ChromeNotifierService::CreateNotificationFromSyncData( 184 ChromeNotifierService::CreateNotificationFromSyncData(
185 const syncer::SyncData& sync_data) { 185 const syncer::SyncData& sync_data) {
186 // Get a pointer to our data within the sync_data object. 186 // Get a pointer to our data within the sync_data object.
187 sync_pb::SyncedNotificationSpecifics specifics = 187 sync_pb::SyncedNotificationSpecifics specifics =
188 sync_data.GetSpecifics().synced_notification(); 188 sync_data.GetSpecifics().synced_notification();
189 189
190 // Check for mandatory fields in the sync_data object. 190 // Check for mandatory fields in the sync_data object.
191 if (!specifics.has_coalesced_notification() || 191 if (!specifics.has_coalesced_notification() ||
192 !specifics.coalesced_notification().has_key() || 192 !specifics.coalesced_notification().has_key() ||
193 !specifics.coalesced_notification().has_read_state()) { 193 !specifics.coalesced_notification().has_read_state())
194 return scoped_ptr<SyncedNotification>(); 194 return scoped_ptr<SyncedNotification>();
dcheng 2013/03/26 07:48:50 Indent is wrong.
Pete Williamson 2013/03/26 17:18:30 Done.
195 }
196 195
197 // TODO(petewil): Is this the right set? Should I add more? 196 // TODO(petewil): Is this the right set? Should I add more?
198 bool is_well_formed_unread_notification = 197 bool is_well_formed_unread_notification =
199 (static_cast<SyncedNotification::ReadState>( 198 (static_cast<SyncedNotification::ReadState>(
200 specifics.coalesced_notification().read_state()) == 199 specifics.coalesced_notification().read_state()) ==
201 SyncedNotification::kUnread && 200 SyncedNotification::kUnread &&
202 specifics.coalesced_notification().has_render_info()); 201 specifics.coalesced_notification().has_render_info());
203 bool is_well_formed_dismissed_notification = 202 bool is_well_formed_dismissed_notification =
204 (static_cast<SyncedNotification::ReadState>( 203 (static_cast<SyncedNotification::ReadState>(
205 specifics.coalesced_notification().read_state()) == 204 specifics.coalesced_notification().read_state()) ==
206 SyncedNotification::kDismissed); 205 SyncedNotification::kDismissed);
207 206
208 // if the notification is poorly formed, return a null pointer 207 // if the notification is poorly formed, return a null pointer
209 if (!is_well_formed_unread_notification && 208 if (!is_well_formed_unread_notification &&
210 !is_well_formed_dismissed_notification) 209 !is_well_formed_dismissed_notification)
211 return scoped_ptr<SyncedNotification>(); 210 return scoped_ptr<SyncedNotification>();
212 211
213 // Create a new notification object based on the supplied sync_data. 212 // Create a new notification object based on the supplied sync_data.
214 scoped_ptr<SyncedNotification> notification( 213 scoped_ptr<SyncedNotification> notification(
215 new SyncedNotification(sync_data)); 214 new SyncedNotification(sync_data));
216 215
217 return notification.Pass(); 216 return notification.Pass();
218 } 217 }
219 218
220 // This returns a pointer into a vector that we own. Caller must not free it. 219 // This returns a pointer into a vector that we own. Caller must not free it.
221 // Returns NULL if no match is found. 220 // Returns NULL if no match is found.
222 // This uses the <app_id/coalescing_key> pair as a key. 221 SyncedNotification* ChromeNotifierService::FindNotificationByKey(
223 SyncedNotification* ChromeNotifierService::FindNotificationById( 222 const std::string& key) {
224 const std::string& id) {
225 // TODO(petewil): We can make a performance trade off here. 223 // TODO(petewil): We can make a performance trade off here.
226 // While the vector has good locality of reference, a map has faster lookup. 224 // While the vector has good locality of reference, a map has faster lookup.
227 // Based on how big we expect this to get, maybe change this to a map. 225 // Based on how big we expect this to get, maybe change this to a map.
228 for (std::vector<SyncedNotification*>::const_iterator it = 226 for (std::vector<SyncedNotification*>::const_iterator it =
229 notification_data_.begin(); 227 notification_data_.begin();
230 it != notification_data_.end(); 228 it != notification_data_.end();
231 ++it) { 229 ++it) {
232 SyncedNotification* notification = *it; 230 SyncedNotification* notification = *it;
233 if (id == notification->notification_id()) 231 if (key == notification->key())
234 return *it; 232 return *it;
235 } 233 }
236 234
237 return NULL; 235 return NULL;
238 } 236 }
239 237
240 void ChromeNotifierService::MarkNotificationAsDismissed(const std::string& id) { 238 void ChromeNotifierService::MarkNotificationAsDismissed(
241 SyncedNotification* notification = FindNotificationById(id); 239 const std::string& key) {
240 SyncedNotification* notification = FindNotificationByKey(key);
242 CHECK(notification != NULL); 241 CHECK(notification != NULL);
243 242
244 notification->NotificationHasBeenDismissed(); 243 notification->NotificationHasBeenDismissed();
245 syncer::SyncChangeList new_changes; 244 syncer::SyncChangeList new_changes;
246 245
247 syncer::SyncData sync_data = CreateSyncDataFromNotification(*notification); 246 syncer::SyncData sync_data = CreateSyncDataFromNotification(*notification);
248 new_changes.push_back( 247 new_changes.push_back(
249 syncer::SyncChange(FROM_HERE, 248 syncer::SyncChange(FROM_HERE,
250 syncer::SyncChange::ACTION_UPDATE, 249 syncer::SyncChange::ACTION_UPDATE,
251 sync_data)); 250 sync_data));
(...skipping 11 matching lines...) Expand all
263 262
264 // Show it to the user. 263 // Show it to the user.
265 Show(notification_copy); 264 Show(notification_copy);
266 } 265 }
267 266
268 // Send the notification to the NotificationUIManager to show to the user. 267 // Send the notification to the NotificationUIManager to show to the user.
269 void ChromeNotifierService::Show(SyncedNotification* notification) { 268 void ChromeNotifierService::Show(SyncedNotification* notification) {
270 // Set up the fields we need to send and create a Notification object. 269 // Set up the fields we need to send and create a Notification object.
271 GURL origin_url(notification->origin_url()); 270 GURL origin_url(notification->origin_url());
272 GURL app_icon_url(notification->app_icon_url()); 271 GURL app_icon_url(notification->app_icon_url());
272 GURL image_url(notification->image_url());
273 string16 title = UTF8ToUTF16(notification->title()); 273 string16 title = UTF8ToUTF16(notification->title());
274 string16 text = UTF8ToUTF16(notification->text()); 274 string16 text = UTF8ToUTF16(notification->text());
275 string16 heading = UTF8ToUTF16(notification->heading()); 275 string16 heading = UTF8ToUTF16(notification->heading());
276 string16 description = UTF8ToUTF16(notification->description()); 276 string16 description = UTF8ToUTF16(notification->description());
277 277 double creation_time = notification->creation_time();
278 // TODO(petewil): What goes in the display source, is empty OK? 278 // TODO(petewil): What goes in the display source, is empty OK?
279 string16 display_source; 279 string16 display_source;
280 string16 replace_id = UTF8ToUTF16(notification->notification_id()); 280 string16 replace_key = UTF8ToUTF16(notification->key());
281 int priority = notification->priority();
282 int notification_count = notification->notification_count();
283 int button_count = notification->button_count();
284 string16 button_one_title = UTF8ToUTF16(notification->button_one_title());
285 string16 button_one_icon_url =
286 UTF8ToUTF16(notification->button_one_icon_url());
dcheng 2013/03/26 07:48:50 Why convert this to UTF16? StringValue's construct
Pete Williamson 2013/03/26 17:18:30 Done.
287 string16 button_two_title = UTF8ToUTF16(notification->button_two_title());
288 string16 button_two_icon_url =
289 UTF8ToUTF16(notification->button_two_icon_url());
290
291 // Deduce which notification template to use from the data.
292 message_center::NotificationType notification_type =
293 message_center::NOTIFICATION_TYPE_SIMPLE;
294 if (!image_url.is_empty()) {
295 notification_type = message_center::NOTIFICATION_TYPE_IMAGE;
296 } else if (notification_count > 1) {
297 notification_type = message_center::NOTIFICATION_TYPE_MULTIPLE;
298 } else if (button_count > 0) {
299 notification_type = message_center::NOTIFICATION_TYPE_BASE_FORMAT;
300 }
301
302 // Fill the optional fields with the information we need to make a
303 // notification.
304 scoped_ptr<DictionaryValue> optional_fields(new DictionaryValue());
305 optional_fields->SetDouble(message_center::kTimestampKey, creation_time);
306 if (priority != 0)
307 optional_fields->SetInteger(message_center::kTimestampKey, priority);
308 if (!button_one_title.empty())
309 optional_fields->SetString(message_center::kButtonOneTitleKey,
310 button_one_title);
311 if (!button_one_icon_url.empty())
312 optional_fields->SetString(message_center::kButtonOneIconUrlKey,
313 button_one_icon_url);
314 if (!button_two_title.empty())
315 optional_fields->SetString(message_center::kButtonTwoTitleKey,
316 button_two_title);
317 if (!button_two_icon_url.empty())
318 optional_fields->SetString(message_center::kButtonTwoIconUrlKey,
319 button_two_icon_url);
320
321 // Fill the individual notification fields for a mutiple notification.
322 if (notification_count > 1) {
323 base::ListValue* items = new base::ListValue();
324
325 for (int ii = 0; ii < notification_count; ++ii) {
326 DictionaryValue* item = new DictionaryValue();
327 item->SetString(message_center::kItemTitleKey,
328 UTF8ToUTF16(notification->contained_notification_title(
329 ii)));
330 item->SetString(message_center::kItemMessageKey,
331 UTF8ToUTF16(notification->contained_notification_message(
332 ii)));
333 items->Append(item);
334 }
335
336 optional_fields->Set(message_center::kItemsKey, items);
337 }
281 338
282 // TODO(petewil): For now, just punt on dismissed notifications until 339 // TODO(petewil): For now, just punt on dismissed notifications until
283 // I change the interface to let NotificationUIManager know the right way. 340 // I change the interface to let NotificationUIManager know the right way.
284 if (SyncedNotification::kRead == notification->read_state() || 341 if (SyncedNotification::kRead == notification->read_state() ||
285 SyncedNotification::kDismissed == notification->read_state() ) { 342 SyncedNotification::kDismissed == notification->read_state() ) {
286 DVLOG(2) << "Not showing dismissed notification" 343 DVLOG(2) << "Dismissed notification arrived"
287 << notification->title() << " " << notification->text(); 344 << notification->title() << " " << notification->text();
288 return; 345 return;
289 } 346 }
290
291 // The delegate will eventually catch calls that the notification 347 // The delegate will eventually catch calls that the notification
292 // was read or deleted, and send the changes back to the server. 348 // was read or deleted, and send the changes back to the server.
293 scoped_refptr<NotificationDelegate> delegate = 349 scoped_refptr<NotificationDelegate> delegate =
294 new ChromeNotifierDelegate(notification->notification_id(), this); 350 new ChromeNotifierDelegate(notification->key(), this);
295 351
296 Notification ui_notification(origin_url, app_icon_url, heading, description, 352 Notification ui_notification(notification_type,
353 origin_url,
354 app_icon_url,
355 heading,
356 text,
297 WebKit::WebTextDirectionDefault, 357 WebKit::WebTextDirectionDefault,
298 display_source, replace_id, delegate); 358 display_source,
359 replace_key,
360 optional_fields.get(),
dcheng 2013/03/26 07:48:50 The documentation seems to indicate that Notificat
Pete Williamson 2013/03/26 17:18:30 I originally copied this from notification_api.cc.
361 delegate);
299 362
300 notification_manager_->Add(ui_notification, profile_); 363 notification_manager_->Add(ui_notification, profile_);
301 364
302 DVLOG(1) << "Synced Notification arrived! " << title << " " << text 365 DVLOG(1) << "Synced Notification arrived! " << title << " " << text
303 << " " << app_icon_url << " " << replace_id << " " 366 << " " << app_icon_url << " " << replace_key << " "
304 << notification->read_state(); 367 << notification->read_state();
305 368
306 return; 369 return;
307 } 370 }
308 371
309 } // namespace notifier 372 } // namespace notifier
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698