| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 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 | 
|  | 3 // found in the LICENSE file. | 
|  | 4 | 
|  | 5 'use strict'; | 
|  | 6 | 
|  | 7 /** | 
|  | 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 | 
|  | 10  * them as Chrome notifications. | 
|  | 11  * The service performs periodic updating of Google Now cards. | 
|  | 12  * Each updating of the cards includes 3 steps: | 
|  | 13  * 1. Obtaining the location of the machine; | 
|  | 14  * 2. Making a server request based on that location; | 
|  | 15  * 3. Showing the received cards as notifications. | 
|  | 16  */ | 
|  | 17 | 
|  | 18 // TODO(vadimt): Use background permission to show notifications even when all | 
|  | 19 // browser windows are closed. | 
|  | 20 // TODO(vadimt): Remove the C++ implementation. | 
|  | 21 // TODO(vadimt): Decide what to do in incognito mode. | 
|  | 22 // TODO(vadimt): Gather UMAs. | 
|  | 23 // TODO(vadimt): Honor the flag the enables Google Now integration. | 
|  | 24 // TODO(vadimt): Figure out the final values of the constants. | 
|  | 25 // TODO(vadimt): Report errors to the user. | 
|  | 26 | 
|  | 27 // TODO(vadimt): Figure out the server name. Use it in the manifest and for | 
|  | 28 // NOTIFICATION_CARDS_URL. Meanwhile, to use the feature, you need to manually | 
|  | 29 // edit NOTIFICATION_CARDS_URL before building Chrome. | 
|  | 30 /** | 
|  | 31  * URL to retrieve notification cards. | 
|  | 32  */ | 
|  | 33 var NOTIFICATION_CARDS_URL = ''; | 
|  | 34 | 
|  | 35 /** | 
|  | 36  * Standard response code for successful HTTP requests. This is the only success | 
|  | 37  * code the server will send. | 
|  | 38  */ | 
|  | 39 var HTTP_OK = 200; | 
|  | 40 | 
|  | 41 /** | 
|  | 42  * Period for polling for Google Now Notifications cards to use when the period | 
|  | 43  * from the server is not available. | 
|  | 44  */ | 
|  | 45 var DEFAULT_POLLING_PERIOD_SECONDS = 300;  // 5 minutes | 
|  | 46 | 
|  | 47 /** | 
|  | 48  * Parse JSON response of the notifications server, show notifications and | 
|  | 49  * schedule next update. | 
|  | 50  * @param {string} response Server response. | 
|  | 51  */ | 
|  | 52 function parseAndShowNotificationCards(response) { | 
|  | 53   try { | 
|  | 54     var parsedResponse = JSON.parse(response); | 
|  | 55   } catch (error) { | 
|  | 56     // TODO(vadimt): Report errors to the user. | 
|  | 57     return; | 
|  | 58   } | 
|  | 59 | 
|  | 60   var cards = parsedResponse.cards; | 
|  | 61 | 
|  | 62   if (!(cards instanceof Array)) { | 
|  | 63     // TODO(vadimt): Report errors to the user. | 
|  | 64     return; | 
|  | 65   } | 
|  | 66 | 
|  | 67   if (typeof parsedResponse.expiration_timestamp_seconds != 'number') { | 
|  | 68     // TODO(vadimt): Report errors to the user. | 
|  | 69     return; | 
|  | 70   } | 
|  | 71 | 
|  | 72   for (var i = 0; i != cards.length; ++i) { | 
|  | 73     try { | 
|  | 74       chrome.experimental.notification.show(cards[i], function(showInfo) {}); | 
|  | 75     } catch (error) { | 
|  | 76       // TODO(vadimt): Report errors to the user. | 
|  | 77       return; | 
|  | 78     } | 
|  | 79   } | 
|  | 80 | 
|  | 81   scheduleNextUpdate(parsedResponse.expiration_timestamp_seconds); | 
|  | 82 } | 
|  | 83 | 
|  | 84 /** | 
|  | 85  * Request notification cards from the server. | 
|  | 86  * @param {string} requestParameters Query string for the request. | 
|  | 87  */ | 
|  | 88 function requestNotificationCards(requestParameters) { | 
|  | 89   // TODO(vadimt): Figure out how to send user's identity to the server. | 
|  | 90   var request = new XMLHttpRequest(); | 
|  | 91 | 
|  | 92   request.responseType = 'text'; | 
|  | 93   request.onload = function(event) { | 
|  | 94     if (request.status == HTTP_OK) | 
|  | 95       parseAndShowNotificationCards(request.response); | 
|  | 96   } | 
|  | 97 | 
|  | 98   request.open('GET', NOTIFICATION_CARDS_URL + requestParameters, true); | 
|  | 99   request.send(); | 
|  | 100 } | 
|  | 101 | 
|  | 102 /** | 
|  | 103  * Request notification cards from the server when we have geolocation. | 
|  | 104  * @param {Geoposition} position Location of this computer. | 
|  | 105  */ | 
|  | 106 function requestNotificationCardsWithLocation(position) { | 
|  | 107   // TODO(vadimt): Should we use 'q' as the parameter name? | 
|  | 108   var requestParameters = | 
|  | 109       '?q=' + position.coords.latitude + | 
|  | 110       ',' + position.coords.longitude + | 
|  | 111       ',' + position.coords.accuracy; | 
|  | 112 | 
|  | 113   requestNotificationCards(requestParameters); | 
|  | 114 } | 
|  | 115 | 
|  | 116 /** | 
|  | 117  * Request notification cards from the server when we don't have geolocation. | 
|  | 118  * @param {PositionError} positionError Position error. | 
|  | 119  */ | 
|  | 120 function requestNotificationCardsWithoutLocation(positionError) { | 
|  | 121   requestNotificationCards(''); | 
|  | 122 } | 
|  | 123 | 
|  | 124 /** | 
|  | 125  * Obtain new location; request and show notification cards based on this | 
|  | 126  * location. | 
|  | 127  */ | 
|  | 128 function updateNotificationsCards() { | 
|  | 129   // Immediately schedule the update after the default period. If we | 
|  | 130   // successfully retrieve, parse and show the notifications cards, we'll | 
|  | 131   // schedule next update based on the expiration timestamp received from the | 
|  | 132   // server. At that point scheduled time will be overwritten by the new one | 
|  | 133   // based on the expiration timestamp. | 
|  | 134   // TODO(vadimt): Implement exponential backoff with randomized jitter. | 
|  | 135   scheduleNextUpdate(DEFAULT_POLLING_PERIOD_SECONDS); | 
|  | 136 | 
|  | 137   // TODO(vadimt): Use chrome.* geolocation API once it's ready. | 
|  | 138   navigator.geolocation.getCurrentPosition( | 
|  | 139       requestNotificationCardsWithLocation, | 
|  | 140       requestNotificationCardsWithoutLocation); | 
|  | 141 } | 
|  | 142 | 
|  | 143 /** | 
|  | 144  * Schedule next update for notification cards. | 
|  | 145  * @param {int} delaySeconds Length of time in seconds after which the alarm | 
|  | 146  *     event should fire. | 
|  | 147  */ | 
|  | 148 function scheduleNextUpdate(delaySeconds) { | 
|  | 149   chrome.alarms.create({delayInMinutes: delaySeconds / 60}); | 
|  | 150 } | 
|  | 151 | 
|  | 152 /** | 
|  | 153  * Initialize the event page on install or on browser startup. | 
|  | 154  */ | 
|  | 155 function initialize() { | 
|  | 156   updateNotificationsCards(); | 
|  | 157 } | 
|  | 158 | 
|  | 159 chrome.runtime.onInstalled.addListener(function(details) { | 
|  | 160   if (details.reason != 'chrome_update') | 
|  | 161     initialize(); | 
|  | 162 }); | 
|  | 163 | 
|  | 164 chrome.runtime.onStartup.addListener(function() { | 
|  | 165   initialize(); | 
|  | 166 }); | 
|  | 167 | 
|  | 168 chrome.alarms.onAlarm.addListener(function(alarm) { | 
|  | 169   updateNotificationsCards(); | 
|  | 170 }); | 
| OLD | NEW | 
|---|