1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
// 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('printerProvider');
var printerProviderInternal = require('binding').Binding.create(
'printerProviderInternal').generate();
var eventBindings = require('event_bindings');
var blobNatives = requireNative('blob_natives');
var printerProviderSchema =
requireNative('schema_registry').GetSchema('printerProvider')
var utils = require('utils');
var validate = require('schemaUtils').validate;
// Custom bindings for chrome.printerProvider API.
// The bindings are used to implement callbacks for the API events. Internally
// each event is passed 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.printerProviderInternal API function that is used to report the event
// result from the extension. The function is passed requestId and values
// provided by the extension. It validates that the values provided by the
// extension match chrome.printerProvider 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.printerProviderInternal function
// is called with a default error value.
//
// Handles a chrome.printerProvider event as described in the file comment.
// |eventName|: The event name.
// |prepareArgsForDispatch|: Function called before dispatching the event to
// the extension. It's called with original event |args| list and callback
// that should be called when the |args| are ready for dispatch. The
// callbacks should report whether the argument preparation was successful.
// The function should not change the first argument, which contains the
// request id.
// |resultreporter|: The function that should be called to report event result.
// One of chrome.printerProviderInternal API functions.
function handleEvent(eventName, prepareArgsForDispatch, resultReporter) {
eventBindings.registerArgumentMassager(
'printerProvider.' + eventName,
function(args, dispatch) {
var responded = false;
// Validates that the result passed by the extension to the event
// callback matches the callback schema. Throws an exception in case of
// an error.
var validateResult = function(result) {
var eventSchema =
utils.lookup(printerProviderSchema.events, 'name', eventName);
var callbackSchema =
utils.lookup(eventSchema.parameters, 'type', 'function');
validate([result], callbackSchema.parameters);
};
// Function provided to the extension as the event callback argument.
// It makes sure that the event result hasn't previously been returned
// and that the provided result matches the callback schema. In case of
// an error it throws an exception.
var reportResult = function(result) {
if (responded) {
throw new Error(
'Event callback must not be called more than once.');
}
var finalResult = null;
try {
validateResult(result); // throws on failure
finalResult = result;
} finally {
responded = true;
resultReporter(args[0] /* requestId */, finalResult);
}
};
prepareArgsForDispatch(args, function(success) {
if (!success) {
// Do not throw an exception since the extension should not yet be
// aware of the event.
resultReporter(args[0] /* requestId */, null);
return;
}
dispatch(args.slice(1).concat(reportResult));
});
});
}
// Sets up printJob.document property for a print request.
function createPrintRequestBlobArguments(args, callback) {
printerProviderInternal.getPrintData(args[0] /* requestId */,
function(blobInfo) {
if (chrome.runtime.lastError) {
callback(false);
return;
}
// |args[1]| is printJob.
args[1].document = blobNatives.TakeBrowserProcessBlob(
blobInfo.blobUuid, blobInfo.type, blobInfo.size);
callback(true);
});
}
handleEvent('onGetPrintersRequested',
function(args, callback) { callback(true); },
printerProviderInternal.reportPrinters);
handleEvent('onGetCapabilityRequested',
function(args, callback) { callback(true); },
printerProviderInternal.reportPrinterCapability);
handleEvent('onPrintRequested',
createPrintRequestBlobArguments,
printerProviderInternal.reportPrintResult);
handleEvent('onGetUsbPrinterInfoRequested',
function(args, callback) { callback(true); },
printerProviderInternal.reportUsbPrinterInfo);
exports.$set('binding', binding.generate());
|