1 // Copyright 2014 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 cr.define('chrome.invalidations', function() { 6 /** 7 * Local variable where we maintain a count of the invalidations received 8 * and of every ObjectId that has ever been updated (note that this doesn't 9 * log any invalidations ocurred prior to opening the about:invalidation 10 * page). 11 */ 12 var tableObjects = {}; 13 14 /** 15 * Local variable that contains the detailed information in an object form. 16 * This was done this way as to allow multiple calls to updateDetailedStatus 17 * to keep adding new items. 18 */ 19 var cachedDetails = {}; 20 21 function quote(str) { 22 return '\"' + str + '\"'; 23 } 24 25 function nowTimeString() { 26 return '[' + new Date().getTime() + '] '; 27 } 28 29 /** 30 * Appends a string to a textarea log. 31 * @param {string} logMessage The string to be appended. 32 */ 33 function appendToLog(logMessage) { 34 var invalidationsLog = $('invalidations-log'); 35 invalidationsLog.value += logMessage + '\n'; 36 } 37 /** 38 * Updates the jstemplate with the latest ObjectIds, ordered by registrar. 39 */ 40 function repaintTable() { 41 var keys = []; 42 for (var key in tableObjects) { 43 keys.push(key); 44 } 45 keys.sort(); 46 var sortedInvalidations = []; 47 for (var i = 0; i < keys.length; i++) { 48 sortedInvalidations.push(tableObjects[keys[i]]); 49 } 50 var wrapped = { objectsidtable: sortedInvalidations }; 51 jstProcess(new JsEvalContext(wrapped), $('objectsid-table-div')); 52 } 53 54 /** 55 * Shows the current state of the InvalidatorService. 56 * @param {string} newState The string to be displayed and logged. 57 * @param {number} lastChangedTime The time in epoch when the state was last 58 * changed. 59 */ 60 function updateInvalidatorState(newState, lastChangedTime) { 61 var logMessage = nowTimeString() + 62 'Invalidations service state changed to ' + quote(newState); 63 64 appendToLog(logMessage); 65 $('invalidations-state').textContent = newState + ' (since ' + 66 new Date(lastChangedTime) + ')'; 67 } 68 69 /** 70 * Adds to the log the latest invalidations received 71 * @param {!Array.<!Object>} allInvalidations The array of ObjectId 72 * that contains the invalidations received by the InvalidatorService. 73 */ 74 function logInvalidations(allInvalidations) { 75 for (var i = 0; i < allInvalidations.length; i++) { 76 var inv = allInvalidations[i]; 77 if (inv.hasOwnProperty('objectId')) { 78 var logMessage = nowTimeString() + 79 'Received Invalidation with type ' + 80 quote(inv.objectId.name) + 81 ' version ' + 82 quote((inv.isUnknownVersion ? 'Unknown' : inv.version)) + 83 ' with payload ' + 84 quote(inv.payload); 85 86 appendToLog(logMessage); 87 var isInvalidation = true; 88 logToTable(inv, isInvalidation); 89 } 90 } 91 repaintTable(); 92 } 93 94 /** 95 * Marks a change in the table whether a new invalidation has arrived 96 * or a new ObjectId is currently being added or updated. 97 * @param {!Object} oId The ObjectId being added or updated. 98 * @param {!boolean} isInvaldation A flag that says that an invalidation 99 * for this ObjectId has arrived or we just need to add it to the table 100 * as it was just updated its state. 101 */ 102 function logToTable(oId, isInvalidation) { 103 var registrar = oId.registrar; 104 var name = oId.objectId.name; 105 var source = oId.objectId.source; 106 var totalCount = oId.objectId.totalCount || 0; 107 var key = source + '-' + name; 108 var time = new Date(); 109 var version = oId.isUnknownVersion ? '?' : 110 oId.version; 111 var payload = ''; 112 if (oId.hasOwnProperty('payload')) 113 payload = oId.payload; 114 if (!(key in tableObjects)) { 115 tableObjects[key] = { 116 name: name, 117 source: source, 118 totalCount: totalCount, 119 sessionCount: 0, 120 registrar: registrar, 121 time: '', 122 version: '', 123 payload: '', 124 type: 'content' 125 }; 126 } 127 // Refresh the type to be a content because it might have been 128 // greyed out. 129 tableObjects[key].type = 'content'; 130 if (isInvalidation) { 131 tableObjects[key].totalCount = tableObjects[key].totalCount + 1; 132 tableObjects[key].sessionCount = tableObjects[key].sessionCount + 1; 133 tableObjects[key].time = time.toTimeString(); 134 tableObjects[key].version = version; 135 tableObjects[key].payload = payload; 136 } 137 } 138 139 /** 140 * Shows the handlers that are currently registered for invalidations 141 * (but might not have objects ids registered yet). 142 * @param {!Array.<string>} allHandlers An array of Strings that are 143 * the names of all the handlers currently registered in the 144 * InvalidatorService. 145 */ 146 function updateHandlers(allHandlers) { 147 var allHandlersFormatted = allHandlers.join(', '); 148 $('registered-handlers').textContent = allHandlersFormatted; 149 var logMessage = nowTimeString() + 150 'InvalidatorHandlers currently registered: ' + allHandlersFormatted; 151 appendToLog(logMessage); 152 } 153 154 /** 155 * Updates the table with the objects ids registered for invalidations 156 * @param {string} registrar The name of the owner of the InvalidationHandler 157 * that is registered for invalidations 158 * @param {Array of Object} allIds An array of ObjectsIds that are currently 159 * registered for invalidations. It is not differential (as in, whatever 160 * is not registered now but was before, it mean it was taken out the 161 * registered objects) 162 */ 163 function updateIds(registrar, allIds) { 164 // Grey out every datatype assigned to this registrar 165 // (and reenable them later in case they are still registered). 166 for (var key in tableObjects) { 167 if (tableObjects[key]['registrar'] === registrar) 168 tableObjects[key].type = 'greyed'; 169 } 170 // Reenable those ObjectsIds still registered with this registrar. 171 for (var i = 0; i < allIds.length; i++) { 172 var oId = { objectId: allIds[i], registrar: registrar }; 173 var isInvalidation = false; 174 logToTable(oId, isInvalidation); 175 } 176 repaintTable(); 177 } 178 179 /** 180 * Update the internal status display, merging new detailed information. 181 * @param {!Object} newDetails The dictionary containing assorted debugging 182 * details (e.g. Network Channel information). 183 */ 184 function updateDetailedStatus(newDetails) { 185 for (var key in newDetails) { 186 cachedDetails[key] = newDetails[key]; 187 } 188 $('internal-display').value = JSON.stringify(cachedDetails, null, 2); 189 } 190 191 /** 192 * Function that notifies the InvalidationsMessageHandler that the UI is 193 * ready to receive real-time notifications. 194 */ 195 function onLoadWork() { 196 $('request-detailed-status').onclick = function() { 197 cachedDetails = {}; 198 chrome.send('requestDetailedStatus'); 199 }; 200 chrome.send('doneLoading'); 201 } 202 203 return { 204 logInvalidations: logInvalidations, 205 onLoadWork: onLoadWork, 206 updateDetailedStatus: updateDetailedStatus, 207 updateHandlers: updateHandlers, 208 updateIds: updateIds, 209 updateInvalidatorState: updateInvalidatorState, 210 }; 211 }); 212 213 document.addEventListener('DOMContentLoaded', chrome.invalidations.onLoadWork); 214