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

Unified 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: Adjust PrintPreview unit test. 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | chrome/browser/resources/print_preview/data/app_state.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/resources/print_preview/cloud_print_interface.js
diff --git a/chrome/browser/resources/print_preview/cloud_print_interface.js b/chrome/browser/resources/print_preview/cloud_print_interface.js
index 71906609e34f38e0294056e4763df5003bd7bf08..a31ecdee90ac5e0e467f3986a8e5c85705a51199 100644
--- a/chrome/browser/resources/print_preview/cloud_print_interface.js
+++ b/chrome/browser/resources/print_preview/cloud_print_interface.js
@@ -47,11 +47,12 @@ cr.define('cloudprint', function() {
this.userSessionIndex_ = {};
/**
- * Last received XSRF token. Sent as a parameter in every request.
- * @type {string}
+ * Stores last received XSRF tokens for each user account. Sent as
+ * a parameter with every request.
+ * @type {!Object.<string, string>}
* @private
*/
- this.xsrfToken_ = '';
+ this.xsrfTokens_ = {};
/**
* Pending requests delayed until we get access token.
@@ -168,35 +169,33 @@ cr.define('cloudprint', function() {
/**
* Sends Google Cloud Print search API request.
+ * @param {string=} opt_account Account the search is sent for. When
+ * omitted, the search is done on behalf of the primary user.
* @param {print_preview.Destination.Origin=} opt_origin When specified,
* searches destinations for {@code opt_origin} only, otherwise starts
* searches for all origins.
*/
- search: function(opt_origin) {
+ search: function(opt_account, opt_origin) {
+ var account = opt_account || '';
var origins =
opt_origin && [opt_origin] || CloudPrintInterface.CLOUD_ORIGINS_;
- // Terminate outstanding search requests for all requested origins.
- this.outstandingCloudSearchRequests_ =
- this.outstandingCloudSearchRequests_.filter(function(request) {
- if (origins.indexOf(request.origin) >= 0) {
- request.xhr.abort();
- return false;
- }
- return true;
- });
- this.search_(true, origins);
- this.search_(false, origins);
+ this.abortSearchRequests_(origins);
+ this.search_(true, account, origins);
+ this.search_(false, account, origins);
},
/**
* Sends Google Cloud Print search API requests.
* @param {boolean} isRecent Whether to search for only recently used
* printers.
+ * @param {string} account Account the search is sent for. It matters for
+ * COOKIES origin only, and can be empty (sent on behalf of the primary
+ * user in this case).
* @param {!Array.<!print_preview.Destination.Origin>} origins Origins to
* search printers for.
* @private
*/
- search_: function(isRecent, origins) {
+ search_: function(isRecent, account, origins) {
var params = [
new HttpParam('connection_status', 'ALL'),
new HttpParam('client', 'chrome'),
@@ -206,9 +205,13 @@ cr.define('cloudprint', function() {
params.push(new HttpParam('q', '^recent'));
}
origins.forEach(function(origin) {
- var cpRequest =
- this.buildRequest_('GET', 'search', params, origin,
- this.onSearchDone_.bind(this, isRecent));
+ var cpRequest = this.buildRequest_(
+ 'GET',
+ 'search',
+ params,
+ origin,
+ account,
+ this.onSearchDone_.bind(this, isRecent));
this.outstandingCloudSearchRequests_.push(cpRequest);
this.sendOrQueueRequest_(cpRequest);
}, this);
@@ -241,9 +244,13 @@ cr.define('cloudprint', function() {
'__google__chrome_version=' + chromeVersion),
new HttpParam('tag', '__google__os=' + navigator.platform)
];
- var cpRequest = this.buildRequest_('POST', 'submit', params,
- destination.origin,
- this.onSubmitDone_.bind(this));
+ var cpRequest = this.buildRequest_(
+ 'POST',
+ 'submit',
+ params,
+ destination.origin,
+ destination.account,
+ this.onSubmitDone_.bind(this));
this.sendOrQueueRequest_(cpRequest);
},
@@ -251,37 +258,46 @@ cr.define('cloudprint', function() {
* Sends a Google Cloud Print printer API request.
* @param {string} printerId ID of the printer to lookup.
* @param {!print_preview.Destination.Origin} origin Origin of the printer.
+ * @param {string=} account Account this printer is registered for. When
+ * provided for COOKIES {@code origin}, and users sessions are still not
+ * known, will be checked against the response (both success and failure
+ * to get printer) and, if the active user account is not the one
+ * requested, {@code account} is activated and printer request reissued.
*/
- printer: function(printerId, origin) {
+ printer: function(printerId, origin, account) {
var params = [
new HttpParam('printerid', printerId),
new HttpParam('use_cdd', 'true'),
new HttpParam('printer_connection_status', 'true')
];
- var cpRequest =
- this.buildRequest_('GET', 'printer', params, origin,
- this.onPrinterDone_.bind(this, printerId));
- this.sendOrQueueRequest_(cpRequest);
+ this.sendOrQueueRequest_(this.buildRequest_(
+ 'GET',
+ 'printer',
+ params,
+ origin,
+ account,
+ this.onPrinterDone_.bind(this, printerId)));
},
/**
* Sends a Google Cloud Print update API request to accept (or reject) the
* terms-of-service of the given printer.
- * @param {string} printerId ID of the printer to accept the
- * terms-of-service for.
- * @param {!print_preview.Destination.Origin} origin Origin of the printer.
- * @param {boolean} isAccepted Whether the user accepted the
- * terms-of-service.
+ * @param {!print_preview.Destination} destination Destination to accept ToS
+ * for.
+ * @param {boolean} isAccepted Whether the user accepted ToS or not.
*/
- updatePrinterTosAcceptance: function(printerId, origin, isAccepted) {
+ updatePrinterTosAcceptance: function(destination, isAccepted) {
var params = [
- new HttpParam('printerid', printerId),
+ new HttpParam('printerid', destination.id),
new HttpParam('is_tos_accepted', isAccepted)
];
- var cpRequest =
- this.buildRequest_('POST', 'update', params, origin,
- this.onUpdatePrinterTosAcceptanceDone_.bind(this));
- this.sendOrQueueRequest_(cpRequest);
+ this.sendOrQueueRequest_(this.buildRequest_(
+ 'POST',
+ 'update',
+ params,
+ destination.origin,
+ destination.account,
+ this.onUpdatePrinterTosAcceptanceDone_.bind(this)));
},
/**
@@ -302,25 +318,28 @@ cr.define('cloudprint', function() {
* @param {Array.<!HttpParam>} params HTTP parameters to include in the
* request.
* @param {!print_preview.Destination.Origin} origin Origin for destination.
+ * @param {?string} account Account the request is sent for. Can be
+ * {@code null} or empty string if the request is not cookie bound or
+ * is sent on behalf of the primary user.
* @param {function(number, Object, !print_preview.Destination.Origin)}
* callback Callback to invoke when request completes.
* @return {!CloudPrintRequest} Partially prepared request.
* @private
*/
- buildRequest_: function(method, action, params, origin, callback) {
+ buildRequest_: function(method, action, params, origin, account, callback) {
var url = this.baseUrl_ + '/' + action + '?xsrf=';
if (origin == print_preview.Destination.Origin.COOKIES) {
- if (!this.xsrfToken_) {
+ var xsrfToken = this.xsrfTokens_[account];
+ if (!xsrfToken) {
// TODO(rltoscano): Should throw an error if not a read-only action or
// issue an xsrf token request.
} else {
- url = url + this.xsrfToken_;
+ url = url + xsrfToken;
}
- params = params || [];
- if (this.userInfo_.activeUser) {
- var index = this.userSessionIndex_[this.userInfo_.activeUser] || 0;
+ if (account) {
+ var index = this.userSessionIndex_[account] || 0;
if (index > 0) {
- params.push(new HttpParam('user', index));
+ url += '&user=' + index;
}
}
}
@@ -356,7 +375,7 @@ cr.define('cloudprint', function() {
xhr.setRequestHeader(header, headers[header]);
}
- return new CloudPrintRequest(xhr, body, origin, callback);
+ return new CloudPrintRequest(xhr, body, origin, account, callback);
},
/**
@@ -407,6 +426,39 @@ cr.define('cloudprint', function() {
},
/**
+ * Updates user info and session index from the {@code request} response.
+ * @param {!CloudPrintRequest} request Request to extract user info from.
+ * @private
+ */
+ setUsers_: function(request) {
+ if (request.origin == print_preview.Destination.Origin.COOKIES) {
+ var users = request.result['request']['users'] || [];
+ this.userSessionIndex_ = {};
+ for (var i = 0; i < users.length; i++) {
+ this.userSessionIndex_[users[i]] = i;
+ }
+ this.userInfo_.setUsers(request.result['request']['user'], users);
+ }
+ },
+
+ /**
+ * Terminates search requests for requested {@code origins}.
+ * @param {!Array.<print_preview.Destination.Origin>} origins Origins
+ * to terminate search requests for.
+ * @private
+ */
+ abortSearchRequests_: function(origins) {
+ this.outstandingCloudSearchRequests_ =
+ this.outstandingCloudSearchRequests_.filter(function(request) {
+ if (origins.indexOf(request.origin) >= 0) {
+ request.xhr.abort();
+ return false;
+ }
+ return true;
+ });
+ },
+
+ /**
* Called when a native layer receives access token.
* @param {Event} evt Contains the authentication type and access token.
* @private
@@ -424,7 +476,7 @@ cr.define('cloudprint', function() {
'Bearer ' + event.accessToken);
this.sendRequest_(request);
} else { // No valid token.
- // Without abort status does not exists.
+ // Without abort status does not exist.
request.xhr.abort();
request.callback(request);
}
@@ -444,7 +496,8 @@ cr.define('cloudprint', function() {
request.result = JSON.parse(request.xhr.responseText);
if (request.origin == print_preview.Destination.Origin.COOKIES &&
request.result['success']) {
- this.xsrfToken_ = request.result['xsrf_token'];
+ this.xsrfTokens_[request.result['request']['user']] =
+ request.result['xsrf_token'];
}
}
request.status = request.xhr.status;
@@ -460,15 +513,24 @@ cr.define('cloudprint', function() {
* @private
*/
onSearchDone_: function(isRecent, request) {
+ var lastRequestForThisOrigin = true;
this.outstandingCloudSearchRequests_ =
this.outstandingCloudSearchRequests_.filter(function(item) {
+ if (item != request && item.origin == request.origin) {
+ lastRequestForThisOrigin = false;
+ }
return item != request;
});
+ var activeUser = '';
+ if (request.origin == print_preview.Destination.Origin.COOKIES) {
+ activeUser =
+ request.result &&
+ request.result['request'] &&
+ request.result['request']['user'];
+ }
+ var event = null;
if (request.xhr.status == 200 && request.result['success']) {
- var activeUser = '';
- if (request.origin == print_preview.Destination.Origin.COOKIES) {
- activeUser = request.result['request']['user'];
- }
+ // Extract printers.
var printerListJson = request.result['printers'] || [];
var printerList = [];
printerListJson.forEach(function(printerJson) {
@@ -479,25 +541,21 @@ cr.define('cloudprint', function() {
console.error('Unable to parse cloud print destination: ' + err);
}
});
- var searchDoneEvent =
- new Event(CloudPrintInterface.EventType.SEARCH_DONE);
- searchDoneEvent.printers = printerList;
- searchDoneEvent.origin = request.origin;
- searchDoneEvent.isRecent = isRecent;
- if (request.origin == print_preview.Destination.Origin.COOKIES) {
- var users = request.result['request']['users'] || [];
- this.userSessionIndex_ = {};
- for (var i = 0; i < users.length; i++) {
- this.userSessionIndex_[users[i]] = i;
- }
- this.userInfo_.setUsers(activeUser, users);
- }
- this.dispatchEvent(searchDoneEvent);
+ // Extract and store users.
+ this.setUsers_(request);
+ // Dispatch SEARCH_DONE event.
+ event = new Event(CloudPrintInterface.EventType.SEARCH_DONE);
+ event.origin = request.origin;
+ event.printers = printerList;
+ event.isRecent = isRecent;
} else {
- var errorEvent = this.createErrorEvent_(
- CloudPrintInterface.EventType.SEARCH_FAILED, request);
- this.dispatchEvent(errorEvent);
+ event = this.createErrorEvent_(
+ CloudPrintInterface.EventType.SEARCH_FAILED,
+ request);
}
+ event.user = activeUser;
+ event.searchDone = lastRequestForThisOrigin;
+ this.dispatchEvent(event);
},
/**
@@ -525,6 +583,29 @@ cr.define('cloudprint', function() {
* @private
*/
onPrinterDone_: function(destinationId, request) {
+ // Special handling of the first printer request. It does not matter at
+ // this point, whether printer was found or not.
+ if (request.origin == print_preview.Destination.Origin.COOKIES &&
+ request.result &&
+ request.account &&
+ request.result['request']['user'] &&
+ request.result['request']['users'] &&
+ request.account != request.result['request']['user']) {
+ this.setUsers_(request);
+ // In case the user account is known, but not the primary one,
+ // activate it.
+ if (this.userSessionIndex_[request.account] > 0) {
+ this.userInfo_.activeUser = request.account;
+ // Repeat the request for the newly activated account.
+ this.printer(
+ request.result['request']['params']['printerid'],
+ request.origin,
+ request.account);
+ // Stop processing this request, wait for the new response.
+ return;
+ }
+ }
+ // Process response.
if (request.xhr.status == 200 && request.result['success']) {
var activeUser = '';
if (request.origin == print_preview.Destination.Origin.COOKIES) {
@@ -574,11 +655,14 @@ cr.define('cloudprint', function() {
* @param {!XMLHttpRequest} xhr Partially prepared http request.
* @param {string} body Data to send with POST requests.
* @param {!print_preview.Destination.Origin} origin Origin for destination.
+ * @param {?string} account Account the request is sent for. Can be
+ * {@code null} or empty string if the request is not cookie bound or
+ * is sent on behalf of the primary user.
* @param {function(!CloudPrintRequest)} callback Callback to invoke when
* request completes.
* @constructor
*/
- function CloudPrintRequest(xhr, body, origin, callback) {
+ function CloudPrintRequest(xhr, body, origin, account, callback) {
/**
* Partially prepared http request.
* @type {!XMLHttpRequest}
@@ -598,6 +682,12 @@ cr.define('cloudprint', function() {
this.origin = origin;
/**
+ * User account this request is expected to be executed for.
+ * @type {?string}
+ */
+ this.account = account;
+
+ /**
* Callback to invoke when request completes.
* @type {function(!CloudPrintRequest)}
*/
« no previous file with comments | « no previous file | chrome/browser/resources/print_preview/data/app_state.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698