| 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
|
| index 2646154d2185a78e844486cf684ae670b7880fea..f55be5d556f5081c63145eb908d5a7def164b2a2 100644
|
| --- a/chrome/browser/resources/google_now/background.js
|
| +++ b/chrome/browser/resources/google_now/background.js
|
| @@ -1,309 +1,369 @@
|
| -// 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.
|
| -
|
| -'use strict';
|
| -
|
| -/**
|
| - * @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 internal and server errors. Collect UMAs on errors where
|
| -// appropriate. Also consider logging errors or throwing exceptions.
|
| -
|
| -// TODO(vadimt): Consider processing errors for all storage.set calls.
|
| -// 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
|
| -// set the server name via local storage.
|
| -/**
|
| - * URL to retrieve notification cards.
|
| - */
|
| -var NOTIFICATION_CARDS_URL = localStorage['server_url'];
|
| -
|
| -/**
|
| - * Standard response code for successful HTTP requests. This is the only success
|
| - * code the server will send.
|
| - */
|
| -var HTTP_OK = 200;
|
| -
|
| -/**
|
| - * Initial period for polling for Google Now Notifications cards to use when the
|
| - * period from the server is not available.
|
| - */
|
| -var INITIAL_POLLING_PERIOD_SECONDS = 300; // 5 minutes
|
| -
|
| -/**
|
| - * Maximal period for polling for Google Now Notifications cards to use when the
|
| - * period from the server is not available.
|
| - */
|
| -var MAXIMUM_POLLING_PERIOD_SECONDS = 3600; // 1 hour
|
| -
|
| -var storage = chrome.storage.local;
|
| -
|
| -/**
|
| - * Show a notification and remember information associated with it.
|
| - * @param {Object} card Google Now card represented as a set of parameters for
|
| - * showing a Chrome notification.
|
| - * @param {Object} notificationsUrlInfo Map from notification id to the
|
| - * notification's set of URLs.
|
| - */
|
| -function createNotification(card, notificationsUrlInfo) {
|
| - // Create a notification or quietly update if it already exists.
|
| - // TODO(vadimt): Implement non-quiet updates.
|
| - chrome.notifications.create(
|
| - card.notificationId,
|
| - card.notification,
|
| - function(assignedNotificationId) {});
|
| -
|
| - notificationsUrlInfo[card.notificationId] = card.actionUrls;
|
| -}
|
| -
|
| -/**
|
| - * Parse JSON response from the notification server, show notifications and
|
| - * schedule next update.
|
| - * @param {string} response Server response.
|
| - */
|
| -function parseAndShowNotificationCards(response) {
|
| - try {
|
| - var parsedResponse = JSON.parse(response);
|
| - } catch (error) {
|
| - // TODO(vadimt): Report errors to the user.
|
| - return;
|
| - }
|
| -
|
| - var cards = parsedResponse.cards;
|
| -
|
| - if (!(cards instanceof Array)) {
|
| - // TODO(vadimt): Report errors to the user.
|
| - return;
|
| - }
|
| -
|
| - if (typeof parsedResponse.expiration_timestamp_seconds != 'number') {
|
| - // TODO(vadimt): Report errors to the user.
|
| - return;
|
| - }
|
| -
|
| - storage.get('activeNotifications', function(items) {
|
| - // Mark existing notifications that received an update in this server
|
| - // response.
|
| - for (var i = 0; i < cards.length; ++i) {
|
| - var notificationId = cards[i].notificationId;
|
| - if (notificationId in items.activeNotifications)
|
| - items.activeNotifications[notificationId].hasUpdate = true;
|
| - }
|
| -
|
| - // Delete notifications that didn't receive an update.
|
| - for (var notificationId in items.activeNotifications)
|
| - if (!items.activeNotifications[notificationId].hasUpdate) {
|
| - chrome.notifications.clear(
|
| - notificationId,
|
| - function(wasDeleted) {});
|
| - }
|
| -
|
| - // Create/update notifications and store their new properties.
|
| - var notificationsUrlInfo = {};
|
| -
|
| - for (var i = 0; i < cards.length; ++i) {
|
| - try {
|
| - createNotification(cards[i], notificationsUrlInfo);
|
| - } catch (error) {
|
| - // TODO(vadimt): Report errors to the user.
|
| - }
|
| - }
|
| - storage.set({activeNotifications: notificationsUrlInfo});
|
| -
|
| - scheduleNextUpdate(parsedResponse.expiration_timestamp_seconds);
|
| -
|
| - // Now that we got a valid response from the server, reset the retry period
|
| - // to the initial value. This retry period will be used the next time we
|
| - // fail to get the server-provided period.
|
| - storage.set({retryDelaySeconds: INITIAL_POLLING_PERIOD_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.responseType = 'text';
|
| - request.onload = function(event) {
|
| - if (request.status == HTTP_OK)
|
| - parseAndShowNotificationCards(request.response);
|
| - }
|
| -
|
| - request.open(
|
| - 'GET',
|
| - NOTIFICATION_CARDS_URL + '/notifications' + 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() {
|
| - storage.get('retryDelaySeconds', function(items) {
|
| - // Immediately schedule the update after the current retry period. Then,
|
| - // we'll use update time from the server if available.
|
| - scheduleNextUpdate(items.retryDelaySeconds);
|
| -
|
| - // TODO(vadimt): Consider interrupting waiting for the next update if we
|
| - // detect that the network conditions have changed. Also, decide whether the
|
| - // exponential backoff is needed both when we are offline and when there are
|
| - // failures on the server side.
|
| - var newRetryDelaySeconds =
|
| - Math.min(items.retryDelaySeconds * 2 * (1 + 0.2 * Math.random()),
|
| - MAXIMUM_POLLING_PERIOD_SECONDS);
|
| - storage.set({retryDelaySeconds: newRetryDelaySeconds});
|
| -
|
| - navigator.geolocation.getCurrentPosition(
|
| - requestNotificationCardsWithLocation,
|
| - requestNotificationCardsWithoutLocation);
|
| - });
|
| -}
|
| -
|
| -/**
|
| - * Opens URL corresponding to the clicked part of the notification.
|
| - * @param {string} notificationId Unique identifier of the notification.
|
| - * @param {function(Object): string} selector Function that extracts the url for
|
| - * the clicked area from the button action URLs info.
|
| - */
|
| -function onNotificationClicked(notificationId, selector) {
|
| - storage.get('activeNotifications', function(items) {
|
| - var actionUrls = items.activeNotifications[notificationId];
|
| - if (typeof actionUrls != 'object') {
|
| - // TODO(vadimt): report an error.
|
| - return;
|
| - }
|
| -
|
| - var url = selector(actionUrls);
|
| -
|
| - if (typeof url != 'string') {
|
| - // TODO(vadimt): report an error.
|
| - return;
|
| - }
|
| -
|
| - chrome.tabs.create({url: url});
|
| - });
|
| -}
|
| -
|
| -/**
|
| - * Callback for chrome.notifications.onClosed event.
|
| - * @param {string} notificationId Unique identifier of the notification.
|
| - * @param {boolean} byUser Whether the notification was closed by the user.
|
| - */
|
| -function onNotificationClosed(notificationId, byUser) {
|
| - if (byUser) {
|
| - // TODO(vadimt): Analyze possible race conditions between request for cards
|
| - // and dismissal.
|
| - // Send a dismiss request to the server.
|
| - var requestParameters = '?id=' + notificationId;
|
| - var request = new XMLHttpRequest();
|
| - request.responseType = 'text';
|
| - // TODO(vadimt): If the request fails, for example, because there is no
|
| - // internet connection, do retry with exponential backoff.
|
| - request.open(
|
| - 'GET',
|
| - NOTIFICATION_CARDS_URL + '/dismiss' + requestParameters,
|
| - true);
|
| - request.send();
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * Schedule next update for notification cards.
|
| - * @param {int} delaySeconds Length of time in seconds after which the alarm
|
| - * event should fire.
|
| - */
|
| -function scheduleNextUpdate(delaySeconds) {
|
| - // Schedule an alarm after the specified delay. 'periodInMinutes' is for the
|
| - // case when we fail to re-register the alarm.
|
| - chrome.alarms.create({
|
| - delayInMinutes: delaySeconds / 60,
|
| - periodInMinutes: MAXIMUM_POLLING_PERIOD_SECONDS / 60
|
| - });
|
| -}
|
| -
|
| -/**
|
| - * Initialize the event page on install or on browser startup.
|
| - */
|
| -function initialize() {
|
| - var initialStorage = {
|
| - activeNotifications: {},
|
| - retryDelaySeconds: INITIAL_POLLING_PERIOD_SECONDS
|
| - };
|
| - storage.set(initialStorage, 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();
|
| -});
|
| -
|
| -chrome.notifications.onClicked.addListener(
|
| - function(notificationId) {
|
| - onNotificationClicked(notificationId, function(actionUrls) {
|
| - return actionUrls.messageUrl;
|
| - });
|
| - });
|
| -
|
| -chrome.notifications.onButtonClicked.addListener(
|
| - function(notificationId, buttonIndex) {
|
| - onNotificationClicked(notificationId, function(actionUrls) {
|
| - if (!Array.isArray(actionUrls.buttonUrls))
|
| - return undefined;
|
| -
|
| - return actionUrls.buttonUrls[buttonIndex];
|
| - });
|
| - });
|
| -
|
| -chrome.notifications.onClosed.addListener(onNotificationClosed);
|
| +// 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.
|
| +
|
| +'use strict';
|
| +
|
| +/**
|
| + * @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 internal and server errors. Collect UMAs on errors where
|
| +// appropriate. Also consider logging errors or throwing exceptions.
|
| +// TODO(vadimt): Consider processing errors for all storage.set calls.
|
| +
|
| +// 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
|
| +// set the server name via local storage.
|
| +/**
|
| + * URL to retrieve notification cards.
|
| + */
|
| +var NOTIFICATION_CARDS_URL = localStorage['server_url'];
|
| +
|
| +/**
|
| + * Standard response code for successful HTTP requests. This is the only success
|
| + * code the server will send.
|
| + */
|
| +var HTTP_OK = 200;
|
| +
|
| +/**
|
| + * Initial period for polling for Google Now Notifications cards to use when the
|
| + * period from the server is not available.
|
| + */
|
| +var INITIAL_POLLING_PERIOD_SECONDS = 300; // 5 minutes
|
| +
|
| +/**
|
| + * Maximal period for polling for Google Now Notifications cards to use when the
|
| + * period from the server is not available.
|
| + */
|
| +var MAXIMUM_POLLING_PERIOD_SECONDS = 3600; // 1 hour
|
| +
|
| +var UPDATE_NOTIFICATIONS_ALARM_NAME = 'UPDATE';
|
| +
|
| +var storage = chrome.storage.local;
|
| +
|
| +/**
|
| + * Names for tasks that can be created by the extension.
|
| + */
|
| +var UPDATE_CARDS_TASK_NAME = 'update-cards';
|
| +var DISMISS_CARD_TASK_NAME = 'dismiss-card';
|
| +var CARD_CLICKED_TASK_NAME = 'card-clicked';
|
| +
|
| +/**
|
| + * Checks if a new task can't be scheduled when another task is already
|
| + * scheduled.
|
| + * @param {string} newTaskName Name of the new task.
|
| + * @param {string} queuedTaskName Name of the task in the queue.
|
| + * @return {boolean} Whether the new task conflicts with the existing task.
|
| + */
|
| +function areTasksConflicting(newTaskName, queuedTaskName) {
|
| + if (newTaskName == UPDATE_CARDS_TASK_NAME &&
|
| + queuedTaskName == UPDATE_CARDS_TASK_NAME) {
|
| + // If a card update is requested while an old update is still scheduled, we
|
| + // don't need the new update.
|
| + return true;
|
| + }
|
| +
|
| + return false;
|
| +}
|
| +
|
| +var tasks = buildTaskManager(areTasksConflicting);
|
| +
|
| +/**
|
| + * Shows a notification and remembers information associated with it.
|
| + * @param {Object} card Google Now card represented as a set of parameters for
|
| + * showing a Chrome notification.
|
| + * @param {Object} notificationsUrlInfo Map from notification id to the
|
| + * notification's set of URLs.
|
| + */
|
| +function createNotification(card, notificationsUrlInfo) {
|
| + // Create a notification or quietly update if it already exists.
|
| + // TODO(vadimt): Implement non-quiet updates.
|
| + chrome.notifications.create(
|
| + card.notificationId,
|
| + card.notification,
|
| + function() {});
|
| +
|
| + notificationsUrlInfo[card.notificationId] = card.actionUrls;
|
| +}
|
| +
|
| +/**
|
| + * Parses JSON response from the notification server, show notifications and
|
| + * schedule next update.
|
| + * @param {string} response Server response.
|
| + * @param {function()} callback Completion callback.
|
| + */
|
| +function parseAndShowNotificationCards(response, callback) {
|
| + try {
|
| + var parsedResponse = JSON.parse(response);
|
| + } catch (error) {
|
| + // TODO(vadimt): Report errors to the user.
|
| + return;
|
| + }
|
| +
|
| + var cards = parsedResponse.cards;
|
| +
|
| + if (!(cards instanceof Array)) {
|
| + // TODO(vadimt): Report errors to the user.
|
| + return;
|
| + }
|
| +
|
| + if (typeof parsedResponse.expiration_timestamp_seconds != 'number') {
|
| + // TODO(vadimt): Report errors to the user.
|
| + return;
|
| + }
|
| +
|
| + tasks.debugSetStepName(
|
| + 'parseAndShowNotificationCards-get-active-notifications');
|
| + storage.get('activeNotifications', function(items) {
|
| + // Mark existing notifications that received an update in this server
|
| + // response.
|
| + for (var i = 0; i < cards.length; ++i) {
|
| + var notificationId = cards[i].notificationId;
|
| + if (notificationId in items.activeNotifications)
|
| + items.activeNotifications[notificationId].hasUpdate = true;
|
| + }
|
| +
|
| + // Delete notifications that didn't receive an update.
|
| + for (var notificationId in items.activeNotifications) {
|
| + if (!items.activeNotifications[notificationId].hasUpdate) {
|
| + chrome.notifications.clear(
|
| + notificationId,
|
| + function() {});
|
| + }
|
| + }
|
| +
|
| + // Create/update notifications and store their new properties.
|
| + var notificationsUrlInfo = {};
|
| +
|
| + for (var i = 0; i < cards.length; ++i) {
|
| + try {
|
| + createNotification(cards[i], notificationsUrlInfo);
|
| + } catch (error) {
|
| + // TODO(vadimt): Report errors to the user.
|
| + }
|
| + }
|
| + storage.set({activeNotifications: notificationsUrlInfo});
|
| +
|
| + scheduleNextUpdate(parsedResponse.expiration_timestamp_seconds);
|
| +
|
| + // Now that we got a valid response from the server, reset the retry period
|
| + // to the initial value. This retry period will be used the next time we
|
| + // fail to get the server-provided period.
|
| + storage.set({retryDelaySeconds: INITIAL_POLLING_PERIOD_SECONDS});
|
| + callback();
|
| + });
|
| +}
|
| +
|
| +/**
|
| + * Requests notification cards from the server.
|
| + * @param {string} requestParameters Query string for the request.
|
| + * @param {function()} callback Completion callback.
|
| + */
|
| +function requestNotificationCards(requestParameters, callback) {
|
| + // TODO(vadimt): Figure out how to send user's identity to the server.
|
| + var request = new XMLHttpRequest();
|
| +
|
| + request.responseType = 'text';
|
| + request.onloadend = function(event) {
|
| + if (request.status == HTTP_OK)
|
| + parseAndShowNotificationCards(request.response, callback);
|
| + else
|
| + callback();
|
| + };
|
| +
|
| + request.open(
|
| + 'GET',
|
| + NOTIFICATION_CARDS_URL + '/notifications' + requestParameters,
|
| + true);
|
| + tasks.debugSetStepName('requestNotificationCards-send-request');
|
| + request.send();
|
| +}
|
| +
|
| +/**
|
| + * Requests notification cards from the server when we have geolocation.
|
| + * @param {Geoposition} position Location of this computer.
|
| + * @param {function()} callback Completion callback.
|
| + */
|
| +function requestNotificationCardsWithLocation(position, callback) {
|
| + // TODO(vadimt): Should we use 'q' as the parameter name?
|
| + var requestParameters =
|
| + '?q=' + position.coords.latitude +
|
| + ',' + position.coords.longitude +
|
| + ',' + position.coords.accuracy;
|
| +
|
| + requestNotificationCards(requestParameters, callback);
|
| +}
|
| +
|
| +/**
|
| + * Obtains new location; requests and shows notification cards based on this
|
| + * location.
|
| + */
|
| +function updateNotificationsCards() {
|
| + tasks.add(UPDATE_CARDS_TASK_NAME, function(callback) {
|
| + tasks.debugSetStepName('updateNotificationsCards-get-retryDelaySeconds');
|
| + storage.get('retryDelaySeconds', function(items) {
|
| + // Immediately schedule the update after the current retry period. Then,
|
| + // we'll use update time from the server if available.
|
| + scheduleNextUpdate(items.retryDelaySeconds);
|
| +
|
| + // TODO(vadimt): Consider interrupting waiting for the next update if we
|
| + // detect that the network conditions have changed. Also, decide whether
|
| + // the exponential backoff is needed both when we are offline and when
|
| + // there are failures on the server side.
|
| + var newRetryDelaySeconds =
|
| + Math.min(items.retryDelaySeconds * 2 * (1 + 0.2 * Math.random()),
|
| + MAXIMUM_POLLING_PERIOD_SECONDS);
|
| + storage.set({retryDelaySeconds: newRetryDelaySeconds});
|
| +
|
| + tasks.debugSetStepName('updateNotificationsCards-get-location');
|
| + navigator.geolocation.getCurrentPosition(
|
| + function(position) {
|
| + requestNotificationCardsWithLocation(position, callback);
|
| + },
|
| + function() {
|
| + requestNotificationCards('', callback);
|
| + });
|
| + });
|
| + });
|
| +}
|
| +
|
| +/**
|
| + * Opens URL corresponding to the clicked part of the notification.
|
| + * @param {string} notificationId Unique identifier of the notification.
|
| + * @param {function(Object): string} selector Function that extracts the url for
|
| + * the clicked area from the button action URLs info.
|
| + */
|
| +function onNotificationClicked(notificationId, selector) {
|
| + tasks.add(CARD_CLICKED_TASK_NAME, function(callback) {
|
| + tasks.debugSetStepName('onNotificationClicked-get-activeNotifications');
|
| + storage.get('activeNotifications', function(items) {
|
| + var actionUrls = items.activeNotifications[notificationId];
|
| + if (typeof actionUrls != 'object') {
|
| + // TODO(vadimt): report an error.
|
| + callback();
|
| + return;
|
| + }
|
| +
|
| + var url = selector(actionUrls);
|
| +
|
| + if (typeof url != 'string') {
|
| + // TODO(vadimt): report an error.
|
| + callback();
|
| + return;
|
| + }
|
| +
|
| + chrome.tabs.create({url: url});
|
| + callback();
|
| + });
|
| + });
|
| +}
|
| +
|
| +/**
|
| + * Callback for chrome.notifications.onClosed event.
|
| + * @param {string} notificationId Unique identifier of the notification.
|
| + * @param {boolean} byUser Whether the notification was closed by the user.
|
| + */
|
| +function onNotificationClosed(notificationId, byUser) {
|
| + if (!byUser)
|
| + return;
|
| +
|
| + tasks.add(DISMISS_CARD_TASK_NAME, function(callback) {
|
| + // Deleting the notification in case it was re-added while this task was
|
| + // waiting in the queue.
|
| + chrome.notifications.clear(
|
| + notificationId,
|
| + function() {});
|
| +
|
| + // Send a dismiss request to the server.
|
| + var requestParameters = '?id=' + notificationId;
|
| + var request = new XMLHttpRequest();
|
| + request.responseType = 'text';
|
| + request.onloadend = function(event) {
|
| + callback();
|
| + };
|
| + // TODO(vadimt): If the request fails, for example, because there is no
|
| + // internet connection, do retry with exponential backoff.
|
| + request.open(
|
| + 'GET',
|
| + NOTIFICATION_CARDS_URL + '/dismiss' + requestParameters,
|
| + true);
|
| + tasks.debugSetStepName('onNotificationClosed-send-request');
|
| + request.send();
|
| + });
|
| +}
|
| +
|
| +/**
|
| + * Schedules next update for notification cards.
|
| + * @param {int} delaySeconds Length of time in seconds after which the alarm
|
| + * event should fire.
|
| + */
|
| +function scheduleNextUpdate(delaySeconds) {
|
| + // Schedule an alarm after the specified delay. 'periodInMinutes' is for the
|
| + // case when we fail to re-register the alarm.
|
| + var alarmInfo = {
|
| + delayInMinutes: delaySeconds / 60,
|
| + periodInMinutes: MAXIMUM_POLLING_PERIOD_SECONDS / 60
|
| + };
|
| +
|
| + chrome.alarms.create(UPDATE_NOTIFICATIONS_ALARM_NAME, alarmInfo);
|
| +}
|
| +
|
| +/**
|
| + * Initializes the event page on install or on browser startup.
|
| + */
|
| +function initialize() {
|
| + var initialStorage = {
|
| + activeNotifications: {},
|
| + retryDelaySeconds: INITIAL_POLLING_PERIOD_SECONDS
|
| + };
|
| + storage.set(initialStorage);
|
| + 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) {
|
| + if (alarm.name == UPDATE_NOTIFICATIONS_ALARM_NAME)
|
| + updateNotificationsCards();
|
| +});
|
| +
|
| +chrome.notifications.onClicked.addListener(
|
| + function(notificationId) {
|
| + onNotificationClicked(notificationId, function(actionUrls) {
|
| + return actionUrls.messageUrl;
|
| + });
|
| + });
|
| +
|
| +chrome.notifications.onButtonClicked.addListener(
|
| + function(notificationId, buttonIndex) {
|
| + onNotificationClicked(notificationId, function(actionUrls) {
|
| + if (!Array.isArray(actionUrls.buttonUrls))
|
| + return undefined;
|
| +
|
| + return actionUrls.buttonUrls[buttonIndex];
|
| + });
|
| + });
|
| +
|
| +chrome.notifications.onClosed.addListener(onNotificationClosed);
|
|
|