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

Side by Side Diff: chrome/browser/resources/google_now/background.js

Issue 114533002: Chrome Now notificationGroups Storage Race Condition Fix (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: CR Feedback Created 7 years 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | chrome/browser/resources/google_now/cards.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 'use strict'; 5 'use strict';
6 6
7 /** 7 /**
8 * @fileoverview The event page for Google Now for Chrome implementation. 8 * @fileoverview The event page for Google Now for Chrome implementation.
9 * The Google Now event page gets Google Now cards from the server and shows 9 * The Google Now event page gets Google Now cards from the server and shows
10 * them as Chrome notifications. 10 * them as Chrome notifications.
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 originalOnLoadEnd(event); 286 originalOnLoadEnd(event);
287 } 287 }
288 }); 288 });
289 289
290 callbackBoolean(true); 290 callbackBoolean(true);
291 }); 291 });
292 } 292 }
293 293
294 /** 294 /**
295 * Shows parsed and combined cards as notifications. 295 * Shows parsed and combined cards as notifications.
296 * @param {Object.<string, StoredNotificationGroup>} notificationGroups Map from
297 * group name to group information.
296 * @param {Object.<ChromeNotificationId, CombinedCard>} cards Map from 298 * @param {Object.<ChromeNotificationId, CombinedCard>} cards Map from
297 * chromeNotificationId to the combined card, containing cards to show. 299 * chromeNotificationId to the combined card, containing cards to show.
300 * @param {function()} onSuccess Called on success.
298 * @param {function(ReceivedNotification)=} onCardShown Optional parameter 301 * @param {function(ReceivedNotification)=} onCardShown Optional parameter
299 * called when each card is shown. 302 * called when each card is shown.
300 */ 303 */
301 function showNotificationCards(cards, onCardShown) { 304 function showNotificationCards(
305 notificationGroups, cards, onSuccess, onCardShown) {
302 console.log('showNotificationCards ' + JSON.stringify(cards)); 306 console.log('showNotificationCards ' + JSON.stringify(cards));
303 307
304 instrumented.notifications.getAll(function(notifications) { 308 instrumented.notifications.getAll(function(notifications) {
305 console.log('showNotificationCards-getAll ' + 309 console.log('showNotificationCards-getAll ' +
306 JSON.stringify(notifications)); 310 JSON.stringify(notifications));
307 notifications = notifications || {}; 311 notifications = notifications || {};
308 312
309 // Mark notifications that didn't receive an update as having received 313 // Mark notifications that didn't receive an update as having received
310 // an empty update. 314 // an empty update.
311 for (var chromeNotificationId in notifications) { 315 for (var chromeNotificationId in notifications) {
312 cards[chromeNotificationId] = cards[chromeNotificationId] || []; 316 cards[chromeNotificationId] = cards[chromeNotificationId] || [];
313 } 317 }
314 318
315 /** @type {Object.<string, NotificationDataEntry>} */ 319 /** @type {Object.<string, NotificationDataEntry>} */
316 var notificationsData = {}; 320 var notificationsData = {};
317 321
318 // Create/update/delete notifications. 322 // Create/update/delete notifications.
319 for (var chromeNotificationId in cards) { 323 for (var chromeNotificationId in cards) {
320 notificationsData[chromeNotificationId] = cardSet.update( 324 notificationsData[chromeNotificationId] = cardSet.update(
321 chromeNotificationId, 325 chromeNotificationId,
322 cards[chromeNotificationId], 326 cards[chromeNotificationId],
327 notificationGroups,
323 onCardShown); 328 onCardShown);
324 } 329 }
325 chrome.storage.local.set({notificationsData: notificationsData}); 330 chrome.storage.local.set({notificationsData: notificationsData});
331 onSuccess();
326 }); 332 });
327 } 333 }
328 334
329 /** 335 /**
330 * Removes all cards and card state on Google Now close down. 336 * Removes all cards and card state on Google Now close down.
331 * For example, this occurs when the geolocation preference is unchecked in the 337 * For example, this occurs when the geolocation preference is unchecked in the
332 * content settings. 338 * content settings.
333 */ 339 */
334 function removeAllCards() { 340 function removeAllCards() {
335 console.log('removeAllCards'); 341 console.log('removeAllCards');
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 updateCardsAttempts.start(optinPollPeriodSeconds); 416 updateCardsAttempts.start(optinPollPeriodSeconds);
411 }); 417 });
412 } 418 }
413 } 419 }
414 420
415 /** 421 /**
416 * Combines notification groups into a set of Chrome notifications and shows 422 * Combines notification groups into a set of Chrome notifications and shows
417 * them. 423 * them.
418 * @param {Object.<string, StoredNotificationGroup>} notificationGroups Map from 424 * @param {Object.<string, StoredNotificationGroup>} notificationGroups Map from
419 * group name to group information. 425 * group name to group information.
426 * @param {function()} onSuccess Called on success.
420 * @param {function(ReceivedNotification)=} onCardShown Optional parameter 427 * @param {function(ReceivedNotification)=} onCardShown Optional parameter
421 * called when each card is shown. 428 * called when each card is shown.
422 */ 429 */
423 function combineAndShowNotificationCards(notificationGroups, onCardShown) { 430 function combineAndShowNotificationCards(
431 notificationGroups, onSuccess, onCardShown) {
424 console.log('combineAndShowNotificationCards ' + 432 console.log('combineAndShowNotificationCards ' +
425 JSON.stringify(notificationGroups)); 433 JSON.stringify(notificationGroups));
426 /** @type {Object.<ChromeNotificationId, CombinedCard>} */ 434 /** @type {Object.<ChromeNotificationId, CombinedCard>} */
427 var combinedCards = {}; 435 var combinedCards = {};
428 436
429 for (var groupName in notificationGroups) 437 for (var groupName in notificationGroups)
430 combineGroup(combinedCards, notificationGroups[groupName]); 438 combineGroup(combinedCards, notificationGroups[groupName]);
431 439
432 showNotificationCards(combinedCards, onCardShown); 440 showNotificationCards(
441 notificationGroups, combinedCards, onSuccess, onCardShown);
433 } 442 }
434 443
435 /** 444 /**
436 * Parses JSON response from the notification server, shows notifications and 445 * Parses JSON response from the notification server, shows notifications and
437 * schedules next update. 446 * schedules next update.
438 * @param {string} response Server response. 447 * @param {string} response Server response.
439 * @param {function(ReceivedNotification)=} onCardShown Optional parameter 448 * @param {function(ReceivedNotification)=} onCardShown Optional parameter
440 * called when each card is shown. 449 * called when each card is shown.
441 */ 450 */
442 function parseAndShowNotificationCards(response, onCardShown) { 451 function parseAndShowNotificationCards(response, onCardShown) {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 // cards updates. 533 // cards updates.
525 if (receivedGroup.nextPollSeconds !== undefined) { 534 if (receivedGroup.nextPollSeconds !== undefined) {
526 storedGroup.nextPollTime = 535 storedGroup.nextPollTime =
527 now + receivedGroup.nextPollSeconds * MS_IN_SECOND; 536 now + receivedGroup.nextPollSeconds * MS_IN_SECOND;
528 } 537 }
529 538
530 updatedGroups[groupName] = storedGroup; 539 updatedGroups[groupName] = storedGroup;
531 } 540 }
532 541
533 scheduleNextPoll(updatedGroups, !parsedResponse.googleNowDisabled); 542 scheduleNextPoll(updatedGroups, !parsedResponse.googleNowDisabled);
534 chrome.storage.local.set({ 543 combineAndShowNotificationCards(
535 notificationGroups: updatedGroups, 544 updatedGroups,
536 recentDismissals: updatedRecentDismissals 545 function() {
537 }); 546 chrome.storage.local.set({
538 combineAndShowNotificationCards(updatedGroups, onCardShown); 547 notificationGroups: updatedGroups,
539 recordEvent(GoogleNowEvent.CARDS_PARSE_SUCCESS); 548 recentDismissals: updatedRecentDismissals
549 });
550 recordEvent(GoogleNowEvent.CARDS_PARSE_SUCCESS);
551 },
552 onCardShown);
540 }); 553 });
541 } 554 }
542 555
543 /** 556 /**
544 * Update Location Cards Shown Count. 557 * Update Location Cards Shown Count.
545 * @param {ReceivedNotification} receivedNotification Notification as it was 558 * @param {ReceivedNotification} receivedNotification Notification as it was
546 * received from the server. 559 * received from the server.
547 */ 560 */
548 function countLocationCard(receivedNotification) { 561 function countLocationCard(receivedNotification) {
549 if (receivedNotification.locationBased) { 562 if (receivedNotification.locationBased) {
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
898 if (!byUser) 911 if (!byUser)
899 return; 912 return;
900 913
901 // At this point we are guaranteed that the notification is a now card. 914 // At this point we are guaranteed that the notification is a now card.
902 chrome.metricsPrivate.recordUserAction('GoogleNow.Dismissed'); 915 chrome.metricsPrivate.recordUserAction('GoogleNow.Dismissed');
903 916
904 tasks.add(DISMISS_CARD_TASK_NAME, function() { 917 tasks.add(DISMISS_CARD_TASK_NAME, function() {
905 dismissalAttempts.start(); 918 dismissalAttempts.start();
906 919
907 instrumented.storage.local.get( 920 instrumented.storage.local.get(
908 ['pendingDismissals', 'notificationsData'], function(items) { 921 ['pendingDismissals', 'notificationsData', 'notificationGroups'],
909 items = items || {}; 922 function(items) {
910 /** @type {Array.<PendingDismissal>} */ 923 items = items || {};
911 items.pendingDismissals = items.pendingDismissals || []; 924 /** @type {Array.<PendingDismissal>} */
912 /** @type {Object.<string, NotificationDataEntry>} */ 925 items.pendingDismissals = items.pendingDismissals || [];
913 items.notificationsData = items.notificationsData || {}; 926 /** @type {Object.<string, NotificationDataEntry>} */
927 items.notificationsData = items.notificationsData || {};
928 /** @type {Object.<string, StoredNotificationGroup>} */
929 items.notificationGroups = items.notificationGroups || {};
914 930
915 /** @type {NotificationDataEntry} */ 931 /** @type {NotificationDataEntry} */
916 var notificationData = items.notificationsData[chromeNotificationId] || { 932 var notificationData =
917 timestamp: Date.now(), 933 items.notificationsData[chromeNotificationId] ||
918 combinedCard: [] 934 {
919 }; 935 timestamp: Date.now(),
936 combinedCard: []
937 };
920 938
921 var dismissalResult = 939 var dismissalResult =
922 cardSet.onDismissal(chromeNotificationId, notificationData); 940 cardSet.onDismissal(
941 chromeNotificationId,
942 notificationData,
943 items.notificationGroups);
923 944
924 for (var i = 0; i < dismissalResult.dismissals.length; i++) { 945 for (var i = 0; i < dismissalResult.dismissals.length; i++) {
925 /** @type {PendingDismissal} */ 946 /** @type {PendingDismissal} */
926 var dismissal = { 947 var dismissal = {
927 chromeNotificationId: chromeNotificationId, 948 chromeNotificationId: chromeNotificationId,
928 time: Date.now(), 949 time: Date.now(),
929 dismissalData: dismissalResult.dismissals[i] 950 dismissalData: dismissalResult.dismissals[i]
930 }; 951 };
931 items.pendingDismissals.push(dismissal); 952 items.pendingDismissals.push(dismissal);
932 } 953 }
933 954
934 items.notificationsData[chromeNotificationId] = 955 items.notificationsData[chromeNotificationId] =
935 dismissalResult.notificationData; 956 dismissalResult.notificationData;
936 957
937 chrome.storage.local.set({ 958 chrome.storage.local.set(items);
938 pendingDismissals: items.pendingDismissals,
939 notificationsData: items.notificationsData
940 });
941 959
942 processPendingDismissals(function(success) {}); 960 processPendingDismissals(function(success) {});
943 }); 961 });
944 }); 962 });
945 } 963 }
946 964
947 /** 965 /**
948 * Initializes the polling system to start monitoring location and fetching 966 * Initializes the polling system to start monitoring location and fetching
949 * cards. 967 * cards.
950 */ 968 */
951 function startPollingCards() { 969 function startPollingCards() {
952 // Create an update timer for a case when for some reason location request 970 // Create an update timer for a case when for some reason location request
953 // gets stuck. 971 // gets stuck.
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
1118 // Show notifications received by earlier polls. Doing this as early as 1136 // Show notifications received by earlier polls. Doing this as early as
1119 // possible to reduce latency of showing first notifications. This mimics how 1137 // possible to reduce latency of showing first notifications. This mimics how
1120 // persistent notifications will work. 1138 // persistent notifications will work.
1121 tasks.add(SHOW_ON_START_TASK_NAME, function() { 1139 tasks.add(SHOW_ON_START_TASK_NAME, function() {
1122 instrumented.storage.local.get('notificationGroups', function(items) { 1140 instrumented.storage.local.get('notificationGroups', function(items) {
1123 console.log('onStartup-get ' + JSON.stringify(items)); 1141 console.log('onStartup-get ' + JSON.stringify(items));
1124 items = items || {}; 1142 items = items || {};
1125 /** @type {Object.<string, StoredNotificationGroup>} */ 1143 /** @type {Object.<string, StoredNotificationGroup>} */
1126 items.notificationGroups = items.notificationGroups || {}; 1144 items.notificationGroups = items.notificationGroups || {};
1127 1145
1128 combineAndShowNotificationCards(items.notificationGroups); 1146 combineAndShowNotificationCards(items.notificationGroups, function() {
1147 chrome.storage.local.set(items);
1148 });
1129 }); 1149 });
1130 }); 1150 });
1131 1151
1132 initialize(); 1152 initialize();
1133 }); 1153 });
1134 1154
1135 instrumented. 1155 instrumented.
1136 preferencesPrivate. 1156 preferencesPrivate.
1137 googleGeolocationAccessEnabled. 1157 googleGeolocationAccessEnabled.
1138 onChange. 1158 onChange.
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1216 lastPollNowPayloads: items.lastPollNowPayloads, 1236 lastPollNowPayloads: items.lastPollNowPayloads,
1217 notificationGroups: items.notificationGroups 1237 notificationGroups: items.notificationGroups
1218 }); 1238 });
1219 1239
1220 updateNotificationsCards(); 1240 updateNotificationsCards();
1221 } 1241 }
1222 }); 1242 });
1223 }); 1243 });
1224 } 1244 }
1225 }); 1245 });
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/resources/google_now/cards.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698