1 import '../common/init';
2 import * as XWalkExtension from '../common/wrt_xwalk_extension';
3 import { DeviceAPIRouter } from './device_api_router';
4 import { isMainThread, parentPort, workerData } from 'worker_threads';
5 import { wrt } from '../browser/wrt';
7 Object.defineProperty(global, 'serviceType', {
8 value: wrt.getServiceModel(),
12 function isServiceApplication() {
13 return global['serviceType'] !== 'UI';
16 function isGlobalService() {
17 return global['serviceType'] === 'GLOBAL';
19 function printAppControlData(id: string) {
20 let reqAppControl = global.tizen.application.getCurrentApplication().getRequestedAppControl();
22 console.debug(`id: ${id}, appControlData operation: ${reqAppControl.appControl.operation}`);
23 let appControlData = reqAppControl.appControl.data;
24 for (let dataIndex in appControlData) {
25 for (let valueIndex in appControlData[dataIndex].value)
26 console.debug(`data[${dataIndex}][${valueIndex}]: ${appControlData[dataIndex].value[valueIndex]}`);
31 function registerExtensionResolver(id: string) {
33 let extensionResolver = (module: any, file_path: string) => {
34 console.debug(`resolved path: ${file_path}`);
35 let content = (wrt.tv as NativeWRTjs.TVExtension).decryptFile(id, file_path);
38 if (content.charCodeAt(0) === 0xFEFF)
39 content = content.slice(1);
40 module._compile(content, file_path);
43 require.extensions['.js.spm'] = extensionResolver;
44 require.extensions['.spm'] = extensionResolver;
48 let requestStopService = (id: string) => {
49 requestStopService = (id: string) => {};
50 setTimeout(() => wrt.stopService(id), 500);
55 let periodLauncherAlive = 20; // 2s
57 let checkLauncherAlive = (id: string) => {
58 periodLauncherAlive--;
59 if (!periodLauncherAlive) {
60 periodLauncherAlive = 20;
61 if (!wrt.checkLauncherAlive(id)) {
62 console.debug(`${id} launcher was killed.`)
63 requestStopService(id);
64 checkLauncherAlive = () => {};
69 export function start(id: string, filename: string) {
70 wrt.setServiceAppId(id);
71 XWalkExtension.initialize();
72 XWalkExtension.setRuntimeMessageHandler((type, data) => {
73 if (type === 'tizen://exit') {
74 console.debug(`${id} will be closed by ${type}`);
75 requestStopService(id);
79 console.debug(`serviceType : ${global['serviceType']}`)
80 new DeviceAPIRouter(id, isGlobalService());
82 // this is workaround solution to make webapis singleton worker
83 // ahead of dropThreadPrivilege()
84 global.tizen.systeminfo.getPropertyValue("CPU", () => { }, () => { });
86 // This is for awaking up uv loop.
87 if (isGlobalService()) {
88 dummyTimer = setInterval(() => {
89 checkLauncherAlive(id);
93 if (isServiceApplication()) {
94 registerExtensionResolver(id);
95 filename = wrt.getStartServiceFile(id);
96 console.debug(`start global service file: ${filename}`);
100 let ids = id.split(':');
101 let serviceId = ids[0];
102 let packageId = global.webapis.getPackageId();
103 wrt.security?.dropThreadPrivilege(packageId, serviceId);
104 printAppControlData(id);
106 app = require(filename);
107 if (app.onStart !== undefined) {
110 if (app.onRequest !== undefined) {
113 if (isGlobalService()) {
114 wrt.finishStartingService(id);
117 console.debug(`exception on start: ${e}`);
118 requestStopService(id);
122 export function stop(id: string) {
124 clearInterval(dummyTimer);
126 if (app.onStop !== undefined) {
128 } else if (app.onExit !== undefined) {
132 console.debug(`exception on stop: ${e}`);
137 let id = workerData.id;
138 Object.defineProperty(global, 'internalId', {
143 // FIXME: this should be 'wrt.tv?.serviceMount(id)' after Tizen 6.5 release
144 (wrt.tv as any)?.serviceMount(id);
146 let filename = workerData.filename;
151 parentPort.on('message', (message) => {
152 console.debug(`Received message type : ${message.type}`);
153 if (message.type === 'wake') {
155 } else if (message.type === 'stop') {
158 XWalkExtension.cleanup();
159 parentPort?.postMessage("will-terminate");
160 (wrt.tv as any)?.serviceUmount(id);