1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
3 * LADI Session Handler (ladish)
5 * Copyright (C) 2009, 2010, 2011 Nedko Arnaudov <nedko@arnaudov.name>
7 **************************************************************************
8 * This file contains implementation of app supervisor object
9 **************************************************************************
11 * LADI Session Handler is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * LADI Session Handler is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with LADI Session Handler. If not, see <http://www.gnu.org/licenses/>
23 * or write to the Free Software Foundation, Inc.,
24 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include "config.h" /* Get _GNU_SOURCE defenition first to have some GNU extension available */
29 #include <sys/types.h>
34 #include "app_supervisor.h"
35 #include "../dbus/error.h"
36 #include "../dbus_constants.h"
38 #include "studio_internal.h"
39 #include "../proxies/notify_proxy.h"
40 #include "../proxies/lash_client_proxy.h"
41 #include "../common/catdup.h"
42 #include "../common/dirhelpers.h"
46 struct list_head siblings
;
52 char level
[MAX_LEVEL_CHARCOUNT
];
57 int firstborn_refcount
;
58 bool zombie
; /* if true, remove when stopped */
62 struct ladish_app_supervisor
* supervisor
;
65 struct ladish_app_supervisor
73 struct list_head applist
;
74 void * on_app_renamed_context
;
75 ladish_app_supervisor_on_app_renamed_callback on_app_renamed
;
78 bool ladish_check_app_level_validity(const char * level
, size_t * len_ptr
)
82 if (len
>= MAX_LEVEL_CHARCOUNT
)
87 if (strcmp(level
, LADISH_APP_LEVEL_0
) != 0 &&
88 strcmp(level
, LADISH_APP_LEVEL_1
) != 0&&
89 strcmp(level
, LADISH_APP_LEVEL_LASH
) != 0)
102 static int ladish_level_string_to_integer(const char * level
)
104 if (strcmp(level
, LADISH_APP_LEVEL_0
) == 0)
108 else if (strcmp(level
, LADISH_APP_LEVEL_1
) == 0)
112 else if (strcmp(level
, LADISH_APP_LEVEL_LASH
) == 0 ||
113 strcmp(level
, LADISH_APP_LEVEL_JACKSESSION
) == 0)
123 ladish_app_supervisor_create(
124 ladish_app_supervisor_handle
* supervisor_handle_ptr
,
128 ladish_app_supervisor_on_app_renamed_callback on_app_renamed
)
130 struct ladish_app_supervisor
* supervisor_ptr
;
132 supervisor_ptr
= malloc(sizeof(struct ladish_app_supervisor
));
133 if (supervisor_ptr
== NULL
)
135 log_error("malloc() failed to allocate struct ladish_app_supervisor");
139 supervisor_ptr
->opath
= strdup(opath
);
140 if (supervisor_ptr
->opath
== NULL
)
142 log_error("strdup() failed for app supervisor opath");
143 free(supervisor_ptr
);
147 supervisor_ptr
->name
= strdup(name
);
148 if (supervisor_ptr
->name
== NULL
)
150 log_error("strdup() failed for app supervisor name");
151 free(supervisor_ptr
->opath
);
152 free(supervisor_ptr
);
156 supervisor_ptr
->dir
= NULL
;
157 supervisor_ptr
->project_name
= NULL
;
159 supervisor_ptr
->version
= 0;
160 supervisor_ptr
->next_id
= 1;
162 INIT_LIST_HEAD(&supervisor_ptr
->applist
);
164 supervisor_ptr
->on_app_renamed_context
= context
;
165 supervisor_ptr
->on_app_renamed
= on_app_renamed
;
167 *supervisor_handle_ptr
= (ladish_app_supervisor_handle
)supervisor_ptr
;
172 struct ladish_app
* ladish_app_supervisor_find_app_by_id_internal(struct ladish_app_supervisor
* supervisor_ptr
, uint64_t id
)
174 struct list_head
* node_ptr
;
175 struct ladish_app
* app_ptr
;
177 list_for_each(node_ptr
, &supervisor_ptr
->applist
)
179 app_ptr
= list_entry(node_ptr
, struct ladish_app
, siblings
);
180 if (app_ptr
->id
== id
)
189 void remove_app_internal(struct ladish_app_supervisor
* supervisor_ptr
, struct ladish_app
* app_ptr
)
191 ASSERT(app_ptr
->pid
== 0); /* Removing not-stoped app? Zombies will make a rebellion! */
193 list_del(&app_ptr
->siblings
);
195 supervisor_ptr
->version
++;
198 cdbus_g_dbus_connection
,
199 supervisor_ptr
->opath
,
200 IFACE_APP_SUPERVISOR
,
203 &supervisor_ptr
->version
,
206 free(app_ptr
->dbus_name
);
208 free(app_ptr
->commandline
);
212 void emit_app_state_changed(struct ladish_app_supervisor
* supervisor_ptr
, struct ladish_app
* app_ptr
)
215 dbus_bool_t terminal
;
216 const char * level_str
;
219 running
= app_ptr
->pid
!= 0;
220 terminal
= app_ptr
->terminal
;
221 level_str
= app_ptr
->level
;
222 level_byte
= ladish_level_string_to_integer(app_ptr
->level
);
224 supervisor_ptr
->version
++;
227 cdbus_g_dbus_connection
,
228 supervisor_ptr
->opath
,
229 IFACE_APP_SUPERVISOR
,
232 &supervisor_ptr
->version
,
240 cdbus_g_dbus_connection
,
241 supervisor_ptr
->opath
,
242 IFACE_APP_SUPERVISOR
,
245 &supervisor_ptr
->version
,
253 #define supervisor_ptr ((struct ladish_app_supervisor *)supervisor_handle)
255 const char * ladish_app_supervisor_get_opath(ladish_app_supervisor_handle supervisor_handle
)
257 return supervisor_ptr
->opath
;
260 ladish_app_handle
ladish_app_supervisor_find_app_by_name(ladish_app_supervisor_handle supervisor_handle
, const char * name
)
262 struct list_head
* node_ptr
;
263 struct ladish_app
* app_ptr
;
265 list_for_each(node_ptr
, &supervisor_ptr
->applist
)
267 app_ptr
= list_entry(node_ptr
, struct ladish_app
, siblings
);
268 if (strcmp(app_ptr
->name
, name
) == 0)
270 return (ladish_app_handle
)app_ptr
;
277 ladish_app_handle
ladish_app_supervisor_find_app_by_id(ladish_app_supervisor_handle supervisor_handle
, uint64_t id
)
279 return (ladish_app_handle
)ladish_app_supervisor_find_app_by_id_internal(supervisor_ptr
, id
);
282 ladish_app_handle
ladish_app_supervisor_find_app_by_pid(ladish_app_supervisor_handle supervisor_handle
, pid_t pid
)
284 struct list_head
* node_ptr
;
285 struct ladish_app
* app_ptr
;
287 list_for_each(node_ptr
, &supervisor_ptr
->applist
)
289 app_ptr
= list_entry(node_ptr
, struct ladish_app
, siblings
);
290 if (app_ptr
->pid
== pid
)
292 //log_info("app \"%s\" found by pid %llu", app_ptr->name, (unsigned long long)pid);
293 return (ladish_app_handle
)app_ptr
;
300 ladish_app_handle
ladish_app_supervisor_find_app_by_uuid(ladish_app_supervisor_handle supervisor_handle
, const uuid_t uuid
)
302 struct list_head
* node_ptr
;
303 struct ladish_app
* app_ptr
;
305 list_for_each(node_ptr
, &supervisor_ptr
->applist
)
307 app_ptr
= list_entry(node_ptr
, struct ladish_app
, siblings
);
308 if (uuid_compare(app_ptr
->uuid
, uuid
) == 0)
310 return (ladish_app_handle
)app_ptr
;
318 ladish_app_supervisor_add(
319 ladish_app_supervisor_handle supervisor_handle
,
323 const char * command
,
327 struct ladish_app
* app_ptr
;
329 dbus_bool_t dbus_terminal
;
333 if (!ladish_check_app_level_validity(level
, &len
))
335 log_error("invalid level '%s'", level
);
339 app_ptr
= malloc(sizeof(struct ladish_app
));
342 log_error("malloc of struct ladish_app failed");
346 app_ptr
->name
= strdup(name
);
347 if (app_ptr
->name
== NULL
)
349 log_error("strdup() failed for app name");
354 app_ptr
->commandline
= strdup(command
);
355 if (app_ptr
->commandline
== NULL
)
357 log_error("strdup() failed for app commandline");
363 app_ptr
->dbus_name
= NULL
;
365 app_ptr
->terminal
= terminal
;
366 memcpy(app_ptr
->level
, level
, len
+ 1);
369 app_ptr
->firstborn_pid
= 0;
370 app_ptr
->firstborn_pgrp
= 0;
371 app_ptr
->firstborn_refcount
= 0;
373 app_ptr
->id
= supervisor_ptr
->next_id
++;
374 if (uuid
== NULL
|| uuid_is_null(uuid
))
376 uuid_generate(app_ptr
->uuid
);
380 uuid_copy(app_ptr
->uuid
, uuid
);
383 app_ptr
->zombie
= false;
384 app_ptr
->state
= LADISH_APP_STATE_STOPPED
;
385 app_ptr
->autorun
= autorun
;
386 app_ptr
->supervisor
= supervisor_ptr
;
387 list_add_tail(&app_ptr
->siblings
, &supervisor_ptr
->applist
);
389 supervisor_ptr
->version
++;
392 dbus_terminal
= terminal
;
393 level
= app_ptr
->level
;
394 level_byte
= ladish_level_string_to_integer(app_ptr
->level
);
396 cdbus_g_dbus_connection
,
397 supervisor_ptr
->opath
,
398 IFACE_APP_SUPERVISOR
,
401 &supervisor_ptr
->version
,
408 cdbus_g_dbus_connection
,
409 supervisor_ptr
->opath
,
410 IFACE_APP_SUPERVISOR
,
413 &supervisor_ptr
->version
,
420 return (ladish_app_handle
)app_ptr
;
423 static void ladish_app_send_signal(struct ladish_app
* app_ptr
, int sig
, bool prefer_firstborn
)
426 const char * signal_name
;
428 ASSERT(app_ptr
->state
= LADISH_APP_STATE_STARTED
);
433 signal_name
= "SIGTERM";
436 signal_name
= "SIGKILL";
439 signal_name
= "SIGUSR1";
442 signal_name
= strsignal(sig
);
443 if (signal_name
== NULL
)
445 signal_name
= "unknown";
449 if (app_ptr
->pid
== 0)
451 log_error("not sending signal %d (%s) to app '%s' because its pid is %d", sig
, signal_name
, app_ptr
->name
, (int)app_ptr
->pid
);
460 if (app_ptr
->pgrp
== 0)
462 app_ptr
->pgrp
= getpgid(app_ptr
->pid
);
463 if (app_ptr
->pgrp
== -1)
468 log_error("getpgid(%u) failed. %s (%d)", (unsigned int)app_ptr
->pid
, strerror(errno
), errno
);
473 if (app_ptr
->firstborn_pid
!= 0)
475 app_ptr
->firstborn_pgrp
= getpgid(app_ptr
->firstborn_pid
);
476 if (app_ptr
->firstborn_pgrp
== -1)
478 app_ptr
->firstborn_pgrp
= 0;
481 log_error("getpgid(%u) failed (firstborn). %s (%d)", (unsigned int)app_ptr
->firstborn_pid
, strerror(errno
), errno
);
486 if (app_ptr
->pgrp
!= 0)
488 log_info("sending signal %d (%s) to pgrp %u ('%s')", sig
, signal_name
, (unsigned int)app_ptr
->pgrp
, app_ptr
->name
);
490 if (app_ptr
->pgrp
<= 1)
496 killpg(app_ptr
->pgrp
, sig
);
498 if (app_ptr
->firstborn_pid
!= 0)
500 if (app_ptr
->firstborn_pgrp
!= 0)
502 if (app_ptr
->firstborn_pgrp
<= 1)
508 if (app_ptr
->firstborn_pgrp
!= app_ptr
->pgrp
)
510 log_info("sending signal %d (%s) to firstborn pgrp %u ('%s')", sig
, signal_name
, (unsigned int)app_ptr
->firstborn_pgrp
, app_ptr
->name
);
512 killpg(app_ptr
->firstborn_pgrp
, sig
);
516 /* fall through to sending signal to pid */
523 /* fall through to sending signal to pid */
525 if (app_ptr
->pid
<= 1)
531 if (prefer_firstborn
&& app_ptr
->firstborn_pid
!= 0)
533 pid
= app_ptr
->firstborn_pid
;
546 log_info("sending signal %d (%s) to '%s' with pid %u", sig
, signal_name
, app_ptr
->name
, (unsigned int)pid
);
551 static inline void ladish_app_initiate_lash_save(struct ladish_app
* app_ptr
, const char * base_dir
)
556 if (base_dir
== NULL
)
558 log_error("Cannot initiate LASH save because base dir is unknown");
563 uuid_unparse(app_ptr
->uuid
, uuid_str
);
564 app_dir
= catdup3(base_dir
, "/lash_apps/", uuid_str
);
567 log_error("Cannot initiate LASH save because of memory allocation failure.");
571 if (!ensure_dir_exist(app_dir
, S_IRWXU
| S_IRWXG
| S_IRWXO
))
576 if (lash_client_proxy_save(app_ptr
->dbus_name
, app_dir
))
578 log_info("LASH Save into '%s' initiated for '%s' with D-Bus name '%s'", app_dir
, app_ptr
->name
, app_ptr
->dbus_name
);
587 static inline void ladish_app_initiate_lash_restore(struct ladish_app
* app_ptr
, const char * base_dir
)
593 if (base_dir
== NULL
)
595 log_error("Cannot initiate LASH restore because base dir is unknown");
600 uuid_unparse(app_ptr
->uuid
, uuid_str
);
601 app_dir
= catdup3(base_dir
, "/lash_apps/", uuid_str
);
604 log_error("Cannot initiate LASH restore because of memory allocation failure.");
608 if (!check_dir_exists(app_dir
))
610 log_info("Not initiating LASH restore because of app directory '%s' does not exist.", app_dir
);
614 if (lash_client_proxy_restore(app_ptr
->dbus_name
, app_dir
))
616 log_info("LASH Save from '%s' initiated for '%s' with D-Bus name '%s'", app_dir
, app_ptr
->name
, app_ptr
->dbus_name
);
625 static inline void ladish_app_initiate_save(struct ladish_app
* app_ptr
)
627 if (strcmp(app_ptr
->level
, LADISH_APP_LEVEL_LASH
) == 0 &&
628 app_ptr
->dbus_name
!= NULL
)
630 ladish_app_initiate_lash_save(app_ptr
, app_ptr
->supervisor
->dir
!= NULL
? app_ptr
->supervisor
->dir
: g_base_dir
);
632 else if (strcmp(app_ptr
->level
, LADISH_APP_LEVEL_1
) == 0)
634 ladish_app_send_signal(app_ptr
, SIGUSR1
, true);
638 static inline void ladish_app_initiate_stop(struct ladish_app
* app_ptr
)
640 if (strcmp(app_ptr
->level
, LADISH_APP_LEVEL_LASH
) == 0 &&
641 app_ptr
->dbus_name
!= NULL
&&
642 lash_client_proxy_quit(app_ptr
->dbus_name
))
644 log_info("LASH Quit initiated for '%s' with D-Bus name '%s'", app_ptr
->name
, app_ptr
->dbus_name
);
648 ladish_app_send_signal(app_ptr
, SIGTERM
, false);
651 app_ptr
->state
= LADISH_APP_STATE_STOPPING
;
654 bool ladish_app_supervisor_clear(ladish_app_supervisor_handle supervisor_handle
)
656 struct list_head
* node_ptr
;
657 struct list_head
* safe_node_ptr
;
658 struct ladish_app
* app_ptr
;
661 free(supervisor_ptr
->dir
);
662 supervisor_ptr
->dir
= NULL
;
664 free(supervisor_ptr
->project_name
);
665 supervisor_ptr
->project_name
= NULL
;
669 list_for_each_safe(node_ptr
, safe_node_ptr
, &supervisor_ptr
->applist
)
671 app_ptr
= list_entry(node_ptr
, struct ladish_app
, siblings
);
672 if (app_ptr
->pid
!= 0)
674 log_info("terminating '%s'...", app_ptr
->name
);
675 ladish_app_initiate_stop(app_ptr
);
676 app_ptr
->zombie
= true;
681 log_info("removing '%s'", app_ptr
->name
);
682 remove_app_internal(supervisor_ptr
, app_ptr
);
689 void ladish_app_supervisor_destroy(ladish_app_supervisor_handle supervisor_handle
)
691 ladish_app_supervisor_clear(supervisor_handle
);
692 free(supervisor_ptr
->name
);
693 free(supervisor_ptr
->opath
);
694 free(supervisor_ptr
);
698 ladish_app_supervisor_set_directory(
699 ladish_app_supervisor_handle supervisor_handle
,
707 log_error("strdup(\"%s\") failed", dir
);
711 if (supervisor_ptr
->dir
!= NULL
)
713 free(supervisor_ptr
->dir
);
716 supervisor_ptr
->dir
= dup
;
722 ladish_app_supervisor_set_project_name(
723 ladish_app_supervisor_handle supervisor_handle
,
724 const char * project_name
)
728 if (project_name
!= NULL
)
730 dup
= strdup(project_name
);
733 log_error("strdup(\"%s\") failed", project_name
);
742 free(supervisor_ptr
->project_name
);
743 supervisor_ptr
->project_name
= dup
;
748 bool ladish_app_supervisor_child_exit(ladish_app_supervisor_handle supervisor_handle
, pid_t pid
)
750 struct list_head
* node_ptr
;
751 struct ladish_app
* app_ptr
;
753 list_for_each(node_ptr
, &supervisor_ptr
->applist
)
755 app_ptr
= list_entry(node_ptr
, struct ladish_app
, siblings
);
756 if (app_ptr
->pid
== pid
)
758 log_info("exit of child '%s' detected.", app_ptr
->name
);
762 /* firstborn pid and pgrp is not reset here because it is refcounted
763 and managed independently through the add/del_pid() methods */
767 remove_app_internal(supervisor_ptr
, app_ptr
);
771 if (app_ptr
->state
== LADISH_APP_STATE_STARTED
)
773 ladish_notify_simple(LADISH_NOTIFY_URGENCY_HIGH
, "App terminated unexpectedly", app_ptr
->name
);
776 app_ptr
->state
= LADISH_APP_STATE_STOPPED
;
778 emit_app_state_changed(supervisor_ptr
, app_ptr
);
789 ladish_app_supervisor_enum(
790 ladish_app_supervisor_handle supervisor_handle
,
792 ladish_app_supervisor_enum_callback callback
)
794 struct list_head
* node_ptr
;
795 struct ladish_app
* app_ptr
;
797 list_for_each(node_ptr
, &supervisor_ptr
->applist
)
799 app_ptr
= list_entry(node_ptr
, struct ladish_app
, siblings
);
801 if (!callback(context
, app_ptr
->name
, app_ptr
->pid
!= 0, app_ptr
->commandline
, app_ptr
->terminal
, app_ptr
->level
, app_ptr
->pid
, app_ptr
->uuid
))
810 #define app_ptr ((struct ladish_app *)app_handle)
812 bool ladish_app_supervisor_start_app(ladish_app_supervisor_handle supervisor_handle
, ladish_app_handle app_handle
)
814 app_ptr
->zombie
= false;
816 ASSERT(app_ptr
->pid
== 0);
819 supervisor_ptr
->name
,
820 supervisor_ptr
->project_name
,
822 supervisor_ptr
->dir
!= NULL
? supervisor_ptr
->dir
: "/",
824 app_ptr
->commandline
,
830 ASSERT(app_ptr
->pid
!= 0);
831 app_ptr
->state
= LADISH_APP_STATE_STARTED
;
833 emit_app_state_changed(supervisor_ptr
, app_ptr
);
837 void ladish_app_supervisor_remove_app(ladish_app_supervisor_handle supervisor_handle
, ladish_app_handle app_handle
)
839 remove_app_internal(supervisor_ptr
, app_ptr
);
842 unsigned int ladish_app_get_state(ladish_app_handle app_handle
)
844 return app_ptr
->state
;
847 bool ladish_app_is_running(ladish_app_handle app_handle
)
849 return app_ptr
->pid
!= 0;
852 const char * ladish_app_get_name(ladish_app_handle app_handle
)
854 return app_ptr
->name
;
857 void ladish_app_get_uuid(ladish_app_handle app_handle
, uuid_t uuid
)
859 uuid_copy(uuid
, app_ptr
->uuid
);
862 void ladish_app_stop(ladish_app_handle app_handle
)
864 ladish_app_initiate_stop(app_ptr
);
867 void ladish_app_kill(ladish_app_handle app_handle
)
869 ladish_app_send_signal(app_ptr
, SIGKILL
, false);
870 app_ptr
->state
= LADISH_APP_STATE_KILL
;
873 void ladish_app_save(ladish_app_handle app_handle
)
875 ladish_app_initiate_save(app_ptr
);
878 void ladish_app_restore(ladish_app_handle app_handle
)
880 if (strcmp(app_ptr
->level
, LADISH_APP_LEVEL_LASH
) == 0 &&
881 app_ptr
->dbus_name
!= NULL
)
883 ladish_app_initiate_lash_restore(app_ptr
, app_ptr
->supervisor
->dir
!= NULL
? app_ptr
->supervisor
->dir
: g_base_dir
);
887 void ladish_app_add_pid(ladish_app_handle app_handle
, pid_t pid
)
889 if (app_ptr
->pid
== 0)
891 log_error("Associating pid with stopped app does not make sense");
896 if (pid
<= 1) /* catch -1, 0 and 1 */
898 log_error("Refusing domination by ignoring pid %d", (int)pid
);
903 if (app_ptr
->pid
== pid
)
904 { /* The top level process that is already known */
908 if (app_ptr
->firstborn_pid
!= 0)
909 { /* Ignore non-first children */
910 if (app_ptr
->firstborn_pid
== pid
)
912 app_ptr
->firstborn_refcount
++;
917 log_info("First grandchild with pid %u", (unsigned int)pid
);
918 app_ptr
->firstborn_pid
= pid
;
919 ASSERT(app_ptr
->firstborn_refcount
== 0);
920 app_ptr
->firstborn_refcount
= 1;
923 void ladish_app_del_pid(ladish_app_handle app_handle
, pid_t pid
)
925 if (app_ptr
->firstborn_pid
!= 0 && app_ptr
->firstborn_pid
== pid
)
927 ASSERT(app_ptr
->firstborn_refcount
> 0);
928 app_ptr
->firstborn_refcount
--;
929 if (app_ptr
->firstborn_refcount
> 0)
933 log_info("First grandchild with pid %u has gone", (unsigned int)pid
);
934 app_ptr
->firstborn_pid
= 0;
935 app_ptr
->firstborn_pgrp
= 0;
936 app_ptr
->firstborn_refcount
= 0;
940 bool ladish_app_set_dbus_name(ladish_app_handle app_handle
, const char * name
)
947 log_error("strdup() failed for app dbus name");
951 free(app_ptr
->dbus_name
);
952 app_ptr
->dbus_name
= dup
;
958 void ladish_app_supervisor_autorun(ladish_app_supervisor_handle supervisor_handle
)
960 struct list_head
* node_ptr
;
961 struct ladish_app
* app_ptr
;
963 list_for_each(node_ptr
, &supervisor_ptr
->applist
)
965 app_ptr
= list_entry(node_ptr
, struct ladish_app
, siblings
);
967 if (!app_ptr
->autorun
)
972 app_ptr
->autorun
= false;
974 log_info("autorun('%s', %s, '%s') called", app_ptr
->name
, app_ptr
->terminal
? "terminal" : "shell", app_ptr
->commandline
);
976 if (!ladish_app_supervisor_start_app((ladish_app_supervisor_handle
)supervisor_ptr
, (ladish_app_handle
)app_ptr
))
978 log_error("Execution of '%s' failed", app_ptr
->commandline
);
984 void ladish_app_supervisor_stop(ladish_app_supervisor_handle supervisor_handle
)
986 struct list_head
* node_ptr
;
987 struct ladish_app
* app_ptr
;
989 list_for_each(node_ptr
, &supervisor_ptr
->applist
)
991 app_ptr
= list_entry(node_ptr
, struct ladish_app
, siblings
);
992 if (app_ptr
->pid
!= 0)
994 log_info("terminating '%s'...", app_ptr
->name
);
995 app_ptr
->autorun
= true;
996 ladish_app_initiate_stop(app_ptr
);
1001 void ladish_app_supervisor_save(ladish_app_supervisor_handle supervisor_handle
)
1003 struct list_head
* node_ptr
;
1004 struct ladish_app
* app_ptr
;
1006 list_for_each(node_ptr
, &supervisor_ptr
->applist
)
1008 app_ptr
= list_entry(node_ptr
, struct ladish_app
, siblings
);
1009 if (app_ptr
->state
!= LADISH_APP_STATE_STARTED
)
1014 if (app_ptr
->pid
== 0)
1020 ladish_app_initiate_save(app_ptr
);
1024 const char * ladish_app_supervisor_get_name(ladish_app_supervisor_handle supervisor_handle
)
1026 return supervisor_ptr
->name
;
1029 unsigned int ladish_app_supervisor_get_running_app_count(ladish_app_supervisor_handle supervisor_handle
)
1031 struct list_head
* node_ptr
;
1032 struct ladish_app
* app_ptr
;
1033 unsigned int counter
;
1036 list_for_each(node_ptr
, &supervisor_ptr
->applist
)
1038 app_ptr
= list_entry(node_ptr
, struct ladish_app
, siblings
);
1039 if (app_ptr
->pid
!= 0)
1048 bool ladish_app_supervisor_has_apps(ladish_app_supervisor_handle supervisor_handle
)
1050 return !list_empty(&supervisor_ptr
->applist
);
1053 void ladish_app_supervisor_dump(ladish_app_supervisor_handle supervisor_handle
)
1055 struct list_head
* node_ptr
;
1056 struct ladish_app
* app_ptr
;
1059 list_for_each(node_ptr
, &supervisor_ptr
->applist
)
1061 app_ptr
= list_entry(node_ptr
, struct ladish_app
, siblings
);
1062 uuid_unparse(app_ptr
->uuid
, uuid_str
);
1063 log_info("app '%s' with commandline '%s'", app_ptr
->name
, app_ptr
->commandline
);
1064 log_info(" %s", uuid_str
);
1065 log_info(" %s, %s, level '%s'", app_ptr
->terminal
? "terminal" : "shell", app_ptr
->autorun
? "autorun" : "stopped", app_ptr
->level
, app_ptr
->commandline
);
1069 #undef supervisor_ptr
1071 /**********************************************************************************/
1073 /**********************************************************************************/
1075 #define supervisor_ptr ((struct ladish_app_supervisor *)call_ptr->iface_context)
1077 static void get_version(struct dbus_method_call
* call_ptr
)
1083 method_return_new_single(call_ptr
, DBUS_TYPE_UINT32
, &version
);
1086 static void get_all_multiversion(struct dbus_method_call
* call_ptr
, int version
)
1088 DBusMessageIter iter
, array_iter
, struct_iter
;
1089 struct list_head
* node_ptr
;
1090 struct ladish_app
* app_ptr
;
1091 dbus_bool_t running
;
1092 dbus_bool_t terminal
;
1093 const char * level_str
;
1096 //log_info("get_all called");
1098 call_ptr
->reply
= dbus_message_new_method_return(call_ptr
->message
);
1099 if (call_ptr
->reply
== NULL
)
1104 dbus_message_iter_init_append(call_ptr
->reply
, &iter
);
1106 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_UINT64
, &supervisor_ptr
->version
))
1111 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_ARRAY
, version
== 1 ? "(tsbby)" : "(tsbbs)", &array_iter
))
1116 list_for_each(node_ptr
, &supervisor_ptr
->applist
)
1118 app_ptr
= list_entry(node_ptr
, struct ladish_app
, siblings
);
1120 log_info("app '%s' (%llu)", app_ptr
->name
, (unsigned long long)app_ptr
->id
);
1122 if (!dbus_message_iter_open_container (&array_iter
, DBUS_TYPE_STRUCT
, NULL
, &struct_iter
))
1127 if (!dbus_message_iter_append_basic(&struct_iter
, DBUS_TYPE_UINT64
, &app_ptr
->id
))
1132 if (!dbus_message_iter_append_basic(&struct_iter
, DBUS_TYPE_STRING
, &app_ptr
->name
))
1137 running
= app_ptr
->pid
!= 0;
1138 if (!dbus_message_iter_append_basic(&struct_iter
, DBUS_TYPE_BOOLEAN
, &running
))
1143 terminal
= app_ptr
->terminal
;
1144 if (!dbus_message_iter_append_basic(&struct_iter
, DBUS_TYPE_BOOLEAN
, &terminal
))
1151 level_byte
= ladish_level_string_to_integer(app_ptr
->level
);
1152 if (!dbus_message_iter_append_basic(&struct_iter
, DBUS_TYPE_BYTE
, &level_byte
))
1159 ASSERT(version
== 2);
1161 level_str
= app_ptr
->level
;
1162 if (!dbus_message_iter_append_basic(&struct_iter
, DBUS_TYPE_STRING
, &level_str
))
1168 if (!dbus_message_iter_close_container(&array_iter
, &struct_iter
))
1174 if (!dbus_message_iter_close_container(&iter
, &array_iter
))
1182 dbus_message_unref(call_ptr
->reply
);
1183 call_ptr
->reply
= NULL
;
1186 log_error("Ran out of memory trying to construct method return");
1189 static void get_all1(struct dbus_method_call
* call_ptr
)
1191 get_all_multiversion(call_ptr
, 1);
1194 static void get_all2(struct dbus_method_call
* call_ptr
)
1196 get_all_multiversion(call_ptr
, 2);
1199 static void run_custom1(struct dbus_method_call
* call_ptr
)
1201 dbus_bool_t terminal
;
1202 const char * commandline
;
1206 if (!dbus_message_get_args(
1208 &cdbus_g_dbus_error
,
1209 DBUS_TYPE_BOOLEAN
, &terminal
,
1210 DBUS_TYPE_STRING
, &commandline
,
1211 DBUS_TYPE_STRING
, &name
,
1212 DBUS_TYPE_BYTE
, &level
,
1215 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_INVALID_ARGS
, "Invalid arguments to method \"%s\": %s", call_ptr
->method_name
, cdbus_g_dbus_error
.message
);
1216 dbus_error_free(&cdbus_g_dbus_error
);
1220 log_info("%s('%s', %s, '%s', %"PRIu8
") called", call_ptr
->method_name
, name
, terminal
? "terminal" : "shell", commandline
, level
);
1224 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_INVALID_ARGS
, "invalid integer level %"PRIu8
, level
);
1228 if (ladish_command_new_app(
1230 ladish_studio_get_cmd_queue(),
1231 supervisor_ptr
->opath
,
1235 level
== 0 ? LADISH_APP_LEVEL_0
: LADISH_APP_LEVEL_1
))
1237 method_return_new_void(call_ptr
);
1241 static void run_custom2(struct dbus_method_call
* call_ptr
)
1243 dbus_bool_t terminal
;
1244 const char * commandline
;
1248 if (!dbus_message_get_args(
1250 &cdbus_g_dbus_error
,
1251 DBUS_TYPE_BOOLEAN
, &terminal
,
1252 DBUS_TYPE_STRING
, &commandline
,
1253 DBUS_TYPE_STRING
, &name
,
1254 DBUS_TYPE_STRING
, &level
,
1257 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_INVALID_ARGS
, "Invalid arguments to method \"%s\": %s", call_ptr
->method_name
, cdbus_g_dbus_error
.message
);
1258 dbus_error_free(&cdbus_g_dbus_error
);
1262 log_info("%s('%s', %s, '%s', '%s') called", call_ptr
->method_name
, name
, terminal
? "terminal" : "shell", commandline
, level
);
1264 if (!ladish_check_app_level_validity(level
, NULL
))
1266 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_INVALID_ARGS
, "invalid level '%s'", level
);
1270 if (ladish_command_new_app(
1272 ladish_studio_get_cmd_queue(),
1273 supervisor_ptr
->opath
,
1279 method_return_new_void(call_ptr
);
1283 static void start_app(struct dbus_method_call
* call_ptr
)
1287 if (!dbus_message_get_args(
1289 &cdbus_g_dbus_error
,
1290 DBUS_TYPE_UINT64
, &id
,
1293 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_INVALID_ARGS
, "Invalid arguments to method \"%s\": %s", call_ptr
->method_name
, cdbus_g_dbus_error
.message
);
1294 dbus_error_free(&cdbus_g_dbus_error
);
1298 if (ladish_command_change_app_state(call_ptr
, ladish_studio_get_cmd_queue(), supervisor_ptr
->opath
, id
, LADISH_APP_STATE_STARTED
))
1300 method_return_new_void(call_ptr
);
1304 static void stop_app(struct dbus_method_call
* call_ptr
)
1308 if (!dbus_message_get_args(
1310 &cdbus_g_dbus_error
,
1311 DBUS_TYPE_UINT64
, &id
,
1314 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_INVALID_ARGS
, "Invalid arguments to method \"%s\": %s", call_ptr
->method_name
, cdbus_g_dbus_error
.message
);
1315 dbus_error_free(&cdbus_g_dbus_error
);
1319 if (ladish_command_change_app_state(call_ptr
, ladish_studio_get_cmd_queue(), supervisor_ptr
->opath
, id
, LADISH_APP_STATE_STOPPED
))
1321 method_return_new_void(call_ptr
);
1325 static void kill_app(struct dbus_method_call
* call_ptr
)
1329 if (!dbus_message_get_args(
1331 &cdbus_g_dbus_error
,
1332 DBUS_TYPE_UINT64
, &id
,
1335 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_INVALID_ARGS
, "Invalid arguments to method \"%s\": %s", call_ptr
->method_name
, cdbus_g_dbus_error
.message
);
1336 dbus_error_free(&cdbus_g_dbus_error
);
1340 if (ladish_command_change_app_state(call_ptr
, ladish_studio_get_cmd_queue(), supervisor_ptr
->opath
, id
, LADISH_APP_STATE_KILL
))
1342 method_return_new_void(call_ptr
);
1346 static void get_app_properties_multiversion(struct dbus_method_call
* call_ptr
, int version
)
1349 struct ladish_app
* app_ptr
;
1350 dbus_bool_t running
;
1351 dbus_bool_t terminal
;
1352 const char * level_str
;
1357 if (!dbus_message_get_args(
1359 &cdbus_g_dbus_error
,
1360 DBUS_TYPE_UINT64
, &id
,
1363 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_INVALID_ARGS
, "Invalid arguments to method \"%s\": %s", call_ptr
->method_name
, cdbus_g_dbus_error
.message
);
1364 dbus_error_free(&cdbus_g_dbus_error
);
1368 app_ptr
= ladish_app_supervisor_find_app_by_id_internal(supervisor_ptr
, id
);
1369 if (app_ptr
== NULL
)
1371 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_INVALID_ARGS
, "App with ID %"PRIu64
" not found", id
);
1375 running
= app_ptr
->pid
!= 0;
1376 terminal
= app_ptr
->terminal
;
1379 level_byte
= ladish_level_string_to_integer(app_ptr
->level
);
1380 level_type
= DBUS_TYPE_BYTE
;
1381 level_ptr
= &level_byte
;
1385 ASSERT(version
== 2);
1386 level_str
= app_ptr
->level
;
1387 level_type
= DBUS_TYPE_STRING
;
1388 level_ptr
= &level_str
;
1391 call_ptr
->reply
= dbus_message_new_method_return(call_ptr
->message
);
1392 if (call_ptr
->reply
== NULL
)
1397 if (!dbus_message_append_args(
1399 DBUS_TYPE_STRING
, &app_ptr
->name
,
1400 DBUS_TYPE_STRING
, &app_ptr
->commandline
,
1401 DBUS_TYPE_BOOLEAN
, &running
,
1402 DBUS_TYPE_BOOLEAN
, &terminal
,
1403 level_type
, level_ptr
,
1412 dbus_message_unref(call_ptr
->reply
);
1413 call_ptr
->reply
= NULL
;
1416 log_error("Ran out of memory trying to construct method return");
1419 static void get_app_properties1(struct dbus_method_call
* call_ptr
)
1421 get_app_properties_multiversion(call_ptr
, 1);
1424 static void get_app_properties2(struct dbus_method_call
* call_ptr
)
1426 get_app_properties_multiversion(call_ptr
, 2);
1429 static void set_app_properties_multiversion(struct dbus_method_call
* call_ptr
, int version
)
1432 dbus_bool_t terminal
;
1434 const char * commandline
;
1435 const char * level_str
;
1439 struct ladish_app
* app_ptr
;
1441 char * commandline_buffer
;
1446 level_type
= DBUS_TYPE_BYTE
;
1447 level_ptr
= &level_byte
;
1451 ASSERT(version
== 2);
1452 level_type
= DBUS_TYPE_STRING
;
1453 level_ptr
= &level_str
;
1456 if (!dbus_message_get_args(
1458 &cdbus_g_dbus_error
,
1459 DBUS_TYPE_UINT64
, &id
,
1460 DBUS_TYPE_STRING
, &name
,
1461 DBUS_TYPE_STRING
, &commandline
,
1462 DBUS_TYPE_BOOLEAN
, &terminal
,
1463 level_type
, level_ptr
,
1466 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_INVALID_ARGS
, "Invalid arguments to method \"%s\": %s", call_ptr
->method_name
, cdbus_g_dbus_error
.message
);
1467 dbus_error_free(&cdbus_g_dbus_error
);
1475 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_INVALID_ARGS
, "invalid integer level %"PRIu8
, level_byte
);
1479 level_str
= level_byte
== 0 ? LADISH_APP_LEVEL_0
: LADISH_APP_LEVEL_1
;
1480 len
= strlen(level_str
);
1484 ASSERT(version
== 2);
1485 if (!ladish_check_app_level_validity(level_str
, &len
))
1487 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_INVALID_ARGS
, "invalid level '%s'", level_str
);
1492 app_ptr
= ladish_app_supervisor_find_app_by_id_internal(supervisor_ptr
, id
);
1493 if (app_ptr
== NULL
)
1495 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_INVALID_ARGS
, "App with ID %"PRIu64
" not found", id
);
1499 if (app_ptr
->pid
!= 0 && strcmp(commandline
, app_ptr
->commandline
) != 0)
1501 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_GENERIC
, "Cannot change commandline when app is running. '%s' -> '%s'", app_ptr
->commandline
, commandline
);
1505 if (app_ptr
->pid
!= 0 && ((app_ptr
->terminal
&& !terminal
) || (!app_ptr
->terminal
&& terminal
)))
1507 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_GENERIC
, "Cannot change whether to run in terminal when app is running");
1511 if (app_ptr
->pid
!= 0 && strcmp(app_ptr
->level
, level_str
) != 0)
1513 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_GENERIC
, "Cannot change app level when app is running");
1517 if (strcmp(commandline
, app_ptr
->commandline
) != 0)
1519 commandline_buffer
= strdup(commandline
);
1520 if (commandline_buffer
== NULL
)
1522 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_GENERIC
, "strdup() failed for app commandline");
1528 commandline_buffer
= NULL
;
1531 if (strcmp(name
, app_ptr
->name
) != 0)
1533 name_buffer
= strdup(name
);
1534 if (name_buffer
== NULL
)
1536 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_GENERIC
, "strdup() failed for app nam");
1537 if (commandline_buffer
!= NULL
)
1539 free(commandline_buffer
);
1549 if (name_buffer
!= NULL
)
1551 supervisor_ptr
->on_app_renamed(supervisor_ptr
->on_app_renamed_context
, app_ptr
->uuid
, app_ptr
->name
, name_buffer
);
1552 free(app_ptr
->name
);
1553 app_ptr
->name
= name_buffer
;
1556 if (commandline_buffer
!= NULL
)
1558 free(app_ptr
->commandline
);
1559 app_ptr
->commandline
= commandline_buffer
;
1562 memcpy(app_ptr
->level
, level_str
, len
+ 1);
1563 app_ptr
->terminal
= terminal
;
1565 emit_app_state_changed(supervisor_ptr
, app_ptr
);
1567 method_return_new_void(call_ptr
);
1570 static void set_app_properties1(struct dbus_method_call
* call_ptr
)
1572 set_app_properties_multiversion(call_ptr
, 1);
1575 static void set_app_properties2(struct dbus_method_call
* call_ptr
)
1577 set_app_properties_multiversion(call_ptr
, 2);
1581 static void remove_app(struct dbus_method_call
* call_ptr
)
1585 if (!dbus_message_get_args(
1587 &cdbus_g_dbus_error
,
1588 DBUS_TYPE_UINT64
, &id
,
1591 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_INVALID_ARGS
, "Invalid arguments to method \"%s\": %s", call_ptr
->method_name
, cdbus_g_dbus_error
.message
);
1592 dbus_error_free(&cdbus_g_dbus_error
);
1596 if (ladish_command_remove_app(call_ptr
, ladish_studio_get_cmd_queue(), supervisor_ptr
->opath
, id
))
1598 method_return_new_void(call_ptr
);
1602 static void is_app_running(struct dbus_method_call
* call_ptr
)
1605 struct ladish_app
* app_ptr
;
1606 dbus_bool_t running
;
1608 if (!dbus_message_get_args(
1610 &cdbus_g_dbus_error
,
1611 DBUS_TYPE_UINT64
, &id
,
1614 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_INVALID_ARGS
, "Invalid arguments to method \"%s\": %s", call_ptr
->method_name
, cdbus_g_dbus_error
.message
);
1615 dbus_error_free(&cdbus_g_dbus_error
);
1619 app_ptr
= ladish_app_supervisor_find_app_by_id_internal(supervisor_ptr
, id
);
1620 if (app_ptr
== NULL
)
1622 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_INVALID_ARGS
, "App with ID %"PRIu64
" not found", id
);
1626 running
= app_ptr
->pid
!= 0;
1628 method_return_new_single(call_ptr
, DBUS_TYPE_BOOLEAN
, &running
);
1631 #undef supervisor_ptr
1633 METHOD_ARGS_BEGIN(GetInterfaceVersion
, "Get version of this D-Bus interface")
1634 METHOD_ARG_DESCRIBE_OUT("running", DBUS_TYPE_UINT32_AS_STRING
, "Interface version")
1637 METHOD_ARGS_BEGIN(GetAll
, "Get list of apps")
1638 METHOD_ARG_DESCRIBE_OUT("list_version", DBUS_TYPE_UINT64_AS_STRING
, "Version of the list")
1639 METHOD_ARG_DESCRIBE_OUT("apps_list", "a(tsbby)", "List of apps")
1642 METHOD_ARGS_BEGIN(GetAll2
, "Get list of apps")
1643 METHOD_ARG_DESCRIBE_OUT("list_version", DBUS_TYPE_UINT64_AS_STRING
, "Version of the list")
1644 METHOD_ARG_DESCRIBE_OUT("apps_list", "a(tsbbs)", "List of apps")
1647 METHOD_ARGS_BEGIN(RunCustom
, "Start application by supplying commandline")
1648 METHOD_ARG_DESCRIBE_IN("terminal", DBUS_TYPE_BOOLEAN_AS_STRING
, "Whether to run in terminal")
1649 METHOD_ARG_DESCRIBE_IN("commandline", DBUS_TYPE_STRING_AS_STRING
, "Commandline")
1650 METHOD_ARG_DESCRIBE_IN("name", DBUS_TYPE_STRING_AS_STRING
, "Name")
1651 METHOD_ARG_DESCRIBE_IN("level", DBUS_TYPE_BYTE_AS_STRING
, "Level")
1654 METHOD_ARGS_BEGIN(RunCustom2
, "Start application by supplying commandline")
1655 METHOD_ARG_DESCRIBE_IN("terminal", DBUS_TYPE_BOOLEAN_AS_STRING
, "Whether to run in terminal")
1656 METHOD_ARG_DESCRIBE_IN("commandline", DBUS_TYPE_STRING_AS_STRING
, "Commandline")
1657 METHOD_ARG_DESCRIBE_IN("name", DBUS_TYPE_STRING_AS_STRING
, "Name")
1658 METHOD_ARG_DESCRIBE_IN("level", DBUS_TYPE_STRING_AS_STRING
, "Level")
1661 METHOD_ARGS_BEGIN(StartApp
, "Start application")
1662 METHOD_ARG_DESCRIBE_IN("id", DBUS_TYPE_UINT64_AS_STRING
, "id of app")
1665 METHOD_ARGS_BEGIN(StopApp
, "Stop application")
1666 METHOD_ARG_DESCRIBE_IN("id", DBUS_TYPE_UINT64_AS_STRING
, "id of app")
1669 METHOD_ARGS_BEGIN(KillApp
, "Kill application")
1670 METHOD_ARG_DESCRIBE_IN("id", DBUS_TYPE_UINT64_AS_STRING
, "id of app")
1673 METHOD_ARGS_BEGIN(RemoveApp
, "Remove application")
1674 METHOD_ARG_DESCRIBE_IN("id", DBUS_TYPE_UINT64_AS_STRING
, "id of app")
1677 METHOD_ARGS_BEGIN(GetAppProperties
, "Get properties of an application")
1678 METHOD_ARG_DESCRIBE_IN("id", DBUS_TYPE_UINT64_AS_STRING
, "id of app")
1679 METHOD_ARG_DESCRIBE_OUT("name", DBUS_TYPE_STRING_AS_STRING
, "")
1680 METHOD_ARG_DESCRIBE_OUT("commandline", DBUS_TYPE_STRING_AS_STRING
, "Commandline")
1681 METHOD_ARG_DESCRIBE_OUT("running", DBUS_TYPE_BOOLEAN_AS_STRING
, "")
1682 METHOD_ARG_DESCRIBE_OUT("terminal", DBUS_TYPE_BOOLEAN_AS_STRING
, "Whether to run in terminal")
1683 METHOD_ARG_DESCRIBE_OUT("level", DBUS_TYPE_BYTE_AS_STRING
, "Level")
1686 METHOD_ARGS_BEGIN(GetAppProperties2
, "Get properties of an application")
1687 METHOD_ARG_DESCRIBE_IN("id", DBUS_TYPE_UINT64_AS_STRING
, "id of app")
1688 METHOD_ARG_DESCRIBE_OUT("name", DBUS_TYPE_STRING_AS_STRING
, "")
1689 METHOD_ARG_DESCRIBE_OUT("commandline", DBUS_TYPE_STRING_AS_STRING
, "Commandline")
1690 METHOD_ARG_DESCRIBE_OUT("running", DBUS_TYPE_BOOLEAN_AS_STRING
, "")
1691 METHOD_ARG_DESCRIBE_OUT("terminal", DBUS_TYPE_BOOLEAN_AS_STRING
, "Whether to run in terminal")
1692 METHOD_ARG_DESCRIBE_OUT("level", DBUS_TYPE_STRING_AS_STRING
, "Level")
1695 METHOD_ARGS_BEGIN(SetAppProperties
, "Set properties of an application")
1696 METHOD_ARG_DESCRIBE_IN("id", DBUS_TYPE_UINT64_AS_STRING
, "id of app")
1697 METHOD_ARG_DESCRIBE_IN("name", DBUS_TYPE_STRING_AS_STRING
, "")
1698 METHOD_ARG_DESCRIBE_IN("commandline", DBUS_TYPE_STRING_AS_STRING
, "Commandline")
1699 METHOD_ARG_DESCRIBE_IN("terminal", DBUS_TYPE_BOOLEAN_AS_STRING
, "Whether to run in terminal")
1700 METHOD_ARG_DESCRIBE_IN("level", DBUS_TYPE_BYTE_AS_STRING
, "Level")
1703 METHOD_ARGS_BEGIN(SetAppProperties2
, "Set properties of an application")
1704 METHOD_ARG_DESCRIBE_IN("id", DBUS_TYPE_UINT64_AS_STRING
, "id of app")
1705 METHOD_ARG_DESCRIBE_IN("name", DBUS_TYPE_STRING_AS_STRING
, "")
1706 METHOD_ARG_DESCRIBE_IN("commandline", DBUS_TYPE_STRING_AS_STRING
, "Commandline")
1707 METHOD_ARG_DESCRIBE_IN("terminal", DBUS_TYPE_BOOLEAN_AS_STRING
, "Whether to run in terminal")
1708 METHOD_ARG_DESCRIBE_IN("level", DBUS_TYPE_STRING_AS_STRING
, "Level")
1711 METHOD_ARGS_BEGIN(IsAppRunning
, "Check whether application is running")
1712 METHOD_ARG_DESCRIBE_IN("id", DBUS_TYPE_UINT64_AS_STRING
, "id of app")
1713 METHOD_ARG_DESCRIBE_OUT("running", DBUS_TYPE_BOOLEAN_AS_STRING
, "Whether app is running")
1718 METHOD_DESCRIBE(GetInterfaceVersion
, get_version
) /* sync */
1719 METHOD_DESCRIBE(GetAll
, get_all1
) /* sync */
1720 METHOD_DESCRIBE(GetAll2
, get_all2
) /* sync */
1721 METHOD_DESCRIBE(RunCustom
, run_custom1
) /* async */
1722 METHOD_DESCRIBE(RunCustom2
, run_custom2
) /* async */
1723 METHOD_DESCRIBE(StartApp
, start_app
) /* async */
1724 METHOD_DESCRIBE(StopApp
, stop_app
) /* async */
1725 METHOD_DESCRIBE(KillApp
, kill_app
) /* async */
1726 METHOD_DESCRIBE(GetAppProperties
, get_app_properties1
) /* sync */
1727 METHOD_DESCRIBE(GetAppProperties2
, get_app_properties2
) /* sync */
1728 METHOD_DESCRIBE(SetAppProperties
, set_app_properties1
) /* sync */
1729 METHOD_DESCRIBE(SetAppProperties2
, set_app_properties2
) /* sync */
1730 METHOD_DESCRIBE(RemoveApp
, remove_app
) /* sync */
1731 METHOD_DESCRIBE(IsAppRunning
, is_app_running
) /* sync */
1734 SIGNAL_ARGS_BEGIN(AppAdded
, "")
1735 SIGNAL_ARG_DESCRIBE("new_list_version", DBUS_TYPE_UINT64_AS_STRING
, "")
1736 SIGNAL_ARG_DESCRIBE("id", DBUS_TYPE_UINT64_AS_STRING
, "")
1737 SIGNAL_ARG_DESCRIBE("name", DBUS_TYPE_STRING_AS_STRING
, "")
1738 SIGNAL_ARG_DESCRIBE("running", DBUS_TYPE_BOOLEAN_AS_STRING
, "")
1739 SIGNAL_ARG_DESCRIBE("terminal", DBUS_TYPE_BOOLEAN_AS_STRING
, "Whether to run in terminal")
1740 SIGNAL_ARG_DESCRIBE("level", DBUS_TYPE_BYTE_AS_STRING
, "Level")
1743 SIGNAL_ARGS_BEGIN(AppAdded2
, "")
1744 SIGNAL_ARG_DESCRIBE("new_list_version", DBUS_TYPE_UINT64_AS_STRING
, "")
1745 SIGNAL_ARG_DESCRIBE("id", DBUS_TYPE_UINT64_AS_STRING
, "")
1746 SIGNAL_ARG_DESCRIBE("name", DBUS_TYPE_STRING_AS_STRING
, "")
1747 SIGNAL_ARG_DESCRIBE("running", DBUS_TYPE_BOOLEAN_AS_STRING
, "")
1748 SIGNAL_ARG_DESCRIBE("terminal", DBUS_TYPE_BOOLEAN_AS_STRING
, "Whether to run in terminal")
1749 SIGNAL_ARG_DESCRIBE("level", DBUS_TYPE_STRING_AS_STRING
, "Level")
1752 SIGNAL_ARGS_BEGIN(AppRemoved
, "")
1753 SIGNAL_ARG_DESCRIBE("new_list_version", DBUS_TYPE_UINT64_AS_STRING
, "")
1754 SIGNAL_ARG_DESCRIBE("id", DBUS_TYPE_UINT64_AS_STRING
, "")
1757 SIGNAL_ARGS_BEGIN(AppStateChanged
, "")
1758 SIGNAL_ARG_DESCRIBE("new_list_version", DBUS_TYPE_UINT64_AS_STRING
, "")
1759 SIGNAL_ARG_DESCRIBE("id", DBUS_TYPE_UINT64_AS_STRING
, "")
1760 SIGNAL_ARG_DESCRIBE("name", DBUS_TYPE_STRING_AS_STRING
, "")
1761 SIGNAL_ARG_DESCRIBE("running", DBUS_TYPE_BOOLEAN_AS_STRING
, "")
1762 SIGNAL_ARG_DESCRIBE("terminal", DBUS_TYPE_BOOLEAN_AS_STRING
, "Whether to run in terminal")
1763 SIGNAL_ARG_DESCRIBE("level", DBUS_TYPE_BYTE_AS_STRING
, "Level")
1766 SIGNAL_ARGS_BEGIN(AppStateChanged2
, "")
1767 SIGNAL_ARG_DESCRIBE("new_list_version", DBUS_TYPE_UINT64_AS_STRING
, "")
1768 SIGNAL_ARG_DESCRIBE("id", DBUS_TYPE_UINT64_AS_STRING
, "")
1769 SIGNAL_ARG_DESCRIBE("name", DBUS_TYPE_STRING_AS_STRING
, "")
1770 SIGNAL_ARG_DESCRIBE("running", DBUS_TYPE_BOOLEAN_AS_STRING
, "")
1771 SIGNAL_ARG_DESCRIBE("terminal", DBUS_TYPE_BOOLEAN_AS_STRING
, "Whether to run in terminal")
1772 SIGNAL_ARG_DESCRIBE("level", DBUS_TYPE_STRING_AS_STRING
, "Level")
1776 SIGNAL_DESCRIBE(AppAdded
)
1777 SIGNAL_DESCRIBE(AppAdded2
)
1778 SIGNAL_DESCRIBE(AppRemoved
)
1779 SIGNAL_DESCRIBE(AppStateChanged
)
1780 SIGNAL_DESCRIBE(AppStateChanged2
)
1783 INTERFACE_BEGIN(g_iface_app_supervisor
, IFACE_APP_SUPERVISOR
)
1784 INTERFACE_DEFAULT_HANDLER
1785 INTERFACE_EXPOSE_METHODS
1786 INTERFACE_EXPOSE_SIGNALS