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

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

Issue 15868004: Using notifications.getAll (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: estade@'s comments Created 7 years, 6 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
« 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'; TODO(vadimt): Uncomment once crbug.com/237617 is fixed. 5 // 'use strict'; TODO(vadimt): Uncomment once crbug.com/237617 is fixed.
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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 /** 57 /**
58 * Time we keep dismissals after successful server dismiss requests. 58 * Time we keep dismissals after successful server dismiss requests.
59 */ 59 */
60 var DISMISS_RETENTION_TIME_MS = 20 * 60 * 1000; // 20 minutes 60 var DISMISS_RETENTION_TIME_MS = 20 * 60 * 1000; // 20 minutes
61 61
62 /** 62 /**
63 * Names for tasks that can be created by the extension. 63 * Names for tasks that can be created by the extension.
64 */ 64 */
65 var UPDATE_CARDS_TASK_NAME = 'update-cards'; 65 var UPDATE_CARDS_TASK_NAME = 'update-cards';
66 var DISMISS_CARD_TASK_NAME = 'dismiss-card'; 66 var DISMISS_CARD_TASK_NAME = 'dismiss-card';
67 var CARD_CLICKED_TASK_NAME = 'card-clicked';
68 var RETRY_DISMISS_TASK_NAME = 'retry-dismiss'; 67 var RETRY_DISMISS_TASK_NAME = 'retry-dismiss';
69 68
70 var LOCATION_WATCH_NAME = 'location-watch'; 69 var LOCATION_WATCH_NAME = 'location-watch';
71 70
72 /** 71 /**
73 * Checks if a new task can't be scheduled when another task is already 72 * Checks if a new task can't be scheduled when another task is already
74 * scheduled. 73 * scheduled.
75 * @param {string} newTaskName Name of the new task. 74 * @param {string} newTaskName Name of the new task.
76 * @param {string} scheduledTaskName Name of the scheduled task. 75 * @param {string} scheduledTaskName Name of the scheduled task.
77 * @return {boolean} Whether the new task conflicts with the existing task. 76 * @return {boolean} Whether the new task conflicts with the existing task.
(...skipping 17 matching lines...) Expand all
95 94
96 return false; 95 return false;
97 } 96 }
98 97
99 var tasks = buildTaskManager(areTasksConflicting); 98 var tasks = buildTaskManager(areTasksConflicting);
100 99
101 // Add error processing to API calls. 100 // Add error processing to API calls.
102 tasks.instrumentApiFunction(chrome.location.onLocationUpdate, 'addListener', 0); 101 tasks.instrumentApiFunction(chrome.location.onLocationUpdate, 'addListener', 0);
103 tasks.instrumentApiFunction(chrome.notifications, 'create', 2); 102 tasks.instrumentApiFunction(chrome.notifications, 'create', 2);
104 tasks.instrumentApiFunction(chrome.notifications, 'update', 2); 103 tasks.instrumentApiFunction(chrome.notifications, 'update', 2);
104 tasks.instrumentApiFunction(chrome.notifications, 'getAll', 0);
105 tasks.instrumentApiFunction( 105 tasks.instrumentApiFunction(
106 chrome.notifications.onButtonClicked, 'addListener', 0); 106 chrome.notifications.onButtonClicked, 'addListener', 0);
107 tasks.instrumentApiFunction(chrome.notifications.onClicked, 'addListener', 0); 107 tasks.instrumentApiFunction(chrome.notifications.onClicked, 'addListener', 0);
108 tasks.instrumentApiFunction(chrome.notifications.onClosed, 'addListener', 0); 108 tasks.instrumentApiFunction(chrome.notifications.onClosed, 'addListener', 0);
109 tasks.instrumentApiFunction(chrome.runtime.onInstalled, 'addListener', 0); 109 tasks.instrumentApiFunction(chrome.runtime.onInstalled, 'addListener', 0);
110 tasks.instrumentApiFunction(chrome.runtime.onStartup, 'addListener', 0); 110 tasks.instrumentApiFunction(chrome.runtime.onStartup, 'addListener', 0);
111 tasks.instrumentApiFunction(chrome.tabs, 'create', 1); 111 tasks.instrumentApiFunction(chrome.tabs, 'create', 1);
112 tasks.instrumentApiFunction(storage, 'get', 1); 112 tasks.instrumentApiFunction(storage, 'get', 1);
113 113
114 var updateCardsAttempts = buildAttemptManager( 114 var updateCardsAttempts = buildAttemptManager(
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 153
154 chrome.metricsPrivate.recordValue(metricDescription, event); 154 chrome.metricsPrivate.recordValue(metricDescription, event);
155 } 155 }
156 156
157 /** 157 /**
158 * Shows a notification and remembers information associated with it. 158 * Shows a notification and remembers information associated with it.
159 * @param {Object} card Google Now card represented as a set of parameters for 159 * @param {Object} card Google Now card represented as a set of parameters for
160 * showing a Chrome notification. 160 * showing a Chrome notification.
161 * @param {Object} notificationsData Map from notification id to the data 161 * @param {Object} notificationsData Map from notification id to the data
162 * associated with a notification. 162 * associated with a notification.
163 * @param {number} previousVersion The version of the shown card with this id, 163 * @param {number=} opt_previousVersion The version of the shown card with this
164 * if it exists, undefined otherwise. 164 * id, if it exists, undefined otherwise.
165 */ 165 */
166 function showNotification(card, notificationsData, previousVersion) { 166 function showNotification(card, notificationsData, opt_previousVersion) {
167 console.log('showNotification ' + JSON.stringify(card) + ' ' + 167 console.log('showNotification ' + JSON.stringify(card) + ' ' +
168 previousVersion); 168 opt_previousVersion);
169 169
170 if (typeof card.version != 'number') { 170 if (typeof card.version != 'number') {
171 console.error('card.version is not a number'); 171 console.error('card.version is not a number');
172 // Fix card version. 172 // Fix card version.
173 card.version = previousVersion !== undefined ? previousVersion : 0; 173 card.version = opt_previousVersion !== undefined ? opt_previousVersion : 0;
174 } 174 }
175 175
176 if (previousVersion !== card.version) { 176 if (opt_previousVersion !== card.version) {
177 try { 177 try {
178 // Delete a notification with the specified id if it already exists, and 178 // Delete a notification with the specified id if it already exists, and
179 // then create a notification. 179 // then create a notification.
180 chrome.notifications.create( 180 chrome.notifications.create(
181 card.notificationId, 181 card.notificationId,
182 card.notification, 182 card.notification,
183 function(notificationId) { 183 function(notificationId) {
184 if (!notificationId || chrome.runtime.lastError) { 184 if (!notificationId || chrome.runtime.lastError) {
185 var errorMessage = 185 var errorMessage =
186 chrome.runtime.lastError && chrome.runtime.lastError.message; 186 chrome.runtime.lastError && chrome.runtime.lastError.message;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 callback(); 238 callback();
239 return; 239 return;
240 } 240 }
241 241
242 if (typeof parsedResponse.expiration_timestamp_seconds != 'number') { 242 if (typeof parsedResponse.expiration_timestamp_seconds != 'number') {
243 callback(); 243 callback();
244 return; 244 return;
245 } 245 }
246 246
247 tasks.debugSetStepName('parseAndShowNotificationCards-storage-get'); 247 tasks.debugSetStepName('parseAndShowNotificationCards-storage-get');
248 storage.get(['activeNotifications', 'recentDismissals'], function(items) { 248 storage.get(['notificationsData', 'recentDismissals'], function(items) {
249 console.log('parseAndShowNotificationCards-get ' + JSON.stringify(items)); 249 console.log('parseAndShowNotificationCards-get ' + JSON.stringify(items));
250 items.activeNotifications = items.activeNotifications || {}; 250 items.notificationsData = items.notificationsData || {};
251 items.recentDismissals = items.recentDismissals || {}; 251 items.recentDismissals = items.recentDismissals || {};
252 252
253 // Build a set of non-expired recent dismissals. It will be used for 253 tasks.debugSetStepName(
254 // client-side filtering of cards. 254 'parseAndShowNotificationCards-notifications-getAll');
255 var updatedRecentDismissals = {}; 255 chrome.notifications.getAll(function(notifications) {
256 var currentTimeMs = Date.now(); 256 console.log('parseAndShowNotificationCards-getAll ' +
257 for (var notificationId in items.recentDismissals) { 257 JSON.stringify(notifications));
258 if (currentTimeMs - items.recentDismissals[notificationId] < 258 // Build a set of non-expired recent dismissals. It will be used for
259 DISMISS_RETENTION_TIME_MS) { 259 // client-side filtering of cards.
260 updatedRecentDismissals[notificationId] = 260 var updatedRecentDismissals = {};
261 items.recentDismissals[notificationId]; 261 var currentTimeMs = Date.now();
262 for (var notificationId in items.recentDismissals) {
263 if (currentTimeMs - items.recentDismissals[notificationId] <
264 DISMISS_RETENTION_TIME_MS) {
265 updatedRecentDismissals[notificationId] =
266 items.recentDismissals[notificationId];
267 }
262 } 268 }
263 }
264 269
265 // Mark existing notifications that received an update in this server 270 // Mark existing notifications that received an update in this server
266 // response. 271 // response.
267 for (var i = 0; i < cards.length; ++i) { 272 var updatedNotifications = {};
268 var notificationId = cards[i].notificationId; 273
269 if (!(notificationId in updatedRecentDismissals) && 274 for (var i = 0; i < cards.length; ++i) {
270 notificationId in items.activeNotifications) { 275 var notificationId = cards[i].notificationId;
271 items.activeNotifications[notificationId].hasUpdate = true; 276 if (!(notificationId in updatedRecentDismissals) &&
277 notificationId in notifications) {
278 updatedNotifications[notificationId] = true;
279 }
272 } 280 }
273 }
274 281
275 // Delete notifications that didn't receive an update. 282 // Delete notifications that didn't receive an update.
276 for (var notificationId in items.activeNotifications) { 283 for (var notificationId in notifications) {
277 console.log('parseAndShowNotificationCards-delete-check ' + 284 console.log('parseAndShowNotificationCards-delete-check ' +
278 notificationId); 285 notificationId);
279 if (!items.activeNotifications[notificationId].hasUpdate) { 286 if (!(notificationId in updatedNotifications)) {
280 console.log('parseAndShowNotificationCards-delete ' + notificationId); 287 console.log('parseAndShowNotificationCards-delete ' + notificationId);
281 chrome.notifications.clear( 288 chrome.notifications.clear(
282 notificationId, 289 notificationId,
283 function() {}); 290 function() {});
291 }
284 } 292 }
285 }
286 293
287 recordEvent(DiagnosticEvent.CARDS_PARSE_SUCCESS); 294 recordEvent(DiagnosticEvent.CARDS_PARSE_SUCCESS);
288 295
289 // Create/update notifications and store their new properties. 296 // Create/update notifications and store their new properties.
290 var notificationsData = {}; 297 var newNotificationsData = {};
291 for (var i = 0; i < cards.length; ++i) { 298 for (var i = 0; i < cards.length; ++i) {
292 var card = cards[i]; 299 var card = cards[i];
293 if (!(card.notificationId in updatedRecentDismissals)) { 300 if (!(card.notificationId in updatedRecentDismissals)) {
294 var activeNotification = items.activeNotifications[card.notificationId]; 301 var notificationData = items.notificationsData[card.notificationId];
295 showNotification(card, 302 var previousVersion = notifications[card.notificationId] &&
296 notificationsData, 303 notificationData &&
297 activeNotification && activeNotification.version); 304 notificationData.previousVersion;
305 showNotification(card, newNotificationsData, previousVersion);
306 }
298 } 307 }
299 }
300 308
301 updateCardsAttempts.start(parsedResponse.expiration_timestamp_seconds); 309 updateCardsAttempts.start(parsedResponse.expiration_timestamp_seconds);
302 310
303 storage.set({ 311 storage.set({
304 activeNotifications: notificationsData, 312 notificationsData: newNotificationsData,
305 recentDismissals: updatedRecentDismissals 313 recentDismissals: updatedRecentDismissals
314 });
315 callback();
306 }); 316 });
307 callback();
308 }); 317 });
309 } 318 }
310 319
311 /** 320 /**
312 * Requests notification cards from the server. 321 * Requests notification cards from the server.
313 * @param {Location} position Location of this computer. 322 * @param {Location} position Location of this computer.
314 * @param {function()} callback Completion callback. 323 * @param {function()} callback Completion callback.
315 */ 324 */
316 function requestNotificationCards(position, callback) { 325 function requestNotificationCards(position, callback) {
317 console.log('requestNotificationCards ' + JSON.stringify(position) + 326 console.log('requestNotificationCards ' + JSON.stringify(position) +
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 }); 482 });
474 } 483 }
475 484
476 /** 485 /**
477 * Opens URL corresponding to the clicked part of the notification. 486 * Opens URL corresponding to the clicked part of the notification.
478 * @param {string} notificationId Unique identifier of the notification. 487 * @param {string} notificationId Unique identifier of the notification.
479 * @param {function(Object): string} selector Function that extracts the url for 488 * @param {function(Object): string} selector Function that extracts the url for
480 * the clicked area from the button action URLs info. 489 * the clicked area from the button action URLs info.
481 */ 490 */
482 function onNotificationClicked(notificationId, selector) { 491 function onNotificationClicked(notificationId, selector) {
483 tasks.add(CARD_CLICKED_TASK_NAME, function(callback) { 492 storage.get('notificationsData', function(items) {
484 tasks.debugSetStepName('onNotificationClicked-get-activeNotifications'); 493 items.notificationsData = items.notificationsData || {};
485 storage.get('activeNotifications', function(items) {
486 items.activeNotifications = items.activeNotifications || {};
487 494
488 var actionUrls = items.activeNotifications[notificationId].actionUrls; 495 var notificationData = items.notificationsData[notificationId];
489 if (typeof actionUrls != 'object') {
490 callback();
491 return;
492 }
493 496
494 var url = selector(actionUrls); 497 if (!notificationData) {
498 // 'notificationsData' in storage may not match the actual list of
499 // notifications.
500 return;
501 }
495 502
496 if (typeof url != 'string') { 503 var actionUrls = notificationData.actionUrls;
497 callback(); 504 if (typeof actionUrls != 'object') {
498 return; 505 return;
499 } 506 }
500 507
501 chrome.tabs.create({url: url}, function(tab) { 508 var url = selector(actionUrls);
502 if (!tab) 509
503 chrome.windows.create({url: url}); 510 if (typeof url != 'string')
504 }); 511 return;
505 callback(); 512
513 chrome.tabs.create({url: url}, function(tab) {
514 if (!tab)
515 chrome.windows.create({url: url});
506 }); 516 });
507 }); 517 });
508 } 518 }
509 519
510 /** 520 /**
511 * Callback for chrome.notifications.onClosed event. 521 * Callback for chrome.notifications.onClosed event.
512 * @param {string} notificationId Unique identifier of the notification. 522 * @param {string} notificationId Unique identifier of the notification.
513 * @param {boolean} byUser Whether the notification was closed by the user. 523 * @param {boolean} byUser Whether the notification was closed by the user.
514 */ 524 */
515 function onNotificationClosed(notificationId, byUser) { 525 function onNotificationClosed(notificationId, byUser) {
(...skipping 27 matching lines...) Expand all
543 } 553 }
544 554
545 /** 555 /**
546 * Initializes the event page on install or on browser startup. 556 * Initializes the event page on install or on browser startup.
547 */ 557 */
548 function initialize() { 558 function initialize() {
549 // Create an update timer for a case when for some reason location request 559 // Create an update timer for a case when for some reason location request
550 // gets stuck. 560 // gets stuck.
551 updateCardsAttempts.start(MAXIMUM_POLLING_PERIOD_SECONDS); 561 updateCardsAttempts.start(MAXIMUM_POLLING_PERIOD_SECONDS);
552 562
553 var initialStorage = {
554 activeNotifications: {}
555 };
556 storage.set(initialStorage);
557
558 requestLocation(); 563 requestLocation();
559 } 564 }
560 565
561 chrome.runtime.onInstalled.addListener(function(details) { 566 chrome.runtime.onInstalled.addListener(function(details) {
562 console.log('onInstalled ' + JSON.stringify(details)); 567 console.log('onInstalled ' + JSON.stringify(details));
563 if (details.reason != 'chrome_update') { 568 if (details.reason != 'chrome_update') {
564 initialize(); 569 initialize();
565 } 570 }
566 }); 571 });
567 572
(...skipping 26 matching lines...) Expand all
594 599
595 chrome.location.onLocationUpdate.addListener(function(position) { 600 chrome.location.onLocationUpdate.addListener(function(position) {
596 recordEvent(DiagnosticEvent.LOCATION_UPDATE); 601 recordEvent(DiagnosticEvent.LOCATION_UPDATE);
597 updateNotificationsCards(position); 602 updateNotificationsCards(position);
598 }); 603 });
599 604
600 chrome.omnibox.onInputEntered.addListener(function(text) { 605 chrome.omnibox.onInputEntered.addListener(function(text) {
601 localStorage['server_url'] = NOTIFICATION_CARDS_URL = text; 606 localStorage['server_url'] = NOTIFICATION_CARDS_URL = text;
602 initialize(); 607 initialize();
603 }); 608 });
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