#include <signal.h>
#include <aul.h>
+#include <glib.h>
#include "amd_app_status.h"
#include "amd_config.h"
#include "amd_login_monitor.h"
#include "amd_signal.h"
#include "amd_util.h"
+#include "amd_socket.h"
+
+#define TIMEOUT_INTERVAL 1000
+#define LAUNCHPAD_RECOVERY_SOCK ".launchpad-recovery-sock"
struct launchpad_info {
int (*launcher)(bundle *, uid_t t, void *);
};
static struct launchpad_info __launchpad;
+static GHashTable *__timer_tbl;
int _launchpad_set_launcher(int (*callback)(bundle *, uid_t, void *),
void *user_data)
return __launchpad.launcher(kb, uid, __launchpad.data);
}
+static void __remove_recovery_timer(gpointer data)
+{
+ guint timer = GPOINTER_TO_UINT(data);
+
+ g_source_remove(timer);
+}
+
+static void __unset_recovery_timer(uid_t uid)
+{
+ if (!g_hash_table_contains(__timer_tbl, GUINT_TO_POINTER(uid)))
+ return;
+
+ g_hash_table_remove(__timer_tbl, GUINT_TO_POINTER(uid));
+ _W("[__RECOVERY__] timer is removed. uid(%u)", uid);
+}
+
+static gboolean __launchpad_recovery_cb(gpointer data)
+{
+ uid_t uid = GPOINTER_TO_UINT(data);
+ bundle *b;
+ pid_t pgid;
+ pid_t pid;
+ int ret;
+
+ pid = _login_monitor_get_launchpad_pid(uid);
+ if (pid > 0) {
+ pgid = getpgid(pid);
+ if (pgid > 0) {
+ _W("[__RECOVERY__] launchpad(%d) is running", pid);
+ return G_SOURCE_CONTINUE;
+ }
+ }
+
+ b = bundle_create();
+ ret = _send_cmd_to_launchpad_async(LAUNCHPAD_RECOVERY_SOCK, uid,
+ 0, b);
+ bundle_free(b);
+ if (ret < 0) {
+ _E("[__RECOVERY__] Failed to send recovery request. error(%d)",
+ ret);
+ return G_SOURCE_CONTINUE;
+ }
+
+ _W("[__RECOVERY__] Recovery launchpad");
+ __unset_recovery_timer(uid);
+ return G_SOURCE_CONTINUE;
+}
+
+static void __set_recovery_timer(uid_t uid)
+{
+ guint timer;
+
+ timer = g_timeout_add(TIMEOUT_INTERVAL, __launchpad_recovery_cb,
+ GUINT_TO_POINTER(uid));
+ g_hash_table_insert(__timer_tbl, GUINT_TO_POINTER(uid),
+ GUINT_TO_POINTER(timer));
+ _W("[__RECOVERY__] timer(%u) is removed. uid(%u)", timer, uid);
+}
+
+static bool __is_recovering(uid_t uid)
+{
+ return g_hash_table_contains(__timer_tbl, GUINT_TO_POINTER(uid));
+}
+
static void __running_appinfo_cb(app_status_h app_status, void *user_data)
{
const char *appid;
pid_t pid;
int ret;
+ if (__is_recovering(uid))
+ return 0;
+
_W("[__RECOVERY__] uid(%u)", uid);
pid = _login_monitor_get_launchpad_pid(uid);
if (pid < 0) {
ret = kill(pid, SIGABRT);
_E("[__RECOVERY__] launchpad pid(%d), uid(%d), result(%d)",
pid, uid, ret);
+
+ __set_recovery_timer(uid);
return ret;
}
+
+int _launchpad_init(void)
+{
+ _D("LAUNCHPAD_INIT");
+
+ __timer_tbl = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+ NULL, __remove_recovery_timer);
+ if (!__timer_tbl) {
+ _E("g_hash_table_new() is failed");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+void _launchpad_fini(void)
+{
+ _D("LAUNCHPAD_FINI");
+ if (__timer_tbl)
+ g_hash_table_destroy(__timer_tbl);
+}