blob: 9573a1abbdd5e22471d429cd5a05f7314a5dcd65 [file] [log] [blame]
// 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.$set('binding', binding.generate());