| 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 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 return false; | 146 return false; |
| 147 } | 147 } |
| 148 | 148 |
| 149 var tasks = buildTaskManager(areTasksConflicting); | 149 var tasks = buildTaskManager(areTasksConflicting); |
| 150 | 150 |
| 151 // Add error processing to API calls. | 151 // Add error processing to API calls. |
| 152 wrapper.instrumentChromeApiFunction('location.onLocationUpdate.addListener', 0); | 152 wrapper.instrumentChromeApiFunction('location.onLocationUpdate.addListener', 0); |
| 153 wrapper.instrumentChromeApiFunction('metricsPrivate.getVariationParams', 1); | 153 wrapper.instrumentChromeApiFunction('metricsPrivate.getVariationParams', 1); |
| 154 wrapper.instrumentChromeApiFunction('notifications.clear', 1); | 154 wrapper.instrumentChromeApiFunction('notifications.clear', 1); |
| 155 wrapper.instrumentChromeApiFunction('notifications.create', 2); | 155 wrapper.instrumentChromeApiFunction('notifications.create', 2); |
| 156 wrapper.instrumentChromeApiFunction('notifications.getPermissionLevel', 0); |
| 156 wrapper.instrumentChromeApiFunction('notifications.update', 2); | 157 wrapper.instrumentChromeApiFunction('notifications.update', 2); |
| 157 wrapper.instrumentChromeApiFunction('notifications.getAll', 0); | 158 wrapper.instrumentChromeApiFunction('notifications.getAll', 0); |
| 158 wrapper.instrumentChromeApiFunction( | 159 wrapper.instrumentChromeApiFunction( |
| 159 'notifications.onButtonClicked.addListener', 0); | 160 'notifications.onButtonClicked.addListener', 0); |
| 160 wrapper.instrumentChromeApiFunction('notifications.onClicked.addListener', 0); | 161 wrapper.instrumentChromeApiFunction('notifications.onClicked.addListener', 0); |
| 161 wrapper.instrumentChromeApiFunction('notifications.onClosed.addListener', 0); | 162 wrapper.instrumentChromeApiFunction('notifications.onClosed.addListener', 0); |
| 162 wrapper.instrumentChromeApiFunction( | 163 wrapper.instrumentChromeApiFunction( |
| 164 'notifications.onPermissionLevelChanged.addListener', 0); |
| 165 wrapper.instrumentChromeApiFunction( |
| 163 'preferencesPrivate.googleGeolocationAccessEnabled.get', | 166 'preferencesPrivate.googleGeolocationAccessEnabled.get', |
| 164 1); | 167 1); |
| 165 wrapper.instrumentChromeApiFunction( | 168 wrapper.instrumentChromeApiFunction( |
| 166 'preferencesPrivate.googleGeolocationAccessEnabled.onChange.addListener', | 169 'preferencesPrivate.googleGeolocationAccessEnabled.onChange.addListener', |
| 167 0); | 170 0); |
| 168 wrapper.instrumentChromeApiFunction('permissions.contains', 1); | 171 wrapper.instrumentChromeApiFunction('permissions.contains', 1); |
| 169 wrapper.instrumentChromeApiFunction('pushMessaging.onMessage.addListener', 0); | 172 wrapper.instrumentChromeApiFunction('pushMessaging.onMessage.addListener', 0); |
| 170 wrapper.instrumentChromeApiFunction('runtime.onInstalled.addListener', 0); | 173 wrapper.instrumentChromeApiFunction('runtime.onInstalled.addListener', 0); |
| 171 wrapper.instrumentChromeApiFunction('runtime.onStartup.addListener', 0); | 174 wrapper.instrumentChromeApiFunction('runtime.onStartup.addListener', 0); |
| 172 wrapper.instrumentChromeApiFunction('tabs.create', 1); | 175 wrapper.instrumentChromeApiFunction('tabs.create', 1); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 function(items) { | 269 function(items) { |
| 267 console.log('showNotificationCards-get ' + | 270 console.log('showNotificationCards-get ' + |
| 268 JSON.stringify(items)); | 271 JSON.stringify(items)); |
| 269 items = items || {}; | 272 items = items || {}; |
| 270 items.notificationsData = items.notificationsData || {}; | 273 items.notificationsData = items.notificationsData || {}; |
| 271 items.recentDismissals = items.recentDismissals || {}; | 274 items.recentDismissals = items.recentDismissals || {}; |
| 272 | 275 |
| 273 instrumented.notifications.getAll(function(notifications) { | 276 instrumented.notifications.getAll(function(notifications) { |
| 274 console.log('showNotificationCards-getAll ' + | 277 console.log('showNotificationCards-getAll ' + |
| 275 JSON.stringify(notifications)); | 278 JSON.stringify(notifications)); |
| 276 // TODO(vadimt): Figure out what to do when notifications are | |
| 277 // disabled for our extension. | |
| 278 notifications = notifications || {}; | 279 notifications = notifications || {}; |
| 279 | 280 |
| 280 // Build a set of non-expired recent dismissals. It will be used for | 281 // Build a set of non-expired recent dismissals. It will be used for |
| 281 // client-side filtering of cards. | 282 // client-side filtering of cards. |
| 282 var updatedRecentDismissals = {}; | 283 var updatedRecentDismissals = {}; |
| 283 var currentTimeMs = Date.now(); | 284 var currentTimeMs = Date.now(); |
| 284 for (var chromeNotificationId in items.recentDismissals) { | 285 for (var chromeNotificationId in items.recentDismissals) { |
| 285 if (currentTimeMs - items.recentDismissals[chromeNotificationId] < | 286 if (currentTimeMs - items.recentDismissals[chromeNotificationId] < |
| 286 DISMISS_RETENTION_TIME_MS) { | 287 DISMISS_RETENTION_TIME_MS) { |
| 287 updatedRecentDismissals[chromeNotificationId] = | 288 updatedRecentDismissals[chromeNotificationId] = |
| (...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 913 } | 914 } |
| 914 | 915 |
| 915 /** | 916 /** |
| 916 * Does the actual work of deciding what Google Now should do | 917 * Does the actual work of deciding what Google Now should do |
| 917 * based off of the current state of Chrome. | 918 * based off of the current state of Chrome. |
| 918 * @param {boolean} signedIn true if the user is signed in. | 919 * @param {boolean} signedIn true if the user is signed in. |
| 919 * @param {boolean} geolocationEnabled true if | 920 * @param {boolean} geolocationEnabled true if |
| 920 * the geolocation option is enabled. | 921 * the geolocation option is enabled. |
| 921 * @param {boolean} enableBackground true if | 922 * @param {boolean} enableBackground true if |
| 922 * the background permission should be requested. | 923 * the background permission should be requested. |
| 924 * @param {boolean} notificationEnabled true if |
| 925 * Google Now for Chrome is allowed to show notifications. |
| 923 */ | 926 */ |
| 924 function updateRunningState( | 927 function updateRunningState( |
| 925 signedIn, | 928 signedIn, |
| 926 geolocationEnabled, | 929 geolocationEnabled, |
| 927 enableBackground) { | 930 enableBackground, |
| 931 notificationEnabled) { |
| 928 console.log( | 932 console.log( |
| 929 'State Update signedIn=' + signedIn + ' ' + | 933 'State Update signedIn=' + signedIn + ' ' + |
| 930 'geolocationEnabled=' + geolocationEnabled); | 934 'geolocationEnabled=' + geolocationEnabled + ' ' + |
| 935 'enableBackground=' + enableBackground + ' ' + |
| 936 'notificationEnabled=' + notificationEnabled); |
| 931 | 937 |
| 932 // TODO(vadimt): Remove this line once state machine design is finalized. | 938 // TODO(vadimt): Remove this line once state machine design is finalized. |
| 933 geolocationEnabled = true; | 939 geolocationEnabled = true; |
| 934 | 940 |
| 935 var shouldPollCards = false; | 941 var shouldPollCards = false; |
| 936 var shouldSetBackground = false; | 942 var shouldSetBackground = false; |
| 937 | 943 |
| 938 if (signedIn) { | 944 if (signedIn && notificationEnabled) { |
| 939 if (geolocationEnabled) { | 945 if (geolocationEnabled) { |
| 940 if (enableBackground) | 946 if (enableBackground) |
| 941 shouldSetBackground = true; | 947 shouldSetBackground = true; |
| 942 | 948 |
| 943 shouldPollCards = true; | 949 shouldPollCards = true; |
| 944 } | 950 } |
| 945 } else { | 951 } else { |
| 946 recordEvent(GoogleNowEvent.STOPPED); | 952 recordEvent(GoogleNowEvent.STOPPED); |
| 947 } | 953 } |
| 948 | 954 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 960 */ | 966 */ |
| 961 function onStateChange() { | 967 function onStateChange() { |
| 962 tasks.add(STATE_CHANGED_TASK_NAME, function() { | 968 tasks.add(STATE_CHANGED_TASK_NAME, function() { |
| 963 authenticationManager.isSignedIn(function(token) { | 969 authenticationManager.isSignedIn(function(token) { |
| 964 var signedIn = !!token; | 970 var signedIn = !!token; |
| 965 instrumented.metricsPrivate.getVariationParams( | 971 instrumented.metricsPrivate.getVariationParams( |
| 966 'GoogleNow', | 972 'GoogleNow', |
| 967 function(response) { | 973 function(response) { |
| 968 var enableBackground = | 974 var enableBackground = |
| 969 (!response || (response.enableBackground != 'false')); | 975 (!response || (response.enableBackground != 'false')); |
| 970 instrumented. | 976 instrumented.notifications.getPermissionLevel(function(level) { |
| 977 var notificationEnabled = (level == 'granted'); |
| 978 instrumented. |
| 971 preferencesPrivate. | 979 preferencesPrivate. |
| 972 googleGeolocationAccessEnabled. | 980 googleGeolocationAccessEnabled. |
| 973 get({}, function(prefValue) { | 981 get({}, function(prefValue) { |
| 974 var geolocationEnabled = !!prefValue.value; | 982 var geolocationEnabled = !!prefValue.value; |
| 975 updateRunningState( | 983 updateRunningState( |
| 976 signedIn, | 984 signedIn, |
| 977 geolocationEnabled, | 985 geolocationEnabled, |
| 978 enableBackground); | 986 enableBackground, |
| 987 notificationEnabled); |
| 979 }); | 988 }); |
| 989 }); |
| 980 }); | 990 }); |
| 981 }); | 991 }); |
| 982 }); | 992 }); |
| 983 } | 993 } |
| 984 | 994 |
| 985 instrumented.runtime.onInstalled.addListener(function(details) { | 995 instrumented.runtime.onInstalled.addListener(function(details) { |
| 986 console.log('onInstalled ' + JSON.stringify(details)); | 996 console.log('onInstalled ' + JSON.stringify(details)); |
| 987 if (details.reason != 'chrome_update') { | 997 if (details.reason != 'chrome_update') { |
| 988 initialize(); | 998 initialize(); |
| 989 } | 999 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1037 'GoogleNow.ButtonClicked' + buttonIndex); | 1047 'GoogleNow.ButtonClicked' + buttonIndex); |
| 1038 onNotificationClicked(chromeNotificationId, function(actionUrls) { | 1048 onNotificationClicked(chromeNotificationId, function(actionUrls) { |
| 1039 var url = actionUrls.buttonUrls[buttonIndex]; | 1049 var url = actionUrls.buttonUrls[buttonIndex]; |
| 1040 verify(url, 'onButtonClicked: no url for a button'); | 1050 verify(url, 'onButtonClicked: no url for a button'); |
| 1041 return url; | 1051 return url; |
| 1042 }); | 1052 }); |
| 1043 }); | 1053 }); |
| 1044 | 1054 |
| 1045 instrumented.notifications.onClosed.addListener(onNotificationClosed); | 1055 instrumented.notifications.onClosed.addListener(onNotificationClosed); |
| 1046 | 1056 |
| 1057 instrumented.notifications.onPermissionLevelChanged.addListener( |
| 1058 function(permissionLevel) { |
| 1059 console.log('Notifications permissionLevel Change'); |
| 1060 onStateChange(); |
| 1061 }); |
| 1062 |
| 1047 instrumented.location.onLocationUpdate.addListener(function(position) { | 1063 instrumented.location.onLocationUpdate.addListener(function(position) { |
| 1048 recordEvent(GoogleNowEvent.LOCATION_UPDATE); | 1064 recordEvent(GoogleNowEvent.LOCATION_UPDATE); |
| 1049 updateNotificationsCards(position); | 1065 updateNotificationsCards(position); |
| 1050 }); | 1066 }); |
| 1051 | 1067 |
| 1052 instrumented.pushMessaging.onMessage.addListener(function(message) { | 1068 instrumented.pushMessaging.onMessage.addListener(function(message) { |
| 1053 // message.payload will be '' when the extension first starts. | 1069 // message.payload will be '' when the extension first starts. |
| 1054 // Each time after signing in, we'll get latest payload for all channels. | 1070 // Each time after signing in, we'll get latest payload for all channels. |
| 1055 // So, we need to poll the server only when the payload is non-empty and has | 1071 // So, we need to poll the server only when the payload is non-empty and has |
| 1056 // changed. | 1072 // changed. |
| 1057 console.log('pushMessaging.onMessage ' + JSON.stringify(message)); | 1073 console.log('pushMessaging.onMessage ' + JSON.stringify(message)); |
| 1058 if (message.subchannelId == SUBCHANNEL_ID_POLL_NOW && message.payload) { | 1074 if (message.subchannelId == SUBCHANNEL_ID_POLL_NOW && message.payload) { |
| 1059 tasks.add(ON_PUSH_MESSAGE_START_TASK_NAME, function() { | 1075 tasks.add(ON_PUSH_MESSAGE_START_TASK_NAME, function() { |
| 1060 instrumented.storage.local.get('lastPollNowPayload', function(items) { | 1076 instrumented.storage.local.get('lastPollNowPayload', function(items) { |
| 1061 if (items && items.lastPollNowPayload != message.payload) { | 1077 if (items && items.lastPollNowPayload != message.payload) { |
| 1062 chrome.storage.local.set({lastPollNowPayload: message.payload}); | 1078 chrome.storage.local.set({lastPollNowPayload: message.payload}); |
| 1063 | 1079 |
| 1064 updateCardsAttempts.isRunning(function(running) { | 1080 updateCardsAttempts.isRunning(function(running) { |
| 1065 if (running) | 1081 if (running) |
| 1066 requestNotificationGroups([]); | 1082 requestNotificationGroups([]); |
| 1067 }); | 1083 }); |
| 1068 } | 1084 } |
| 1069 }); | 1085 }); |
| 1070 }); | 1086 }); |
| 1071 } | 1087 } |
| 1072 }); | 1088 }); |
| OLD | NEW |