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

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

Issue 166033010: Convert Google Now's use of chrome.local.storage.get to use Promises (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebasing to r253863 Created 6 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 | Annotate | Revision Log
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 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 wrapper.instrumentChromeApiFunction('notifications.onClosed.addListener', 0); 189 wrapper.instrumentChromeApiFunction('notifications.onClosed.addListener', 0);
190 wrapper.instrumentChromeApiFunction( 190 wrapper.instrumentChromeApiFunction(
191 'notifications.onPermissionLevelChanged.addListener', 0); 191 'notifications.onPermissionLevelChanged.addListener', 0);
192 wrapper.instrumentChromeApiFunction( 192 wrapper.instrumentChromeApiFunction(
193 'notifications.onShowSettings.addListener', 0); 193 'notifications.onShowSettings.addListener', 0);
194 wrapper.instrumentChromeApiFunction('permissions.contains', 1); 194 wrapper.instrumentChromeApiFunction('permissions.contains', 1);
195 wrapper.instrumentChromeApiFunction('pushMessaging.onMessage.addListener', 0); 195 wrapper.instrumentChromeApiFunction('pushMessaging.onMessage.addListener', 0);
196 wrapper.instrumentChromeApiFunction('runtime.onInstalled.addListener', 0); 196 wrapper.instrumentChromeApiFunction('runtime.onInstalled.addListener', 0);
197 wrapper.instrumentChromeApiFunction('runtime.onStartup.addListener', 0); 197 wrapper.instrumentChromeApiFunction('runtime.onStartup.addListener', 0);
198 wrapper.instrumentChromeApiFunction('tabs.create', 1); 198 wrapper.instrumentChromeApiFunction('tabs.create', 1);
199 wrapper.instrumentChromeApiFunction('storage.local.get', 1);
200 199
201 var updateCardsAttempts = buildAttemptManager( 200 var updateCardsAttempts = buildAttemptManager(
202 'cards-update', 201 'cards-update',
203 requestCards, 202 requestCards,
204 INITIAL_POLLING_PERIOD_SECONDS, 203 INITIAL_POLLING_PERIOD_SECONDS,
205 MAXIMUM_POLLING_PERIOD_SECONDS); 204 MAXIMUM_POLLING_PERIOD_SECONDS);
206 var dismissalAttempts = buildAttemptManager( 205 var dismissalAttempts = buildAttemptManager(
207 'dismiss', 206 'dismiss',
208 retryPendingDismissals, 207 retryPendingDismissals,
209 INITIAL_RETRY_DISMISS_PERIOD_SECONDS, 208 INITIAL_RETRY_DISMISS_PERIOD_SECONDS,
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 chrome.storage.local.set({googleNowEnabled: false}); 438 chrome.storage.local.set({googleNowEnabled: false});
440 // TODO(vadimt): Remove the line below once the server stops sending groups 439 // TODO(vadimt): Remove the line below once the server stops sending groups
441 // with 'googleNowDisabled' responses. 440 // with 'googleNowDisabled' responses.
442 response.groups = {}; 441 response.groups = {};
443 // Google Now was enabled; now it's disabled. This is a state change. 442 // Google Now was enabled; now it's disabled. This is a state change.
444 onStateChange(); 443 onStateChange();
445 } 444 }
446 445
447 var receivedGroups = response.groups; 446 var receivedGroups = response.groups;
448 447
449 instrumented.storage.local.get( 448 fillFromChromeLocalStorage({
450 ['notificationGroups', 'recentDismissals'], 449 /** @type {Object.<string, StoredNotificationGroup>} */
451 function(items) { 450 notificationGroups: {},
452 console.log( 451 /** @type {Object.<NotificationId, number>} */
453 'processServerResponse-get ' + JSON.stringify(items)); 452 recentDismissals: {}
454 items = items || {}; 453 }).then(function(items) {
455 /** @type {Object.<string, StoredNotificationGroup>} */ 454 console.log('processServerResponse-get ' + JSON.stringify(items));
456 items.notificationGroups = items.notificationGroups || {};
457 /** @type {Object.<NotificationId, number>} */
458 items.recentDismissals = items.recentDismissals || {};
459 455
460 // Build a set of non-expired recent dismissals. It will be used for 456 // Build a set of non-expired recent dismissals. It will be used for
461 // client-side filtering of cards. 457 // client-side filtering of cards.
462 /** @type {Object.<NotificationId, number>} */ 458 /** @type {Object.<NotificationId, number>} */
463 var updatedRecentDismissals = {}; 459 var updatedRecentDismissals = {};
464 var now = Date.now(); 460 var now = Date.now();
465 for (var notificationId in items.recentDismissals) { 461 for (var notificationId in items.recentDismissals) {
466 var dismissalAge = now - items.recentDismissals[notificationId]; 462 var dismissalAge = now - items.recentDismissals[notificationId];
467 if (dismissalAge < DISMISS_RETENTION_TIME_MS) { 463 if (dismissalAge < DISMISS_RETENTION_TIME_MS) {
468 updatedRecentDismissals[notificationId] = 464 updatedRecentDismissals[notificationId] =
469 items.recentDismissals[notificationId]; 465 items.recentDismissals[notificationId];
470 } 466 }
467 }
468
469 // Populate groups with corresponding cards.
470 if (response.notifications) {
471 for (var i = 0; i < response.notifications.length; ++i) {
472 /** @type {ReceivedNotification} */
473 var card = response.notifications[i];
474 if (!(card.notificationId in updatedRecentDismissals)) {
475 var group = receivedGroups[card.groupName];
476 group.cards = group.cards || [];
477 group.cards.push(card);
471 } 478 }
479 }
480 }
472 481
473 // Populate groups with corresponding cards. 482 // Build updated set of groups.
474 if (response.notifications) { 483 var updatedGroups = {};
475 for (var i = 0; i < response.notifications.length; ++i) {
476 /** @type {ReceivedNotification} */
477 var card = response.notifications[i];
478 if (!(card.notificationId in updatedRecentDismissals)) {
479 var group = receivedGroups[card.groupName];
480 group.cards = group.cards || [];
481 group.cards.push(card);
482 }
483 }
484 }
485 484
486 // Build updated set of groups. 485 for (var groupName in receivedGroups) {
487 var updatedGroups = {}; 486 var receivedGroup = receivedGroups[groupName];
487 var storedGroup = items.notificationGroups[groupName] || {
488 cards: [],
489 cardsTimestamp: undefined,
490 nextPollTime: undefined,
491 rank: undefined
492 };
488 493
489 for (var groupName in receivedGroups) { 494 if (receivedGroup.requested)
490 var receivedGroup = receivedGroups[groupName]; 495 receivedGroup.cards = receivedGroup.cards || [];
491 var storedGroup = items.notificationGroups[groupName] || {
492 cards: [],
493 cardsTimestamp: undefined,
494 nextPollTime: undefined,
495 rank: undefined
496 };
497 496
498 if (receivedGroup.requested) 497 if (receivedGroup.cards) {
499 receivedGroup.cards = receivedGroup.cards || []; 498 // If the group contains a cards update, all its fields will get new
499 // values.
500 storedGroup.cards = receivedGroup.cards;
501 storedGroup.cardsTimestamp = now;
502 storedGroup.rank = receivedGroup.rank;
503 storedGroup.nextPollTime = undefined;
504 // The code below assigns nextPollTime a defined value if
505 // nextPollSeconds is specified in the received group.
506 // If the group's cards are not updated, and nextPollSeconds is
507 // unspecified, this method doesn't change group's nextPollTime.
508 }
500 509
501 if (receivedGroup.cards) { 510 // 'nextPollSeconds' may be sent even for groups that don't contain
502 // If the group contains a cards update, all its fields will get new 511 // cards updates.
503 // values. 512 if (receivedGroup.nextPollSeconds !== undefined) {
504 storedGroup.cards = receivedGroup.cards; 513 storedGroup.nextPollTime =
505 storedGroup.cardsTimestamp = now; 514 now + receivedGroup.nextPollSeconds * MS_IN_SECOND;
506 storedGroup.rank = receivedGroup.rank; 515 }
507 storedGroup.nextPollTime = undefined;
508 // The code below assigns nextPollTime a defined value if
509 // nextPollSeconds is specified in the received group.
510 // If the group's cards are not updated, and nextPollSeconds is
511 // unspecified, this method doesn't change group's nextPollTime.
512 }
513 516
514 // 'nextPollSeconds' may be sent even for groups that don't contain 517 updatedGroups[groupName] = storedGroup;
515 // cards updates. 518 }
516 if (receivedGroup.nextPollSeconds !== undefined) {
517 storedGroup.nextPollTime =
518 now + receivedGroup.nextPollSeconds * MS_IN_SECOND;
519 }
520 519
521 updatedGroups[groupName] = storedGroup; 520 scheduleNextPoll(updatedGroups, !response.googleNowDisabled);
522 } 521 combineAndShowNotificationCards(
523 522 updatedGroups,
524 scheduleNextPoll(updatedGroups, !response.googleNowDisabled); 523 function() {
525 combineAndShowNotificationCards( 524 chrome.storage.local.set({
526 updatedGroups, 525 notificationGroups: updatedGroups,
527 function() { 526 recentDismissals: updatedRecentDismissals
528 chrome.storage.local.set({ 527 });
529 notificationGroups: updatedGroups, 528 recordEvent(GoogleNowEvent.CARDS_PARSE_SUCCESS);
530 recentDismissals: updatedRecentDismissals 529 },
531 }); 530 onCardShown);
532 recordEvent(GoogleNowEvent.CARDS_PARSE_SUCCESS); 531 });
533 },
534 onCardShown);
535 });
536 } 532 }
537 533
538 /** 534 /**
539 * Update the Explanatory Total Cards Shown Count. 535 * Update the Explanatory Total Cards Shown Count.
540 */ 536 */
541 function countExplanatoryCard() { 537 function countExplanatoryCard() {
542 localStorage['explanatoryCardsShown']++; 538 localStorage['explanatoryCardsShown']++;
543 } 539 }
544 540
545 /** 541 /**
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
619 request.send(); 615 request.send();
620 }); 616 });
621 } 617 }
622 618
623 /** 619 /**
624 * Requests notification cards from the server. 620 * Requests notification cards from the server.
625 */ 621 */
626 function requestNotificationCards() { 622 function requestNotificationCards() {
627 console.log('requestNotificationCards'); 623 console.log('requestNotificationCards');
628 624
629 instrumented.storage.local.get( 625 fillFromChromeLocalStorage({
630 ['notificationGroups', 'googleNowEnabled'], function(items) {
631 console.log('requestNotificationCards-storage-get ' +
632 JSON.stringify(items));
633 items = items || {};
634 /** @type {Object.<string, StoredNotificationGroup>} */ 626 /** @type {Object.<string, StoredNotificationGroup>} */
635 items.notificationGroups = items.notificationGroups || {}; 627 notificationGroups: {},
628 googleNowEnabled: false
629 }).then(function(items) {
630 console.log(
631 'requestNotificationCards-storage-get ' + JSON.stringify(items));
636 632
637 var groupsToRequest = []; 633 var groupsToRequest = [];
638 634
639 var now = Date.now(); 635 var now = Date.now();
640 636
641 for (var groupName in items.notificationGroups) { 637 for (var groupName in items.notificationGroups) {
642 var group = items.notificationGroups[groupName]; 638 var group = items.notificationGroups[groupName];
643 if (group.nextPollTime !== undefined && group.nextPollTime <= now) 639 if (group.nextPollTime !== undefined && group.nextPollTime <= now)
644 groupsToRequest.push(groupName); 640 groupsToRequest.push(groupName);
645 } 641 }
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 callbackBoolean(false); 732 callbackBoolean(false);
737 }); 733 });
738 } 734 }
739 735
740 /** 736 /**
741 * Tries to send dismiss requests for all pending dismissals. 737 * Tries to send dismiss requests for all pending dismissals.
742 * @param {function(boolean)} callbackBoolean Completion callback with 'success' 738 * @param {function(boolean)} callbackBoolean Completion callback with 'success'
743 * parameter. Success means that no pending dismissals are left. 739 * parameter. Success means that no pending dismissals are left.
744 */ 740 */
745 function processPendingDismissals(callbackBoolean) { 741 function processPendingDismissals(callbackBoolean) {
746 instrumented.storage.local.get(['pendingDismissals', 'recentDismissals'], 742 fillFromChromeLocalStorage({
747 function(items) { 743 /** @type {Array.<PendingDismissal>} */
748 console.log('processPendingDismissals-storage-get ' + 744 pendingDismissals: [],
749 JSON.stringify(items)); 745 /** @type {Object.<NotificationId, number>} */
750 items = items || {}; 746 recentDismissals: {}
751 /** @type {Array.<PendingDismissal>} */ 747 }).then(function(items) {
752 items.pendingDismissals = items.pendingDismissals || []; 748 console.log(
753 /** @type {Object.<NotificationId, number>} */ 749 'processPendingDismissals-storage-get ' + JSON.stringify(items));
754 items.recentDismissals = items.recentDismissals || {};
755 750
756 var dismissalsChanged = false; 751 var dismissalsChanged = false;
757 752
758 function onFinish(success) { 753 function onFinish(success) {
759 if (dismissalsChanged) { 754 if (dismissalsChanged) {
760 chrome.storage.local.set({ 755 chrome.storage.local.set({
761 pendingDismissals: items.pendingDismissals, 756 pendingDismissals: items.pendingDismissals,
762 recentDismissals: items.recentDismissals 757 recentDismissals: items.recentDismissals
763 }); 758 });
764 } 759 }
765 callbackBoolean(success); 760 callbackBoolean(success);
766 } 761 }
767 762
768 function doProcessDismissals() { 763 function doProcessDismissals() {
769 if (items.pendingDismissals.length == 0) { 764 if (items.pendingDismissals.length == 0) {
770 dismissalAttempts.stop(); 765 dismissalAttempts.stop();
771 onFinish(true); 766 onFinish(true);
772 return; 767 return;
773 } 768 }
774 769
775 // Send dismissal for the first card, and if successful, repeat 770 // Send dismissal for the first card, and if successful, repeat
776 // recursively with the rest. 771 // recursively with the rest.
777 /** @type {PendingDismissal} */ 772 /** @type {PendingDismissal} */
778 var dismissal = items.pendingDismissals[0]; 773 var dismissal = items.pendingDismissals[0];
779 requestCardDismissal( 774 requestCardDismissal(
780 dismissal.chromeNotificationId, 775 dismissal.chromeNotificationId,
781 dismissal.time, 776 dismissal.time,
782 dismissal.dismissalData, 777 dismissal.dismissalData,
783 function(done) { 778 function(done) {
784 if (done) { 779 if (done) {
785 dismissalsChanged = true; 780 dismissalsChanged = true;
786 items.pendingDismissals.splice(0, 1); 781 items.pendingDismissals.splice(0, 1);
787 items.recentDismissals[ 782 items.recentDismissals[
788 dismissal.dismissalData.notificationId] = 783 dismissal.dismissalData.notificationId] =
789 Date.now(); 784 Date.now();
790 doProcessDismissals(); 785 doProcessDismissals();
791 } else { 786 } else {
792 onFinish(false); 787 onFinish(false);
793 } 788 }
794 }); 789 });
795 } 790 }
796 791
797 doProcessDismissals(); 792 doProcessDismissals();
798 }); 793 });
799 } 794 }
800 795
801 /** 796 /**
802 * Submits a task to send pending dismissals. 797 * Submits a task to send pending dismissals.
803 */ 798 */
804 function retryPendingDismissals() { 799 function retryPendingDismissals() {
805 tasks.add(RETRY_DISMISS_TASK_NAME, function() { 800 tasks.add(RETRY_DISMISS_TASK_NAME, function() {
806 dismissalAttempts.planForNext(function() { 801 dismissalAttempts.planForNext(function() {
807 processPendingDismissals(function(success) {}); 802 processPendingDismissals(function(success) {});
808 }); 803 });
(...skipping 15 matching lines...) Expand all
824 819
825 /** 820 /**
826 * Opens URL corresponding to the clicked part of the notification. 821 * Opens URL corresponding to the clicked part of the notification.
827 * @param {ChromeNotificationId} chromeNotificationId chrome.notifications ID of 822 * @param {ChromeNotificationId} chromeNotificationId chrome.notifications ID of
828 * the card. 823 * the card.
829 * @param {function((ActionUrls|undefined)): (string|undefined)} selector 824 * @param {function((ActionUrls|undefined)): (string|undefined)} selector
830 * Function that extracts the url for the clicked area from the button 825 * Function that extracts the url for the clicked area from the button
831 * action URLs info. 826 * action URLs info.
832 */ 827 */
833 function onNotificationClicked(chromeNotificationId, selector) { 828 function onNotificationClicked(chromeNotificationId, selector) {
834 instrumented.storage.local.get('notificationsData', function(items) { 829 fillFromChromeLocalStorage({
835 /** @type {(NotificationDataEntry|undefined)} */ 830 /** @type {NotificationDataEntry} */
836 var notificationData = items && 831 notificationsData: {}
837 items.notificationsData && 832 }).then(function(items) {
838 items.notificationsData[chromeNotificationId]; 833 var notificationData = items.notificationsData[chromeNotificationId];
839
840 if (!notificationData) 834 if (!notificationData)
841 return; 835 return;
842 836
843 var url = selector(notificationData.actionUrls); 837 var url = selector(notificationData.actionUrls);
844 if (!url) 838 if (!url)
845 return; 839 return;
846 840
847 openUrl(url); 841 openUrl(url);
848 }); 842 });
849 } 843 }
850 844
851 /** 845 /**
852 * Callback for chrome.notifications.onClosed event. 846 * Callback for chrome.notifications.onClosed event.
853 * @param {ChromeNotificationId} chromeNotificationId chrome.notifications ID of 847 * @param {ChromeNotificationId} chromeNotificationId chrome.notifications ID of
854 * the card. 848 * the card.
855 * @param {boolean} byUser Whether the notification was closed by the user. 849 * @param {boolean} byUser Whether the notification was closed by the user.
856 */ 850 */
857 function onNotificationClosed(chromeNotificationId, byUser) { 851 function onNotificationClosed(chromeNotificationId, byUser) {
858 if (!byUser) 852 if (!byUser)
859 return; 853 return;
860 854
861 // At this point we are guaranteed that the notification is a now card. 855 // At this point we are guaranteed that the notification is a now card.
862 chrome.metricsPrivate.recordUserAction('GoogleNow.Dismissed'); 856 chrome.metricsPrivate.recordUserAction('GoogleNow.Dismissed');
863 857
864 tasks.add(DISMISS_CARD_TASK_NAME, function() { 858 tasks.add(DISMISS_CARD_TASK_NAME, function() {
865 dismissalAttempts.start(); 859 dismissalAttempts.start();
866 860
867 instrumented.storage.local.get( 861 fillFromChromeLocalStorage({
868 ['pendingDismissals', 'notificationsData', 'notificationGroups'], 862 /** @type {Array.<PendingDismissal>} */
869 function(items) { 863 pendingDismissals: [],
870 items = items || {}; 864 /** @type {Object.<string, NotificationDataEntry>} */
871 /** @type {Array.<PendingDismissal>} */ 865 notificationsData: {},
872 items.pendingDismissals = items.pendingDismissals || []; 866 /** @type {Object.<string, StoredNotificationGroup>} */
873 /** @type {Object.<string, NotificationDataEntry>} */ 867 notificationGroups: {}
874 items.notificationsData = items.notificationsData || {}; 868 }).then(function(items) {
875 /** @type {Object.<string, StoredNotificationGroup>} */ 869 /** @type {NotificationDataEntry} */
876 items.notificationGroups = items.notificationGroups || {}; 870 var notificationData =
871 items.notificationsData[chromeNotificationId] ||
872 {
873 timestamp: Date.now(),
874 combinedCard: []
875 };
877 876
878 /** @type {NotificationDataEntry} */ 877 var dismissalResult =
879 var notificationData = 878 cardSet.onDismissal(
880 items.notificationsData[chromeNotificationId] || 879 chromeNotificationId,
881 { 880 notificationData,
882 timestamp: Date.now(), 881 items.notificationGroups);
883 combinedCard: []
884 };
885 882
886 var dismissalResult = 883 for (var i = 0; i < dismissalResult.dismissals.length; i++) {
887 cardSet.onDismissal( 884 /** @type {PendingDismissal} */
888 chromeNotificationId, 885 var dismissal = {
889 notificationData, 886 chromeNotificationId: chromeNotificationId,
890 items.notificationGroups); 887 time: Date.now(),
888 dismissalData: dismissalResult.dismissals[i]
889 };
890 items.pendingDismissals.push(dismissal);
891 }
891 892
892 for (var i = 0; i < dismissalResult.dismissals.length; i++) { 893 items.notificationsData[chromeNotificationId] =
893 /** @type {PendingDismissal} */ 894 dismissalResult.notificationData;
894 var dismissal = {
895 chromeNotificationId: chromeNotificationId,
896 time: Date.now(),
897 dismissalData: dismissalResult.dismissals[i]
898 };
899 items.pendingDismissals.push(dismissal);
900 }
901 895
902 items.notificationsData[chromeNotificationId] = 896 chrome.storage.local.set(items);
903 dismissalResult.notificationData;
904 897
905 chrome.storage.local.set(items); 898 processPendingDismissals(function(success) {});
906 899 });
907 processPendingDismissals(function(success) {});
908 });
909 }); 900 });
910 } 901 }
911 902
912 /** 903 /**
913 * Initializes the polling system to start fetching cards. 904 * Initializes the polling system to start fetching cards.
914 */ 905 */
915 function startPollingCards() { 906 function startPollingCards() {
916 console.log('startPollingCards'); 907 console.log('startPollingCards');
917 // Create an update timer for a case when for some reason requesting 908 // Create an update timer for a case when for some reason requesting
918 // cards gets stuck. 909 // cards gets stuck.
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
1066 }); 1057 });
1067 }); 1058 });
1068 } 1059 }
1069 1060
1070 /** 1061 /**
1071 * Gets the previous Google Now opt-in state. 1062 * Gets the previous Google Now opt-in state.
1072 * @return {Promise} A promise to determine the previous Google Now 1063 * @return {Promise} A promise to determine the previous Google Now
1073 * opt-in state. 1064 * opt-in state.
1074 */ 1065 */
1075 function isGoogleNowEnabled() { 1066 function isGoogleNowEnabled() {
1076 return new Promise(function(resolve) { 1067 return fillFromChromeLocalStorage({googleNowEnabled: false})
1077 instrumented.storage.local.get('googleNowEnabled', function(items) { 1068 .then(function(items) {
1078 resolve(items && !!items.googleNowEnabled); 1069 return items.googleNowEnabled;
1079 }); 1070 });
1080 });
1081 } 1071 }
1082 1072
1083 instrumented.runtime.onInstalled.addListener(function(details) { 1073 instrumented.runtime.onInstalled.addListener(function(details) {
1084 console.log('onInstalled ' + JSON.stringify(details)); 1074 console.log('onInstalled ' + JSON.stringify(details));
1085 if (details.reason != 'chrome_update') { 1075 if (details.reason != 'chrome_update') {
1086 initialize(); 1076 initialize();
1087 } 1077 }
1088 }); 1078 });
1089 1079
1090 instrumented.runtime.onStartup.addListener(function() { 1080 instrumented.runtime.onStartup.addListener(function() {
1091 console.log('onStartup'); 1081 console.log('onStartup');
1092 1082
1093 // Show notifications received by earlier polls. Doing this as early as 1083 // Show notifications received by earlier polls. Doing this as early as
1094 // possible to reduce latency of showing first notifications. This mimics how 1084 // possible to reduce latency of showing first notifications. This mimics how
1095 // persistent notifications will work. 1085 // persistent notifications will work.
1096 tasks.add(SHOW_ON_START_TASK_NAME, function() { 1086 tasks.add(SHOW_ON_START_TASK_NAME, function() {
1097 instrumented.storage.local.get('notificationGroups', function(items) { 1087 fillFromChromeLocalStorage({
1088 /** @type {Object.<string, StoredNotificationGroup>} */
1089 notificationGroups: {}
1090 }).then(function(items) {
1098 console.log('onStartup-get ' + JSON.stringify(items)); 1091 console.log('onStartup-get ' + JSON.stringify(items));
1099 items = items || {};
1100 /** @type {Object.<string, StoredNotificationGroup>} */
1101 items.notificationGroups = items.notificationGroups || {};
1102 1092
1103 combineAndShowNotificationCards(items.notificationGroups, function() { 1093 combineAndShowNotificationCards(items.notificationGroups, function() {
1104 chrome.storage.local.set(items); 1094 chrome.storage.local.set(items);
1105 }); 1095 });
1106 }); 1096 });
1107 }); 1097 });
1108 1098
1109 initialize(); 1099 initialize();
1110 }); 1100 });
1111 1101
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1146 }); 1136 });
1147 1137
1148 instrumented.pushMessaging.onMessage.addListener(function(message) { 1138 instrumented.pushMessaging.onMessage.addListener(function(message) {
1149 // message.payload will be '' when the extension first starts. 1139 // message.payload will be '' when the extension first starts.
1150 // Each time after signing in, we'll get latest payload for all channels. 1140 // Each time after signing in, we'll get latest payload for all channels.
1151 // So, we need to poll the server only when the payload is non-empty and has 1141 // So, we need to poll the server only when the payload is non-empty and has
1152 // changed. 1142 // changed.
1153 console.log('pushMessaging.onMessage ' + JSON.stringify(message)); 1143 console.log('pushMessaging.onMessage ' + JSON.stringify(message));
1154 if (message.payload.indexOf('REQUEST_CARDS') == 0) { 1144 if (message.payload.indexOf('REQUEST_CARDS') == 0) {
1155 tasks.add(ON_PUSH_MESSAGE_START_TASK_NAME, function() { 1145 tasks.add(ON_PUSH_MESSAGE_START_TASK_NAME, function() {
1156 instrumented.storage.local.get( 1146 // Accept promise rejection on failure since it's safer to do nothing,
1157 ['lastPollNowPayloads', 'notificationGroups'], function(items) { 1147 // preventing polling the server when the payload really didn't change.
1158 // If storage.get fails, it's safer to do nothing, preventing polling 1148 fillFromChromeLocalStorage({
1159 // the server when the payload really didn't change. 1149 lastPollNowPayloads: {},
1160 if (!items) 1150 /** @type {Object.<string, StoredNotificationGroup>} */
1161 return; 1151 notificationGroups: {}
1162 1152 }, PromiseRejection.ALLOW).then(function(items) {
1163 // If this is the first time we get lastPollNowPayloads, initialize it.
1164 items.lastPollNowPayloads = items.lastPollNowPayloads || {};
1165
1166 if (items.lastPollNowPayloads[message.subchannelId] != 1153 if (items.lastPollNowPayloads[message.subchannelId] !=
1167 message.payload) { 1154 message.payload) {
1168 items.lastPollNowPayloads[message.subchannelId] = message.payload; 1155 items.lastPollNowPayloads[message.subchannelId] = message.payload;
1169 1156
1170 /** @type {Object.<string, StoredNotificationGroup>} */
1171 items.notificationGroups = items.notificationGroups || {};
1172 items.notificationGroups['PUSH' + message.subchannelId] = { 1157 items.notificationGroups['PUSH' + message.subchannelId] = {
1173 cards: [], 1158 cards: [],
1174 nextPollTime: Date.now() 1159 nextPollTime: Date.now()
1175 }; 1160 };
1176 1161
1177 chrome.storage.local.set({ 1162 chrome.storage.local.set({
1178 lastPollNowPayloads: items.lastPollNowPayloads, 1163 lastPollNowPayloads: items.lastPollNowPayloads,
1179 notificationGroups: items.notificationGroups 1164 notificationGroups: items.notificationGroups
1180 }); 1165 });
1181 1166
1182 requestCards(); 1167 requestCards();
1183 } 1168 }
1184 }); 1169 });
1185 }); 1170 });
1186 } 1171 }
1187 }); 1172 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698