Index: chrome/renderer/resources/extensions/certificate_provider_custom_bindings.js |
diff --git a/chrome/renderer/resources/extensions/certificate_provider_custom_bindings.js b/chrome/renderer/resources/extensions/certificate_provider_custom_bindings.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..6089677b2a8f6e7a1db4bbc2c091e46f0e3105fc |
--- /dev/null |
+++ b/chrome/renderer/resources/extensions/certificate_provider_custom_bindings.js |
@@ -0,0 +1,81 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+var binding = require('binding').Binding.create('certificateProvider'); |
+var certificateProviderInternal = require('binding').Binding.create( |
+ 'certificateProviderInternal').generate(); |
+var eventBindings = require('event_bindings'); |
+ |
+var certificateProviderSchema = |
+ requireNative('schema_registry').GetSchema('certificateProvider') |
+var utils = require('utils'); |
+var validate = require('schemaUtils').validate; |
+ |
+// Custom bindings for chrome.certificateProvider API. |
+// The bindings are used to implement callbacks for the API events. Internally |
+// each event is passed a requestId argument used to identify the callback |
+// associated with the event. This argument is massaged out from the event |
+// arguments before dispatching the event to consumers. A callback is appended |
+// to the event arguments. The callback wraps an appropriate |
+// chrome.certificateProviderInternal API function that is used to report the |
+// event result from the extension. The function is passed the requestId and |
+// values provided by the extension. It validates that the values provided by |
+// the extension match chrome.certificateProvider event callback schemas. It |
+// also ensures that a callback is run at most once. In case there is an |
+// exception during event dispatching, the chrome.certificateProviderInternal |
+// function is called with a default error value. |
+ |
+// Handles a chrome.certificateProvider event as described in the file comment. |
+// |eventName|: The event name. The first argument of the event must be a |
+// request id. |
+// |internalReportFunc|: The function that should be called to report results in |
+// reply to an event. The first argument of the function must be the request |
+// id that was received with the event. |
+function handleEvent(eventName, internalReportFunc) { |
+ var eventSchema = |
+ utils.lookup(certificateProviderSchema.events, 'name', eventName); |
+ var callbackSchema = utils.lookup(eventSchema.parameters, 'type', 'function'); |
+ |
+ eventBindings.registerArgumentMassager( |
+ 'certificateProvider.' + eventName, |
+ function(args, dispatch) { |
+ var responded = false; |
+ |
+ // Function provided to the extension as the event callback argument. |
+ // The extension calls this to report results in reply to the event. |
+ // It throws an exception if called more than once and if the provided |
+ // results don't match the callback schema. |
+ var reportFunc = function(reportArg1, reportArg2) { |
+ if (responded) { |
+ throw new Error( |
+ 'Event callback must not be called more than once.'); |
+ } |
+ |
+ var reportArgs = [reportArg1]; |
+ if (reportArg2 !== undefined) |
+ reportArgs.push(reportArg2); |
+ var finalArgs = []; |
+ try { |
+ // Validates that the results reported by the extension matche the |
+ // callback schema of the event. Throws an exception in case of an |
+ // error. |
+ validate(reportArgs, callbackSchema.parameters); |
+ finalArgs = reportArgs; |
+ } finally { |
+ responded = true; |
+ internalReportFunc.apply( |
+ null, [args[0] /* requestId */].concat(finalArgs)); |
+ } |
+ }; |
+ dispatch(args.slice(1).concat(reportFunc)); |
+ }); |
+} |
+ |
+handleEvent('onCertificatesRequested', |
+ certificateProviderInternal.reportCertificates); |
+ |
+handleEvent('onSignDigestRequested', |
+ certificateProviderInternal.reportSignature); |
+ |
+exports.binding = binding.generate(); |