[M76 Migration][Service][Global] Support multiple connections
[platform/framework/web/wrtjs.git] / wrt_app / service / main.js
1 /*
2  * Copyright (c) 2019 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 'use strict';
18
19 require('../common/init')
20 const wrt = require('../browser/wrt');
21 const vm = require('vm');
22 const AccessControlManager = require('./access_control_manager');
23 const XWalkExtension = require('../common/wrt_xwalk_extension');
24
25 var sandbox = [];
26 var sandbox_count = 0;
27 var service_source = [];
28
29 wrt.on('start-service', (event, internal_id, permissions) => {
30   console.log('start service app : ' + internal_id + ', permissions : ' + permissions);
31   if (sandbox[internal_id] === undefined) {
32     if (sandbox_count === 0) {
33       new XWalkExtension();
34     }
35     sandbox_count++;
36     const Module = require('module');
37     sandbox[internal_id] = {
38       console: console,
39       module: new Module,
40       require: require,
41       tizen: tizen,
42     };
43     let access_control_manager = new AccessControlManager(permissions, sandbox[internal_id]);
44     access_control_manager.initialize();
45     for (let key in global) {
46       sandbox[internal_id][key] = global[key];
47     }
48     let standard_object_list = [ Error, EvalError, RangeError, ReferenceError,
49         SyntaxError, TypeError, URIError, Number, BigInt, Math, Date,
50         String, RegExp, Array, Int8Array, Uint8Array, Uint8ClampedArray,
51         Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array,
52         Float64Array, BigInt64Array, BigUint64Array, Map, Set, WeakMap,
53         WeakSet, ArrayBuffer, DataView, JSON, Promise, Reflect, Proxy,
54         Intl, Intl.Collator, Intl.DateTimeFormat, Intl.NumberFormat, Intl.PluralRules,
55         WebAssembly, WebAssembly.Module, WebAssembly.Instance, WebAssembly.Memory,
56         WebAssembly.Table, WebAssembly.CompileError, WebAssembly.LinkError,
57         WebAssembly.RuntimeError, Boolean, Function, Object, Symbol ];
58     for (let idx in standard_object_list) {
59       sandbox[internal_id][standard_object_list[idx].name] = standard_object_list[idx];
60     }
61     let options = { filename: internal_id };
62     let service_id = internal_id.substr(0, internal_id.indexOf(":"));
63     let terminate_service_client_process = false;
64     if (service_source[service_id] === undefined) {
65       service_source[service_id] = wrt.readService(internal_id);
66       terminate_service_client_process = true;
67     }
68     vm.runInNewContext(service_source[service_id], sandbox[internal_id], options);
69
70     if (terminate_service_client_process) {
71       if (!wrt.terminateServiceClientProcess(internal_id)) {
72         console.log('Failed to terminate client process');
73       }
74     }
75   }
76   if (sandbox[internal_id]['started'] === undefined) {
77     sandbox[internal_id]['started'] = true;
78     sandbox[internal_id]['stopped'] = undefined;
79     const start_callback_string = 'if (module.exports.onStart !== undefined) { module.exports.onStart(); }';
80     vm.runInContext(start_callback_string, sandbox[internal_id]);
81   }
82   const request_callback_string = 'if (module.exports.onRequest !== undefined) { module.exports.onRequest(); }';
83   vm.runInContext(request_callback_string, sandbox[internal_id]);
84 });
85
86 wrt.on('stop-service', (event, internal_id) => {
87   if (sandbox[internal_id]['stopped'] === undefined) {
88     sandbox_count--;
89     sandbox[internal_id]['stopped'] = true;
90     sandbox[internal_id]['started'] = undefined;
91     const stop_callback_string = 'if (module.exports.onStop !== undefined) { module.exports.onStop(); }';
92     vm.runInContext(stop_callback_string, sandbox[internal_id]);
93     for(let key in sandbox[internal_id]) {
94       delete sandbox[internal_id][key];
95     }
96     delete sandbox[internal_id];
97     if (sandbox_count === 0) {
98       tizen = null;
99     }
100   } else {
101     console.log('The global service has been already stopped.');
102   }
103 });
104
105 process.on('exit', (code) => {
106   console.log('Exit with code : ' + code);
107 });