From 275f022e89171ece776f80e104eb8a3767240fde Mon Sep 17 00:00:00 2001 From: DongHyun Song Date: Thu, 17 Sep 2020 16:52:51 +0900 Subject: [PATCH 01/16] [Service] Remove global.gc() LowMemoryNotification() with repeat timer will replace global.gc() in JavascriptEnvironment side. Related chromium-efl patch: https://review.tizen.org/gerrit/244329 Change-Id: I18864ed3de3b3c7ac367f4d247e3e1b81a9c9564 Signed-off-by: DongHyun Song --- wrt_app/common/service_manager.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/wrt_app/common/service_manager.ts b/wrt_app/common/service_manager.ts index 9637542..ea6e1df 100644 --- a/wrt_app/common/service_manager.ts +++ b/wrt_app/common/service_manager.ts @@ -21,14 +21,6 @@ export function startService(id: string, filename: string) { if (isMainThread) { let startService = __dirname + '/service_runner.js'; workers[id] = new Worker(startService, { workerData: { id: id, filename: filename } }); - workers[id].on('exit', () => { - try { - global.gc(); - console.log(`global.gc() is called by ${id}`); - } catch (e) { - console.log(`${e.name}: ${e.message}`); - } - }); } } } -- 2.7.4 From 569ecd5822a96e855bb0df54733a63830568b4fb Mon Sep 17 00:00:00 2001 From: "k2.nagaraju" Date: Wed, 16 Sep 2020 23:16:01 +0530 Subject: [PATCH 02/16] [Service] update package_id based on input received If passed parameter is |false| or |undefined| then also |package_id| is updated as current package. which is causing failure in package service webtct failure. Change-Id: I6823ed175c3e65224e699d3084b28cd27eb3fab9 Signed-off-by: k2.nagaraju --- wrt_app/service/device_api_router.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/wrt_app/service/device_api_router.ts b/wrt_app/service/device_api_router.ts index b7f645b..3772d5d 100644 --- a/wrt_app/service/device_api_router.ts +++ b/wrt_app/service/device_api_router.ts @@ -119,10 +119,11 @@ export class DeviceAPIRouter { refinePackageApis() { // tizen.package.getPackageInfo() this.funcGetPackageInfo = global.tizen.package.getPackageInfo; - global.tizen.package.getPackageInfo = (package_id?: string) => { - console.log(`Routing - getPackageInfo()`); - if (!package_id) + global.tizen.package.getPackageInfo = (...args: any[]) => { + let package_id = args[0]; + if (!args.length || args[0] === null) package_id = this.getPackageId(); + console.log(`Routing - getPackageInfo() : ${package_id}`); return this.funcGetPackageInfo(package_id); } } -- 2.7.4 From 6b7c4aab36e0ebbe3e5bffb27867d39239532e99 Mon Sep 17 00:00:00 2001 From: "k2.nagaraju" Date: Tue, 22 Sep 2020 00:02:04 +0530 Subject: [PATCH 03/16] [service] filesystem web deviceapi call getting hanged. filesystem deviceapi calls are overloaded, some functions expecting return value. But it is not returning, which is causing failure of test cases. Change-Id: I77d08193fcc9aa7505f53836a36b78cb82697b30 Signed-off-by: k2.nagaraju --- wrt_app/service/device_api_router.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrt_app/service/device_api_router.ts b/wrt_app/service/device_api_router.ts index 3772d5d..5d65aa3 100644 --- a/wrt_app/service/device_api_router.ts +++ b/wrt_app/service/device_api_router.ts @@ -133,7 +133,7 @@ export class DeviceAPIRouter { console.log(args); args[0] = wrt.resolveVirtualRoot(this.getServiceId(), args[0]); console.log(args[0]); - func.apply(global.tizen.filesystem, args); + return func.apply(global.tizen.filesystem, args); } } -- 2.7.4 From 3985daa08f8f8373cebdcdbc1aa843bf6059e30c Mon Sep 17 00:00:00 2001 From: Aron kim Date: Tue, 22 Sep 2020 23:02:17 -0700 Subject: [PATCH 04/16] [D2D] Add privilege for DeviceWebServer. http://tizen.org/privilege/filesystem.read http://tizen.org/privilege/filesystem.write http://tizen.org/privilege/mediastorage Change-Id: I393428a9a6d44ecd6311e425a4d3fe6f76bec29f Signed-off-by: Aron kim --- d2d_app/config.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/d2d_app/config.xml b/d2d_app/config.xml index f84c871..3f3ecfc 100755 --- a/d2d_app/config.xml +++ b/d2d_app/config.xml @@ -7,6 +7,9 @@ + + + -- 2.7.4 From c5297c3540f1761d8fa4caad0413efac64e4a765 Mon Sep 17 00:00:00 2001 From: DongHyun Song Date: Mon, 14 Sep 2020 19:02:37 +0900 Subject: [PATCH 05/16] [Service] Refactor builtin-service with node worker This applies builtin-service to execute on node worker same as service application with refactoring worker creation/termination. Change-Id: I105a4e3f91409deb9805ac2ca08e4e62a162c2fa Signed-off-by: DongHyun Song --- wrt_app/common/service_manager.ts | 68 +++++++++++++++++++++++------ wrt_app/common/service_runner.ts | 6 +-- wrt_app/service/builtins/builtin_handler.ts | 30 ------------- wrt_app/service/builtins/wasm_builder.ts | 11 ++--- wrt_app/service/main.ts | 5 +-- 5 files changed, 66 insertions(+), 54 deletions(-) delete mode 100644 wrt_app/service/builtins/builtin_handler.ts diff --git a/wrt_app/common/service_manager.ts b/wrt_app/common/service_manager.ts index ea6e1df..b9daf4e 100644 --- a/wrt_app/common/service_manager.ts +++ b/wrt_app/common/service_manager.ts @@ -5,13 +5,48 @@ interface WorkerMap { [id: string]: any; } let workers: WorkerMap = {}; -let serviceType: string = wrt.getServiceModel();; +let serviceType: string = wrt.getServiceModel(); let runner: any; +function isGlobalService() { + return serviceType === 'DAEMON'; +} + function isStandalone() { return serviceType === 'STANDALONE'; } +function createWorker(id: string, startService: string, filename: string) { + if (workers[id]) { + console.log(`This worker is already running. ${id}`); + return; + } + workers[id] = new Worker(startService, { + workerData: { + id, + filename + } + }); +} + +function terminateWorker(id: string, delay: number) { + if (!workers[id]) { + console.log(`This worker is already terminated. ${id}`); + return; + } + workers[id].postMessage('stopService'); + let terminate = () => { + workers[id].terminate(); + delete workers[id]; + let runningServices = Object.keys(workers).length; + console.log('Running services : ' + runningServices); + if (runningServices === 0 && isGlobalService()) { + process.exit(); + } + } + setTimeout(() => terminate(), delay); +} + export function startService(id: string, filename: string) { console.log(`startService - ${id}`); if (isStandalone()) { @@ -19,8 +54,8 @@ export function startService(id: string, filename: string) { runner.start(id, filename); } else { if (isMainThread) { - let startService = __dirname + '/service_runner.js'; - workers[id] = new Worker(startService, { workerData: { id: id, filename: filename } }); + let startService = `${__dirname}/service_runner.js`; + createWorker(id, startService, filename); } } } @@ -35,15 +70,22 @@ export function stopService(id: string) { runner.stop(id); setTimeout(() => process.exit(), 500); } else { - workers[id].postMessage('stopService'); - setTimeout(() => { - workers[id].terminate(); - delete workers[id]; - let runningServices = Object.keys(workers).length; - console.log('Running services : ' + runningServices); - if (runningServices === 0 && serviceType !== 'UI') { - process.exit(); - } - }, 500); + terminateWorker(id, 500); } } + +export function handleBuiltinService(serviceId: string, serviceName: string) { + if (!serviceName) { + return; + } + let need_stop = (serviceName.substr(0, 5) === 'stop_'); + if (need_stop) { + terminateWorker(serviceId, 0); + } else { + if (isMainThread) { + console.log(`Builtin service is ${serviceName}`); + let startService = `${__dirname}/../service/builtins/${serviceName}.js`; + createWorker(serviceId, startService, ''); + } + } +} \ No newline at end of file diff --git a/wrt_app/common/service_runner.ts b/wrt_app/common/service_runner.ts index 8e1c032..7ea5bca 100644 --- a/wrt_app/common/service_runner.ts +++ b/wrt_app/common/service_runner.ts @@ -10,7 +10,7 @@ function isServiceApplication() { return serviceType !== 'UI'; } -function isGloablService() { +function isGlobalService() { return serviceType === 'DAEMON'; } @@ -42,7 +42,7 @@ export function start(id: string, filename: string) { }); console.log('serviceType : '+serviceType) - new DeviceAPIRouter(id, isGloablService()); + new DeviceAPIRouter(id, isGlobalService()); if (isServiceApplication()) { registerExtensionResolver(id); @@ -61,7 +61,7 @@ export function start(id: string, filename: string) { if (app.onRequest !== undefined) { app.onRequest(); } - if (isGloablService()) { + if (isGlobalService()) { wrt.finishStartingService(id); } } catch (e) { diff --git a/wrt_app/service/builtins/builtin_handler.ts b/wrt_app/service/builtins/builtin_handler.ts deleted file mode 100644 index de9c8a8..0000000 --- a/wrt_app/service/builtins/builtin_handler.ts +++ /dev/null @@ -1,30 +0,0 @@ -import * as vm from 'vm'; - -let sandbox: vm.Context = { - console: console, - require: require, - services: {} -}; - -export function handleService(service_name: string, service_id: string) { - if (!service_name) - return; - - let need_stop = (service_name.substr(0, 5) === 'stop_'); - if (need_stop) { - service_name = service_name.substr(5); - } - let builtin_service = `./${service_name}.js`; - console.log(`Builtin service is ${builtin_service}`); - let options = { - filename: service_id, - }; - if (need_stop) { - let code = `services['${service_id}'].stop('${service_id}')`; - vm.runInContext(code, sandbox); - } else { - let code = `services['${service_id}'] = require('${builtin_service}');`; - code += `services['${service_id}'].run('${service_id}')`; - vm.runInNewContext(code, sandbox, options); - } -} \ No newline at end of file diff --git a/wrt_app/service/builtins/wasm_builder.ts b/wrt_app/service/builtins/wasm_builder.ts index b61ed86..aa8a00f 100644 --- a/wrt_app/service/builtins/wasm_builder.ts +++ b/wrt_app/service/builtins/wasm_builder.ts @@ -1,5 +1,7 @@ -import * as fs from 'fs'; +import '../../common/init'; +import { isMainThread, workerData } from 'worker_threads'; import { wrt } from '../../browser/wrt'; +import * as fs from 'fs'; async function compileWasmForCaching(file_path: string) { console.log(`Requesting WASM compilation for building a cache, file_path:(${file_path})`); @@ -25,7 +27,6 @@ export function run(app_id: string) { }); } -export function stop(app_id: string) { - // TODO, stop caching will be implemented here - console.log(`wasm_builder.js suspended, app_id:(${app_id})`); -} \ No newline at end of file +if (!isMainThread) { + run(workerData.id); +} diff --git a/wrt_app/service/main.ts b/wrt_app/service/main.ts index 6fa2f41..b0c371a 100755 --- a/wrt_app/service/main.ts +++ b/wrt_app/service/main.ts @@ -19,7 +19,6 @@ import '../common/init'; import { wrt } from '../browser/wrt'; import * as ServiceManager from '../common/service_manager'; -import * as BuiltinService from './builtins/builtin_handler'; wrt.on('start-service', (event: any, internal_id: string) => { console.log('start service app : ' + internal_id); @@ -34,8 +33,8 @@ wrt.on('stop-service', (event: any, internal_id: string) => { }); wrt.on('builtin-service', (event: any, internal_id: string, service_name: string) => { - console.log(`service_name: ${service_name}`); - BuiltinService.handleService(service_name, internal_id); + console.log(`id: ${internal_id}, service_name: ${service_name}`); + ServiceManager.handleBuiltinService(internal_id, service_name); }); wrt.on('quit', (event: any) => { -- 2.7.4 From b6a74f93575992e34c406ae477fb00ba95f012f0 Mon Sep 17 00:00:00 2001 From: DongHyun Song Date: Mon, 21 Sep 2020 17:13:22 +0900 Subject: [PATCH 06/16] [Service][TV] Refactor for wasm-caching shutdown 1) Calls delayShutdown() every wasm cache creation. - If built-in service is implemented with async functions, after run() is done and there is no running services, node main will be terminated by itself 1 minute later. delayShutdown() can reset the timeout to 1 min. 2) After finish wasm-caching, notify parent to terminate node worker - When wasm-caching is finished, node worker is able to terminate by stop messaging Change-Id: I23b3587d3f3746a451b517c7cd7a70c5f9593302 Signed-off-by: DongHyun Song --- wrt_app/common/service_manager.ts | 13 ++++++------- wrt_app/service/builtins/wasm_builder.ts | 7 +++++-- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/wrt_app/common/service_manager.ts b/wrt_app/common/service_manager.ts index b9daf4e..1ce2ea5 100644 --- a/wrt_app/common/service_manager.ts +++ b/wrt_app/common/service_manager.ts @@ -17,16 +17,12 @@ function isStandalone() { } function createWorker(id: string, startService: string, filename: string) { - if (workers[id]) { - console.log(`This worker is already running. ${id}`); - return; - } - workers[id] = new Worker(startService, { + return workers[id] ?? (workers[id] = new Worker(startService, { workerData: { id, filename } - }); + })); } function terminateWorker(id: string, delay: number) { @@ -85,7 +81,10 @@ export function handleBuiltinService(serviceId: string, serviceName: string) { if (isMainThread) { console.log(`Builtin service is ${serviceName}`); let startService = `${__dirname}/../service/builtins/${serviceName}.js`; - createWorker(serviceId, startService, ''); + let worker = createWorker(serviceId, startService, ''); + worker.on('stop', () => { + terminateWorker(serviceId, 0); + }); } } } \ No newline at end of file diff --git a/wrt_app/service/builtins/wasm_builder.ts b/wrt_app/service/builtins/wasm_builder.ts index aa8a00f..7ec30a3 100644 --- a/wrt_app/service/builtins/wasm_builder.ts +++ b/wrt_app/service/builtins/wasm_builder.ts @@ -1,5 +1,5 @@ import '../../common/init'; -import { isMainThread, workerData } from 'worker_threads'; +import { isMainThread, parentPort, workerData } from 'worker_threads'; import { wrt } from '../../browser/wrt'; import * as fs from 'fs'; @@ -19,12 +19,15 @@ export function run(app_id: string) { let tv = wrt.tv as NativeWRTjs.TVExtension; tv.setWasmFlags(); tv.setDiskCache(app_id); - tv.delayShutdown(); let files = tv.getWasmFiles(app_id); console.log(files); files.forEach((file_path: string) => { + tv.delayShutdown(); compileWasmForCaching(file_path); }); + if (parentPort) { + parentPort.postMessage('stop'); + } } if (!isMainThread) { -- 2.7.4 From 8b45240fb1eaea93bedf12079beff1a24eeaad59 Mon Sep 17 00:00:00 2001 From: DongHyun Song Date: Wed, 9 Sep 2020 18:31:38 +0900 Subject: [PATCH 07/16] [Service] APIRouter - xwalk.util.checkPrivilegeAccess xwalk.util.checkPrivilegeAccess() is an internal API of webapis for checking the app has proper privilege. If the app hasn't required privilege, it will throw exception. For example, When 'tizen.filesystem.listStorages' is handled xwalk.utils.checkPrivilegeAccess( xwalk.utils.privilege.FILESYSTEM_READ); it checks if the app has 'filesystem.read' privilege, then, this overrided checkPrivilegeAccess() can inspect its privileges defined in config.xml. (not wrt-service's privileges) This is different from AccessControlManager's webapis drops. In webapis, there are two ways of privilege checking. 1) by xwalk.util.checkPrivilegeAccess() 2) by cynara inspection directly AccessControlManager purpose should be considered way #2. webapis's cynara DB checking, it always inspects on wrt-service's. Then, AccessControlManager should be able to disable webapis which the app doesn't have required privileges. Change-Id: I84ce85a580a483c209d354ca2f1b7c3d17c08fb3 Signed-off-by: DongHyun Song --- wrt_app/common/service_manager.ts | 11 ++++++----- wrt_app/common/service_runner.ts | 8 +++----- wrt_app/common/wrt_xwalk_extension.ts | 9 +++++++-- wrt_app/service/device_api_router.ts | 16 +++++++++++++--- 4 files changed, 29 insertions(+), 15 deletions(-) diff --git a/wrt_app/common/service_manager.ts b/wrt_app/common/service_manager.ts index 1ce2ea5..3038364 100644 --- a/wrt_app/common/service_manager.ts +++ b/wrt_app/common/service_manager.ts @@ -5,15 +5,16 @@ interface WorkerMap { [id: string]: any; } let workers: WorkerMap = {}; -let serviceType: string = wrt.getServiceModel(); let runner: any; -function isGlobalService() { - return serviceType === 'DAEMON'; -} +global.serviceType = wrt.getServiceModel(); function isStandalone() { - return serviceType === 'STANDALONE'; + return global.serviceType === 'STANDALONE'; +} + +function isGlobalService() { + return global.serviceType === 'DAEMON'; } function createWorker(id: string, startService: string, filename: string) { diff --git a/wrt_app/common/service_runner.ts b/wrt_app/common/service_runner.ts index 7ea5bca..286297a 100644 --- a/wrt_app/common/service_runner.ts +++ b/wrt_app/common/service_runner.ts @@ -4,14 +4,12 @@ import { DeviceAPIRouter } from '../service/device_api_router'; import { isMainThread, parentPort, workerData } from 'worker_threads'; import { wrt } from '../browser/wrt'; -let serviceType: string = wrt.getServiceModel(); - function isServiceApplication() { - return serviceType !== 'UI'; + return global.serviceType !== 'UI'; } function isGlobalService() { - return serviceType === 'DAEMON'; + return global.serviceType === 'DAEMON'; } function registerExtensionResolver(id: string) { @@ -41,7 +39,7 @@ export function start(id: string, filename: string) { } }); - console.log('serviceType : '+serviceType) + console.log(`serviceType : ${global.serviceType}`) new DeviceAPIRouter(id, isGlobalService()); if (isServiceApplication()) { diff --git a/wrt_app/common/wrt_xwalk_extension.ts b/wrt_app/common/wrt_xwalk_extension.ts index 461e7dd..f7ba13d 100644 --- a/wrt_app/common/wrt_xwalk_extension.ts +++ b/wrt_app/common/wrt_xwalk_extension.ts @@ -117,14 +117,19 @@ class XWalkExtension { this.createNamespace(global, ext.name); var api = (ext.use_trampoline) ? api_ : global; - + var extension_api = ext.jsapi; + if (global.serviceType === 'DAEMON' && ext.name === 'xwalk') { + console.log(`Delete freeze exports.utils for override method`); + extension_api = extension_api.replace('Object.freeze(exports.utils);', ''); + extension_api = extension_api.replace('Object.freeze(Utils.prototype);', ''); + } const jscode = '(function(extension) {' + ' extension.internal = {};' + ' extension.internal.sendSyncMessage = extension.sendSyncMessage;' + ' delete extension.sendSyncMessage;' + ' var exports = {}; ' + - ' (function() {\'use strict\'; ' + ext.jsapi + '})();' + + ' (function() {\'use strict\'; ' + extension_api + '})();' + ' api.' + ext.name + ' = exports; ' + '});'; diff --git a/wrt_app/service/device_api_router.ts b/wrt_app/service/device_api_router.ts index 5d65aa3..b7a6e0f 100644 --- a/wrt_app/service/device_api_router.ts +++ b/wrt_app/service/device_api_router.ts @@ -14,6 +14,7 @@ export class DeviceAPIRouter { serviceId: string; packageId: string; callerAppId: string; + permissions: string[]; constructor(id: string, isGlobal: boolean) { this.id = id; @@ -21,6 +22,7 @@ export class DeviceAPIRouter { this.serviceId = ids[0]; this.callerAppId = ids[1] ?? ''; this.packageId = this.serviceId.split('.')[0]; + this.permissions = wrt.getPrivileges(this.id); this.initWebapis(); if (isGlobal) { @@ -28,6 +30,7 @@ export class DeviceAPIRouter { this.refinePackageApis(); this.refineFilesystemApis() this.initAccessControlManager(); + this.refineXwalkUtilApis(); } } @@ -50,10 +53,9 @@ export class DeviceAPIRouter { } initAccessControlManager() { - const permissions = wrt.getPrivileges(this.id); - console.log(`permissions : ${permissions}`); + console.log(`permissions : ${this.permissions}`); const AccessControlManager = require('./access_control_manager'); - AccessControlManager.initialize(permissions); + AccessControlManager.initialize(this.permissions); } getServiceId() { @@ -152,4 +154,12 @@ export class DeviceAPIRouter { global.tizen.filesystem.isDirectory = this.injectVirtualRootResolver(global.tizen.filesystem.isDirectory); global.tizen.filesystem.pathExists = this.injectVirtualRootResolver(global.tizen.filesystem.pathExists); } + + refineXwalkUtilApis() { + global.xwalk.utils.checkPrivilegeAccess = (privilege: string) => { + if (!this.permissions.includes(privilege)) { + throw 'Permission denied'; + } + } + } } -- 2.7.4 From ad5118f066c383a6bf22fc375a6e8b60ceeb3c03 Mon Sep 17 00:00:00 2001 From: Youngsoo Choi Date: Thu, 24 Sep 2020 04:48:29 -0700 Subject: [PATCH 08/16] [Service] Fix not returning handler id of systeminfo The systeminfo device API should return handler id to control listener later. Change-Id: Idc12f8164be0a500a29b1a272899148e3c17aff7 Signed-off-by: Youngsoo Choi --- wrt_app/service/access_control_manager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrt_app/service/access_control_manager.ts b/wrt_app/service/access_control_manager.ts index 120fe1c..87afb7a 100644 --- a/wrt_app/service/access_control_manager.ts +++ b/wrt_app/service/access_control_manager.ts @@ -6,7 +6,7 @@ function checkSystemInfoApiPrivilege(func: any, permissions: string[]) { console.log('The telephony permission is missing.'); return ; } - override_func.call(global.tizen.systeminfo, ...args); + return override_func.call(global.tizen.systeminfo, ...args); } } -- 2.7.4 From b778ba1661387e54d89fe9007fa0831db1def900 Mon Sep 17 00:00:00 2001 From: Aron kim Date: Thu, 24 Sep 2020 19:19:38 -0700 Subject: [PATCH 09/16] [D2D] Change path for app routing. The installation path of the built-in deviceWebServer is changed. Reroute according to the changed path. Change-Id: I54b9004811a14e22aba5263921510b1798e43412 Signed-off-by: Aron kim --- d2d_app/service/app_router.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/d2d_app/service/app_router.js b/d2d_app/service/app_router.js index f9dd99d..56a5c51 100644 --- a/d2d_app/service/app_router.js +++ b/d2d_app/service/app_router.js @@ -3,7 +3,7 @@ var express = require('express'); class AppRouter { constructor(app, path) { var appRouter = express.Router(); - appRouter.use(express.static(__dirname + '/../../../../' + path + '/res/wgt/client')); + appRouter.use(express.static('/opt/usr/globalapps/' + path + '/res/wgt/client')); appRouter.get('/', (req, res) => { res.redirect('client.html'); -- 2.7.4 From 05a663a54e531739ca85dd55ad8cf44811e77d7b Mon Sep 17 00:00:00 2001 From: DongHyun Song Date: Thu, 10 Sep 2020 09:36:51 +0900 Subject: [PATCH 10/16] [Service][TV] Add TV productinfo webapis Add webapis.productinfo of TV profile. Related chromium-efl patch: https://review.tizen.org/gerrit/238981/ Change-Id: I1c865e7d0b2f2708f09e4de504a52836585c7090 Signed-off-by: DongHyun Song --- wrt_app/service/device_api_router.ts | 38 ++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/wrt_app/service/device_api_router.ts b/wrt_app/service/device_api_router.ts index b7a6e0f..42a57f3 100644 --- a/wrt_app/service/device_api_router.ts +++ b/wrt_app/service/device_api_router.ts @@ -50,6 +50,44 @@ export class DeviceAPIRouter { global.webapis.getPackageId = () => { return this.packageId; } + this.initProductWebapis(); + } + + initProductWebapis() { + // for TV profile + if (wrt.tv && !global.webapis.productinfo) { + global.webapis.cachedProperty = global.webapis.cachedProperty ?? {}; + let getCachedValue = (name: string) => { + if (global.webapis.cachedProperty[name]) { + return global.webapis.cachedProperty[name]; + } + let tv = wrt.tv as NativeWRTjs.TVExtension; + return (global.webapis.cachedProperty[name] = tv.queryProductValue(name)); + } + global.webapis.productinfo = { + getDuid: () => { + return getCachedValue('getDuid'); + }, + getFirmware: () => { + return getCachedValue('getFirmware'); + }, + getLocalSet: () => { + return getCachedValue('getLocalSet'); + }, + getModel: () => { + return getCachedValue('getModel'); + }, + getModelCode: () => { + return getCachedValue('getModelCode'); + }, + getRealModel: () => { + return getCachedValue('getRealModel'); + }, + getSmartTVServerVersion: () => { + return getCachedValue('getSmartTVServerVersion'); + } + }; + } } initAccessControlManager() { -- 2.7.4 From 2a4193c066ef648844cc47c7212378589fe96bef Mon Sep 17 00:00:00 2001 From: liwei Date: Tue, 29 Sep 2020 13:44:54 +0800 Subject: [PATCH 11/16] [Service] Add service type in node worker Add service type in node worker, otherwise value of "global.serviceType" is 'undefined', service app in global service cannot work well. Change-Id: I39fadd30c14b89f20b1bf817fe4d9db46f65eb44 Signed-off-by: liwei --- wrt_app/common/service_runner.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wrt_app/common/service_runner.ts b/wrt_app/common/service_runner.ts index 286297a..43681b5 100644 --- a/wrt_app/common/service_runner.ts +++ b/wrt_app/common/service_runner.ts @@ -4,6 +4,8 @@ import { DeviceAPIRouter } from '../service/device_api_router'; import { isMainThread, parentPort, workerData } from 'worker_threads'; import { wrt } from '../browser/wrt'; +global.serviceType = wrt.getServiceModel(); + function isServiceApplication() { return global.serviceType !== 'UI'; } -- 2.7.4 From 3078f777fd86b985ab96a9c806bc8f3291740320 Mon Sep 17 00:00:00 2001 From: "k2.nagaraju" Date: Wed, 30 Sep 2020 17:10:30 +0530 Subject: [PATCH 12/16] [service] Add notification xwalk extension support for service app. For alarm service webtct notification xwalk extension support is needed. updated the entry points for notification extension. Change-Id: If4857b74a5929e03c6738858e8a3a9098af90c22 Signed-off-by: k2.nagaraju --- packaging/plugins.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packaging/plugins.json b/packaging/plugins.json index 26d4f0a..7838bf7 100644 --- a/packaging/plugins.json +++ b/packaging/plugins.json @@ -74,5 +74,10 @@ "lib":"/usr/lib/tizen-extensions-crosswalk/libtizen_iotcon.so", "entry_points": ["tizen.IotconOption","tizen.Query","tizen.QueryFilter", "tizen.Representation","tizen.Response","tizen.State"] + }, + { + "name":"tizen.notification", + "lib":"/usr/lib/tizen-extensions-crosswalk/libtizen_notification.so", + "entry_points": ["tizen.StatusNotification","tizen.UserNotification", "tizen.NotificationDetailInfo"] } ] -- 2.7.4 From 962847b68a93c171a4348d0f14cbdbf2848d5a8e Mon Sep 17 00:00:00 2001 From: "k2.nagaraju" Date: Thu, 1 Oct 2020 22:52:13 +0530 Subject: [PATCH 13/16] [Service] Update app_id based on input received. If passed parameter is |false| or |undefined| then also |app_id| is updated as current app id. which is causing failure in application webtct failure. Change-Id: Id4ba0c2ea5068620c422585311cfc65ed81ad6c8 Signed-off-by: k2.nagaraju --- wrt_app/service/device_api_router.ts | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/wrt_app/service/device_api_router.ts b/wrt_app/service/device_api_router.ts index 42a57f3..5bdb1ed 100644 --- a/wrt_app/service/device_api_router.ts +++ b/wrt_app/service/device_api_router.ts @@ -124,34 +124,38 @@ export class DeviceAPIRouter { } // tizen.application.getAppInfo() this.funcGetAppInfo = global.tizen.application.getAppInfo; - global.tizen.application.getAppInfo = (app_id?: string) => { - console.log(`Routing - getAppInfo()`); - if (!app_id) + global.tizen.application.getAppInfo = (...args: any[]) => { + let app_id = args[0]; + if (!args.length || args[0] === null) app_id = this.getServiceId(); + console.log(`Routing - getAppInfo()`); return this.funcGetAppInfo(app_id); } // tizen.application.getAppCerts() this.funcGetAppcerts = global.tizen.application.getAppCerts; - global.tizen.application.getAppCerts = (app_id?: string) => { - console.log(`Routing - getAppCerts()`); - if (!app_id) + global.tizen.application.getAppCerts = (...args: any[]) => { + let app_id = args[0]; + if (!args.length || args[0] === null) app_id = this.getServiceId(); + console.log(`Routing - getAppCerts() ` + app_id); return this.funcGetAppcerts(app_id); } // tizen.application.getAppSharedURI() this.funcGetSharedUri = global.tizen.application.getAppSharedURI; - global.tizen.application.getAppSharedURI = (app_id?: string) => { - console.log(`Routing - getAppSharedURI()`); - if (!app_id) + global.tizen.application.getAppSharedURI = (...args: any[]) => { + let app_id = args[0]; + if (!args.length || args[0] === null) app_id = this.getServiceId(); + console.log(`Routing - getAppSharedURI()`); return this.funcGetSharedUri(app_id); } // tizen.application.getAppMetaData() this.funcGetMetadata = global.tizen.application.getAppMetaData; - global.tizen.application.getAppMetaData = (app_id?: string) => { - console.log(`Routing - getAppMetaData()`); - if (!app_id) + global.tizen.application.getAppMetaData = (...args: any[]) => { + let app_id = args[0]; + if (!args.length || args[0] === null) app_id = this.getServiceId(); + console.log(`Routing - getAppMetaData()`); return this.funcGetMetadata(app_id); } } -- 2.7.4 From 2b011acf4a65ec8b940605ddeb53cc3709f2009d Mon Sep 17 00:00:00 2001 From: DongHyun Song Date: Mon, 28 Sep 2020 15:32:06 +0900 Subject: [PATCH 14/16] [Service] Apply node worker for standalone model This change is implemented for 1) unify source code with global model 2) isolate v8 variable scope from main thread - standalone service application cannot get main global variable of service_manaer / service_runner There is no noticeable memory increase with node worker. Change-Id: I7bb4576026ce326a3903987c537810093db028b4 Signed-off-by: DongHyun Song --- wrt_app/common/service_manager.ts | 33 +++++++-------------------------- wrt_app/service/main.ts | 3 --- 2 files changed, 7 insertions(+), 29 deletions(-) diff --git a/wrt_app/common/service_manager.ts b/wrt_app/common/service_manager.ts index 3038364..c4b2940 100644 --- a/wrt_app/common/service_manager.ts +++ b/wrt_app/common/service_manager.ts @@ -5,16 +5,11 @@ interface WorkerMap { [id: string]: any; } let workers: WorkerMap = {}; -let runner: any; global.serviceType = wrt.getServiceModel(); -function isStandalone() { - return global.serviceType === 'STANDALONE'; -} - -function isGlobalService() { - return global.serviceType === 'DAEMON'; +function isServiceApplication() { + return global.serviceType !== 'UI'; } function createWorker(id: string, startService: string, filename: string) { @@ -37,7 +32,7 @@ function terminateWorker(id: string, delay: number) { delete workers[id]; let runningServices = Object.keys(workers).length; console.log('Running services : ' + runningServices); - if (runningServices === 0 && isGlobalService()) { + if (runningServices === 0 && isServiceApplication()) { process.exit(); } } @@ -46,29 +41,15 @@ function terminateWorker(id: string, delay: number) { export function startService(id: string, filename: string) { console.log(`startService - ${id}`); - if (isStandalone()) { - runner = require('../common/service_runner'); - runner.start(id, filename); - } else { - if (isMainThread) { - let startService = `${__dirname}/service_runner.js`; - createWorker(id, startService, filename); - } + if (isMainThread) { + let startService = `${__dirname}/service_runner.js`; + createWorker(id, startService, filename); } } export function stopService(id: string) { console.log(`stopService - ${id}`); - if (isStandalone()) { - if (!runner) { - console.log('runner instance is null in standalone mode'); - return; - } - runner.stop(id); - setTimeout(() => process.exit(), 500); - } else { - terminateWorker(id, 500); - } + terminateWorker(id, 500); } export function handleBuiltinService(serviceId: string, serviceName: string) { diff --git a/wrt_app/service/main.ts b/wrt_app/service/main.ts index b0c371a..c64591e 100755 --- a/wrt_app/service/main.ts +++ b/wrt_app/service/main.ts @@ -27,9 +27,6 @@ wrt.on('start-service', (event: any, internal_id: string) => { wrt.on('stop-service', (event: any, internal_id: string) => { ServiceManager.stopService(internal_id); - if (wrt.getServiceModel() === 'STANDALONE') { - setTimeout(() => {process.exit()}, 10); - } }); wrt.on('builtin-service', (event: any, internal_id: string, service_name: string) => { -- 2.7.4 From 8d65e05cc5e16bc8dbf7e3c388c2a4939869b5c8 Mon Sep 17 00:00:00 2001 From: Youngsoo Choi Date: Mon, 5 Oct 2020 03:41:42 -0700 Subject: [PATCH 15/16] [Service] Let UI service use web app privileges The UI service has used web app privileges because it resides in Web Runtime browser thread. This resolves following error: >> TypeError: wrt_1.wrt.getPrivileges is not a function Change-Id: I3258513a88b4ae34604ee41b57ac56828656b3ae Signed-off-by: Youngsoo Choi --- wrt_app/service/device_api_router.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wrt_app/service/device_api_router.ts b/wrt_app/service/device_api_router.ts index 5bdb1ed..09bb5af 100644 --- a/wrt_app/service/device_api_router.ts +++ b/wrt_app/service/device_api_router.ts @@ -22,10 +22,11 @@ export class DeviceAPIRouter { this.serviceId = ids[0]; this.callerAppId = ids[1] ?? ''; this.packageId = this.serviceId.split('.')[0]; - this.permissions = wrt.getPrivileges(this.id); + this.permissions = []; this.initWebapis(); if (isGlobal) { + this.permissions = wrt.getPrivileges(this.id); this.refineApplicationApis(); this.refinePackageApis(); this.refineFilesystemApis() -- 2.7.4 From f4e898db8745fd155bce9a03aa9f1bbdc4688d45 Mon Sep 17 00:00:00 2001 From: Youngsoo Choi Date: Tue, 6 Oct 2020 02:32:50 -0700 Subject: [PATCH 16/16] [Service] Make application.getAppContext work This makes service app have its own service app id from application.getAppContext(), not 'org.tizen.chromium-efl.wrt-service'. Change-Id: I7378802cc61ea42e2b79559e0d83526d7da665dd Signed-off-by: Youngsoo Choi --- wrt_app/service/device_api_router.ts | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/wrt_app/service/device_api_router.ts b/wrt_app/service/device_api_router.ts index 09bb5af..5c39392 100644 --- a/wrt_app/service/device_api_router.ts +++ b/wrt_app/service/device_api_router.ts @@ -6,6 +6,7 @@ export class DeviceAPIRouter { funcRequestedAppcontrol: any; funcGetAppInfo: any; funcGetAppcerts: any; + funcGetContext: any; funcGetSharedUri: any; funcGetMetadata: any; funcGetPackageInfo: any; @@ -105,6 +106,10 @@ export class DeviceAPIRouter { return global.webapis.getPackageId(); } + hasNoneOrNull(...args: any[]) { + return !args.length || null === args[0]; + } + refineApplicationApis() { // tizen.application.getCurrentApplication() this.funcCurrentApplication = global.tizen.application.getCurrentApplication; @@ -127,7 +132,7 @@ export class DeviceAPIRouter { this.funcGetAppInfo = global.tizen.application.getAppInfo; global.tizen.application.getAppInfo = (...args: any[]) => { let app_id = args[0]; - if (!args.length || args[0] === null) + if (this.hasNoneOrNull(args)) app_id = this.getServiceId(); console.log(`Routing - getAppInfo()`); return this.funcGetAppInfo(app_id); @@ -136,16 +141,28 @@ export class DeviceAPIRouter { this.funcGetAppcerts = global.tizen.application.getAppCerts; global.tizen.application.getAppCerts = (...args: any[]) => { let app_id = args[0]; - if (!args.length || args[0] === null) + if (this.hasNoneOrNull(args)) app_id = this.getServiceId(); console.log(`Routing - getAppCerts() ` + app_id); return this.funcGetAppcerts(app_id); } + // tizen.application.getAppContext() + this.funcGetContext = global.tizen.application.getAppContext; + global.tizen.application.getAppContext = (...args: any[]) => { + console.log(`Routing - getAppContext()`); + if (this.hasNoneOrNull(args)) { + const context = {"id": this.funcGetContext().id, "appId": this.getServiceId()}; + Object.defineProperty(context, 'appId', { writable: false }); + Object.defineProperty(context, 'id', { writable: false }); + return context; + } + return this.funcGetContext(args[0]); + } // tizen.application.getAppSharedURI() this.funcGetSharedUri = global.tizen.application.getAppSharedURI; global.tizen.application.getAppSharedURI = (...args: any[]) => { let app_id = args[0]; - if (!args.length || args[0] === null) + if (this.hasNoneOrNull(args)) app_id = this.getServiceId(); console.log(`Routing - getAppSharedURI()`); return this.funcGetSharedUri(app_id); @@ -154,7 +171,7 @@ export class DeviceAPIRouter { this.funcGetMetadata = global.tizen.application.getAppMetaData; global.tizen.application.getAppMetaData = (...args: any[]) => { let app_id = args[0]; - if (!args.length || args[0] === null) + if (this.hasNoneOrNull(args)) app_id = this.getServiceId(); console.log(`Routing - getAppMetaData()`); return this.funcGetMetadata(app_id); @@ -166,7 +183,7 @@ export class DeviceAPIRouter { this.funcGetPackageInfo = global.tizen.package.getPackageInfo; global.tizen.package.getPackageInfo = (...args: any[]) => { let package_id = args[0]; - if (!args.length || args[0] === null) + if (this.hasNoneOrNull(args)) package_id = this.getPackageId(); console.log(`Routing - getPackageInfo() : ${package_id}`); return this.funcGetPackageInfo(package_id); -- 2.7.4