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. |
| 11 * The service performs periodic updating of Google Now cards. | 11 * The service performs periodic updating of Google Now cards. |
| 12 * Each updating of the cards includes 4 steps: | 12 * Each updating of the cards includes 4 steps: |
| 13 * 1. Processing requests for cards dismissals that are not yet sent to the | 13 * 1. Processing requests for cards dismissals that are not yet sent to the |
| 14 * server. | 14 * server. |
| 15 * 2. Making a server request. | 15 * 2. Making a server request. |
| 16 * 3. Showing the received cards as notifications. | 16 * 3. Showing the received cards as notifications. |
| 17 */ | 17 */ |
| 18 | 18 |
| 19 // TODO(vadimt): Decide what to do in incognito mode. | 19 // TODO(robliao): Decide what to do in incognito mode. |
| 20 // TODO(vadimt): Figure out the final values of the constants. | |
| 21 | 20 |
| 22 /** | 21 /** |
| 23 * Standard response code for successful HTTP requests. This is the only success | 22 * Standard response code for successful HTTP requests. This is the only success |
| 24 * code the server will send. | 23 * code the server will send. |
| 25 */ | 24 */ |
| 26 var HTTP_OK = 200; | 25 var HTTP_OK = 200; |
| 27 var HTTP_NOCONTENT = 204; | 26 var HTTP_NOCONTENT = 204; |
| 28 | 27 |
| 29 var HTTP_BAD_REQUEST = 400; | 28 var HTTP_BAD_REQUEST = 400; |
| 30 var HTTP_UNAUTHORIZED = 401; | 29 var HTTP_UNAUTHORIZED = 401; |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 325 resolve(request); | 324 resolve(request); |
| 326 }, false); | 325 }, false); |
| 327 request.send(); | 326 request.send(); |
| 328 }); | 327 }); |
| 329 requestPromise.then(checkAuthenticationStatus(token)); | 328 requestPromise.then(checkAuthenticationStatus(token)); |
| 330 return requestPromise; | 329 return requestPromise; |
| 331 }); | 330 }); |
| 332 } | 331 } |
| 333 | 332 |
| 334 /** | 333 /** |
| 335 * Shows parsed and combined cards as notifications. | 334 * Shows the notification groups as notification cards. |
| 336 * @param {Object.<string, StoredNotificationGroup>} notificationGroups Map from | 335 * @param {Object.<string, StoredNotificationGroup>} notificationGroups Map from |
| 337 * group name to group information. | 336 * group name to group information. |
| 338 * @param {Object.<ChromeNotificationId, CombinedCard>} cards Map from | 337 * @param {function(ReceivedNotification)=} opt_onCardShown Optional parameter |
| 339 * chromeNotificationId to the combined card, containing cards to show. | |
| 340 * @param {function()} onSuccess Called on success. | |
| 341 * @param {function(ReceivedNotification)=} onCardShown Optional parameter | |
| 342 * called when each card is shown. | 338 * called when each card is shown. |
| 339 * @return {Promise} A promise to show the notification groups as cards. | |
| 343 */ | 340 */ |
| 344 function showNotificationCards( | 341 function showNotificationGroups(notificationGroups, opt_onCardShown) { |
| 345 notificationGroups, cards, onSuccess, onCardShown) { | 342 var cards = combineCardsFromGroups(notificationGroups); |
| 346 console.log('showNotificationCards ' + JSON.stringify(cards)); | 343 console.log('showNotificationGroups ' + JSON.stringify(cards)); |
| 347 | 344 |
| 348 instrumented.notifications.getAll(function(notifications) { | 345 return new Promise(function(resolve) { |
| 349 console.log('showNotificationCards-getAll ' + | 346 instrumented.notifications.getAll(function(notifications) { |
| 350 JSON.stringify(notifications)); | 347 console.log('showNotificationGroups-getAll ' + |
| 351 notifications = notifications || {}; | 348 JSON.stringify(notifications)); |
| 349 notifications = notifications || {}; | |
| 352 | 350 |
| 353 // Mark notifications that didn't receive an update as having received | 351 // Mark notifications that didn't receive an update as having received |
| 354 // an empty update. | 352 // an empty update. |
| 355 for (var chromeNotificationId in notifications) { | 353 for (var chromeNotificationId in notifications) { |
| 356 cards[chromeNotificationId] = cards[chromeNotificationId] || []; | 354 cards[chromeNotificationId] = cards[chromeNotificationId] || []; |
| 357 } | 355 } |
| 358 | 356 |
| 359 /** @type {Object.<string, NotificationDataEntry>} */ | 357 /** @type {Object.<string, NotificationDataEntry>} */ |
| 360 var notificationsData = {}; | 358 var notificationsData = {}; |
| 361 | 359 |
| 362 // Create/update/delete notifications. | 360 // Create/update/delete notifications. |
| 363 for (var chromeNotificationId in cards) { | 361 for (var chromeNotificationId in cards) { |
| 364 notificationsData[chromeNotificationId] = cardSet.update( | 362 notificationsData[chromeNotificationId] = cardSet.update( |
| 365 chromeNotificationId, | 363 chromeNotificationId, |
| 366 cards[chromeNotificationId], | 364 cards[chromeNotificationId], |
| 367 notificationGroups, | 365 notificationGroups, |
| 368 onCardShown); | 366 opt_onCardShown); |
| 369 } | 367 } |
| 370 chrome.storage.local.set({notificationsData: notificationsData}); | 368 chrome.storage.local.set({notificationsData: notificationsData}); |
| 371 onSuccess(); | 369 resolve(); |
| 370 }); | |
| 372 }); | 371 }); |
| 373 } | 372 } |
| 374 | 373 |
| 375 /** | 374 /** |
| 376 * Removes all cards and card state on Google Now close down. | 375 * Removes all cards and card state on Google Now close down. |
| 377 */ | 376 */ |
| 378 function removeAllCards() { | 377 function removeAllCards() { |
| 379 console.log('removeAllCards'); | 378 console.log('removeAllCards'); |
| 380 | 379 |
| 381 // TODO(robliao): Once Google Now clears its own checkbox in the | 380 // TODO(robliao): Once Google Now clears its own checkbox in the |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 450 'GoogleNow', function(params) { | 449 'GoogleNow', function(params) { |
| 451 var optinPollPeriodSeconds = | 450 var optinPollPeriodSeconds = |
| 452 parseInt(params && params.optinPollPeriodSeconds, 10) || | 451 parseInt(params && params.optinPollPeriodSeconds, 10) || |
| 453 DEFAULT_OPTIN_CHECK_PERIOD_SECONDS; | 452 DEFAULT_OPTIN_CHECK_PERIOD_SECONDS; |
| 454 updateCardsAttempts.start(optinPollPeriodSeconds); | 453 updateCardsAttempts.start(optinPollPeriodSeconds); |
| 455 }); | 454 }); |
| 456 } | 455 } |
| 457 } | 456 } |
| 458 | 457 |
| 459 /** | 458 /** |
| 460 * Combines notification groups into a set of Chrome notifications and shows | 459 * Combines notification groups into a set of Chrome notifications. |
| 461 * them. | |
| 462 * @param {Object.<string, StoredNotificationGroup>} notificationGroups Map from | 460 * @param {Object.<string, StoredNotificationGroup>} notificationGroups Map from |
| 463 * group name to group information. | 461 * group name to group information. |
| 464 * @param {function()} onSuccess Called on success. | 462 * @return {Object.<ChromeNotificationId, CombinedCard>} Cards to show. |
| 465 * @param {function(ReceivedNotification)=} onCardShown Optional parameter | |
| 466 * called when each card is shown. | |
| 467 */ | 463 */ |
| 468 function combineAndShowNotificationCards( | 464 function combineCardsFromGroups(notificationGroups) { |
| 469 notificationGroups, onSuccess, onCardShown) { | 465 console.log('combineCardsFromGroups ' + JSON.stringify(notificationGroups)); |
| 470 console.log('combineAndShowNotificationCards ' + | |
| 471 JSON.stringify(notificationGroups)); | |
| 472 /** @type {Object.<ChromeNotificationId, CombinedCard>} */ | 466 /** @type {Object.<ChromeNotificationId, CombinedCard>} */ |
| 473 var combinedCards = {}; | 467 var combinedCards = {}; |
| 474 | 468 |
| 475 for (var groupName in notificationGroups) | 469 for (var groupName in notificationGroups) |
| 476 combineGroup(combinedCards, notificationGroups[groupName]); | 470 combineGroup(combinedCards, notificationGroups[groupName]); |
| 477 | 471 |
| 478 showNotificationCards( | 472 return combinedCards; |
| 479 notificationGroups, combinedCards, onSuccess, onCardShown); | |
| 480 } | 473 } |
| 481 | 474 |
| 482 /** | 475 /** |
| 483 * Based on a response from the notification server, shows notifications and | 476 * Processes a server response for consumption by showNotificationGroups. |
| 484 * schedules next update. | |
| 485 * @param {ServerResponse} response Server response. | 477 * @param {ServerResponse} response Server response. |
| 486 * @param {function(ReceivedNotification)=} onCardShown Optional parameter | 478 * @return {Promise} A promise to process the server response and provide |
| 487 * called when each card is shown. | 479 * updated groups. Rejects if the server response shouldn't be processed. |
| 488 */ | 480 */ |
| 489 function processServerResponse(response, onCardShown) { | 481 function processServerResponse(response) { |
| 490 console.log('processServerResponse ' + JSON.stringify(response)); | 482 console.log('processServerResponse ' + JSON.stringify(response)); |
| 491 | 483 |
| 492 if (response.googleNowDisabled) { | 484 if (response.googleNowDisabled) { |
| 493 chrome.storage.local.set({googleNowEnabled: false}); | 485 chrome.storage.local.set({googleNowEnabled: false}); |
| 494 // TODO(vadimt): Remove the line below once the server stops sending groups | 486 // TODO(robliao): Remove the line below once the server stops sending groups |
| 495 // with 'googleNowDisabled' responses. | 487 // with 'googleNowDisabled' responses. |
| 496 response.groups = {}; | 488 response.groups = {}; |
| 497 // Google Now was enabled; now it's disabled. This is a state change. | 489 // Google Now was enabled; now it's disabled. This is a state change. |
| 498 onStateChange(); | 490 onStateChange(); |
| 491 // Allow this to continue. We still need to do work here to clear | |
|
rgustafson
2014/04/02 22:23:09
On first read, I thought this data would be cleare
robliao
2014/04/02 23:24:10
I fell into the same trap. The optin portions here
| |
| 492 // the cards and schedule the next opt-in poll. | |
| 499 } | 493 } |
| 500 | 494 |
| 501 var receivedGroups = response.groups; | 495 var receivedGroups = response.groups; |
| 502 | 496 |
| 503 fillFromChromeLocalStorage({ | 497 return fillFromChromeLocalStorage({ |
| 504 /** @type {Object.<string, StoredNotificationGroup>} */ | 498 /** @type {Object.<string, StoredNotificationGroup>} */ |
| 505 notificationGroups: {}, | 499 notificationGroups: {}, |
| 506 /** @type {Object.<NotificationId, number>} */ | 500 /** @type {Object.<NotificationId, number>} */ |
| 507 recentDismissals: {} | 501 recentDismissals: {} |
| 508 }).then(function(items) { | 502 }).then(function(items) { |
| 509 console.log('processServerResponse-get ' + JSON.stringify(items)); | 503 console.log('processServerResponse-get ' + JSON.stringify(items)); |
| 510 | 504 |
| 511 // Build a set of non-expired recent dismissals. It will be used for | 505 // Build a set of non-expired recent dismissals. It will be used for |
| 512 // client-side filtering of cards. | 506 // client-side filtering of cards. |
| 513 /** @type {Object.<NotificationId, number>} */ | 507 /** @type {Object.<NotificationId, number>} */ |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 566 // cards updates. | 560 // cards updates. |
| 567 if (receivedGroup.nextPollSeconds !== undefined) { | 561 if (receivedGroup.nextPollSeconds !== undefined) { |
| 568 storedGroup.nextPollTime = | 562 storedGroup.nextPollTime = |
| 569 now + receivedGroup.nextPollSeconds * MS_IN_SECOND; | 563 now + receivedGroup.nextPollSeconds * MS_IN_SECOND; |
| 570 } | 564 } |
| 571 | 565 |
| 572 updatedGroups[groupName] = storedGroup; | 566 updatedGroups[groupName] = storedGroup; |
| 573 } | 567 } |
| 574 | 568 |
| 575 scheduleNextPoll(updatedGroups, !response.googleNowDisabled); | 569 scheduleNextPoll(updatedGroups, !response.googleNowDisabled); |
| 576 combineAndShowNotificationCards( | 570 return { |
| 577 updatedGroups, | 571 updatedGroups: updatedGroups, |
| 578 function() { | 572 recentDismissals: updatedRecentDismissals |
| 579 chrome.storage.local.set({ | 573 }; |
| 580 notificationGroups: updatedGroups, | |
| 581 recentDismissals: updatedRecentDismissals | |
| 582 }); | |
| 583 recordEvent(GoogleNowEvent.CARDS_PARSE_SUCCESS); | |
| 584 }, | |
| 585 onCardShown); | |
| 586 }); | 574 }); |
| 587 } | 575 } |
| 588 | 576 |
| 589 /** | 577 /** |
| 590 * Update the Explanatory Total Cards Shown Count. | 578 * Update the Explanatory Total Cards Shown Count. |
| 591 */ | 579 */ |
| 592 function countExplanatoryCard() { | 580 function countExplanatoryCard() { |
| 593 localStorage['explanatoryCardsShown']++; | 581 localStorage['explanatoryCardsShown']++; |
| 594 } | 582 } |
| 595 | 583 |
| 596 /** | 584 /** |
| 585 * Determines if cards should have an explanation link. | |
| 586 * @return {boolean} true if an explanatory card should be shown. | |
| 587 */ | |
| 588 function shouldShowExplanatoryCard() { | |
| 589 var isBelowThreshold = | |
| 590 localStorage['explanatoryCardsShown'] < EXPLANATORY_CARDS_LINK_THRESHOLD; | |
| 591 return isBelowThreshold; | |
| 592 } | |
| 593 | |
| 594 /** | |
| 597 * Requests notification cards from the server for specified groups. | 595 * Requests notification cards from the server for specified groups. |
| 598 * @param {Array.<string>} groupNames Names of groups that need to be refreshed. | 596 * @param {Array.<string>} groupNames Names of groups that need to be refreshed. |
| 597 * @return {Promise} A promise to request the specified notification groups. | |
| 599 */ | 598 */ |
| 600 function requestNotificationGroups(groupNames) { | 599 function requestNotificationGroupsFromServer(groupNames) { |
| 601 console.log('requestNotificationGroups from ' + NOTIFICATION_CARDS_URL + | 600 console.log( |
| 601 'requestNotificationGroupsFromServer from ' + NOTIFICATION_CARDS_URL + | |
| 602 ', groupNames=' + JSON.stringify(groupNames)); | 602 ', groupNames=' + JSON.stringify(groupNames)); |
| 603 | 603 |
| 604 recordEvent(GoogleNowEvent.REQUEST_FOR_CARDS_TOTAL); | 604 recordEvent(GoogleNowEvent.REQUEST_FOR_CARDS_TOTAL); |
| 605 | 605 |
| 606 var requestParameters = '?timeZoneOffsetMs=' + | 606 var requestParameters = '?timeZoneOffsetMs=' + |
| 607 (-new Date().getTimezoneOffset() * MS_IN_MINUTE); | 607 (-new Date().getTimezoneOffset() * MS_IN_MINUTE); |
| 608 | 608 |
| 609 var cardShownCallback = undefined; | 609 if (shouldShowExplanatoryCard()) { |
| 610 var belowExplanatoryThreshold = | |
| 611 localStorage['explanatoryCardsShown'] < EXPLANATORY_CARDS_LINK_THRESHOLD; | |
| 612 if (belowExplanatoryThreshold) { | |
| 613 requestParameters += '&cardExplanation=true'; | 610 requestParameters += '&cardExplanation=true'; |
| 614 cardShownCallback = countExplanatoryCard; | |
| 615 } | 611 } |
| 616 | 612 |
| 617 groupNames.forEach(function(groupName) { | 613 groupNames.forEach(function(groupName) { |
| 618 requestParameters += ('&requestTypes=' + groupName); | 614 requestParameters += ('&requestTypes=' + groupName); |
| 619 }); | 615 }); |
| 620 | 616 |
| 621 requestParameters += '&uiLocale=' + navigator.language; | 617 requestParameters += '&uiLocale=' + navigator.language; |
| 622 | 618 |
| 623 console.log('requestNotificationGroups: request=' + requestParameters); | 619 console.log( |
| 620 'requestNotificationGroupsFromServer: request=' + requestParameters); | |
| 624 | 621 |
| 625 requestFromServer('GET', 'notifications' + requestParameters).then( | 622 return requestFromServer('GET', 'notifications' + requestParameters).then( |
| 626 function(request) { | 623 function(request) { |
| 627 console.log('requestNotificationGroups-received ' + request.status); | 624 console.log( |
| 625 'requestNotificationGroupsFromServer-received ' + request.status); | |
| 628 if (request.status == HTTP_OK) { | 626 if (request.status == HTTP_OK) { |
| 629 recordEvent(GoogleNowEvent.REQUEST_FOR_CARDS_SUCCESS); | 627 recordEvent(GoogleNowEvent.REQUEST_FOR_CARDS_SUCCESS); |
| 630 processServerResponse( | 628 return JSON.parse(request.responseText); |
| 631 JSON.parse(request.responseText), cardShownCallback); | |
| 632 } | 629 } |
| 633 }); | 630 }); |
| 634 } | 631 } |
| 635 | 632 |
| 636 /** | 633 /** |
| 637 * Requests the account opted-in state from the server. | 634 * Requests the account opted-in state from the server and updates any |
| 638 * @param {function()} optedInCallback Function that will be called if | 635 * state as necessary. |
| 639 * opted-in state is 'true'. | 636 * @return {Promise} A promise to request and update the opted-in state. |
| 637 * The promise resolves if the opt-in state is true. | |
| 640 */ | 638 */ |
| 641 function requestOptedIn(optedInCallback) { | 639 function requestAndUpdateOptedIn() { |
| 642 console.log('requestOptedIn from ' + NOTIFICATION_CARDS_URL); | 640 console.log('requestOptedIn from ' + NOTIFICATION_CARDS_URL); |
| 643 | 641 |
| 644 requestFromServer('GET', 'settings/optin').then(function(request) { | 642 return requestFromServer('GET', 'settings/optin').then(function(request) { |
| 645 console.log( | 643 console.log( |
| 646 'requestOptedIn-received ' + request.status + ' ' + request.response); | 644 'requestOptedIn-received ' + request.status + ' ' + request.response); |
| 647 if (request.status == HTTP_OK) { | 645 if (request.status == HTTP_OK) { |
| 648 var parsedResponse = JSON.parse(request.responseText); | 646 var parsedResponse = JSON.parse(request.responseText); |
| 649 if (parsedResponse.value) { | 647 return parsedResponse.value; |
| 650 chrome.storage.local.set({googleNowEnabled: true}); | 648 } else { |
| 651 optedInCallback(); | 649 return Promise.reject(); |
| 652 // Google Now was disabled, now it's enabled. This is a state change. | 650 } |
| 653 onStateChange(); | 651 }).then(function(optedIn) { |
| 654 } else { | 652 if (optedIn) { |
| 655 scheduleNextPoll({}, false); | 653 chrome.storage.local.set({googleNowEnabled: true}); |
| 656 } | 654 // Google Now was disabled, now it's enabled. This is a state change. |
| 655 onStateChange(); | |
| 656 return Promise.resolve(); | |
| 657 } else { | |
| 658 scheduleNextPoll({}, false); | |
| 659 return Promise.reject(); | |
| 657 } | 660 } |
| 658 }); | 661 }); |
| 659 } | 662 } |
| 660 | 663 |
| 661 /** | 664 /** |
| 662 * Requests notification cards from the server. | 665 * Determines the groups that need to be requested right now. |
| 666 * @return {Promise} A promise to determine the groups to request. | |
| 663 */ | 667 */ |
| 664 function requestNotificationCards() { | 668 function getGroupsToRequest() { |
| 665 console.log('requestNotificationCards'); | 669 return fillFromChromeLocalStorage({ |
| 666 | |
| 667 fillFromChromeLocalStorage({ | |
| 668 /** @type {Object.<string, StoredNotificationGroup>} */ | 670 /** @type {Object.<string, StoredNotificationGroup>} */ |
| 669 notificationGroups: {}, | 671 notificationGroups: {} |
| 670 googleNowEnabled: false | |
| 671 }).then(function(items) { | 672 }).then(function(items) { |
| 672 console.log( | 673 console.log('getGroupsToRequest-storage-get ' + JSON.stringify(items)); |
| 673 'requestNotificationCards-storage-get ' + JSON.stringify(items)); | |
| 674 | |
| 675 var groupsToRequest = []; | 674 var groupsToRequest = []; |
| 676 | |
| 677 var now = Date.now(); | 675 var now = Date.now(); |
| 678 | 676 |
| 679 for (var groupName in items.notificationGroups) { | 677 for (var groupName in items.notificationGroups) { |
| 680 var group = items.notificationGroups[groupName]; | 678 var group = items.notificationGroups[groupName]; |
| 681 if (group.nextPollTime !== undefined && group.nextPollTime <= now) | 679 if (group.nextPollTime !== undefined && group.nextPollTime <= now) |
| 682 groupsToRequest.push(groupName); | 680 groupsToRequest.push(groupName); |
| 683 } | 681 } |
| 684 | 682 return groupsToRequest; |
| 685 if (items.googleNowEnabled) { | |
| 686 requestNotificationGroups(groupsToRequest); | |
| 687 } else { | |
| 688 requestOptedIn(function() { | |
| 689 requestNotificationGroups(groupsToRequest); | |
| 690 }); | |
| 691 } | |
| 692 }); | 683 }); |
| 693 } | 684 } |
| 694 | 685 |
| 695 /** | 686 /** |
| 687 * Requests notification cards from the server. | |
| 688 * @return {Promise} A promise to request the notification cards. | |
| 689 * Rejects if the cards won't be requested. | |
| 690 */ | |
| 691 function requestNotificationCards() { | |
| 692 console.log('requestNotificationCards'); | |
| 693 | |
| 694 return isGoogleNowEnabled() | |
| 695 .then(function(googleNowEnabled) { | |
| 696 return googleNowEnabled ? Promise.resolve() : requestAndUpdateOptedIn(); | |
| 697 }) | |
| 698 .then(getGroupsToRequest) | |
| 699 .then(requestNotificationGroupsFromServer) | |
| 700 .then(processServerResponse) | |
| 701 .then(function(processedResponse) { | |
| 702 var onCardShown = | |
| 703 shouldShowExplanatoryCard() ? countExplanatoryCard : undefined; | |
| 704 return showNotificationGroups( | |
| 705 processedResponse.updatedGroups, onCardShown).then(function() { | |
| 706 chrome.storage.local.set({ | |
| 707 notificationGroups: processedResponse.updatedGroups, | |
| 708 recentDismissals: processedResponse.updatedRecentDismissals | |
| 709 }); | |
| 710 recordEvent(GoogleNowEvent.CARDS_PARSE_SUCCESS); | |
| 711 } | |
| 712 ); | |
| 713 }); | |
| 714 } | |
| 715 | |
| 716 /** | |
| 696 * Requests and shows notification cards. | 717 * Requests and shows notification cards. |
| 697 */ | 718 */ |
| 698 function requestCards() { | 719 function requestCards() { |
| 699 console.log('requestCards @' + new Date()); | 720 console.log('requestCards @' + new Date()); |
| 700 // LOCATION_REQUEST is a legacy histogram value when we requested location. | 721 // LOCATION_REQUEST is a legacy histogram value when we requested location. |
| 701 // This corresponds to the extension attempting to request for cards. | 722 // This corresponds to the extension attempting to request for cards. |
| 702 // We're keeping the name the same to keep our histograms in order. | 723 // We're keeping the name the same to keep our histograms in order. |
| 703 recordEvent(GoogleNowEvent.LOCATION_REQUEST); | 724 recordEvent(GoogleNowEvent.LOCATION_REQUEST); |
| 704 tasks.add(UPDATE_CARDS_TASK_NAME, function() { | 725 tasks.add(UPDATE_CARDS_TASK_NAME, function() { |
| 705 console.log('requestCards-task-begin'); | 726 console.log('requestCards-task-begin'); |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 925 } | 946 } |
| 926 | 947 |
| 927 /** | 948 /** |
| 928 * Initializes the polling system to start fetching cards. | 949 * Initializes the polling system to start fetching cards. |
| 929 */ | 950 */ |
| 930 function startPollingCards() { | 951 function startPollingCards() { |
| 931 console.log('startPollingCards'); | 952 console.log('startPollingCards'); |
| 932 // Create an update timer for a case when for some reason requesting | 953 // Create an update timer for a case when for some reason requesting |
| 933 // cards gets stuck. | 954 // cards gets stuck. |
| 934 updateCardsAttempts.start(MAXIMUM_POLLING_PERIOD_SECONDS); | 955 updateCardsAttempts.start(MAXIMUM_POLLING_PERIOD_SECONDS); |
| 935 | |
| 936 requestCards(); | 956 requestCards(); |
| 937 } | 957 } |
| 938 | 958 |
| 939 /** | 959 /** |
| 940 * Stops all machinery in the polling system. | 960 * Stops all machinery in the polling system. |
| 941 */ | 961 */ |
| 942 function stopPollingCards() { | 962 function stopPollingCards() { |
| 943 console.log('stopPollingCards'); | 963 console.log('stopPollingCards'); |
| 944 updateCardsAttempts.stop(); | 964 updateCardsAttempts.stop(); |
| 945 removeAllCards(); | 965 removeAllCards(); |
| 946 // Mark the Google Now as disabled to start with checking the opt-in state | 966 // Since we're stopping everything, clear all storage too. |
| 947 // next time startPollingCards() is called. | 967 chrome.storage.local.clear(); |
|
skare_
2014/04/03 00:11:59
this doesn't clear localStorage, correct? They are
robliao
2014/04/03 00:43:22
localStorage is unaffected with this clearing.
Th
| |
| 948 chrome.storage.local.set({googleNowEnabled: false}); | |
| 949 } | 968 } |
| 950 | 969 |
| 951 /** | 970 /** |
| 952 * Initializes the event page on install or on browser startup. | 971 * Initializes the event page on install or on browser startup. |
| 953 */ | 972 */ |
| 954 function initialize() { | 973 function initialize() { |
| 955 recordEvent(GoogleNowEvent.EXTENSION_START); | 974 recordEvent(GoogleNowEvent.EXTENSION_START); |
| 956 onStateChange(); | 975 onStateChange(); |
| 957 } | 976 } |
| 958 | 977 |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1121 */ | 1140 */ |
| 1122 function pollOptedIn() { | 1141 function pollOptedIn() { |
| 1123 /** | 1142 /** |
| 1124 * Cleans up any state used to recheck the opt-in poll. | 1143 * Cleans up any state used to recheck the opt-in poll. |
| 1125 */ | 1144 */ |
| 1126 function clearPollingState() { | 1145 function clearPollingState() { |
| 1127 localStorage.removeItem('optedInCheckCount'); | 1146 localStorage.removeItem('optedInCheckCount'); |
| 1128 optInCheckAttempts.stop(); | 1147 optInCheckAttempts.stop(); |
| 1129 } | 1148 } |
| 1130 | 1149 |
| 1131 /** | |
| 1132 * Performs the actual work for checking the opt-in state and requesting cards | |
| 1133 * on opted-in. | |
| 1134 */ | |
| 1135 function checkOptedIn() { | |
| 1136 // Limit retries to 5. | |
| 1137 if (localStorage.optedInCheckCount < 5) { | |
| 1138 console.log(new Date() + | |
| 1139 ' checkOptedIn Attempt ' + localStorage.optedInCheckCount); | |
| 1140 localStorage.optedInCheckCount++; | |
| 1141 requestOptedIn(function() { | |
| 1142 clearPollingState(); | |
| 1143 requestCards(); | |
| 1144 }); | |
| 1145 } else { | |
| 1146 clearPollingState(); | |
| 1147 } | |
| 1148 } | |
| 1149 | |
| 1150 if (localStorage.optedInCheckCount === undefined) { | 1150 if (localStorage.optedInCheckCount === undefined) { |
| 1151 localStorage.optedInCheckCount = 0; | 1151 localStorage.optedInCheckCount = 0; |
| 1152 optInCheckAttempts.start(); | 1152 optInCheckAttempts.start(); |
| 1153 checkOptedIn(); | |
| 1154 } else { | |
| 1155 optInCheckAttempts.planForNext(checkOptedIn); | |
| 1156 } | 1153 } |
| 1154 | |
| 1155 console.log(new Date() + | |
| 1156 ' checkOptedIn Attempt ' + localStorage.optedInCheckCount); | |
| 1157 | |
| 1158 requestAndUpdateOptedIn().then(function() { | |
| 1159 clearPollingState(); | |
| 1160 requestCards(); | |
| 1161 }).catch(function() { | |
| 1162 if (localStorage.optedInCheckCount < 5) { | |
| 1163 localStorage.optedInCheckCount++; | |
| 1164 optInCheckAttempts.planForNext(function() {}); | |
| 1165 } else { | |
| 1166 clearPollingState(); | |
| 1167 } | |
| 1168 }); | |
| 1157 } | 1169 } |
| 1158 | 1170 |
| 1159 instrumented.runtime.onInstalled.addListener(function(details) { | 1171 instrumented.runtime.onInstalled.addListener(function(details) { |
| 1160 console.log('onInstalled ' + JSON.stringify(details)); | 1172 console.log('onInstalled ' + JSON.stringify(details)); |
| 1161 if (details.reason != 'chrome_update') { | 1173 if (details.reason != 'chrome_update') { |
| 1162 initialize(); | 1174 initialize(); |
| 1163 } | 1175 } |
| 1164 }); | 1176 }); |
| 1165 | 1177 |
| 1166 instrumented.runtime.onStartup.addListener(function() { | 1178 instrumented.runtime.onStartup.addListener(function() { |
| 1167 console.log('onStartup'); | 1179 console.log('onStartup'); |
| 1168 | 1180 |
| 1169 // Show notifications received by earlier polls. Doing this as early as | 1181 // Show notifications received by earlier polls. Doing this as early as |
| 1170 // possible to reduce latency of showing first notifications. This mimics how | 1182 // possible to reduce latency of showing first notifications. This mimics how |
| 1171 // persistent notifications will work. | 1183 // persistent notifications will work. |
| 1172 tasks.add(SHOW_ON_START_TASK_NAME, function() { | 1184 tasks.add(SHOW_ON_START_TASK_NAME, function() { |
| 1173 fillFromChromeLocalStorage({ | 1185 fillFromChromeLocalStorage({ |
| 1174 /** @type {Object.<string, StoredNotificationGroup>} */ | 1186 /** @type {Object.<string, StoredNotificationGroup>} */ |
| 1175 notificationGroups: {} | 1187 notificationGroups: {} |
| 1176 }).then(function(items) { | 1188 }).then(function(items) { |
| 1177 console.log('onStartup-get ' + JSON.stringify(items)); | 1189 console.log('onStartup-get ' + JSON.stringify(items)); |
| 1178 | 1190 |
| 1179 combineAndShowNotificationCards(items.notificationGroups, function() { | 1191 showNotificationGroups(items.notificationGroups).then(function() { |
| 1180 chrome.storage.local.set(items); | 1192 chrome.storage.local.set(items); |
| 1181 }); | 1193 }); |
| 1182 }); | 1194 }); |
| 1183 }); | 1195 }); |
| 1184 | 1196 |
| 1185 initialize(); | 1197 initialize(); |
| 1186 }); | 1198 }); |
| 1187 | 1199 |
| 1188 authenticationManager.addListener(function() { | 1200 authenticationManager.addListener(function() { |
| 1189 console.log('signIn State Change'); | 1201 console.log('signIn State Change'); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1261 lastPollNowPayloads: items.lastPollNowPayloads, | 1273 lastPollNowPayloads: items.lastPollNowPayloads, |
| 1262 notificationGroups: items.notificationGroups | 1274 notificationGroups: items.notificationGroups |
| 1263 }); | 1275 }); |
| 1264 | 1276 |
| 1265 pollOptedIn(); | 1277 pollOptedIn(); |
| 1266 } | 1278 } |
| 1267 }); | 1279 }); |
| 1268 }); | 1280 }); |
| 1269 } | 1281 } |
| 1270 }); | 1282 }); |
| OLD | NEW |