OLD | NEW |
---|---|
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 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
199 'preferencesPrivate.googleGeolocationAccessEnabled.get', | 199 'preferencesPrivate.googleGeolocationAccessEnabled.get', |
200 1); | 200 1); |
201 wrapper.instrumentChromeApiFunction( | 201 wrapper.instrumentChromeApiFunction( |
202 'preferencesPrivate.googleGeolocationAccessEnabled.onChange.addListener', | 202 'preferencesPrivate.googleGeolocationAccessEnabled.onChange.addListener', |
203 0); | 203 0); |
204 wrapper.instrumentChromeApiFunction('permissions.contains', 1); | 204 wrapper.instrumentChromeApiFunction('permissions.contains', 1); |
205 wrapper.instrumentChromeApiFunction('pushMessaging.onMessage.addListener', 0); | 205 wrapper.instrumentChromeApiFunction('pushMessaging.onMessage.addListener', 0); |
206 wrapper.instrumentChromeApiFunction('runtime.onInstalled.addListener', 0); | 206 wrapper.instrumentChromeApiFunction('runtime.onInstalled.addListener', 0); |
207 wrapper.instrumentChromeApiFunction('runtime.onStartup.addListener', 0); | 207 wrapper.instrumentChromeApiFunction('runtime.onStartup.addListener', 0); |
208 wrapper.instrumentChromeApiFunction('tabs.create', 1); | 208 wrapper.instrumentChromeApiFunction('tabs.create', 1); |
209 wrapper.instrumentChromeApiFunction('storage.local.get', 1); | |
210 | 209 |
211 var updateCardsAttempts = buildAttemptManager( | 210 var updateCardsAttempts = buildAttemptManager( |
212 'cards-update', | 211 'cards-update', |
213 requestLocation, | 212 requestLocation, |
214 INITIAL_POLLING_PERIOD_SECONDS, | 213 INITIAL_POLLING_PERIOD_SECONDS, |
215 MAXIMUM_POLLING_PERIOD_SECONDS); | 214 MAXIMUM_POLLING_PERIOD_SECONDS); |
216 var dismissalAttempts = buildAttemptManager( | 215 var dismissalAttempts = buildAttemptManager( |
217 'dismiss', | 216 'dismiss', |
218 retryPendingDismissals, | 217 retryPendingDismissals, |
219 INITIAL_RETRY_DISMISS_PERIOD_SECONDS, | 218 INITIAL_RETRY_DISMISS_PERIOD_SECONDS, |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
451 chrome.storage.local.set({googleNowEnabled: false}); | 450 chrome.storage.local.set({googleNowEnabled: false}); |
452 // TODO(vadimt): Remove the line below once the server stops sending groups | 451 // TODO(vadimt): Remove the line below once the server stops sending groups |
453 // with 'googleNowDisabled' responses. | 452 // with 'googleNowDisabled' responses. |
454 response.groups = {}; | 453 response.groups = {}; |
455 // Google Now was enabled; now it's disabled. This is a state change. | 454 // Google Now was enabled; now it's disabled. This is a state change. |
456 onStateChange(); | 455 onStateChange(); |
457 } | 456 } |
458 | 457 |
459 var receivedGroups = response.groups; | 458 var receivedGroups = response.groups; |
460 | 459 |
461 instrumented.storage.local.get( | 460 fillFromChromeLocalStorage({ |
462 ['notificationGroups', 'recentDismissals'], | 461 /** @type {Object.<string, StoredNotificationGroup>} */ |
463 function(items) { | 462 notificationGroups: {}, |
464 console.log( | 463 /** @type {Object.<NotificationId, number>} */ |
465 'processServerResponse-get ' + JSON.stringify(items)); | 464 recentDismissals: {} |
466 items = items || {}; | 465 }).then(function(items) { |
467 /** @type {Object.<string, StoredNotificationGroup>} */ | 466 console.log('processServerResponse-get ' + JSON.stringify(items)); |
468 items.notificationGroups = items.notificationGroups || {}; | |
469 /** @type {Object.<NotificationId, number>} */ | |
470 items.recentDismissals = items.recentDismissals || {}; | |
471 | 467 |
472 // Build a set of non-expired recent dismissals. It will be used for | 468 // Build a set of non-expired recent dismissals. It will be used for |
473 // client-side filtering of cards. | 469 // client-side filtering of cards. |
474 /** @type {Object.<NotificationId, number>} */ | 470 /** @type {Object.<NotificationId, number>} */ |
475 var updatedRecentDismissals = {}; | 471 var updatedRecentDismissals = {}; |
476 var now = Date.now(); | 472 var now = Date.now(); |
477 for (var notificationId in items.recentDismissals) { | 473 for (var notificationId in items.recentDismissals) { |
478 var dismissalAge = now - items.recentDismissals[notificationId]; | 474 var dismissalAge = now - items.recentDismissals[notificationId]; |
479 if (dismissalAge < DISMISS_RETENTION_TIME_MS) { | 475 if (dismissalAge < DISMISS_RETENTION_TIME_MS) { |
480 updatedRecentDismissals[notificationId] = | 476 updatedRecentDismissals[notificationId] = |
481 items.recentDismissals[notificationId]; | 477 items.recentDismissals[notificationId]; |
482 } | 478 } |
479 } | |
480 | |
481 // Populate groups with corresponding cards. | |
482 if (response.notifications) { | |
483 for (var i = 0; i < response.notifications.length; ++i) { | |
484 /** @type {ReceivedNotification} */ | |
485 var card = response.notifications[i]; | |
486 if (!(card.notificationId in updatedRecentDismissals)) { | |
487 var group = receivedGroups[card.groupName]; | |
488 group.cards = group.cards || []; | |
489 group.cards.push(card); | |
483 } | 490 } |
491 } | |
492 } | |
484 | 493 |
485 // Populate groups with corresponding cards. | 494 // Build updated set of groups. |
486 if (response.notifications) { | 495 var updatedGroups = {}; |
487 for (var i = 0; i < response.notifications.length; ++i) { | |
488 /** @type {ReceivedNotification} */ | |
489 var card = response.notifications[i]; | |
490 if (!(card.notificationId in updatedRecentDismissals)) { | |
491 var group = receivedGroups[card.groupName]; | |
492 group.cards = group.cards || []; | |
493 group.cards.push(card); | |
494 } | |
495 } | |
496 } | |
497 | 496 |
498 // Build updated set of groups. | 497 for (var groupName in receivedGroups) { |
499 var updatedGroups = {}; | 498 var receivedGroup = receivedGroups[groupName]; |
499 var storedGroup = items.notificationGroups[groupName] || { | |
500 cards: [], | |
501 cardsTimestamp: undefined, | |
502 nextPollTime: undefined, | |
503 rank: undefined | |
504 }; | |
500 | 505 |
501 for (var groupName in receivedGroups) { | 506 if (receivedGroup.requested) |
502 var receivedGroup = receivedGroups[groupName]; | 507 receivedGroup.cards = receivedGroup.cards || []; |
503 var storedGroup = items.notificationGroups[groupName] || { | |
504 cards: [], | |
505 cardsTimestamp: undefined, | |
506 nextPollTime: undefined, | |
507 rank: undefined | |
508 }; | |
509 | 508 |
510 if (receivedGroup.requested) | 509 if (receivedGroup.cards) { |
511 receivedGroup.cards = receivedGroup.cards || []; | 510 // If the group contains a cards update, all its fields will get new |
511 // values. | |
512 storedGroup.cards = receivedGroup.cards; | |
513 storedGroup.cardsTimestamp = now; | |
514 storedGroup.rank = receivedGroup.rank; | |
515 storedGroup.nextPollTime = undefined; | |
516 // The code below assigns nextPollTime a defined value if | |
517 // nextPollSeconds is specified in the received group. | |
518 // If the group's cards are not updated, and nextPollSeconds is | |
519 // unspecified, this method doesn't change group's nextPollTime. | |
520 } | |
512 | 521 |
513 if (receivedGroup.cards) { | 522 // 'nextPollSeconds' may be sent even for groups that don't contain |
514 // If the group contains a cards update, all its fields will get new | 523 // cards updates. |
515 // values. | 524 if (receivedGroup.nextPollSeconds !== undefined) { |
516 storedGroup.cards = receivedGroup.cards; | 525 storedGroup.nextPollTime = |
517 storedGroup.cardsTimestamp = now; | 526 now + receivedGroup.nextPollSeconds * MS_IN_SECOND; |
518 storedGroup.rank = receivedGroup.rank; | 527 } |
519 storedGroup.nextPollTime = undefined; | |
520 // The code below assigns nextPollTime a defined value if | |
521 // nextPollSeconds is specified in the received group. | |
522 // If the group's cards are not updated, and nextPollSeconds is | |
523 // unspecified, this method doesn't change group's nextPollTime. | |
524 } | |
525 | 528 |
526 // 'nextPollSeconds' may be sent even for groups that don't contain | 529 updatedGroups[groupName] = storedGroup; |
527 // cards updates. | 530 } |
528 if (receivedGroup.nextPollSeconds !== undefined) { | |
529 storedGroup.nextPollTime = | |
530 now + receivedGroup.nextPollSeconds * MS_IN_SECOND; | |
531 } | |
532 | 531 |
533 updatedGroups[groupName] = storedGroup; | 532 scheduleNextPoll(updatedGroups, !response.googleNowDisabled); |
534 } | 533 combineAndShowNotificationCards( |
535 | 534 updatedGroups, |
536 scheduleNextPoll(updatedGroups, !response.googleNowDisabled); | 535 function() { |
537 combineAndShowNotificationCards( | 536 chrome.storage.local.set({ |
538 updatedGroups, | 537 notificationGroups: updatedGroups, |
539 function() { | 538 recentDismissals: updatedRecentDismissals |
540 chrome.storage.local.set({ | 539 }); |
541 notificationGroups: updatedGroups, | 540 recordEvent(GoogleNowEvent.CARDS_PARSE_SUCCESS); |
542 recentDismissals: updatedRecentDismissals | 541 }, |
543 }); | 542 onCardShown); |
544 recordEvent(GoogleNowEvent.CARDS_PARSE_SUCCESS); | 543 }); |
545 }, | |
546 onCardShown); | |
547 }); | |
548 } | 544 } |
549 | 545 |
550 /** | 546 /** |
551 * Update the Explanatory Total Cards Shown Count. | 547 * Update the Explanatory Total Cards Shown Count. |
552 */ | 548 */ |
553 function countExplanatoryCard() { | 549 function countExplanatoryCard() { |
554 localStorage['explanatoryCardsShown']++; | 550 localStorage['explanatoryCardsShown']++; |
555 } | 551 } |
556 | 552 |
557 /** | 553 /** |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
630 }); | 626 }); |
631 } | 627 } |
632 | 628 |
633 /** | 629 /** |
634 * Requests notification cards from the server. | 630 * Requests notification cards from the server. |
635 * @param {Location=} position Location of this computer. | 631 * @param {Location=} position Location of this computer. |
636 */ | 632 */ |
637 function requestNotificationCards(position) { | 633 function requestNotificationCards(position) { |
638 console.log('requestNotificationCards ' + JSON.stringify(position)); | 634 console.log('requestNotificationCards ' + JSON.stringify(position)); |
639 | 635 |
640 instrumented.storage.local.get( | 636 fillFromChromeLocalStorage({ |
641 ['notificationGroups', 'googleNowEnabled'], function(items) { | |
642 console.log('requestNotificationCards-storage-get ' + | |
643 JSON.stringify(items)); | |
644 items = items || {}; | |
645 /** @type {Object.<string, StoredNotificationGroup>} */ | 637 /** @type {Object.<string, StoredNotificationGroup>} */ |
646 items.notificationGroups = items.notificationGroups || {}; | 638 notificationGroups: {}, |
639 googleNowEnabled: false | |
640 }).then(function(items) { | |
641 console.log( | |
642 'requestNotificationCards-storage-get ' + JSON.stringify(items)); | |
647 | 643 |
648 var groupsToRequest = []; | 644 var groupsToRequest = []; |
649 | 645 |
650 var now = Date.now(); | 646 var now = Date.now(); |
651 | 647 |
652 for (var groupName in items.notificationGroups) { | 648 for (var groupName in items.notificationGroups) { |
653 var group = items.notificationGroups[groupName]; | 649 var group = items.notificationGroups[groupName]; |
654 if (group.nextPollTime !== undefined && group.nextPollTime <= now) | 650 if (group.nextPollTime !== undefined && group.nextPollTime <= now) |
655 groupsToRequest.push(groupName); | 651 groupsToRequest.push(groupName); |
656 } | 652 } |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
782 callbackBoolean(false); | 778 callbackBoolean(false); |
783 }); | 779 }); |
784 } | 780 } |
785 | 781 |
786 /** | 782 /** |
787 * Tries to send dismiss requests for all pending dismissals. | 783 * Tries to send dismiss requests for all pending dismissals. |
788 * @param {function(boolean)} callbackBoolean Completion callback with 'success' | 784 * @param {function(boolean)} callbackBoolean Completion callback with 'success' |
789 * parameter. Success means that no pending dismissals are left. | 785 * parameter. Success means that no pending dismissals are left. |
790 */ | 786 */ |
791 function processPendingDismissals(callbackBoolean) { | 787 function processPendingDismissals(callbackBoolean) { |
792 instrumented.storage.local.get(['pendingDismissals', 'recentDismissals'], | 788 fillFromChromeLocalStorage({ |
793 function(items) { | 789 /** @type {Array.<PendingDismissal>} */ |
794 console.log('processPendingDismissals-storage-get ' + | 790 pendingDismissals: [], |
795 JSON.stringify(items)); | 791 /** @type {Object.<NotificationId, number>} */ |
796 items = items || {}; | 792 recentDismissals: {} |
797 /** @type {Array.<PendingDismissal>} */ | 793 }).then(function(items) { |
798 items.pendingDismissals = items.pendingDismissals || []; | 794 console.log( |
799 /** @type {Object.<NotificationId, number>} */ | 795 'processPendingDismissals-storage-get ' + JSON.stringify(items)); |
800 items.recentDismissals = items.recentDismissals || {}; | |
801 | 796 |
802 var dismissalsChanged = false; | 797 var dismissalsChanged = false; |
803 | 798 |
804 function onFinish(success) { | 799 function onFinish(success) { |
805 if (dismissalsChanged) { | 800 if (dismissalsChanged) { |
806 chrome.storage.local.set({ | 801 chrome.storage.local.set({ |
807 pendingDismissals: items.pendingDismissals, | 802 pendingDismissals: items.pendingDismissals, |
808 recentDismissals: items.recentDismissals | 803 recentDismissals: items.recentDismissals |
809 }); | 804 }); |
810 } | 805 } |
811 callbackBoolean(success); | 806 callbackBoolean(success); |
812 } | 807 } |
813 | 808 |
814 function doProcessDismissals() { | 809 function doProcessDismissals() { |
815 if (items.pendingDismissals.length == 0) { | 810 if (items.pendingDismissals.length == 0) { |
816 dismissalAttempts.stop(); | 811 dismissalAttempts.stop(); |
817 onFinish(true); | 812 onFinish(true); |
818 return; | 813 return; |
819 } | 814 } |
820 | 815 |
821 // Send dismissal for the first card, and if successful, repeat | 816 // Send dismissal for the first card, and if successful, repeat |
822 // recursively with the rest. | 817 // recursively with the rest. |
823 /** @type {PendingDismissal} */ | 818 /** @type {PendingDismissal} */ |
824 var dismissal = items.pendingDismissals[0]; | 819 var dismissal = items.pendingDismissals[0]; |
825 requestCardDismissal( | 820 requestCardDismissal( |
826 dismissal.chromeNotificationId, | 821 dismissal.chromeNotificationId, |
827 dismissal.time, | 822 dismissal.time, |
828 dismissal.dismissalData, | 823 dismissal.dismissalData, |
829 function(done) { | 824 function(done) { |
830 if (done) { | 825 if (done) { |
831 dismissalsChanged = true; | 826 dismissalsChanged = true; |
832 items.pendingDismissals.splice(0, 1); | 827 items.pendingDismissals.splice(0, 1); |
833 items.recentDismissals[ | 828 items.recentDismissals[ |
834 dismissal.dismissalData.notificationId] = | 829 dismissal.dismissalData.notificationId] = |
835 Date.now(); | 830 Date.now(); |
836 doProcessDismissals(); | 831 doProcessDismissals(); |
837 } else { | 832 } else { |
838 onFinish(false); | 833 onFinish(false); |
839 } | 834 } |
840 }); | 835 }); |
841 } | 836 } |
842 | 837 |
843 doProcessDismissals(); | 838 doProcessDismissals(); |
844 }); | 839 }); |
845 } | 840 } |
846 | 841 |
847 /** | 842 /** |
848 * Submits a task to send pending dismissals. | 843 * Submits a task to send pending dismissals. |
849 */ | 844 */ |
850 function retryPendingDismissals() { | 845 function retryPendingDismissals() { |
851 tasks.add(RETRY_DISMISS_TASK_NAME, function() { | 846 tasks.add(RETRY_DISMISS_TASK_NAME, function() { |
852 dismissalAttempts.planForNext(function() { | 847 dismissalAttempts.planForNext(function() { |
853 processPendingDismissals(function(success) {}); | 848 processPendingDismissals(function(success) {}); |
854 }); | 849 }); |
(...skipping 15 matching lines...) Expand all Loading... | |
870 | 865 |
871 /** | 866 /** |
872 * Opens URL corresponding to the clicked part of the notification. | 867 * Opens URL corresponding to the clicked part of the notification. |
873 * @param {ChromeNotificationId} chromeNotificationId chrome.notifications ID of | 868 * @param {ChromeNotificationId} chromeNotificationId chrome.notifications ID of |
874 * the card. | 869 * the card. |
875 * @param {function((ActionUrls|undefined)): (string|undefined)} selector | 870 * @param {function((ActionUrls|undefined)): (string|undefined)} selector |
876 * Function that extracts the url for the clicked area from the button | 871 * Function that extracts the url for the clicked area from the button |
877 * action URLs info. | 872 * action URLs info. |
878 */ | 873 */ |
879 function onNotificationClicked(chromeNotificationId, selector) { | 874 function onNotificationClicked(chromeNotificationId, selector) { |
880 instrumented.storage.local.get('notificationsData', function(items) { | 875 fillFromChromeLocalStorage({ |
881 /** @type {(NotificationDataEntry|undefined)} */ | 876 /** @type {NotificationDataEntry} */ |
882 var notificationData = items && | 877 notificationsData: {} |
883 items.notificationsData && | 878 }).then(function(items) { |
884 items.notificationsData[chromeNotificationId]; | 879 var notificationData = items.notificationsData[chromeNotificationId]; |
885 | |
886 if (!notificationData) | 880 if (!notificationData) |
887 return; | 881 return; |
888 | 882 |
889 var url = selector(notificationData.actionUrls); | 883 var url = selector(notificationData.actionUrls); |
890 if (!url) | 884 if (!url) |
891 return; | 885 return; |
892 | 886 |
893 openUrl(url); | 887 openUrl(url); |
894 }); | 888 }); |
895 } | 889 } |
896 | 890 |
897 /** | 891 /** |
898 * Callback for chrome.notifications.onClosed event. | 892 * Callback for chrome.notifications.onClosed event. |
899 * @param {ChromeNotificationId} chromeNotificationId chrome.notifications ID of | 893 * @param {ChromeNotificationId} chromeNotificationId chrome.notifications ID of |
900 * the card. | 894 * the card. |
901 * @param {boolean} byUser Whether the notification was closed by the user. | 895 * @param {boolean} byUser Whether the notification was closed by the user. |
902 */ | 896 */ |
903 function onNotificationClosed(chromeNotificationId, byUser) { | 897 function onNotificationClosed(chromeNotificationId, byUser) { |
904 if (!byUser) | 898 if (!byUser) |
905 return; | 899 return; |
906 | 900 |
907 // At this point we are guaranteed that the notification is a now card. | 901 // At this point we are guaranteed that the notification is a now card. |
908 chrome.metricsPrivate.recordUserAction('GoogleNow.Dismissed'); | 902 chrome.metricsPrivate.recordUserAction('GoogleNow.Dismissed'); |
909 | 903 |
910 tasks.add(DISMISS_CARD_TASK_NAME, function() { | 904 tasks.add(DISMISS_CARD_TASK_NAME, function() { |
911 dismissalAttempts.start(); | 905 dismissalAttempts.start(); |
912 | 906 |
913 instrumented.storage.local.get( | 907 fillFromChromeLocalStorage({ |
914 ['pendingDismissals', 'notificationsData', 'notificationGroups'], | 908 /** @type {Array.<PendingDismissal>} */ |
915 function(items) { | 909 pendingDismissals: [], |
916 items = items || {}; | 910 /** @type {Object.<string, NotificationDataEntry>} */ |
917 /** @type {Array.<PendingDismissal>} */ | 911 notificationsData: {}, |
918 items.pendingDismissals = items.pendingDismissals || []; | 912 /** @type {Object.<string, StoredNotificationGroup>} */ |
919 /** @type {Object.<string, NotificationDataEntry>} */ | 913 notificationGroups: {} |
920 items.notificationsData = items.notificationsData || {}; | 914 }).then(function(items) { |
921 /** @type {Object.<string, StoredNotificationGroup>} */ | 915 /** @type {NotificationDataEntry} */ |
922 items.notificationGroups = items.notificationGroups || {}; | 916 var notificationData = |
917 items.notificationsData[chromeNotificationId] || | |
918 { | |
919 timestamp: Date.now(), | |
920 combinedCard: [] | |
921 }; | |
923 | 922 |
924 /** @type {NotificationDataEntry} */ | 923 var dismissalResult = |
925 var notificationData = | 924 cardSet.onDismissal( |
926 items.notificationsData[chromeNotificationId] || | 925 chromeNotificationId, |
927 { | 926 notificationData, |
928 timestamp: Date.now(), | 927 items.notificationGroups); |
929 combinedCard: [] | |
930 }; | |
931 | 928 |
932 var dismissalResult = | 929 for (var i = 0; i < dismissalResult.dismissals.length; i++) { |
933 cardSet.onDismissal( | 930 /** @type {PendingDismissal} */ |
934 chromeNotificationId, | 931 var dismissal = { |
935 notificationData, | 932 chromeNotificationId: chromeNotificationId, |
936 items.notificationGroups); | 933 time: Date.now(), |
934 dismissalData: dismissalResult.dismissals[i] | |
935 }; | |
936 items.pendingDismissals.push(dismissal); | |
937 } | |
937 | 938 |
938 for (var i = 0; i < dismissalResult.dismissals.length; i++) { | 939 items.notificationsData[chromeNotificationId] = |
939 /** @type {PendingDismissal} */ | 940 dismissalResult.notificationData; |
940 var dismissal = { | |
941 chromeNotificationId: chromeNotificationId, | |
942 time: Date.now(), | |
943 dismissalData: dismissalResult.dismissals[i] | |
944 }; | |
945 items.pendingDismissals.push(dismissal); | |
946 } | |
947 | 941 |
948 items.notificationsData[chromeNotificationId] = | 942 chrome.storage.local.set(items); |
949 dismissalResult.notificationData; | |
950 | 943 |
951 chrome.storage.local.set(items); | 944 processPendingDismissals(function(success) {}); |
952 | 945 }); |
953 processPendingDismissals(function(success) {}); | |
954 }); | |
955 }); | 946 }); |
956 } | 947 } |
957 | 948 |
958 /** | 949 /** |
959 * Initializes the polling system to start monitoring location and fetching | 950 * Initializes the polling system to start monitoring location and fetching |
960 * cards. | 951 * cards. |
961 */ | 952 */ |
962 function startPollingCards() { | 953 function startPollingCards() { |
963 // Create an update timer for a case when for some reason location request | 954 // Create an update timer for a case when for some reason location request |
964 // gets stuck. | 955 // gets stuck. |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1084 */ | 1075 */ |
1085 function onStateChange() { | 1076 function onStateChange() { |
1086 tasks.add(STATE_CHANGED_TASK_NAME, function() { | 1077 tasks.add(STATE_CHANGED_TASK_NAME, function() { |
1087 Promise.all([ | 1078 Promise.all([ |
1088 authenticationManager.isSignedIn(), | 1079 authenticationManager.isSignedIn(), |
1089 isGeolocationEnabled(), | 1080 isGeolocationEnabled(), |
1090 canEnableBackground(), | 1081 canEnableBackground(), |
1091 isNotificationsEnabled(), | 1082 isNotificationsEnabled(), |
1092 isGoogleNowEnabled()]) | 1083 isGoogleNowEnabled()]) |
1093 .then(function(results) { | 1084 .then(function(results) { |
1085 console.log(results); | |
skare_
2014/02/20 00:17:12
temporary?
robliao
2014/02/21 21:25:45
Yup! Done.
On 2014/02/20 00:17:12, Travis Skare wr
| |
1094 updateRunningState.apply(null, results); | 1086 updateRunningState.apply(null, results); |
1095 }); | 1087 }); |
1096 }); | 1088 }); |
1097 } | 1089 } |
1098 | 1090 |
1099 /** | 1091 /** |
1100 * Gets the geolocation enabled preference. | 1092 * Gets the geolocation enabled preference. |
1101 * @return {Promise} A promise to get the geolocation enabled preference. | 1093 * @return {Promise} A promise to get the geolocation enabled preference. |
1102 */ | 1094 */ |
1103 function isGeolocationEnabled() { | 1095 function isGeolocationEnabled() { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1136 }); | 1128 }); |
1137 }); | 1129 }); |
1138 } | 1130 } |
1139 | 1131 |
1140 /** | 1132 /** |
1141 * Gets the previous Google Now opt-in state. | 1133 * Gets the previous Google Now opt-in state. |
1142 * @return {Promise} A promise to determine the previous Google Now | 1134 * @return {Promise} A promise to determine the previous Google Now |
1143 * opt-in state. | 1135 * opt-in state. |
1144 */ | 1136 */ |
1145 function isGoogleNowEnabled() { | 1137 function isGoogleNowEnabled() { |
1146 return new Promise(function(resolve) { | 1138 return fillFromChromeLocalStorage({googleNowEnabled: false}) |
1147 instrumented.storage.local.get('googleNowEnabled', function(items) { | 1139 .then(function(items) { |
1148 resolve(items && !!items.googleNowEnabled); | 1140 return items.googleNowEnabled; |
1149 }); | 1141 }); |
1150 }); | |
1151 } | 1142 } |
1152 | 1143 |
1153 instrumented.runtime.onInstalled.addListener(function(details) { | 1144 instrumented.runtime.onInstalled.addListener(function(details) { |
1154 console.log('onInstalled ' + JSON.stringify(details)); | 1145 console.log('onInstalled ' + JSON.stringify(details)); |
1155 if (details.reason != 'chrome_update') { | 1146 if (details.reason != 'chrome_update') { |
1156 initialize(); | 1147 initialize(); |
1157 } | 1148 } |
1158 }); | 1149 }); |
1159 | 1150 |
1160 instrumented.runtime.onStartup.addListener(function() { | 1151 instrumented.runtime.onStartup.addListener(function() { |
1161 console.log('onStartup'); | 1152 console.log('onStartup'); |
1162 | 1153 |
1163 // Show notifications received by earlier polls. Doing this as early as | 1154 // Show notifications received by earlier polls. Doing this as early as |
1164 // possible to reduce latency of showing first notifications. This mimics how | 1155 // possible to reduce latency of showing first notifications. This mimics how |
1165 // persistent notifications will work. | 1156 // persistent notifications will work. |
1166 tasks.add(SHOW_ON_START_TASK_NAME, function() { | 1157 tasks.add(SHOW_ON_START_TASK_NAME, function() { |
1167 instrumented.storage.local.get('notificationGroups', function(items) { | 1158 fillFromChromeLocalStorage({ |
1159 /** @type {Object.<string, StoredNotificationGroup>} */ | |
1160 notificationGroups: {} | |
1161 }).then(function(items) { | |
1168 console.log('onStartup-get ' + JSON.stringify(items)); | 1162 console.log('onStartup-get ' + JSON.stringify(items)); |
1169 items = items || {}; | |
1170 /** @type {Object.<string, StoredNotificationGroup>} */ | |
1171 items.notificationGroups = items.notificationGroups || {}; | |
1172 | 1163 |
1173 combineAndShowNotificationCards(items.notificationGroups, function() { | 1164 combineAndShowNotificationCards(items.notificationGroups, function() { |
1174 chrome.storage.local.set(items); | 1165 chrome.storage.local.set(items); |
1175 }); | 1166 }); |
1176 }); | 1167 }); |
1177 }); | 1168 }); |
1178 | 1169 |
1179 initialize(); | 1170 initialize(); |
1180 }); | 1171 }); |
1181 | 1172 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1231 }); | 1222 }); |
1232 | 1223 |
1233 instrumented.pushMessaging.onMessage.addListener(function(message) { | 1224 instrumented.pushMessaging.onMessage.addListener(function(message) { |
1234 // message.payload will be '' when the extension first starts. | 1225 // message.payload will be '' when the extension first starts. |
1235 // Each time after signing in, we'll get latest payload for all channels. | 1226 // Each time after signing in, we'll get latest payload for all channels. |
1236 // So, we need to poll the server only when the payload is non-empty and has | 1227 // So, we need to poll the server only when the payload is non-empty and has |
1237 // changed. | 1228 // changed. |
1238 console.log('pushMessaging.onMessage ' + JSON.stringify(message)); | 1229 console.log('pushMessaging.onMessage ' + JSON.stringify(message)); |
1239 if (message.payload.indexOf('REQUEST_CARDS') == 0) { | 1230 if (message.payload.indexOf('REQUEST_CARDS') == 0) { |
1240 tasks.add(ON_PUSH_MESSAGE_START_TASK_NAME, function() { | 1231 tasks.add(ON_PUSH_MESSAGE_START_TASK_NAME, function() { |
1241 instrumented.storage.local.get( | 1232 // Accept promise rejection on failure since it's safer to do nothing, |
1242 ['lastPollNowPayloads', 'notificationGroups'], function(items) { | 1233 // preventing polling the server when the payload really didn't change. |
1243 // If storage.get fails, it's safer to do nothing, preventing polling | 1234 fillFromChromeLocalStorage({ |
1244 // the server when the payload really didn't change. | 1235 lastPollNowPayloads: {}, |
1245 if (!items) | 1236 /** @type {Object.<string, StoredNotificationGroup>} */ |
1246 return; | 1237 notificationGroups: {} |
1247 | 1238 }, ALLOW_PROMISE_REJECTION).then(function(items) { |
1248 // If this is the first time we get lastPollNowPayloads, initialize it. | |
1249 items.lastPollNowPayloads = items.lastPollNowPayloads || {}; | |
1250 | |
1251 if (items.lastPollNowPayloads[message.subchannelId] != | 1239 if (items.lastPollNowPayloads[message.subchannelId] != |
1252 message.payload) { | 1240 message.payload) { |
1253 items.lastPollNowPayloads[message.subchannelId] = message.payload; | 1241 items.lastPollNowPayloads[message.subchannelId] = message.payload; |
1254 | 1242 |
1255 /** @type {Object.<string, StoredNotificationGroup>} */ | |
1256 items.notificationGroups = items.notificationGroups || {}; | |
1257 items.notificationGroups['PUSH' + message.subchannelId] = { | 1243 items.notificationGroups['PUSH' + message.subchannelId] = { |
1258 cards: [], | 1244 cards: [], |
1259 nextPollTime: Date.now() | 1245 nextPollTime: Date.now() |
1260 }; | 1246 }; |
1261 | 1247 |
1262 chrome.storage.local.set({ | 1248 chrome.storage.local.set({ |
1263 lastPollNowPayloads: items.lastPollNowPayloads, | 1249 lastPollNowPayloads: items.lastPollNowPayloads, |
1264 notificationGroups: items.notificationGroups | 1250 notificationGroups: items.notificationGroups |
1265 }); | 1251 }); |
1266 | 1252 |
1267 updateNotificationsCards(); | 1253 updateNotificationsCards(); |
1268 } | 1254 } |
1269 }); | 1255 }); |
1270 }); | 1256 }); |
1271 } | 1257 } |
1272 }); | 1258 }); |
OLD | NEW |