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

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

Issue 19749007: Processing timefences from the server. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixing manifest typo Created 7 years, 5 months 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
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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 // send dismissals is scheduled. 108 // send dismissals is scheduled.
109 return true; 109 return true;
110 } 110 }
111 111
112 return false; 112 return false;
113 } 113 }
114 114
115 var tasks = buildTaskManager(areTasksConflicting); 115 var tasks = buildTaskManager(areTasksConflicting);
116 116
117 // Add error processing to API calls. 117 // Add error processing to API calls.
118 tasks.instrumentApiFunction(chrome.alarms, 'getAll', 0);
rgustafson 2013/07/19 23:37:12 Where is alarms.getAll used?
vadimt 2013/07/22 19:22:52 Done.
118 tasks.instrumentApiFunction(chrome.identity, 'getAuthToken', 1); 119 tasks.instrumentApiFunction(chrome.identity, 'getAuthToken', 1);
119 tasks.instrumentApiFunction(chrome.identity, 'removeCachedAuthToken', 1); 120 tasks.instrumentApiFunction(chrome.identity, 'removeCachedAuthToken', 1);
120 tasks.instrumentApiFunction(chrome.location.onLocationUpdate, 'addListener', 0); 121 tasks.instrumentApiFunction(chrome.location.onLocationUpdate, 'addListener', 0);
121 tasks.instrumentApiFunction(chrome.notifications, 'create', 2); 122 tasks.instrumentApiFunction(chrome.notifications, 'create', 2);
122 tasks.instrumentApiFunction(chrome.notifications, 'update', 2); 123 tasks.instrumentApiFunction(chrome.notifications, 'update', 2);
123 tasks.instrumentApiFunction(chrome.notifications, 'getAll', 0); 124 tasks.instrumentApiFunction(chrome.notifications, 'getAll', 0);
124 tasks.instrumentApiFunction( 125 tasks.instrumentApiFunction(
125 chrome.notifications.onButtonClicked, 'addListener', 0); 126 chrome.notifications.onButtonClicked, 'addListener', 0);
126 tasks.instrumentApiFunction(chrome.notifications.onClicked, 'addListener', 0); 127 tasks.instrumentApiFunction(chrome.notifications.onClicked, 'addListener', 0);
127 tasks.instrumentApiFunction(chrome.notifications.onClosed, 'addListener', 0); 128 tasks.instrumentApiFunction(chrome.notifications.onClosed, 'addListener', 0);
128 tasks.instrumentApiFunction(chrome.runtime.onInstalled, 'addListener', 0); 129 tasks.instrumentApiFunction(chrome.runtime.onInstalled, 'addListener', 0);
129 tasks.instrumentApiFunction(chrome.runtime.onStartup, 'addListener', 0); 130 tasks.instrumentApiFunction(chrome.runtime.onStartup, 'addListener', 0);
130 tasks.instrumentApiFunction(chrome.tabs, 'create', 1); 131 tasks.instrumentApiFunction(chrome.tabs, 'create', 1);
131 tasks.instrumentApiFunction(storage, 'get', 1); 132 tasks.instrumentApiFunction(storage, 'get', 1);
132 133
133 var updateCardsAttempts = buildAttemptManager( 134 var updateCardsAttempts = buildAttemptManager(
134 'cards-update', 135 'cards-update',
135 requestLocation, 136 requestLocation,
136 INITIAL_POLLING_PERIOD_SECONDS, 137 INITIAL_POLLING_PERIOD_SECONDS,
137 MAXIMUM_POLLING_PERIOD_SECONDS); 138 MAXIMUM_POLLING_PERIOD_SECONDS);
138 var dismissalAttempts = buildAttemptManager( 139 var dismissalAttempts = buildAttemptManager(
139 'dismiss', 140 'dismiss',
140 retryPendingDismissals, 141 retryPendingDismissals,
141 INITIAL_RETRY_DISMISS_PERIOD_SECONDS, 142 INITIAL_RETRY_DISMISS_PERIOD_SECONDS,
142 MAXIMUM_RETRY_DISMISS_PERIOD_SECONDS); 143 MAXIMUM_RETRY_DISMISS_PERIOD_SECONDS);
144 var cardSet = buildCardManager();
143 145
144 /** 146 /**
145 * Diagnostic event identifier. 147 * Diagnostic event identifier.
146 * @enum {number} 148 * @enum {number}
147 */ 149 */
148 var DiagnosticEvent = { 150 var DiagnosticEvent = {
149 REQUEST_FOR_CARDS_TOTAL: 0, 151 REQUEST_FOR_CARDS_TOTAL: 0,
150 REQUEST_FOR_CARDS_SUCCESS: 1, 152 REQUEST_FOR_CARDS_SUCCESS: 1,
151 CARDS_PARSE_SUCCESS: 2, 153 CARDS_PARSE_SUCCESS: 2,
152 DISMISS_REQUEST_TOTAL: 3, 154 DISMISS_REQUEST_TOTAL: 3,
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 } else { 212 } else {
211 originalOnLoadEnd(event); 213 originalOnLoadEnd(event);
212 } 214 }
213 }); 215 });
214 216
215 callbackBoolean(true); 217 callbackBoolean(true);
216 }); 218 });
217 } 219 }
218 220
219 /** 221 /**
220 * Shows a notification and remembers information associated with it.
221 * @param {Object} card Google Now card represented as a set of parameters for
222 * showing a Chrome notification.
223 * @param {Object} notificationsData Map from notification id to the data
224 * associated with a notification.
225 * @param {number=} opt_previousVersion The version of the shown card with this
226 * id, if it exists, undefined otherwise.
227 */
228 function showNotification(card, notificationsData, opt_previousVersion) {
229 console.log('showNotification ' + JSON.stringify(card) + ' ' +
230 opt_previousVersion);
231
232 if (typeof card.version != 'number') {
233 console.error('card.version is not a number');
234 // Fix card version.
235 card.version = opt_previousVersion !== undefined ? opt_previousVersion : 0;
236 }
237
238 if (opt_previousVersion !== card.version) {
239 try {
240 // Delete a notification with the specified id if it already exists, and
241 // then create a notification.
242 chrome.notifications.create(
243 card.notificationId,
244 card.notification,
245 function(notificationId) {
246 if (!notificationId || chrome.runtime.lastError) {
247 var errorMessage =
248 chrome.runtime.lastError && chrome.runtime.lastError.message;
249 console.error('notifications.create: ID=' + notificationId +
250 ', ERROR=' + errorMessage);
251 }
252 });
253 } catch (error) {
254 console.error('Error in notifications.create: ' + error);
255 }
256 } else {
257 try {
258 // Update existing notification.
259 chrome.notifications.update(
260 card.notificationId,
261 card.notification,
262 function(wasUpdated) {
263 if (!wasUpdated || chrome.runtime.lastError) {
264 var errorMessage =
265 chrome.runtime.lastError && chrome.runtime.lastError.message;
266 console.error('notifications.update: UPDATED=' + wasUpdated +
267 ', ERROR=' + errorMessage);
268 }
269 });
270 } catch (error) {
271 console.error('Error in notifications.update: ' + error);
272 }
273 }
274
275 notificationsData[card.notificationId] = {
276 actionUrls: card.actionUrls,
277 version: card.version
278 };
279 }
280
281 /**
282 * Parses JSON response from the notification server, show notifications and 222 * Parses JSON response from the notification server, show notifications and
283 * schedule next update. 223 * schedule next update.
284 * @param {string} response Server response. 224 * @param {string} response Server response.
285 * @param {function()} callback Completion callback. 225 * @param {function()} callback Completion callback.
286 */ 226 */
287 function parseAndShowNotificationCards(response, callback) { 227 function parseAndShowNotificationCards(response, callback) {
288 console.log('parseAndShowNotificationCards ' + response); 228 console.log('parseAndShowNotificationCards ' + response);
289 try { 229 try {
290 var parsedResponse = JSON.parse(response); 230 var parsedResponse = JSON.parse(response);
291 } catch (error) { 231 } catch (error) {
292 console.error('parseAndShowNotificationCards parse error: ' + error); 232 console.error('parseAndShowNotificationCards parse error: ' + error);
293 callback(); 233 callback();
294 return; 234 return;
295 } 235 }
296 236
297 var cards = parsedResponse.cards; 237 var cards = parsedResponse.cards;
298 238
299 if (!(cards instanceof Array)) { 239 if (!(cards instanceof Array)) {
300 callback(); 240 callback();
301 return; 241 return;
302 } 242 }
303 243
304 if (typeof parsedResponse.expiration_timestamp_seconds != 'number') { 244 if (typeof parsedResponse.expiration_timestamp_seconds != 'number') {
rgustafson 2013/07/22 17:48:07 Can we change expiration_timestamp_seconds to next
vadimt 2013/07/22 19:22:52 Done.
305 callback(); 245 callback();
306 return; 246 return;
307 } 247 }
308 248
309 tasks.debugSetStepName('parseAndShowNotificationCards-storage-get'); 249 tasks.debugSetStepName('parseAndShowNotificationCards-storage-get');
310 storage.get(['notificationsData', 'recentDismissals'], function(items) { 250 storage.get(['notificationsData', 'recentDismissals'], function(items) {
311 console.log('parseAndShowNotificationCards-get ' + JSON.stringify(items)); 251 console.log('parseAndShowNotificationCards-get ' + JSON.stringify(items));
312 items.notificationsData = items.notificationsData || {}; 252 items.notificationsData = items.notificationsData || {};
313 items.recentDismissals = items.recentDismissals || {}; 253 items.recentDismissals = items.recentDismissals || {};
314 254
315 tasks.debugSetStepName( 255 tasks.debugSetStepName(
316 'parseAndShowNotificationCards-notifications-getAll'); 256 'parseAndShowNotificationCards-notifications-getAll');
317 chrome.notifications.getAll(function(notifications) { 257 chrome.notifications.getAll(function(notifications) {
318 console.log('parseAndShowNotificationCards-getAll ' + 258 console.log('parseAndShowNotificationCards-getAll ' +
319 JSON.stringify(notifications)); 259 JSON.stringify(notifications));
320 // TODO(vadimt): Figure out what to do when notifications are disabled for 260 // TODO(vadimt): Figure out what to do when notifications are disabled for
rgustafson 2013/07/19 23:37:12 Why was this un-tabbed? It should be on the level
vadimt 2013/07/22 19:22:52 Done. I probably need to see my doctor.
321 // our extension. 261 // our extension.
322 notifications = notifications || {}; 262 notifications = notifications || {};
323 263
324 // Build a set of non-expired recent dismissals. It will be used for 264 // Build a set of non-expired recent dismissals. It will be used for
325 // client-side filtering of cards. 265 // client-side filtering of cards.
326 var updatedRecentDismissals = {}; 266 var updatedRecentDismissals = {};
327 var currentTimeMs = Date.now(); 267 var currentTimeMs = Date.now();
328 for (var notificationId in items.recentDismissals) { 268 for (var notificationId in items.recentDismissals) {
329 if (currentTimeMs - items.recentDismissals[notificationId] < 269 if (currentTimeMs - items.recentDismissals[notificationId] <
330 DISMISS_RETENTION_TIME_MS) { 270 DISMISS_RETENTION_TIME_MS) {
331 updatedRecentDismissals[notificationId] = 271 updatedRecentDismissals[notificationId] =
332 items.recentDismissals[notificationId]; 272 items.recentDismissals[notificationId];
(...skipping 11 matching lines...) Expand all
344 updatedNotifications[notificationId] = true; 284 updatedNotifications[notificationId] = true;
345 } 285 }
346 } 286 }
347 287
348 // Delete notifications that didn't receive an update. 288 // Delete notifications that didn't receive an update.
349 for (var notificationId in notifications) { 289 for (var notificationId in notifications) {
350 console.log('parseAndShowNotificationCards-delete-check ' + 290 console.log('parseAndShowNotificationCards-delete-check ' +
351 notificationId); 291 notificationId);
352 if (!(notificationId in updatedNotifications)) { 292 if (!(notificationId in updatedNotifications)) {
353 console.log('parseAndShowNotificationCards-delete ' + notificationId); 293 console.log('parseAndShowNotificationCards-delete ' + notificationId);
354 chrome.notifications.clear( 294 cardSet.clear(notificationId);
355 notificationId,
356 function() {});
357 } 295 }
358 } 296 }
359 297
360 recordEvent(DiagnosticEvent.CARDS_PARSE_SUCCESS); 298 recordEvent(DiagnosticEvent.CARDS_PARSE_SUCCESS);
361 299
362 // Create/update notifications and store their new properties. 300 // Create/update notifications and store their new properties.
363 var newNotificationsData = {}; 301 var newNotificationsData = {};
364 for (var i = 0; i < cards.length; ++i) { 302 for (var i = 0; i < cards.length; ++i) {
365 var card = cards[i]; 303 var card = cards[i];
366 if (!(card.notificationId in updatedRecentDismissals)) { 304 if (!(card.notificationId in updatedRecentDismissals)) {
367 var notificationData = items.notificationsData[card.notificationId]; 305 var notificationData = items.notificationsData[card.notificationId];
368 var previousVersion = notifications[card.notificationId] && 306 var previousVersion = notifications[card.notificationId] &&
369 notificationData && 307 notificationData &&
370 notificationData.previousVersion; 308 notificationData.cardCreateInfo &&
371 showNotification(card, newNotificationsData, previousVersion); 309 notificationData.cardCreateInfo.version;
310 newNotificationsData[card.notificationId] =
311 cardSet.update(card, previousVersion);
372 } 312 }
373 } 313 }
374 314
375 updateCardsAttempts.start(parsedResponse.expiration_timestamp_seconds); 315 updateCardsAttempts.start(parsedResponse.expiration_timestamp_seconds);
rgustafson 2013/07/22 17:48:07 expiration_timestamp_seconds to next_poll_seconds
vadimt 2013/07/22 19:22:52 Done.
376 316
377 storage.set({ 317 storage.set({
378 notificationsData: newNotificationsData, 318 notificationsData: newNotificationsData,
379 recentDismissals: updatedRecentDismissals 319 recentDismissals: updatedRecentDismissals
380 }); 320 });
381 callback(); 321 callback();
382 }); 322 });
383 }); 323 });
384 } 324 }
385 325
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 } 574 }
635 575
636 // At this point we are guaranteed that the notification is a now card. 576 // At this point we are guaranteed that the notification is a now card.
637 chrome.metricsPrivate.recordUserAction('GoogleNow.Dismissed'); 577 chrome.metricsPrivate.recordUserAction('GoogleNow.Dismissed');
638 578
639 tasks.add(DISMISS_CARD_TASK_NAME, function(callback) { 579 tasks.add(DISMISS_CARD_TASK_NAME, function(callback) {
640 dismissalAttempts.start(); 580 dismissalAttempts.start();
641 581
642 // Deleting the notification in case it was re-added while this task was 582 // Deleting the notification in case it was re-added while this task was
643 // scheduled, waiting for execution. 583 // scheduled, waiting for execution.
644 chrome.notifications.clear( 584 cardSet.clear(notificationId);
645 notificationId,
646 function() {});
647 585
648 tasks.debugSetStepName('onNotificationClosed-get-pendingDismissals'); 586 tasks.debugSetStepName('onNotificationClosed-get-pendingDismissals');
649 storage.get('pendingDismissals', function(items) { 587 storage.get('pendingDismissals', function(items) {
650 items.pendingDismissals = items.pendingDismissals || []; 588 items.pendingDismissals = items.pendingDismissals || [];
651 589
652 var dismissal = { 590 var dismissal = {
653 notificationId: notificationId, 591 notificationId: notificationId,
654 time: Date.now() 592 time: Date.now()
655 }; 593 };
656 items.pendingDismissals.push(dismissal); 594 items.pendingDismissals.push(dismissal);
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 696
759 chrome.location.onLocationUpdate.addListener(function(position) { 697 chrome.location.onLocationUpdate.addListener(function(position) {
760 recordEvent(DiagnosticEvent.LOCATION_UPDATE); 698 recordEvent(DiagnosticEvent.LOCATION_UPDATE);
761 updateNotificationsCards(position); 699 updateNotificationsCards(position);
762 }); 700 });
763 701
764 chrome.omnibox.onInputEntered.addListener(function(text) { 702 chrome.omnibox.onInputEntered.addListener(function(text) {
765 localStorage['server_url'] = NOTIFICATION_CARDS_URL = text; 703 localStorage['server_url'] = NOTIFICATION_CARDS_URL = text;
766 initialize(); 704 initialize();
767 }); 705 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698