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');
60 webContents.on('before-input-event', (event, input) => {
61 if (this.isLaunched && this.webApplication)
62 this.handleKeyEvents(input.key);
65 app.once('ready', (event) => {
67 let addonAvailable = addonManager.build();
68 console.log("addonBuild : " + addonAvailable);
70 const XWalkExtension = require('../common/wrt_xwalk_extension');
71 XWalkExtension.initialize();
72 XWalkExtension.preventCleanup();
74 wrt.tv?.importCertificate('');
76 wrt.on('app-control', (event, appControl) => {
77 console.log('app-control');
78 let loadInfo = appControl.getLoadInfo();
79 let src = loadInfo.getSrc();
81 if (wrt.isElectronApp()) {
82 console.log('Electron App launch');
83 const Module = require('module');
84 Module.globalPaths.push(wrt.getAppPath());
85 let filePath = src[7] === '/' ? src.substr(8) : src.substr(7); // strip "file://"
86 let pkgJson = require(filePath);
87 let pos = filePath.lastIndexOf('/');
89 let mainJsPath = (pos !== -1 ? filePath.substr(0, pos + 1) : '') +
90 (pkgJson.main || 'index.js');
91 console.log('loading path:', mainJsPath);
92 Module._load(mainJsPath, Module, true);
95 console.log('Tizen Web App launch');
96 let launchMode = appControl.getData('http://samsung.com/appcontrol/data/launch_mode');
97 if (!this.webApplication) {
98 console.log('Creating WebApplication');
99 let options: RuntimeOption = {
100 isAddonAvailable: addonManager.isAddonAvailable(),
101 launchMode: launchMode
103 this.webApplication = new WebApplication(options);
105 this.inspectorEnabledByVconf = wrt.tv.needUseInspector();
106 if (this.inspectorEnabledByVconf && launchMode != 'backgroundExecution') {
107 this.webApplication.inspectorSrc = src;
110 let useDiskCache = appControl.getData('USE_DISKCACHE');
111 let halfWindowOption = appControl.getData('http://samsung.com/appcontrol/data/half_window_support');
112 wrt.tv.setDiskCache(useDiskCache);
113 wrt.tv.handleAppControlData(launchMode, halfWindowOption);
115 this.webApplication.mainWindow.loadURL(src);
116 this.webApplication.prelaunch(src);
118 console.log('Handling app-control event');
119 if (this.webApplication.preloadStatus == 'readyToShow') {
120 this.webApplication.show();
122 if (launchMode != 'backgroundAtStartup')
123 this.webApplication.preloadStatus = 'none';
126 let skipReload = appControl.getData('SkipReload');
127 if (skipReload == 'Yes') {
128 console.log('skipping reload');
129 // TODO : Need to care this situation and decide to pass the addon event emitter to resume()
130 this.webApplication.resume();
134 let reload = loadInfo.getReload() || this.webApplication.isAlwaysReload;
136 let originalUrl = this.webApplication.mainWindow.webContents.getURL();
138 console.log(`appcontrol src = ${src}, original url = ${originalUrl}`);
139 if (src && originalUrl) {
140 let appcontrolUrl = (new URL(src)).href;
141 let oldUrl = (new URL(originalUrl)).href;
142 console.log(`appcontrolUrl = ${appcontrolUrl}, oldUrl = ${oldUrl}`);
144 // Below case it must be distinguishable for known cases
145 // from 'file:///index.htmlx' to 'file:///index.html'
146 if (appcontrolUrl !== oldUrl.substr(0, appcontrolUrl.length))
151 } else if (src !== originalUrl) {
155 // handle http://tizen.org/appcontrol/operation/main operation specially.
156 // only menu-screen app can send launch request with main operation.
157 // in this case, web app should have to resume web app not reset.
158 if (reload && appControl.getOperation() == 'http://tizen.org/appcontrol/operation/main')
161 this.webApplication.handleAppControlReload(src);
163 this.webApplication.sendAppControlEvent();
166 this.setCookiePath();
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 setCookiePath() {
236 this.setCookiePath = () => {}; // call once
237 console.log('setCookiePath');
239 // FIX ME : It must be supplemented to set a specific path
243 private handleKeyEvents(key: string) {
245 console.log(key + ' is pressed');
254 console.log('No handler for the key ' + key);
258 this.webApplication?.keyEvent(key);