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: any) => {
31 console.log('before-quit');
32 this.webApplication?.beforeQuit();
35 app.on('will-quit', (event: any) => {
36 console.log('will-quit');
37 addonManager.deactivateAll();
40 app.on('quit', (event: any) => {
42 if (this.webApplication) {
43 this.webApplication.quit();
44 this.webApplication = undefined;
48 app.on('browser-window-created', () => {
49 console.log('browser-window-created');
50 if (!this.isLaunched) {
51 addonManager.activateAll();
52 this.isLaunched = true;
56 app.on('window-all-closed', () => {
57 console.log('window-all-closed');
61 app.on('web-contents-created', (event: any, webContents: any) => {
62 console.log('web-contents-created');
63 webContents.on('before-input-event', (event: any, input: any) => {
64 if (this.isLaunched && this.webApplication)
65 this.handleKeyEvents(input.key);
69 app.once('ready', (event: any) => {
71 let addonAvailable = addonManager.build();
72 console.log("addonBuild : " + addonAvailable);
74 const XWalkExtension = require('../common/wrt_xwalk_extension');
75 XWalkExtension.initialize();
76 XWalkExtension.preventCleanup();
78 wrt.tv?.importCertificate('');
81 wrt.on('app-control', (event: any, appControl: any) => {
82 console.log('app-control');
83 let loadInfo = appControl.getLoadInfo();
84 let src = loadInfo.getSrc();
86 if (wrt.isElectronApp()) {
87 console.log('Electron App launch');
88 const Module = require('module');
89 Module.globalPaths.push(wrt.getAppPath());
90 let filePath = src[7] === '/' ? src.substr(8) : src.substr(7); // strip "file://"
91 let pkgJson = require(filePath);
92 let pos = filePath.lastIndexOf('/');
94 let mainJsPath = (pos !== -1 ? filePath.substr(0, pos + 1) : '') +
95 (pkgJson.main || 'index.js');
96 console.log('loading path:', mainJsPath);
97 Module._load(mainJsPath, Module, true);
100 console.log('Tizen Web App launch');
101 let launchMode = appControl.getData('http://samsung.com/appcontrol/data/launch_mode');
102 if (!this.webApplication) {
103 console.log('Creating WebApplication');
104 let options: RuntimeOption = {
105 isAddonAvailable: addonManager.isAddonAvailable(),
106 launchMode: launchMode
108 this.webApplication = new WebApplication(options);
110 this.inspectorEnabledByVconf = wrt.tv.needUseInspector();
111 if (this.inspectorEnabledByVconf && launchMode != 'backgroundExecution') {
112 this.webApplication.inspectorSrc = src;
115 let useDiskCache = appControl.getData('USE_DISKCACHE');
116 let halfWindowOption = appControl.getData('http://samsung.com/appcontrol/data/half_window_support');
117 wrt.tv.setDiskCache(useDiskCache);
118 wrt.tv.handleAppControlData(launchMode, halfWindowOption);
120 this.webApplication.mainWindow.loadURL(src);
121 this.webApplication.prelaunch(src);
123 this.webApplication.mainWindow.emit('ready-to-show');
126 console.log('Handling app-control event');
127 if (this.webApplication.preloadStatus == 'readyToShow') {
128 this.webApplication.show();
130 if (launchMode != 'backgroundAtStartup')
131 this.webApplication.preloadStatus = 'none';
134 let skipReload = appControl.getData('SkipReload');
135 if (skipReload == 'Yes') {
136 console.log('skipping reload');
137 // TODO : Need to care this situation and decide to pass the addon event emitter to resume()
138 this.webApplication.resume();
142 let reload = loadInfo.getReload() || this.webApplication.isAlwaysReload;
144 let originalUrl = this.webApplication.mainWindow.webContents.getURL();
146 console.log(`appcontrol src = ${src}, original url = ${originalUrl}`);
147 if (src && originalUrl) {
148 let appcontrolUrl = (new URL(src)).href;
149 let oldUrl = (new URL(originalUrl)).href;
150 console.log(`appcontrolUrl = ${appcontrolUrl}, oldUrl = ${oldUrl}`);
152 // Below case it must be distinguishable for known cases
153 // from 'file:///index.htmlx' to 'file:///index.html'
154 if (appcontrolUrl !== oldUrl.substr(0, appcontrolUrl.length))
159 } else if (src !== originalUrl) {
163 // handle http://tizen.org/appcontrol/operation/main operation specially.
164 // only menu-screen app can send launch request with main operation.
165 // in this case, web app should have to resume web app not reset.
166 if (reload && appControl.getOperation() == 'http://tizen.org/appcontrol/operation/main')
169 this.webApplication.handleAppControlReload(src);
171 this.webApplication.sendAppControlEvent();
174 this.launchInspector(appControl);
177 wrt.on('suspend', () => {
178 console.log('suspend');
179 this.webApplication?.suspend();
182 wrt.on('resume', () => {
183 console.log('resume');
184 this.webApplication?.resume();
187 wrt.on('low-memory', () => {
188 console.log('low-memory');
189 this.webApplication?.lowMemory();
192 wrt.on('message', (event: any, type: string, params: string[]) => {
193 console.log('message type(' + type + ') params : ' + params);
194 const app_id = params[0];
195 if (type === 'startService') {
196 require('../common/service_manager').startService(app_id, params[1]);
197 event.preventDefault();
198 } else if (type === 'stopService') {
199 require('../common/service_manager').stopService(app_id);
200 event.preventDefault();
204 wrt.on('ambient-tick', () => {
205 this.webApplication?.ambientTick();
208 wrt.on('ambient-changed', (event: any, ambient_mode: boolean) => {
209 console.log('ambient-changed , ambient_mode:' + ambient_mode);
210 this.webApplication?.ambientChanged(ambient_mode);
213 wrt.on('addon-installed', (event: any, path: string) => {
214 console.log('addon-installed at ' + path);
215 addonManager.checkAddon(path);
218 wrt.on('addon-uninstalled', (event: any, id: string) => {
219 console.log('addon-unistalled named ' + id);
222 wrt.on('wgt-checking-done', (event: any) => {
223 console.log('wgt-checking-done');
224 addonManager.updateDB();
227 /* FIXME: will uncheck after chromium-efl released */
228 if (wrt.getPlatformType() !== "product_tv")
229 wrt.getInstalledPkg();
232 private launchInspector(appControl: NativeWRTjs.AppControl) {
233 this.launchInspector = (param) => {}; // call once
234 console.log('launchInspector');
236 // AUL public key/Vconf - To support inspector
237 if (this.checkInspectorCondition(appControl)) {
238 let debugPort = wrt.startInspectorServer();
239 let data = { "port" : [ debugPort.toString() ] };
240 if (this.webApplication)
241 this.webApplication.debugPort = debugPort;
242 appControl.reply(data);
246 private checkInspectorCondition(appControl: NativeWRTjs.AppControl) {
247 let bundleDebug = (appControl.getData('__AUL_DEBUG__') === "1");
248 return (bundleDebug || this.inspectorEnabledByVconf);
251 private handleKeyEvents(key: string) {
253 console.log(key + ' is pressed');
262 console.log('No handler for the key ' + key);
266 this.webApplication?.keyEvent(key);