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

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: skare@ 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 | no next file » | 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 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 mergedCards[card.chromeNotificationId], 420 mergedCards[card.chromeNotificationId],
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. If this map is empty, the user is not opted in to Google
431 * Now.
426 */ 432 */
427 function scheduleNextPoll(groups) { 433 function scheduleNextPoll(groups) {
rgustafson 2013/10/31 18:37:59 Why not add another optional param for boolean opt
vadimt 2013/10/31 19:59:57 Added param. Note that we happen to call this func
428 var nextPollTime = null; 434 var nextPollTime = null;
429 435
430 for (var groupName in groups) { 436 for (var groupName in groups) {
431 var group = groups[groupName]; 437 var group = groups[groupName];
432 if (group.nextPollTime !== undefined) { 438 if (group.nextPollTime !== undefined) {
433 nextPollTime = nextPollTime == null ? 439 nextPollTime = nextPollTime == null ?
434 group.nextPollTime : Math.min(group.nextPollTime, nextPollTime); 440 group.nextPollTime : Math.min(group.nextPollTime, nextPollTime);
435 } 441 }
436 } 442 }
437 443
438 // At least one of the groups must have nextPollTime. 444 if (nextPollTime != null) {
439 verify(nextPollTime != null, 'scheduleNextPoll: nextPollTime is null'); 445 var nextPollDelaySeconds = Math.max(
440 446 (nextPollTime - Date.now()) / MS_IN_SECOND,
441 var nextPollDelaySeconds = Math.max( 447 MINIMUM_POLLING_PERIOD_SECONDS);
442 (nextPollTime - Date.now()) / MS_IN_SECOND, 448 updateCardsAttempts.start(nextPollDelaySeconds);
443 MINIMUM_POLLING_PERIOD_SECONDS); 449 } else {
444 updateCardsAttempts.start(nextPollDelaySeconds); 450 instrumented.metricsPrivate.getVariationParams(
451 'GoogleNow', function(params) {
452 var optinPollPeriodSeconds =
453 parseInt(params && params.optinPollPeriodSeconds, 10) ||
454 DEFAULT_OPTIN_CHECK_PERIOD_SECONDS;
455 updateCardsAttempts.start(optinPollPeriodSeconds);
456 });
457 }
445 } 458 }
446 459
447 /** 460 /**
448 * Merges notification groups into a set of Chrome notifications and shows them. 461 * Merges notification groups into a set of Chrome notifications and shows them.
449 * @param {Object.<string, StorageGroup>} notificationGroups Map from group name 462 * @param {Object.<string, StorageGroup>} notificationGroups Map from group name
450 * to group information. 463 * to group information.
451 */ 464 */
452 function mergeAndShowNotificationCards(notificationGroups) { 465 function mergeAndShowNotificationCards(notificationGroups) {
453 var mergedCards = {}; 466 var mergedCards = {};
454 467
455 for (var groupName in notificationGroups) 468 for (var groupName in notificationGroups)
456 mergeGroup(mergedCards, notificationGroups[groupName]); 469 mergeGroup(mergedCards, notificationGroups[groupName]);
457 470
458 showNotificationCards(mergedCards); 471 showNotificationCards(mergedCards);
459 } 472 }
460 473
461 /** 474 /**
462 * Parses JSON response from the notification server, shows notifications and 475 * Parses JSON response from the notification server, shows notifications and
463 * schedules next update. 476 * schedules next update.
464 * @param {string} response Server response. 477 * @param {string} response Server response.
465 */ 478 */
466 function parseAndShowNotificationCards(response) { 479 function parseAndShowNotificationCards(response) {
467 console.log('parseAndShowNotificationCards ' + response); 480 console.log('parseAndShowNotificationCards ' + response);
468 var parsedResponse = JSON.parse(response); 481 var parsedResponse = JSON.parse(response);
469 482
483 if (parsedResponse.googleNowDisabled) {
rgustafson 2013/10/31 18:37:59 Why not call the function to schedule next poll th
vadimt 2013/10/31 19:59:57 We want to delete cards, avoid restoring cards on
484 chrome.storage.local.set({googleNowEnabled: false});
485 // TODO(vadimt): Remove the line below once the server stops sending groups
486 // with 'googleNowDisabled' responses.
487 parsedResponse.groups = {};
488 }
489
470 var receivedGroups = parsedResponse.groups; 490 var receivedGroups = parsedResponse.groups;
471 491
472 // Populate groups with corresponding cards. 492 // Populate groups with corresponding cards.
473 if (parsedResponse.notifications) { 493 if (parsedResponse.notifications) {
474 for (var i = 0; i != parsedResponse.notifications.length; ++i) { 494 for (var i = 0; i != parsedResponse.notifications.length; ++i) {
475 var card = parsedResponse.notifications[i]; 495 var card = parsedResponse.notifications[i];
476 var group = receivedGroups[card.groupName]; 496 var group = receivedGroups[card.groupName];
477 group.cards = group.cards || []; 497 group.cards = group.cards || [];
478 group.cards.push(card); 498 group.cards.push(card);
479 } 499 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 } 580 }
561 }; 581 };
562 582
563 setAuthorization(request, function(success) { 583 setAuthorization(request, function(success) {
564 if (success) 584 if (success)
565 request.send(); 585 request.send();
566 }); 586 });
567 } 587 }
568 588
569 /** 589 /**
590 * Requests the account opted-in state from the server.
591 * @param {function()} optedInCallback Function that will be called if
592 * opted-in state is 'true'.
593 */
594 function requestOptedIn(optedInCallback) {
595 console.log('requestOptedIn from ' + NOTIFICATION_CARDS_URL);
596
597 var request = buildServerRequest('GET', 'settings/optin');
598
599 request.onloadend = function(event) {
600 console.log(
601 'requestOptedIn-onloadend ' + request.status + ' ' + request.response);
602 if (request.status == HTTP_OK) {
603 var parsedResponse = JSON.parse(request.response);
604 if (parsedResponse.value) {
605 chrome.storage.local.set({googleNowEnabled: true});
606 optedInCallback();
607 } else {
608 scheduleNextPoll({});
609 }
610 }
611 };
612
613 setAuthorization(request, function(success) {
614 if (success)
615 request.send();
616 });
617 }
618
619 /**
570 * Requests notification cards from the server. 620 * Requests notification cards from the server.
571 * @param {Location} position Location of this computer. 621 * @param {Location} position Location of this computer.
572 */ 622 */
573 function requestNotificationCards(position) { 623 function requestNotificationCards(position) {
574 console.log('requestNotificationCards ' + JSON.stringify(position)); 624 console.log('requestNotificationCards ' + JSON.stringify(position));
575 625
576 instrumented.storage.local.get('notificationGroups', function(items) { 626 instrumented.storage.local.get(
627 ['notificationGroups', 'googleNowEnabled'], function(items) {
577 console.log('requestNotificationCards-storage-get ' + 628 console.log('requestNotificationCards-storage-get ' +
578 JSON.stringify(items)); 629 JSON.stringify(items));
579 items = items || {}; 630 items = items || {};
580 631
581 var groupsToRequest = []; 632 var groupsToRequest = [];
582 633
583 if (items.notificationGroups) { 634 if (items.notificationGroups) {
584 var now = Date.now(); 635 var now = Date.now();
585 636
586 for (var groupName in items.notificationGroups) { 637 for (var groupName in items.notificationGroups) {
587 var group = items.notificationGroups[groupName]; 638 var group = items.notificationGroups[groupName];
588 if (group.nextPollTime !== undefined && group.nextPollTime <= now) 639 if (group.nextPollTime !== undefined && group.nextPollTime <= now)
589 groupsToRequest.push(groupName); 640 groupsToRequest.push(groupName);
590 } 641 }
591 } 642 }
592 643
593 requestNotificationGroups(groupsToRequest); 644 if (items.googleNowEnabled) {
645 requestNotificationGroups(groupsToRequest);
646 } else {
647 requestOptedIn(function() {
648 requestNotificationGroups(groupsToRequest);
649 });
650 }
594 }); 651 });
595 } 652 }
596 653
597 /** 654 /**
598 * Starts getting location for a cards update. 655 * Starts getting location for a cards update.
599 */ 656 */
600 function requestLocation() { 657 function requestLocation() {
601 console.log('requestLocation'); 658 console.log('requestLocation');
602 recordEvent(GoogleNowEvent.LOCATION_REQUEST); 659 recordEvent(GoogleNowEvent.LOCATION_REQUEST);
603 // TODO(vadimt): Figure out location request options. 660 // TODO(vadimt): Figure out location request options.
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after
1075 }); 1132 });
1076 1133
1077 instrumented.pushMessaging.onMessage.addListener(function(message) { 1134 instrumented.pushMessaging.onMessage.addListener(function(message) {
1078 // message.payload will be '' when the extension first starts. 1135 // message.payload will be '' when the extension first starts.
1079 // Each time after signing in, we'll get latest payload for all channels. 1136 // 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 1137 // So, we need to poll the server only when the payload is non-empty and has
1081 // changed. 1138 // changed.
1082 console.log('pushMessaging.onMessage ' + JSON.stringify(message)); 1139 console.log('pushMessaging.onMessage ' + JSON.stringify(message));
1083 if (message.payload.indexOf('REQUEST_CARDS') == 0) { 1140 if (message.payload.indexOf('REQUEST_CARDS') == 0) {
1084 tasks.add(ON_PUSH_MESSAGE_START_TASK_NAME, function() { 1141 tasks.add(ON_PUSH_MESSAGE_START_TASK_NAME, function() {
1085 instrumented.storage.local.get('lastPollNowPayloads', function(items) { 1142 instrumented.storage.local.get(
1143 ['lastPollNowPayloads', 'notificationGroups'], function(items) {
1086 // If storage.get fails, it's safer to do nothing, preventing polling 1144 // If storage.get fails, it's safer to do nothing, preventing polling
1087 // the server when the payload really didn't change. 1145 // the server when the payload really didn't change.
1088 if (!items) 1146 if (!items)
1089 return; 1147 return;
1090 1148
1091 // If this is the first time we get lastPollNowPayloads, initialize it. 1149 // If this is the first time we get lastPollNowPayloads, initialize it.
1092 items.lastPollNowPayloads = items.lastPollNowPayloads || {}; 1150 items.lastPollNowPayloads = items.lastPollNowPayloads || {};
1093 1151
1094 if (items.lastPollNowPayloads[message.subchannelId] != 1152 if (items.lastPollNowPayloads[message.subchannelId] !=
1095 message.payload) { 1153 message.payload) {
1096 items.lastPollNowPayloads[message.subchannelId] = message.payload; 1154 items.lastPollNowPayloads[message.subchannelId] = message.payload;
1097 chrome.storage.local.set(
1098 {lastPollNowPayloads: items.lastPollNowPayloads});
1099 1155
1100 updateCardsAttempts.isRunning(function(running) { 1156 items.notificationGroups = items.notificationGroups || {};
1101 if (running) 1157 items.notificationGroups['PUSH' + message.subchannelId] = {
1102 requestNotificationGroups(['PUSH' + message.subchannelId]); 1158 cards: [],
1159 nextPollTime: Date.now()
1160 };
1161
1162 chrome.storage.local.set({
1163 lastPollNowPayloads: items.lastPollNowPayloads,
1164 notificationGroups: items.notificationGroups
1103 }); 1165 });
1166
1167 updateNotificationsCards();
1104 } 1168 }
1105 }); 1169 });
1106 }); 1170 });
1107 } 1171 }
1108 }); 1172 });
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698