OLD | NEW |
---|---|
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'; | 5 'use strict'; |
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 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
227 DELETED_SHOW_WELCOME_TOAST: 8, | 227 DELETED_SHOW_WELCOME_TOAST: 8, |
228 STOPPED: 9, | 228 STOPPED: 9, |
229 DELETED_USER_SUPPRESSED: 10, | 229 DELETED_USER_SUPPRESSED: 10, |
230 SIGNED_OUT: 11, | 230 SIGNED_OUT: 11, |
231 NOTIFICATION_DISABLED: 12, | 231 NOTIFICATION_DISABLED: 12, |
232 GOOGLE_NOW_DISABLED: 13, | 232 GOOGLE_NOW_DISABLED: 13, |
233 EVENTS_TOTAL: 14 // EVENTS_TOTAL is not an event; all new events need to be | 233 EVENTS_TOTAL: 14 // EVENTS_TOTAL is not an event; all new events need to be |
234 // added before it. | 234 // added before it. |
235 }; | 235 }; |
236 | 236 |
237 // CARD_TYPES_TOTAL is the maximum histogram value and card type value. | |
238 var CARD_TYPES_TOTAL = 50; | |
239 | |
237 /** | 240 /** |
238 * Records a Google Now Event. | 241 * Records a Google Now Event. |
239 * @param {GoogleNowEvent} event Event identifier. | 242 * @param {GoogleNowEvent} event Event identifier. |
240 */ | 243 */ |
241 function recordEvent(event) { | 244 function recordEvent(event) { |
242 var metricDescription = { | 245 var metricDescription = { |
243 metricName: 'GoogleNow.Event', | 246 metricName: 'GoogleNow.Event', |
244 type: 'histogram-linear', | 247 type: 'histogram-linear', |
245 min: 1, | 248 min: 1, |
246 max: GoogleNowEvent.EVENTS_TOTAL, | 249 max: GoogleNowEvent.EVENTS_TOTAL, |
247 buckets: GoogleNowEvent.EVENTS_TOTAL + 1 | 250 buckets: GoogleNowEvent.EVENTS_TOTAL + 1 |
248 }; | 251 }; |
249 | 252 |
250 chrome.metricsPrivate.recordValue(metricDescription, event); | 253 chrome.metricsPrivate.recordValue(metricDescription, event); |
251 } | 254 } |
252 | 255 |
253 /** | 256 /** |
257 * Records a notification clicked event. | |
258 * @param {number|undefined} cardTypeId Card type ID. | |
259 */ | |
260 function recordNotificationClick(cardTypeId) { | |
261 if (cardTypeId !== undefined) { | |
262 var metricDescription = { | |
263 metricName: 'GoogleNow.Card.Clicked', | |
264 type: 'histogram-linear', | |
265 min: 1, | |
266 max: CARD_TYPES_TOTAL, | |
267 buckets: CARD_TYPES_TOTAL + 1 | |
268 }; | |
269 chrome.metricsPrivate.recordValue(metricDescription, cardTypeId); | |
skare_
2014/03/25 23:55:39
Should we range-check cardTypeId<=CARD_TYPES_TOTAL
robliao
2014/03/26 00:25:59
I remember a series of crashes surrounding this co
| |
270 } | |
271 } | |
272 | |
273 /** | |
274 * Records a button clicked event. | |
275 * @param {number|undefined} cardTypeId Card type ID. | |
276 * @param {number} buttonIndex Button Index | |
277 */ | |
278 function recordButtonClick(cardTypeId, buttonIndex) { | |
279 if (cardTypeId !== undefined) { | |
280 var metricDescription = { | |
281 metricName: 'GoogleNow.Card.Button.Clicked' + buttonIndex, | |
282 type: 'histogram-linear', | |
283 min: 1, | |
284 max: CARD_TYPES_TOTAL, | |
285 buckets: CARD_TYPES_TOTAL + 1 | |
286 }; | |
287 chrome.metricsPrivate.recordValue(metricDescription, cardTypeId); | |
288 } | |
289 } | |
290 | |
291 /** | |
254 * Checks the result of the HTTP Request and updates the authentication | 292 * Checks the result of the HTTP Request and updates the authentication |
255 * manager on any failure. | 293 * manager on any failure. |
256 * @param {string} token Authentication token to validate against an | 294 * @param {string} token Authentication token to validate against an |
257 * XMLHttpRequest. | 295 * XMLHttpRequest. |
258 * @return {function(XMLHttpRequest)} Function that validates the token with the | 296 * @return {function(XMLHttpRequest)} Function that validates the token with the |
259 * supplied XMLHttpRequest. | 297 * supplied XMLHttpRequest. |
260 */ | 298 */ |
261 function checkAuthenticationStatus(token) { | 299 function checkAuthenticationStatus(token) { |
262 return function(request) { | 300 return function(request) { |
263 if (request.status == HTTP_FORBIDDEN || | 301 if (request.status == HTTP_FORBIDDEN || |
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
796 chrome.windows.update(tab.windowId, {focused: true}); | 834 chrome.windows.update(tab.windowId, {focused: true}); |
797 else | 835 else |
798 chrome.windows.create({url: url, focused: true}); | 836 chrome.windows.create({url: url, focused: true}); |
799 }); | 837 }); |
800 } | 838 } |
801 | 839 |
802 /** | 840 /** |
803 * Opens URL corresponding to the clicked part of the notification. | 841 * Opens URL corresponding to the clicked part of the notification. |
804 * @param {ChromeNotificationId} chromeNotificationId chrome.notifications ID of | 842 * @param {ChromeNotificationId} chromeNotificationId chrome.notifications ID of |
805 * the card. | 843 * the card. |
806 * @param {function((ActionUrls|undefined)): (string|undefined)} selector | 844 * @param {function(NotificationDataEntry): (string|undefined)} selector |
807 * Function that extracts the url for the clicked area from the button | 845 * Function that extracts the url for the clicked area from the |
808 * action URLs info. | 846 * notification data entry. |
809 */ | 847 */ |
810 function onNotificationClicked(chromeNotificationId, selector) { | 848 function onNotificationClicked(chromeNotificationId, selector) { |
811 fillFromChromeLocalStorage({ | 849 fillFromChromeLocalStorage({ |
812 /** @type {Object.<string, NotificationDataEntry>} */ | 850 /** @type {Object.<string, NotificationDataEntry>} */ |
813 notificationsData: {} | 851 notificationsData: {} |
814 }).then(function(items) { | 852 }).then(function(items) { |
815 /** @type {(NotificationDataEntry|undefined)} */ | 853 /** @type {(NotificationDataEntry|undefined)} */ |
816 var notificationData = items.notificationsData[chromeNotificationId]; | 854 var notificationDataEntry = items.notificationsData[chromeNotificationId]; |
817 if (!notificationData) | 855 if (!notificationDataEntry) |
818 return; | 856 return; |
819 | 857 |
820 var url = selector(notificationData.actionUrls); | 858 var url = selector(notificationDataEntry); |
821 if (!url) | 859 if (!url) |
822 return; | 860 return; |
823 | 861 |
824 openUrl(url); | 862 openUrl(url); |
825 }); | 863 }); |
826 } | 864 } |
827 | 865 |
828 /** | 866 /** |
829 * Callback for chrome.notifications.onClosed event. | 867 * Callback for chrome.notifications.onClosed event. |
830 * @param {ChromeNotificationId} chromeNotificationId chrome.notifications ID of | 868 * @param {ChromeNotificationId} chromeNotificationId chrome.notifications ID of |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1103 }); | 1141 }); |
1104 | 1142 |
1105 authenticationManager.addListener(function() { | 1143 authenticationManager.addListener(function() { |
1106 console.log('signIn State Change'); | 1144 console.log('signIn State Change'); |
1107 onStateChange(); | 1145 onStateChange(); |
1108 }); | 1146 }); |
1109 | 1147 |
1110 instrumented.notifications.onClicked.addListener( | 1148 instrumented.notifications.onClicked.addListener( |
1111 function(chromeNotificationId) { | 1149 function(chromeNotificationId) { |
1112 chrome.metricsPrivate.recordUserAction('GoogleNow.MessageClicked'); | 1150 chrome.metricsPrivate.recordUserAction('GoogleNow.MessageClicked'); |
1113 onNotificationClicked(chromeNotificationId, function(actionUrls) { | 1151 onNotificationClicked(chromeNotificationId, |
1114 return actionUrls && actionUrls.messageUrl; | 1152 function(notificationDataEntry) { |
1115 }); | 1153 var actionUrls = notificationDataEntry.actionUrls; |
1116 }); | 1154 var url = actionUrls && actionUrls.messageUrl; |
1155 if (url) { | |
1156 recordNotificationClick(notificationDataEntry.cardTypeId); | |
1157 } | |
1158 return url; | |
1159 }); | |
1160 }); | |
1117 | 1161 |
1118 instrumented.notifications.onButtonClicked.addListener( | 1162 instrumented.notifications.onButtonClicked.addListener( |
1119 function(chromeNotificationId, buttonIndex) { | 1163 function(chromeNotificationId, buttonIndex) { |
1120 chrome.metricsPrivate.recordUserAction( | 1164 chrome.metricsPrivate.recordUserAction( |
1121 'GoogleNow.ButtonClicked' + buttonIndex); | 1165 'GoogleNow.ButtonClicked' + buttonIndex); |
1122 onNotificationClicked(chromeNotificationId, function(actionUrls) { | 1166 onNotificationClicked(chromeNotificationId, |
1123 var url = actionUrls.buttonUrls[buttonIndex]; | 1167 function(notificationDataEntry) { |
1124 verify(url !== undefined, 'onButtonClicked: no url for a button'); | 1168 var actionUrls = notificationDataEntry.actionUrls; |
1125 return url; | 1169 var url = actionUrls.buttonUrls[buttonIndex]; |
1126 }); | 1170 if (url) { |
1127 }); | 1171 recordButtonClick(notificationDataEntry.cardTypeId, buttonIndex); |
1172 } else { | |
1173 verify(false, 'onButtonClicked: no url for a button'); | |
1174 } | |
1175 return url; | |
1176 }); | |
1177 }); | |
1128 | 1178 |
1129 instrumented.notifications.onClosed.addListener(onNotificationClosed); | 1179 instrumented.notifications.onClosed.addListener(onNotificationClosed); |
1130 | 1180 |
1131 instrumented.notifications.onPermissionLevelChanged.addListener( | 1181 instrumented.notifications.onPermissionLevelChanged.addListener( |
1132 function(permissionLevel) { | 1182 function(permissionLevel) { |
1133 console.log('Notifications permissionLevel Change'); | 1183 console.log('Notifications permissionLevel Change'); |
1134 onStateChange(); | 1184 onStateChange(); |
1135 }); | 1185 }); |
1136 | 1186 |
1137 instrumented.notifications.onShowSettings.addListener(function() { | 1187 instrumented.notifications.onShowSettings.addListener(function() { |
(...skipping 28 matching lines...) Expand all Loading... | |
1166 lastPollNowPayloads: items.lastPollNowPayloads, | 1216 lastPollNowPayloads: items.lastPollNowPayloads, |
1167 notificationGroups: items.notificationGroups | 1217 notificationGroups: items.notificationGroups |
1168 }); | 1218 }); |
1169 | 1219 |
1170 requestCards(); | 1220 requestCards(); |
1171 } | 1221 } |
1172 }); | 1222 }); |
1173 }); | 1223 }); |
1174 } | 1224 } |
1175 }); | 1225 }); |
OLD | NEW |