Chromium Code Reviews| Index: chrome/browser/resources/google_now/background.js |
| diff --git a/chrome/browser/resources/google_now/background.js b/chrome/browser/resources/google_now/background.js |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..59d4f0719bb9d4f1b9ad404610acc9e158ee89d4 |
| --- /dev/null |
| +++ b/chrome/browser/resources/google_now/background.js |
| @@ -0,0 +1,159 @@ |
| +// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +/** |
| + * @fileoverview The event page for Google Now for Chrome implementation. |
| + * The Google Now event page gets Google Now cards from the server and shows |
| + * them as Chrome notifications. |
| + * The service performs periodic updating of Google Now cards. |
| + * Each updating of the cards includes 3 steps: |
| + * 1. Obtaining the location of the machine; |
| + * 2. Making a server request based on that location; |
| + * 3. Showing the received cards as notifications. |
| + */ |
| + |
| +// TODO(vadimt): Use background permission to show notifications even when all |
| +// browser windows are closed. |
| +// TODO(vadimt): Remove the C++ implementation. |
| +// TODO(vadimt): Decide what to do in incognito mode. |
| +// TODO(vadimt): Gather UMAs. |
| +// TODO(vadimt): Honor the flag the enables Google Now integration. |
| +// TODO(vadimt): Figure out the final values of the constants. |
| +// TODO(vadimt): Report errors to the user. |
| + |
| +// TODO(vadimt): Figure out the server name. Use it in the manifest and for |
| +// NOTIFICATION_CARDS_URL. Meanwhile, to use the feature, you need to manually |
| +// edit NOTIFICATION_CARDS_URL before building Chrome. |
| +/** |
| + * URL to retrieve notification cards. |
| + */ |
| +var NOTIFICATION_CARDS_URL = ''; |
| + |
| +/** |
| + * Standard response code for successful HTTP requests. This is the only success |
| + * code the server will send. |
| + */ |
| +var HTTP_OK = 200; |
| + |
| +/** |
| + * Period for polling for Google Now Notifications cards to use when the period |
| + * from the server is not available. |
| + */ |
| +var DEFAULT_POLLING_PERIOD_SECONDS = 300; // 5 minutes |
| + |
| +/** |
| + * Parse JSON response of the notifications server, show notifications and |
| + * schedule next update. |
| + * @param {string} response Server response. |
| + */ |
| +function ParseAndShowNotificationCards(response) { |
| + try { |
| + var parsedResponse = JSON.parse(response); |
| + } catch (error) { |
| + return; |
| + } |
| + |
| + var cards = parsedResponse.cards; |
| + |
| + if (!(cards instanceof Array)) |
| + return; |
| + |
| + if (typeof parsedResponse.expiration_timestamp_seconds != 'number') |
|
rgustafson
2013/01/22 21:10:28
If the timestamp isn't present, it should still di
vadimt
2013/01/23 03:04:05
The fact that the timestamp is not present most li
rgustafson
2013/01/23 23:18:56
I'd prefer to give the user everything we have, an
|
| + return; |
| + |
| + for (var i = 0; i != cards.length; ++i) { |
| + try { |
| + chrome.experimental.notification.show(cards[i], function(showInfo) {}); |
| + } catch (error) { |
| + return; |
| + } |
| + } |
| + |
| + ScheduleNextUpdate(parsedResponse.expiration_timestamp_seconds); |
| +} |
| + |
| +/** |
| + * Request notification cards from the server. |
| + * @param {string} requestParameters Query string for the request. |
| + */ |
| +function RequestNotificationCards(requestParameters) { |
| + // TODO(vadimt): Figure out how to send user's identity to the server. |
| + var request = new XMLHttpRequest(); |
| + request.onreadystatechange = function(event) { |
| + if (request.readyState == request.DONE && request.status == HTTP_OK) |
| + ParseAndShowNotificationCards(request.response); |
| + } |
| + request.open('GET', NOTIFICATION_CARDS_URL + requestParameters, true); |
| + request.send(); |
| +} |
| + |
| +/** |
| + * Request notification cards from the server when we have geolocation. |
| + * @param {Geoposition} position Location of this computer. |
| + */ |
| +function RequestNotificationCardsWithLocation(position) { |
| + // TODO(vadimt): Should we use 'q' as the parameter name? |
| + var requestParameters = |
| + '?q=' + position.coords.latitude + |
| + ',' + position.coords.longitude + |
| + ',' + position.coords.accuracy; |
| + |
| + RequestNotificationCards(requestParameters); |
| +} |
| + |
| +/** |
| + * Request notification cards from the server when we don't have geolocation. |
| + * @param {PositionError} positionError Position error. |
| + */ |
| +function RequestNotificationCardsWithoutLocation(positionError) { |
| + RequestNotificationCards(''); |
| +} |
| + |
| +/** |
| + * Obtain new location; request and show notification cards based on this |
| + * location. |
| + */ |
| +function UpdateNotificationsCards() { |
| + // Immediately schedule the update after the default period. If we |
| + // successfully retrieve, parse and show the notifications cards, we'll |
| + // schedule next update based on the expiration timestamp received from the |
| + // server. At that point scheduled time will be overwritten by the new one |
| + // based on the expiration timestamp. |
| + // TODO(vadimt): Implement exponential backoff with randomized jitter. |
| + ScheduleNextUpdate(DEFAULT_POLLING_PERIOD_SECONDS); |
| + |
| + // TODO(vadimt): Use chrome.* geolocation API once it's ready. |
| + navigator.geolocation.getCurrentPosition( |
| + RequestNotificationCardsWithLocation, |
| + RequestNotificationCardsWithoutLocation); |
| +} |
| + |
| +/** |
| + * Schedule next update for notification cards. |
| + * @param {int} delaySeconds Length of time in seconds after which the alarm |
| + * event should fire. |
| + */ |
| +function ScheduleNextUpdate(delaySeconds) { |
| + chrome.alarms.create({ when: Date.now() + delaySeconds * 1000 }); |
| +} |
| + |
| +/** |
| + * Initialize the event page on install or on browser startup. |
| + */ |
| +function Initialize() { |
| + UpdateNotificationsCards(); |
| +} |
| + |
| +chrome.runtime.onInstalled.addListener(function(details) { |
| + if (details.reason != 'chrome_update') |
| + Initialize(); |
| +}); |
| + |
| +chrome.runtime.onStartup.addListener(function() { |
| + Initialize(); |
| +}); |
| + |
| +chrome.alarms.onAlarm.addListener(function(alarm) { |
| + UpdateNotificationsCards(); |
| +}); |