Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(140)

Side by Side Diff: chrome/browser/resources/google_now/background.js

Issue 53823002: Using “is opted in” server request (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rgustafson's comments Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | chrome/browser/resources/google_now/background_unittest.gtestjs » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 * Time we keep retrying dismissals. 67 * Time we keep retrying dismissals.
68 */ 68 */
69 var MAXIMUM_DISMISSAL_AGE_MS = 24 * 60 * 60 * 1000; // 1 day 69 var MAXIMUM_DISMISSAL_AGE_MS = 24 * 60 * 60 * 1000; // 1 day
70 70
71 /** 71 /**
72 * Time we keep dismissals after successful server dismiss requests. 72 * Time we keep dismissals after successful server dismiss requests.
73 */ 73 */
74 var DISMISS_RETENTION_TIME_MS = 20 * 60 * 1000; // 20 minutes 74 var DISMISS_RETENTION_TIME_MS = 20 * 60 * 1000; // 20 minutes
75 75
76 /** 76 /**
77 * Default period for checking whether the user is opted in to Google Now.
78 */
79 var DEFAULT_OPTIN_CHECK_PERIOD_SECONDS = 60 * 60 * 24 * 7; // 1 week
80
81 /**
77 * Names for tasks that can be created by the extension. 82 * Names for tasks that can be created by the extension.
78 */ 83 */
79 var UPDATE_CARDS_TASK_NAME = 'update-cards'; 84 var UPDATE_CARDS_TASK_NAME = 'update-cards';
80 var DISMISS_CARD_TASK_NAME = 'dismiss-card'; 85 var DISMISS_CARD_TASK_NAME = 'dismiss-card';
81 var RETRY_DISMISS_TASK_NAME = 'retry-dismiss'; 86 var RETRY_DISMISS_TASK_NAME = 'retry-dismiss';
82 var STATE_CHANGED_TASK_NAME = 'state-changed'; 87 var STATE_CHANGED_TASK_NAME = 'state-changed';
83 var SHOW_ON_START_TASK_NAME = 'show-cards-on-start'; 88 var SHOW_ON_START_TASK_NAME = 'show-cards-on-start';
84 var ON_PUSH_MESSAGE_START_TASK_NAME = 'on-push-message'; 89 var ON_PUSH_MESSAGE_START_TASK_NAME = 'on-push-message';
85 90
86 var LOCATION_WATCH_NAME = 'location-watch'; 91 var LOCATION_WATCH_NAME = 'location-watch';
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 card, 421 card,
417 storageGroup.cardsTimestamp, 422 storageGroup.cardsTimestamp,
418 storageGroup.rank); 423 storageGroup.rank);
419 } 424 }
420 } 425 }
421 426
422 /** 427 /**
423 * Schedules next cards poll. 428 * Schedules next cards poll.
424 * @param {Object.<string, StorageGroup>} groups Map from group name to group 429 * @param {Object.<string, StorageGroup>} groups Map from group name to group
425 * information. 430 * information.
431 * @param {boolean} isOptedIn True if the user is opted in to Google Now.
426 */ 432 */
427 function scheduleNextPoll(groups) { 433 function scheduleNextPoll(groups, isOptedIn) {
428 var nextPollTime = null; 434 if (isOptedIn) {
435 var nextPollTime = null;
429 436
430 for (var groupName in groups) { 437 for (var groupName in groups) {
431 var group = groups[groupName]; 438 var group = groups[groupName];
432 if (group.nextPollTime !== undefined) { 439 if (group.nextPollTime !== undefined) {
433 nextPollTime = nextPollTime == null ? 440 nextPollTime = nextPollTime == null ?
434 group.nextPollTime : Math.min(group.nextPollTime, nextPollTime); 441 group.nextPollTime : Math.min(group.nextPollTime, nextPollTime);
442 }
435 } 443 }
444
445 // At least one of the groups must have nextPollTime.
446 verify(nextPollTime != null, 'scheduleNextPoll: nextPollTime is null');
447
448 var nextPollDelaySeconds = Math.max(
449 (nextPollTime - Date.now()) / MS_IN_SECOND,
450 MINIMUM_POLLING_PERIOD_SECONDS);
451 updateCardsAttempts.start(nextPollDelaySeconds);
452 } else {
453 instrumented.metricsPrivate.getVariationParams(
454 'GoogleNow', function(params) {
455 var optinPollPeriodSeconds =
456 parseInt(params && params.optinPollPeriodSeconds, 10) ||
457 DEFAULT_OPTIN_CHECK_PERIOD_SECONDS;
458 updateCardsAttempts.start(optinPollPeriodSeconds);
459 });
436 } 460 }
437
438 // At least one of the groups must have nextPollTime.
439 verify(nextPollTime != null, 'scheduleNextPoll: nextPollTime is null');
440
441 var nextPollDelaySeconds = Math.max(
442 (nextPollTime - Date.now()) / MS_IN_SECOND,
443 MINIMUM_POLLING_PERIOD_SECONDS);
444 updateCardsAttempts.start(nextPollDelaySeconds);
445 } 461 }
446 462
447 /** 463 /**
448 * Merges notification groups into a set of Chrome notifications and shows them. 464 * Merges notification groups into a set of Chrome notifications and shows them.
449 * @param {Object.<string, StorageGroup>} notificationGroups Map from group name 465 * @param {Object.<string, StorageGroup>} notificationGroups Map from group name
450 * to group information. 466 * to group information.
451 */ 467 */
452 function mergeAndShowNotificationCards(notificationGroups) { 468 function mergeAndShowNotificationCards(notificationGroups) {
453 var mergedCards = {}; 469 var mergedCards = {};
454 470
455 for (var groupName in notificationGroups) 471 for (var groupName in notificationGroups)
456 mergeGroup(mergedCards, notificationGroups[groupName]); 472 mergeGroup(mergedCards, notificationGroups[groupName]);
457 473
458 showNotificationCards(mergedCards); 474 showNotificationCards(mergedCards);
459 } 475 }
460 476
461 /** 477 /**
462 * Parses JSON response from the notification server, shows notifications and 478 * Parses JSON response from the notification server, shows notifications and
463 * schedules next update. 479 * schedules next update.
464 * @param {string} response Server response. 480 * @param {string} response Server response.
465 */ 481 */
466 function parseAndShowNotificationCards(response) { 482 function parseAndShowNotificationCards(response) {
467 console.log('parseAndShowNotificationCards ' + response); 483 console.log('parseAndShowNotificationCards ' + response);
468 var parsedResponse = JSON.parse(response); 484 var parsedResponse = JSON.parse(response);
469 485
486 if (parsedResponse.googleNowDisabled) {
487 chrome.storage.local.set({googleNowEnabled: false});
488 // TODO(vadimt): Remove the line below once the server stops sending groups
489 // with 'googleNowDisabled' responses.
490 parsedResponse.groups = {};
491 }
492
470 var receivedGroups = parsedResponse.groups; 493 var receivedGroups = parsedResponse.groups;
471 494
472 // Populate groups with corresponding cards. 495 // Populate groups with corresponding cards.
473 if (parsedResponse.notifications) { 496 if (parsedResponse.notifications) {
474 for (var i = 0; i != parsedResponse.notifications.length; ++i) { 497 for (var i = 0; i != parsedResponse.notifications.length; ++i) {
475 var card = parsedResponse.notifications[i]; 498 var card = parsedResponse.notifications[i];
476 var group = receivedGroups[card.groupName]; 499 var group = receivedGroups[card.groupName];
477 group.cards = group.cards || []; 500 group.cards = group.cards || [];
478 group.cards.push(card); 501 group.cards.push(card);
479 } 502 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 // 'nextPollSeconds' may be sent even for groups that don't contain cards 540 // 'nextPollSeconds' may be sent even for groups that don't contain cards
518 // updates. 541 // updates.
519 if (receivedGroup.nextPollSeconds !== undefined) { 542 if (receivedGroup.nextPollSeconds !== undefined) {
520 storageGroup.nextPollTime = 543 storageGroup.nextPollTime =
521 now + receivedGroup.nextPollSeconds * MS_IN_SECOND; 544 now + receivedGroup.nextPollSeconds * MS_IN_SECOND;
522 } 545 }
523 546
524 updatedGroups[groupName] = storageGroup; 547 updatedGroups[groupName] = storageGroup;
525 } 548 }
526 549
527 scheduleNextPoll(updatedGroups); 550 scheduleNextPoll(updatedGroups, !parsedResponse.googleNowDisabled);
528 chrome.storage.local.set({notificationGroups: updatedGroups}); 551 chrome.storage.local.set({notificationGroups: updatedGroups});
529 mergeAndShowNotificationCards(updatedGroups); 552 mergeAndShowNotificationCards(updatedGroups);
530 recordEvent(GoogleNowEvent.CARDS_PARSE_SUCCESS); 553 recordEvent(GoogleNowEvent.CARDS_PARSE_SUCCESS);
531 }); 554 });
532 } 555 }
533 556
534 /** 557 /**
535 * Requests notification cards from the server for specified groups. 558 * Requests notification cards from the server for specified groups.
536 * @param {Array.<string>} groupNames Names of groups that need to be refreshed. 559 * @param {Array.<string>} groupNames Names of groups that need to be refreshed.
537 */ 560 */
(...skipping 22 matching lines...) Expand all
560 } 583 }
561 }; 584 };
562 585
563 setAuthorization(request, function(success) { 586 setAuthorization(request, function(success) {
564 if (success) 587 if (success)
565 request.send(); 588 request.send();
566 }); 589 });
567 } 590 }
568 591
569 /** 592 /**
593 * Requests the account opted-in state from the server.
594 * @param {function()} optedInCallback Function that will be called if
595 * opted-in state is 'true'.
596 */
597 function requestOptedIn(optedInCallback) {
598 console.log('requestOptedIn from ' + NOTIFICATION_CARDS_URL);
599
600 var request = buildServerRequest('GET', 'settings/optin');
601
602 request.onloadend = function(event) {
603 console.log(
604 'requestOptedIn-onloadend ' + request.status + ' ' + request.response);
605 if (request.status == HTTP_OK) {
606 var parsedResponse = JSON.parse(request.response);
607 if (parsedResponse.value) {
608 chrome.storage.local.set({googleNowEnabled: true});
609 optedInCallback();
610 } else {
611 scheduleNextPoll({}, false);
612 }
613 }
614 };
615
616 setAuthorization(request, function(success) {
617 if (success)
618 request.send();
619 });
620 }
621
622 /**
570 * Requests notification cards from the server. 623 * Requests notification cards from the server.
571 * @param {Location} position Location of this computer. 624 * @param {Location} position Location of this computer.
572 */ 625 */
573 function requestNotificationCards(position) { 626 function requestNotificationCards(position) {
574 console.log('requestNotificationCards ' + JSON.stringify(position)); 627 console.log('requestNotificationCards ' + JSON.stringify(position));
575 628
576 instrumented.storage.local.get('notificationGroups', function(items) { 629 instrumented.storage.local.get(
630 ['notificationGroups', 'googleNowEnabled'], function(items) {
577 console.log('requestNotificationCards-storage-get ' + 631 console.log('requestNotificationCards-storage-get ' +
578 JSON.stringify(items)); 632 JSON.stringify(items));
579 items = items || {}; 633 items = items || {};
580 634
581 var groupsToRequest = []; 635 var groupsToRequest = [];
582 636
583 if (items.notificationGroups) { 637 if (items.notificationGroups) {
584 var now = Date.now(); 638 var now = Date.now();
585 639
586 for (var groupName in items.notificationGroups) { 640 for (var groupName in items.notificationGroups) {
587 var group = items.notificationGroups[groupName]; 641 var group = items.notificationGroups[groupName];
588 if (group.nextPollTime !== undefined && group.nextPollTime <= now) 642 if (group.nextPollTime !== undefined && group.nextPollTime <= now)
589 groupsToRequest.push(groupName); 643 groupsToRequest.push(groupName);
590 } 644 }
591 } 645 }
592 646
593 requestNotificationGroups(groupsToRequest); 647 if (items.googleNowEnabled) {
648 requestNotificationGroups(groupsToRequest);
649 } else {
650 requestOptedIn(function() {
651 requestNotificationGroups(groupsToRequest);
652 });
653 }
594 }); 654 });
595 } 655 }
596 656
597 /** 657 /**
598 * Starts getting location for a cards update. 658 * Starts getting location for a cards update.
599 */ 659 */
600 function requestLocation() { 660 function requestLocation() {
601 console.log('requestLocation'); 661 console.log('requestLocation');
602 recordEvent(GoogleNowEvent.LOCATION_REQUEST); 662 recordEvent(GoogleNowEvent.LOCATION_REQUEST);
603 // TODO(vadimt): Figure out location request options. 663 // TODO(vadimt): Figure out location request options.
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after
1075 }); 1135 });
1076 1136
1077 instrumented.pushMessaging.onMessage.addListener(function(message) { 1137 instrumented.pushMessaging.onMessage.addListener(function(message) {
1078 // message.payload will be '' when the extension first starts. 1138 // message.payload will be '' when the extension first starts.
1079 // Each time after signing in, we'll get latest payload for all channels. 1139 // Each time after signing in, we'll get latest payload for all channels.
1080 // So, we need to poll the server only when the payload is non-empty and has 1140 // So, we need to poll the server only when the payload is non-empty and has
1081 // changed. 1141 // changed.
1082 console.log('pushMessaging.onMessage ' + JSON.stringify(message)); 1142 console.log('pushMessaging.onMessage ' + JSON.stringify(message));
1083 if (message.payload.indexOf('REQUEST_CARDS') == 0) { 1143 if (message.payload.indexOf('REQUEST_CARDS') == 0) {
1084 tasks.add(ON_PUSH_MESSAGE_START_TASK_NAME, function() { 1144 tasks.add(ON_PUSH_MESSAGE_START_TASK_NAME, function() {
1085 instrumented.storage.local.get('lastPollNowPayloads', function(items) { 1145 instrumented.storage.local.get(
1146 ['lastPollNowPayloads', 'notificationGroups'], function(items) {
1086 // If storage.get fails, it's safer to do nothing, preventing polling 1147 // If storage.get fails, it's safer to do nothing, preventing polling
1087 // the server when the payload really didn't change. 1148 // the server when the payload really didn't change.
1088 if (!items) 1149 if (!items)
1089 return; 1150 return;
1090 1151
1091 // If this is the first time we get lastPollNowPayloads, initialize it. 1152 // If this is the first time we get lastPollNowPayloads, initialize it.
1092 items.lastPollNowPayloads = items.lastPollNowPayloads || {}; 1153 items.lastPollNowPayloads = items.lastPollNowPayloads || {};
1093 1154
1094 if (items.lastPollNowPayloads[message.subchannelId] != 1155 if (items.lastPollNowPayloads[message.subchannelId] !=
1095 message.payload) { 1156 message.payload) {
1096 items.lastPollNowPayloads[message.subchannelId] = message.payload; 1157 items.lastPollNowPayloads[message.subchannelId] = message.payload;
1097 chrome.storage.local.set(
1098 {lastPollNowPayloads: items.lastPollNowPayloads});
1099 1158
1100 updateCardsAttempts.isRunning(function(running) { 1159 items.notificationGroups = items.notificationGroups || {};
1101 if (running) 1160 items.notificationGroups['PUSH' + message.subchannelId] = {
1102 requestNotificationGroups(['PUSH' + message.subchannelId]); 1161 cards: [],
1162 nextPollTime: Date.now()
1163 };
1164
1165 chrome.storage.local.set({
1166 lastPollNowPayloads: items.lastPollNowPayloads,
1167 notificationGroups: items.notificationGroups
1103 }); 1168 });
1169
1170 updateNotificationsCards();
1104 } 1171 }
1105 }); 1172 });
1106 }); 1173 });
1107 } 1174 }
1108 }); 1175 });
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/resources/google_now/background_unittest.gtestjs » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698