From 6598bb763862a498bdf9c74ae47f2c113545fdaf Mon Sep 17 00:00:00 2001 From: SangYong Park Date: Fri, 22 Nov 2019 17:17:58 +0900 Subject: [PATCH 01/16] Fix the issue that OnPause function is called after showing splash image Call showSplashScreen exclicity during create main browser window. (prevent showTimer if splash screen is applied.) and fix hideSplashScreen parameter offset. Change-Id: Ia063d72c9de953321c2263935220aaf83878bdc1 Signed-off-by: SangYong Park --- wrt_app/src/web_application.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wrt_app/src/web_application.js b/wrt_app/src/web_application.js index fc38141..c3af185 100755 --- a/wrt_app/src/web_application.js +++ b/wrt_app/src/web_application.js @@ -249,7 +249,7 @@ class WebApplication { }); } let self = this; - if (!wrt.tv) { + if (!wrt.showSplashScreen() && !wrt.tv) { self.showTimer = setTimeout(() => { if (!self.suspended) { console.log('FrameRendered not obtained from engine. To show window, timer fired'); @@ -262,7 +262,7 @@ class WebApplication { console.log('mainWindow ready-to-show'); if (self.showTimer) clearTimeout(self.showTimer); - wrt.hideSplashScreen(1); + wrt.hideSplashScreen(0); self.firstRendered = true; if (self.preloadStatus == 'preload') { self.preloadStatus = 'readyToShow'; @@ -278,7 +278,7 @@ class WebApplication { this.mainWindow.webContents.on('did-finish-load', function() { console.log('webContents did-finish-load'); self.loadFinished = true; - wrt.hideSplashScreen(2); + wrt.hideSplashScreen(1); if (wrt.isIMEWebApp()) { self.activateIMEWebHelperClient(); } else if (wrt.tv) { -- 2.7.4 From e4c643a762edddf72bc68216f19355b97ab42dc2 Mon Sep 17 00:00:00 2001 From: Youngsoo Choi Date: Wed, 27 Nov 2019 04:42:21 -0800 Subject: [PATCH 02/16] [Service] Refactor tizen extension module to be called on demand The tiezn extension module is loaded on demand to reduce memory usage. It's not loaded until web service starts. Change-Id: I760310b617de49bb6f1968cf64d6938d3bec63cb Signed-off-by: Youngsoo Choi --- wrt_app/service/tizen_extension.js | 68 ++++++++++++++++++-------------------- wrt_app/src/runtime.js | 14 +++++++- 2 files changed, 46 insertions(+), 36 deletions(-) diff --git a/wrt_app/service/tizen_extension.js b/wrt_app/service/tizen_extension.js index 6e80497..3c88d5a 100644 --- a/wrt_app/service/tizen_extension.js +++ b/wrt_app/service/tizen_extension.js @@ -14,7 +14,6 @@ * limitations under the License. */ -(function() { const extension = require('./wrt_service_extension'); const wrt = require('../browser/wrt'); var window = global; @@ -22,33 +21,33 @@ var api_ = {}; var extensions_ = {}; var runtime_variables_ = {'runtime_name': 'wrt-service'}; -var ExtensionLoader = function() { - let plugins = require('./plugins.json'); - extension.initialize(runtime_variables_); - - var extensions = extension.getExtensions(); - for (var i = 0; i < extensions.length; i++) { - extensions[i].loaded = false; - for (var idx in plugins) { - if (extensions[i].name === plugins[idx].name) { - console.log("ExtensionLoader name " + extensions[i].name); - extensions_[extensions[i].name] = extensions[i]; +class TizenExtension { + constructor() { + let plugins = require('./plugins.json'); + extension.initialize(runtime_variables_); + + var extensions = extension.getExtensions(); + for (var i = 0; i < extensions.length; i++) { + extensions[i].loaded = false; + for (var idx in plugins) { + if (extensions[i].name === plugins[idx].name) { + console.log("ExtensionLoader name " + extensions[i].name); + extensions_[extensions[i].name] = extensions[i]; + } } } - } - for (var name in extensions_) { - if (!extensions_[name].use_trampoline) { - this.load(extensions_[name]); + for (var name in extensions_) { + if (!extensions_[name].use_trampoline) { + this.load(extensions_[name]); + } } - } - for (var name in extensions_) { - if (extensions_[name].use_trampoline) { - this.installTrampoline(extensions_[name]); + for (var name in extensions_) { + if (extensions_[name].use_trampoline) { + this.installTrampoline(extensions_[name]); + } } } -}; -ExtensionLoader.prototype = { /** * Creates namespace for 'name' in given object. * Eg. this.createNamespace(GLOBAL, 'tizen.contact') will create: @@ -57,15 +56,16 @@ ExtensionLoader.prototype = { * @param {Object} object * @param {String} name */ - createNamespace: function(object, name) { + createNamespace(object, name) { var obj = object; var arr = name.split('.'); for (var i = 0; i < arr.length; i++) { obj[arr[i]] = obj[arr[i]] || {}; obj = obj[arr[i]]; } - }, - exposeApi: function (ext) { + } + + exposeApi(ext) { var i, entry_points, entry_point, tmp, parent_name, base_name; // additional entry points are installed in GLOBAL context by eval() @@ -99,12 +99,12 @@ ExtensionLoader.prototype = { enumerable: true }); } - }, + } /** * @param {Object} ext */ - load: function(ext) { + load(ext) { if (ext.loaded) { return; } @@ -168,7 +168,7 @@ ExtensionLoader.prototype = { } catch (err) { console.log('Error loading extension "' + ext.name + '": ' + err.message); } - }, + } /** * This is used to defer extension loading to it's first usage. @@ -176,7 +176,7 @@ ExtensionLoader.prototype = { * * @param {Object} ext */ - installTrampoline: function(ext) { + installTrampoline(ext) { var entry_points = [...new Set(ext.entry_points)]; entry_points.push(ext.name); for (var i = 0; i < entry_points.length; i++) { @@ -201,9 +201,9 @@ ExtensionLoader.prototype = { enumerable: true }); } - }, + } - deleteTrampoline: function(ext) { + deleteTrampoline(ext) { var entry_points = [...new Set(ext.entry_points)]; entry_points.push(ext.name); @@ -214,7 +214,5 @@ ExtensionLoader.prototype = { delete GLOBAL[parent_name][base_name]; } } -}; - -new ExtensionLoader(); -})(); +} +module.exports = TizenExtension; diff --git a/wrt_app/src/runtime.js b/wrt_app/src/runtime.js index 077bdcf..7ca90c2 100755 --- a/wrt_app/src/runtime.js +++ b/wrt_app/src/runtime.js @@ -33,6 +33,7 @@ class Runtime { this.isLaunched = false; this.inspectorEnabledByVconf = false; this.sandbox = []; + this.sandbox_count = 0; this.webContents = null; this.addonPkgs = []; @@ -209,6 +210,10 @@ class Runtime { const vm = require('vm'); if (type === 'startService') { if (_this.sandbox[app_id] === undefined) { + if (_this.sandbox_count === 0) { + new TizenExtension(); + } + _this.sandbox_count++; const fs = require('fs'); const Module = require('module'); _this.sandbox[app_id] = { @@ -253,12 +258,19 @@ class Runtime { event.preventDefault(); } else if (type === 'stopService') { if (_this.sandbox[app_id]['stopped'] === undefined) { + _this.sandbox_count--; _this.sandbox[app_id]['stopped'] = true; _this.sandbox[app_id]['started'] = undefined; const stop_callback_string = 'if (module.exports.onStop !== undefined) { module.exports.onStop(); }'; vm.runInContext(stop_callback_string, _this.sandbox[app_id]); _this.sandbox[app_id]['timer_manager'].releaseRemainingTimers(); - _this.sandbox[app_id] = undefined; + for(let key in _this.sandbox[app_id]) { + delete _this.sandbox[app_id][key]; + } + delete _this.sandbox[app_id]; + if (sandbox_count === 0) { + tizen = null; + } } else { console.log('UI service has been stopped.'); } -- 2.7.4 From a717e2c56372134d4e094a5eec24699d8c6010da Mon Sep 17 00:00:00 2001 From: Youngsoo Choi Date: Wed, 27 Nov 2019 21:59:01 -0800 Subject: [PATCH 03/16] fixup! [Service] Refactor tizen extension module to be called on demand This adds missed _this object. Change-Id: Ie697fc4e876063e57ec484339861424416a1ef6d Signed-off-by: Youngsoo Choi --- wrt_app/src/runtime.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrt_app/src/runtime.js b/wrt_app/src/runtime.js index 7ca90c2..14c51c5 100755 --- a/wrt_app/src/runtime.js +++ b/wrt_app/src/runtime.js @@ -268,7 +268,7 @@ class Runtime { delete _this.sandbox[app_id][key]; } delete _this.sandbox[app_id]; - if (sandbox_count === 0) { + if (_this.sandbox_count === 0) { tizen = null; } } else { -- 2.7.4 From 2a9a06be0a4e0105bc2ba1af71fc2de1bb3b73c6 Mon Sep 17 00:00:00 2001 From: liwei Date: Thu, 5 Dec 2019 21:56:24 +0800 Subject: [PATCH 04/16] [VD] Fix issue for app deeplink that page is not reload When amazon music app(3201710014874) is shown in FG, and press preview in amazon music, page is not reload, bcz WRT think request src is the same with original url. request src is "file:///index.html#!/deepLink", original url is "file:///index.html#!/main/home". Actually they are different, WRT should reload it. Change-Id: I7f7b5767c1a34b017f80d6babe8e58f760f967a1 Signed-off-by: liwei --- wrt_app/src/runtime.js | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) mode change 100755 => 100644 wrt_app/src/runtime.js diff --git a/wrt_app/src/runtime.js b/wrt_app/src/runtime.js old mode 100755 new mode 100644 index 14c51c5..c0a59ce --- a/wrt_app/src/runtime.js +++ b/wrt_app/src/runtime.js @@ -157,20 +157,25 @@ class Runtime { let reload = loadInfo.getReload() || _this.webApplication.isAlwaysReload; if (!reload) { + let originalUrl = _this.webApplication.mainWindow.getURL(); if (wrt.tv) { - console.log(`src = ${src}, app-control uri = ${_this.webApplication.mainWindow.getURL()}`); - const url = require('url'); - let appcontrolUrl = url.parse(src); - let originUrl = url.parse(_this.webApplication.mainWindow.getURL()); - if (appcontrolUrl.protocol !== originUrl.protocol || - appcontrolUrl.host !== originUrl.host || - appcontrolUrl.pathname !== originUrl.pathname) { - reload = true; - } - } else { - if (src != _this.webApplication.mainWindow.getURL()) { + console.log(`appcontrol src = ${src}, original url = ${originalUrl}`); + if (src && originalUrl) { + let appcontrolUrl = new URL(src); + let oldUrl = new URL(originalUrl); + if ('file:' !== appcontrolUrl.protocol && + (appcontrolUrl.protocol !== oldUrl.protocol || + appcontrolUrl.host !== oldUrl.host || + appcontrolUrl.pathname !== oldUrl.pathname)) { + reload = true; + } else if ('file:' === appcontrolUrl.protocol && (src !== originalUrl)) { + reload = true; + } + } else if (src !== originalUrl) { reload = true; } + } else if (src !== originalUrl) { + reload = true; } } // handle http://tizen.org/appcontrol/operation/main operation specially. -- 2.7.4 From 064cd6515c989ad95caed8195db1d0273d587809 Mon Sep 17 00:00:00 2001 From: DongHyun Song Date: Wed, 18 Dec 2019 02:48:47 +0000 Subject: [PATCH 05/16] Revert "[VD][Workaround] Show popup when need default client cert" This reverts commit e2ffe802b48f3465572d60ba3b6337409d758ea8. Change-Id: I55fbeeaf1ceab5fea8b9a82bd0529aa5d7ed14f9 Signed-off-by: DongHyun Song --- wrt_app/src/web_application.js | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/wrt_app/src/web_application.js b/wrt_app/src/web_application.js index c3af185..7680eae 100755 --- a/wrt_app/src/web_application.js +++ b/wrt_app/src/web_application.js @@ -137,22 +137,6 @@ class WebApplication { wrt.handleAuthRequest(id, webContents); } }); - if (wrt.tv) { - // TODO. This logic in only for QA verification - // Current TV default client cert will be expired. - // So that detecting apps which use TV client certificate, - // adds popup alarms for QA - app.on('select-client-certificate', function(event, webContents, host, list, callback) { - console.log('select-client-certificate'); - event.preventDefault(); - if (list.length > 0 && list[0].subjectName == 'Samsung TV,BDP certificate') { - setTimeout(() => { - wrt.tv.showDialog(webContents, 'Samsung TV,BDP certificate'); - }, 7000); - } - callback(list[0]); - }); - } if (this.accessiblePath) { console.log(`accessiblePath: ${this.accessiblePath}`); protocol.interceptFileProtocol('file', (request, callback) => { -- 2.7.4 From ea8975a312813f766a9cc5ad71d8461584d5c77f Mon Sep 17 00:00:00 2001 From: liwei Date: Tue, 24 Dec 2019 18:09:14 +0800 Subject: [PATCH 06/16] [VD] Cancel Auth if no proxy usrname/passwd Follow 5.0 spec, if proxy need login and no usrname/passwd, WRT will cancel auth not show popup for user to input usrname and passwd. Change-Id: Ie1851b745e75fb065d3d96bb22cc4c824f08f0b5 Signed-off-by: liwei --- wrt_app/src/web_application.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) mode change 100755 => 100644 wrt_app/src/web_application.js diff --git a/wrt_app/src/web_application.js b/wrt_app/src/web_application.js old mode 100755 new mode 100644 index 7680eae..38efdab --- a/wrt_app/src/web_application.js +++ b/wrt_app/src/web_application.js @@ -127,9 +127,12 @@ class WebApplication { usrname = proxyInfo.username; passwd = proxyInfo.password; } - } - if (usrname && passwd) { - callback(usrname, passwd); + if (usrname && passwd) { + callback(usrname, passwd); + } else { + console.log('Login, but usrname and passwd is empty!!!'); + callback(); + } } else { const id = ++self.pendingID; console.log(`Raising a login info request with id: ${id}`); -- 2.7.4 From 31da1d9b3ffa7df5fdc2c538267f1a9773827d90 Mon Sep 17 00:00:00 2001 From: liwei Date: Mon, 30 Dec 2019 15:28:58 +0800 Subject: [PATCH 07/16] [VD] Fix deeplink issue in current known scenario This patch will cover well deeplink issues which we have known. Common WRT's deep link policy is very simple, it just check sameness, but to support compatibility of previous apps on TV side, VD WRT has to handle below difference cases. 1) 'TVing': not-reload From http://d2ehepluhe2jv7.cloudfront.net/#/ to http://d2ehepluhe2jv7.cloudfront.net 2) SlingTV: not-reload From file:///index.html#/login to file:///index.html 3) 'Amazon Music': will-reload From file:///index.html#!/main/home to file:///index.html#!/deepLink However, this logic has a potential problem with below case, even though the URL has reload to appcontol's src but, it will be skipped. To solve this problem is easy but, it conflicts previous compatibility functionality. From file:///index.htmlx to file:///index.html Change-Id: I401a8ead2f745de3ce938b16ac5c11efb4d9bd66 Signed-off-by: liwei --- wrt_app/src/runtime.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/wrt_app/src/runtime.js b/wrt_app/src/runtime.js index c0a59ce..dac4b09 100644 --- a/wrt_app/src/runtime.js +++ b/wrt_app/src/runtime.js @@ -161,17 +161,16 @@ class Runtime { if (wrt.tv) { console.log(`appcontrol src = ${src}, original url = ${originalUrl}`); if (src && originalUrl) { - let appcontrolUrl = new URL(src); - let oldUrl = new URL(originalUrl); - if ('file:' !== appcontrolUrl.protocol && - (appcontrolUrl.protocol !== oldUrl.protocol || - appcontrolUrl.host !== oldUrl.host || - appcontrolUrl.pathname !== oldUrl.pathname)) { - reload = true; - } else if ('file:' === appcontrolUrl.protocol && (src !== originalUrl)) { - reload = true; + let appcontrolUrl = (new URL(src)).href; + let oldUrl = (new URL(originalUrl)).href; + console.log(`appcontrolUrl = ${appcontrolUrl}, oldUrl = ${oldUrl}`); + // FIXME(dh81.song) + // Below case it must be distinguishable for known cases + // from 'file:///index.htmlx' to 'file:///index.html' + if (appcontrolUrl !== oldUrl.substr(0, appcontrolUrl.length)) { + reload = true; } - } else if (src !== originalUrl) { + } else { reload = true; } } else if (src !== originalUrl) { -- 2.7.4 From 6b44aee3be25d7d958152076d9a27ce02b46672d Mon Sep 17 00:00:00 2001 From: "k2.nagaraju" Date: Fri, 22 Nov 2019 20:38:13 +0530 Subject: [PATCH 08/16] [Service][Global] Support tizen web device APIs This supports tizen web device APIS. Change-Id: I61e088aa5fda4fb2479fed310426caa058ed1c41 Signed-off-by: k2.nagaraju --- wrt_app/service/main.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/wrt_app/service/main.js b/wrt_app/service/main.js index 782fd2e..2098ad5 100755 --- a/wrt_app/service/main.js +++ b/wrt_app/service/main.js @@ -18,15 +18,19 @@ const wrt = require('../browser/wrt'); const vm = require('vm'); +const TizenExtension = require('./tizen_extension'); var sandbox = []; wrt.on('start-service', (event, app_id) => { console.log('start service app : ' + app_id); + new TizenExtension(); if (sandbox[app_id] === undefined) { + const Module = require('module'); sandbox[app_id] = { console: console, - module: module, + module: new Module, require: require, + tizen: tizen, }; let options = { filename: app_id }; vm.runInNewContext(wrt.readService(app_id), sandbox[app_id], options); -- 2.7.4 From 0b9845ca6f60b69b9e93dfb1cb742da32fd7d8c7 Mon Sep 17 00:00:00 2001 From: Youngsoo Choi Date: Mon, 25 Nov 2019 20:42:42 -0800 Subject: [PATCH 09/16] [Service][Global] Expose standard and global objects This enables functions and properties of global object, such as setInterval, setTimeout, and etc in service apps. Also, the primitives and standard objects are exposed to fix following undefined and type-mismatched errors: > Cannot set property 'setDate' of undefined > Cannot convert 11,21,31,71,81,91 to Uint8Array The list refers to following site: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects Change-Id: I61977e05b73b3817b75591d2c8b0bb708f175c8d Signed-off-by: Youngsoo Choi --- wrt_app/service/main.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/wrt_app/service/main.js b/wrt_app/service/main.js index 2098ad5..9713ffb 100755 --- a/wrt_app/service/main.js +++ b/wrt_app/service/main.js @@ -32,6 +32,22 @@ wrt.on('start-service', (event, app_id) => { require: require, tizen: tizen, }; + for(let key in global) { + sandbox[app_id][key] = global[key]; + } + let standard_object_list = [ Error, EvalError, RangeError, ReferenceError, + SyntaxError, TypeError, URIError, Number, BigInt, Math, Date, + String, RegExp, Array, Int8Array, Uint8Array, Uint8ClampedArray, + Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, + Float64Array, BigInt64Array, BigUint64Array, Map, Set, WeakMap, + WeakSet, ArrayBuffer, DataView, JSON, Promise, Reflect, Proxy, + Intl, Intl.Collator, Intl.DateTimeFormat, Intl.NumberFormat, Intl.PluralRules, + WebAssembly, WebAssembly.Module, WebAssembly.Instance, WebAssembly.Memory, + WebAssembly.Table, WebAssembly.CompileError, WebAssembly.LinkError, + WebAssembly.RuntimeError, Boolean, Function, Object, Symbol ]; + for (let idx in standard_object_list) { + sandbox[app_id][standard_object_list[idx].name] = standard_object_list[idx]; + } let options = { filename: app_id }; vm.runInNewContext(wrt.readService(app_id), sandbox[app_id], options); -- 2.7.4 From 690a82fac06197ea379322e486df1976ce598405 Mon Sep 17 00:00:00 2001 From: Youngsoo Choi Date: Tue, 26 Nov 2019 21:29:54 -0800 Subject: [PATCH 10/16] [Service][Global] Add handler of stop-service This adds handler of stop-service. Change-Id: I7c73f9a204844216141edc47ab26e142368ec3d1 Signed-off-by: Youngsoo Choi --- wrt_app/service/main.js | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/wrt_app/service/main.js b/wrt_app/service/main.js index 9713ffb..19594ce 100755 --- a/wrt_app/service/main.js +++ b/wrt_app/service/main.js @@ -19,12 +19,18 @@ const wrt = require('../browser/wrt'); const vm = require('vm'); const TizenExtension = require('./tizen_extension'); + var sandbox = []; +var sandbox_count = 0; wrt.on('start-service', (event, app_id) => { console.log('start service app : ' + app_id); new TizenExtension(); if (sandbox[app_id] === undefined) { + if (sandbox_count === 0) { + new TizenExtension(); + } + sandbox_count++; const Module = require('module'); sandbox[app_id] = { console: console, @@ -57,13 +63,33 @@ wrt.on('start-service', (event, app_id) => { } if (sandbox[app_id]['started'] === undefined) { sandbox[app_id]['started'] = true; + sandbox[app_id]['stopped'] = undefined; const start_callback_string = 'if (module.exports.onStart !== undefined) { module.exports.onStart(); }'; vm.runInContext(start_callback_string, sandbox[app_id]); } const request_callback_string = 'if (module.exports.onRequest !== undefined) { module.exports.onRequest(); }'; vm.runInContext(request_callback_string, sandbox[app_id]); -}) +}); + +wrt.on('stop-service', (event, app_id) => { + if (sandbox[app_id]['stopped'] === undefined) { + sandbox_count--; + sandbox[app_id]['stopped'] = true; + sandbox[app_id]['started'] = undefined; + const stop_callback_string = 'if (module.exports.onStop !== undefined) { module.exports.onStop(); }'; + vm.runInContext(stop_callback_string, sandbox[app_id]); + for(let key in sandbox[app_id]) { + delete sandbox[app_id][key]; + } + delete sandbox[app_id]; + if (sandbox_count === 0) { + tizen = null; + } + } else { + console.log('The global service has been already stopped.'); + } +}); process.on('exit', (code) => { console.log('Exit with code : ' + code); -}) +}); -- 2.7.4 From 8c0aa40bf1e2768b25db44536032d8b58df3ab40 Mon Sep 17 00:00:00 2001 From: "k2.nagaraju" Date: Tue, 17 Dec 2019 20:30:57 +0530 Subject: [PATCH 11/16] [Service][Global] Implement access control for privilege management This provides access control as per specified privileges in config.xml for service application. Change-Id: I2bae3574fccd9e7333c485e6b3229b407ad28660 Signed-off-by: k2.nagaraju Signed-off-by: Youngsoo Choi --- wrt_app/service/access_control_manager.js | 123 ++++++++++++++++++++++++++++++ wrt_app/service/main.js | 7 +- 2 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 wrt_app/service/access_control_manager.js diff --git a/wrt_app/service/access_control_manager.js b/wrt_app/service/access_control_manager.js new file mode 100644 index 0000000..bda869d --- /dev/null +++ b/wrt_app/service/access_control_manager.js @@ -0,0 +1,123 @@ +class AccessControlManager { + constructor(permissions, sandbox) { + this.permissions = permissions; + this.sandbox = sandbox; + this.systeminfo = {}; + this.systeminfo.getPropertyValue = sandbox.tizen.systeminfo.getPropertyValue; + } + initialize() { + const permissions = this.permissions; + let tizen = this.sandbox.tizen; + if (!permissions.includes("http://tizen.org/privilege/alarm")) { + tizen.alarm.add = + tizen.alarm.remove = + tizen.alarm.removeAll = + tizen.alarm.get = + tizen.alarm.getAll = + tizen.alarm.getAlarmNotification = + tizen.alarm.addAlarmNotification = function() { + console.log('The alarm permission is missing.'); + } + } + if (!permissions.includes("http://tizen.org/privilege/apphistory.read")) { + tizen.application.getAppsUsageInfo = + tizen.application.getBatteryUsageInfo = function() { + console.log('The application.read permission is missing.'); + } + } + if (!permissions.includes("http://tizen.org/privilege/application.launch")) { + tizen.application.launch = + tizen.application.launchAppControl = function() { + console.log('The application.launch permission is missing.'); + } + } + if (!permissions.includes("http://tizen.org/privilege/application.info")) { + tizen.application.getAppMetaData = function() { + console.log('The application.info permission is missing.'); + } + } + if (!permissions.includes("http://tizen.org/privilege/appmanager.certificate")) { + tizen.application.getAppCerts = function() { + console.log('The application.certificate permission is missing.'); + } + } + if (!permissions.includes("http://tizen.org/privilege/appmanager.kill")) { + tizen.application.kill = function() { + console.log('The application.kill permission is missing.'); + } + } + if (!permissions.includes("http://tizen.org/privilege/appmanager.launch") || + !permissions.includes("http://tizen.org/privilege/datasharing")) { + tizen.datacontrol.addChangeListener = + tizen.datacontrol.removeChangeListener = function() { + console.log('The appmanager.launch or datasharing permission is missing.'); + } + } + if (!permissions.includes("http://tizen.org/privilege/datacontrol.consumer")) { + tizen.datacontrol.getValue = + tizen.datacontrol.updateValue = + tizen.datacontrol.insert = + tizen.datacontrol.update = + tizen.datacontrol.remove = + tizen.datacontrol.select = + tizen.datacontrol.addValue = + tizen.datacontrol.removeValue = + tizen.datacontrol.getDataControlConsumer = function() { + console.log('The datacontrol.consumer permission is missing.'); + } + } + if (!permissions.includes("http://tizen.org/privilege/filesystem.read")) { + tizen.filesystem.listDirectory = + tizen.filesystem.isFile = + tizen.filesystem.isDirectory = + tizen.filesystem.pathExists = + tizen.filesystem.copyFile = + tizen.filesystem.copyDirectory = + tizen.filesystem.moveFile = + tizen.filesystem.moveDirectory = + tizen.filesystem.resolve = function() { + console.log('The filesystem.read permission is missing.'); + } + } + if (!permissions.includes("http://tizen.org/privilege/filesystem.write")) { + tizen.filesystem.createDirectory = + tizen.filesystem.deleteFile = + tizen.filesystem.deleteDirectory = + tizen.filesystem.copyFile = + tizen.filesystem.copyDirectory = + tizen.filesystem.moveFile = + tizen.filesystem.moveDirectory = + tizen.filesystem.rename = function() { + console.log('The filesystem.write permission is missing.'); + } + } + if (!permissions.includes("http://tizen.org/privilege/notification")) { + tizen.alarm.addAlarmNotification = function() { + console.log('The notification permission is missing.'); + } + } + if (!permissions.includes("http://tizen.org/privilege/package.info")) { + tizen.package.setPackageInfoEventListener = + tizen.package.unsetPackageInfoEventListener = + tizen.package.getPackageInfo = + tizen.package.getPackagesInfo = function() { + console.log('The package.info permission is missing.'); + } + } + if (!permissions.includes("http://tizen.org/privilege/packagemanager.install")) { + tizen.package.install = + tizen.package.uninstall = function() { + console.log('The packagemanager.install permission is missing.'); + } + } + // systeminfo : Runtime privilege validation is required, based on parameters + tizen.systeminfo.getPropertyValue = function(type, onSuccessCallback, onErrorCallback) { + if (type === "CELLULAR_NETWORK" && !permissions.includes("http://tizen.org/privilege/telephony")) { + console.log('The telephony permission is missing.'); + return; + } + this.systeminfo.getPropertyValue.apply(tizen.systeminfo, arguments); + }.bind(this); + } +} +module.exports = AccessControlManager; diff --git a/wrt_app/service/main.js b/wrt_app/service/main.js index 19594ce..ed10e5d 100755 --- a/wrt_app/service/main.js +++ b/wrt_app/service/main.js @@ -18,13 +18,14 @@ const wrt = require('../browser/wrt'); const vm = require('vm'); +const AccessControlManager = require('./access_control_manager'); const TizenExtension = require('./tizen_extension'); var sandbox = []; var sandbox_count = 0; -wrt.on('start-service', (event, app_id) => { - console.log('start service app : ' + app_id); +wrt.on('start-service', (event, app_id, permissions) => { + console.log('start service app : ' + app_id + ', permissions : ' + permissions); new TizenExtension(); if (sandbox[app_id] === undefined) { if (sandbox_count === 0) { @@ -38,6 +39,8 @@ wrt.on('start-service', (event, app_id) => { require: require, tizen: tizen, }; + let access_control_manager = new AccessControlManager(permissions, sandbox[app_id]); + access_control_manager.initialize(); for(let key in global) { sandbox[app_id][key] = global[key]; } -- 2.7.4 From b017416c2d8597c1bc99f4bb847e99b44fd6ccc5 Mon Sep 17 00:00:00 2001 From: Youngsoo Choi Date: Mon, 18 Nov 2019 18:43:03 -0800 Subject: [PATCH 12/16] [Service] Provide iteration API setServiceInterval This provides the use of service iteration and usage is like below: * API: setServiceInterval(function, after, repeat); * Parameters: {func} The function |func| will run. {repeat} The number of iteration is |repeat|. The value 0 means infinite and default. {after} The iteration interval is |after| ms and default is 1000 ms. Change-Id: I5e50ddf9c11f6b7a49cf48aa4c526698c044794f Signed-off-by: Youngsoo Choi --- wrt_app/service/timer_manager.js | 14 ++++++++++++++ wrt_app/src/runtime.js | 4 ++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/wrt_app/service/timer_manager.js b/wrt_app/service/timer_manager.js index 1f04a72..e17cd68 100644 --- a/wrt_app/service/timer_manager.js +++ b/wrt_app/service/timer_manager.js @@ -20,6 +20,20 @@ class TimerManager { this.timer_api.setTimeout = function(func, delay) { _this.timeout_handlers.push(setTimeout(func, delay)); } + this.timer_api.setServiceInterval = function(func, after = 1000, repeat = 0) { + if (typeof func !== "function") { + console.log("Use function as the first parameter."); + return; + } + let count = 1; + let handler = this.timer_api.setInterval(function() { + func(); + count++; + if (count > repeat && repeat !== 0) { + this.timer_api.clearInterval(handler); + } + }.bind(this), after); + }.bind(this); } getTimerAPI() { return this.timer_api; diff --git a/wrt_app/src/runtime.js b/wrt_app/src/runtime.js index dac4b09..0ef19b0 100644 --- a/wrt_app/src/runtime.js +++ b/wrt_app/src/runtime.js @@ -229,8 +229,8 @@ class Runtime { for(let key in global) { _this.sandbox[app_id][key] = global[key]; } - _this.sandbox[app_id]['timer_manager'] = new TimerManager(); - const timer_api = _this.sandbox[app_id]['timer_manager'].getTimerAPI(); + _this.sandbox[app_id].timer_manager = new TimerManager(); + const timer_api = _this.sandbox[app_id].timer_manager.getTimerAPI(); for(let key in timer_api) { _this.sandbox[app_id][key] = timer_api[key]; } -- 2.7.4 From 72560a7b582e43ac4380d36b3761ae9384ca9b47 Mon Sep 17 00:00:00 2001 From: "jaekuk, lee" Date: Thu, 5 Dec 2019 16:22:48 -0800 Subject: [PATCH 13/16] [MCD] Update gbs.conf.in & common.sh Fixed the build error for wearable Change-Id: I069f5295630a005c70a547041269130196596303 Signed-off-by: jaekuk, lee --- tizen/build/common.sh | 2 +- tizen/build/gbs.conf.in | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/tizen/build/common.sh b/tizen/build/common.sh index dd94659..5c42bf0 100644 --- a/tizen/build/common.sh +++ b/tizen/build/common.sh @@ -70,7 +70,7 @@ function setupAndExecuteTargetBuild() { fi elif [[ $platform == "wearable" ]]; then if [ "$DEFAULT_TIZEN_VERSION" == "5.5" ]; then - PROFILE=tzwr_5.5_armv7l_spin + PROFILE=tzwr_5.5_spin fi else echo "Cannot set default PROFILE for platform=${platform}" diff --git a/tizen/build/gbs.conf.in b/tizen/build/gbs.conf.in index ca83cf1..b13f2ee 100755 --- a/tizen/build/gbs.conf.in +++ b/tizen/build/gbs.conf.in @@ -87,7 +87,6 @@ url = http://165.213.149.200/download/snapshots/tizen/base-wearable/latest/repos # Tizen v5.5 spin Wearable (armv7l) # [profile.tzwr_5.5_spin] -obs = obs.spin repos = repo.wearable_product_5.5_base, repo.wearable_product_5.5 buildroot = ~/GBS-ROOT-M69-TZWR_5.5_SPIN-TIZEN_LATEST-RELEASE user = blinkbot -- 2.7.4 From 1e706bba79c504097569b5688164353c0b60872c Mon Sep 17 00:00:00 2001 From: DongHyun Song Date: Tue, 7 Jan 2020 17:18:08 +0900 Subject: [PATCH 14/16] Change hide() time for 'visibilitychange' callback In window.hide(), 'visibilitychange' or 'webkitvisibilitychange' event is dispatched from Document::DidChangeVisibilityState(), which is triggered by RenderWidgetHostViewEfl::SetPageVisibility() In window.setEnable(), it try to request suspending to renderer thread, then it try to stop chromium resources even JavaScript context. Thus if hide() is called after setEnable(), it can defer application's 'visibilitchange' callback unexpectedly. Change-Id: Ibe89b79f8a01ca170db40af8a5792fe64e9bf4ba Signed-off-by: DongHyun Song --- wrt_app/src/web_application.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) mode change 100644 => 100755 wrt_app/src/web_application.js diff --git a/wrt_app/src/web_application.js b/wrt_app/src/web_application.js old mode 100644 new mode 100755 index 38efdab..2c478d0 --- a/wrt_app/src/web_application.js +++ b/wrt_app/src/web_application.js @@ -312,6 +312,7 @@ class WebApplication { console.log('WebApplication : suspend - Invalid event emitter'); } this.suspended = true; + this.windowList[this.windowList.length - 1].hide(); if (wrt.tv) { wrt.tv.flushCookie(); this.windowList.forEach((window) => window.webContents.session.flushStorageData()); @@ -327,13 +328,10 @@ class WebApplication { this.windowList.forEach((window) => window.setEnabled(false)); } } - this.windowList[this.windowList.length - 1].hide(); } resume() { console.log('WebApplication : resume'); - this.suspended = false; - if (this.addonEmitter) { console.log('WebApplication : resume - Found event emitter'); this.addonEmitter.emit('lcResume', this.mainWindow.id); @@ -343,7 +341,7 @@ class WebApplication { if (!this.firstRendered) { console.log('WebApplication : resume firstRendered is false'); - return; + return; } if (!this.backgroundRunnable()) { this.windowList.forEach((window) => window.setEnabled(true)); -- 2.7.4 From 1599f3b7db85f19ebb5feffd881a5185f26fc073 Mon Sep 17 00:00:00 2001 From: YONGMAN SON Date: Fri, 10 Jan 2020 11:17:18 +0900 Subject: [PATCH 15/16] [VD] skip wrt-loader launch from LFD product zygote process crashed due to a capability issue related to the zone container in the LFD prodect. LFD uses only one webapp, so there is no need for a wrt-loader. Change-Id: I64f977a0e47d6963726ca8c44d5b360b2547ac34 Signed-off-by: YONGMAN SON --- packaging/wrtjs.spec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packaging/wrtjs.spec b/packaging/wrtjs.spec index 5e76021..7754296 100755 --- a/packaging/wrtjs.spec +++ b/packaging/wrtjs.spec @@ -35,6 +35,7 @@ install -d %{buildroot}%{_resourcedir} install -m 0755 %{_outdir}/wrt-loader %{buildroot}%{_bindir} install -m 0644 packaging/wrt.loader %{buildroot}%{_datadir}/aul/ %else +%if "%{_vd_cfg_product_type}" != "LFD" ln -s %{_bindir}/wrt %{buildroot}%{_bindir}/wrt-loader %if "%{_vd_cfg_platform_type}" == "FULL_SMART" install -m 0644 packaging/wrt_tv.loader %{buildroot}%{_datadir}/aul/wrt.loader @@ -43,6 +44,7 @@ install -d %{buildroot}%{_resourcedir} install -m 0644 packaging/wrt_tv_lite.loader %{buildroot}%{_datadir}/aul/wrt.loader %endif %endif +%endif cp -r wrt_app/* %{buildroot}%{_resourcedir}/ %post -- 2.7.4 From 9ec00eb2d51387e34ee67b2ebd9442ec4f6c4ddf Mon Sep 17 00:00:00 2001 From: YONGMAN SON Date: Mon, 13 Jan 2020 15:47:18 +0900 Subject: [PATCH 16/16] [VD] Build fix - skip wrt-loader launch for LFD product Eventually, This patch won't make the wrt.loader service file for LFD product. In LFD, it has only one webapp which is launched early time after boot. Thus, wrt-loader is not effective to LFD product. In addition, with WRTjs, zygote process is changed to /usr/bin/wrt from efl_webprocess. 'wrt' has more capability than efl_webprocess and some of its capability (i.e. cap_setpcap), they cannot be working with zone container of security framework. Thus, zygote process is going to die with wrt-loader launching. If webapp is launched directly without wrt-loader, the webapp process is started with app privilege, which means that process has changed smack label, process group as app permission its manifest describes. With these reason, this patch will not make wrt.loader file for LFD product. Change-Id: I6a1db9b65a4e20ac70d072f93f581d50085ee814 Signed-off-by: YONGMAN SON Signed-off-by: DongHyun Song --- packaging/wrtjs.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packaging/wrtjs.spec b/packaging/wrtjs.spec index 7754296..deccb07 100755 --- a/packaging/wrtjs.spec +++ b/packaging/wrtjs.spec @@ -35,7 +35,6 @@ install -d %{buildroot}%{_resourcedir} install -m 0755 %{_outdir}/wrt-loader %{buildroot}%{_bindir} install -m 0644 packaging/wrt.loader %{buildroot}%{_datadir}/aul/ %else -%if "%{_vd_cfg_product_type}" != "LFD" ln -s %{_bindir}/wrt %{buildroot}%{_bindir}/wrt-loader %if "%{_vd_cfg_platform_type}" == "FULL_SMART" install -m 0644 packaging/wrt_tv.loader %{buildroot}%{_datadir}/aul/wrt.loader @@ -44,7 +43,6 @@ install -d %{buildroot}%{_resourcedir} install -m 0644 packaging/wrt_tv_lite.loader %{buildroot}%{_datadir}/aul/wrt.loader %endif %endif -%endif cp -r wrt_app/* %{buildroot}%{_resourcedir}/ %post @@ -62,5 +60,7 @@ rm -fr %{buildroot} %else %{_bindir}/wrt-loader %endif +%if "%{_vd_cfg_product_type}" != "LFD" %{_datadir}/aul/wrt.loader +%endif %{_resourcedir}/* -- 2.7.4