| 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 632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 643 console.log('requestCards @' + new Date()); | 643 console.log('requestCards @' + new Date()); |
| 644 // LOCATION_REQUEST is a legacy histogram value when we requested location. | 644 // LOCATION_REQUEST is a legacy histogram value when we requested location. |
| 645 // This corresponds to the extension attempting to request for cards. | 645 // This corresponds to the extension attempting to request for cards. |
| 646 // We're keeping the name the same to keep our histograms in order. | 646 // We're keeping the name the same to keep our histograms in order. |
| 647 recordEvent(GoogleNowEvent.LOCATION_REQUEST); | 647 recordEvent(GoogleNowEvent.LOCATION_REQUEST); |
| 648 tasks.add(UPDATE_CARDS_TASK_NAME, function() { | 648 tasks.add(UPDATE_CARDS_TASK_NAME, function() { |
| 649 console.log('requestCards-task-begin'); | 649 console.log('requestCards-task-begin'); |
| 650 updateCardsAttempts.isRunning(function(running) { | 650 updateCardsAttempts.isRunning(function(running) { |
| 651 if (running) { | 651 if (running) { |
| 652 updateCardsAttempts.planForNext(function() { | 652 updateCardsAttempts.planForNext(function() { |
| 653 processPendingDismissals(function(success) { | 653 // The cards are requested only if there are no unsent dismissals. |
| 654 if (success) { | 654 processPendingDismissals().then(requestNotificationCards); |
| 655 // The cards are requested only if there are no unsent dismissals. | |
| 656 requestNotificationCards(); | |
| 657 } | |
| 658 }); | |
| 659 }); | 655 }); |
| 660 } | 656 } |
| 661 }); | 657 }); |
| 662 }); | 658 }); |
| 663 } | 659 } |
| 664 | 660 |
| 665 /** | 661 /** |
| 666 * Sends a server request to dismiss a card. | 662 * Sends a server request to dismiss a card. |
| 667 * @param {ChromeNotificationId} chromeNotificationId chrome.notifications ID of | 663 * @param {ChromeNotificationId} chromeNotificationId chrome.notifications ID of |
| 668 * the card. | 664 * the card. |
| 669 * @param {number} dismissalTimeMs Time of the user's dismissal of the card in | 665 * @param {number} dismissalTimeMs Time of the user's dismissal of the card in |
| 670 * milliseconds since epoch. | 666 * milliseconds since epoch. |
| 671 * @param {DismissalData} dismissalData Data to build a dismissal request. | 667 * @param {DismissalData} dismissalData Data to build a dismissal request. |
| 672 * @param {function(boolean)} callbackBoolean Completion callback with 'done' | 668 * @return {Promise} A promise to request the card dismissal, rejects on error. |
| 673 * parameter. | |
| 674 */ | 669 */ |
| 675 function requestCardDismissal( | 670 function requestCardDismissal( |
| 676 chromeNotificationId, dismissalTimeMs, dismissalData, callbackBoolean) { | 671 chromeNotificationId, dismissalTimeMs, dismissalData) { |
| 677 console.log('requestDismissingCard ' + chromeNotificationId + | 672 console.log('requestDismissingCard ' + chromeNotificationId + |
| 678 ' from ' + NOTIFICATION_CARDS_URL + | 673 ' from ' + NOTIFICATION_CARDS_URL + |
| 679 ', dismissalData=' + JSON.stringify(dismissalData)); | 674 ', dismissalData=' + JSON.stringify(dismissalData)); |
| 680 | 675 |
| 681 var dismissalAge = Date.now() - dismissalTimeMs; | 676 var dismissalAge = Date.now() - dismissalTimeMs; |
| 682 | 677 |
| 683 if (dismissalAge > MAXIMUM_DISMISSAL_AGE_MS) { | 678 if (dismissalAge > MAXIMUM_DISMISSAL_AGE_MS) { |
| 684 callbackBoolean(true); | 679 callbackBoolean(true); |
| 685 return; | 680 return; |
| 686 } | 681 } |
| 687 | 682 |
| 688 recordEvent(GoogleNowEvent.DISMISS_REQUEST_TOTAL); | 683 recordEvent(GoogleNowEvent.DISMISS_REQUEST_TOTAL); |
| 689 | 684 |
| 690 var requestParameters = 'notifications/' + dismissalData.notificationId + | 685 var requestParameters = 'notifications/' + dismissalData.notificationId + |
| 691 '?age=' + dismissalAge + | 686 '?age=' + dismissalAge + |
| 692 '&chromeNotificationId=' + chromeNotificationId; | 687 '&chromeNotificationId=' + chromeNotificationId; |
| 693 | 688 |
| 694 for (var paramField in dismissalData.parameters) | 689 for (var paramField in dismissalData.parameters) |
| 695 requestParameters += ('&' + paramField + | 690 requestParameters += ('&' + paramField + |
| 696 '=' + dismissalData.parameters[paramField]); | 691 '=' + dismissalData.parameters[paramField]); |
| 697 | 692 |
| 698 console.log('requestCardDismissal: requestParameters=' + requestParameters); | 693 console.log('requestCardDismissal: requestParameters=' + requestParameters); |
| 699 | 694 |
| 700 requestFromServer('DELETE', requestParameters).then(function(request) { | 695 return requestFromServer('DELETE', requestParameters).then(function(request) { |
| 701 console.log('requestDismissingCard-onloadend ' + request.status); | 696 console.log('requestDismissingCard-onloadend ' + request.status); |
| 702 if (request.status == HTTP_NOCONTENT) | 697 if (request.status == HTTP_NOCONTENT) |
| 703 recordEvent(GoogleNowEvent.DISMISS_REQUEST_SUCCESS); | 698 recordEvent(GoogleNowEvent.DISMISS_REQUEST_SUCCESS); |
| 704 | 699 |
| 705 // A dismissal doesn't require further retries if it was successful or | 700 // A dismissal doesn't require further retries if it was successful or |
| 706 // doesn't have a chance for successful completion. | 701 // doesn't have a chance for successful completion. |
| 707 var done = request.status == HTTP_NOCONTENT || | 702 var done = request.status == HTTP_NOCONTENT || |
| 708 request.status == HTTP_BAD_REQUEST || | 703 request.status == HTTP_BAD_REQUEST || |
| 709 request.status == HTTP_METHOD_NOT_ALLOWED; | 704 request.status == HTTP_METHOD_NOT_ALLOWED; |
| 710 callbackBoolean(done); | 705 return done ? Promise.resolve() : Promise.reject(); |
| 711 }).catch(function() { | |
| 712 callbackBoolean(false); | |
| 713 }); | 706 }); |
| 714 } | 707 } |
| 715 | 708 |
| 716 /** | 709 /** |
| 717 * Tries to send dismiss requests for all pending dismissals. | 710 * Tries to send dismiss requests for all pending dismissals. |
| 718 * @param {function(boolean)} callbackBoolean Completion callback with 'success' | 711 * @return {Promise} A promise to process the pending dismissals. |
| 719 * parameter. Success means that no pending dismissals are left. | 712 * The promise is rejected if a problem was encountered. |
| 720 */ | 713 */ |
| 721 function processPendingDismissals(callbackBoolean) { | 714 function processPendingDismissals() { |
| 722 fillFromChromeLocalStorage({ | 715 return fillFromChromeLocalStorage({ |
| 723 /** @type {Array.<PendingDismissal>} */ | 716 /** @type {Array.<PendingDismissal>} */ |
| 724 pendingDismissals: [], | 717 pendingDismissals: [], |
| 725 /** @type {Object.<NotificationId, number>} */ | 718 /** @type {Object.<NotificationId, number>} */ |
| 726 recentDismissals: {} | 719 recentDismissals: {} |
| 727 }).then(function(items) { | 720 }).then(function(items) { |
| 728 console.log( | 721 console.log( |
| 729 'processPendingDismissals-storage-get ' + JSON.stringify(items)); | 722 'processPendingDismissals-storage-get ' + JSON.stringify(items)); |
| 730 | 723 |
| 731 var dismissalsChanged = false; | 724 var dismissalsChanged = false; |
| 732 | 725 |
| 733 function onFinish(success) { | 726 function onFinish(success) { |
| 734 if (dismissalsChanged) { | 727 if (dismissalsChanged) { |
| 735 chrome.storage.local.set({ | 728 chrome.storage.local.set({ |
| 736 pendingDismissals: items.pendingDismissals, | 729 pendingDismissals: items.pendingDismissals, |
| 737 recentDismissals: items.recentDismissals | 730 recentDismissals: items.recentDismissals |
| 738 }); | 731 }); |
| 739 } | 732 } |
| 740 callbackBoolean(success); | 733 return success ? Promise.resolve() : Promise.reject(); |
| 741 } | 734 } |
| 742 | 735 |
| 743 function doProcessDismissals() { | 736 function doProcessDismissals() { |
| 744 if (items.pendingDismissals.length == 0) { | 737 if (items.pendingDismissals.length == 0) { |
| 745 dismissalAttempts.stop(); | 738 dismissalAttempts.stop(); |
| 746 onFinish(true); | 739 return onFinish(true); |
| 747 return; | |
| 748 } | 740 } |
| 749 | 741 |
| 750 // Send dismissal for the first card, and if successful, repeat | 742 // Send dismissal for the first card, and if successful, repeat |
| 751 // recursively with the rest. | 743 // recursively with the rest. |
| 752 /** @type {PendingDismissal} */ | 744 /** @type {PendingDismissal} */ |
| 753 var dismissal = items.pendingDismissals[0]; | 745 var dismissal = items.pendingDismissals[0]; |
| 754 requestCardDismissal( | 746 return requestCardDismissal( |
| 755 dismissal.chromeNotificationId, | 747 dismissal.chromeNotificationId, |
| 756 dismissal.time, | 748 dismissal.time, |
| 757 dismissal.dismissalData, | 749 dismissal.dismissalData).then(function() { |
| 758 function(done) { | 750 dismissalsChanged = true; |
| 759 if (done) { | 751 items.pendingDismissals.splice(0, 1); |
| 760 dismissalsChanged = true; | 752 items.recentDismissals[dismissal.dismissalData.notificationId] = |
| 761 items.pendingDismissals.splice(0, 1); | 753 Date.now(); |
| 762 items.recentDismissals[ | 754 return doProcessDismissals(); |
| 763 dismissal.dismissalData.notificationId] = | 755 }).catch(function() { |
| 764 Date.now(); | 756 return onFinish(false); |
| 765 doProcessDismissals(); | |
| 766 } else { | |
| 767 onFinish(false); | |
| 768 } | |
| 769 }); | 757 }); |
| 770 } | 758 } |
| 771 | 759 |
| 772 doProcessDismissals(); | 760 return doProcessDismissals(); |
| 773 }); | 761 }); |
| 774 } | 762 } |
| 775 | 763 |
| 776 /** | 764 /** |
| 777 * Submits a task to send pending dismissals. | 765 * Submits a task to send pending dismissals. |
| 778 */ | 766 */ |
| 779 function retryPendingDismissals() { | 767 function retryPendingDismissals() { |
| 780 tasks.add(RETRY_DISMISS_TASK_NAME, function() { | 768 tasks.add(RETRY_DISMISS_TASK_NAME, function() { |
| 781 dismissalAttempts.planForNext(function() { | 769 dismissalAttempts.planForNext(function() { |
| 782 processPendingDismissals(function(success) {}); | 770 processPendingDismissals(); |
| 783 }); | 771 }); |
| 784 }); | 772 }); |
| 785 } | 773 } |
| 786 | 774 |
| 787 /** | 775 /** |
| 788 * Opens a URL in a new tab. | 776 * Opens a URL in a new tab. |
| 789 * @param {string} url URL to open. | 777 * @param {string} url URL to open. |
| 790 */ | 778 */ |
| 791 function openUrl(url) { | 779 function openUrl(url) { |
| 792 instrumented.tabs.create({url: url}, function(tab) { | 780 instrumented.tabs.create({url: url}, function(tab) { |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 869 dismissalData: dismissalResult.dismissals[i] | 857 dismissalData: dismissalResult.dismissals[i] |
| 870 }; | 858 }; |
| 871 items.pendingDismissals.push(dismissal); | 859 items.pendingDismissals.push(dismissal); |
| 872 } | 860 } |
| 873 | 861 |
| 874 items.notificationsData[chromeNotificationId] = | 862 items.notificationsData[chromeNotificationId] = |
| 875 dismissalResult.notificationData; | 863 dismissalResult.notificationData; |
| 876 | 864 |
| 877 chrome.storage.local.set(items); | 865 chrome.storage.local.set(items); |
| 878 | 866 |
| 879 processPendingDismissals(function(success) {}); | 867 processPendingDismissals(); |
| 880 }); | 868 }); |
| 881 }); | 869 }); |
| 882 } | 870 } |
| 883 | 871 |
| 884 /** | 872 /** |
| 885 * Initializes the polling system to start fetching cards. | 873 * Initializes the polling system to start fetching cards. |
| 886 */ | 874 */ |
| 887 function startPollingCards() { | 875 function startPollingCards() { |
| 888 console.log('startPollingCards'); | 876 console.log('startPollingCards'); |
| 889 // Create an update timer for a case when for some reason requesting | 877 // Create an update timer for a case when for some reason requesting |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1144 lastPollNowPayloads: items.lastPollNowPayloads, | 1132 lastPollNowPayloads: items.lastPollNowPayloads, |
| 1145 notificationGroups: items.notificationGroups | 1133 notificationGroups: items.notificationGroups |
| 1146 }); | 1134 }); |
| 1147 | 1135 |
| 1148 requestCards(); | 1136 requestCards(); |
| 1149 } | 1137 } |
| 1150 }); | 1138 }); |
| 1151 }); | 1139 }); |
| 1152 } | 1140 } |
| 1153 }); | 1141 }); |
| OLD | NEW |