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);
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);
void *data);
int _signal_add_ready_cb(signal_ready_cb callback, void *user_data);
+
+int _signal_send_app_dead(int pid);
fg_timeout=5000
watchdog_interval=10000
wathcdog_max_retry=3
+launchpad_max_launch_failure=5
#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;
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];
_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;
__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");
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);
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;
/*
- * 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 *);
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;
+}
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,
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)
{