502
/* Throw out a DBus signal that we've signalled all of these processes. This
503
is the fun GVariant building part. */
505
notify_signalling (GList * pids, const gchar * appid, const gchar * signal_name)
507
GDBusConnection * conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
512
/* Pull together a PID array */
513
GVariant *pidarray = NULL;
515
pidarray = g_variant_new_array(G_VARIANT_TYPE_UINT64, NULL, 0);
518
GVariantBuilder builder;
519
g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
521
for (i = pids; i != NULL; i = g_list_next(i))
522
g_variant_builder_add_value(&builder, g_variant_new_uint64(GPOINTER_TO_INT(i->data)));
524
pidarray = g_variant_builder_end(&builder);
527
/* Combine into the wrapping tuple */
528
GVariantBuilder btuple;
529
g_variant_builder_init(&btuple, G_VARIANT_TYPE_TUPLE);
530
g_variant_builder_add_value(&btuple, g_variant_new_string(appid));
531
g_variant_builder_add_value(&btuple, pidarray);
534
GError * error = NULL;
535
g_dbus_connection_emit_signal(conn,
536
NULL, /* destination */
538
"com.canonical.UbuntuAppLaunch", /* interface */
539
signal_name, /* signal */
540
g_variant_builder_end(&btuple), /* params, the same */
544
g_warning("Unable to emit signal '%s' for appid '%s': %s", signal_name, appid, error->message);
547
g_debug("Emmitted '%s' to DBus", signal_name);
550
g_object_unref(conn);
502
553
/* Gets all the pids for an appid and sends a signal to all of them. This also
503
554
loops to ensure no new pids are added while we're signaling */
505
signal_to_cgroup (const gchar * appid, int signal, const gchar * oomscore)
556
signal_to_cgroup (const gchar * appid, int signal, const gchar * oomscore, const gchar * signal_name)
507
558
GHashTable * pidssignaled = g_hash_table_new(g_direct_hash, g_direct_equal);
508
559
guint hash_table_size = 0;
612
664
ubuntu_app_launch_pause_application (const gchar * appid)
614
666
report_zg_event(appid, ZEITGEIST_ZG_LEAVE_EVENT);
615
return signal_to_cgroup(appid, SIGSTOP, "900");
667
return signal_to_cgroup(appid, SIGSTOP, "900", "ApplicationPaused");
619
671
ubuntu_app_launch_resume_application (const gchar * appid)
621
673
report_zg_event(appid, ZEITGEIST_ZG_ACCESS_EVENT);
622
return signal_to_cgroup(appid, SIGCONT, "100");
674
return signal_to_cgroup(appid, SIGCONT, "100", "ApplicationResumed");
709
761
gpointer user_data;
764
/* The data we keep for each failed observer */
765
typedef struct _paused_resumed_observer_t paused_resumed_observer_t;
766
struct _paused_resumed_observer_t {
767
GDBusConnection * conn;
769
UbuntuAppLaunchAppPausedResumedObserver func;
771
const gchar * lttng_signal;
712
774
/* The lists of Observers */
713
775
static GList * starting_array = NULL;
714
776
static GList * started_array = NULL;
716
778
static GList * focus_array = NULL;
717
779
static GList * resume_array = NULL;
718
780
static GList * failed_array = NULL;
781
static GList * paused_array = NULL;
782
static GList * resumed_array = NULL;
721
785
observer_cb (GDBusConnection * conn, const gchar * sender, const gchar * object, const gchar * interface, const gchar * signal, GVariant * params, gpointer user_data)
1061
/* Handle the paused signal when it occurs, call the observer */
1063
paused_signal_cb (GDBusConnection * conn, const gchar * sender, const gchar * object, const gchar * interface, const gchar * signal, GVariant * params, gpointer user_data)
1065
paused_resumed_observer_t * observer = (paused_resumed_observer_t *)user_data;
1067
ual_tracepoint(observer_start, observer->lttng_signal);
1069
if (observer->func != NULL) {
1070
GArray * pidarray = g_array_new(TRUE, TRUE, sizeof(GPid));
1071
GVariant * appid = g_variant_get_child_value(params, 0);
1072
GVariant * pids = g_variant_get_child_value(params, 1);
1074
GVariantIter thispid;
1075
g_variant_iter_init(&thispid, pids);
1077
while (g_variant_iter_loop(&thispid, "t", &pid)) {
1078
GPid gpid = (GPid)pid; /* Should be a no-op for most architectures, but just in case */
1079
g_array_append_val(pidarray, gpid);
1082
observer->func(g_variant_get_string(appid, NULL), (GPid *)pidarray->data, observer->user_data);
1084
g_array_free(pidarray, TRUE);
1085
g_variant_unref(appid);
1086
g_variant_unref(pids);
1089
ual_tracepoint(observer_finish, observer->lttng_signal);
1093
paused_resumed_generic (UbuntuAppLaunchAppPausedResumedObserver observer, gpointer user_data, GList ** queue, const gchar * signal_name, const gchar * lttng_signal)
1095
GDBusConnection * conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
1101
paused_resumed_observer_t * observert = g_new0(paused_resumed_observer_t, 1);
1103
observert->conn = conn;
1104
observert->func = observer;
1105
observert->user_data = user_data;
1106
observert->lttng_signal = lttng_signal;
1108
*queue = g_list_prepend(*queue, observert);
1110
observert->sighandle = g_dbus_connection_signal_subscribe(conn,
1112
"com.canonical.UbuntuAppLaunch", /* interface */
1113
signal_name, /* signal */
1116
G_DBUS_SIGNAL_FLAGS_NONE,
1119
NULL); /* user data destroy */
1125
ubuntu_app_launch_observer_add_app_paused (UbuntuAppLaunchAppPausedResumedObserver observer, gpointer user_data)
1127
return paused_resumed_generic(observer, user_data, &paused_array, "ApplicationPaused", "paused");
1131
ubuntu_app_launch_observer_add_app_resumed (UbuntuAppLaunchAppPausedResumedObserver observer, gpointer user_data)
1133
return paused_resumed_generic(observer, user_data, &resumed_array, "ApplicationResumed", "resumed");
998
1137
delete_app_generic (UbuntuAppLaunchAppObserver observer, gpointer user_data, GList ** list)
1221
paused_resumed_delete (UbuntuAppLaunchAppPausedResumedObserver observer, gpointer user_data, GList ** list)
1223
paused_resumed_observer_t * observert = NULL;
1226
for (look = *list; look != NULL; look = g_list_next(look)) {
1227
observert = (paused_resumed_observer_t *)look->data;
1229
if (observert->func == observer && observert->user_data == user_data) {
1238
g_dbus_connection_signal_unsubscribe(observert->conn, observert->sighandle);
1239
g_object_unref(observert->conn);
1242
*list = g_list_delete_link(*list, look);
1248
ubuntu_app_launch_observer_delete_app_paused (UbuntuAppLaunchAppPausedResumedObserver observer, gpointer user_data)
1250
return paused_resumed_delete(observer, user_data, &paused_array);
1254
ubuntu_app_launch_observer_delete_app_resumed (UbuntuAppLaunchAppPausedResumedObserver observer, gpointer user_data)
1256
return paused_resumed_delete(observer, user_data, &resumed_array);
1081
1259
typedef void (*per_instance_func_t) (GDBusConnection * con, GVariant * prop_dict, gpointer user_data);