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 import { wrt } from '../browser/wrt'; // Load first for log
20 import { addonManager } from './addon_manager';
21 import { app } from 'electron';
22 import { WebApplication } from './web_application';
25 webApplication?: WebApplication = undefined;
27 inspectorEnabledByVconf = false;
30 app.on('before-quit', (event) => {
31 console.log('before-quit');
32 this.webApplication?.quit();
34 app.on('will-quit', (event) => {
35 console.log('will-quit');
36 addonManager.deactivateAll();
38 app.on('quit', (event) => {
40 if (this.webApplication) {
41 this.webApplication.finalize();
42 this.webApplication = undefined;
45 app.on('browser-window-created', () => {
46 console.log('browser-window-created');
47 if (!this.isLaunched) {
48 addonManager.activateAll();
49 this.isLaunched = true;
52 app.on('window-all-closed', () => {
53 console.log('window-all-closed');
56 app.on('web-contents-created', (event, webContents) => {
57 console.log('web-contents-created');
58 webContents.on('before-input-event', (event, input) => {
59 if (this.isLaunched && this.webApplication)
60 this.handleKeyEvents(input.key);
63 app.once('ready', (event) => {
65 let addonAvailable = addonManager.build();
66 console.log("addonBuild : " + addonAvailable);
68 const XWalkExtension = require('../common/wrt_xwalk_extension');
69 XWalkExtension.initialize();
70 XWalkExtension.preventCleanup();
72 wrt.tv?.importCertificate('');
74 wrt.on('app-control', (event, appControl) => {
75 console.log('app-control');
76 let loadInfo = appControl.getLoadInfo();
77 let src = loadInfo.getSrc();
79 if (wrt.isElectronApp()) {
80 console.log('Electron App launch');
81 const Module = require('module');
82 Module.globalPaths.push(wrt.getAppPath());
83 let filePath = src[7] === '/' ? src.substr(8) : src.substr(7); // strip "file://"
84 let pkgJson = require(filePath);
85 let pos = filePath.lastIndexOf('/');
87 let mainJsPath = (pos !== -1 ? filePath.substr(0, pos + 1) : '') +
88 (pkgJson.main || 'index.js');
89 console.log('loading path:', mainJsPath);
90 Module._load(mainJsPath, Module, true);
93 console.log('Tizen Web App launch');
94 let launchMode = appControl.getData('http://samsung.com/appcontrol/data/launch_mode');
95 if (!this.webApplication) {
96 console.log('Creating WebApplication');
97 let options: RuntimeOption = {
98 isAddonAvailable: addonManager.isAddonAvailable(),
99 launchMode: launchMode
101 this.webApplication = new WebApplication(options);
103 this.inspectorEnabledByVconf = wrt.tv.needUseInspector();
104 if (this.inspectorEnabledByVconf && launchMode != 'backgroundExecution') {
105 this.webApplication.inspectorSrc = src;
108 let useDiskCache = appControl.getData('USE_DISKCACHE');
109 let halfWindowOption = appControl.getData('http://samsung.com/appcontrol/data/half_window_support');
110 wrt.tv.setDiskCache(useDiskCache);
111 wrt.tv.handleAppControlData(launchMode, halfWindowOption);
113 this.webApplication.mainWindow.loadURL(src);
114 this.webApplication.prelaunch(src);
116 this.webApplication.mainWindow.emit('ready-to-show');
119 console.log('Handling app-control event');
120 if (this.webApplication.preloadStatus == 'readyToShow') {
121 this.webApplication.show();
123 if (launchMode != 'backgroundAtStartup')
124 this.webApplication.preloadStatus = 'none';
127 let skipReload = appControl.getData('SkipReload');
128 if (skipReload == 'Yes') {
129 console.log('skipping reload');
130 // TODO : Need to care this situation and decide to pass the addon event emitter to resume()
131 this.webApplication.resume();
135 let reload = loadInfo.getReload() || this.webApplication.isAlwaysReload;
137 let originalUrl = this.webApplication.mainWindow.webContents.getURL();
139 console.log(`appcontrol src = ${src}, original url = ${originalUrl}`);
140 if (src && originalUrl) {
141 let appcontrolUrl = (new URL(src)).href;
142 let oldUrl = (new URL(originalUrl)).href;
143 console.log(`appcontrolUrl = ${appcontrolUrl}, oldUrl = ${oldUrl}`);
145 // Below case it must be distinguishable for known cases
146 // from 'file:///index.htmlx' to 'file:///index.html'
147 if (appcontrolUrl !== oldUrl.substr(0, appcontrolUrl.length))
152 } else if (src !== originalUrl) {
156 // handle http://tizen.org/appcontrol/operation/main operation specially.
157 // only menu-screen app can send launch request with main operation.
158 // in this case, web app should have to resume web app not reset.
159 if (reload && appControl.getOperation() == 'http://tizen.org/appcontrol/operation/main')
162 this.webApplication.handleAppControlReload(src);
164 this.webApplication.sendAppControlEvent();
167 this.launchInspector(appControl);
169 wrt.on('suspend', () => {
170 console.log('suspend');
171 this.webApplication?.suspend();
173 wrt.on('resume', () => {
174 console.log('resume');
175 this.webApplication?.resume();
177 wrt.on('low-memory', () => {
178 console.log('low-memory');
179 this.webApplication?.lowMemory();
181 wrt.on('message', (event, type, params) => {
182 console.log('message type(' + type + ') params : ' + params);
183 const app_id = params[0];
184 if (type === 'startService') {
185 require('../common/service_manager').startService(app_id, params[1]);
186 event.preventDefault();
187 } else if (type === 'stopService') {
188 require('../common/service_manager').stopService(app_id);
189 event.preventDefault();
192 wrt.on('ambient-tick', () => {
193 this.webApplication?.ambientTick();
195 wrt.on('ambient-changed', (event, ambient_mode) => {
196 console.log('ambient-changed , ambient_mode:' + ambient_mode);
197 this.webApplication?.ambientChanged(ambient_mode);
199 wrt.on('addon-installed', (event, path) => {
200 console.log('addon-installed at ' + path);
201 addonManager.checkAddon(path);
203 wrt.on('addon-uninstalled', (event, id) => {
204 console.log('addon-unistalled named ' + id);
206 wrt.on('wgt-checking-done', (event) => {
207 console.log('wgt-checking-done');
208 addonManager.updateDB();
211 /* FIXME: will uncheck after chromium-efl released */
212 if (wrt.getPlatformType() !== "product_tv")
213 wrt.getInstalledPkg();
216 private launchInspector(appControl: NativeWRTjs.AppControl) {
217 this.launchInspector = (param) => {}; // call once
218 console.log('launchInspector');
220 // AUL public key/Vconf - To support inspector
221 if (this.checkInspectorCondition(appControl)) {
222 let debugPort = wrt.startInspectorServer();
223 let data = { "port" : [ debugPort.toString() ] };
224 if (this.webApplication)
225 this.webApplication.debugPort = debugPort;
226 appControl.reply(data);
230 private checkInspectorCondition(appControl: NativeWRTjs.AppControl) {
231 let bundleDebug = (appControl.getData('__AUL_DEBUG__') === "1");
232 return (bundleDebug || this.inspectorEnabledByVconf);
235 private handleKeyEvents(key: string) {
237 console.log(key + ' is pressed');
246 console.log('No handler for the key ' + key);
250 this.webApplication?.keyEvent(key);