1 // Copyright 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.
8 * Show/hide trigger in a card.
18 * Data to build a dismissal request for a card from a specific group.
21 * notificationId: string,
28 * Card merged from potentially multiple groups.
34 * notification: Object,
35 * actionUrls: Object=,
37 * dismissals: Array.<DismissalData>,
38 * locationBased: boolean=
44 * Set of parameters for creating card notification.
47 * notification: Object,
50 * previousVersion: number=,
51 * locationBased: boolean=
57 * Names for tasks that can be created by the this file.
59 var SHOW_CARD_TASK_NAME = 'show-card';
60 var CLEAR_CARD_TASK_NAME = 'clear-card';
63 * Builds an object to manage notification card set.
64 * @return {Object} Card set interface.
66 function buildCardSet() {
67 var cardShowPrefix = 'card-show-';
68 var cardHidePrefix = 'card-hide-';
71 * Schedules hiding a notification.
72 * @param {string} cardId Card ID.
73 * @param {number=} opt_timeHide If specified, epoch time to hide the card. If
74 * undefined, the card will be kept shown at least until next update.
76 function scheduleHiding(cardId, opt_timeHide) {
77 if (opt_timeHide === undefined)
80 var alarmName = cardHidePrefix + cardId;
81 var alarmInfo = {when: opt_timeHide};
82 chrome.alarms.create(alarmName, alarmInfo);
86 * Shows a notification.
87 * @param {string} cardId Card ID.
88 * @param {CardCreateInfo} cardCreateInfo Google Now card represented as a set
89 * of parameters for showing a Chrome notification.
90 * @param {function(CardCreateInfo)=} onCardShown Optional parameter called
91 * when each card is shown.
93 function showNotification(cardId, cardCreateInfo, onCardShown) {
94 console.log('cardManager.showNotification ' + cardId + ' ' +
95 JSON.stringify(cardCreateInfo));
97 if (cardCreateInfo.hideTime <= Date.now()) {
98 console.log('cardManager.showNotification ' + cardId + ': expired');
99 // Card has expired. Schedule hiding to delete asociated information.
100 scheduleHiding(cardId, cardCreateInfo.hideTime);
104 if (cardCreateInfo.previousVersion !== cardCreateInfo.version) {
105 // Delete a notification with the specified id if it already exists, and
106 // then create a notification.
107 instrumented.notifications.create(
109 cardCreateInfo.notification,
110 function(newNotificationId) {
111 if (!newNotificationId || chrome.runtime.lastError) {
112 var errorMessage = chrome.runtime.lastError &&
113 chrome.runtime.lastError.message;
114 console.error('notifications.create: ID=' + newNotificationId +
115 ', ERROR=' + errorMessage);
119 if (onCardShown !== undefined)
120 onCardShown(cardCreateInfo);
122 scheduleHiding(cardId, cardCreateInfo.hideTime);
125 // Update existing notification.
126 instrumented.notifications.update(
128 cardCreateInfo.notification,
129 function(wasUpdated) {
130 if (!wasUpdated || chrome.runtime.lastError) {
131 var errorMessage = chrome.runtime.lastError &&
132 chrome.runtime.lastError.message;
133 console.error('notifications.update: UPDATED=' + wasUpdated +
134 ', ERROR=' + errorMessage);
138 scheduleHiding(cardId, cardCreateInfo.hideTime);
144 * Updates/creates a card notification with new data.
145 * @param {string} cardId Card ID.
146 * @param {MergedCard} card Google Now card from the server.
147 * @param {number=} previousVersion The version of the shown card with
148 * this id, if it exists, undefined otherwise.
149 * @param {function(CardCreateInfo)=} onCardShown Optional parameter called
150 * when each card is shown.
151 * @return {Object} Notification data entry for this card.
153 function update(cardId, card, previousVersion, onCardShown) {
154 console.log('cardManager.update ' + JSON.stringify(card) + ' ' +
157 chrome.alarms.clear(cardHidePrefix + cardId);
159 var cardCreateInfo = {
160 notification: card.notification,
161 hideTime: card.trigger.hideTime,
162 version: card.version,
163 previousVersion: previousVersion,
164 locationBased: card.locationBased
167 var shownImmediately = false;
168 var cardShowAlarmName = cardShowPrefix + cardId;
169 if (card.trigger.showTime && card.trigger.showTime > Date.now()) {
170 // Card needs to be shown later.
171 console.log('cardManager.update: postponed');
173 when: card.trigger.showTime
175 chrome.alarms.create(cardShowAlarmName, alarmInfo);
177 // Card needs to be shown immediately.
178 console.log('cardManager.update: immediate');
179 chrome.alarms.clear(cardShowAlarmName);
180 showNotification(cardId, cardCreateInfo, onCardShown);
184 actionUrls: card.actionUrls,
185 cardCreateInfo: cardCreateInfo,
186 dismissals: card.dismissals
191 * Removes a card notification.
192 * @param {string} cardId Card ID.
193 * @param {boolean} clearStorage True if the information associated with the
194 * card should be erased from chrome.storage.
196 function clear(cardId, clearStorage) {
197 console.log('cardManager.clear ' + cardId);
199 chrome.notifications.clear(cardId, function() {});
200 chrome.alarms.clear(cardShowPrefix + cardId);
201 chrome.alarms.clear(cardHidePrefix + cardId);
204 instrumented.storage.local.get(
205 ['notificationsData', 'notificationGroups'],
208 items.notificationsData = items.notificationsData || {};
209 items.notificationGroups = items.notificationGroups || {};
211 delete items.notificationsData[cardId];
213 for (var groupName in items.notificationGroups) {
214 var group = items.notificationGroups[groupName];
215 for (var i = 0; i != group.cards.length; ++i) {
216 if (group.cards[i].chromeNotificationId == cardId) {
217 group.cards.splice(i, 1);
223 chrome.storage.local.set(items);
228 instrumented.alarms.onAlarm.addListener(function(alarm) {
229 console.log('cardManager.onAlarm ' + JSON.stringify(alarm));
231 if (alarm.name.indexOf(cardShowPrefix) == 0) {
232 // Alarm to show the card.
233 tasks.add(SHOW_CARD_TASK_NAME, function() {
234 var cardId = alarm.name.substring(cardShowPrefix.length);
235 instrumented.storage.local.get('notificationsData', function(items) {
236 console.log('cardManager.onAlarm.get ' + JSON.stringify(items));
237 if (!items || !items.notificationsData)
239 var notificationData = items.notificationsData[cardId];
240 if (!notificationData)
243 var cardShownCallback = undefined;
244 if (localStorage['locationCardsShown'] <
245 LOCATION_CARDS_LINK_THRESHOLD) {
246 cardShownCallback = countLocationCard;
250 cardId, notificationData.cardCreateInfo, cardShownCallback);
253 } else if (alarm.name.indexOf(cardHidePrefix) == 0) {
254 // Alarm to hide the card.
255 tasks.add(CLEAR_CARD_TASK_NAME, function() {
256 var cardId = alarm.name.substring(cardHidePrefix.length);