2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 var validator_ = xwalk.utils.validator;
18 var types_ = validator_.Types;
19 var type_utils = xwalk.utils.type;
20 var native_ = new xwalk.utils.NativeManager(extension);
21 var privUtils_ = xwalk.utils;
22 var privilege_ = xwalk.utils.privilege;
24 //////////////////SEService/////////////////
26 function ListenerManager(native, listenerName) {
29 this.nativeSet = false;
31 this.listenerName = listenerName;
34 ListenerManager.prototype.onListenerCalled = function(msg) {
39 e = new WebAPIException(
40 WebAPIException.IO_ERR,
41 'I/O error occurred on Secure Element reader'
45 case 'onUSBCardInserted':
46 case 'onUSBCardRemoved':
47 d = new Reader(msg.handle);
50 privUtils_.log('Unknown mode: ' + msg.action);
54 for (var watchId in this.listeners) {
56 this.listeners.hasOwnProperty(watchId) &&
57 this.listeners[watchId][msg.action]
59 this.listeners[watchId][msg.action](d, e);
64 ListenerManager.prototype.addListener = function(callback) {
66 if (!this.nativeSet) {
67 this.native.addListener(this.listenerName, this.onListenerCalled.bind(this));
68 var result = this.native.callSync('SEServiceRegisterSEListener');
69 if (this.native.isFailure(result)) {
70 throw this.native.getErrorObject(result);
72 this.nativeSet = true;
75 this.listeners[id] = callback;
81 ListenerManager.prototype.removeListener = function(watchId) {
82 if (type_utils.isEmptyObject(this.listeners)) {
83 privUtils_.checkPrivilegeAccess(privilege_.SECUREELEMENT);
86 if (this.listeners.hasOwnProperty(watchId)) {
87 delete this.listeners[watchId];
90 if (this.nativeSet && type_utils.isEmptyObject(this.listeners)) {
91 var result = this.native.callSync('SEServiceUnregisterSEListener');
92 if (this.native.isFailure(result)) {
93 throw this.native.getErrorObject(result);
95 this.native.removeListener(this.listenerName);
96 this.nativeSet = false;
100 var SE_CHANGE_LISTENER = 'SecureElementChangeListener';
101 var SEChangeListener = new ListenerManager(native_, SE_CHANGE_LISTENER);
103 function SEService() {}
105 var SEServiceGetReaders = function() {
106 xwalk.utils.checkPrivilegeAccess(xwalk.utils.privilege.SECUREELEMENT);
107 var args = validator_.validateArgs(arguments, [
108 { name: 'successCallback', type: types_.FUNCTION },
109 { name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true }
112 var callback = function(result) {
113 if (native_.isFailure(result)) {
114 native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
116 var result_obj = native_.getResultObject(result);
117 var readers_array = [];
119 result_obj.forEach(function(data) {
120 readers_array.push(new Reader(data));
123 args.successCallback(readers_array);
127 var result = native_.call('SEServiceGetReaders', {}, callback);
128 if (native_.isFailure(result)) {
129 throw native_.getErrorObject(result);
133 SEService.prototype.getReaders = function() {
134 SEServiceGetReaders.apply(this, arguments);
137 var SEServiceRegisterSEListener = function() {
138 xwalk.utils.checkPrivilegeAccess(xwalk.utils.privilege.SECUREELEMENT);
139 var args = validator_.validateArgs(arguments, [
141 name: 'eventCallback',
142 type: types_.LISTENER,
143 values: ['onSEReady', 'onSENotReady', 'onSEError']
147 return SEChangeListener.addListener(args.eventCallback);
150 SEService.prototype.registerSEListener = function() {
151 return SEServiceRegisterSEListener.apply(this, arguments);
154 var SEServiceUnregisterSEListener = function() {
155 xwalk.utils.checkPrivilegeAccess(xwalk.utils.privilege.SECUREELEMENT);
156 var args = validator_.validateArgs(arguments, [
159 type: types_.UNSIGNED_LONG
163 SEChangeListener.removeListener(args.id);
166 SEService.prototype.unregisterSEListener = function() {
167 SEServiceUnregisterSEListener.apply(this, arguments);
170 var SEServiceShutdown = function() {
171 xwalk.utils.checkPrivilegeAccess(xwalk.utils.privilege.SECUREELEMENT);
172 var result = native_.callSync('SEServiceShutdown', {});
174 if (native_.isFailure(result)) {
175 throw native_.getErrorObject(result);
179 SEService.prototype.shutdown = function() {
180 SEServiceShutdown.apply(this, arguments);
183 //////////////////Reader/////////////////
185 function Reader(reader_handle) {
186 Object.defineProperties(this, {
192 var callArgs = { handle: reader_handle };
193 var result = native_.callSync('SEReaderIsPresent', callArgs);
194 if (native_.isFailure(result)) {
196 'SEReader_isPresent error: ' + native_.getErrorObject(result)
200 return native_.getResultObject(result);
209 return reader_handle;
215 Reader.prototype.getName = function() {
216 var callArgs = { handle: this._handle };
217 var result = native_.callSync('SEReaderGetName', callArgs);
219 if (native_.isFailure(result)) {
220 throw native_.getErrorObject(result);
223 return native_.getResultObject(result);
226 Reader.prototype.openSession = function() {
227 var args = validator_.validateArgs(arguments, [
228 { name: 'successCallback', type: types_.FUNCTION },
229 { name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true }
232 var callback = function(result) {
233 if (native_.isFailure(result)) {
234 native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
236 var result_obj = native_.getResultObject(result);
237 var session = new Session(result_obj.handle);
238 args.successCallback(session);
242 var callArgs = { handle: this._handle };
244 var result = native_.call('SEReaderOpenSession', callArgs, callback);
246 if (native_.isFailure(result)) {
247 throw native_.getErrorObject(result);
251 Reader.prototype.closeSessions = function() {
252 var callArgs = { handle: this._handle };
253 var result = native_.callSync('SEReaderCloseSessions', callArgs);
254 if (native_.isFailure(result)) {
255 throw native_.getErrorObject(result);
259 //////////////////Channel/////////////////
261 function Channel(channel_handle, is_basic_channel) {
262 Object.defineProperties(this, {
268 return channel_handle;
276 return is_basic_channel;
282 Channel.prototype.close = function() {
283 var callArgs = { handle: this._handle };
284 var result = native_.callSync('SEChannelClose', callArgs);
286 if (native_.isFailure(result)) {
287 throw native_.getErrorObject(result);
291 Channel.prototype.transmit = function() {
292 var args = validator_.validateArgs(arguments, [
293 { name: 'command', type: types_.ARRAY, values: types_.BYTE },
294 { name: 'successCallback', type: types_.FUNCTION },
295 { name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true }
298 var callback = function(result) {
299 if (native_.isFailure(result)) {
300 native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
302 args.successCallback(native_.getResultObject(result));
307 handle: this._handle,
308 command: args.command
311 var result = native_.call('SEChannelTransmit', callArgs, callback);
313 if (native_.isFailure(result)) {
314 throw native_.getErrorObject(result);
318 Channel.prototype.getSelectResponse = function() {
319 var callArgs = { handle: this._handle };
320 var result = native_.callSync('SEChannelGetSelectResponse', callArgs);
322 if (native_.isFailure(result)) {
323 throw native_.getErrorObject(result);
327 //////////////////Session/////////////////
329 function Session(session_handle) {
330 Object.defineProperties(this, {
336 var callArgs = { handle: session_handle };
337 var result = native_.callSync('SESessionIsClosed', callArgs);
338 if (native_.isFailure(result)) {
340 'SESession_isClosed error: ' + native_.getErrorObject(result)
344 return native_.getResultObject(result);
353 return session_handle;
359 Session.prototype.openBasicChannel = function() {
360 var args = validator_.validateArgs(arguments, [
361 { name: 'aid', type: types_.ARRAY, values: types_.BYTE },
362 { name: 'successCallback', type: types_.FUNCTION },
363 { name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true }
366 var callback = function(result) {
367 if (native_.isFailure(result)) {
368 native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
370 var result_obj = native_.getResultObject(result);
371 var channel = new Channel(result_obj.handle, result_obj.isBasicChannel);
372 args.successCallback(channel);
377 handle: this._handle,
381 var result = native_.call('SESessionOpenBasicChannel', callArgs, callback);
383 if (native_.isFailure(result)) {
384 throw native_.getErrorObject(result);
388 Session.prototype.openLogicalChannel = function() {
389 var args = validator_.validateArgs(arguments, [
390 { name: 'aid', type: types_.ARRAY, values: types_.BYTE },
391 { name: 'successCallback', type: types_.FUNCTION },
392 { name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true }
395 var callback = function(result) {
396 if (native_.isFailure(result)) {
397 native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
399 var result_obj = native_.getResultObject(result);
400 var channel = new Channel(result_obj.handle, result_obj.isBasicChannel);
401 args.successCallback(channel);
406 handle: this._handle,
410 var result = native_.call('SESessionOpenLogicalChannel', callArgs, callback);
412 if (native_.isFailure(result)) {
413 throw native_.getErrorObject(result);
417 Session.prototype.getATR = function() {
418 var callArgs = { handle: this._handle };
419 var result = native_.callSync('SESessionGetATR', callArgs);
420 if (native_.isFailure(result)) {
421 throw native_.getErrorObject(result);
423 return native_.getResultObject(result);
427 Session.prototype.close = function() {
428 var callArgs = { handle: this._handle };
429 var result = native_.callSync('SESessionClose', callArgs);
431 if (native_.isFailure(result)) {
432 throw native_.getErrorObject(result);
436 Session.prototype.closeChannels = function() {
437 var callArgs = { handle: this._handle };
438 var result = native_.callSync('SESessionCloseChannels', callArgs);
440 if (native_.isFailure(result)) {
441 throw native_.getErrorObject(result);
445 exports = new SEService();