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