From 8b45240fb1eaea93bedf12079beff1a24eeaad59 Mon Sep 17 00:00:00 2001 From: DongHyun Song Date: Wed, 9 Sep 2020 18:31:38 +0900 Subject: [PATCH 01/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 02/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 03/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 04/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 05/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 06/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 07/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 08/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 09/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 10/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 From 01d19cab2e3a12bea61796dcadbddb6092ccc5cc Mon Sep 17 00:00:00 2001 From: Youngsoo Choi Date: Wed, 7 Oct 2020 01:08:49 -0700 Subject: [PATCH 11/16] fixup! [Service] Make application.getAppContext work This changes arguments with array. Change-Id: I4f729b560b581a94c6f2ce1a914baf0bece55038 Signed-off-by: Youngsoo Choi --- 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 5c39392..a9cbdde 100644 --- a/wrt_app/service/device_api_router.ts +++ b/wrt_app/service/device_api_router.ts @@ -106,7 +106,7 @@ export class DeviceAPIRouter { return global.webapis.getPackageId(); } - hasNoneOrNull(...args: any[]) { + hasNoneOrNull(args: any[]) { return !args.length || null === args[0]; } -- 2.7.4 From de7f2584aaeca8fa264bd539a5be2cb938fe83d9 Mon Sep 17 00:00:00 2001 From: Youngsoo Choi Date: Wed, 7 Oct 2020 21:43:49 -0700 Subject: [PATCH 12/16] [Service] Make application.getCurrentApplication work The appInfo.id of application.getCurrentApplication() should be its own service id, not 'org.tizen.chromium-efl.wrt-service'. The object returned from application.getCurrentApplication() is non re-writable. So, new object is needed to modify the id. Btw, broadcast APIs need to have daemon id because they are working on app id of current process. Change-Id: I71a62f9dc0bccd68fa7e2b9269a2543e651ec64a Signed-off-by: Youngsoo Choi --- wrt_app/service/device_api_router.ts | 42 +++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/wrt_app/service/device_api_router.ts b/wrt_app/service/device_api_router.ts index a9cbdde..4ccf2ef 100644 --- a/wrt_app/service/device_api_router.ts +++ b/wrt_app/service/device_api_router.ts @@ -117,7 +117,41 @@ export class DeviceAPIRouter { console.log(`Routing - getCurrentApplication() : ${this.getServiceId()}`); if (this.currentApplication) return this.currentApplication; - this.currentApplication = this.funcCurrentApplication(); + this.currentApplication = {}; + const originCurrentApplication = this.funcCurrentApplication(); + for (let key in originCurrentApplication) { + if (key === 'appInfo') { + this.currentApplication.appInfo = {}; + for (let key in originCurrentApplication.appInfo) { + if (key === 'id') { + this.currentApplication.appInfo[key] = this.getServiceId(); + } else { + this.currentApplication.appInfo[key] = originCurrentApplication.appInfo[key]; + } + } + } else { + if (key === 'broadcastEvent' || key === 'broadcastTrustedEvent') { + this.currentApplication[key] = originCurrentApplication[key].bind(originCurrentApplication); + } else { + this.currentApplication[key] = originCurrentApplication[key]; + } + } + } + Object.defineProperties(this.currentApplication.appInfo, { + categories: { writable: false, enumerable: true }, + iconPath: { writable: false, enumerable: true }, + id: { writable: false, enumerable: true }, + installDate: { writable: false, enumerable: true }, + name: { writable: false, enumerable: true }, + packageId: { writable: false, enumerable: true }, + show: { writable: false, enumerable: true }, + size: { enumerable: true }, + version: { writable: false, enumerable: true } + }); + Object.defineProperties(this.currentApplication, { + appInfo: { writable: false, enumerable: true }, + contextId: { writable: false, enumerable: true } + }); // tizen.application.getCurrentApplication().getRequestedAppControl() this.funcRequestedAppcontrol = this.currentApplication.getRequestedAppControl; this.currentApplication.getRequestedAppControl = () => { @@ -152,8 +186,10 @@ export class DeviceAPIRouter { 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 }); + Object.defineProperties(context, { + appId: { writable: false, enumerable: true }, + id: { writable: false, enumerable: true } + }); return context; } return this.funcGetContext(args[0]); -- 2.7.4 From dd79b18738cdb66f003a5195e78b5ff03248e27e Mon Sep 17 00:00:00 2001 From: DongHyun Song Date: Tue, 13 Oct 2020 10:20:10 +0900 Subject: [PATCH 13/16] [Service] Refactor stop service sequence When service application needs to terminate by tizen://exit, it should call wrt.stopService(id). However, it is called in worker thread with standalone model, WRTServiceManager::Remove() will be handled in worker thread, not main thread. then, uv loop sometimes makes abort() or get SIGSEGV. Then, wrt.stopService(id) should be called in main thread side. Change-Id: I103bf8f38111db984bb22d0af56c05456851b681 Signed-off-by: DongHyun Song --- wrt_app/common/service_manager.ts | 15 ++++++++++++--- wrt_app/common/service_runner.ts | 11 ++++++++--- wrt_app/service/builtins/wasm_builder.ts | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/wrt_app/common/service_manager.ts b/wrt_app/common/service_manager.ts index c4b2940..beb3d6e 100644 --- a/wrt_app/common/service_manager.ts +++ b/wrt_app/common/service_manager.ts @@ -43,7 +43,13 @@ export function startService(id: string, filename: string) { console.log(`startService - ${id}`); if (isMainThread) { let startService = `${__dirname}/service_runner.js`; - createWorker(id, startService, filename); + let worker = createWorker(id, startService, filename); + worker.on('message', (message: any) => { + if (message.type === 'stop') { + console.log(`${id} will shutdown after ${message.delay}ms`); + setTimeout(() => wrt.stopService(id), message.delay); + } + }); } } @@ -64,8 +70,11 @@ export function handleBuiltinService(serviceId: string, serviceName: string) { console.log(`Builtin service is ${serviceName}`); let startService = `${__dirname}/../service/builtins/${serviceName}.js`; let worker = createWorker(serviceId, startService, ''); - worker.on('stop', () => { - terminateWorker(serviceId, 0); + worker.on('message', (message: any) => { + if (message.type === 'stop') { + console.log(`${serviceName} built-in service will be stopped`); + terminateWorker(serviceId, message.delay); + } }); } } diff --git a/wrt_app/common/service_runner.ts b/wrt_app/common/service_runner.ts index 43681b5..c86829c 100644 --- a/wrt_app/common/service_runner.ts +++ b/wrt_app/common/service_runner.ts @@ -31,13 +31,18 @@ function registerExtensionResolver(id: string) { } } +function requestStopService(delay: number) { + if (parentPort) { + parentPort.postMessage({type: 'stop', delay: delay}); + } +} + let app: any = null; export function start(id: string, filename: string) { XWalkExtension.initialize(); XWalkExtension.setRuntimeMessageHandler((type, data) => { if (type === 'tizen://exit') { - console.log(`${id} will be closed by ${type}`); - setTimeout(() => wrt.stopService(id), 500); + requestStopService(500); } }); @@ -66,7 +71,7 @@ export function start(id: string, filename: string) { } } catch (e) { console.log(`exception on start: ${e}`); - setTimeout(() => wrt.stopService(id), 500); + requestStopService(500); } } diff --git a/wrt_app/service/builtins/wasm_builder.ts b/wrt_app/service/builtins/wasm_builder.ts index 7ec30a3..6f6c5b1 100644 --- a/wrt_app/service/builtins/wasm_builder.ts +++ b/wrt_app/service/builtins/wasm_builder.ts @@ -26,7 +26,7 @@ export function run(app_id: string) { compileWasmForCaching(file_path); }); if (parentPort) { - parentPort.postMessage('stop'); + parentPort.postMessage({type: 'stop', delay: 0}); } } -- 2.7.4 From 12ff1412f2c81ffce556a1ad5756d42996434898 Mon Sep 17 00:00:00 2001 From: DongHyun Song Date: Tue, 13 Oct 2020 08:14:25 +0000 Subject: [PATCH 14/16] Revert "[Service] Refactor stop service sequence" This reverts commit dd79b18738cdb66f003a5195e78b5ff03248e27e. Change-Id: If6ff1a847e9aeed86faf9fd9fc014971c339096f --- wrt_app/common/service_manager.ts | 15 +++------------ wrt_app/common/service_runner.ts | 11 +++-------- wrt_app/service/builtins/wasm_builder.ts | 2 +- 3 files changed, 7 insertions(+), 21 deletions(-) diff --git a/wrt_app/common/service_manager.ts b/wrt_app/common/service_manager.ts index beb3d6e..c4b2940 100644 --- a/wrt_app/common/service_manager.ts +++ b/wrt_app/common/service_manager.ts @@ -43,13 +43,7 @@ export function startService(id: string, filename: string) { console.log(`startService - ${id}`); if (isMainThread) { let startService = `${__dirname}/service_runner.js`; - let worker = createWorker(id, startService, filename); - worker.on('message', (message: any) => { - if (message.type === 'stop') { - console.log(`${id} will shutdown after ${message.delay}ms`); - setTimeout(() => wrt.stopService(id), message.delay); - } - }); + createWorker(id, startService, filename); } } @@ -70,11 +64,8 @@ export function handleBuiltinService(serviceId: string, serviceName: string) { console.log(`Builtin service is ${serviceName}`); let startService = `${__dirname}/../service/builtins/${serviceName}.js`; let worker = createWorker(serviceId, startService, ''); - worker.on('message', (message: any) => { - if (message.type === 'stop') { - console.log(`${serviceName} built-in service will be stopped`); - terminateWorker(serviceId, message.delay); - } + worker.on('stop', () => { + terminateWorker(serviceId, 0); }); } } diff --git a/wrt_app/common/service_runner.ts b/wrt_app/common/service_runner.ts index c86829c..43681b5 100644 --- a/wrt_app/common/service_runner.ts +++ b/wrt_app/common/service_runner.ts @@ -31,18 +31,13 @@ function registerExtensionResolver(id: string) { } } -function requestStopService(delay: number) { - if (parentPort) { - parentPort.postMessage({type: 'stop', delay: delay}); - } -} - let app: any = null; export function start(id: string, filename: string) { XWalkExtension.initialize(); XWalkExtension.setRuntimeMessageHandler((type, data) => { if (type === 'tizen://exit') { - requestStopService(500); + console.log(`${id} will be closed by ${type}`); + setTimeout(() => wrt.stopService(id), 500); } }); @@ -71,7 +66,7 @@ export function start(id: string, filename: string) { } } catch (e) { console.log(`exception on start: ${e}`); - requestStopService(500); + setTimeout(() => wrt.stopService(id), 500); } } diff --git a/wrt_app/service/builtins/wasm_builder.ts b/wrt_app/service/builtins/wasm_builder.ts index 6f6c5b1..7ec30a3 100644 --- a/wrt_app/service/builtins/wasm_builder.ts +++ b/wrt_app/service/builtins/wasm_builder.ts @@ -26,7 +26,7 @@ export function run(app_id: string) { compileWasmForCaching(file_path); }); if (parentPort) { - parentPort.postMessage({type: 'stop', delay: 0}); + parentPort.postMessage('stop'); } } -- 2.7.4 From a3646fe3fdc71541b00cf057feb2a8a46e346f48 Mon Sep 17 00:00:00 2001 From: DongHyun Song Date: Tue, 13 Oct 2020 08:14:52 +0000 Subject: [PATCH 15/16] Revert "[Service] Apply node worker for standalone model" This reverts commit 2b011acf4a65ec8b940605ddeb53cc3709f2009d. Change-Id: I4203e460734b8befd84a2286663ae6c41a7b3232 --- wrt_app/common/service_manager.ts | 33 ++++++++++++++++++++++++++------- wrt_app/service/main.ts | 3 +++ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/wrt_app/common/service_manager.ts b/wrt_app/common/service_manager.ts index c4b2940..3038364 100644 --- a/wrt_app/common/service_manager.ts +++ b/wrt_app/common/service_manager.ts @@ -5,11 +5,16 @@ interface WorkerMap { [id: string]: any; } let workers: WorkerMap = {}; +let runner: any; global.serviceType = wrt.getServiceModel(); -function isServiceApplication() { - return global.serviceType !== 'UI'; +function isStandalone() { + return global.serviceType === 'STANDALONE'; +} + +function isGlobalService() { + return global.serviceType === 'DAEMON'; } function createWorker(id: string, startService: string, filename: string) { @@ -32,7 +37,7 @@ function terminateWorker(id: string, delay: number) { delete workers[id]; let runningServices = Object.keys(workers).length; console.log('Running services : ' + runningServices); - if (runningServices === 0 && isServiceApplication()) { + if (runningServices === 0 && isGlobalService()) { process.exit(); } } @@ -41,15 +46,29 @@ function terminateWorker(id: string, delay: number) { export function startService(id: string, filename: string) { console.log(`startService - ${id}`); - if (isMainThread) { - let startService = `${__dirname}/service_runner.js`; - createWorker(id, startService, filename); + if (isStandalone()) { + runner = require('../common/service_runner'); + runner.start(id, filename); + } else { + if (isMainThread) { + let startService = `${__dirname}/service_runner.js`; + createWorker(id, startService, filename); + } } } export function stopService(id: string) { console.log(`stopService - ${id}`); - terminateWorker(id, 500); + 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); + } } export function handleBuiltinService(serviceId: string, serviceName: string) { diff --git a/wrt_app/service/main.ts b/wrt_app/service/main.ts index c64591e..b0c371a 100755 --- a/wrt_app/service/main.ts +++ b/wrt_app/service/main.ts @@ -27,6 +27,9 @@ 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 8b7fec189a3c571f4b56ff318b51c7f18cd21651 Mon Sep 17 00:00:00 2001 From: liwei Date: Mon, 28 Sep 2020 15:35:21 +0800 Subject: [PATCH 16/16] [Service][TV] Support more webapis.productinfo Support webapis.productinfo.is8KPanelSupported() / isUHDAModel() / getSmartTVServerType() / isWallModel() Native Patch: https://review.tizen.org/gerrit/244962/ Change-Id: Icdd34cf44338a8d5b92bfad1c98cd96b07309b4a Signed-off-by: liwei --- wrt_app/service/device_api_router.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/wrt_app/service/device_api_router.ts b/wrt_app/service/device_api_router.ts index 4ccf2ef..8884fb3 100644 --- a/wrt_app/service/device_api_router.ts +++ b/wrt_app/service/device_api_router.ts @@ -87,8 +87,26 @@ export class DeviceAPIRouter { }, getSmartTVServerVersion: () => { return getCachedValue('getSmartTVServerVersion'); + }, + getSmartTVServerType: () => { + return Number(getCachedValue('getSmartTVServerType')); + }, + isWallModel: () => { + return (getCachedValue('isWallModel') === 'true'); + }, + isUHDAModel: () => { + return (getCachedValue('isUHDAModel') === 'true'); + }, + is8KPanelSupported: () => { + return (getCachedValue('is8KPanelSupported') === 'true'); } }; + + global.webapis.productinfo.ProductInfoSiServerType = { + SI_TYPE_OPERATIING_SERVER: 0, + SI_TYPE_DEVELOPMENT_SERVER: 1, + SI_TYPE_DEVELOPING_SERVER: 2 + }; } } -- 2.7.4