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

Unified Diff: chrome/browser/resources/print_preview/cloud_print_interface.js

Issue 14370003: Use device Robot Account to access Cloud Print. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 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/destination_store.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 ea6b271bb31bb0f2ffcd11a020c55d0a3937b8bd..35da404ef3a38e1d1b260eb9bb05cf1f02b18d51 100644
--- a/chrome/browser/resources/print_preview/cloud_print_interface.js
+++ b/chrome/browser/resources/print_preview/cloud_print_interface.js
@@ -10,10 +10,12 @@ cr.define('cloudprint', function() {
* @param {string} baseUrl Base part of the Google Cloud Print service URL
* with no trailing slash. For example,
* 'https://www.google.com/cloudprint'.
+ * @param {!print_preview.NativeLayer} nativeLayer Native layer used to get
+ * Auth2 tokens.
* @constructor
* @extends {cr.EventTarget}
*/
- function CloudPrintInterface(baseUrl) {
+ function CloudPrintInterface(baseUrl, nativeLayer) {
/**
* The base URL of the Google Cloud Print API.
* @type {string}
@@ -22,6 +24,13 @@ cr.define('cloudprint', function() {
this.baseUrl_ = baseUrl;
/**
+ * Used to get Auth2 tokens.
+ * @type {!print_preview.NativeLayer}
+ * @private
+ */
+ this.nativeLayer_ = nativeLayer;
+
+ /**
* Last received XSRF token. Sent as a parameter in every request.
* @type {string}
* @private
@@ -29,11 +38,27 @@ cr.define('cloudprint', function() {
this.xsrfToken_ = '';
/**
+ * Pending requests delayed until we get access token.
+ * @type {!Array<objects>}
Toscano 2013/04/19 17:04:33 The type looks like: {!Array.<Object>}
Vitaly Buka (NO REVIEWS) 2013/04/19 22:14:29 Actually i have type so * @type {!Array<!ClourPrin
+ * @private
+ */
+ this.requestQueue_ = [];
+
+ /**
* Number of outstanding cloud destination search requests.
* @type {number}
* @private
*/
this.outstandingCloudSearchRequestCount_ = 0;
+
+ /**
+ * Event tracker used to keep track of native layer events.
+ * @type {!EventTracker}
+ * @private
+ */
+ this.tracker_ = new EventTracker();
+
+ this.addEventListeners_();
};
/**
@@ -97,6 +122,19 @@ cr.define('cloudprint', function() {
PRINTER: 'printer'
};
+ /**
+ * Could Print origins used to search printers.
+ * @type {!Array<!print_preview.Destination.Origin>}
Toscano 2013/04/19 17:04:33 Missing the "." between "Array" and "<!...": {!Ar
Vitaly Buka (NO REVIEWS) 2013/04/19 22:14:29 Done.
+ * @const
+ * @private
+ */
+ CloudPrintInterface.CLOUD_ORIGINS_ = [
+ print_preview.Destination.Origin.COOKIES,
+ print_preview.Destination.Origin.DEVICE
+ // TODO(vitalybuka): Enable when implemented.
+ // ready print_preview.Destination.Origin.PROFILE
+ ];
+
CloudPrintInterface.prototype = {
__proto__: cr.EventTarget.prototype,
@@ -126,9 +164,12 @@ cr.define('cloudprint', function() {
if (isRecent) {
params.push(new HttpParam('q', '^recent'));
}
- ++this.outstandingCloudSearchRequestCount_;
- this.sendRequest_('GET', 'search', params,
- this.onSearchDone_.bind(this, isRecent));
+ CloudPrintInterface.CLOUD_ORIGINS_.forEach(function(origin) {
+ ++this.outstandingCloudSearchRequestCount_;
+ var cpRequest = this.buildRequest_('GET', 'search', params, origin);
+ this.sendOrQueueRequest_(cpRequest,
+ this.onSearchDone_.bind(this, isRecent));
+ }, this);
},
/**
@@ -157,21 +198,24 @@ cr.define('cloudprint', function() {
'__google__chrome_version=' + chromeVersion),
new HttpParam('tag', '__google__os=' + navigator.platform)
];
- this.sendRequest_('POST', 'submit', params,
- this.onSubmitDone_.bind(this));
+ var cpRequest = this.buildRequest_('POST', 'submit', params,
+ destination.origin);
+ this.sendOrQueueRequest_(cpRequest, this.onSubmitDone_.bind(this));
},
/**
* 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.
*/
- printer: function(printerId) {
+ printer: function(printerId, origin) {
var params = [
new HttpParam('printerid', printerId),
new HttpParam('use_cdd', 'true')
];
- this.sendRequest_('GET', 'printer', params,
- this.onPrinterDone_.bind(this, printerId));
+ var cpRequest = this.buildRequest_('GET', 'printer', params, origin);
+ this.sendOrQueueRequest_(cpRequest,
+ this.onPrinterDone_.bind(this, printerId));
},
/**
@@ -179,16 +223,55 @@ cr.define('cloudprint', function() {
* 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.
*/
- updatePrinterTosAcceptance: function(printerId, isAccepted) {
+ updatePrinterTosAcceptance: function(printerId, origin, isAccepted) {
var params = [
new HttpParam('printerid', printerId),
new HttpParam('is_tos_accepted', isAccepted)
];
- this.sendRequest_('POST', 'update', params,
- this.onUpdatePrinterTosAcceptanceDone_.bind(this));
+ var cpRequest = this.buildRequest_('POST', 'update', params, origin);
+ this.sendOrQueueRequest_(cpRequest,
+ this.onUpdateTosAcceptanceDone_.bind(this));
Toscano 2013/04/19 17:04:33 Why did you change the name of the callback? Now i
Vitaly Buka (NO REVIEWS) 2013/04/19 22:14:29 Done.
+ },
+
+ /**
+ * Adds event listeners to the relevant native layer events.
+ * @private
+ */
+ addEventListeners_: function() {
+ this.tracker_.add(
+ this.nativeLayer_,
+ print_preview.NativeLayer.EventType.ACCESS_TOKEN_READY,
+ this.onAccessTokenReady_.bind(this));
+ },
+
+ /**
+ * Called when a native layer receives access token.
+ * @param {cr.Event} evt Contains the authetication type and access token.
+ * @private
+ */
+ onAccessTokenReady_: function(event) {
Toscano 2013/04/19 17:04:33 private handlers should come after all other priva
Vitaly Buka (NO REVIEWS) 2013/04/19 22:14:29 Done.
+ assert(event.authType == print_preview.Destination.Origin.DEVICE);
+ this.requestQueue_ = this.requestQueue_.filter(function(request) {
+ assert(request.origin == print_preview.Destination.Origin.DEVICE);
Toscano 2013/04/19 17:04:33 Can you add a TODO to remove this assert once we s
Vitaly Buka (NO REVIEWS) 2013/04/19 22:14:29 Done.
+ if (request.origin != event.authType)
Toscano 2013/04/19 17:04:33 Please enclose "if" body with {}
Vitaly Buka (NO REVIEWS) 2013/04/19 22:14:29 Done.
+ return true;
+ if (event.accessToken) {
+ request.xhr.setRequestHeader('Authorization',
+ 'Bearer ' + event.accessToken);
+ this.sendRequest_(request);
+ } else {
+ // No valid token.
+ request.callback(401, {
Toscano 2013/04/19 17:04:33 Should be 403. With a string as the second paramet
Vitaly Buka (NO REVIEWS) 2013/04/19 22:14:29 403 cause sign in promo
+ 'errorCode' : -1,
+ 'message' : 'No access token.'
+ }, request.origin);
+ }
+ return false;
+ }, this);
},
/**
@@ -246,22 +329,25 @@ cr.define('cloudprint', function() {
},
/**
- * Sends a request to the Google Cloud Print API.
+ * Builds request to the Google Cloud Print API.
* @param {string} method HTTP method of the request.
* @param {string} action Google Cloud Print action to perform.
* @param {Array.<!HttpParam>} params HTTP parameters to include in the
* request.
- * @param {function(number, Object)} callback Callback to invoke when
- * request completes.
+ * @param {!print_preview.Destination.Origin} origin Origin for destination.
+ * @private
Toscano 2013/04/19 17:04:33 Where is the @return statement?
Vitaly Buka (NO REVIEWS) 2013/04/19 22:14:29 Done.
*/
- sendRequest_: function(method, action, params, callback) {
- if (!this.xsrfToken_) {
- // TODO(rltoscano): Should throw an error if not a read-only action or
- // issue an xsrf token request.
+ buildRequest_: function(method, action, params, origin) {
+ var url = this.baseUrl_ + '/' + action + '?xsrf=';
Toscano 2013/04/19 17:04:33 You add "xsrf=" to the url, but you only provide a
Vitaly Buka (NO REVIEWS) 2013/04/19 22:14:29 that's how search request worked before, the first
Toscano 2013/04/19 22:32:33 Ok, not a big deal. As long as it works. On 2013/
+ if (origin == print_preview.Destination.Origin.COOKIES) {
+ if (!this.xsrfToken_) {
+ // TODO(rltoscano): Should throw an error if not a read-only action or
+ // issue an xsrf token request.
+ } else {
+ url = url + this.xsrfToken_;
+ }
}
- var url = this.baseUrl_ + '/' + action + '?xsrf=' + this.xsrfToken_;
var body = null;
-
if (params) {
if (method == 'GET') {
url = params.reduce(function(partialUrl, param) {
@@ -286,14 +372,38 @@ cr.define('cloudprint', function() {
}
var xhr = new XMLHttpRequest();
- xhr.onreadystatechange =
- this.onReadyStateChange_.bind(this, xhr, callback);
xhr.open(method, url, true);
- xhr.withCredentials = true;
+ xhr.withCredentials =
+ (origin == print_preview.Destination.Origin.COOKIES);
for (var header in headers) {
xhr.setRequestHeader(header, headers[header]);
}
- xhr.send(body);
+
+ return new ClourPrintRequest(xhr, body, origin);
Toscano 2013/04/19 17:04:33 Cloud*PrintRequest.
Vitaly Buka (NO REVIEWS) 2013/04/19 22:14:29 Done.
+ },
+
+ /**
+ * Sends a request to the Google Cloud Print API. Or queue if it needs to
Toscano 2013/04/19 17:04:33 This is one sentence. No need for a period before
Vitaly Buka (NO REVIEWS) 2013/04/19 22:14:29 Done.
+ * wait OAuth2 access token.
+ * @param {!CloudPrintRequest} request Request to send or queue.
+ * @param {function(number, Object, !print_preview.Destination.Origin)}
+ * callback Callback to invoke when request completes.
+ * @private
+ */
+ sendOrQueueRequest_: function(request, callback) {
Toscano 2013/04/19 17:04:33 It actually looks like it makes more sense to incl
Vitaly Buka (NO REVIEWS) 2013/04/19 22:14:29 Done.
+ request.callback = callback;
Toscano 2013/04/19 17:04:33 The CloudPrintRequest does not have a callback fie
Vitaly Buka (NO REVIEWS) 2013/04/19 22:14:29 Done.
+ if (request.origin == print_preview.Destination.Origin.COOKIES) {
+ return this.sendRequest_(request);
+ } else {
+ this.requestQueue_.push(request);
+ this.nativeLayer_.startGetAccessToken(request.origin);
+ }
+ },
+
+ sendRequest_: function(request) {
Toscano 2013/04/19 17:04:33 Please add jsdoc for this method.
Vitaly Buka (NO REVIEWS) 2013/04/19 22:14:29 Done.
+ request.xhr.onreadystatechange =
+ this.onReadyStateChange_.bind(this, request);
+ request.xhr.send(request.body);
},
/**
@@ -316,20 +426,19 @@ cr.define('cloudprint', function() {
/**
* Called when the ready-state of a XML http request changes.
* Calls the successCallback with the result or dispatches an ERROR event.
- * @param {XMLHttpRequest} xhr XML http request that changed.
- * @param {function(number, Object)} callback Callback to invoke when
- * request completes.
+ * @param {!CloudPrintRequest} request Request that changed.
* @private
*/
- onReadyStateChange_: function(xhr, callback) {
- if (xhr.readyState == 4) {
- if (xhr.status == 200) {
- var result = JSON.parse(xhr.responseText);
- if (result['success']) {
+ onReadyStateChange_: function(request) {
+ if (request.xhr.readyState == 4) {
+ if (request.xhr.status == 200) {
+ var result = JSON.parse(request.xhr.responseText);
+ if (request.origin == print_preview.Destination.Origin.COOKIES &&
+ result['success']) {
this.xsrfToken_ = result['xsrf_token'];
}
}
- callback(xhr.status, result);
+ request.callback(request.xhr.status, result, request.origin);
Toscano 2013/04/19 17:04:33 Let's just add a result field to CloudPrintRequest
Vitaly Buka (NO REVIEWS) 2013/04/19 22:14:29 Done.
}
},
@@ -339,9 +448,10 @@ cr.define('cloudprint', function() {
* destinations.
* @param {number} status Status of the HTTP request.
* @param {Object} result JSON response.
+ * @param {!print_preview.Destination.Origin} origin Origin for destination.
* @private
*/
- onSearchDone_: function(isRecent, status, result) {
+ onSearchDone_: function(isRecent, status, result, origin) {
--this.outstandingCloudSearchRequestCount_;
if (status == 200 && result['success']) {
var printerListJson = result['printers'] || [];
@@ -349,8 +459,7 @@ cr.define('cloudprint', function() {
printerListJson.forEach(function(printerJson) {
try {
printerList.push(
- cloudprint.CloudDestinationParser.parse(
- printerJson, print_preview.Destination.Origin.COOKIES));
+ cloudprint.CloudDestinationParser.parse(printerJson, origin));
} catch (err) {
console.error('Unable to parse cloud print destination: ' + err);
}
@@ -358,6 +467,7 @@ cr.define('cloudprint', function() {
var searchDoneEvent =
new cr.Event(CloudPrintInterface.EventType.SEARCH_DONE);
searchDoneEvent.printers = printerList;
+ searchDoneEvent.origin = origin;
searchDoneEvent.isRecent = isRecent;
searchDoneEvent.email = result['request']['user'];
this.dispatchEvent(searchDoneEvent);
@@ -372,9 +482,10 @@ cr.define('cloudprint', function() {
* Called when the submit request completes.
* @param {number} status Status of the HTTP request.
* @param {Object} result JSON response.
+ * @param {!print_preview.Destination.Origin} origin Origin for destination.
* @private
*/
- onSubmitDone_: function(status, result) {
+ onSubmitDone_: function(status, result, origin) {
if (status == 200 && result['success']) {
var submitDoneEvent = new cr.Event(
CloudPrintInterface.EventType.SUBMIT_DONE);
@@ -392,15 +503,16 @@ cr.define('cloudprint', function() {
* @param {string} destinationId ID of the destination that was looked up.
* @param {number} status Status of the HTTP request.
* @param {Object} result JSON response.
+ * @param {!print_preview.Destination.Origin} origin Origin for destination.
* @private
*/
- onPrinterDone_: function(destinationId, status, result) {
+ onPrinterDone_: function(destinationId, status, result, origin) {
if (status == 200 && result['success']) {
var printerJson = result['printers'][0];
var printer;
try {
- printer = cloudprint.CloudDestinationParser.parse(
- printerJson, print_preview.Destination.Origin.COOKIES);
+ printer = cloudprint.CloudDestinationParser.parse(printerJson,
+ origin);
} catch (err) {
console.error('Failed to parse cloud print destination: ' +
JSON.stringify(printerJson));
@@ -414,8 +526,8 @@ cr.define('cloudprint', function() {
var errorEvent = this.createErrorEvent_(
CloudPrintInterface.EventType.PRINTER_FAILED, status, result);
errorEvent.destinationId = destinationId;
- errorEvent.destinationOrigin = print_preview.Destination.Origin.COOKIES;
- this.dispatchEvent(errorEvent);
+ errorEvent.destinationOrigin = origin;
+ this.dispatchEvent(errorEvent, origin);
}
},
@@ -423,9 +535,10 @@ cr.define('cloudprint', function() {
* Called when the update printer TOS acceptance request completes.
* @param {number} status Status of the HTTP request.
* @param {Object} result JSON response.
+ * @param {!print_preview.Destination.Origin} origin Origin for destination.
* @private
*/
- onUpdatePrinterTosAcceptanceDone_: function(status, result) {
+ onUpdateTosAcceptanceDone_: function(status, result, origin) {
if (status == 200 && result['success']) {
// Do nothing.
} else {
@@ -437,6 +550,33 @@ cr.define('cloudprint', function() {
};
/**
+ * Data structure that holds data for delayed Cloud Print requests.
Toscano 2013/04/19 17:04:33 delayed: not all of them are delayed.
Vitaly Buka (NO REVIEWS) 2013/04/19 22:14:29 Done.
+ * @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.
+ * @constructor
+ */
+ function ClourPrintRequest(xhr, body, origin) {
Toscano 2013/04/19 17:04:33 Cloud*PrintRequest
Toscano 2013/04/19 17:04:33 Please add callback parameter.
Vitaly Buka (NO REVIEWS) 2013/04/19 22:14:29 Done.
Vitaly Buka (NO REVIEWS) 2013/04/19 22:14:29 Done.
+ /**
+ * Partially prepared http request.
+ * @type {!XMLHttpRequest}
+ */
+ this.xhr = xhr;
+
+ /**
+ * Data to send with POST requests.
+ * @type {string}
+ */
+ this.body = body;
+
+ /**
+ * Origin for destination.
+ * @type {!print_preview.Destination.Origin}
+ */
+ this.origin = origin;
+ };
Toscano 2013/04/19 17:04:33 Please add "callback" and "result" fields.
Vitaly Buka (NO REVIEWS) 2013/04/19 22:14:29 Done.
+
+ /**
* Data structure that represents an HTTP parameter.
* @param {string} name Name of the parameter.
* @param {string} value Value of the parameter.
« no previous file with comments | « no previous file | chrome/browser/resources/print_preview/data/destination_store.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698