Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(292)

Side by Side Diff: chrome/browser/resources/print_preview/cloud_print_interface.js

Issue 233623003: Remember and restore the account last used destination is registered for. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 cr.define('cloudprint', function() { 5 cr.define('cloudprint', function() {
6 'use strict'; 6 'use strict';
7 7
8 /** 8 /**
9 * API to the Google Cloud Print service. 9 * API to the Google Cloud Print service.
10 * @param {string} baseUrl Base part of the Google Cloud Print service URL 10 * @param {string} baseUrl Base part of the Google Cloud Print service URL
(...skipping 29 matching lines...) Expand all
40 40
41 /** 41 /**
42 * Currently logged in users (identified by email) mapped to the Google 42 * Currently logged in users (identified by email) mapped to the Google
43 * session index. 43 * session index.
44 * @type {!Object.<string, number>} 44 * @type {!Object.<string, number>}
45 * @private 45 * @private
46 */ 46 */
47 this.userSessionIndex_ = {}; 47 this.userSessionIndex_ = {};
48 48
49 /** 49 /**
50 * Last received XSRF token. Sent as a parameter in every request. 50 * Stores last received XSRF tokens for each user account. Sent as
51 * @type {string} 51 * a parameter with every request.
52 * @type {!Object.<string, string>}
52 * @private 53 * @private
53 */ 54 */
54 this.xsrfToken_ = ''; 55 this.xsrfTokens_ = {};
55 56
56 /** 57 /**
57 * Pending requests delayed until we get access token. 58 * Pending requests delayed until we get access token.
58 * @type {!Array.<!CloudPrintRequest>} 59 * @type {!Array.<!CloudPrintRequest>}
59 * @private 60 * @private
60 */ 61 */
61 this.requestQueue_ = []; 62 this.requestQueue_ = [];
62 63
63 /** 64 /**
64 * Outstanding cloud destination search requests. 65 * Outstanding cloud destination search requests.
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 169
169 /** 170 /**
170 * Sends Google Cloud Print search API request. 171 * Sends Google Cloud Print search API request.
171 * @param {print_preview.Destination.Origin=} opt_origin When specified, 172 * @param {print_preview.Destination.Origin=} opt_origin When specified,
172 * searches destinations for {@code opt_origin} only, otherwise starts 173 * searches destinations for {@code opt_origin} only, otherwise starts
173 * searches for all origins. 174 * searches for all origins.
174 */ 175 */
175 search: function(opt_origin) { 176 search: function(opt_origin) {
176 var origins = 177 var origins =
177 opt_origin && [opt_origin] || CloudPrintInterface.CLOUD_ORIGINS_; 178 opt_origin && [opt_origin] || CloudPrintInterface.CLOUD_ORIGINS_;
178 // Terminate outstanding search requests for all requested origins. 179 this.abortSearchRequests_(origins);
179 this.outstandingCloudSearchRequests_ =
180 this.outstandingCloudSearchRequests_.filter(function(request) {
181 if (origins.indexOf(request.origin) >= 0) {
182 request.xhr.abort();
183 return false;
184 }
185 return true;
186 });
187 this.search_(true, origins); 180 this.search_(true, origins);
188 this.search_(false, origins); 181 this.search_(false, origins);
189 }, 182 },
190 183
191 /** 184 /**
192 * Sends Google Cloud Print search API requests. 185 * Sends Google Cloud Print search API requests.
193 * @param {boolean} isRecent Whether to search for only recently used 186 * @param {boolean} isRecent Whether to search for only recently used
194 * printers. 187 * printers.
195 * @param {!Array.<!print_preview.Destination.Origin>} origins Origins to 188 * @param {!Array.<!print_preview.Destination.Origin>} origins Origins to
196 * search printers for. 189 * search printers for.
197 * @private 190 * @private
198 */ 191 */
199 search_: function(isRecent, origins) { 192 search_: function(isRecent, origins) {
200 var params = [ 193 var params = [
201 new HttpParam('connection_status', 'ALL'), 194 new HttpParam('connection_status', 'ALL'),
202 new HttpParam('client', 'chrome'), 195 new HttpParam('client', 'chrome'),
203 new HttpParam('use_cdd', 'true') 196 new HttpParam('use_cdd', 'true')
204 ]; 197 ];
205 if (isRecent) { 198 if (isRecent) {
206 params.push(new HttpParam('q', '^recent')); 199 params.push(new HttpParam('q', '^recent'));
207 } 200 }
208 origins.forEach(function(origin) { 201 origins.forEach(function(origin) {
209 var cpRequest = 202 var cpRequest = this.buildRequest_(
210 this.buildRequest_('GET', 'search', params, origin, 203 'GET',
211 this.onSearchDone_.bind(this, isRecent)); 204 'search',
205 params,
206 origin,
207 this.userInfo_.activeUser,
Toscano 2014/04/11 04:24:00 Hmm, seems like a hidden contract that the search
Aleksey Shlyapnikov 2014/04/11 19:09:29 Done.
208 this.onSearchDone_.bind(this, isRecent));
212 this.outstandingCloudSearchRequests_.push(cpRequest); 209 this.outstandingCloudSearchRequests_.push(cpRequest);
213 this.sendOrQueueRequest_(cpRequest); 210 this.sendOrQueueRequest_(cpRequest);
214 }, this); 211 }, this);
215 }, 212 },
216 213
217 /** 214 /**
218 * Sends a Google Cloud Print submit API request. 215 * Sends a Google Cloud Print submit API request.
219 * @param {!print_preview.Destination} destination Cloud destination to 216 * @param {!print_preview.Destination} destination Cloud destination to
220 * print to. 217 * print to.
221 * @param {!print_preview.PrintTicketStore} printTicketStore Contains the 218 * @param {!print_preview.PrintTicketStore} printTicketStore Contains the
(...skipping 12 matching lines...) Expand all
234 new HttpParam('printerid', destination.id), 231 new HttpParam('printerid', destination.id),
235 new HttpParam('contentType', 'dataUrl'), 232 new HttpParam('contentType', 'dataUrl'),
236 new HttpParam('title', documentInfo.title), 233 new HttpParam('title', documentInfo.title),
237 new HttpParam('ticket', 234 new HttpParam('ticket',
238 printTicketStore.createPrintTicket(destination)), 235 printTicketStore.createPrintTicket(destination)),
239 new HttpParam('content', 'data:application/pdf;base64,' + data), 236 new HttpParam('content', 'data:application/pdf;base64,' + data),
240 new HttpParam('tag', 237 new HttpParam('tag',
241 '__google__chrome_version=' + chromeVersion), 238 '__google__chrome_version=' + chromeVersion),
242 new HttpParam('tag', '__google__os=' + navigator.platform) 239 new HttpParam('tag', '__google__os=' + navigator.platform)
243 ]; 240 ];
244 var cpRequest = this.buildRequest_('POST', 'submit', params, 241 var cpRequest = this.buildRequest_(
245 destination.origin, 242 'POST',
246 this.onSubmitDone_.bind(this)); 243 'submit',
244 params,
245 destination.origin,
246 destination.account,
247 this.onSubmitDone_.bind(this));
247 this.sendOrQueueRequest_(cpRequest); 248 this.sendOrQueueRequest_(cpRequest);
248 }, 249 },
249 250
250 /** 251 /**
251 * Sends a Google Cloud Print printer API request. 252 * Sends a Google Cloud Print printer API request.
252 * @param {string} printerId ID of the printer to lookup. 253 * @param {string} printerId ID of the printer to lookup.
253 * @param {!print_preview.Destination.Origin} origin Origin of the printer. 254 * @param {!print_preview.Destination.Origin} origin Origin of the printer.
255 * @param {string=} account Account this printer is registered for. When
256 * provided for COOKIES {@code origin}, and users sessions are still not
257 * known, will be checked against the response (both success and failure
258 * to get printer) and, if the active user account is not the one
259 * requested, {@code account} is activated and printer request reissued.
254 */ 260 */
255 printer: function(printerId, origin) { 261 printer: function(printerId, origin, account) {
256 var params = [ 262 var params = [
257 new HttpParam('printerid', printerId), 263 new HttpParam('printerid', printerId),
258 new HttpParam('use_cdd', 'true'), 264 new HttpParam('use_cdd', 'true'),
259 new HttpParam('printer_connection_status', 'true') 265 new HttpParam('printer_connection_status', 'true')
260 ]; 266 ];
261 var cpRequest = 267 this.sendOrQueueRequest_(this.buildRequest_(
262 this.buildRequest_('GET', 'printer', params, origin, 268 'GET',
263 this.onPrinterDone_.bind(this, printerId)); 269 'printer',
264 this.sendOrQueueRequest_(cpRequest); 270 params,
271 origin,
272 account,
273 this.onPrinterDone_.bind(this, printerId)));
265 }, 274 },
266 275
267 /** 276 /**
268 * Sends a Google Cloud Print update API request to accept (or reject) the 277 * Sends a Google Cloud Print update API request to accept (or reject) the
269 * terms-of-service of the given printer. 278 * terms-of-service of the given printer.
270 * @param {string} printerId ID of the printer to accept the 279 * @param {!print_preview.Destination} destination Destination to accept ToS
271 * terms-of-service for. 280 * for.
272 * @param {!print_preview.Destination.Origin} origin Origin of the printer. 281 * @param {boolean} isAccepted Whether the user accepted ToS or not.
273 * @param {boolean} isAccepted Whether the user accepted the
274 * terms-of-service.
275 */ 282 */
276 updatePrinterTosAcceptance: function(printerId, origin, isAccepted) { 283 updatePrinterTosAcceptance: function(destination, isAccepted) {
277 var params = [ 284 var params = [
278 new HttpParam('printerid', printerId), 285 new HttpParam('printerid', destination.id),
279 new HttpParam('is_tos_accepted', isAccepted) 286 new HttpParam('is_tos_accepted', isAccepted)
280 ]; 287 ];
281 var cpRequest = 288 var cpRequest = this.buildRequest_(
282 this.buildRequest_('POST', 'update', params, origin, 289 'POST',
283 this.onUpdatePrinterTosAcceptanceDone_.bind(this)); 290 'update',
291 params,
Vitaly Buka (NO REVIEWS) 2014/04/11 02:32:57 inconsistent
Aleksey Shlyapnikov 2014/04/11 19:09:29 Done.
292 destination.origin,
293 destination.account,
294 this.onUpdatePrinterTosAcceptanceDone_.bind(this));
284 this.sendOrQueueRequest_(cpRequest); 295 this.sendOrQueueRequest_(cpRequest);
285 }, 296 },
286 297
287 /** 298 /**
288 * Adds event listeners to relevant events. 299 * Adds event listeners to relevant events.
289 * @private 300 * @private
290 */ 301 */
291 addEventListeners_: function() { 302 addEventListeners_: function() {
292 this.tracker_.add( 303 this.tracker_.add(
293 this.nativeLayer_, 304 this.nativeLayer_,
294 print_preview.NativeLayer.EventType.ACCESS_TOKEN_READY, 305 print_preview.NativeLayer.EventType.ACCESS_TOKEN_READY,
295 this.onAccessTokenReady_.bind(this)); 306 this.onAccessTokenReady_.bind(this));
307 this.tracker_.add(
308 this.userInfo_,
309 print_preview.UserInfo.EventType.ACTIVE_USER_CHANGED,
310 this.onActiveUserChanged_.bind(this));
296 }, 311 },
297 312
298 /** 313 /**
299 * Builds request to the Google Cloud Print API. 314 * Builds request to the Google Cloud Print API.
300 * @param {string} method HTTP method of the request. 315 * @param {string} method HTTP method of the request.
301 * @param {string} action Google Cloud Print action to perform. 316 * @param {string} action Google Cloud Print action to perform.
302 * @param {Array.<!HttpParam>} params HTTP parameters to include in the 317 * @param {Array.<!HttpParam>} params HTTP parameters to include in the
303 * request. 318 * request.
304 * @param {!print_preview.Destination.Origin} origin Origin for destination. 319 * @param {!print_preview.Destination.Origin} origin Origin for destination.
320 * @param {?string} account Account the request is sent for. Can be
321 * {@code null} or empty string if the request is not cookie bound or
322 * is sent on behalf of the primary user.
305 * @param {function(number, Object, !print_preview.Destination.Origin)} 323 * @param {function(number, Object, !print_preview.Destination.Origin)}
306 * callback Callback to invoke when request completes. 324 * callback Callback to invoke when request completes.
307 * @return {!CloudPrintRequest} Partially prepared request. 325 * @return {!CloudPrintRequest} Partially prepared request.
308 * @private 326 * @private
309 */ 327 */
310 buildRequest_: function(method, action, params, origin, callback) { 328 buildRequest_: function(method, action, params, origin, account, callback) {
311 var url = this.baseUrl_ + '/' + action + '?xsrf='; 329 var url = this.baseUrl_ + '/' + action + '?xsrf=';
312 if (origin == print_preview.Destination.Origin.COOKIES) { 330 if (origin == print_preview.Destination.Origin.COOKIES) {
313 if (!this.xsrfToken_) { 331 var xsrfToken = this.xsrfTokens_[account];
332 if (!xsrfToken) {
314 // TODO(rltoscano): Should throw an error if not a read-only action or 333 // TODO(rltoscano): Should throw an error if not a read-only action or
315 // issue an xsrf token request. 334 // issue an xsrf token request.
316 } else { 335 } else {
317 url = url + this.xsrfToken_; 336 url = url + xsrfToken;
318 } 337 }
319 params = params || []; 338 if (account) {
320 if (this.userInfo_.activeUser) { 339 var index = this.userSessionIndex_[account] || 0;
321 var index = this.userSessionIndex_[this.userInfo_.activeUser] || 0;
322 if (index > 0) { 340 if (index > 0) {
323 params.push(new HttpParam('user', index)); 341 url += '&user=' + index;
324 } 342 }
325 } 343 }
326 } 344 }
327 var body = null; 345 var body = null;
328 if (params) { 346 if (params) {
329 if (method == 'GET') { 347 if (method == 'GET') {
330 url = params.reduce(function(partialUrl, param) { 348 url = params.reduce(function(partialUrl, param) {
331 return partialUrl + '&' + param.name + '=' + 349 return partialUrl + '&' + param.name + '=' +
332 encodeURIComponent(param.value); 350 encodeURIComponent(param.value);
333 }, url); 351 }, url);
(...skipping 15 matching lines...) Expand all
349 } 367 }
350 368
351 var xhr = new XMLHttpRequest(); 369 var xhr = new XMLHttpRequest();
352 xhr.open(method, url, true); 370 xhr.open(method, url, true);
353 xhr.withCredentials = 371 xhr.withCredentials =
354 (origin == print_preview.Destination.Origin.COOKIES); 372 (origin == print_preview.Destination.Origin.COOKIES);
355 for (var header in headers) { 373 for (var header in headers) {
356 xhr.setRequestHeader(header, headers[header]); 374 xhr.setRequestHeader(header, headers[header]);
357 } 375 }
358 376
359 return new CloudPrintRequest(xhr, body, origin, callback); 377 return new CloudPrintRequest(xhr, body, origin, account, callback);
360 }, 378 },
361 379
362 /** 380 /**
363 * Sends a request to the Google Cloud Print API or queues if it needs to 381 * Sends a request to the Google Cloud Print API or queues if it needs to
364 * wait OAuth2 access token. 382 * wait OAuth2 access token.
365 * @param {!CloudPrintRequest} request Request to send or queue. 383 * @param {!CloudPrintRequest} request Request to send or queue.
366 * @private 384 * @private
367 */ 385 */
368 sendOrQueueRequest_: function(request) { 386 sendOrQueueRequest_: function(request) {
369 if (request.origin == print_preview.Destination.Origin.COOKIES) { 387 if (request.origin == print_preview.Destination.Origin.COOKIES) {
(...skipping 30 matching lines...) Expand all
400 errorEvent.message = request.result['message']; 418 errorEvent.message = request.result['message'];
401 } else { 419 } else {
402 errorEvent.errorCode = 0; 420 errorEvent.errorCode = 0;
403 errorEvent.message = ''; 421 errorEvent.message = '';
404 } 422 }
405 errorEvent.origin = request.origin; 423 errorEvent.origin = request.origin;
406 return errorEvent; 424 return errorEvent;
407 }, 425 },
408 426
409 /** 427 /**
428 * Updates user info and session index from the {@code request} response.
429 * @param {!CloudPrintRequest} request Request to extract user info from.
430 * @private
431 */
432 setUsers_: function(request) {
433 if (request.origin == print_preview.Destination.Origin.COOKIES) {
434 var activeUser = request.result['request']['user'];
Toscano 2014/04/11 04:24:00 Maybe move this to right above line 440 since it's
Aleksey Shlyapnikov 2014/04/11 19:09:29 Done.
435 var users = request.result['request']['users'] || [];
436 this.userSessionIndex_ = {};
437 for (var i = 0; i < users.length; i++) {
438 this.userSessionIndex_[users[i]] = i;
439 }
440 this.userInfo_.setUsers(activeUser, users);
441 }
442 },
443
444 /**
445 * Terminates search requests for requested {@code origins}.
446 * @param {!Array.<print_preview.Destination.Origin>} origins Origins
447 * to terminate search requests for.
448 * @private
449 */
450 abortSearchRequests_: function(origins) {
451 this.outstandingCloudSearchRequests_ =
452 this.outstandingCloudSearchRequests_.filter(function(request) {
453 if (origins.indexOf(request.origin) >= 0) {
454 request.xhr.abort();
455 return false;
456 }
457 return true;
458 });
459 },
460
461 /**
462 * Called when active user account changes. Terminates all outstanding
463 * cookie based search requests.
464 * @private
465 */
466 onActiveUserChanged_: function() {
467 this.abortSearchRequests_([print_preview.Destination.Origin.COOKIES]);
Toscano 2014/04/11 04:24:00 Hmm, wouldn't it be simpler to only abort if and o
Aleksey Shlyapnikov 2014/04/11 19:09:29 The thing is, search request reply _is_ the source
Toscano 2014/04/12 02:09:08 But wait, how can you change the user if the first
Aleksey Shlyapnikov 2014/04/12 03:44:03 It's assumed that all search requests issued under
468 },
469
470 /**
410 * Called when a native layer receives access token. 471 * Called when a native layer receives access token.
411 * @param {Event} evt Contains the authentication type and access token. 472 * @param {Event} evt Contains the authentication type and access token.
412 * @private 473 * @private
413 */ 474 */
414 onAccessTokenReady_: function(event) { 475 onAccessTokenReady_: function(event) {
415 // TODO(vitalybuka): remove when other Origins implemented. 476 // TODO(vitalybuka): remove when other Origins implemented.
416 assert(event.authType == print_preview.Destination.Origin.DEVICE); 477 assert(event.authType == print_preview.Destination.Origin.DEVICE);
417 this.requestQueue_ = this.requestQueue_.filter(function(request) { 478 this.requestQueue_ = this.requestQueue_.filter(function(request) {
418 assert(request.origin == print_preview.Destination.Origin.DEVICE); 479 assert(request.origin == print_preview.Destination.Origin.DEVICE);
419 if (request.origin != event.authType) { 480 if (request.origin != event.authType) {
420 return true; 481 return true;
421 } 482 }
422 if (event.accessToken) { 483 if (event.accessToken) {
423 request.xhr.setRequestHeader('Authorization', 484 request.xhr.setRequestHeader('Authorization',
424 'Bearer ' + event.accessToken); 485 'Bearer ' + event.accessToken);
425 this.sendRequest_(request); 486 this.sendRequest_(request);
426 } else { // No valid token. 487 } else { // No valid token.
427 // Without abort status does not exists. 488 // Without abort status does not exist.
428 request.xhr.abort(); 489 request.xhr.abort();
429 request.callback(request); 490 request.callback(request);
430 } 491 }
431 return false; 492 return false;
432 }, this); 493 }, this);
433 }, 494 },
434 495
435 /** 496 /**
436 * Called when the ready-state of a XML http request changes. 497 * Called when the ready-state of a XML http request changes.
437 * Calls the successCallback with the result or dispatches an ERROR event. 498 * Calls the successCallback with the result or dispatches an ERROR event.
438 * @param {!CloudPrintRequest} request Request that was changed. 499 * @param {!CloudPrintRequest} request Request that was changed.
439 * @private 500 * @private
440 */ 501 */
441 onReadyStateChange_: function(request) { 502 onReadyStateChange_: function(request) {
442 if (request.xhr.readyState == 4) { 503 if (request.xhr.readyState == 4) {
443 if (request.xhr.status == 200) { 504 if (request.xhr.status == 200) {
444 request.result = JSON.parse(request.xhr.responseText); 505 request.result = JSON.parse(request.xhr.responseText);
445 if (request.origin == print_preview.Destination.Origin.COOKIES && 506 if (request.origin == print_preview.Destination.Origin.COOKIES &&
446 request.result['success']) { 507 request.result['success'] &&
447 this.xsrfToken_ = request.result['xsrf_token']; 508 request.account) {
509 this.xsrfTokens_[request.account] = request.result['xsrf_token'];
448 } 510 }
449 } 511 }
450 request.status = request.xhr.status; 512 request.status = request.xhr.status;
451 request.callback(request); 513 request.callback(request);
452 } 514 }
453 }, 515 },
454 516
455 /** 517 /**
456 * Called when the search request completes. 518 * Called when the search request completes.
457 * @param {boolean} isRecent Whether the search request was for recent 519 * @param {boolean} isRecent Whether the search request was for recent
458 * destinations. 520 * destinations.
459 * @param {!CloudPrintRequest} request Request that has been completed. 521 * @param {!CloudPrintRequest} request Request that has been completed.
460 * @private 522 * @private
461 */ 523 */
462 onSearchDone_: function(isRecent, request) { 524 onSearchDone_: function(isRecent, request) {
525 var lastRequestForThisOrigin = true;
463 this.outstandingCloudSearchRequests_ = 526 this.outstandingCloudSearchRequests_ =
464 this.outstandingCloudSearchRequests_.filter(function(item) { 527 this.outstandingCloudSearchRequests_.filter(function(item) {
528 if (item != request && item.origin == request.origin) {
529 lastRequestForThisOrigin = false;
530 }
465 return item != request; 531 return item != request;
466 }); 532 });
533 var activeUser = '';
534 if (request.origin == print_preview.Destination.Origin.COOKIES) {
535 activeUser = request.result['request']['user'];
536 }
537 var event = null;
467 if (request.xhr.status == 200 && request.result['success']) { 538 if (request.xhr.status == 200 && request.result['success']) {
468 var activeUser = ''; 539 // Extract printers.
469 if (request.origin == print_preview.Destination.Origin.COOKIES) {
470 activeUser = request.result['request']['user'];
471 }
472 var printerListJson = request.result['printers'] || []; 540 var printerListJson = request.result['printers'] || [];
473 var printerList = []; 541 var printerList = [];
474 printerListJson.forEach(function(printerJson) { 542 printerListJson.forEach(function(printerJson) {
475 try { 543 try {
476 printerList.push(cloudprint.CloudDestinationParser.parse( 544 printerList.push(cloudprint.CloudDestinationParser.parse(
Vitaly Buka (NO REVIEWS) 2014/04/11 02:32:57 maybe extractPrinters_
Aleksey Shlyapnikov 2014/04/11 19:09:29 This is the only place printer list is parsed, I'd
477 printerJson, request.origin, activeUser)); 545 printerJson, request.origin, activeUser));
478 } catch (err) { 546 } catch (err) {
479 console.error('Unable to parse cloud print destination: ' + err); 547 console.error('Unable to parse cloud print destination: ' + err);
480 } 548 }
481 }); 549 });
482 var searchDoneEvent = 550 // Extract users.
483 new Event(CloudPrintInterface.EventType.SEARCH_DONE); 551 this.setUsers_(request);
Vitaly Buka (NO REVIEWS) 2014/04/11 02:32:57 setUsers_ -> extractUsers_
Aleksey Shlyapnikov 2014/04/11 19:09:29 It updates userInfo_ state, not just extracts user
484 searchDoneEvent.printers = printerList; 552 // Dispatch SEARCH_DONE event.
485 searchDoneEvent.origin = request.origin; 553 event = new Event(CloudPrintInterface.EventType.SEARCH_DONE);
486 searchDoneEvent.isRecent = isRecent; 554 event.origin = request.origin;
487 if (request.origin == print_preview.Destination.Origin.COOKIES) { 555 event.printers = printerList;
488 var users = request.result['request']['users'] || []; 556 event.isRecent = isRecent;
489 this.userSessionIndex_ = {};
490 for (var i = 0; i < users.length; i++) {
491 this.userSessionIndex_[users[i]] = i;
492 }
493 this.userInfo_.setUsers(activeUser, users);
494 }
495 this.dispatchEvent(searchDoneEvent);
496 } else { 557 } else {
497 var errorEvent = this.createErrorEvent_( 558 event = this.createErrorEvent_(
498 CloudPrintInterface.EventType.SEARCH_FAILED, request); 559 CloudPrintInterface.EventType.SEARCH_FAILED,
499 this.dispatchEvent(errorEvent); 560 request);
500 } 561 }
562 event.user = activeUser;
563 event.searchDone = lastRequestForThisOrigin;
564 this.dispatchEvent(event);
501 }, 565 },
502 566
503 /** 567 /**
504 * Called when the submit request completes. 568 * Called when the submit request completes.
505 * @param {!CloudPrintRequest} request Request that has been completed. 569 * @param {!CloudPrintRequest} request Request that has been completed.
506 * @private 570 * @private
507 */ 571 */
508 onSubmitDone_: function(request) { 572 onSubmitDone_: function(request) {
509 if (request.xhr.status == 200 && request.result['success']) { 573 if (request.xhr.status == 200 && request.result['success']) {
510 var submitDoneEvent = new Event( 574 var submitDoneEvent = new Event(
511 CloudPrintInterface.EventType.SUBMIT_DONE); 575 CloudPrintInterface.EventType.SUBMIT_DONE);
512 submitDoneEvent.jobId = request.result['job']['id']; 576 submitDoneEvent.jobId = request.result['job']['id'];
513 this.dispatchEvent(submitDoneEvent); 577 this.dispatchEvent(submitDoneEvent);
514 } else { 578 } else {
515 var errorEvent = this.createErrorEvent_( 579 var errorEvent = this.createErrorEvent_(
516 CloudPrintInterface.EventType.SUBMIT_FAILED, request); 580 CloudPrintInterface.EventType.SUBMIT_FAILED, request);
517 this.dispatchEvent(errorEvent); 581 this.dispatchEvent(errorEvent);
518 } 582 }
519 }, 583 },
520 584
521 /** 585 /**
522 * Called when the printer request completes. 586 * Called when the printer request completes.
523 * @param {string} destinationId ID of the destination that was looked up. 587 * @param {string} destinationId ID of the destination that was looked up.
524 * @param {!CloudPrintRequest} request Request that has been completed. 588 * @param {!CloudPrintRequest} request Request that has been completed.
525 * @private 589 * @private
526 */ 590 */
527 onPrinterDone_: function(destinationId, request) { 591 onPrinterDone_: function(destinationId, request) {
592 // Special handling of the first printer request. It does not matter at
593 // this point, whether printer was found or not.
594 if (request.origin == print_preview.Destination.Origin.COOKIES &&
595 request.account &&
596 request.result['request']['user'] &&
597 request.result['request']['users'] &&
598 request.account != request.result['request']['user']) {
599 var users = request.result['request']['users'];
Toscano 2014/04/11 04:24:00 Let's keep user parsing logic in place. Why not th
Aleksey Shlyapnikov 2014/04/11 19:09:29 Done. On 2014/04/11 04:24:00, Toscano wrote:
600 // In case the user account is known, but not the primary one,
601 // activate it.
602 if (users.indexOf(request.account) > 0) {
603 this.setUsers_(request);
604 this.userInfo_.activeUser = request.account;
605 // Repeat the request for the newly activated account.
606 this.printer(
607 request.result['request']['params']['printerid'],
608 request.origin,
609 request.account);
610 // Stop processing this request, wait for the new response.
611 return;
612 }
613 }
614 // Process response.
528 if (request.xhr.status == 200 && request.result['success']) { 615 if (request.xhr.status == 200 && request.result['success']) {
529 var activeUser = ''; 616 var activeUser = '';
530 if (request.origin == print_preview.Destination.Origin.COOKIES) { 617 if (request.origin == print_preview.Destination.Origin.COOKIES) {
531 activeUser = request.result['request']['user']; 618 activeUser = request.result['request']['user'];
532 } 619 }
533 var printerJson = request.result['printers'][0]; 620 var printerJson = request.result['printers'][0];
534 var printer; 621 var printer;
535 try { 622 try {
536 printer = cloudprint.CloudDestinationParser.parse( 623 printer = cloudprint.CloudDestinationParser.parse(
537 printerJson, request.origin, activeUser); 624 printerJson, request.origin, activeUser);
(...skipping 29 matching lines...) Expand all
567 this.dispatchEvent(errorEvent); 654 this.dispatchEvent(errorEvent);
568 } 655 }
569 } 656 }
570 }; 657 };
571 658
572 /** 659 /**
573 * Data structure that holds data for Cloud Print requests. 660 * Data structure that holds data for Cloud Print requests.
574 * @param {!XMLHttpRequest} xhr Partially prepared http request. 661 * @param {!XMLHttpRequest} xhr Partially prepared http request.
575 * @param {string} body Data to send with POST requests. 662 * @param {string} body Data to send with POST requests.
576 * @param {!print_preview.Destination.Origin} origin Origin for destination. 663 * @param {!print_preview.Destination.Origin} origin Origin for destination.
664 * @param {?string} account Account the request is sent for. Can be
665 * {@code null} or empty string if the request is not cookie bound or
666 * is sent on behalf of the primary user.
Toscano 2014/04/11 04:24:00 If it's nullable, maybe it should be opt_account?
Aleksey Shlyapnikov 2014/04/11 19:09:29 I don't see the benefit of optional here, it's a p
577 * @param {function(!CloudPrintRequest)} callback Callback to invoke when 667 * @param {function(!CloudPrintRequest)} callback Callback to invoke when
578 * request completes. 668 * request completes.
579 * @constructor 669 * @constructor
580 */ 670 */
581 function CloudPrintRequest(xhr, body, origin, callback) { 671 function CloudPrintRequest(xhr, body, origin, account, callback) {
582 /** 672 /**
583 * Partially prepared http request. 673 * Partially prepared http request.
584 * @type {!XMLHttpRequest} 674 * @type {!XMLHttpRequest}
585 */ 675 */
586 this.xhr = xhr; 676 this.xhr = xhr;
587 677
588 /** 678 /**
589 * Data to send with POST requests. 679 * Data to send with POST requests.
590 * @type {string} 680 * @type {string}
591 */ 681 */
592 this.body = body; 682 this.body = body;
593 683
594 /** 684 /**
595 * Origin for destination. 685 * Origin for destination.
596 * @type {!print_preview.Destination.Origin} 686 * @type {!print_preview.Destination.Origin}
597 */ 687 */
598 this.origin = origin; 688 this.origin = origin;
599 689
600 /** 690 /**
691 * User account this request is expected to be executed for.
692 * @type {?string}
693 */
694 this.account = account;
695
696 /**
601 * Callback to invoke when request completes. 697 * Callback to invoke when request completes.
602 * @type {function(!CloudPrintRequest)} 698 * @type {function(!CloudPrintRequest)}
603 */ 699 */
604 this.callback = callback; 700 this.callback = callback;
605 701
606 /** 702 /**
607 * Result for requests. 703 * Result for requests.
608 * @type {Object} JSON response. 704 * @type {Object} JSON response.
609 */ 705 */
610 this.result = null; 706 this.result = null;
(...skipping 17 matching lines...) Expand all
628 * @type {string} 724 * @type {string}
629 */ 725 */
630 this.value = value; 726 this.value = value;
631 }; 727 };
632 728
633 // Export 729 // Export
634 return { 730 return {
635 CloudPrintInterface: CloudPrintInterface 731 CloudPrintInterface: CloudPrintInterface
636 }; 732 };
637 }); 733 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698