diff options
Diffstat (limited to 'src/app_launcher.c')
-rw-r--r-- | src/app_launcher.c | 208 |
1 files changed, 19 insertions, 189 deletions
diff --git a/src/app_launcher.c b/src/app_launcher.c index 417f59a..d576332 100644 --- a/src/app_launcher.c +++ b/src/app_launcher.c @@ -1,40 +1,20 @@ +// SPDX-License-Identifier: Apache-2.0 /* * Copyright (C) 2021 Collabora Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright (C) 2022 Konsulko Group */ #include "app_info.h" #include "app_launcher.h" #include "systemd_manager.h" -#include "utils.h" typedef struct _AppLauncher { applaunchdAppLaunchSkeleton parent; -/* TODO: try to move event and bus properties down to systemd_manager */ - sd_event *event; - sd_bus *bus; - SystemdManager *systemd_manager; - GList *apps_list; } AppLauncher; -extern GMainLoop *main_loop; - -extern GSource *g_sd_event_create_source(sd_event *event, sd_bus *bus); - static void app_launcher_iface_init(applaunchdAppLaunchIface *iface); G_DEFINE_TYPE_WITH_CODE(AppLauncher, app_launcher, @@ -51,109 +31,26 @@ static void app_launcher_started_cb(AppLauncher *self, */ /* - * This function is executed during the object initialization. It goes through - * all available applications on the system and creates a static list - * containing all the relevant info (ID, name, unit, icon...) for further - * processing. - */ -static void app_launcher_update_applications_list(AppLauncher *self) -{ - g_auto(GStrv) dirlist = NULL; - - char *xdg_data_dirs = getenv("XDG_DATA_DIRS"); - if (xdg_data_dirs) - dirlist = g_strsplit(getenv("XDG_DATA_DIRS"), ":", -1); - - GList *units = NULL; - if (!systemd_manager_enumerate_app_units(self->systemd_manager, self, &units)) { - return; - } - - GList *iterator; - for (iterator = units; iterator != NULL; iterator = iterator->next) { - g_autofree const gchar *app_id = NULL; - g_autofree const gchar *icon_path = NULL; - AppInfo *app_info = NULL; - - if (!iterator->data) - continue; - - // Parse service and app id out of unit filename - gchar *service = g_strrstr(iterator->data, "/"); - if (!service) - service = iterator->data; - else - service += 1; - - g_autofree char *tmp = g_strdup(service); - char *end = tmp + strlen(tmp); - while (end > tmp && *end != '.') { - --end; - } - if (end > tmp) { - *end = '\0'; - } else { - g_free(tmp); - continue; - } - while (end > tmp && *end != '@') { - --end; - } - if (end > tmp) { - app_id = g_strdup(end + 1); - } - // Potentially handle non-template agl-app-foo.service units here - - // Try getting display name from unit Description property - char *name = NULL; - if (!systemd_manager_get_app_description(self->systemd_manager, - self, - service, - &name) || - name == NULL) { - - // Fall back to the application ID - g_warning("Could not retrieve Description of '%s'", service); - name = app_id; - } - - /* - * GAppInfo retrieves the icon data but doesn't provide a way to retrieve - * the corresponding file name, so we have to look it up by ourselves. - */ - if (app_id && dirlist) - icon_path = applaunchd_utils_get_icon(dirlist, app_id); - - app_info = app_info_new(app_id, - name, - icon_path ? icon_path : "", - service); - - g_debug("Adding application '%s' with display name '%s'", app_id, name); - - self->apps_list = g_list_append(self->apps_list, app_info); - } - g_list_free_full(units, g_free); -} - -/* * Construct the application list to be sent over D-Bus. It has format "av", meaning * the list itself is an array, each item being a variant consisting of 3 strings: * - app-id * - app name * - icon path */ -static GVariant *app_launcher_get_list_variant(AppLauncher *self, gboolean graphical) +static GVariant *app_launcher_get_list_variant(AppLauncher *self) { GVariantBuilder builder; - guint len = g_list_length(self->apps_list); + GList *apps_list = systemd_manager_get_app_list(self->systemd_manager); + if (!apps_list) + return NULL; + guint len = g_list_length(apps_list); /* Init array variant for storing the applications list */ g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); for (guint i = 0; i < len; i++) { GVariantBuilder app_builder; - AppInfo *app_info = g_list_nth_data(self->apps_list, i); + AppInfo *app_info = g_list_nth_data(apps_list, i); g_variant_builder_init (&app_builder, G_VARIANT_TYPE("(sss)")); @@ -173,36 +70,12 @@ static GVariant *app_launcher_get_list_variant(AppLauncher *self, gboolean graph * Starts the requested application using either the D-Bus activation manager * or the process manager. */ -static gboolean app_launcher_start_app(AppLauncher *self, AppInfo *app_info) +gboolean app_launcher_start_app(AppLauncher *self, AppInfo *app_info) { g_return_val_if_fail(APPLAUNCHD_IS_APP_LAUNCHER(self), FALSE); g_return_val_if_fail(APPLAUNCHD_IS_APP_INFO(app_info), FALSE); - AppStatus app_status = app_info_get_status(app_info); - const gchar *app_id = app_info_get_app_id(app_info); - - switch (app_status) { - case APP_STATUS_STARTING: - g_debug("Application '%s' is already starting", app_id); - return TRUE; - case APP_STATUS_RUNNING: - g_debug("Application '%s' is already running", app_id); - /* - * The application may be running in the background, activate it - * and notify subscribers it should be activated/brought to the - * foreground - */ - app_launcher_started_cb(self, app_id, NULL); - return TRUE; - case APP_STATUS_INACTIVE: - systemd_manager_start_app(self->systemd_manager, app_info); - return TRUE; - default: - g_critical("Unknown status %d for application '%s'", app_status, app_id); - break; - } - - return FALSE; + return systemd_manager_start_app(self->systemd_manager, app_info); } /* @@ -221,7 +94,7 @@ static gboolean app_launcher_handle_start(applaunchdAppLaunch *object, g_return_val_if_fail(APPLAUNCHD_IS_APP_LAUNCHER(self), FALSE); /* Search the apps list for the given app-id */ - app = app_launcher_get_app_info(self, app_id); + app = systemd_manager_get_app_info(self->systemd_manager, app_id); if (!app) { g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, @@ -248,8 +121,9 @@ static gboolean app_launcher_handle_list_applications(applaunchdAppLaunch *objec g_return_val_if_fail(APPLAUNCHD_IS_APP_LAUNCHER(self), FALSE); /* Retrieve the applications list in the right format for sending over D-Bus */ - result = app_launcher_get_list_variant(self, graphical); - applaunchd_app_launch_complete_list_applications(object, invocation, result); + result = app_launcher_get_list_variant(self); + if (result) + applaunchd_app_launch_complete_list_applications(object, invocation, result); return TRUE; } @@ -303,9 +177,6 @@ static void app_launcher_dispose(GObject *object) { AppLauncher *self = APPLAUNCHD_APP_LAUNCHER(object); - if (self->apps_list) - g_list_free_full(g_steal_pointer(&self->apps_list), g_object_unref); - g_clear_object(&self->systemd_manager); G_OBJECT_CLASS(app_launcher_parent_class)->dispose(object); @@ -331,24 +202,15 @@ static void app_launcher_iface_init(applaunchdAppLaunchIface *iface) static void app_launcher_init (AppLauncher *self) { - sd_bus_open_system(&self->bus); - sd_event_default(&self->event); - sd_bus_attach_event(self->bus, self->event, SD_EVENT_PRIORITY_NORMAL); - g_source_attach(g_sd_event_create_source(self->event, self->bus), g_main_loop_get_context(main_loop)); - /* * Create the systemd manager and connect to its signals * so we get notified on app startup/termination */ - self->systemd_manager = g_object_new(APPLAUNCHD_TYPE_SYSTEMD_MANAGER, - NULL); - g_signal_connect_swapped(self->systemd_manager, "started", - G_CALLBACK(app_launcher_started_cb), self); - g_signal_connect_swapped(self->systemd_manager, "terminated", - G_CALLBACK(app_launcher_terminated_cb), self); - - /* Initialize the applications list */ - app_launcher_update_applications_list(self); + self->systemd_manager = systemd_manager_get_default(); + systemd_manager_connect_callbacks(self->systemd_manager, + G_CALLBACK(app_launcher_started_cb), + G_CALLBACK(app_launcher_terminated_cb), + self); } /* @@ -371,35 +233,3 @@ AppLauncher *app_launcher_get_default(void) return launcher; } - -/* - * Search the applications list for an app which matches the provided app-id - * and return the corresponding AppInfo object. - */ -AppInfo *app_launcher_get_app_info(AppLauncher *self, const gchar *app_id) -{ - g_return_val_if_fail(APPLAUNCHD_IS_APP_LAUNCHER(self), NULL); - - guint len = g_list_length(self->apps_list); - - for (guint i = 0; i < len; i++) { - AppInfo *app_info = g_list_nth_data(self->apps_list, i); - - if (g_strcmp0(app_info_get_app_id(app_info), app_id) == 0) - return app_info; - } - - g_warning("Unable to find application with ID '%s'", app_id); - - return NULL; -} - -sd_bus *app_launcher_get_bus(AppLauncher *self) -{ - return self->bus; -} - -sd_event *app_launcher_get_event(AppLauncher *self) -{ - return self->event; -} |