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 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 * requested: (boolean|undefined) | 118 * requested: (boolean|undefined) |
119 * }} | 119 * }} |
120 */ | 120 */ |
121 var ReceivedGroup; | 121 var ReceivedGroup; |
122 | 122 |
123 /** | 123 /** |
124 * Server response with notifications and groups. | 124 * Server response with notifications and groups. |
125 * | 125 * |
126 * @typedef {{ | 126 * @typedef {{ |
127 * googleNowDisabled: (boolean|undefined), | 127 * googleNowDisabled: (boolean|undefined), |
128 * groups: Object.<string, ReceivedGroup>, | 128 * groups: Object<string, ReceivedGroup>, |
129 * notifications: Array.<ReceivedNotification> | 129 * notifications: Array<ReceivedNotification> |
130 * }} | 130 * }} |
131 */ | 131 */ |
132 var ServerResponse; | 132 var ServerResponse; |
133 | 133 |
134 /** | 134 /** |
135 * Notification group as the client stores it. |cardsTimestamp| and |rank| are | 135 * Notification group as the client stores it. |cardsTimestamp| and |rank| are |
136 * defined if |cards| is non-empty. |nextPollTime| is undefined if the server | 136 * defined if |cards| is non-empty. |nextPollTime| is undefined if the server |
137 * (1) never sent 'nextPollSeconds' for the group or | 137 * (1) never sent 'nextPollSeconds' for the group or |
138 * (2) didn't send 'nextPollSeconds' with the last group update containing a | 138 * (2) didn't send 'nextPollSeconds' with the last group update containing a |
139 * cards update and all the times after that. | 139 * cards update and all the times after that. |
140 * | 140 * |
141 * @typedef {{ | 141 * @typedef {{ |
142 * cards: Array.<ReceivedNotification>, | 142 * cards: Array<ReceivedNotification>, |
143 * cardsTimestamp: (number|undefined), | 143 * cardsTimestamp: (number|undefined), |
144 * nextPollTime: (number|undefined), | 144 * nextPollTime: (number|undefined), |
145 * rank: (number|undefined) | 145 * rank: (number|undefined) |
146 * }} | 146 * }} |
147 */ | 147 */ |
148 var StoredNotificationGroup; | 148 var StoredNotificationGroup; |
149 | 149 |
150 /** | 150 /** |
151 * Pending (not yet successfully sent) dismissal for a received notification. | 151 * Pending (not yet successfully sent) dismissal for a received notification. |
152 * |time| is the moment when the user requested dismissal. | 152 * |time| is the moment when the user requested dismissal. |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
335 }, false); | 335 }, false); |
336 request.send(); | 336 request.send(); |
337 }); | 337 }); |
338 requestPromise.catch(checkAuthenticationStatus(token)); | 338 requestPromise.catch(checkAuthenticationStatus(token)); |
339 return requestPromise; | 339 return requestPromise; |
340 }); | 340 }); |
341 } | 341 } |
342 | 342 |
343 /** | 343 /** |
344 * Shows the notification groups as notification cards. | 344 * Shows the notification groups as notification cards. |
345 * @param {Object.<string, StoredNotificationGroup>} notificationGroups Map from | 345 * @param {Object<string, StoredNotificationGroup>} notificationGroups Map from |
346 * group name to group information. | 346 * group name to group information. |
347 * @param {function(ReceivedNotification)=} opt_onCardShown Optional parameter | 347 * @param {function(ReceivedNotification)=} opt_onCardShown Optional parameter |
348 * called when each card is shown. | 348 * called when each card is shown. |
349 * @return {Promise} A promise to show the notification groups as cards. | 349 * @return {Promise} A promise to show the notification groups as cards. |
350 */ | 350 */ |
351 function showNotificationGroups(notificationGroups, opt_onCardShown) { | 351 function showNotificationGroups(notificationGroups, opt_onCardShown) { |
352 /** @type {Object.<ChromeNotificationId, CombinedCard>} */ | 352 /** @type {Object<ChromeNotificationId, CombinedCard>} */ |
353 var cards = combineCardsFromGroups(notificationGroups); | 353 var cards = combineCardsFromGroups(notificationGroups); |
354 console.log('showNotificationGroups ' + JSON.stringify(cards)); | 354 console.log('showNotificationGroups ' + JSON.stringify(cards)); |
355 | 355 |
356 return new Promise(function(resolve) { | 356 return new Promise(function(resolve) { |
357 instrumented.notifications.getAll(function(notifications) { | 357 instrumented.notifications.getAll(function(notifications) { |
358 console.log('showNotificationGroups-getAll ' + | 358 console.log('showNotificationGroups-getAll ' + |
359 JSON.stringify(notifications)); | 359 JSON.stringify(notifications)); |
360 notifications = notifications || {}; | 360 notifications = notifications || {}; |
361 | 361 |
362 // Mark notifications that didn't receive an update as having received | 362 // Mark notifications that didn't receive an update as having received |
363 // an empty update. | 363 // an empty update. |
364 for (var chromeNotificationId in notifications) { | 364 for (var chromeNotificationId in notifications) { |
365 cards[chromeNotificationId] = cards[chromeNotificationId] || []; | 365 cards[chromeNotificationId] = cards[chromeNotificationId] || []; |
366 } | 366 } |
367 | 367 |
368 /** @type {Object.<ChromeNotificationId, NotificationDataEntry>} */ | 368 /** @type {Object<ChromeNotificationId, NotificationDataEntry>} */ |
369 var notificationsData = {}; | 369 var notificationsData = {}; |
370 | 370 |
371 // Create/update/delete notifications. | 371 // Create/update/delete notifications. |
372 for (var chromeNotificationId in cards) { | 372 for (var chromeNotificationId in cards) { |
373 notificationsData[chromeNotificationId] = cardSet.update( | 373 notificationsData[chromeNotificationId] = cardSet.update( |
374 chromeNotificationId, | 374 chromeNotificationId, |
375 cards[chromeNotificationId], | 375 cards[chromeNotificationId], |
376 notificationGroups, | 376 notificationGroups, |
377 opt_onCardShown); | 377 opt_onCardShown); |
378 } | 378 } |
(...skipping 16 matching lines...) Expand all Loading... |
395 notifications = notifications || {}; | 395 notifications = notifications || {}; |
396 for (var chromeNotificationId in notifications) { | 396 for (var chromeNotificationId in notifications) { |
397 instrumented.notifications.clear(chromeNotificationId, function() {}); | 397 instrumented.notifications.clear(chromeNotificationId, function() {}); |
398 } | 398 } |
399 chrome.storage.local.remove(['notificationsData', 'notificationGroups']); | 399 chrome.storage.local.remove(['notificationsData', 'notificationGroups']); |
400 }); | 400 }); |
401 } | 401 } |
402 | 402 |
403 /** | 403 /** |
404 * Adds a card group into a set of combined cards. | 404 * Adds a card group into a set of combined cards. |
405 * @param {Object.<ChromeNotificationId, CombinedCard>} combinedCards Map from | 405 * @param {Object<ChromeNotificationId, CombinedCard>} combinedCards Map from |
406 * chromeNotificationId to a combined card. | 406 * chromeNotificationId to a combined card. |
407 * This is an input/output parameter. | 407 * This is an input/output parameter. |
408 * @param {StoredNotificationGroup} storedGroup Group to combine into the | 408 * @param {StoredNotificationGroup} storedGroup Group to combine into the |
409 * combined card set. | 409 * combined card set. |
410 */ | 410 */ |
411 function combineGroup(combinedCards, storedGroup) { | 411 function combineGroup(combinedCards, storedGroup) { |
412 for (var i = 0; i < storedGroup.cards.length; i++) { | 412 for (var i = 0; i < storedGroup.cards.length; i++) { |
413 /** @type {ReceivedNotification} */ | 413 /** @type {ReceivedNotification} */ |
414 var receivedNotification = storedGroup.cards[i]; | 414 var receivedNotification = storedGroup.cards[i]; |
415 | 415 |
416 /** @type {UncombinedNotification} */ | 416 /** @type {UncombinedNotification} */ |
417 var uncombinedNotification = { | 417 var uncombinedNotification = { |
418 receivedNotification: receivedNotification, | 418 receivedNotification: receivedNotification, |
419 showTime: receivedNotification.trigger.showTimeSec && | 419 showTime: receivedNotification.trigger.showTimeSec && |
420 (storedGroup.cardsTimestamp + | 420 (storedGroup.cardsTimestamp + |
421 receivedNotification.trigger.showTimeSec * MS_IN_SECOND), | 421 receivedNotification.trigger.showTimeSec * MS_IN_SECOND), |
422 hideTime: storedGroup.cardsTimestamp + | 422 hideTime: storedGroup.cardsTimestamp + |
423 receivedNotification.trigger.hideTimeSec * MS_IN_SECOND | 423 receivedNotification.trigger.hideTimeSec * MS_IN_SECOND |
424 }; | 424 }; |
425 | 425 |
426 var combinedCard = | 426 var combinedCard = |
427 combinedCards[receivedNotification.chromeNotificationId] || []; | 427 combinedCards[receivedNotification.chromeNotificationId] || []; |
428 combinedCard.push(uncombinedNotification); | 428 combinedCard.push(uncombinedNotification); |
429 combinedCards[receivedNotification.chromeNotificationId] = combinedCard; | 429 combinedCards[receivedNotification.chromeNotificationId] = combinedCard; |
430 } | 430 } |
431 } | 431 } |
432 | 432 |
433 /** | 433 /** |
434 * Calculates the soonest poll time from a map of groups as an absolute time. | 434 * Calculates the soonest poll time from a map of groups as an absolute time. |
435 * @param {Object.<string, StoredNotificationGroup>} groups Map from group name | 435 * @param {Object<string, StoredNotificationGroup>} groups Map from group name |
436 * to group information. | 436 * to group information. |
437 * @return {number} The next poll time based off of the groups. | 437 * @return {number} The next poll time based off of the groups. |
438 */ | 438 */ |
439 function calculateNextPollTimeMilliseconds(groups) { | 439 function calculateNextPollTimeMilliseconds(groups) { |
440 var nextPollTime = null; | 440 var nextPollTime = null; |
441 | 441 |
442 for (var groupName in groups) { | 442 for (var groupName in groups) { |
443 var group = groups[groupName]; | 443 var group = groups[groupName]; |
444 if (group.nextPollTime !== undefined) { | 444 if (group.nextPollTime !== undefined) { |
445 nextPollTime = nextPollTime == null ? | 445 nextPollTime = nextPollTime == null ? |
446 group.nextPollTime : Math.min(group.nextPollTime, nextPollTime); | 446 group.nextPollTime : Math.min(group.nextPollTime, nextPollTime); |
447 } | 447 } |
448 } | 448 } |
449 | 449 |
450 // At least one of the groups must have nextPollTime. | 450 // At least one of the groups must have nextPollTime. |
451 verify(nextPollTime != null, 'calculateNextPollTime: nextPollTime is null'); | 451 verify(nextPollTime != null, 'calculateNextPollTime: nextPollTime is null'); |
452 return nextPollTime; | 452 return nextPollTime; |
453 } | 453 } |
454 | 454 |
455 /** | 455 /** |
456 * Schedules next cards poll. | 456 * Schedules next cards poll. |
457 * @param {Object.<string, StoredNotificationGroup>} groups Map from group name | 457 * @param {Object<string, StoredNotificationGroup>} groups Map from group name |
458 * to group information. | 458 * to group information. |
459 */ | 459 */ |
460 function scheduleNextCardsPoll(groups) { | 460 function scheduleNextCardsPoll(groups) { |
461 var nextPollTimeMs = calculateNextPollTimeMilliseconds(groups); | 461 var nextPollTimeMs = calculateNextPollTimeMilliseconds(groups); |
462 | 462 |
463 var nextPollDelaySeconds = Math.max( | 463 var nextPollDelaySeconds = Math.max( |
464 (nextPollTimeMs - Date.now()) / MS_IN_SECOND, | 464 (nextPollTimeMs - Date.now()) / MS_IN_SECOND, |
465 MINIMUM_POLLING_PERIOD_SECONDS); | 465 MINIMUM_POLLING_PERIOD_SECONDS); |
466 updateCardsAttempts.start(nextPollDelaySeconds); | 466 updateCardsAttempts.start(nextPollDelaySeconds); |
467 } | 467 } |
468 | 468 |
469 /** | 469 /** |
470 * Schedules the next opt-in check poll. | 470 * Schedules the next opt-in check poll. |
471 */ | 471 */ |
472 function scheduleOptInCheckPoll() { | 472 function scheduleOptInCheckPoll() { |
473 instrumented.metricsPrivate.getVariationParams( | 473 instrumented.metricsPrivate.getVariationParams( |
474 'GoogleNow', function(params) { | 474 'GoogleNow', function(params) { |
475 var optinPollPeriodSeconds = | 475 var optinPollPeriodSeconds = |
476 parseInt(params && params.optinPollPeriodSeconds, 10) || | 476 parseInt(params && params.optinPollPeriodSeconds, 10) || |
477 DEFAULT_OPTIN_CHECK_PERIOD_SECONDS; | 477 DEFAULT_OPTIN_CHECK_PERIOD_SECONDS; |
478 optInPollAttempts.start(optinPollPeriodSeconds); | 478 optInPollAttempts.start(optinPollPeriodSeconds); |
479 }); | 479 }); |
480 } | 480 } |
481 | 481 |
482 /** | 482 /** |
483 * Combines notification groups into a set of Chrome notifications. | 483 * Combines notification groups into a set of Chrome notifications. |
484 * @param {Object.<string, StoredNotificationGroup>} notificationGroups Map from | 484 * @param {Object<string, StoredNotificationGroup>} notificationGroups Map from |
485 * group name to group information. | 485 * group name to group information. |
486 * @return {Object.<ChromeNotificationId, CombinedCard>} Cards to show. | 486 * @return {Object<ChromeNotificationId, CombinedCard>} Cards to show. |
487 */ | 487 */ |
488 function combineCardsFromGroups(notificationGroups) { | 488 function combineCardsFromGroups(notificationGroups) { |
489 console.log('combineCardsFromGroups ' + JSON.stringify(notificationGroups)); | 489 console.log('combineCardsFromGroups ' + JSON.stringify(notificationGroups)); |
490 /** @type {Object.<ChromeNotificationId, CombinedCard>} */ | 490 /** @type {Object<ChromeNotificationId, CombinedCard>} */ |
491 var combinedCards = {}; | 491 var combinedCards = {}; |
492 | 492 |
493 for (var groupName in notificationGroups) | 493 for (var groupName in notificationGroups) |
494 combineGroup(combinedCards, notificationGroups[groupName]); | 494 combineGroup(combinedCards, notificationGroups[groupName]); |
495 | 495 |
496 return combinedCards; | 496 return combinedCards; |
497 } | 497 } |
498 | 498 |
499 /** | 499 /** |
500 * Processes a server response for consumption by showNotificationGroups. | 500 * Processes a server response for consumption by showNotificationGroups. |
501 * @param {ServerResponse} response Server response. | 501 * @param {ServerResponse} response Server response. |
502 * @return {Promise} A promise to process the server response and provide | 502 * @return {Promise} A promise to process the server response and provide |
503 * updated groups. Rejects if the server response shouldn't be processed. | 503 * updated groups. Rejects if the server response shouldn't be processed. |
504 */ | 504 */ |
505 function processServerResponse(response) { | 505 function processServerResponse(response) { |
506 console.log('processServerResponse ' + JSON.stringify(response)); | 506 console.log('processServerResponse ' + JSON.stringify(response)); |
507 | 507 |
508 if (response.googleNowDisabled) { | 508 if (response.googleNowDisabled) { |
509 chrome.storage.local.set({googleNowEnabled: false}); | 509 chrome.storage.local.set({googleNowEnabled: false}); |
510 // Stop processing now. The state change will clear the cards. | 510 // Stop processing now. The state change will clear the cards. |
511 return Promise.reject(); | 511 return Promise.reject(); |
512 } | 512 } |
513 | 513 |
514 var receivedGroups = response.groups; | 514 var receivedGroups = response.groups; |
515 | 515 |
516 return fillFromChromeLocalStorage({ | 516 return fillFromChromeLocalStorage({ |
517 /** @type {Object.<string, StoredNotificationGroup>} */ | 517 /** @type {Object<string, StoredNotificationGroup>} */ |
518 notificationGroups: {}, | 518 notificationGroups: {}, |
519 /** @type {Object.<ServerNotificationId, number>} */ | 519 /** @type {Object<ServerNotificationId, number>} */ |
520 recentDismissals: {} | 520 recentDismissals: {} |
521 }).then(function(items) { | 521 }).then(function(items) { |
522 console.log('processServerResponse-get ' + JSON.stringify(items)); | 522 console.log('processServerResponse-get ' + JSON.stringify(items)); |
523 | 523 |
524 // Build a set of non-expired recent dismissals. It will be used for | 524 // Build a set of non-expired recent dismissals. It will be used for |
525 // client-side filtering of cards. | 525 // client-side filtering of cards. |
526 /** @type {Object.<ServerNotificationId, number>} */ | 526 /** @type {Object<ServerNotificationId, number>} */ |
527 var updatedRecentDismissals = {}; | 527 var updatedRecentDismissals = {}; |
528 var now = Date.now(); | 528 var now = Date.now(); |
529 for (var serverNotificationId in items.recentDismissals) { | 529 for (var serverNotificationId in items.recentDismissals) { |
530 var dismissalAge = now - items.recentDismissals[serverNotificationId]; | 530 var dismissalAge = now - items.recentDismissals[serverNotificationId]; |
531 if (dismissalAge < DISMISS_RETENTION_TIME_MS) { | 531 if (dismissalAge < DISMISS_RETENTION_TIME_MS) { |
532 updatedRecentDismissals[serverNotificationId] = | 532 updatedRecentDismissals[serverNotificationId] = |
533 items.recentDismissals[serverNotificationId]; | 533 items.recentDismissals[serverNotificationId]; |
534 } | 534 } |
535 } | 535 } |
536 | 536 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
605 * @return {boolean} true if an explanatory card should be shown. | 605 * @return {boolean} true if an explanatory card should be shown. |
606 */ | 606 */ |
607 function shouldShowExplanatoryCard() { | 607 function shouldShowExplanatoryCard() { |
608 var isBelowThreshold = | 608 var isBelowThreshold = |
609 localStorage['explanatoryCardsShown'] < EXPLANATORY_CARDS_LINK_THRESHOLD; | 609 localStorage['explanatoryCardsShown'] < EXPLANATORY_CARDS_LINK_THRESHOLD; |
610 return isBelowThreshold; | 610 return isBelowThreshold; |
611 } | 611 } |
612 | 612 |
613 /** | 613 /** |
614 * Requests notification cards from the server for specified groups. | 614 * Requests notification cards from the server for specified groups. |
615 * @param {Array.<string>} groupNames Names of groups that need to be refreshed. | 615 * @param {Array<string>} groupNames Names of groups that need to be refreshed. |
616 * @return {Promise} A promise to request the specified notification groups. | 616 * @return {Promise} A promise to request the specified notification groups. |
617 */ | 617 */ |
618 function requestNotificationGroupsFromServer(groupNames) { | 618 function requestNotificationGroupsFromServer(groupNames) { |
619 console.log( | 619 console.log( |
620 'requestNotificationGroupsFromServer from ' + NOTIFICATION_CARDS_URL + | 620 'requestNotificationGroupsFromServer from ' + NOTIFICATION_CARDS_URL + |
621 ', groupNames=' + JSON.stringify(groupNames)); | 621 ', groupNames=' + JSON.stringify(groupNames)); |
622 | 622 |
623 recordEvent(GoogleNowEvent.REQUEST_FOR_CARDS_TOTAL); | 623 recordEvent(GoogleNowEvent.REQUEST_FOR_CARDS_TOTAL); |
624 | 624 |
625 var requestParameters = '?timeZoneOffsetMs=' + | 625 var requestParameters = '?timeZoneOffsetMs=' + |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
687 return optedIn; | 687 return optedIn; |
688 }); | 688 }); |
689 } | 689 } |
690 | 690 |
691 /** | 691 /** |
692 * Determines the groups that need to be requested right now. | 692 * Determines the groups that need to be requested right now. |
693 * @return {Promise} A promise to determine the groups to request. | 693 * @return {Promise} A promise to determine the groups to request. |
694 */ | 694 */ |
695 function getGroupsToRequest() { | 695 function getGroupsToRequest() { |
696 return fillFromChromeLocalStorage({ | 696 return fillFromChromeLocalStorage({ |
697 /** @type {Object.<string, StoredNotificationGroup>} */ | 697 /** @type {Object<string, StoredNotificationGroup>} */ |
698 notificationGroups: {} | 698 notificationGroups: {} |
699 }).then(function(items) { | 699 }).then(function(items) { |
700 console.log('getGroupsToRequest-storage-get ' + JSON.stringify(items)); | 700 console.log('getGroupsToRequest-storage-get ' + JSON.stringify(items)); |
701 var groupsToRequest = []; | 701 var groupsToRequest = []; |
702 var now = Date.now(); | 702 var now = Date.now(); |
703 | 703 |
704 for (var groupName in items.notificationGroups) { | 704 for (var groupName in items.notificationGroups) { |
705 var group = items.notificationGroups[groupName]; | 705 var group = items.notificationGroups[groupName]; |
706 if (group.nextPollTime !== undefined && group.nextPollTime <= now) | 706 if (group.nextPollTime !== undefined && group.nextPollTime <= now) |
707 groupsToRequest.push(groupName); | 707 groupsToRequest.push(groupName); |
(...skipping 24 matching lines...) Expand all Loading... |
732 recordEvent(GoogleNowEvent.CARDS_PARSE_SUCCESS); | 732 recordEvent(GoogleNowEvent.CARDS_PARSE_SUCCESS); |
733 } | 733 } |
734 ); | 734 ); |
735 }); | 735 }); |
736 } | 736 } |
737 | 737 |
738 /** | 738 /** |
739 * Determines if an immediate retry should occur based off of the given groups. | 739 * Determines if an immediate retry should occur based off of the given groups. |
740 * The NOR group is expected most often and less latency sensitive, so we will | 740 * The NOR group is expected most often and less latency sensitive, so we will |
741 * simply wait MAXIMUM_POLLING_PERIOD_SECONDS before trying again. | 741 * simply wait MAXIMUM_POLLING_PERIOD_SECONDS before trying again. |
742 * @param {Array.<string>} groupNames Names of groups that need to be refreshed. | 742 * @param {Array<string>} groupNames Names of groups that need to be refreshed. |
743 * @return {boolean} Whether a retry should occur. | 743 * @return {boolean} Whether a retry should occur. |
744 */ | 744 */ |
745 function shouldScheduleRetryFromGroupList(groupNames) { | 745 function shouldScheduleRetryFromGroupList(groupNames) { |
746 return (groupNames.length != 1) || (groupNames[0] !== 'NOR'); | 746 return (groupNames.length != 1) || (groupNames[0] !== 'NOR'); |
747 } | 747 } |
748 | 748 |
749 /** | 749 /** |
750 * Requests and shows notification cards. | 750 * Requests and shows notification cards. |
751 */ | 751 */ |
752 function requestCards() { | 752 function requestCards() { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
826 }); | 826 }); |
827 } | 827 } |
828 | 828 |
829 /** | 829 /** |
830 * Tries to send dismiss requests for all pending dismissals. | 830 * Tries to send dismiss requests for all pending dismissals. |
831 * @return {Promise} A promise to process the pending dismissals. | 831 * @return {Promise} A promise to process the pending dismissals. |
832 * The promise is rejected if a problem was encountered. | 832 * The promise is rejected if a problem was encountered. |
833 */ | 833 */ |
834 function processPendingDismissals() { | 834 function processPendingDismissals() { |
835 return fillFromChromeLocalStorage({ | 835 return fillFromChromeLocalStorage({ |
836 /** @type {Array.<PendingDismissal>} */ | 836 /** @type {Array<PendingDismissal>} */ |
837 pendingDismissals: [], | 837 pendingDismissals: [], |
838 /** @type {Object.<ServerNotificationId, number>} */ | 838 /** @type {Object<ServerNotificationId, number>} */ |
839 recentDismissals: {} | 839 recentDismissals: {} |
840 }).then(function(items) { | 840 }).then(function(items) { |
841 console.log( | 841 console.log( |
842 'processPendingDismissals-storage-get ' + JSON.stringify(items)); | 842 'processPendingDismissals-storage-get ' + JSON.stringify(items)); |
843 | 843 |
844 var dismissalsChanged = false; | 844 var dismissalsChanged = false; |
845 | 845 |
846 function onFinish(success) { | 846 function onFinish(success) { |
847 if (dismissalsChanged) { | 847 if (dismissalsChanged) { |
848 chrome.storage.local.set({ | 848 chrome.storage.local.set({ |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
906 /** | 906 /** |
907 * Opens URL corresponding to the clicked part of the notification. | 907 * Opens URL corresponding to the clicked part of the notification. |
908 * @param {ChromeNotificationId} chromeNotificationId chrome.notifications ID of | 908 * @param {ChromeNotificationId} chromeNotificationId chrome.notifications ID of |
909 * the card. | 909 * the card. |
910 * @param {function(NotificationDataEntry): (string|undefined)} selector | 910 * @param {function(NotificationDataEntry): (string|undefined)} selector |
911 * Function that extracts the url for the clicked area from the | 911 * Function that extracts the url for the clicked area from the |
912 * notification data entry. | 912 * notification data entry. |
913 */ | 913 */ |
914 function onNotificationClicked(chromeNotificationId, selector) { | 914 function onNotificationClicked(chromeNotificationId, selector) { |
915 fillFromChromeLocalStorage({ | 915 fillFromChromeLocalStorage({ |
916 /** @type {Object.<ChromeNotificationId, NotificationDataEntry>} */ | 916 /** @type {Object<ChromeNotificationId, NotificationDataEntry>} */ |
917 notificationsData: {} | 917 notificationsData: {} |
918 }).then(function(items) { | 918 }).then(function(items) { |
919 /** @type {(NotificationDataEntry|undefined)} */ | 919 /** @type {(NotificationDataEntry|undefined)} */ |
920 var notificationDataEntry = items.notificationsData[chromeNotificationId]; | 920 var notificationDataEntry = items.notificationsData[chromeNotificationId]; |
921 if (!notificationDataEntry) | 921 if (!notificationDataEntry) |
922 return; | 922 return; |
923 | 923 |
924 var url = selector(notificationDataEntry); | 924 var url = selector(notificationDataEntry); |
925 if (!url) | 925 if (!url) |
926 return; | 926 return; |
(...skipping 12 matching lines...) Expand all Loading... |
939 if (!byUser) | 939 if (!byUser) |
940 return; | 940 return; |
941 | 941 |
942 // At this point we are guaranteed that the notification is a now card. | 942 // At this point we are guaranteed that the notification is a now card. |
943 chrome.metricsPrivate.recordUserAction('GoogleNow.Dismissed'); | 943 chrome.metricsPrivate.recordUserAction('GoogleNow.Dismissed'); |
944 | 944 |
945 tasks.add(DISMISS_CARD_TASK_NAME, function() { | 945 tasks.add(DISMISS_CARD_TASK_NAME, function() { |
946 dismissalAttempts.start(); | 946 dismissalAttempts.start(); |
947 | 947 |
948 fillFromChromeLocalStorage({ | 948 fillFromChromeLocalStorage({ |
949 /** @type {Array.<PendingDismissal>} */ | 949 /** @type {Array<PendingDismissal>} */ |
950 pendingDismissals: [], | 950 pendingDismissals: [], |
951 /** @type {Object.<ChromeNotificationId, NotificationDataEntry>} */ | 951 /** @type {Object<ChromeNotificationId, NotificationDataEntry>} */ |
952 notificationsData: {}, | 952 notificationsData: {}, |
953 /** @type {Object.<string, StoredNotificationGroup>} */ | 953 /** @type {Object<string, StoredNotificationGroup>} */ |
954 notificationGroups: {} | 954 notificationGroups: {} |
955 }).then(function(items) { | 955 }).then(function(items) { |
956 /** @type {NotificationDataEntry} */ | 956 /** @type {NotificationDataEntry} */ |
957 var notificationData = | 957 var notificationData = |
958 items.notificationsData[chromeNotificationId] || | 958 items.notificationsData[chromeNotificationId] || |
959 { | 959 { |
960 timestamp: Date.now(), | 960 timestamp: Date.now(), |
961 combinedCard: [] | 961 combinedCard: [] |
962 }; | 962 }; |
963 | 963 |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1251 }); | 1251 }); |
1252 | 1252 |
1253 instrumented.runtime.onStartup.addListener(function() { | 1253 instrumented.runtime.onStartup.addListener(function() { |
1254 console.log('onStartup'); | 1254 console.log('onStartup'); |
1255 | 1255 |
1256 // Show notifications received by earlier polls. Doing this as early as | 1256 // Show notifications received by earlier polls. Doing this as early as |
1257 // possible to reduce latency of showing first notifications. This mimics how | 1257 // possible to reduce latency of showing first notifications. This mimics how |
1258 // persistent notifications will work. | 1258 // persistent notifications will work. |
1259 tasks.add(SHOW_ON_START_TASK_NAME, function() { | 1259 tasks.add(SHOW_ON_START_TASK_NAME, function() { |
1260 fillFromChromeLocalStorage({ | 1260 fillFromChromeLocalStorage({ |
1261 /** @type {Object.<string, StoredNotificationGroup>} */ | 1261 /** @type {Object<string, StoredNotificationGroup>} */ |
1262 notificationGroups: {} | 1262 notificationGroups: {} |
1263 }).then(function(items) { | 1263 }).then(function(items) { |
1264 console.log('onStartup-get ' + JSON.stringify(items)); | 1264 console.log('onStartup-get ' + JSON.stringify(items)); |
1265 | 1265 |
1266 showNotificationGroups(items.notificationGroups).then(function() { | 1266 showNotificationGroups(items.notificationGroups).then(function() { |
1267 chrome.storage.local.set(items); | 1267 chrome.storage.local.set(items); |
1268 }); | 1268 }); |
1269 }); | 1269 }); |
1270 }); | 1270 }); |
1271 | 1271 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1339 // Each time after signing in, we'll get latest payload for all channels. | 1339 // Each time after signing in, we'll get latest payload for all channels. |
1340 // So, we need to poll the server only when the payload is non-empty and has | 1340 // So, we need to poll the server only when the payload is non-empty and has |
1341 // changed. | 1341 // changed. |
1342 console.log('pushMessaging.onMessage ' + JSON.stringify(message)); | 1342 console.log('pushMessaging.onMessage ' + JSON.stringify(message)); |
1343 if (message.payload.indexOf('REQUEST_CARDS') == 0) { | 1343 if (message.payload.indexOf('REQUEST_CARDS') == 0) { |
1344 tasks.add(ON_PUSH_MESSAGE_START_TASK_NAME, function() { | 1344 tasks.add(ON_PUSH_MESSAGE_START_TASK_NAME, function() { |
1345 // Accept promise rejection on failure since it's safer to do nothing, | 1345 // Accept promise rejection on failure since it's safer to do nothing, |
1346 // preventing polling the server when the payload really didn't change. | 1346 // preventing polling the server when the payload really didn't change. |
1347 fillFromChromeLocalStorage({ | 1347 fillFromChromeLocalStorage({ |
1348 lastPollNowPayloads: {}, | 1348 lastPollNowPayloads: {}, |
1349 /** @type {Object.<string, StoredNotificationGroup>} */ | 1349 /** @type {Object<string, StoredNotificationGroup>} */ |
1350 notificationGroups: {} | 1350 notificationGroups: {} |
1351 }, PromiseRejection.ALLOW).then(function(items) { | 1351 }, PromiseRejection.ALLOW).then(function(items) { |
1352 if (items.lastPollNowPayloads[message.subchannelId] != | 1352 if (items.lastPollNowPayloads[message.subchannelId] != |
1353 message.payload) { | 1353 message.payload) { |
1354 items.lastPollNowPayloads[message.subchannelId] = message.payload; | 1354 items.lastPollNowPayloads[message.subchannelId] = message.payload; |
1355 | 1355 |
1356 items.notificationGroups['PUSH' + message.subchannelId] = { | 1356 items.notificationGroups['PUSH' + message.subchannelId] = { |
1357 cards: [], | 1357 cards: [], |
1358 nextPollTime: Date.now() | 1358 nextPollTime: Date.now() |
1359 }; | 1359 }; |
1360 | 1360 |
1361 chrome.storage.local.set({ | 1361 chrome.storage.local.set({ |
1362 lastPollNowPayloads: items.lastPollNowPayloads, | 1362 lastPollNowPayloads: items.lastPollNowPayloads, |
1363 notificationGroups: items.notificationGroups | 1363 notificationGroups: items.notificationGroups |
1364 }); | 1364 }); |
1365 | 1365 |
1366 pollOptedInWithRecheck(); | 1366 pollOptedInWithRecheck(); |
1367 } | 1367 } |
1368 }); | 1368 }); |
1369 }); | 1369 }); |
1370 } | 1370 } |
1371 }); | 1371 }); |
OLD | NEW |