[systeminfo] Prevent possible crash when failure initialization
[platform/core/api/webapi-plugins.git] / src / ml / js / ml_common.js
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 var privUtils_ = xwalk.utils;
18 var validator_ = privUtils_.validator;
19 var types_ = validator_.Types;
20 var native_ = new xwalk.utils.NativeManager(extension);
21
22 var AbortError = new WebAPIException('AbortError', 'An unknown error occurred');
23
24 // Constants
25 var MAX_TENSORS_INFO_COUNT = 16;
26
27 // TensorRawData
28
29 var TensorRawData = function() {
30     Object.defineProperties(this, {
31         data: {
32             enumerable: true,
33             get: function() {
34                 throw new WebAPIException(WebAPIException.ABORT_ERR, 'Not implemented');
35             }
36         },
37         size: {
38             enumerable: true,
39             get: function() {
40                 throw new WebAPIException(WebAPIException.ABORT_ERR, 'Not implemented');
41             }
42         },
43         shape: {
44             enumerable: true,
45             get: function() {
46                 throw new WebAPIException(WebAPIException.ABORT_ERR, 'Not implemented');
47             }
48         }
49     });
50 };
51
52 var TensorType = {
53     INT8: 'INT8',
54     UINT8: 'UINT8',
55     INT16: 'INT16',
56     UINT16: 'UINT16',
57     FLOAT32: 'FLOAT32',
58     INT32: 'INT32',
59     UINT32: 'UINT32',
60     FLOAT64: 'FLOAT64',
61     INT64: 'INT64',
62     UINT64: 'UINT64',
63     UNKNOWN: 'UNKNOWN'
64 };
65
66 // TensorsData
67
68 var _ValidTensorsDataIds = new Set();
69
70 function _CheckIfTensorsDataNotDisposed(id) {
71     if (false == _ValidTensorsDataIds.has(id)) {
72         throw new WebAPIException(WebAPIException.ABORT_ERR, 'TensorsData is disposed');
73     }
74 }
75
76 var TensorsData = function(id, tensorsInfoId) {
77     Object.defineProperties(this, {
78         count: {
79             enumerable: true,
80             get: function() {
81                 return this._tensorsInfo.count;
82             }
83         },
84         tensorsInfo: {
85             enumerable: true,
86             get: function() {
87                 _CheckIfTensorsDataNotDisposed(this._id);
88                 return this._tensorsInfo.clone();
89             }
90         },
91         _id: { value: id, writable: false, enumerable: false },
92         _tensorsInfo: {
93             value: new TensorsInfo(tensorsInfoId),
94             writable: false,
95             enumerable: false
96         }
97     });
98     _ValidTensorsDataIds.add(id);
99 };
100
101 TensorsData.prototype.getTensorRawData = function() {
102     _CheckIfTensorsDataNotDisposed();
103     throw new WebAPIException(WebAPIException.ABORT_ERR, 'Not implemented');
104 };
105
106 TensorsData.prototype.setTensorData = function() {
107     _CheckIfTensorsDataNotDisposed();
108     throw new WebAPIException(WebAPIException.ABORT_ERR, 'Not implemented');
109 };
110
111 TensorsData.prototype.dispose = function() {
112     if (false == _ValidTensorsDataIds.has(this._id)) {
113         privUtils_.log('TensorsData already disposed');
114         return;
115     }
116     var callArgs = {
117         tensorsDataId: this._id
118     };
119
120     var result = native_.callSync('MLTensorsDataDispose', callArgs);
121
122     if (native_.isFailure(result)) {
123         return;
124     }
125     _ValidTensorsDataIds['delete'](this._id);
126     // underlying tensorsInfo_ is also invalid
127     _ValidTensorsInfoIds['delete'](this._tensorsInfo._id);
128 };
129
130 // TensorsInfo
131
132 function tensorsInfoCountGetter(id) {
133     var result = native_.callSync('MLTensorsInfoCountGetter', { tensorsInfoId: id });
134
135     if (native_.isFailure(result)) {
136         return 0;
137     } else {
138         return native_.getResultObject(result);
139     }
140 }
141
142 var _ValidTensorsInfoIds = new Set();
143
144 function _CheckIfTensorsInfoNotDisposed(id) {
145     if (false == _ValidTensorsInfoIds.has(id)) {
146         throw new WebAPIException(WebAPIException.ABORT_ERR, 'TensorsInfo is disposed');
147     }
148 }
149
150 var TensorsInfo = function() {
151     validator_.isConstructorCall(this, TensorsInfo);
152
153     var id;
154     if (arguments.length == 0) {
155         var result = native_.callSync('MLTensorsInfoCreate');
156         if (native_.isFailure(result)) {
157             throw AbortError;
158         }
159         id = result.id;
160     } else {
161         var args = validator_.validateArgs(arguments, [
162             {
163                 name: 'id',
164                 type: types_.LONG
165             }
166         ]);
167         id = args.id;
168     }
169
170     _ValidTensorsInfoIds.add(id);
171
172     Object.defineProperties(this, {
173         count: {
174             enumerable: true,
175             get: function() {
176                 return tensorsInfoCountGetter(this._id);
177             }
178         },
179         _id: { value: id, writable: false, enumerable: false }
180     });
181 };
182
183 var TensorsInfoAddTensorInfoValidExceptions = [
184     'InvalidValuesError',
185     'TypeMismatchError',
186     'NotSupportedError',
187     'AbortError'
188 ];
189
190 TensorsInfo.prototype.addTensorInfo = function() {
191     _CheckIfTensorsInfoNotDisposed(this._id);
192     var args = validator_.validateArgs(arguments, [
193         {
194             name: 'name',
195             type: types_.STRING,
196             optional: false,
197             nullable: true
198         },
199         {
200             name: 'type',
201             type: types_.ENUM,
202             values: Object.values(TensorType),
203             optional: false
204         },
205         {
206             name: 'dimensions',
207             type: types_.ARRAY,
208             optional: false
209         }
210     ]);
211
212     args.dimensions.forEach(function(d) {
213         if (Number.isInteger(d) == false) {
214             throw new WebAPIException(
215                 WebAPIException.TYPE_MISMATCH_ERR,
216                 'dimensions array has to contain only integers'
217             );
218         }
219     });
220
221     var callArgs = {
222         name: args.name,
223         type: args.type,
224         dimensions: args.dimensions,
225         tensorsInfoId: this._id
226     };
227
228     var result = native_.callSync('MLTensorsInfoAddTensorInfo', callArgs);
229     if (native_.isFailure(result)) {
230         throw native_.getErrorObjectAndValidate(
231             result,
232             TensorsInfoAddTensorInfoValidExceptions,
233             AbortError
234         );
235     }
236 };
237
238 var TensorsInfoGettersSettersValidExceptions = [
239     'AbortError',
240     'InvalidValuesError',
241     'NotSupportedError'
242 ];
243
244 TensorsInfo.prototype.clone = function() {
245     _CheckIfTensorsInfoNotDisposed(this._id);
246     var callArgs = {
247         tensorsInfoId: this._id
248     };
249
250     var result = native_.callSync('MLTensorsInfoClone', callArgs);
251
252     if (native_.isFailure(result)) {
253         throw AbortError;
254     }
255
256     return new TensorsInfo(result.id);
257 };
258
259 TensorsInfo.prototype.equals = function() {
260     _CheckIfTensorsInfoNotDisposed(this._id);
261     var args = validator_.validateArgs(arguments, [
262         {
263             name: 'other',
264             type: types_.PLATFORM_OBJECT,
265             values: TensorsInfo
266         }
267     ]);
268
269     if (this._id == args.other._id) {
270         return true;
271     }
272
273     var callArgs = {
274         tensorsInfoId: this._id,
275         otherId: args.other._id
276     };
277
278     var result = native_.callSync('MLTensorsInfoEquals', callArgs);
279
280     if (native_.isFailure(result)) {
281         return false;
282     }
283
284     return native_.getResultObject(result);
285 };
286
287 TensorsInfo.prototype.getDimensions = function() {
288     _CheckIfTensorsInfoNotDisposed(this._id);
289     var args = validator_.validateArgs(arguments, [
290         {
291             name: 'index',
292             type: types_.LONG
293         }
294     ]);
295
296     if (!args.has.index) {
297         throw new WebAPIException(
298             WebAPIException.INVALID_VALUES_ERR,
299             'Invalid parameter: index is undefined'
300         );
301     }
302
303     var callArgs = {
304         index: args.index,
305         tensorsInfoId: this._id
306     };
307
308     var result = native_.callSync('MLTensorsInfoGetDimensions', callArgs);
309
310     if (native_.isFailure(result)) {
311         throw native_.getErrorObjectAndValidate(
312             result,
313             TensorsInfoGettersSettersValidExceptions,
314             AbortError
315         );
316     }
317     return native_.getResultObject(result);
318 };
319
320 var TensorsInfoSetDimensionsExceptions = [
321     'InvalidValuesError',
322     'TypeMismatchError',
323     'NotSupportedError',
324     'AbortError'
325 ];
326
327 TensorsInfo.prototype.setDimensions = function() {
328     _CheckIfTensorsInfoNotDisposed(this._id);
329     var args = validator_.validateArgs(arguments, [
330         {
331             name: 'index',
332             type: types_.LONG
333         },
334         {
335             name: 'dimensions',
336             type: types_.ARRAY
337         }
338     ]);
339
340     args.dimensions.forEach(function(d) {
341         if (Number.isInteger(d) == false) {
342             throw new WebAPIException(
343                 WebAPIException.TYPE_MISMATCH_ERR,
344                 'dimensions array has to contain only integers'
345             );
346         }
347     });
348
349     var callArgs = {
350         index: args.index,
351         dimensions: args.dimensions,
352         tensorsInfoId: this._id
353     };
354
355     var result = native_.callSync('MLTensorsInfoSetDimensions', callArgs);
356
357     if (native_.isFailure(result)) {
358         throw native_.getErrorObjectAndValidate(
359             result,
360             TensorsInfoSetDimensionsExceptions,
361             AbortError
362         );
363     }
364 };
365
366 TensorsInfo.prototype.getTensorName = function() {
367     _CheckIfTensorsInfoNotDisposed(this._id);
368     var args = validator_.validateArgs(arguments, [
369         {
370             name: 'index',
371             type: types_.LONG
372         }
373     ]);
374
375     if (!args.has.index) {
376         throw new WebAPIException(
377             WebAPIException.INVALID_VALUES_ERR,
378             'Invalid parameter: index is undefined'
379         );
380     }
381
382     var callArgs = {
383         index: args.index,
384         tensorsInfoId: this._id
385     };
386
387     var result = native_.callSync('MLTensorsInfoGetTensorName', callArgs);
388
389     if (native_.isFailure(result)) {
390         throw native_.getErrorObjectAndValidate(
391             result,
392             TensorsInfoGettersSettersValidExceptions,
393             AbortError
394         );
395     }
396     return native_.getResultObject(result);
397 };
398
399 TensorsInfo.prototype.setTensorName = function() {
400     _CheckIfTensorsInfoNotDisposed(this._id);
401     var args = validator_.validateArgs(arguments, [
402         {
403             name: 'index',
404             type: types_.LONG
405         },
406         {
407             name: 'name',
408             type: types_.STRING
409         }
410     ]);
411
412     if (!args.has.index) {
413         throw new WebAPIException(
414             WebAPIException.INVALID_VALUES_ERR,
415             'Invalid parameter: index is undefined'
416         );
417     }
418
419     if (!args.has.name) {
420         throw new WebAPIException(
421             WebAPIException.INVALID_VALUES_ERR,
422             'Invalid parameter: name is undefined'
423         );
424     }
425
426     var callArgs = {
427         index: args.index,
428         name: args.name,
429         tensorsInfoId: this._id
430     };
431
432     var result = native_.callSync('MLTensorsInfoSetTensorName', callArgs);
433
434     if (native_.isFailure(result)) {
435         throw native_.getErrorObjectAndValidate(
436             result,
437             TensorsInfoGettersSettersValidExceptions,
438             AbortError
439         );
440     }
441 };
442
443 TensorsInfo.prototype.getTensorType = function() {
444     _CheckIfTensorsInfoNotDisposed(this._id);
445     var args = validator_.validateArgs(arguments, [
446         {
447             name: 'index',
448             type: types_.LONG
449         }
450     ]);
451
452     if (!args.has.index) {
453         throw new WebAPIException(
454             WebAPIException.INVALID_VALUES_ERR,
455             'Invalid parameter: index is undefined'
456         );
457     }
458
459     var callArgs = {
460         index: args.index,
461         tensorsInfoId: this._id
462     };
463
464     var result = native_.callSync('MLTensorsInfoGetTensorType', callArgs);
465
466     if (native_.isFailure(result)) {
467         throw native_.getErrorObjectAndValidate(
468             result,
469             TensorsInfoGettersSettersValidExceptions,
470             AbortError
471         );
472     }
473     return native_.getResultObject(result);
474 };
475
476 var TensorsInfoSetTensorTypeValidExceptions = [
477     'AbortError',
478     'InvalidValuesError',
479     'NotSupportedError',
480     'TypeMismatchError'
481 ];
482
483 TensorsInfo.prototype.setTensorType = function() {
484     _CheckIfTensorsInfoNotDisposed(this._id);
485     var args = validator_.validateArgs(arguments, [
486         {
487             name: 'index',
488             type: types_.LONG
489         },
490         {
491             name: 'type',
492             type: types_.ENUM,
493             values: Object.values(TensorType)
494         }
495     ]);
496
497     var callArgs = {
498         index: args.index,
499         type: args.type,
500         tensorsInfoId: this._id
501     };
502
503     var result = native_.callSync('MLTensorsInfoSetTensorType', callArgs);
504
505     if (native_.isFailure(result)) {
506         throw native_.getErrorObjectAndValidate(
507             result,
508             TensorsInfoSetTensorTypeValidExceptions,
509             AbortError
510         );
511     }
512 };
513
514 TensorsInfo.prototype.getTensorSize = function() {
515     _CheckIfTensorsInfoNotDisposed(this._id);
516     var args = validator_.validateArgs(arguments, [
517         {
518             name: 'index',
519             type: types_.LONG
520         }
521     ]);
522
523     if (!args.has.index) {
524         throw new WebAPIException(
525             WebAPIException.INVALID_VALUES_ERR,
526             'Invalid parameter: index is undefined'
527         );
528     }
529
530     var callArgs = {
531         index: args.index,
532         tensorsInfoId: this._id
533     };
534
535     var result = native_.callSync('MLTensorsInfoGetTensorSize', callArgs);
536
537     if (native_.isFailure(result)) {
538         throw native_.getErrorObjectAndValidate(
539             result,
540             TensorsInfoGettersSettersValidExceptions,
541             AbortError
542         );
543     }
544     return native_.getResultObject(result);
545 };
546
547 var TensorsInfoGetTensorsDataValidExceptions = ['AbortError', 'NotSupportedError'];
548
549 TensorsInfo.prototype.getTensorsData = function() {
550     _CheckIfTensorsInfoNotDisposed(this._id);
551     var callArgs = {
552         tensorsInfoId: this._id
553     };
554
555     var result = native_.callSync('MLTensorsInfoGetTensorsData', callArgs);
556
557     if (native_.isFailure(result)) {
558         throw native_.getErrorObjectAndValidate(
559             result,
560             TensorsInfoGetTensorsDataValidExceptions,
561             AbortError
562         );
563     }
564     return new TensorsData(result.tensorsDataId, result.tensorsInfoId);
565 };
566
567 TensorsInfo.prototype.dispose = function() {
568     if (false == _ValidTensorsInfoIds.has(this._id)) {
569         return;
570     }
571     var callArgs = {
572         tensorsInfoId: this._id
573     };
574
575     var result = native_.callSync('MLTensorsInfoDispose', callArgs);
576
577     if (native_.isFailure(result)) {
578         return;
579     }
580     _ValidTensorsInfoIds['delete'](this._id);
581 };