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