OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 /** | 5 /** |
6 * @type {number} | 6 * @type {number} |
7 * @const | 7 * @const |
8 */ | 8 */ |
9 var FEEDBACK_WIDTH = 500; | 9 var FEEDBACK_WIDTH = 500; |
10 /** | 10 /** |
11 * @type {number} | 11 * @type {number} |
12 * @const | 12 * @const |
13 */ | 13 */ |
14 var FEEDBACK_HEIGHT = 585; | 14 var FEEDBACK_HEIGHT = 585; |
15 | 15 |
16 /** | 16 /** |
17 * @type {string} | 17 * @type {string} |
18 * @const | 18 * @const |
19 */ | 19 */ |
20 var FEEDBACK_DEFAULT_WINDOW_ID = 'default_window'; | 20 var FEEDBACK_DEFAULT_WINDOW_ID = 'default_window'; |
21 | 21 |
22 /** | |
23 * The feedback info received initially when the feedback UI was first requested | |
24 * to start. | |
25 * @type {Object} | |
26 */ | |
27 var initialFeedbackInfo = null; | |
28 | |
29 /** | |
30 * The feedbak info that is ready to be sent later when the system information | |
31 * becomes available. | |
32 * @type {Object} | |
33 */ | |
34 var finalFeedbackInfo = null; | |
35 | |
36 /** | |
37 * The system information received from the C++ side. | |
38 * @type {Object} | |
39 */ | |
40 var systemInfo = null; | |
41 | |
42 /** | |
43 * True if the system information has been received, false otherwise. | |
44 * @type {boolean} | |
45 */ | |
46 var isSystemInfoReady = false; | |
47 | |
48 /** | |
49 * A callback to be invoked when the system information is ready. | |
50 * @type {function(sysInfo)} | |
51 */ | |
52 var onSystemInfoReadyCallback = null; | |
53 | |
54 // To generate a hashed extension ID, use a sha-256 hash, all in lower case. | 22 // To generate a hashed extension ID, use a sha-256 hash, all in lower case. |
55 // Example: | 23 // Example: |
56 // echo -n 'abcdefghijklmnopqrstuvwxyzabcdef' | sha1sum | \ | 24 // echo -n 'abcdefghijklmnopqrstuvwxyzabcdef' | sha1sum | \ |
57 // awk '{print toupper($1)}' | 25 // awk '{print toupper($1)}' |
58 var whitelistedExtensionIds = [ | 26 var whitelistedExtensionIds = [ |
59 '12E618C3C6E97495AAECF2AC12DEB082353241C6', // QuickOffice | 27 '12E618C3C6E97495AAECF2AC12DEB082353241C6', // QuickOffice |
60 '3727DD3E564B6055387425027AD74C58784ACC15', // QuickOffice | 28 '3727DD3E564B6055387425027AD74C58784ACC15', // QuickOffice |
61 '2FC374607C2DF285634B67C64A2E356C607091C3', // QuickOffice | 29 '2FC374607C2DF285634B67C64A2E356C607091C3', // QuickOffice |
62 '2843C1E82A9B6C6FB49308FDDF4E157B6B44BC2B', // G+ Photos | 30 '2843C1E82A9B6C6FB49308FDDF4E157B6B44BC2B', // G+ Photos |
63 '5B5DA6D054D10DB917AF7D9EAE3C56044D1B0B03', // G+ Photos | 31 '5B5DA6D054D10DB917AF7D9EAE3C56044D1B0B03', // G+ Photos |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
104 'A8208CCC87F8261AFAEB6B85D5E8D47372DDEA6B', // http://crbug.com/478929 | 72 'A8208CCC87F8261AFAEB6B85D5E8D47372DDEA6B', // http://crbug.com/478929 |
105 'B620CF4203315F9F2E046EDED22C7571A935958D', // http://crbug.com/510270 | 73 'B620CF4203315F9F2E046EDED22C7571A935958D', // http://crbug.com/510270 |
106 'B206D8716769728278D2D300349C6CB7D7DE2EF9', // http://crbug.com/510270 | 74 'B206D8716769728278D2D300349C6CB7D7DE2EF9', // http://crbug.com/510270 |
107 'EFCF5358672FEE04789FD2EC3638A67ADEDB6C8C', // http://crbug.com/514696 | 75 'EFCF5358672FEE04789FD2EC3638A67ADEDB6C8C', // http://crbug.com/514696 |
108 'FAD85BC419FE00995D196312F53448265EFA86F1', // http://crbug.com/516527 | 76 'FAD85BC419FE00995D196312F53448265EFA86F1', // http://crbug.com/516527 |
109 'F33B037DEDA65F226B7409C2ADB0CF3F8565AB03', // http://crbug.com/541769 | 77 'F33B037DEDA65F226B7409C2ADB0CF3F8565AB03', // http://crbug.com/541769 |
110 '969C788BCBC82FBBE04A17360CA165C23A419257', // http://crbug.com/541769 | 78 '969C788BCBC82FBBE04A17360CA165C23A419257', // http://crbug.com/541769 |
111 '3BC3740BFC58F06088B300274B4CFBEA20136342', // http://crbug.com/541769 | 79 '3BC3740BFC58F06088B300274B4CFBEA20136342', // http://crbug.com/541769 |
112 ]; | 80 ]; |
113 | 81 |
82 /** | |
83 * A FeedbackRequest object represents a unique feedback report, requested by an | |
84 * instance of the feedback window. It contains the system information specific | |
85 * to this report, the full feedbackInfo, and callbacks to send the report upon | |
86 * request. | |
87 */ | |
88 class FeedbackRequest { | |
89 constructor(requestId, feedbackInfo) { | |
90 this.id_ = requestId; | |
91 this.feedbackInfo_ = feedbackInfo; | |
92 this.onSystemInfoReadyCallback_ = null; | |
93 this.isSystemInfoReady_ = false; | |
94 } | |
95 | |
96 /** | |
97 * Called when the system information is sent from the C++ side. | |
98 * @param {Object} sysInfo The received system information. | |
99 */ | |
100 getSystemInformationCallback(sysInfo) { | |
101 this.isSystemInfoReady_ = true; | |
102 | |
103 // Combine the newly received system information with whatever system | |
104 // information we have in the feedback info (if any). | |
105 if (this.feedbackInfo_.systemInformation) { | |
106 this.feedbackInfo_.systemInformation = | |
107 this.feedbackInfo_.systemInformation.concat(sysInfo); | |
108 } else { | |
109 this.feedbackInfo_.systemInformation = sysInfo; | |
110 } | |
111 | |
112 if (this.onSystemInfoReadyCallback_ != null) { | |
113 this.onSystemInfoReadyCallback_(); | |
114 this.onSystemInfoReadyCallback_ = null; | |
115 } | |
116 } | |
117 | |
118 /** | |
119 * Retrieves the system information for this request object. | |
120 * @param {function()} callback Invoked to notify the listener that the system | |
121 * information has been received. | |
122 */ | |
123 getSystemInformation(callback) { | |
124 if (this.isSystemInfoReady_) { | |
125 callback(); | |
126 return; | |
127 } | |
128 | |
129 this.onSystemInfoReadyCallback_ = callback; | |
130 // The C++ side must reply to the callback specific to this object. | |
131 var boundCallback = this.getSystemInformationCallback.bind(this); | |
132 chrome.feedbackPrivate.getSystemInformation(boundCallback); | |
133 } | |
134 | |
135 /** | |
136 * Sends the feedback report represented by the object, either now if system | |
137 * information is ready, or later once it is. | |
138 * @param {boolean} useSystemInfo True if the user would like the system | |
139 * information to be sent with the report. | |
140 */ | |
141 sendReport(useSystemInfo) { | |
142 if (useSystemInfo && !this.isSystemInfoReady_) { | |
143 this.onSystemInfoReadyCallback_ = this.sendReportNow; | |
144 return; | |
145 } | |
146 | |
147 this.sendReportNow(); | |
148 } | |
149 | |
150 /** | |
151 * Sends the report immediately and removes this object once the report is | |
152 * sent. | |
153 */ | |
154 sendReportNow() { | |
155 /** @const */ var ID = this.id_; | |
156 chrome.feedbackPrivate.sendFeedback(this.feedbackInfo_, | |
157 function(result) { | |
158 console.log('Feedback: Report sent for request with ID ' + ID); | |
159 | |
160 // The following deletes this FeedbackRequest object. | |
161 feedbackRequestsMap.delete(ID); | |
162 }); | |
163 } | |
164 }; | |
165 | |
166 /** | |
167 * Maps each FeedbackRequest object by its unique ID. | |
168 * @type {Map} | |
169 */ | |
170 var feedbackRequestsMap = new Map(); | |
171 | |
172 /** | |
173 * Used to generate unique IDs for FeedbackRequest objects. | |
174 * @type {number} | |
175 */ | |
176 var lastUsedId = 0; | |
114 | 177 |
115 /** | 178 /** |
116 * Function to determine whether or not a given extension id is whitelisted to | 179 * Function to determine whether or not a given extension id is whitelisted to |
117 * invoke the feedback UI. If the extension is whitelisted, the callback to | 180 * invoke the feedback UI. If the extension is whitelisted, the callback to |
118 * start the Feedback UI will be called. | 181 * start the Feedback UI will be called. |
119 * @param {string} id the id of the sender extension. | 182 * @param {string} id the id of the sender extension. |
120 * @param {Function} startFeedbackCallback The callback function that will | 183 * @param {Function} startFeedbackCallback The callback function that will |
121 * will start the feedback UI. | 184 * will start the feedback UI. |
122 * @param {Object} feedbackInfo The feedback info object to pass to the | 185 * @param {Object} feedbackInfo The feedback info object to pass to the |
123 * start feedback UI callback. | 186 * start feedback UI callback. |
(...skipping 14 matching lines...) Expand all Loading... | |
138 } | 201 } |
139 | 202 |
140 /** | 203 /** |
141 * Callback which gets notified once our feedback UI has loaded and is ready to | 204 * Callback which gets notified once our feedback UI has loaded and is ready to |
142 * receive its initial feedback info object. | 205 * receive its initial feedback info object. |
143 * @param {Object} request The message request object. | 206 * @param {Object} request The message request object. |
144 * @param {Object} sender The sender of the message. | 207 * @param {Object} sender The sender of the message. |
145 * @param {function(Object)} sendResponse Callback for sending a response. | 208 * @param {function(Object)} sendResponse Callback for sending a response. |
146 */ | 209 */ |
147 function feedbackReadyHandler(request, sender, sendResponse) { | 210 function feedbackReadyHandler(request, sender, sendResponse) { |
148 if (request.ready) { | 211 if (request.ready) |
149 chrome.runtime.sendMessage( | 212 chrome.runtime.sendMessage({sentFromEventPage: true}); |
150 {sentFromEventPage: true, data: initialFeedbackInfo}); | |
151 } | |
152 } | 213 } |
153 | 214 |
154 | |
155 /** | 215 /** |
156 * Callback which gets notified if another extension is requesting feedback. | 216 * Callback which gets notified if another extension is requesting feedback. |
157 * @param {Object} request The message request object. | 217 * @param {Object} request The message request object. |
158 * @param {Object} sender The sender of the message. | 218 * @param {Object} sender The sender of the message. |
159 * @param {function(Object)} sendResponse Callback for sending a response. | 219 * @param {function(Object)} sendResponse Callback for sending a response. |
160 */ | 220 */ |
161 function requestFeedbackHandler(request, sender, sendResponse) { | 221 function requestFeedbackHandler(request, sender, sendResponse) { |
162 if (request.requestFeedback) | 222 if (request.requestFeedback) |
163 senderWhitelisted(sender.id, startFeedbackUI, request.feedbackInfo); | 223 senderWhitelisted(sender.id, startFeedbackUI, request.feedbackInfo); |
164 } | 224 } |
165 | 225 |
166 /** | 226 /** |
167 * Called when the system information is sent from the C++ side. | |
168 * @param {Object} sysInfo The received system information. | |
169 */ | |
170 | |
171 function getSystemInformationCallback(sysInfo) { | |
172 systemInfo = sysInfo; | |
173 isSystemInfoReady = true; | |
174 if (onSystemInfoReadyCallback != null) | |
175 onSystemInfoReadyCallback(sysInfo); | |
176 } | |
177 | |
178 /** | |
179 * If the user requested to send the report before the system information was | |
180 * received, this callback will be invoked once the system information is ready | |
181 * to send the report then. | |
182 * @param {Object} sysInfo The received system information. | |
183 */ | |
184 | |
185 function onSysInfoReadyForSend(sysInfo) { | |
186 // Combine the newly received system information with whatever system | |
187 // information we have in the final feedback info (if any). | |
188 if (finalFeedbackInfo.systemInformation) { | |
189 finalFeedbackInfo.systemInformation = | |
190 finalFeedbackInfo.systemInformation.concat(sysInfo); | |
191 } else { | |
192 finalFeedbackInfo.systemInformation = sysInfo; | |
193 } | |
194 | |
195 chrome.feedbackPrivate.sendFeedback(finalFeedbackInfo, function(result) {}); | |
196 } | |
197 | |
198 /** | |
199 * Callback which starts up the feedback UI. | 227 * Callback which starts up the feedback UI. |
200 * @param {Object} feedbackInfo Object containing any initial feedback info. | 228 * @param {Object} feedbackInfo Object containing any initial feedback info. |
201 */ | 229 */ |
202 function startFeedbackUI(feedbackInfo) { | 230 function startFeedbackUI(feedbackInfo) { |
203 var win = chrome.app.window.get(FEEDBACK_DEFAULT_WINDOW_ID); | 231 var win = chrome.app.window.get(FEEDBACK_DEFAULT_WINDOW_ID); |
204 if (win) { | 232 if (win) { |
205 win.show(); | 233 win.show(); |
206 return; | 234 return; |
207 } | 235 } |
208 chrome.app.window.create('html/default.html', { | 236 chrome.app.window.create('html/default.html', { |
209 frame: 'none', | 237 frame: 'none', |
210 id: FEEDBACK_DEFAULT_WINDOW_ID, | 238 id: FEEDBACK_DEFAULT_WINDOW_ID, |
211 width: FEEDBACK_WIDTH, | 239 width: FEEDBACK_WIDTH, |
212 height: FEEDBACK_HEIGHT, | 240 height: FEEDBACK_HEIGHT, |
213 hidden: true, | 241 hidden: true, |
214 resizable: false }, | 242 resizable: false }, |
215 function(appWindow) { | 243 function(appWindow) { |
216 // Initialize the state of the app only once upon the creation of the | 244 // Generate a unique feedback request ID for this feedback window. |
217 // feedback UI window. | 245 // A FeedbackRequest object is used to represent this instance of the |
218 initialFeedbackInfo = feedbackInfo; | 246 // feedback window. |
219 finalFeedbackInfo = null; | 247 /** @const */ var ID = ++lastUsedId; |
220 systemInfo = null; | 248 /** @const */ var REQUEST = new FeedbackRequest(ID, feedbackInfo); |
xiyuan
2016/03/15 19:54:07
|REQUEST| is not really a const. Let remove @const
afakhry
2016/03/16 00:45:34
Done.
| |
221 isSystemInfoReady = false; | 249 feedbackRequestsMap.set(ID, REQUEST); |
222 onSystemInfoReadyCallback = null; | 250 // The feedbackInfo member of the new window should refer to the one in |
251 // its corresponding FeedbackRequest object to avoid copying and | |
252 // duplicatations. | |
253 appWindow.contentWindow.feedbackInfo = REQUEST.feedbackInfo_; | |
254 | |
255 // When this instance of the feedback window is closed, the | |
256 // corresponding FeedbackRequest object must be deleted unless it needs | |
257 // to be kept alive until the report is sent later. | |
258 var deferRequestdeleteUntilSent = false; | |
223 | 259 |
224 // Define some functions for the new window so that it can call back | 260 // Define some functions for the new window so that it can call back |
225 // into here. | 261 // into here. |
226 | 262 |
227 // Define a function for the new window to get the system information. | 263 // Define a function for the new window to get the system information. |
228 appWindow.contentWindow.getSystemInformation = function(callback) { | 264 appWindow.contentWindow.getSystemInformation = function(callback) { |
229 if (!isSystemInfoReady) { | 265 REQUEST.getSystemInformation(callback); |
230 onSystemInfoReadyCallback = callback; | |
231 chrome.feedbackPrivate.getSystemInformation( | |
232 getSystemInformationCallback); | |
233 return; | |
234 } | |
235 | |
236 callback(systemInfo); | |
237 }; | 266 }; |
238 | 267 |
239 // Define a function to be called by the new window when the report is | 268 // Define a function to request sending the feedback report. |
240 // not ready yet, and has to be sent later when the system information | 269 appWindow.contentWindow.sendFeedbackReport = function(useSystemInfo) { |
241 // is received. | 270 // The report will be sent by the request object. Keep it alive until |
242 appWindow.contentWindow.sendReportLater = function(feedbackInfo) { | 271 // the report is sent. |
243 finalFeedbackInfo = feedbackInfo; | 272 deferRequestdeleteUntilSent = true; |
244 if (!isSystemInfoReady) { | 273 REQUEST.sendReport(useSystemInfo); |
245 onSystemInfoReadyCallback = onSysInfoReadyForSend; | |
246 return; | |
247 } | |
248 | |
249 onSysInfoReadyForSend(systemInfo); | |
250 }; | 274 }; |
251 | 275 |
252 // Returns whether the system information has been received or not. | 276 // Observe when the window is closed. |
253 appWindow.contentWindow.isSystemInfoReady = function() { | 277 appWindow.onClosed.addListener(function() { |
254 return isSystemInfoReady; | 278 if (!deferRequestdeleteUntilSent) |
255 }; | 279 feedbackRequestsMap.delete(ID); |
280 }); | |
256 }); | 281 }); |
257 } | 282 } |
258 | 283 |
259 chrome.runtime.onMessage.addListener(feedbackReadyHandler); | 284 chrome.runtime.onMessage.addListener(feedbackReadyHandler); |
260 chrome.runtime.onMessageExternal.addListener(requestFeedbackHandler); | 285 chrome.runtime.onMessageExternal.addListener(requestFeedbackHandler); |
261 chrome.feedbackPrivate.onFeedbackRequested.addListener(startFeedbackUI); | 286 chrome.feedbackPrivate.onFeedbackRequested.addListener(startFeedbackUI); |
OLD | NEW |