Initial code to handle lifecycles and events in addons 77/208877/3
authorhyunduk.kim <hyunduk.kim@samsung.com>
Mon, 1 Jul 2019 05:18:21 +0000 (22:18 -0700)
committerhyunduk.kim <hyunduk.kim@samsung.com>
Wed, 3 Jul 2019 01:25:41 +0000 (18:25 -0700)
This provides the invocation of predefined methods for lifecycles and events
 - prelanuch : invoking prelaunch() in an addon when app-control is emitted
 - suspend : invoking suspend() in an addon when suspend is emitted
 - resume : invoking resume() in an addon when resume is emitted
 - quit : invoking quit() in an addon when before-quit is emitted
 - arrowup : invoking arrowup() in an addon when arrowup is pressed
 - arrowdown : invoking arrowdown() in an addon when arrowdown is pressed

It's only an initial code and focused on the logic to call each method.

Change-Id: I04c5976dd88fabb2ccdfcf96e0d444ed296acbe4
Signed-off-by: hyunduk.kim <hyunduk.kim@samsung.com>
wrt_app/src/addon_manager.js
wrt_app/src/runtime.js
wrt_app/src/web_application.js

index 7c7c449de56d66fe4a46f919d50ca174d013c3db..d3efecae6966b614318d96a415692edb8e7de80f 100644 (file)
@@ -33,6 +33,12 @@ class AddonManager {
         this.addons_list_ = null;
         this.addons_ = null;
         this.addons_API_ = null;
+        this.prelaunch_path = null;
+        this.resume_path = null;
+        this.suspend_path = null;
+        this.quit_path = null;
+        this.arrowup_path = null;
+        this.arrowdown_path = null;
     }
 
     printAPIs() {
@@ -164,6 +170,44 @@ class AddonManager {
         return true;
     }
 
+    registerLifecycles(lifecycles, path) {
+        if (!lifecycles) {
+            console.log('lifecycle is not declared');
+            return;
+        }
+        if (lifecycles.prelaunch) {
+            this.prelaunch_path = path;
+            console.log('prelaunch operation path :' + this.prelaunch_path);
+        }
+        if (lifecycles.resume) {
+            this.resume_path = path;
+            console.log('resume override path :' + this.resume_path);
+        }
+        if (lifecycles.suspend) {
+            this.suspend_path = path;
+            console.log('suspend override path :' + this.suspend_path);
+        }
+        if (lifecycles.quit) {
+            this.quit_path = path;
+            console.log('quit operation path :' + this.quit_path);
+        }
+    }
+
+    registerEvents(events, path) {
+        if (!events) {
+            console.log('event is not declared');
+            return;
+        }
+        if (events.arrowup) {
+            this.arrowup_path = path;
+            console.log('arrowup operation path :' + this.arrowup_path);
+        }
+        if (events.arrowdown) {
+            this.arrowdown_path = path;
+            console.log('arrowdown operation path :' + this.arrowdown_path);
+        }
+    }
+
     build() {
         // 0. load addons_list_ from JSON DB
         this.loadJsonDB();
@@ -223,6 +267,11 @@ class AddonManager {
                             addons[type][manifest_obj.name] = addon.path;
                         }
                     }
+
+                    let addon_path = path.join(addon.path, manifest_obj.name) + '.js';
+                    this.registerLifecycles(manifest_obj.lifecycle, addon_path);
+                    this.registerEvents(manifest_obj.event, addon_path);
+
                     console.log('addons[' + type + '][' + manifest_obj.name + '] = ' + addons[type][manifest_obj.name] + ' registered');
                 } catch (e) {
                     console.error('AddonManager.build error - ' + e);
index 02af0d83a95a91e82d417b142ac006748a9a38b1..36e0eb1ef0aa62765f687db102efe06686ea317a 100644 (file)
@@ -31,10 +31,23 @@ class Runtime {
         this.isLaunched = false;
         this.debug_mode = false;
         this.need_inspector = false;
+        this.webContents = null;
+        this.allowQuit = false;
 
         var _this = this;
         app.on('before-quit', function(event) {
             console.log('before-quit');
+            if (!wrt.isElectronApp()) {
+                if (_this.addonManager.quit_path && !_this.allowQuit) {
+                    event.preventDefault();
+                    let timeout = _this.webApplication.quit(_this.addonManager.quit_path);
+                    _this.allowQuit = true;
+                    if (timeout >= 0)
+                        setTimeout(function() {
+                            app.quit();
+                        }, timeout, null);
+                }
+            }
         });
         app.on('will-quit', function(event) {
             console.log('will-quit');
@@ -68,6 +81,15 @@ class Runtime {
         app.on('will-finish-launching', function(event) {
             console.log('will-finish-launching');
         });
+        app.on('web-contents-created', function(event, webContents) {
+            console.log('web-contents-created');
+            _this.webContents = webContents;
+            _this.webContents.on('before-input-event', function(event, input) {
+                if (_this.isLaunched && _this.webApplication) {
+                    _this.handleKeyEvents(input.key);
+                }
+            });
+        });
         app.once('ready', function(event) {
             console.log('ready');
             _this.addonManager = new AddonManager();
@@ -103,6 +125,7 @@ class Runtime {
                     options.launchMode = appControl.getData('http://samsung.com/appcontrol/data/launch_mode');
                     _this.webApplication = new WebApplication(options);
                     _this.webApplication.mainWindow.loadURL(src);
+                    _this.webApplication.prelaunch(_this.addonManager.prelaunch_path, src);
                 } else {
                     console.log('Handling app-control event');
                     if (_this.webApplication.preloadState == 'readyToShow') {
@@ -150,11 +173,11 @@ class Runtime {
         });
         wrt.on('suspend', function() {
             console.log('suspend');
-            _this.webApplication.suspend();
+            _this.webApplication.suspend(_this.addonManager.suspend_path);
         });
         wrt.on('resume', function() {
             console.log('resume');
-            _this.webApplication.resume();
+            _this.webApplication.resume(_this.addonManager.resume_path);
         });
         wrt.on('terminate', function() {
             console.log('terminate');
@@ -199,5 +222,28 @@ class Runtime {
         }
         appControl.reply(data);
     }
+    handleKeyEvents(key) {
+        let path = null;
+        let _this = this;
+
+        console.log(key + ' is pressed');
+        switch(key) {
+            case "ArrowUp":
+            case "Up":
+                path = _this.addonManager.arrowup_path;
+                break;
+            case "ArrowDown":
+            case "Down":
+                path = _this.addonManager.arrowdown_path;
+                break;
+            default:
+                console.log('No handler for the key ' + key);
+                break;
+        }
+        console.log('Path for ' + key + ' : ' + path);
+        if (path) {
+            _this.webApplication.keyEvent(key, path);
+        }
+    }
 }
 module.exports = Runtime;
index 77e9f6312a72fc3e65d7c06a1fd951cd76975ae7..068864349354cd637d3ec0e2cace573ccb7783d9 100755 (executable)
@@ -243,8 +243,18 @@ class WebApplication {
             }
         });
     }
-    suspend() {
+    suspend(path) {
         console.log('WebApplication : suspend');
+        if (path != null) {
+            let addon = require(path);
+            console.log('addon for suspend is ' + path);
+            if (addon.suspend) {
+                console.log('addon for suspend is found');
+                addon.suspend(this.mainWindow.id, path);
+            } else {
+                console.log('addon for suspend is NOT found');
+            }
+        }
         this.suspended = true;
         if (this.isTerminating) {
             console.log('App has been terminated; return');
@@ -262,11 +272,21 @@ class WebApplication {
         }
         this.windowList[this.windowList.length - 1].hide();
     }
-    resume() {
+    resume(path) {
         console.log('WebApplication : resume');
         this.suspended = false;
         if (!this.firstRendered) {
             console.log('WebApplication : resume firstRendered is false');
+            if (path != null) {
+                let addon = require(path);
+                console.log('addon for resume is ' + path);
+                if (addon.resume) {
+                    console.log('addon for resume is found');
+                    addon.resume(this.mainWindow.id, path);
+                } else {
+                    console.log('addon for resume is NOT found');
+                }
+            }
             return;
         }
         WRTWindow.getAllWindows().forEach((window) => {
@@ -278,6 +298,21 @@ class WebApplication {
     terminate() {
         this.isTerminating = true;
     }
+    quit(path) {
+       console.log('WebApplication : quit');
+       let timeout = -1;
+       if (path != null) {
+           let addon = require(path);
+           console.log('addon for quit is ' + path);
+           if (addon.quit) {
+               console.log('addon for quit is found');
+               timeout = addon.quit(this.mainWindow.id, path);
+           } else {
+               console.log('addon for quit is NOT found');
+           }
+       }
+       return timeout;
+    }
     sendAppControlEvent() {
         const kAppControlEventScript =
             '(function(){' +
@@ -309,5 +344,51 @@ class WebApplication {
                 window.destroy();
         });
     }
+    keyEvent(key, path) {
+        console.log('WebApplication : keyEvent');
+        if (!path) {
+            console.log('no path for event hook exists');
+            return;
+        }
+        let addon = require(path);
+        console.log('event is hooked for ' + path);
+        switch(key) {
+            case "ArrowUp":
+            case "Up":
+                if (addon.arrowup) {
+                    console.log('arrowup is found');
+                    addon.arrowup(this.mainWindow.id);
+                } else {
+                    console.log('arrowup is NOT found');
+                }
+                break;
+            case "ArrowDown":
+            case "Down":
+                if (addon.arrowdown) {
+                    console.log('arrowdown is found');
+                    addon.arrowdown(this.mainWindow.id);
+                } else {
+                    console.log('arrowdown is NOT found');
+                }
+                break;
+            default:
+                console.log('No handler for ' + key);
+                break;
+        }
+    }
+    prelaunch(path, origURL) {
+        console.log('WebApplication : prelaunch');
+        if (path != null) {
+            let addon = require(path);
+            console.log('addon for additional runtime is ' + path);
+            console.log('prelaunch : org URL : ' + origURL);
+            if (addon.prelaunch) {
+                console.log('prelaunch is found');
+                addon.prelaunch(this.mainWindow.id, origURL);
+            } else {
+                console.log('prelaunch is NOT found');
+            }
+        }
+    }
 }
 module.exports = WebApplication;