2 * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 const wrt = require('../browser/wrt'); // Load first for log
20 const AddonManager = require('./addon_manager');
21 const {app, ipcMain} = require('electron');
22 const IPC_MESSAGE = require('./ipc_message');
23 const WAS_EVENT = require('./was_event');
24 const WebApplication = require('./web_application');
27 constructor(options) {
28 this.webApplication = null;
29 this.handleIpcMessages();
30 this.addonManager = null;
31 this.isLaunched = false;
32 this.inspectorEnabledByVconf = false;
33 this.webContents = null;
36 app.on('before-quit', function(event) {
37 console.log('before-quit');
38 if (!wrt.isElectronApp()) {
39 _this.webApplication.quit(_this.addonManager.evt_emitter_);
40 _this.webApplication.finalize();
41 _this.webApplication = null;
44 app.on('will-quit', function(event) {
45 console.log('will-quit');
46 _this.addonManager.deactivateAll(app);
48 app.on('quit', function(event) {
52 app.on('browser-window-blur', function() {
53 console.log('browser-window-blur');
55 app.on('browser-window-focus', function() {
56 console.log('browser-window-focus');
58 app.on('browser-window-created', function() {
59 console.log('browser-window-created');
60 if (!_this.isLaunched) {
61 _this.addonManager.activateAll(app);
62 _this.isLaunched = true;
65 app.on('gpu-process-crashed', function() {
66 console.error('gpu-process-crashed');
68 app.on('window-all-closed', function(event) {
69 console.log('window-all-closed');
72 app.on('will-finish-launching', function(event) {
73 console.log('will-finish-launching');
75 app.on('web-contents-created', function(event, webContents) {
76 console.log('web-contents-created');
77 _this.webContents = webContents;
78 _this.webContents.on('before-input-event', function(event, input) {
79 if (_this.isLaunched && _this.webApplication) {
80 _this.handleKeyEvents(input.key);
84 app.once('ready', function(event) {
86 _this.addonManager = new AddonManager();
87 if (!options.noAddons) {
88 _this.addonManager.build();
90 wrt.importCertificate('');
92 wrt.on('app-control', function(event, appControl) {
93 console.log('app-control');
94 let loadInfo = appControl.getLoadInfo();
95 let src = loadInfo.getSrc();
97 if (wrt.isElectronApp()) {
98 console.log('Electron App launch');
99 const Module = require('module');
100 Module.globalPaths.push(wrt.getAppPath());
101 let filePath = src[7] === '/' ? src.substr(8) : src.substr(7); // strip "file://"
102 let pkgJson = require(filePath);
103 let pos = filePath.lastIndexOf('/');
105 let mainJsPath = (pos !== -1 ? filePath.substr(0, pos + 1) : '') +
106 (pkgJson.main || 'index.js');
107 console.log('loading path:', mainJsPath);
108 Module._load(mainJsPath, Module, true);
111 console.log('Tizen Web App launch');
112 let launchMode = appControl.getData('http://samsung.com/appcontrol/data/launch_mode');
113 if (!_this.webApplication) {
114 console.log('Creating WebApplication');
115 options.isAddonAvailable = !options.noAddons &&
116 _this.addonManager.isAddonAvailable();
117 options.launchMode = launchMode;
118 _this.webApplication = new WebApplication(options);
119 _this.inspectorEnabledByVconf = wrt.needUseInspector();
120 if (_this.inspectorEnabledByVconf && launchMode != 'backgroundExecution') {
121 _this.webApplication.inspectorSrc = src;
124 _this.webApplication.mainWindow.loadURL(src);
125 _this.webApplication.prelaunch(_this.addonManager.evt_emitter_, src);
127 console.log('Handling app-control event');
128 if (_this.webApplication.preloadStatus == 'readyToShow') {
129 _this.webApplication.show();
131 if (launchMode != 'backgroundAtStartup') {
132 _this.webApplication.preloadStatus = 'none';
136 let skipReload = appControl.getData('SkipReload');
137 if (skipReload == 'Yes') {
138 console.log('skipping reload');
139 // TODO : Need to care this situation and decide to pass the addon event emitter to resume()
140 _this.webApplication.resume();
144 let reload = loadInfo.getReload() || _this.webApplication.isAlwaysReload;
146 if (src != _this.webApplication.mainWindow.getURL())
149 // handle http://tizen.org/appcontrol/operation/main operation specially.
150 // only menu-screen app can send launch request with main operation.
151 // in this case, web app should have to resume web app not reset.
152 if (reload && appControl.getOperation() == 'http://tizen.org/appcontrol/operation/main')
155 _this.webApplication.closeWindows();
156 _this.webApplication.mainWindow.loadURL(src);
158 _this.webApplication.sendAppControlEvent();
162 _this.configureRuntime(appControl);
164 wrt.on('suspend', function() {
165 console.log('suspend');
166 if (_this.webApplication)
167 _this.webApplication.suspend(_this.addonManager.evt_emitter_);
169 wrt.on('resume', function() {
170 console.log('resume');
171 if (_this.webApplication)
172 _this.webApplication.resume(_this.addonManager.evt_emitter_);
174 wrt.on('low-memory', function() {
175 console.log('low-memory');
176 if (_this.webApplication)
177 _this.webApplication.lowMemory();
179 wrt.on('message', function(event, type, params) {
180 console.log('message type(' + type + ') params : ' + params);
181 if (type === 'startService') {
182 const vm = require('vm');
183 const fs = require('fs');
190 let code = fs.readFileSync(params[1]);
191 vm.runInNewContext(code, sandbox, options);
192 event.preventDefault();
195 wrt.on('wgt-installed', function(event, path) {
196 console.log('wgt-installed at ' + path);
197 if (AddonManager.isAddon(path)) {
198 console.log('Addon is updated on DB');
201 wrt.on('addon-uninstalled', function(event, id) {
202 console.log('addon-unistalled named ' + id);
204 /* FIXME: will uncheck after chromium-efl released */
205 if (wrt.getPlatformType() !== "product_tv") {
206 wrt.getInstalledPkg();
209 handleIpcMessages() {
211 ipcMain.on(IPC_MESSAGE.ADDONS.INSTALLED, (sender, name) => {
212 console.log('handleIpcMessages: INSTALLED ' + name);
213 _this.addonManager.build();
214 return _this.addonManager.activate(app, name);
216 ipcMain.on(IPC_MESSAGE.ADDONS.UNINSTALLED, (sender, name, pkg) => {
217 console.log('handleIpcMessages: UNINSTALLED ' + name);
218 _this.addonManager.deactivate(app, name);
219 /* FIXME: will uncheck after chromium-efl released */
220 if (wrt.getPlatformType() !== "product_tv") {
221 wrt.reqUninstallPkg(pkg);
225 ipcMain.on(IPC_MESSAGE.ADDONS.ACTIVATE, (sender, name) => {
226 console.log('handleIpcMessages: ACTIVATE ' + name);
227 return _this.addonManager.activate(app, name);
229 ipcMain.on(IPC_MESSAGE.ADDONS.DEACTIVATE, (sender, name) => {
230 console.log('handleIpcMessages: DEACTIVATE ' + name);
231 return _this.addonManager.deactivate(app, name);
234 checkInspectorCondition(appControl) {
235 let bundleDebug = (appControl.getData('__AUL_DEBUG__') === "1");
236 return (bundleDebug || this.inspectorEnabledByVconf);
238 launchInspector(appControl) {
239 var portnum = wrt.getDebuggingPort();
240 var data = { "port" : [ portnum.toString() ] };
241 if (this.webApplication)
242 this.webApplication.debugPort = portnum;
243 appControl.reply(data);
245 configureRuntime(appControl) {
246 this.configureRuntime = (param) => {}; // call once
248 // FIX ME : It must be supplemented to set a specific path
251 // AUL public key/Vconf - To support inspector
252 if (this.checkInspectorCondition(appControl)) {
253 this.launchInspector(appControl);
256 handleKeyEvents(key) {
260 console.log(key + ' is pressed');
269 console.log('No handler for the key ' + key);
274 _this.webApplication.keyEvent(_this.addonManager.evt_emitter_, key);
278 module.exports = Runtime;