Add Launchpad Recovery Feature 02/237202/5
authorHwankyu Jhun <h.jhun@samsung.com>
Fri, 26 Jun 2020 02:43:30 +0000 (11:43 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Fri, 26 Jun 2020 06:04:44 +0000 (15:04 +0900)
If AMD gets the ECOMM error when sending the launch request, amd sends
SIGABRT signal to Launchpad. Launchpad will be started automatically
by socket activation.

Change-Id: I19b23bbd419aaeb36623d010b59b24a25c6c0f27
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
inc/amd_config.h
inc/amd_launchpad.h
inc/amd_signal.h
packaging/amd.conf
src/core/amd_config.c
src/core/amd_launch.c
src/core/amd_launchpad.c
src/core/amd_signal.c

index 7bb041a8b487c026990b2bffa43b157fdf7a89af..94641145a1d187ac98b38a7716a60141457ce2eb 100644 (file)
@@ -37,6 +37,7 @@ tizen_profile_t _config_get_tizen_profile(void);
 
 unsigned int _config_get_onboot_interval(void);
 unsigned int _config_get_fg_timeout(void);
+unsigned int _config_get_max_launch_failure(void);
 int _config_init(void);
 void _config_fini(void);
 
index 37c7bff5e566784510b556a6d73e6acf8e858ca6..1e4f5f59b5e83b9bd35b474e939a622a7d017b02 100644 (file)
@@ -22,4 +22,7 @@
 
 int _launchpad_set_launcher(int (*callback)(bundle *, uid_t, void *),
                void *user_data);
+
 int _launchpad_launch(bundle *kb, uid_t uid);
+
+int _launchpad_recover_launcher(uid_t uid);
index 366af47543937370d2e0fcd9469519594a842352..c297783c2114b98e2b7723aa037a218359e59e2f 100644 (file)
@@ -71,3 +71,5 @@ int _signal_get_proc_status_async(int pid,
                void *data);
 
 int _signal_add_ready_cb(signal_ready_cb callback, void *user_data);
+
+int _signal_send_app_dead(int pid);
index b146b21be12c860117f71597262cf93428188f8a..aa3f8cda4a93e3c524c895bc16be54079a19e7d3 100644 (file)
@@ -3,3 +3,4 @@ service_app_onboot_interval=3000
 fg_timeout=5000
 watchdog_interval=10000
 wathcdog_max_retry=3
+launchpad_max_launch_failure=5
index 83afe57ff360759c57c8fdfb5ae46d8680b9b87e..fcc8b2ca13617995e5772536b4e47dd74389f65d 100644 (file)
 #define CONFIG_SECTION_NAME "configuration"
 #define CONFIG_SERVICE_APP_ONBOOT_INTERVAL "service_app_onboot_interval"
 #define CONFIG_FG_TIMEOUT "fg_timeout"
+#define CONFIG_LAUNCHPAD_MAX_LAUNCH_FAILURE "launchpad_max_launch_failure"
 
 typedef struct config_s {
        tizen_profile_t profile;
        unsigned int onboot_interval;
        unsigned int fg_timeout;
+       unsigned int max_launch_failure;
 } config;
 
 static config __config;
@@ -83,6 +85,11 @@ unsigned int _config_get_fg_timeout(void)
        return __config.fg_timeout;
 }
 
+unsigned int _config_get_max_launch_failure(void)
+{
+       return __config.max_launch_failure;
+}
+
 static int __get_config_int(dictionary *d, const char *key)
 {
        char buf[512];
@@ -128,6 +135,13 @@ static int __load_config_file(const char *path)
                _I("[__CONFIG__] FG timeout: %u", __config.fg_timeout);
        }
 
+       r = __get_config_int(d, CONFIG_LAUNCHPAD_MAX_LAUNCH_FAILURE);
+       if (r > 0) {
+               __config.max_launch_failure = r;
+               _I("[__CONFIG__] Max launch failure : %u",
+                               __config.max_launch_failure);
+       }
+
        iniparser_freedict(d);
 
        return 0;
@@ -140,6 +154,7 @@ int _config_init(void)
        __config.profile = TIZEN_PROFILE_UNKNOWN;
        __config.onboot_interval = 3000;
        __config.fg_timeout = 5000;
+       __config.max_launch_failure = 5;
 
        if (__load_config_file(CONFIG_FILE_PATH) < 0)
                _W("Failed to load config file");
index d1aedc5f7433d1dcf7b8680ee183e3297bc6f507..1e8318030f7c3e02499c93d8e5164747191eb21b 100644 (file)
@@ -117,6 +117,7 @@ static int __focused_pid;
 static GList *__result_info_list;
 static int __poweroff_state;
 static launch_mode_e __launch_mode = LAUNCH_MODE_NORMAL;
+static unsigned int __failure_count;
 
 static void __set_reply_handler(int fd, int pid, request_h req, int cmd);
 static int __nofork_processing(int cmd, int pid, bundle *kb, request_h req);
@@ -3129,11 +3130,19 @@ static int __do_starting_app(struct launch_s *handle, request_h req,
 
        ret = _launchpad_launch(kb, target_uid);
        if (ret < 0) {
+               __failure_count++;
+               _E("[%u] Failed to send launch request. appid(%s), error(%d)",
+                               __failure_count, handle->appid, ret);
                _noti_send(NOTI_MSG_LAUNCH_DO_STARTING_APP_CANCEL,
                                ret, 0, NULL, NULL);
+               if (__failure_count > _config_get_max_launch_failure()) {
+                       _launchpad_recover_launcher(target_uid);
+                       __failure_count = 0;
+               }
                return ret;
        }
 
+       __failure_count = 0;
        handle->pid = ret;
        *pending = true;
        *bg_launch = handle->bg_launch;
index 58be1db7252fb117f654d0fc060d038d01617353..d63fd4ab6cbd1937125b975264b1d89b4179bc97 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2017 - 2020 Samsung Electronics Co., Ltd All Rights Reserved
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include <stdio.h>
 #include <unistd.h>
 #include <sys/types.h>
+#include <signal.h>
 
+#include <aul.h>
+
+#include "amd_app_status.h"
 #include "amd_config.h"
-#include "amd_util.h"
+#include "amd_launch.h"
 #include "amd_launchpad.h"
+#include "amd_login_monitor.h"
+#include "amd_signal.h"
+#include "amd_util.h"
 
 struct launchpad_info {
        int (*launcher)(bundle *, uid_t t, void *);
@@ -48,3 +55,45 @@ int _launchpad_launch(bundle *kb, uid_t uid)
 
        return __launchpad.launcher(kb, uid, __launchpad.data);
 }
+
+static void __running_appinfo_cb(app_status_h app_status, void *user_data)
+{
+       const char *appid;
+       uid_t uid;
+       pid_t pid;
+       int ret;
+
+       appid = _app_status_get_appid(app_status);
+       pid = _app_status_get_pid(app_status);
+       uid = _app_status_get_uid(app_status);
+
+       aul_send_app_terminate_request_signal(pid, NULL, NULL, NULL);
+       ret = _launch_send_sigkill(pid, uid);
+       _E("[__RECOVERY__] appid(%s), pid(%d), result(%d)", appid, pid, ret);
+
+       ret = _signal_send_app_dead(pid);
+       if (ret < 0) {
+               _W("Failed to send app dead signal. pid(%d)", pid);
+               _app_status_cleanup(app_status);
+       }
+}
+
+int _launchpad_recover_launcher(uid_t uid)
+{
+       pid_t pid;
+       int ret;
+
+       _W("[__RECOVERY__] uid(%u)", uid);
+       pid = _login_monitor_get_launchpad_pid(uid);
+       if (pid < 0) {
+               _E("Failed to get launchpad pid. uid(%u)", uid);
+               return -1;
+       }
+
+       _app_status_foreach_running_appinfo(__running_appinfo_cb, NULL);
+
+       ret = kill(pid, SIGABRT);
+       _E("[__RECOVERY__] launchpad pid(%d), uid(%d), result(%d)",
+                       pid, uid, ret);
+       return ret;
+}
index b92cba0b73439ad2567912094f55caacf0404ee6..3b4c64370b1893bd2c629c2dcda61d60c490c862 100644 (file)
@@ -87,8 +87,11 @@ static int __send_signal(const char *object_path, const char *interface_name,
        GDBusConnection *conn;
 
        conn = __get_system_conn();
-       if (conn == NULL)
+       if (conn == NULL) {
+               if (parameters)
+                       g_variant_unref(parameters);
                return -1;
+       }
 
        if (g_dbus_connection_emit_signal(conn,
                                        NULL,
@@ -762,6 +765,22 @@ int _signal_add_ready_cb(signal_ready_cb callback, void *user_data)
        return 0;
 }
 
+int _signal_send_app_dead(int pid)
+{
+       int ret;
+
+       ret = __send_signal(AUL_DBUS_PATH,
+                       AUL_DBUS_SIGNAL_INTERFACE,
+                       AUL_DBUS_APPDEAD_SIGNAL,
+                       g_variant_new("(u)", pid));
+       if (ret < 0)
+               return ret;
+
+       _D("App dead. pid(%d)", pid);
+
+       return 0;
+}
+
 static void __get_connection_cb(GObject *source_object,
                GAsyncResult *res, gpointer user_data)
 {